AI Chat
Chat AI z obsługą streamingu, draftów i trybów kontekstowych (visit/patient/specialist).
AI Chat Experimental
Dział zatytułowany „AI Chat Experimental”Na tej stronie
Overview
Dział zatytułowany „Overview”AI Chat to interaktywny interfejs do rozmów z AI w kontekście wizyty lub ogólnych konsultacji weterynaryjnych.
Architecture
Dział zatytułowany „Architecture”flowchart TB subgraph UI["Chat UI"] Input[Message Input] Messages[Message List] Streaming[Streaming Display] end
subgraph Hooks useChatHistory[useChatHistory] useChat[useChat] end
subgraph Client["UnifiedAIClient"] chat[chat] chatStream[chatStream] cancelStream[cancelStream] end
subgraph Backend unified_ai_chat unified_ai_chat_stream end
UI --> Hooks Hooks --> Client Client --> BackendComponents
Dział zatytułowany „Components”Chat Panel
Dział zatytułowany „Chat Panel”┌─────────────────────────────────────┐│ AI Assistant [Detach] [X] │├─────────────────────────────────────┤│ ││ 🐾 Witaj! Jak mogę pomóc? ││ ││ 👤 Pies ma wymioty od 2 dni ││ ││ 🐾 Rozumiem. Kilka pytań: ││ - Czy pies je normalnie? ││ - Czy są inne objawy? ││ - Jaki jest wiek psa? ││ ││ 👤 ...typing... ││ │├─────────────────────────────────────┤│ [Type a message...] [Send] 🎤 │└─────────────────────────────────────┘Hook: useChatHistory
Dział zatytułowany „Hook: useChatHistory”Plik: src/features/ai-suite/hooks/useChatHistory.ts
const { messages, isLoading, addMessage, clearMessages, loadDraft, persistDraft,} = useChatHistory(storageKey);Auto-persistence
Dział zatytułowany „Auto-persistence”// Auto-save every second (debounced)useEffect(() => { const timer = setTimeout(() => { persistDraft(messages); }, 1000); return () => clearTimeout(timer);}, [messages]);
// Save on unmountuseEffect(() => { return () => persistDraft(messagesRef.current);}, []);Chat Flow
Dział zatytułowany „Chat Flow”sequenceDiagram participant User participant UI as Chat Panel participant Hook as useChat participant Client as UnifiedAIClient participant BE as Backend
User->>UI: Type message User->>UI: Press Send
UI->>Hook: sendMessage(text) Hook->>Hook: Add user message to history
alt Streaming enabled Hook->>Client: chatStream(message, options) Client->>BE: unified_ai_chat_stream
loop Token streaming BE-->>Client: token Client-->>Hook: onToken(token) Hook->>UI: Update display end
BE-->>Client: complete Client-->>Hook: onComplete(response) else Non-streaming Hook->>Client: chat(message, options) Client->>BE: unified_ai_chat BE-->>Client: Full response Client-->>Hook: response end
Hook->>Hook: Add AI message to history Hook->>UI: Update messagesChat Options
Dział zatytułowany „Chat Options”interface ChatOptions { canonicalModel?: string; // 'chat' | 'ai-suggestions' visitId?: string; // Link to visit context patientId?: string; // Patient context systemPrompt?: string; // Custom system prompt temperature?: number; // 0-1, creativity level maxTokens?: number; // Response length limit}Context Modes
Dział zatytułowany „Context Modes”Chat może działać w różnych kontekstach:
| Mode | Context | Use Case |
|---|---|---|
| General | None | Ogólne pytania |
| Visit | visitId | Pytania o konkretną wizytę |
| Patient | patientId | Historia pacjenta |
| Specialist | Custom prompt | AI Specjalista |
Message Types
Dział zatytułowany „Message Types”interface ChatMessage { id: string; role: 'user' | 'assistant' | 'system'; content: string; timestamp: number; metadata?: { visitId?: string; sources?: string[]; // References confidence?: number; };}Draft Management
Dział zatytułowany „Draft Management”Drafty są zapisywane lokalnie:
// Save draftawait safeInvoke('ai_chat_draft_save', { context_key: storageKey, messages: messages.map(m => ({ role: m.role, content: m.content, timestamp: m.timestamp, })),});
// Load draftconst draft = await safeInvoke('ai_chat_draft_load', { context_key: storageKey,});Chat Sessions
Dział zatytułowany „Chat Sessions”Trwałe sesje dla historii:
// Save sessionawait chatSessionsApi.save({ visitId: currentVisitId, messages: messages,});
// List sessionsconst sessions = await chatSessionsApi.list({ visitId: currentVisitId, limit: 20,});Streaming Controls
Dział zatytułowany „Streaming Controls”// Start streamingconst requestId = UnifiedAIClient.chatStream( message, options, onToken, onComplete, onError);
// Cancel streamingUnifiedAIClient.cancelStream(requestId);Detached Window
Dział zatytułowany „Detached Window”Chat można odłączyć do osobnego okna:
if (isTauriEnv) { // Create new window await createWindow(DETACHED_WINDOW_LABEL, { width: 400, height: 600, title: 'AI Assistant', });
// Apply glass effect await safeInvoke('vista_apply_glass', { label: DETACHED_WINDOW_LABEL, });}Error States
Dział zatytułowany „Error States”// Handle errors gracefullytry { await sendMessage(text);} catch (error) { if (error.code === 'STREAM_CANCELLED') { // User cancelled - no error message } else if (error.code === 'RATE_LIMIT') { addMessage({ role: 'system', content: 'Zbyt wiele wiadomości. Odczekaj chwilę.', }); } else { addMessage({ role: 'system', content: 'Wystąpił błąd. Spróbuj ponownie.', }); }}Related
Dział zatytułowany „Related”- AI Suite Overview - Full AI system
- AI Assistants - Specialist modes
- AI Commands - API reference