Stage 16 — AI Layer: VIN decoder + diagnostic / parts / price helpers
VinDecoder (deterministic, no API): - ISO 3779/3780 parsing: WMI manufacturer (~60 brands), year (cyclical with post-2010 disambiguation via position 7), region, plant, NA checksum - Strip non-VIN chars, accept dashes/spaces, reject I/O/Q per spec AiAssistantService: - Refactored provider HTTP into postClaude/postOpenAI/postGemini so both chat history and one-shot calls share the same transport - singleShot(system, userPrompt, provider?) for fire-and-forget calls - 4 specialized helpers with tight prompts: - suggestDiagnosis(WO) — diagnostician based on complaint + VIN info - suggestParts(WO, task) — OEM parts list for an operation - suggestPrice(Part) — markup recommendation with justification - vinRecommendations(vin, mileage) — scheduled maintenance from decoded VIN - monthlyUsage() — token spend MTD by provider Filament: - VehicleResource: "Decode VIN" + "AI: recomandări" actions - WorkOrderResource Edit: "AI: sugerează diagnostic" header action - PartResource: "AI: preț recomandat" action - Shared views: filament.tenant.ai-reply, filament.tenant.vin-decode - AiAssistant page shows monthly token usage banner Tests (13 new): - 8 VinDecoder unit tests with real VIN samples (Honda 2003, VW 1999, Audi 2014, Dacia, unknown WMI, lowercase/dashes, forbidden chars) - 5 AiHelpers feature tests with Http::fake covering all providers + no-key fallback + token usage aggregation Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,8 +86,21 @@
|
||||
@php
|
||||
$chat = $this->getChat();
|
||||
$chats = $this->getChats();
|
||||
$usage = $this->getUsage();
|
||||
$totalTokens = collect($usage)->sum(fn ($u) => $u['tokens_in'] + $u['tokens_out']);
|
||||
$totalCalls = collect($usage)->sum('calls');
|
||||
@endphp
|
||||
|
||||
@if ($totalCalls > 0)
|
||||
<div style="margin-bottom:12px;padding:10px 14px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;font-size:12px;color:#1e3a8a;">
|
||||
<strong>Tokens consumate luna aceasta:</strong>
|
||||
{{ number_format($totalTokens) }} tokens · {{ $totalCalls }} cereri
|
||||
@foreach ($usage as $provider => $u)
|
||||
· {{ strtoupper($provider) }}: {{ number_format($u['tokens_in'] + $u['tokens_out']) }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="ai-wrap" x-data x-init="$nextTick(() => { const m = $refs.msgs; if (m) m.scrollTop = m.scrollHeight; })">
|
||||
{{-- Sidebar: chat history --}}
|
||||
<div class="ai-side">
|
||||
|
||||
Reference in New Issue
Block a user