@open-mercato/ai-assistant 0.4.11-develop.1917.b6098e78cb → 0.4.11-develop.1922.46b23ba3b5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/frontend/components/DockableChat/DockableChat.js +5 -0
  2. package/dist/frontend/components/DockableChat/DockableChat.js.map +2 -2
  3. package/dist/frontend/hooks/useCommandPalette.js +16 -12
  4. package/dist/frontend/hooks/useCommandPalette.js.map +2 -2
  5. package/dist/frontend/hooks/useMcpTools.js +22 -21
  6. package/dist/frontend/hooks/useMcpTools.js.map +2 -2
  7. package/dist/modules/ai_assistant/api/chat/route.js +9 -1
  8. package/dist/modules/ai_assistant/api/chat/route.js.map +2 -2
  9. package/dist/modules/ai_assistant/api/health/route.js +9 -1
  10. package/dist/modules/ai_assistant/api/health/route.js.map +2 -2
  11. package/dist/modules/ai_assistant/api/route/route.js +9 -1
  12. package/dist/modules/ai_assistant/api/route/route.js.map +2 -2
  13. package/dist/modules/ai_assistant/api/settings/route.js +9 -1
  14. package/dist/modules/ai_assistant/api/settings/route.js.map +2 -2
  15. package/dist/modules/ai_assistant/api/tools/execute/route.js +9 -1
  16. package/dist/modules/ai_assistant/api/tools/execute/route.js.map +2 -2
  17. package/dist/modules/ai_assistant/api/tools/route.js +9 -1
  18. package/dist/modules/ai_assistant/api/tools/route.js.map +2 -2
  19. package/dist/modules/ai_assistant/lib/opencode-client.js +24 -8
  20. package/dist/modules/ai_assistant/lib/opencode-client.js.map +2 -2
  21. package/package.json +4 -4
  22. package/src/frontend/components/DockableChat/DockableChat.tsx +5 -0
  23. package/src/frontend/hooks/useCommandPalette.ts +17 -12
  24. package/src/frontend/hooks/useMcpTools.ts +22 -22
  25. package/src/modules/ai_assistant/api/chat/route.ts +9 -0
  26. package/src/modules/ai_assistant/api/health/route.ts +9 -0
  27. package/src/modules/ai_assistant/api/route/route.ts +9 -0
  28. package/src/modules/ai_assistant/api/settings/route.ts +9 -0
  29. package/src/modules/ai_assistant/api/tools/execute/route.ts +9 -0
  30. package/src/modules/ai_assistant/api/tools/route.ts +9 -0
  31. package/src/modules/ai_assistant/lib/opencode-client.ts +24 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/frontend/hooks/useCommandPalette.ts"],
