feat: tenant AI chat agent with function calling
Actionable AI assistant that uses per-tenant Azure OpenAI credentials to execute natural language commands against the render pipeline. Backend: - ChatMessage model + migration (session-based conversations) - Chat service with 10 OpenAI function-calling tools: list_orders, search_products, create_order, dispatch_renders, get_order_status, set_material_override, set_render_overrides, get_render_stats, check_materials, query_database - All tools tenant-scoped (queries filtered by tenant_id) - Write operations use httpx to call backend API internally - Chat API: POST /chat/messages, GET /chat/sessions, DELETE session - Conversation history preserved in DB (last 50 messages per session) Frontend: - Slide-out ChatPanel (right side, w-96, animated) - User/assistant message styling with avatars and timestamps - Session management (new chat, session history, delete) - Typing indicator while waiting for AI response - Floating chat button in bottom-right corner - Error state for unconfigured AI tenants Example: "Render all Kugellager products as WebP at 1024x1024" → Agent calls search_products + create_order + dispatch_renders Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import api from './client'
|
||||
|
||||
export interface ChatMessage {
|
||||
id: string
|
||||
role: 'user' | 'assistant' | 'system'
|
||||
content: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface ChatSession {
|
||||
session_id: string
|
||||
last_message: string
|
||||
message_count: number
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface ChatResponse {
|
||||
session_id: string
|
||||
message: ChatMessage
|
||||
response: ChatMessage
|
||||
}
|
||||
|
||||
export async function sendChatMessage(
|
||||
message: string,
|
||||
sessionId?: string,
|
||||
contextType?: string,
|
||||
contextId?: string,
|
||||
): Promise<ChatResponse> {
|
||||
const res = await api.post<ChatResponse>('/chat/messages', {
|
||||
message,
|
||||
session_id: sessionId || undefined,
|
||||
context_type: contextType || undefined,
|
||||
context_id: contextId || undefined,
|
||||
})
|
||||
return res.data
|
||||
}
|
||||
|
||||
export async function getChatSessions(): Promise<ChatSession[]> {
|
||||
const res = await api.get<ChatSession[]>('/chat/sessions')
|
||||
return res.data
|
||||
}
|
||||
|
||||
export async function getSessionMessages(sessionId: string): Promise<ChatMessage[]> {
|
||||
const res = await api.get<ChatMessage[]>(`/chat/sessions/${sessionId}/messages`)
|
||||
return res.data
|
||||
}
|
||||
|
||||
export async function deleteChatSession(sessionId: string): Promise<void> {
|
||||
await api.delete(`/chat/sessions/${sessionId}`)
|
||||
}
|
||||
Reference in New Issue
Block a user