60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# AI Features — DeepSeek Integration
|
|
|
|
spq-v2 mirrors v1's AI integration exactly: all calls go to `/deepseek/v1/chat/completions` with `deepseek-v4-flash`.
|
|
|
|
## Architecture
|
|
|
|
All AI functions live in `src/lib/ai.ts` and use a shared `callDeepSeek()` helper:
|
|
|
|
```
|
|
fetch('/deepseek/v1/chat/completions', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
model: 'deepseek-v4-flash',
|
|
messages: [{role:'system', content}, {role:'user', content}],
|
|
temperature: 0,
|
|
thinking: { type: 'disabled' },
|
|
max_tokens: 500,
|
|
}),
|
|
})
|
|
```
|
|
|
|
The endpoint works through the Python proxy server (`/deepseek/*` is forwarded by nginx in production, not the Python proxy — the proxy only handles `/pb/*`; ensure nginx has the `/deepseek` location block).
|
|
|
|
## Exported Functions
|
|
|
|
### 1. `getPriorityAnalysis(services)` — Generate Priorities
|
|
- Input: `ServiceItem[]` (name, recommendation)
|
|
- Output: `PriorityResult[]` (name, rank, priority_reason)
|
|
- Sends services to AI for safety-first ranking: CRITICAL_SAFETY > SAFETY_CONCERN > RECOMMENDED > MAINTENANCE > OPTIONAL
|
|
- Strips markdown code blocks from response before JSON parsing
|
|
|
|
### 2. `aiWriteExplanation(params)` — AI Write
|
|
- Input: `ExplanationParams` (serviceName, recommendation, technicianNotes?, vehicleInfo?, mileage?, maintenanceInterval?)
|
|
- Output: `ExplanationResult` (level, explanation) or null
|
|
- Generates professional customer-facing explanation
|
|
- Incorporates vehicle context, mileage, interval data
|
|
- Parses `LEVEL:` and `EXPLANATION:` tagged response format
|
|
- Level is one of: CRITICAL, RECOMMENDED, OPTIONAL, PREVENTIVE, MAINTENANCE
|
|
|
|
### 3. `aiSuggestServices(vehicle, selectedServices, catalog)` — AI Suggest
|
|
- Input: `SuggestVehicle`, `string[]`, `CatalogItem[]`
|
|
- Output: `SuggestResult[]` (name, reason) or null
|
|
- Recommends services from catalog based on mileage + vehicle info
|
|
- Cross-references AI output against catalog names — only returns catalog matches
|
|
- Never invents services; only suggests from the provided catalog
|
|
|
|
### 4. Screenshot OCR + Extraction (in Appointments.tsx)
|
|
- Uses Tesseract.js (dynamic CDN import: `cdn.jsdelivr.net/npm/tesseract.js@5`)
|
|
- Canvas preprocessing: 2-3x upscale + mild contrast enhancement
|
|
- OCR text sent to `/deepseek/v1/chat/completions` with `max_tokens: 2000` for structured JSON extraction
|
|
- Extracted appointments reviewed before batch import
|
|
|
|
## Pitfalls
|
|
|
|
- **Tesseract.js not in package.json** — the screenshot import feature loads it dynamically from CDN. If offline or CDN blocked, the feature silently fails.
|
|
- **Model must be `deepseek-v4-flash`** — other models may not follow the strict JSON-only response format.
|
|
- **AI functions return `null` on failure** — UI must handle null gracefully (show toast, don't crash).
|
|
- **`temperature: 0` is intentional** — structured extraction needs deterministic output.
|