4
- "sourcesContent": ["'use client'\n\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react'\nimport type {\n AgentStatus,\n CommandPaletteMode,\n CommandPalettePage,\n CommandPaletteState,\n ConnectionStatus,\n PalettePhase,\n PageContext,\n SelectedEntity,\n ToolInfo,\n ToolExecutionResult,\n PendingToolCall,\n ChatMessage,\n RouteResult,\n DebugEvent,\n DebugEventType,\n OpenCodeQuestion,\n} from '../types'\nimport { COMMAND_PALETTE_SHORTCUT, AI_CHAT_SHORTCUT } from '../constants'\nimport { filterTools } from '../utils/toolMatcher'\nimport { useMcpTools } from './useMcpTools'\nimport { useRecentActions } from './useRecentActions'\nimport { useRecentTools } from './useRecentTools'\nimport { useAiAssistantVisibility } from './useAiAssistantVisibility'\n\ninterface UseCommandPaletteOptions {\n pageContext: PageContext | null\n selectedEntities?: SelectedEntity[]\n disableKeyboardShortcut?: boolean\n}\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15)\n}\n\n// Tools that are safe to auto-execute without user confirmation\nconst SAFE_TOOL_PATTERNS = [\n /^search_/, // search_query, search_schema, search_get, search_aggregate, search_status\n /^get_/, // get_ operations are read-only\n /^list_/, // list_ operations are read-only\n /^view_/, // view_ operations are read-only\n /^context_/, // context_whoami etc.\n /_get$/, // tools ending with _get\n /_list$/, // tools ending with _list\n /_status$/, // tools ending with _status\n /_schema$/, // tools ending with _schema\n]\n\n// Tools that should always require confirmation\nconst DANGEROUS_TOOL_PATTERNS = [\n /^delete_/,\n /^remove_/,\n /_delete$/,\n /_remove$/,\n /^reindex_/,\n /_reindex$/,\n]\n\nfunction isToolSafeToAutoExecute(toolName: string): boolean {\n // First check if it's a dangerous tool\n if (DANGEROUS_TOOL_PATTERNS.some(p => p.test(toolName))) {\n return false\n }\n // Then check if it matches safe patterns\n return SAFE_TOOL_PATTERNS.some(p => p.test(toolName))\n}\n\nfunction getToolPrompt(tool: ToolInfo): string {\n const schema = tool.inputSchema\n if (!schema || typeof schema !== 'object') {\n return 'What would you like to do?'\n }\n\n const properties = (schema as { properties?: Record<string, unknown> }).properties\n if (!properties || Object.keys(properties).length === 0) {\n return 'This tool has no parameters. Ready to execute?'\n }\n\n const paramNames = Object.keys(properties).slice(0, 3)\n return `Please provide the following: ${paramNames.join(', ')}.`\n}\n\nexport function useCommandPalette(options: UseCommandPaletteOptions) {\n const { pageContext, selectedEntities = [], disableKeyboardShortcut = false } = options\n\n // Check if AI assistant is enabled (for Cmd+J shortcut)\n const { isEnabled: isAiAssistantEnabled } = useAiAssistantVisibility()\n\n // Core state with phase-based navigation for intelligent routing\n const [state, setState] = useState<CommandPaletteState>({\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n selectedIndex: 0,\n isLoading: false,\n isStreaming: false,\n connectionStatus: 'disconnected',\n // Legacy fields for backwards compatibility\n page: 'home',\n mode: 'commands',\n })\n\n // Tool-related hooks\n const { tools, isLoading: toolsLoading, executeTool: executeToolApi } = useMcpTools()\n const { recentActions, addRecentAction } = useRecentActions()\n const { recentTools, saveRecentTool } = useRecentTools(tools)\n\n // Selected tool for tool-chat page\n const [selectedTool, setSelectedTool] = useState<ToolInfo | null>(null)\n\n // Chat state for tool-chat page\n const [messages, setMessages] = useState<ChatMessage[]>([])\n const [pendingToolCalls, setPendingToolCalls] = useState<PendingToolCall[]>([])\n\n // Initial context from context_whoami - fetched when palette opens\n const [initialContext, setInitialContext] = useState<{\n tenantId: string | null\n organizationId: string | null\n userId: string\n isSuperAdmin: boolean\n features: string[]\n } | null>(null)\n\n // Available entity types from search_schema - fetched when palette opens\n const [availableEntities, setAvailableEntities] = useState<Array<{\n entityId: string\n enabled: boolean\n }> | null>(null)\n\n // Debug mode state\n const [debugEvents, setDebugEvents] = useState<DebugEvent[]>([])\n const [showDebug, setShowDebug] = useState(false)\n\n // OpenCode session state for conversation persistence\n // Use both state (for React reactivity) and ref (to avoid stale closures in callbacks)\n const [opencodeSessionId, setOpencodeSessionId] = useState<string | null>(null)\n const opencodeSessionIdRef = useRef<string | null>(null)\n const [isThinking, setIsThinking] = useState(false)\n const [agentStatus, setAgentStatus] = useState<AgentStatus>({ type: 'idle' })\n const [isSessionAuthorized, setIsSessionAuthorized] = useState(false)\n\n // Pending question from OpenCode requiring user confirmation\n const [pendingQuestion, setPendingQuestion] = useState<OpenCodeQuestion | null>(null)\n\n // Track answered question IDs to prevent re-showing them\n const answeredQuestionIds = useRef<Set<string>>(new Set())\n\n // Flag to indicate the next text event should start a new message (after answering question)\n const shouldStartNewMessage = useRef<boolean>(false)\n\n // AbortController for current streaming request - allows canceling when answering questions\n const currentStreamController = useRef<AbortController | null>(null)\n\n // Wrapper to update both state and ref for opencodeSessionId\n // This ensures the ref is always in sync and callbacks get the latest value\n const updateOpencodeSessionId = useCallback((id: string | null) => {\n opencodeSessionIdRef.current = id\n setOpencodeSessionId(id)\n }, [])\n\n // Helper to add debug events\n const addDebugEvent = useCallback((type: DebugEventType, data: unknown) => {\n // Deep clone the data to capture state at this moment (prevents mutation issues)\n const clonedData = JSON.parse(JSON.stringify(data))\n setDebugEvents((prev) => [\n ...prev.slice(-999), // Keep last 1000 events\n {\n id: generateId(),\n timestamp: new Date(),\n type,\n data: clonedData,\n },\n ])\n }, [])\n\n const clearDebugEvents = useCallback(() => {\n setDebugEvents([])\n }, [])\n\n // Update connection status when tools load\n useEffect(() => {\n if (toolsLoading) {\n setState((prev) => ({ ...prev, connectionStatus: 'connecting' }))\n } else if (tools.length > 0) {\n setState((prev) => ({ ...prev, connectionStatus: 'connected' }))\n } else {\n setState((prev) => ({ ...prev, connectionStatus: 'disconnected' }))\n }\n }, [tools, toolsLoading])\n\n // Fetch initial context and entity schema when palette opens and tools are available\n useEffect(() => {\n if (state.isOpen && tools.length > 0) {\n // Fetch auth context if not already loaded\n if (!initialContext) {\n console.log('[CommandPalette] Fetching initial context via context_whoami...')\n executeToolApi('context_whoami', {})\n .then((result) => {\n if (result.success && result.result) {\n console.log('[CommandPalette] Got initial context:', result.result)\n const ctx = result.result as {\n tenantId: string | null\n organizationId: string | null\n userId: string\n isSuperAdmin: boolean\n features: string[]\n }\n setInitialContext(ctx)\n }\n })\n .catch((err) => {\n console.error('[CommandPalette] Failed to fetch initial context:', err)\n })\n }\n\n // Fetch available entity types if not already loaded\n if (!availableEntities) {\n console.log('[CommandPalette] Fetching available entities via search_schema...')\n executeToolApi('search_schema', {})\n .then((result) => {\n if (result.success && result.result) {\n const schemaResult = result.result as { entities?: Array<{ entityId: string; enabled: boolean }> }\n console.log('[CommandPalette] Got entity schema:', schemaResult.entities?.length, 'entities')\n if (schemaResult.entities) {\n setAvailableEntities(schemaResult.entities.filter(e => e.enabled))\n }\n }\n })\n .catch((err) => {\n console.error('[CommandPalette] Failed to fetch entity schema:', err)\n })\n }\n }\n }, [state.isOpen, tools.length, initialContext, availableEntities, executeToolApi])\n\n // Filtered tools based on input\n const filteredTools = useMemo(() => {\n const query = state.inputValue.startsWith('/') ? state.inputValue.slice(1) : state.inputValue\n return filterTools(tools, query)\n }, [tools, state.inputValue])\n\n // Listen for global open-chat event (from settings page, etc.)\n useEffect(() => {\n const handleOpenChat = () => {\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }\n\n window.addEventListener('om:open-ai-chat', handleOpenChat)\n return () => window.removeEventListener('om:open-ai-chat', handleOpenChat)\n }, [])\n\n // Keyboard shortcut handler\n useEffect(() => {\n if (disableKeyboardShortcut) return\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Open/close with Cmd+K or Ctrl+K\n if (\n (event.metaKey || event.ctrlKey) &&\n event.key.toLowerCase() === AI_CHAT_SHORTCUT.key\n ) {\n event.preventDefault()\n setState((prev) => {\n if (prev.isOpen) {\n // Closing - reset to idle\n return {\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }\n } else {\n // Opening\n return {\n ...prev,\n isOpen: true,\n }\n }\n })\n // Reset selected tool when closing\n if (state.isOpen) {\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }\n\n // Open directly to AI chat mode with Cmd+J or Ctrl+J (only if enabled)\n if (\n (event.metaKey || event.ctrlKey) &&\n event.key.toLowerCase() === AI_CHAT_SHORTCUT.key\n ) {\n // Skip if AI assistant is disabled (but allow closing if already open)\n if (!isAiAssistantEnabled && !state.isOpen) {\n return\n }\n event.preventDefault()\n if (state.isOpen) {\n // Already open - close it\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n } else {\n // Open directly in chatting phase\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }\n }\n\n // Escape - reset or close\n if (event.key === 'Escape' && state.isOpen) {\n event.preventDefault()\n if (state.phase !== 'idle') {\n // Reset to idle\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n } else {\n // Close palette\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [state.isOpen, state.phase, state.inputValue, disableKeyboardShortcut, isAiAssistantEnabled])\n\n // Actions\n const open = useCallback(() => {\n setState((prev) => ({ ...prev, isOpen: true }))\n }, [])\n\n // Open directly in chat mode (for Cmd+J / header button)\n const openChat = useCallback(() => {\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }, [])\n\n const close = useCallback(() => {\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n updateOpencodeSessionId(null)\n setIsSessionAuthorized(false)\n setAgentStatus({ type: 'idle' })\n // Don't reset initialContext - it stays valid for the session\n }, [updateOpencodeSessionId])\n\n // Reset to idle state (without closing)\n const reset = useCallback(() => {\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n updateOpencodeSessionId(null)\n setIsSessionAuthorized(false)\n setAgentStatus({ type: 'idle' })\n }, [updateOpencodeSessionId])\n\n const setIsOpen = useCallback(\n (isOpen: boolean) => {\n if (isOpen) {\n open()\n } else {\n close()\n }\n },\n [open, close]\n )\n\n const setMode = useCallback((mode: CommandPaletteMode) => {\n setState((prev) => ({ ...prev, mode }))\n }, [])\n\n const setInputValue = useCallback((value: string) => {\n setState((prev) => ({ ...prev, inputValue: value, selectedIndex: 0 }))\n }, [])\n\n const setSelectedIndex = useCallback((index: number) => {\n setState((prev) => ({ ...prev, selectedIndex: index }))\n }, [])\n\n // Page navigation - go to tool chat\n const goToToolChat = useCallback(\n (tool: ToolInfo) => {\n setSelectedTool(tool)\n saveRecentTool(tool.name)\n\n // Create initial assistant message\n const initialMessage: ChatMessage = {\n id: generateId(),\n role: 'assistant',\n content: `I'll help you with \"${tool.name}\". ${getToolPrompt(tool)}`,\n createdAt: new Date(),\n }\n setMessages([initialMessage])\n setPendingToolCalls([])\n\n setState((prev) => ({\n ...prev,\n page: 'tool-chat',\n inputValue: '',\n selectedIndex: 0,\n mode: 'chat',\n }))\n },\n [saveRecentTool]\n )\n\n // Page navigation - go back (legacy, kept for compatibility)\n const goBack = useCallback(() => {\n if (state.phase !== 'idle') {\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n page: 'home',\n inputValue: '',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }, [state.phase])\n\n // Route query using fast model\n const routeQuery = useCallback(\n async (query: string): Promise<RouteResult> => {\n const response = await fetch('/api/ai_assistant/route', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query,\n availableTools: tools.map((t) => ({\n name: t.name,\n description: t.description,\n })),\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Routing failed: ${response.status}`)\n }\n\n return response.json()\n },\n [tools]\n )\n\n // Start agentic chat - AI has access to all tools\n const startAgenticChat = useCallback(\n async (initialQuery: string) => {\n setState((prev) => ({\n ...prev,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n\n // Send the initial query to the chat API\n setState((prev) => ({ ...prev, isStreaming: true }))\n setAgentStatus({ type: 'thinking' })\n\n try {\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: initialQuery,\n createdAt: new Date(),\n }\n setMessages([userMessage])\n\n // Create abort controller for this stream\n currentStreamController.current?.abort()\n const controller = new AbortController()\n currentStreamController.current = controller\n\n const response = await fetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: initialQuery }],\n context: pageContext,\n authContext: initialContext,\n availableEntities: availableEntities?.map(e => e.entityId),\n mode: 'agentic',\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[startAgenticChat] Error response body:', errorText)\n throw new Error(`Chat request failed: ${response.status} - ${errorText}`)\n }\n\n // Process the SSE stream\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n let buffer = ''\n let chunkCount = 0\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n chunkCount++\n const rawChunk = decoder.decode(value, { stream: true })\n buffer += rawChunk\n\n const lines = buffer.split('\\n')\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data === '[DONE]') continue\n\n try {\n const event = JSON.parse(data)\n\n\n // Track all events for debug panel (except question - handled separately with enriched data)\n if (event.type !== 'question') {\n addDebugEvent(event.type as DebugEventType, event)\n }\n\n if (event.type === 'text') {\n // Text received - now responding\n setIsThinking(false)\n setAgentStatus({ type: 'responding' })\n\n // Check if we need to start a new message (e.g., after answering a question)\n if (shouldStartNewMessage.current) {\n shouldStartNewMessage.current = false\n // Finalize the current streaming message and reset content\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n assistantContent = '' // Reset for new message\n }\n\n assistantContent += event.content || ''\n setMessages((prev) => {\n const existingAssistant = prev.find((m) => m.id === 'streaming')\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n } else if (event.type === 'tool-call') {\n // Tool calls are executed SERVER-SIDE via the AI SDK's maxSteps feature\n const toolName = event.toolName as string\n const toolArgs = event.args ?? {}\n\n // Update status to show the tool being used\n setAgentStatus({ type: 'tool', toolName })\n\n // For dangerous tools, show a confirmation indicator\n if (!isToolSafeToAutoExecute(toolName)) {\n // Note: Server already executed this - just show visual feedback\n setPendingToolCalls((prev) => [\n ...prev,\n {\n id: event.id,\n toolName: toolName,\n args: toolArgs,\n status: 'completed' as const, // Already executed server-side\n },\n ])\n }\n // Safe tools: no action needed, server handled execution and AI interprets results\n } else if (event.type === 'debug') {\n // Handle debug events for agent status updates\n const debugEvent = event as { partType?: string; data?: Record<string, unknown> }\n\n // Handle step-start: indicates tool execution beginning\n if (debugEvent.partType === 'step-start') {\n setAgentStatus({ type: 'executing' })\n }\n // Handle step-finish: tools completed\n if (debugEvent.partType === 'step-finish' && debugEvent.data?.reason === 'tool-calls') {\n // Tools finished, back to thinking for next step\n setAgentStatus({ type: 'thinking' })\n }\n } else if (event.type === 'error') {\n console.error('[startAgenticChat] Error event:', event.error)\n setAgentStatus({ type: 'idle' })\n } else if (event.type === 'done') {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n // Save session ID for conversation continuity\n if (event.sessionId) {\n updateOpencodeSessionId(event.sessionId)\n }\n } else if (event.type === 'question') {\n // OpenCode is asking for confirmation\n const question = event.question as OpenCodeQuestion\n // Skip if already answered\n if (answeredQuestionIds.current.has(question.id)) {\n // Already answered\n } else {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n setPendingQuestion(question)\n // Save session ID for conversation continuity\n if (question.sessionID) {\n updateOpencodeSessionId(question.sessionID)\n }\n // Add enriched debug event with question details visible at top level\n addDebugEvent('question', {\n type: 'question',\n questionId: question.id,\n sessionID: question.sessionID,\n questionText: question.questions?.[0]?.question || 'No question text',\n header: question.questions?.[0]?.header || 'Confirmation',\n options: question.questions?.[0]?.options?.map(o => o.label) || [],\n fullQuestion: question,\n })\n }\n } else if (event.type === 'session-authorized') {\n // Session has been authorized with ephemeral API key\n setIsSessionAuthorized(true)\n }\n } catch (parseError) {\n console.warn('[startAgenticChat] Failed to parse event:', data, parseError)\n }\n }\n }\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n // Ignore AbortError - this happens when we intentionally cancel the stream\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n console.error('[startAgenticChat] Error:', error)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n setAgentStatus({ type: 'idle' })\n }\n },\n [pageContext, initialContext, availableEntities, executeToolApi, addDebugEvent, updateOpencodeSessionId]\n )\n\n // Start general chat (no specific tool)\n const startGeneralChat = useCallback(\n async (initialQuery: string) => {\n setState((prev) => ({\n ...prev,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n\n setState((prev) => ({ ...prev, isStreaming: true }))\n\n try {\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: initialQuery,\n createdAt: new Date(),\n }\n setMessages([userMessage])\n\n const response = await fetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: initialQuery }],\n context: pageContext,\n authContext: initialContext,\n availableEntities: availableEntities?.map(e => e.entityId),\n mode: 'default',\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n assistantContent += chunk\n\n setMessages((prev) => {\n const existingAssistant = prev.find((m) => m.id === 'streaming')\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n console.error('General chat error:', error)\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n }\n },\n [pageContext, initialContext, availableEntities]\n )\n\n // Execute tool directly\n const executeTool = useCallback(\n async (toolName: string, args: Record<string, unknown> = {}): Promise<ToolExecutionResult> => {\n setState((prev) => ({ ...prev, isLoading: true }))\n\n try {\n const result = await executeToolApi(toolName, args)\n\n if (result.success) {\n // Add to recent actions\n const tool = tools.find((t) => t.name === toolName)\n addRecentAction({\n toolName,\n displayName: tool?.description || toolName,\n args,\n })\n }\n\n return result\n } finally {\n setState((prev) => ({ ...prev, isLoading: false }))\n }\n },\n [executeToolApi, tools, addRecentAction]\n )\n\n // Approve a pending tool call\n const approveToolCall = useCallback(\n async (toolCallId: string) => {\n const toolCall = pendingToolCalls.find((tc) => tc.id === toolCallId)\n if (!toolCall) return\n\n // Update status to executing\n setPendingToolCalls((prev) =>\n prev.map((tc) => (tc.id === toolCallId ? { ...tc, status: 'executing' as const } : tc))\n )\n\n try {\n // Execute the tool\n const result = await executeToolApi(toolCall.toolName, toolCall.args)\n\n // Update tool call with result\n setPendingToolCalls((prev) =>\n prev.map((tc) =>\n tc.id === toolCallId\n ? {\n ...tc,\n status: result.success ? ('completed' as const) : ('error' as const),\n result: result.result,\n error: result.error,\n }\n : tc\n )\n )\n\n // Add to recent actions on success, show error on failure\n // Don't add raw JSON - the AI will provide human-friendly interpretation\n if (result.success) {\n const tool = tools.find((t) => t.name === toolCall.toolName)\n addRecentAction({\n toolName: toolCall.toolName,\n displayName: tool?.description || toolCall.toolName,\n args: toolCall.args,\n })\n // Add a brief success indicator (optional - AI can interpret the result)\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Done! The ${toolCall.toolName.replace(/_/g, ' ')} operation completed successfully.`,\n createdAt: new Date(),\n },\n ])\n } else {\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `I encountered an issue: ${result.error || 'Unknown error'}`,\n createdAt: new Date(),\n },\n ])\n }\n } catch (error) {\n setPendingToolCalls((prev) =>\n prev.map((tc) =>\n tc.id === toolCallId\n ? {\n ...tc,\n status: 'error' as const,\n error: error instanceof Error ? error.message : 'Unknown error',\n }\n : tc\n )\n )\n }\n },\n [pendingToolCalls, executeToolApi, tools, addRecentAction]\n )\n\n // Reject a pending tool call\n const rejectToolCall = useCallback((toolCallId: string) => {\n setPendingToolCalls((prev) =>\n prev.map((tc) => (tc.id === toolCallId ? { ...tc, status: 'rejected' as const } : tc))\n )\n\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: 'Tool call cancelled. How else can I help?',\n createdAt: new Date(),\n },\n ])\n }, [])\n\n // Send message in agentic chat (via OpenCode agent)\n const sendAgenticMessage = useCallback(\n async (content: string) => {\n if (!content.trim()) return\n\n // Add user message\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: content.trim(),\n createdAt: new Date(),\n }\n setMessages((prev) => [...prev, userMessage])\n setState((prev) => ({ ...prev, isStreaming: true }))\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n\n try {\n // Create abort controller for this stream\n currentStreamController.current?.abort()\n const controller = new AbortController()\n currentStreamController.current = controller\n\n // Send to chat API with OpenCode session for context persistence\n const response = await fetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n sessionId: opencodeSessionIdRef.current,\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n // Read the streaming response\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n let buffer = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE events\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data === '[DONE]') continue\n\n try {\n const event = JSON.parse(data)\n\n\n // Track all events for debug panel (except question - handled separately with enriched data)\n if (event.type !== 'question') {\n addDebugEvent(event.type as DebugEventType, event)\n }\n\n if (event.type === 'thinking') {\n // OpenCode is processing - keep thinking state active\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n } else if (event.type === 'session-authorized') {\n // Session has been authorized with ephemeral API key\n setIsSessionAuthorized(true)\n } else if (event.type === 'text') {\n // Check if we need to start a new message (e.g., after answering a question)\n if (shouldStartNewMessage.current) {\n shouldStartNewMessage.current = false\n // Finalize the current streaming message and reset content\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n assistantContent = '' // Reset for new message\n }\n\n // Text received - now responding\n setIsThinking(false)\n setAgentStatus({ type: 'responding' })\n assistantContent += event.content || ''\n // Update assistant message in real-time\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n } else if (event.type === 'done') {\n // Stream complete - save session ID for conversation persistence\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n if (event.sessionId) {\n updateOpencodeSessionId(event.sessionId)\n }\n } else if (event.type === 'error') {\n // Handle error event\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Error: ${event.error || 'Unknown error occurred'}`,\n createdAt: new Date(),\n },\n ])\n } else if (event.type === 'tool-call') {\n // Tool calls are executed SERVER-SIDE via the AI SDK's maxSteps feature\n const toolName = event.toolName as string\n const toolArgs = event.args ?? {}\n\n // Update status to show the tool being used\n setAgentStatus({ type: 'tool', toolName })\n\n // For dangerous tools, show visual feedback (server already executed)\n if (!isToolSafeToAutoExecute(toolName)) {\n setPendingToolCalls((prev) => [\n ...prev,\n { id: event.id, toolName, args: toolArgs, status: 'completed' as const },\n ])\n }\n // Safe tools: no action needed, server handled execution\n } else if (event.type === 'question') {\n // OpenCode is asking for confirmation\n const question = event.question as OpenCodeQuestion\n // Skip if already answered\n if (answeredQuestionIds.current.has(question.id)) {\n // Already answered\n } else {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n setPendingQuestion(question)\n // Add enriched debug event with question details visible at top level\n addDebugEvent('question', {\n type: 'question',\n questionId: question.id,\n sessionID: question.sessionID,\n questionText: question.questions?.[0]?.question || 'No question text',\n header: question.questions?.[0]?.header || 'Confirmation',\n options: question.questions?.[0]?.options?.map(o => o.label) || [],\n fullQuestion: question,\n })\n }\n } else if (event.type === 'debug') {\n // Handle debug events for agent status updates\n const debugEvent = event as { partType?: string; data?: Record<string, unknown> }\n\n // Handle step-start: indicates tool execution beginning\n if (debugEvent.partType === 'step-start') {\n setAgentStatus({ type: 'executing' })\n }\n // Handle step-finish: tools completed\n if (debugEvent.partType === 'step-finish' && debugEvent.data?.reason === 'tool-calls') {\n // Tools finished, back to thinking for next step\n setAgentStatus({ type: 'thinking' })\n }\n }\n } catch {\n // Plain text chunk (fallback for non-SSE responses)\n assistantContent += data\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n } else if (line.trim() && !line.startsWith(':')) {\n // Plain text (not SSE format)\n assistantContent += line\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n }\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n // Ignore AbortError - this happens when we intentionally cancel the stream\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n console.error('Tool chat error:', error)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n }\n },\n [messages, addDebugEvent, updateOpencodeSessionId]\n )\n\n // Main submit handler - starts agentic chat or continues existing session\n const handleSubmit = useCallback(\n async (query: string) => {\n if (!query.trim()) return\n\n // If we have an existing session, continue the conversation\n // Use ref to get latest value (avoids stale closure issues)\n if (opencodeSessionIdRef.current) {\n await sendAgenticMessage(query)\n } else {\n // Start new agentic session where AI has access to all tools\n await startAgenticChat(query)\n }\n },\n [startAgenticChat, sendAgenticMessage]\n )\n\n // Answer a pending OpenCode question\n // The original SSE stream continues running and will receive the follow-up response\n const answerQuestion = useCallback(\n async (answer: number) => {\n if (!pendingQuestion) return\n\n // Mark question as answered BEFORE sending - prevents duplicate display\n const questionId = pendingQuestion.id\n answeredQuestionIds.current.add(questionId)\n\n // Signal that the next text event should start a NEW message (not update the old one)\n shouldStartNewMessage.current = true\n\n // Clear the pending question UI and show thinking state\n setPendingQuestion(null)\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n\n // Add visual feedback of the answer\n const selectedOption = pendingQuestion.questions[0]?.options[answer]\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'user' as const,\n content: `[Confirmed: ${selectedOption?.label || 'Yes'}]`,\n createdAt: new Date(),\n },\n ])\n\n try {\n // Send answer as simple POST - the original SSE stream will receive the follow-up\n const sessionId = pendingQuestion.sessionID\n const response = await fetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n answerQuestion: {\n questionId,\n answer,\n sessionId,\n },\n }),\n })\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n throw new Error(errorData.error || `Answer request failed: ${response.status}`)\n }\n\n // Answer sent successfully - the original stream will handle the response\n // Note: isThinking stays true until the original stream sends 'done' or more 'text'\n } catch (error) {\n console.error('[answerQuestion] Error:', error)\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Error: ${error instanceof Error ? error.message : 'Failed to send answer'}`,\n createdAt: new Date(),\n },\n ])\n }\n },\n [pendingQuestion]\n )\n\n // Legacy sendMessage function (for backwards compatibility)\n const sendMessage = useCallback(\n async (content: string) => {\n if (!content.trim()) return\n\n // Add user message\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: content.trim(),\n createdAt: new Date(),\n }\n setMessages((prev) => [...prev, userMessage])\n setState((prev) => ({ ...prev, isStreaming: true }))\n\n try {\n // Send to chat API\n const response = await fetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n context: pageContext,\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n // Read the streaming response\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n assistantContent += chunk\n\n // Update assistant message in real-time\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n console.error('Chat error:', error)\n // Add error message\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n }\n },\n [messages, pageContext]\n )\n\n const clearMessages = useCallback(() => {\n setMessages([])\n setPendingToolCalls([])\n }, [])\n\n // Stop/cancel the current streaming execution\n const stopExecution = useCallback(() => {\n // Abort the current stream\n currentStreamController.current?.abort()\n currentStreamController.current = null\n\n // Reset streaming state\n setState((prev) => ({ ...prev, isStreaming: false }))\n setAgentStatus({ type: 'idle' })\n setIsThinking(false)\n\n // Add cancellation message to chat\n setMessages((prev) => [\n ...prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)), // Finalize any streaming message\n {\n id: generateId(),\n role: 'system' as const,\n content: 'Execution stopped by user.',\n createdAt: new Date(),\n },\n ])\n }, [])\n\n return {\n // State\n state: {\n ...state,\n isLoading: state.isLoading || toolsLoading,\n },\n isThinking,\n agentStatus,\n isSessionAuthorized,\n pageContext,\n selectedEntities,\n tools,\n filteredTools,\n recentActions,\n recentTools,\n messages,\n pendingToolCalls,\n selectedTool,\n initialContext,\n availableEntities,\n\n // Navigation actions\n open,\n openChat,\n close,\n setIsOpen,\n setInputValue,\n setSelectedIndex,\n\n // Intelligent routing - submit natural language query\n handleSubmit,\n reset,\n\n // Page navigation (legacy, kept for compatibility)\n goToToolChat,\n goBack,\n\n // Tool execution\n executeTool,\n approveToolCall,\n rejectToolCall,\n\n // Chat actions\n sendMessage,\n sendAgenticMessage,\n clearMessages,\n stopExecution,\n\n // Legacy compatibility\n setMode,\n\n // Debug mode\n debugEvents,\n showDebug,\n setShowDebug,\n clearDebugEvents,\n\n // OpenCode question handling\n pendingQuestion,\n answerQuestion,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react'\nimport type {\n AgentStatus,\n CommandPaletteMode,\n CommandPalettePage,\n CommandPaletteState,\n ConnectionStatus,\n PalettePhase,\n PageContext,\n SelectedEntity,\n ToolInfo,\n ToolExecutionResult,\n PendingToolCall,\n ChatMessage,\n RouteResult,\n DebugEvent,\n DebugEventType,\n OpenCodeQuestion,\n} from '../types'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { COMMAND_PALETTE_SHORTCUT, AI_CHAT_SHORTCUT } from '../constants'\nimport { filterTools } from '../utils/toolMatcher'\nimport { useMcpTools } from './useMcpTools'\nimport { useRecentActions } from './useRecentActions'\nimport { useRecentTools } from './useRecentTools'\nimport { useAiAssistantVisibility } from './useAiAssistantVisibility'\n\ninterface UseCommandPaletteOptions {\n pageContext: PageContext | null\n selectedEntities?: SelectedEntity[]\n disableKeyboardShortcut?: boolean\n}\n\nfunction generateId(): string {\n return Math.random().toString(36).substring(2, 15)\n}\n\n// Tools that are safe to auto-execute without user confirmation\nconst SAFE_TOOL_PATTERNS = [\n /^search_/, // search_query, search_schema, search_get, search_aggregate, search_status\n /^get_/, // get_ operations are read-only\n /^list_/, // list_ operations are read-only\n /^view_/, // view_ operations are read-only\n /^context_/, // context_whoami etc.\n /_get$/, // tools ending with _get\n /_list$/, // tools ending with _list\n /_status$/, // tools ending with _status\n /_schema$/, // tools ending with _schema\n]\n\n// Tools that should always require confirmation\nconst DANGEROUS_TOOL_PATTERNS = [\n /^delete_/,\n /^remove_/,\n /_delete$/,\n /_remove$/,\n /^reindex_/,\n /_reindex$/,\n]\n\nfunction isToolSafeToAutoExecute(toolName: string): boolean {\n // First check if it's a dangerous tool\n if (DANGEROUS_TOOL_PATTERNS.some(p => p.test(toolName))) {\n return false\n }\n // Then check if it matches safe patterns\n return SAFE_TOOL_PATTERNS.some(p => p.test(toolName))\n}\n\nfunction getToolPrompt(tool: ToolInfo): string {\n const schema = tool.inputSchema\n if (!schema || typeof schema !== 'object') {\n return 'What would you like to do?'\n }\n\n const properties = (schema as { properties?: Record<string, unknown> }).properties\n if (!properties || Object.keys(properties).length === 0) {\n return 'This tool has no parameters. Ready to execute?'\n }\n\n const paramNames = Object.keys(properties).slice(0, 3)\n return `Please provide the following: ${paramNames.join(', ')}.`\n}\n\nexport function useCommandPalette(options: UseCommandPaletteOptions) {\n const { pageContext, selectedEntities = [], disableKeyboardShortcut = false } = options\n\n // Check if AI assistant is enabled (for Cmd+J shortcut)\n const { isEnabled: isAiAssistantEnabled } = useAiAssistantVisibility()\n\n // Core state with phase-based navigation for intelligent routing\n const [state, setState] = useState<CommandPaletteState>({\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n selectedIndex: 0,\n isLoading: false,\n isStreaming: false,\n connectionStatus: 'disconnected',\n // Legacy fields for backwards compatibility\n page: 'home',\n mode: 'commands',\n })\n\n // Tool-related hooks\n const { tools, isLoading: toolsLoading, executeTool: executeToolApi } = useMcpTools()\n const { recentActions, addRecentAction } = useRecentActions()\n const { recentTools, saveRecentTool } = useRecentTools(tools)\n\n // Selected tool for tool-chat page\n const [selectedTool, setSelectedTool] = useState<ToolInfo | null>(null)\n\n // Chat state for tool-chat page\n const [messages, setMessages] = useState<ChatMessage[]>([])\n const [pendingToolCalls, setPendingToolCalls] = useState<PendingToolCall[]>([])\n\n // Initial context from context_whoami - fetched when palette opens\n const [initialContext, setInitialContext] = useState<{\n tenantId: string | null\n organizationId: string | null\n userId: string\n isSuperAdmin: boolean\n features: string[]\n } | null>(null)\n\n // Available entity types from search_schema - fetched when palette opens\n const [availableEntities, setAvailableEntities] = useState<Array<{\n entityId: string\n enabled: boolean\n }> | null>(null)\n\n // Debug mode state\n const [debugEvents, setDebugEvents] = useState<DebugEvent[]>([])\n const [showDebug, setShowDebug] = useState(false)\n\n // OpenCode session state for conversation persistence\n // Use both state (for React reactivity) and ref (to avoid stale closures in callbacks)\n const [opencodeSessionId, setOpencodeSessionId] = useState<string | null>(null)\n const opencodeSessionIdRef = useRef<string | null>(null)\n const [isThinking, setIsThinking] = useState(false)\n const [agentStatus, setAgentStatus] = useState<AgentStatus>({ type: 'idle' })\n const [isSessionAuthorized, setIsSessionAuthorized] = useState(false)\n\n // Pending question from OpenCode requiring user confirmation\n const [pendingQuestion, setPendingQuestion] = useState<OpenCodeQuestion | null>(null)\n\n // Track answered question IDs to prevent re-showing them\n const answeredQuestionIds = useRef<Set<string>>(new Set())\n\n // Flag to indicate the next text event should start a new message (after answering question)\n const shouldStartNewMessage = useRef<boolean>(false)\n\n // AbortController for current streaming request - allows canceling when answering questions\n const currentStreamController = useRef<AbortController | null>(null)\n\n // Wrapper to update both state and ref for opencodeSessionId\n // This ensures the ref is always in sync and callbacks get the latest value\n const updateOpencodeSessionId = useCallback((id: string | null) => {\n opencodeSessionIdRef.current = id\n setOpencodeSessionId(id)\n }, [])\n\n // Helper to add debug events\n const addDebugEvent = useCallback((type: DebugEventType, data: unknown) => {\n // Deep clone the data to capture state at this moment (prevents mutation issues)\n const clonedData = JSON.parse(JSON.stringify(data))\n setDebugEvents((prev) => [\n ...prev.slice(-999), // Keep last 1000 events\n {\n id: generateId(),\n timestamp: new Date(),\n type,\n data: clonedData,\n },\n ])\n }, [])\n\n const clearDebugEvents = useCallback(() => {\n setDebugEvents([])\n }, [])\n\n // Update connection status when tools load\n useEffect(() => {\n if (toolsLoading) {\n setState((prev) => ({ ...prev, connectionStatus: 'connecting' }))\n } else if (tools.length > 0) {\n setState((prev) => ({ ...prev, connectionStatus: 'connected' }))\n } else {\n setState((prev) => ({ ...prev, connectionStatus: 'disconnected' }))\n }\n }, [tools, toolsLoading])\n\n // Fetch initial context and entity schema when palette opens and tools are available\n useEffect(() => {\n if (state.isOpen && tools.length > 0) {\n // Fetch auth context if not already loaded\n if (!initialContext) {\n console.log('[CommandPalette] Fetching initial context via context_whoami...')\n executeToolApi('context_whoami', {})\n .then((result) => {\n if (result.success && result.result) {\n console.log('[CommandPalette] Got initial context:', result.result)\n const ctx = result.result as {\n tenantId: string | null\n organizationId: string | null\n userId: string\n isSuperAdmin: boolean\n features: string[]\n }\n setInitialContext(ctx)\n }\n })\n .catch((err) => {\n console.error('[CommandPalette] Failed to fetch initial context:', err)\n })\n }\n\n // Fetch available entity types if not already loaded\n if (!availableEntities) {\n console.log('[CommandPalette] Fetching available entities via search_schema...')\n executeToolApi('search_schema', {})\n .then((result) => {\n if (result.success && result.result) {\n const schemaResult = result.result as { entities?: Array<{ entityId: string; enabled: boolean }> }\n console.log('[CommandPalette] Got entity schema:', schemaResult.entities?.length, 'entities')\n if (schemaResult.entities) {\n setAvailableEntities(schemaResult.entities.filter(e => e.enabled))\n }\n }\n })\n .catch((err) => {\n console.error('[CommandPalette] Failed to fetch entity schema:', err)\n })\n }\n }\n }, [state.isOpen, tools.length, initialContext, availableEntities, executeToolApi])\n\n // Filtered tools based on input\n const filteredTools = useMemo(() => {\n const query = state.inputValue.startsWith('/') ? state.inputValue.slice(1) : state.inputValue\n return filterTools(tools, query)\n }, [tools, state.inputValue])\n\n // Listen for global open-chat event (from settings page, etc.)\n useEffect(() => {\n const handleOpenChat = () => {\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }\n\n window.addEventListener('om:open-ai-chat', handleOpenChat)\n return () => window.removeEventListener('om:open-ai-chat', handleOpenChat)\n }, [])\n\n // Keyboard shortcut handler\n useEffect(() => {\n if (disableKeyboardShortcut) return\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Open/close with Cmd+K or Ctrl+K\n if (\n (event.metaKey || event.ctrlKey) &&\n event.key.toLowerCase() === AI_CHAT_SHORTCUT.key\n ) {\n event.preventDefault()\n setState((prev) => {\n if (prev.isOpen) {\n // Closing - reset to idle\n return {\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }\n } else {\n // Opening\n return {\n ...prev,\n isOpen: true,\n }\n }\n })\n // Reset selected tool when closing\n if (state.isOpen) {\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }\n\n // Open directly to AI chat mode with Cmd+J or Ctrl+J (only if enabled)\n if (\n (event.metaKey || event.ctrlKey) &&\n event.key.toLowerCase() === AI_CHAT_SHORTCUT.key\n ) {\n // Skip if AI assistant is disabled (but allow closing if already open)\n if (!isAiAssistantEnabled && !state.isOpen) {\n return\n }\n event.preventDefault()\n if (state.isOpen) {\n // Already open - close it\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n } else {\n // Open directly in chatting phase\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }\n }\n\n // Escape - reset or close\n if (event.key === 'Escape' && state.isOpen) {\n event.preventDefault()\n if (state.phase !== 'idle') {\n // Reset to idle\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n } else {\n // Close palette\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, [state.isOpen, state.phase, state.inputValue, disableKeyboardShortcut, isAiAssistantEnabled])\n\n // Actions\n const open = useCallback(() => {\n setState((prev) => ({ ...prev, isOpen: true }))\n }, [])\n\n // Open directly in chat mode (for Cmd+J / header button)\n const openChat = useCallback(() => {\n setState((prev) => ({\n ...prev,\n isOpen: true,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n }, [])\n\n const close = useCallback(() => {\n setState((prev) => ({\n ...prev,\n isOpen: false,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n updateOpencodeSessionId(null)\n setIsSessionAuthorized(false)\n setAgentStatus({ type: 'idle' })\n // Don't reset initialContext - it stays valid for the session\n }, [updateOpencodeSessionId])\n\n // Reset to idle state (without closing)\n const reset = useCallback(() => {\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n inputValue: '',\n page: 'home',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n updateOpencodeSessionId(null)\n setIsSessionAuthorized(false)\n setAgentStatus({ type: 'idle' })\n }, [updateOpencodeSessionId])\n\n const setIsOpen = useCallback(\n (isOpen: boolean) => {\n if (isOpen) {\n open()\n } else {\n close()\n }\n },\n [open, close]\n )\n\n const setMode = useCallback((mode: CommandPaletteMode) => {\n setState((prev) => ({ ...prev, mode }))\n }, [])\n\n const setInputValue = useCallback((value: string) => {\n setState((prev) => ({ ...prev, inputValue: value, selectedIndex: 0 }))\n }, [])\n\n const setSelectedIndex = useCallback((index: number) => {\n setState((prev) => ({ ...prev, selectedIndex: index }))\n }, [])\n\n // Page navigation - go to tool chat\n const goToToolChat = useCallback(\n (tool: ToolInfo) => {\n setSelectedTool(tool)\n saveRecentTool(tool.name)\n\n // Create initial assistant message\n const initialMessage: ChatMessage = {\n id: generateId(),\n role: 'assistant',\n content: `I'll help you with \"${tool.name}\". ${getToolPrompt(tool)}`,\n createdAt: new Date(),\n }\n setMessages([initialMessage])\n setPendingToolCalls([])\n\n setState((prev) => ({\n ...prev,\n page: 'tool-chat',\n inputValue: '',\n selectedIndex: 0,\n mode: 'chat',\n }))\n },\n [saveRecentTool]\n )\n\n // Page navigation - go back (legacy, kept for compatibility)\n const goBack = useCallback(() => {\n if (state.phase !== 'idle') {\n setState((prev) => ({\n ...prev,\n phase: 'idle',\n page: 'home',\n inputValue: '',\n selectedIndex: 0,\n mode: 'commands',\n }))\n setSelectedTool(null)\n setMessages([])\n setPendingToolCalls([])\n }\n }, [state.phase])\n\n // Route query using fast model\n const routeQuery = useCallback(\n async (query: string): Promise<RouteResult> => {\n const { ok, result, status } = await apiCall<RouteResult>('/api/ai_assistant/route', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query,\n availableTools: tools.map((t) => ({\n name: t.name,\n description: t.description,\n })),\n }),\n })\n\n if (!ok) {\n throw new Error(`Routing failed: ${status}`)\n }\n\n if (!result) {\n throw new Error('Routing returned empty response')\n }\n\n return result\n },\n [tools]\n )\n\n // Start agentic chat - AI has access to all tools\n const startAgenticChat = useCallback(\n async (initialQuery: string) => {\n setState((prev) => ({\n ...prev,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n\n // Send the initial query to the chat API\n setState((prev) => ({ ...prev, isStreaming: true }))\n setAgentStatus({ type: 'thinking' })\n\n try {\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: initialQuery,\n createdAt: new Date(),\n }\n setMessages([userMessage])\n\n // Create abort controller for this stream\n currentStreamController.current?.abort()\n const controller = new AbortController()\n currentStreamController.current = controller\n\n const response = await apiFetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: initialQuery }],\n context: pageContext,\n authContext: initialContext,\n availableEntities: availableEntities?.map(e => e.entityId),\n mode: 'agentic',\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[startAgenticChat] Error response body:', errorText)\n throw new Error(`Chat request failed: ${response.status} - ${errorText}`)\n }\n\n // Process the SSE stream\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n let buffer = ''\n let chunkCount = 0\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n chunkCount++\n const rawChunk = decoder.decode(value, { stream: true })\n buffer += rawChunk\n\n const lines = buffer.split('\\n')\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data === '[DONE]') continue\n\n try {\n const event = JSON.parse(data)\n\n\n // Track all events for debug panel (except question - handled separately with enriched data)\n if (event.type !== 'question') {\n addDebugEvent(event.type as DebugEventType, event)\n }\n\n if (event.type === 'text') {\n // Text received - now responding\n setIsThinking(false)\n setAgentStatus({ type: 'responding' })\n\n // Check if we need to start a new message (e.g., after answering a question)\n if (shouldStartNewMessage.current) {\n shouldStartNewMessage.current = false\n // Finalize the current streaming message and reset content\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n assistantContent = '' // Reset for new message\n }\n\n assistantContent += event.content || ''\n setMessages((prev) => {\n const existingAssistant = prev.find((m) => m.id === 'streaming')\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n } else if (event.type === 'tool-call') {\n // Tool calls are executed SERVER-SIDE via the AI SDK's maxSteps feature\n const toolName = event.toolName as string\n const toolArgs = event.args ?? {}\n\n // Update status to show the tool being used\n setAgentStatus({ type: 'tool', toolName })\n\n // For dangerous tools, show a confirmation indicator\n if (!isToolSafeToAutoExecute(toolName)) {\n // Note: Server already executed this - just show visual feedback\n setPendingToolCalls((prev) => [\n ...prev,\n {\n id: event.id,\n toolName: toolName,\n args: toolArgs,\n status: 'completed' as const, // Already executed server-side\n },\n ])\n }\n // Safe tools: no action needed, server handled execution and AI interprets results\n } else if (event.type === 'debug') {\n // Handle debug events for agent status updates\n const debugEvent = event as { partType?: string; data?: Record<string, unknown> }\n\n // Handle step-start: indicates tool execution beginning\n if (debugEvent.partType === 'step-start') {\n setAgentStatus({ type: 'executing' })\n }\n // Handle step-finish: tools completed\n if (debugEvent.partType === 'step-finish' && debugEvent.data?.reason === 'tool-calls') {\n // Tools finished, back to thinking for next step\n setAgentStatus({ type: 'thinking' })\n }\n } else if (event.type === 'error') {\n console.error('[startAgenticChat] Error event:', event.error)\n setAgentStatus({ type: 'idle' })\n } else if (event.type === 'done') {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n // Save session ID for conversation continuity\n if (event.sessionId) {\n updateOpencodeSessionId(event.sessionId)\n }\n } else if (event.type === 'question') {\n // OpenCode is asking for confirmation\n const question = event.question as OpenCodeQuestion\n // Skip if already answered\n if (answeredQuestionIds.current.has(question.id)) {\n // Already answered\n } else {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n setPendingQuestion(question)\n // Save session ID for conversation continuity\n if (question.sessionID) {\n updateOpencodeSessionId(question.sessionID)\n }\n // Add enriched debug event with question details visible at top level\n addDebugEvent('question', {\n type: 'question',\n questionId: question.id,\n sessionID: question.sessionID,\n questionText: question.questions?.[0]?.question || 'No question text',\n header: question.questions?.[0]?.header || 'Confirmation',\n options: question.questions?.[0]?.options?.map(o => o.label) || [],\n fullQuestion: question,\n })\n }\n } else if (event.type === 'session-authorized') {\n // Session has been authorized with ephemeral API key\n setIsSessionAuthorized(true)\n }\n } catch (parseError) {\n console.warn('[startAgenticChat] Failed to parse event:', data, parseError)\n }\n }\n }\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n // Ignore AbortError - this happens when we intentionally cancel the stream\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n console.error('[startAgenticChat] Error:', error)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n setAgentStatus({ type: 'idle' })\n }\n },\n [pageContext, initialContext, availableEntities, executeToolApi, addDebugEvent, updateOpencodeSessionId]\n )\n\n // Start general chat (no specific tool)\n const startGeneralChat = useCallback(\n async (initialQuery: string) => {\n setState((prev) => ({\n ...prev,\n phase: 'chatting',\n page: 'tool-chat',\n inputValue: '',\n mode: 'chat',\n }))\n\n setState((prev) => ({ ...prev, isStreaming: true }))\n\n try {\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: initialQuery,\n createdAt: new Date(),\n }\n setMessages([userMessage])\n\n const response = await apiFetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: initialQuery }],\n context: pageContext,\n authContext: initialContext,\n availableEntities: availableEntities?.map(e => e.entityId),\n mode: 'default',\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n assistantContent += chunk\n\n setMessages((prev) => {\n const existingAssistant = prev.find((m) => m.id === 'streaming')\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n console.error('General chat error:', error)\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n }\n },\n [pageContext, initialContext, availableEntities]\n )\n\n // Execute tool directly\n const executeTool = useCallback(\n async (toolName: string, args: Record<string, unknown> = {}): Promise<ToolExecutionResult> => {\n setState((prev) => ({ ...prev, isLoading: true }))\n\n try {\n const result = await executeToolApi(toolName, args)\n\n if (result.success) {\n // Add to recent actions\n const tool = tools.find((t) => t.name === toolName)\n addRecentAction({\n toolName,\n displayName: tool?.description || toolName,\n args,\n })\n }\n\n return result\n } finally {\n setState((prev) => ({ ...prev, isLoading: false }))\n }\n },\n [executeToolApi, tools, addRecentAction]\n )\n\n // Approve a pending tool call\n const approveToolCall = useCallback(\n async (toolCallId: string) => {\n const toolCall = pendingToolCalls.find((tc) => tc.id === toolCallId)\n if (!toolCall) return\n\n // Update status to executing\n setPendingToolCalls((prev) =>\n prev.map((tc) => (tc.id === toolCallId ? { ...tc, status: 'executing' as const } : tc))\n )\n\n try {\n // Execute the tool\n const result = await executeToolApi(toolCall.toolName, toolCall.args)\n\n // Update tool call with result\n setPendingToolCalls((prev) =>\n prev.map((tc) =>\n tc.id === toolCallId\n ? {\n ...tc,\n status: result.success ? ('completed' as const) : ('error' as const),\n result: result.result,\n error: result.error,\n }\n : tc\n )\n )\n\n // Add to recent actions on success, show error on failure\n // Don't add raw JSON - the AI will provide human-friendly interpretation\n if (result.success) {\n const tool = tools.find((t) => t.name === toolCall.toolName)\n addRecentAction({\n toolName: toolCall.toolName,\n displayName: tool?.description || toolCall.toolName,\n args: toolCall.args,\n })\n // Add a brief success indicator (optional - AI can interpret the result)\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Done! The ${toolCall.toolName.replace(/_/g, ' ')} operation completed successfully.`,\n createdAt: new Date(),\n },\n ])\n } else {\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `I encountered an issue: ${result.error || 'Unknown error'}`,\n createdAt: new Date(),\n },\n ])\n }\n } catch (error) {\n setPendingToolCalls((prev) =>\n prev.map((tc) =>\n tc.id === toolCallId\n ? {\n ...tc,\n status: 'error' as const,\n error: error instanceof Error ? error.message : 'Unknown error',\n }\n : tc\n )\n )\n }\n },\n [pendingToolCalls, executeToolApi, tools, addRecentAction]\n )\n\n // Reject a pending tool call\n const rejectToolCall = useCallback((toolCallId: string) => {\n setPendingToolCalls((prev) =>\n prev.map((tc) => (tc.id === toolCallId ? { ...tc, status: 'rejected' as const } : tc))\n )\n\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: 'Tool call cancelled. How else can I help?',\n createdAt: new Date(),\n },\n ])\n }, [])\n\n // Send message in agentic chat (via OpenCode agent)\n const sendAgenticMessage = useCallback(\n async (content: string) => {\n if (!content.trim()) return\n\n // Add user message\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: content.trim(),\n createdAt: new Date(),\n }\n setMessages((prev) => [...prev, userMessage])\n setState((prev) => ({ ...prev, isStreaming: true }))\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n\n try {\n // Create abort controller for this stream\n currentStreamController.current?.abort()\n const controller = new AbortController()\n currentStreamController.current = controller\n\n // Send to chat API with OpenCode session for context persistence\n const response = await apiFetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n sessionId: opencodeSessionIdRef.current,\n }),\n signal: controller.signal,\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n // Read the streaming response\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n let buffer = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n\n // Process SSE events\n const lines = buffer.split('\\n')\n buffer = lines.pop() || '' // Keep incomplete line in buffer\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data === '[DONE]') continue\n\n try {\n const event = JSON.parse(data)\n\n\n // Track all events for debug panel (except question - handled separately with enriched data)\n if (event.type !== 'question') {\n addDebugEvent(event.type as DebugEventType, event)\n }\n\n if (event.type === 'thinking') {\n // OpenCode is processing - keep thinking state active\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n } else if (event.type === 'session-authorized') {\n // Session has been authorized with ephemeral API key\n setIsSessionAuthorized(true)\n } else if (event.type === 'text') {\n // Check if we need to start a new message (e.g., after answering a question)\n if (shouldStartNewMessage.current) {\n shouldStartNewMessage.current = false\n // Finalize the current streaming message and reset content\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n assistantContent = '' // Reset for new message\n }\n\n // Text received - now responding\n setIsThinking(false)\n setAgentStatus({ type: 'responding' })\n assistantContent += event.content || ''\n // Update assistant message in real-time\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n } else if (event.type === 'done') {\n // Stream complete - save session ID for conversation persistence\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n if (event.sessionId) {\n updateOpencodeSessionId(event.sessionId)\n }\n } else if (event.type === 'error') {\n // Handle error event\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Error: ${event.error || 'Unknown error occurred'}`,\n createdAt: new Date(),\n },\n ])\n } else if (event.type === 'tool-call') {\n // Tool calls are executed SERVER-SIDE via the AI SDK's maxSteps feature\n const toolName = event.toolName as string\n const toolArgs = event.args ?? {}\n\n // Update status to show the tool being used\n setAgentStatus({ type: 'tool', toolName })\n\n // For dangerous tools, show visual feedback (server already executed)\n if (!isToolSafeToAutoExecute(toolName)) {\n setPendingToolCalls((prev) => [\n ...prev,\n { id: event.id, toolName, args: toolArgs, status: 'completed' as const },\n ])\n }\n // Safe tools: no action needed, server handled execution\n } else if (event.type === 'question') {\n // OpenCode is asking for confirmation\n const question = event.question as OpenCodeQuestion\n // Skip if already answered\n if (answeredQuestionIds.current.has(question.id)) {\n // Already answered\n } else {\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setState((prev) => ({ ...prev, isStreaming: false }))\n setPendingQuestion(question)\n // Add enriched debug event with question details visible at top level\n addDebugEvent('question', {\n type: 'question',\n questionId: question.id,\n sessionID: question.sessionID,\n questionText: question.questions?.[0]?.question || 'No question text',\n header: question.questions?.[0]?.header || 'Confirmation',\n options: question.questions?.[0]?.options?.map(o => o.label) || [],\n fullQuestion: question,\n })\n }\n } else if (event.type === 'debug') {\n // Handle debug events for agent status updates\n const debugEvent = event as { partType?: string; data?: Record<string, unknown> }\n\n // Handle step-start: indicates tool execution beginning\n if (debugEvent.partType === 'step-start') {\n setAgentStatus({ type: 'executing' })\n }\n // Handle step-finish: tools completed\n if (debugEvent.partType === 'step-finish' && debugEvent.data?.reason === 'tool-calls') {\n // Tools finished, back to thinking for next step\n setAgentStatus({ type: 'thinking' })\n }\n }\n } catch {\n // Plain text chunk (fallback for non-SSE responses)\n assistantContent += data\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n } else if (line.trim() && !line.startsWith(':')) {\n // Plain text (not SSE format)\n assistantContent += line\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n }\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n // Ignore AbortError - this happens when we intentionally cancel the stream\n if (error instanceof Error && error.name === 'AbortError') {\n return\n }\n console.error('Tool chat error:', error)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n }\n },\n [messages, addDebugEvent, updateOpencodeSessionId]\n )\n\n // Main submit handler - starts agentic chat or continues existing session\n const handleSubmit = useCallback(\n async (query: string) => {\n if (!query.trim()) return\n\n // If we have an existing session, continue the conversation\n // Use ref to get latest value (avoids stale closure issues)\n if (opencodeSessionIdRef.current) {\n await sendAgenticMessage(query)\n } else {\n // Start new agentic session where AI has access to all tools\n await startAgenticChat(query)\n }\n },\n [startAgenticChat, sendAgenticMessage]\n )\n\n // Answer a pending OpenCode question\n // The original SSE stream continues running and will receive the follow-up response\n const answerQuestion = useCallback(\n async (answer: number) => {\n if (!pendingQuestion) return\n\n // Mark question as answered BEFORE sending - prevents duplicate display\n const questionId = pendingQuestion.id\n answeredQuestionIds.current.add(questionId)\n\n // Signal that the next text event should start a NEW message (not update the old one)\n shouldStartNewMessage.current = true\n\n // Clear the pending question UI and show thinking state\n setPendingQuestion(null)\n setIsThinking(true)\n setAgentStatus({ type: 'thinking' })\n\n // Add visual feedback of the answer\n const selectedOption = pendingQuestion.questions[0]?.options[answer]\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'user' as const,\n content: `[Confirmed: ${selectedOption?.label || 'Yes'}]`,\n createdAt: new Date(),\n },\n ])\n\n try {\n // Send answer as simple POST - the original SSE stream will receive the follow-up\n const sessionId = pendingQuestion.sessionID\n const { ok, result, status } = await apiCall<{ error?: string }>('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n answerQuestion: {\n questionId,\n answer,\n sessionId,\n },\n }),\n })\n\n if (!ok) {\n throw new Error(result?.error || `Answer request failed: ${status}`)\n }\n\n // Answer sent successfully - the original stream will handle the response\n // Note: isThinking stays true until the original stream sends 'done' or more 'text'\n } catch (error) {\n console.error('[answerQuestion] Error:', error)\n setIsThinking(false)\n setAgentStatus({ type: 'idle' })\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant' as const,\n content: `Error: ${error instanceof Error ? error.message : 'Failed to send answer'}`,\n createdAt: new Date(),\n },\n ])\n }\n },\n [pendingQuestion]\n )\n\n // Legacy sendMessage function (for backwards compatibility)\n const sendMessage = useCallback(\n async (content: string) => {\n if (!content.trim()) return\n\n // Add user message\n const userMessage: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: content.trim(),\n createdAt: new Date(),\n }\n setMessages((prev) => [...prev, userMessage])\n setState((prev) => ({ ...prev, isStreaming: true }))\n\n try {\n // Send to chat API\n const response = await apiFetch('/api/ai_assistant/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n context: pageContext,\n }),\n })\n\n if (!response.ok) {\n throw new Error(`Chat request failed: ${response.status}`)\n }\n\n // Read the streaming response\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('No response body')\n }\n\n const decoder = new TextDecoder()\n let assistantContent = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n assistantContent += chunk\n\n // Update assistant message in real-time\n setMessages((prev) => {\n const existingAssistant = prev.find(\n (m) => m.role === 'assistant' && m.id === 'streaming'\n )\n if (existingAssistant) {\n return prev.map((m) =>\n m.id === 'streaming' ? { ...m, content: assistantContent } : m\n )\n } else {\n return [\n ...prev,\n {\n id: 'streaming',\n role: 'assistant' as const,\n content: assistantContent,\n createdAt: new Date(),\n },\n ]\n }\n })\n }\n\n // Finalize the assistant message\n setMessages((prev) => prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)))\n } catch (error) {\n console.error('Chat error:', error)\n // Add error message\n setMessages((prev) => [\n ...prev,\n {\n id: generateId(),\n role: 'assistant',\n content: 'Sorry, I encountered an error. Please try again.',\n createdAt: new Date(),\n },\n ])\n } finally {\n setState((prev) => ({ ...prev, isStreaming: false }))\n }\n },\n [messages, pageContext]\n )\n\n const clearMessages = useCallback(() => {\n setMessages([])\n setPendingToolCalls([])\n }, [])\n\n // Stop/cancel the current streaming execution\n const stopExecution = useCallback(() => {\n // Abort the current stream\n currentStreamController.current?.abort()\n currentStreamController.current = null\n\n // Reset streaming state\n setState((prev) => ({ ...prev, isStreaming: false }))\n setAgentStatus({ type: 'idle' })\n setIsThinking(false)\n\n // Add cancellation message to chat\n setMessages((prev) => [\n ...prev.map((m) => (m.id === 'streaming' ? { ...m, id: generateId() } : m)), // Finalize any streaming message\n {\n id: generateId(),\n role: 'system' as const,\n content: 'Execution stopped by user.',\n createdAt: new Date(),\n },\n ])\n }, [])\n\n return {\n // State\n state: {\n ...state,\n isLoading: state.isLoading || toolsLoading,\n },\n isThinking,\n agentStatus,\n isSessionAuthorized,\n pageContext,\n selectedEntities,\n tools,\n filteredTools,\n recentActions,\n recentTools,\n messages,\n pendingToolCalls,\n selectedTool,\n initialContext,\n availableEntities,\n\n // Navigation actions\n open,\n openChat,\n close,\n setIsOpen,\n setInputValue,\n setSelectedIndex,\n\n // Intelligent routing - submit natural language query\n handleSubmit,\n reset,\n\n // Page navigation (legacy, kept for compatibility)\n goToToolChat,\n goBack,\n\n // Tool execution\n executeTool,\n approveToolCall,\n rejectToolCall,\n\n // Chat actions\n sendMessage,\n sendAgenticMessage,\n clearMessages,\n stopExecution,\n\n // Legacy compatibility\n setMode,\n\n // Debug mode\n debugEvents,\n showDebug,\n setShowDebug,\n clearDebugEvents,\n\n // OpenCode question handling\n pendingQuestion,\n answerQuestion,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { useState, useCallback, useEffect } from "react";
3
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
3
4
  function useMcpTools() {
4
5
  const [tools, setTools] = useState([]);
5
6
  const [isLoading, setIsLoading] = useState(false);
@@ -8,16 +9,14 @@ function useMcpTools() {
8
9
  setIsLoading(true);
9
10
  setError(null);
10
11
  try {
11
- const response = await fetch("/api/ai_assistant/tools", {
12
- headers: {
13
- "x-om-forbidden-redirect": "0"
14
- }
15
- });
16
- if (!response.ok) {
17
- throw new Error(`Failed to fetch tools: ${response.status}`);
12
+ const { ok, result, status } = await apiCall(
13
+ "/api/ai_assistant/tools",
14
+ { headers: { "x-om-forbidden-redirect": "0" } }
15
+ );
16
+ if (!ok) {
17
+ throw new Error(`Failed to fetch tools: ${status}`);
18
18
  }
19
- const data = await response.json();
20
- setTools(data.tools || []);
19
+ setTools(result?.tools || []);
21
20
  } catch (err) {
22
21
  setError(err instanceof Error ? err.message : "Failed to load tools");
23
22
  setTools([]);
@@ -28,24 +27,26 @@ function useMcpTools() {
28
27
  const executeTool = useCallback(
29
28
  async (toolName, args = {}) => {
30
29
  try {
31
- const response = await fetch("/api/ai_assistant/tools/execute", {
32
- method: "POST",
33
- headers: {
34
- "Content-Type": "application/json",
35
- "x-om-forbidden-redirect": "0"
36
- },
37
- body: JSON.stringify({ toolName, args })
38
- });
39
- const data = await response.json();
40
- if (!response.ok) {
30
+ const { ok, result, status } = await apiCall(
31
+ "/api/ai_assistant/tools/execute",
32
+ {
33
+ method: "POST",
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ "x-om-forbidden-redirect": "0"
37
+ },
38
+ body: JSON.stringify({ toolName, args })
39
+ }
40
+ );
41
+ if (!ok) {
41
42
  return {
42
43
  success: false,
43
- error: data.error || `Tool execution failed: ${response.status}`
44
+ error: result?.error || `Tool execution failed: ${status}`
44
45
  };
45
46
  }
46
47
  return {
47
48
  success: true,
48
- result: data.result
49
+ result: result?.result
49
50
  };
50
51
  } catch (err) {
51
52
  return {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/frontend/hooks/useMcpTools.ts"],
4
- "sourcesContent": ["'use client'\n\nimport { useState, useCallback, useEffect } from 'react'\nimport type { ToolInfo, ToolExecutionResult } from '../types'\n\nexport function useMcpTools() {\n const [tools, setTools] = useState<ToolInfo[]>([])\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const fetchTools = useCallback(async () => {\n setIsLoading(true)\n setError(null)\n try {\n const response = await fetch('/api/ai_assistant/tools', {\n headers: {\n 'x-om-forbidden-redirect': '0',\n },\n })\n if (!response.ok) {\n throw new Error(`Failed to fetch tools: ${response.status}`)\n }\n const data = await response.json()\n setTools(data.tools || [])\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load tools')\n setTools([])\n } finally {\n setIsLoading(false)\n }\n }, [])\n\n const executeTool = useCallback(\n async (toolName: string, args: Record<string, unknown> = {}): Promise<ToolExecutionResult> => {\n try {\n const response = await fetch('/api/ai_assistant/tools/execute', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-om-forbidden-redirect': '0',\n },\n body: JSON.stringify({ toolName, args }),\n })\n\n const data = await response.json()\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || `Tool execution failed: ${response.status}`,\n }\n }\n\n return {\n success: true,\n result: data.result,\n }\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : 'Tool execution failed',\n }\n }\n },\n []\n )\n\n // Fetch tools on mount\n useEffect(() => {\n fetchTools()\n }, [fetchTools])\n\n return {\n tools,\n isLoading,\n error,\n fetchTools,\n executeTool,\n }\n}\n"],
5
- "mappings": ";AAEA,SAAS,UAAU,aAAa,iBAAiB;AAG1C,SAAS,cAAc;AAC5B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAqB,CAAC,CAAC;AACjD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,QAAM,aAAa,YAAY,YAAY;AACzC,iBAAa,IAAI;AACjB,aAAS,IAAI;AACb,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,2BAA2B;AAAA,QACtD,SAAS;AAAA,UACP,2BAA2B;AAAA,QAC7B;AAAA,MACF,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,EAAE;AAAA,MAC7D;AACA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAS,KAAK,SAAS,CAAC,CAAC;AAAA,IAC3B,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,IAAI,UAAU,sBAAsB;AACpE,eAAS,CAAC,CAAC;AAAA,IACb,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc;AAAA,IAClB,OAAO,UAAkB,OAAgC,CAAC,MAAoC;AAC5F,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,mCAAmC;AAAA,UAC9D,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,2BAA2B;AAAA,UAC7B;AAAA,UACA,MAAM,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC;AAAA,QACzC,CAAC;AAED,cAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAI,CAAC,SAAS,IAAI;AAChB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO,KAAK,SAAS,0BAA0B,SAAS,MAAM;AAAA,UAChE;AAAA,QACF;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,KAAK;AAAA,QACf;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAGA,YAAU,MAAM;AACd,eAAW;AAAA,EACb,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["'use client'\n\nimport { useState, useCallback, useEffect } from 'react'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport type { ToolInfo, ToolExecutionResult } from '../types'\n\nexport function useMcpTools() {\n const [tools, setTools] = useState<ToolInfo[]>([])\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const fetchTools = useCallback(async () => {\n setIsLoading(true)\n setError(null)\n try {\n const { ok, result, status } = await apiCall<{ tools: ToolInfo[] }>(\n '/api/ai_assistant/tools',\n { headers: { 'x-om-forbidden-redirect': '0' } }\n )\n if (!ok) {\n throw new Error(`Failed to fetch tools: ${status}`)\n }\n setTools(result?.tools || [])\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load tools')\n setTools([])\n } finally {\n setIsLoading(false)\n }\n }, [])\n\n const executeTool = useCallback(\n async (toolName: string, args: Record<string, unknown> = {}): Promise<ToolExecutionResult> => {\n try {\n const { ok, result, status } = await apiCall<{ result: unknown; error?: string }>(\n '/api/ai_assistant/tools/execute',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-om-forbidden-redirect': '0',\n },\n body: JSON.stringify({ toolName, args }),\n }\n )\n\n if (!ok) {\n return {\n success: false,\n error: result?.error || `Tool execution failed: ${status}`,\n }\n }\n\n return {\n success: true,\n result: result?.result,\n }\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : 'Tool execution failed',\n }\n }\n },\n []\n )\n\n // Fetch tools on mount\n useEffect(() => {\n fetchTools()\n }, [fetchTools])\n\n return {\n tools,\n isLoading,\n error,\n fetchTools,\n executeTool,\n }\n}\n"],
5
+ "mappings": ";AAEA,SAAS,UAAU,aAAa,iBAAiB;AACjD,SAAS,eAAe;AAGjB,SAAS,cAAc;AAC5B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAqB,CAAC,CAAC;AACjD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,QAAM,aAAa,YAAY,YAAY;AACzC,iBAAa,IAAI;AACjB,aAAS,IAAI;AACb,QAAI;AACF,YAAM,EAAE,IAAI,QAAQ,OAAO,IAAI,MAAM;AAAA,QACnC;AAAA,QACA,EAAE,SAAS,EAAE,2BAA2B,IAAI,EAAE;AAAA,MAChD;AACA,UAAI,CAAC,IAAI;AACP,cAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE;AAAA,MACpD;AACA,eAAS,QAAQ,SAAS,CAAC,CAAC;AAAA,IAC9B,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,IAAI,UAAU,sBAAsB;AACpE,eAAS,CAAC,CAAC;AAAA,IACb,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc;AAAA,IAClB,OAAO,UAAkB,OAAgC,CAAC,MAAoC;AAC5F,UAAI;AACF,cAAM,EAAE,IAAI,QAAQ,OAAO,IAAI,MAAM;AAAA,UACnC;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,2BAA2B;AAAA,YAC7B;AAAA,YACA,MAAM,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC;AAAA,UACzC;AAAA,QACF;AAEA,YAAI,CAAC,IAAI;AACP,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO,QAAQ,SAAS,0BAA0B,MAAM;AAAA,UAC1D;AAAA,QACF;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,QAClB;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAGA,YAAU,MAAM;AACd,eAAW;AAAA,EACb,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -111,6 +111,13 @@ RESPONSE RULES:
111
111
  - Present results in clean business language with **bold names** and bullet points.
112
112
  - Only ask for confirmation before create/update/delete operations.
113
113
  `.trim();
114
+ const openApi = {
115
+ tag: "AI Assistant",
116
+ summary: "AI chat",
117
+ methods: {
118
+ POST: { summary: "Send message to AI agent via SSE stream" }
119
+ }
120
+ };
114
121
  const metadata = {
115
122
  POST: { requireAuth: true, requireFeatures: ["ai_assistant.view"] }
116
123
  };
@@ -263,6 +270,7 @@ async function POST(req) {
263
270
  }
264
271
  export {
265
272
  POST,
266
- metadata
273
+ metadata,
274
+ openApi
267
275
  };
268
276
  //# sourceMappingURL=route.js.map