@devicai/ui 0.10.1 → 0.10.3
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.
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +2 -0
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js +9 -6
- package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/cjs/hooks/useDevicChat.js +97 -29
- package/dist/cjs/hooks/useDevicChat.js.map +1 -1
- package/dist/cjs/hooks/usePolling.js +16 -12
- package/dist/cjs/hooks/usePolling.js.map +1 -1
- package/dist/cjs/provider/DevicProvider.js +3 -2
- package/dist/cjs/provider/DevicProvider.js.map +1 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/logger.js +17 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +2 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +6 -0
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js +10 -7
- package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
- package/dist/esm/hooks/useDevicChat.d.ts +6 -0
- package/dist/esm/hooks/useDevicChat.js +98 -30
- package/dist/esm/hooks/useDevicChat.js.map +1 -1
- package/dist/esm/hooks/usePolling.d.ts +5 -0
- package/dist/esm/hooks/usePolling.js +17 -13
- package/dist/esm/hooks/usePolling.js.map +1 -1
- package/dist/esm/provider/DevicProvider.d.ts +1 -1
- package/dist/esm/provider/DevicProvider.js +3 -2
- package/dist/esm/provider/DevicProvider.js.map +1 -1
- package/dist/esm/provider/types.d.ts +9 -0
- package/dist/esm/utils/index.d.ts +2 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/logger.d.ts +10 -0
- package/dist/esm/utils/logger.js +15 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDevicChat.js","sources":["../../../../src/hooks/useDevicChat.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useRef } from 'react';\nimport { useOptionalDevicContext } from '../provider';\nimport { DevicApiClient } from '../api/client';\nimport { usePolling } from './usePolling';\nimport { useModelInterface } from './useModelInterface';\n\nconsole.log('[devic-ui] Version: 0.6.1');\nimport type {\n ChatMessage,\n ChatFile,\n ModelInterfaceTool,\n RealtimeChatHistory,\n RealtimeStatus,\n} from '../api/types';\n\nexport interface UseDevicChatOptions {\n /**\n * Assistant identifier\n */\n assistantId: string;\n\n /**\n * Existing chat UID to continue a conversation\n */\n chatUid?: string;\n\n /**\n * API key (overrides provider context)\n */\n apiKey?: string;\n\n /**\n * Base URL (overrides provider context)\n */\n baseUrl?: string;\n\n /**\n * Tenant ID for multi-tenant environments\n */\n tenantId?: string;\n\n /**\n * Tenant metadata\n */\n tenantMetadata?: Record<string, any>;\n\n /**\n * Tools enabled from the assistant's configured tool groups\n */\n enabledTools?: string[];\n\n /**\n * Client-side tools for model interface protocol\n */\n modelInterfaceTools?: ModelInterfaceTool[];\n\n /**\n * Polling interval for async mode (ms)\n * @default 1000\n */\n pollingInterval?: number;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: ChatMessage) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: ChatMessage) => void;\n\n /**\n * Callback when a tool is called\n */\n onToolCall?: (toolName: string, params: any) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when a new chat is created\n */\n onChatCreated?: (chatUid: string) => void;\n}\n\nexport interface UseDevicChatResult {\n /**\n * Current chat messages\n */\n messages: ChatMessage[];\n\n /**\n * Current chat UID\n */\n chatUid: string | null;\n\n /**\n * Whether a message is being processed\n */\n isLoading: boolean;\n\n /**\n * Current status\n */\n status: RealtimeStatus | 'idle';\n\n /**\n * Last error\n */\n error: Error | null;\n\n /**\n * Whether the assistant has handed off to a subagent\n */\n handedOff: boolean;\n\n /**\n * The subthread ID when a handoff is active\n */\n handedOffSubThreadId: string | null;\n\n /**\n * Send a message\n */\n sendMessage: (\n message: string,\n options?: {\n files?: ChatFile[];\n metadata?: Record<string, any>;\n }\n ) => Promise<void>;\n\n /**\n * Clear the chat and start a new conversation\n */\n clearChat: () => void;\n\n /**\n * Load an existing chat\n */\n loadChat: (chatUid: string) => Promise<void>;\n\n /**\n * Called when the handoff subagent completes.\n * Triggers reload of full chat content.\n */\n onHandoffCompleted: () => void;\n\n /**\n * Stop the current conversation processing (client-side only).\n * Stops polling and resets loading state.\n */\n stopChat: () => void;\n}\n\n/**\n * Main hook for managing chat with a Devic assistant\n *\n * @example\n * ```tsx\n * const {\n * messages,\n * isLoading,\n * sendMessage,\n * } = useDevicChat({\n * assistantId: 'my-assistant',\n * modelInterfaceTools: [\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ],\n * onMessageReceived: (msg) => console.log('Received:', msg),\n * });\n * ```\n */\nexport function useDevicChat(options: UseDevicChatOptions): UseDevicChatResult {\n const {\n assistantId,\n chatUid: initialChatUid,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools = [],\n pollingInterval = 1000,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n } = options;\n\n // Get context (may be null if not wrapped in provider)\n const context = useOptionalDevicContext();\n\n // Resolve configuration\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedTenantMetadata = { ...context?.tenantMetadata, ...tenantMetadata };\n\n // State\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [chatUid, setChatUid] = useState<string | null>(initialChatUid || null);\n const [isLoading, setIsLoading] = useState(false);\n const [status, setStatus] = useState<RealtimeStatus | 'idle'>('idle');\n const [error, setError] = useState<Error | null>(null);\n\n // Handoff state\n const [handedOff, setHandedOff] = useState(false);\n const [handedOffSubThreadId, setHandedOffSubThreadId] = useState<string | null>(null);\n const handoffPollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Polling state\n const [shouldPoll, setShouldPoll] = useState(false);\n\n // Refs for callbacks\n const onMessageReceivedRef = useRef(onMessageReceived);\n const onErrorRef = useRef(onError);\n const onChatCreatedRef = useRef(onChatCreated);\n\n useEffect(() => {\n onMessageReceivedRef.current = onMessageReceived;\n onErrorRef.current = onError;\n onChatCreatedRef.current = onChatCreated;\n });\n\n // Create API client\n const clientRef = useRef<DevicApiClient | null>(null);\n if (!clientRef.current && apiKey) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl });\n }\n\n // Update client config if it changes\n useEffect(() => {\n if (clientRef.current && apiKey) {\n clientRef.current.setConfig({ apiKey, baseUrl });\n }\n }, [apiKey, baseUrl]);\n\n // Load initial chat history if chatUid prop is provided\n // This runs once on mount (or when initialChatUid changes) to fetch existing conversation\n const initialChatLoadedRef = useRef(false);\n useEffect(() => {\n if (initialChatUid && clientRef.current && !initialChatLoadedRef.current) {\n initialChatLoadedRef.current = true;\n\n const loadInitialChat = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const history = await clientRef.current!.getChatHistory(\n assistantId,\n initialChatUid,\n { tenantId: resolvedTenantId }\n );\n setMessages(history.chatContent);\n setChatUid(initialChatUid);\n setStatus('completed');\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadInitialChat();\n }\n }, [initialChatUid, assistantId, resolvedTenantId]);\n\n // Model interface hook\n const {\n toolSchemas,\n handleToolCalls,\n extractPendingToolCalls,\n } = useModelInterface({\n tools: modelInterfaceTools,\n onToolExecute: onToolCall,\n });\n\n // Polling hook - uses callbacks for side effects, return value not needed\n console.log('[useDevicChat] Render - shouldPoll:', shouldPoll, 'chatUid:', chatUid);\n usePolling(\n shouldPoll ? chatUid : null,\n async () => {\n console.log('[useDevicChat] fetchFn called, chatUid:', chatUid);\n if (!clientRef.current || !chatUid) {\n throw new Error('Cannot poll without client or chatUid');\n }\n const result = await clientRef.current.getRealtimeHistory(assistantId, chatUid);\n console.log('[useDevicChat] getRealtimeHistory result:', result);\n return result;\n },\n {\n interval: pollingInterval,\n enabled: shouldPoll,\n stopStatuses: ['completed', 'error', 'waiting_for_tool_response', 'handed_off'],\n onUpdate: async (data: RealtimeChatHistory) => {\n console.log('[useDevicChat] onUpdate called, status:', data.status);\n\n // Merge realtime data with optimistic messages\n setMessages((prev) => {\n const realtimeUIDs = new Set(data.chatHistory.map((m) => m.uid));\n const realtimeUserMessages = new Set(\n data.chatHistory\n .filter((m) => m.role === 'user')\n .map((m) => m.content?.message)\n );\n\n // Keep optimistic messages not yet in realtime data\n const optimistic = prev.filter((m) => {\n if (realtimeUIDs.has(m.uid)) return false;\n if (m.role === 'user' && realtimeUserMessages.has(m.content?.message)) return false;\n return true;\n });\n\n return [...data.chatHistory, ...optimistic];\n });\n setStatus(data.status);\n\n // Notify about new messages\n const lastMessage = data.chatHistory[data.chatHistory.length - 1];\n if (lastMessage && lastMessage.role === 'assistant') {\n onMessageReceivedRef.current?.(lastMessage);\n }\n\n // Handle model interface - check for pending tool calls\n if (data.status === 'waiting_for_tool_response' || data.pendingToolCalls?.length) {\n await handlePendingToolCalls(data);\n }\n },\n onStop: (data) => {\n console.log('[useDevicChat] onStop called, status:', data?.status);\n setShouldPoll(false);\n\n if (data?.status === 'error') {\n setIsLoading(false);\n const err = new Error('Chat processing failed');\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'completed') {\n setIsLoading(false);\n } else if (data?.status === 'handed_off') {\n // Subagent is working — keep isLoading true so the UI stays in loading state.\n // Set handoff state directly from the realtime status.\n setHandedOff(true);\n\n const subThreadId = data.handedOffSubThreadId || null;\n console.log('[useDevicChat] Handoff state set:', { handedOff: true, subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n }\n // Note: waiting_for_tool_response is handled in onUpdate to avoid double execution\n },\n onError: (err) => {\n console.error('[useDevicChat] onError called:', err);\n setError(err);\n setIsLoading(false);\n setShouldPoll(false);\n onErrorRef.current?.(err);\n },\n }\n );\n\n // Handle pending tool calls from model interface\n const handlePendingToolCalls = useCallback(\n async (data: RealtimeChatHistory) => {\n if (!clientRef.current || !chatUid) return;\n\n // Get pending tool calls\n const pendingCalls = data.pendingToolCalls || extractPendingToolCalls(data.chatHistory);\n\n if (pendingCalls.length === 0) return;\n\n try {\n // Execute client-side tools\n const responses = await handleToolCalls(pendingCalls);\n\n if (responses.length > 0) {\n // Send tool responses back to the API\n await clientRef.current.sendToolResponses(assistantId, chatUid, responses);\n\n // Resume polling\n setShouldPoll(true);\n setIsLoading(true);\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [chatUid, assistantId, handleToolCalls, extractPendingToolCalls]\n );\n\n // Send a message\n const sendMessage = useCallback(\n async (\n message: string,\n sendOptions?: {\n files?: ChatFile[];\n metadata?: Record<string, any>;\n }\n ) => {\n if (!clientRef.current) {\n const err = new Error(\n 'API client not configured. Please provide an API key.'\n );\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n setStatus('processing');\n\n // Add user message optimistically\n const userMessage: ChatMessage = {\n uid: `temp-${Date.now()}`,\n role: 'user',\n content: {\n message,\n files: sendOptions?.files?.map((f) => ({\n name: f.name,\n url: f.downloadUrl || '',\n type: f.fileType || 'other',\n })),\n },\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n onMessageSent?.(userMessage);\n\n try {\n // Build request DTO\n const dto = {\n message,\n chatUid: chatUid || undefined,\n files: sendOptions?.files,\n metadata: {\n ...resolvedTenantMetadata,\n ...sendOptions?.metadata,\n },\n tenantId: resolvedTenantId,\n enabledTools,\n // Include model interface tools if any\n ...(toolSchemas.length > 0 && { tools: toolSchemas }),\n };\n\n // Send message in async mode\n console.log('[useDevicChat] Sending message async...');\n const response = await clientRef.current.sendMessageAsync(assistantId, dto);\n console.log('[useDevicChat] sendMessageAsync response:', response);\n\n // Update chat UID if this is a new chat\n if (response.chatUid && response.chatUid !== chatUid) {\n console.log('[useDevicChat] Setting chatUid:', response.chatUid);\n setChatUid(response.chatUid);\n onChatCreatedRef.current?.(response.chatUid);\n }\n\n // Start polling for results\n console.log('[useDevicChat] Setting shouldPoll to true');\n setShouldPoll(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setIsLoading(false);\n setStatus('error');\n onErrorRef.current?.(error);\n\n // Remove optimistic user message on error\n setMessages((prev) => prev.filter((m) => m.uid !== userMessage.uid));\n }\n },\n [\n chatUid,\n assistantId,\n enabledTools,\n resolvedTenantId,\n resolvedTenantMetadata,\n toolSchemas,\n onMessageSent,\n ]\n );\n\n // Clear chat\n const clearChat = useCallback(() => {\n setMessages([]);\n setChatUid(null);\n setStatus('idle');\n setError(null);\n setShouldPoll(false);\n }, []);\n\n // Load existing chat\n const loadChat = useCallback(\n async (loadChatUid: string) => {\n if (!clientRef.current) {\n const err = new Error('API client not configured');\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const history = await clientRef.current.getChatHistory(\n assistantId,\n loadChatUid,\n { tenantId: resolvedTenantId }\n );\n\n setMessages(history.chatContent);\n setChatUid(loadChatUid);\n setStatus('completed');\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n } finally {\n setIsLoading(false);\n }\n },\n [assistantId, resolvedTenantId]\n );\n\n // Handoff polling: while handedOff is true, poll the realtime endpoint every 5s\n // to detect when the parent thread is no longer in handed_off state.\n useEffect(() => {\n if (!handedOff || !chatUid || !clientRef.current) return;\n\n const pollHandoff = async () => {\n try {\n const realtime = await clientRef.current!.getRealtimeHistory(assistantId, chatUid!);\n console.log('[useDevicChat] Handoff poll - realtime status:', realtime.status);\n if (realtime.status !== 'handed_off') {\n // Handoff completed — clear handoff state and resume main polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n // Resume main polling to pick up the parent thread's continuation\n setShouldPoll(true);\n }\n } catch {}\n };\n\n handoffPollRef.current = setInterval(pollHandoff, 5000);\n return () => {\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n };\n }, [handedOff, chatUid, assistantId]);\n\n // Called by HandoffSubagentWidget when the subthread reaches a terminal state\n const onHandoffCompleted = useCallback(() => {\n console.log('[useDevicChat] onHandoffCompleted called');\n // Clear the handoff polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n // Clear handoff state and resume main polling\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n setShouldPoll(true);\n }, []);\n\n // Stop current conversation — calls the server-side stop endpoint\n // then stops polling and resets loading state.\n const stopChat = useCallback(async () => {\n if (clientRef.current && chatUid) {\n try {\n await clientRef.current.stopChat(assistantId, chatUid);\n } catch {\n // Ignore errors (e.g. chat already completed)\n }\n }\n setShouldPoll(false);\n setIsLoading(false);\n setStatus('idle');\n }, [chatUid, assistantId]);\n\n return {\n messages,\n chatUid,\n isLoading,\n status,\n error,\n handedOff,\n handedOffSubThreadId,\n sendMessage,\n clearChat,\n loadChat,\n onHandoffCompleted,\n stopChat,\n };\n}\n"],"names":["useOptionalDevicContext","useState","useRef","useEffect","DevicApiClient","useModelInterface","usePolling","useCallback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDevicChat.js","sources":["../../../../src/hooks/useDevicChat.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useOptionalDevicContext } from '../provider';\nimport { DevicApiClient } from '../api/client';\nimport { usePolling } from './usePolling';\nimport { useModelInterface } from './useModelInterface';\nimport { createLogger } from '../utils/logger';\nimport type {\n ChatMessage,\n ChatFile,\n ModelInterfaceTool,\n RealtimeChatHistory,\n RealtimeStatus,\n} from '../api/types';\n\nexport interface UseDevicChatOptions {\n /**\n * Assistant identifier\n */\n assistantId: string;\n\n /**\n * Existing chat UID to continue a conversation\n */\n chatUid?: string;\n\n /**\n * API key (overrides provider context)\n */\n apiKey?: string;\n\n /**\n * Base URL (overrides provider context)\n */\n baseUrl?: string;\n\n /**\n * Tenant ID for multi-tenant environments\n */\n tenantId?: string;\n\n /**\n * Tenant metadata\n */\n tenantMetadata?: Record<string, any>;\n\n /**\n * Tools enabled from the assistant's configured tool groups\n */\n enabledTools?: string[];\n\n /**\n * Client-side tools for model interface protocol\n */\n modelInterfaceTools?: ModelInterfaceTool[];\n\n /**\n * Polling interval for async mode (ms)\n * @default 1000\n */\n pollingInterval?: number;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: ChatMessage) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: ChatMessage) => void;\n\n /**\n * Callback when a tool is called\n */\n onToolCall?: (toolName: string, params: any) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when a new chat is created\n */\n onChatCreated?: (chatUid: string) => void;\n\n /**\n * Enable debug logging to the browser console.\n * Overrides the provider-level debug setting when provided.\n * @default false\n */\n debug?: boolean;\n}\n\nexport interface UseDevicChatResult {\n /**\n * Current chat messages\n */\n messages: ChatMessage[];\n\n /**\n * Current chat UID\n */\n chatUid: string | null;\n\n /**\n * Whether a message is being processed\n */\n isLoading: boolean;\n\n /**\n * Current status\n */\n status: RealtimeStatus | 'idle';\n\n /**\n * Last error\n */\n error: Error | null;\n\n /**\n * Whether the assistant has handed off to a subagent\n */\n handedOff: boolean;\n\n /**\n * The subthread ID when a handoff is active\n */\n handedOffSubThreadId: string | null;\n\n /**\n * Send a message\n */\n sendMessage: (\n message: string,\n options?: {\n files?: ChatFile[];\n metadata?: Record<string, any>;\n }\n ) => Promise<void>;\n\n /**\n * Clear the chat and start a new conversation\n */\n clearChat: () => void;\n\n /**\n * Load an existing chat\n */\n loadChat: (chatUid: string) => Promise<void>;\n\n /**\n * Called when the handoff subagent completes.\n * Triggers reload of full chat content.\n */\n onHandoffCompleted: () => void;\n\n /**\n * Stop the current conversation processing (client-side only).\n * Stops polling and resets loading state.\n */\n stopChat: () => void;\n}\n\n/**\n * Main hook for managing chat with a Devic assistant\n *\n * @example\n * ```tsx\n * const {\n * messages,\n * isLoading,\n * sendMessage,\n * } = useDevicChat({\n * assistantId: 'my-assistant',\n * modelInterfaceTools: [\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ],\n * onMessageReceived: (msg) => console.log('Received:', msg),\n * });\n * ```\n */\nexport function useDevicChat(options: UseDevicChatOptions): UseDevicChatResult {\n const {\n assistantId,\n chatUid: initialChatUid,\n apiKey: propsApiKey,\n baseUrl: propsBaseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools = [],\n pollingInterval = 1000,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n debug: propsDebug,\n } = options;\n\n // Get context (may be null if not wrapped in provider)\n const context = useOptionalDevicContext();\n\n // Resolve configuration\n const apiKey = propsApiKey || context?.apiKey;\n const baseUrl = propsBaseUrl || context?.baseUrl || 'https://api.devic.ai';\n const resolvedTenantId = tenantId || context?.tenantId;\n const resolvedTenantMetadata = { ...context?.tenantMetadata, ...tenantMetadata };\n const debug = propsDebug ?? context?.debug ?? false;\n const log = useMemo(() => createLogger(debug), [debug]);\n const logRef = useRef(log);\n logRef.current = log;\n\n // State\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [chatUid, setChatUid] = useState<string | null>(initialChatUid || null);\n const [isLoading, setIsLoading] = useState(false);\n const [status, setStatus] = useState<RealtimeStatus | 'idle'>('idle');\n const [error, setError] = useState<Error | null>(null);\n\n // Handoff state\n const [handedOff, setHandedOff] = useState(false);\n const [handedOffSubThreadId, setHandedOffSubThreadId] = useState<string | null>(null);\n const handoffPollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Polling state\n const [shouldPoll, setShouldPoll] = useState(false);\n\n // Keep a ref to chatUid so async callbacks always read the latest value\n const chatUidRef = useRef(chatUid);\n chatUidRef.current = chatUid;\n\n // Refs for callbacks\n const onMessageReceivedRef = useRef(onMessageReceived);\n const onErrorRef = useRef(onError);\n const onChatCreatedRef = useRef(onChatCreated);\n\n useEffect(() => {\n onMessageReceivedRef.current = onMessageReceived;\n onErrorRef.current = onError;\n onChatCreatedRef.current = onChatCreated;\n });\n\n // Create API client\n const clientRef = useRef<DevicApiClient | null>(null);\n if (!clientRef.current && apiKey) {\n clientRef.current = new DevicApiClient({ apiKey, baseUrl });\n }\n\n // Update client config if it changes\n useEffect(() => {\n if (clientRef.current && apiKey) {\n clientRef.current.setConfig({ apiKey, baseUrl });\n }\n }, [apiKey, baseUrl]);\n\n // Resume chat state based on realtime status.\n // Called after loading chat history to detect in-progress conversations.\n const resumeFromRealtimeStatus = useCallback(\n async (targetChatUid: string) => {\n if (!clientRef.current) return;\n try {\n const realtime = await clientRef.current.getRealtimeHistory(assistantId, targetChatUid);\n logRef.current.log('[useDevicChat] resumeFromRealtimeStatus:', realtime.status);\n\n // Update messages with realtime data (may be fresher than static history)\n if (realtime.chatHistory?.length) {\n setMessages(realtime.chatHistory);\n }\n setStatus(realtime.status);\n\n if (realtime.status === 'processing') {\n // Chat is still processing — resume polling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'waiting_for_tool_response') {\n // Chat is waiting for tool response — resume polling to trigger tool handling\n setIsLoading(true);\n setShouldPoll(true);\n } else if (realtime.status === 'handed_off') {\n // Chat has an active handoff\n setIsLoading(true);\n setHandedOff(true);\n const subThreadId = realtime.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Resuming handoff state:', { subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n } else {\n // completed or error — just stop\n setIsLoading(false);\n }\n } catch (err) {\n // If realtime fetch fails (e.g. chat has no realtime entry), just stay idle\n logRef.current.warn('[useDevicChat] resumeFromRealtimeStatus failed:', err);\n setIsLoading(false);\n }\n },\n [assistantId]\n );\n\n // Load initial chat history if chatUid prop is provided\n // This runs once on mount (or when initialChatUid changes) to fetch existing conversation\n const initialChatLoadedRef = useRef(false);\n useEffect(() => {\n if (initialChatUid && clientRef.current && !initialChatLoadedRef.current) {\n initialChatLoadedRef.current = true;\n\n const loadInitialChat = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const history = await clientRef.current!.getChatHistory(\n assistantId,\n initialChatUid,\n { tenantId: resolvedTenantId }\n );\n setMessages(history.chatContent);\n setChatUid(initialChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(initialChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n };\n\n loadInitialChat();\n }\n }, [initialChatUid, assistantId, resolvedTenantId, resumeFromRealtimeStatus]);\n\n // Model interface hook\n const {\n toolSchemas,\n handleToolCalls,\n extractPendingToolCalls,\n } = useModelInterface({\n tools: modelInterfaceTools,\n onToolExecute: onToolCall,\n });\n\n // Polling hook - uses callbacks for side effects, return value not needed\n logRef.current.log('[useDevicChat] Render - shouldPoll:', shouldPoll, 'chatUid:', chatUid);\n usePolling(\n shouldPoll ? chatUid : null,\n async () => {\n logRef.current.log('[useDevicChat] fetchFn called, chatUid:', chatUid);\n if (!clientRef.current || !chatUid) {\n throw new Error('Cannot poll without client or chatUid');\n }\n const result = await clientRef.current.getRealtimeHistory(assistantId, chatUid);\n logRef.current.log('[useDevicChat] getRealtimeHistory result:', result);\n return result;\n },\n {\n interval: pollingInterval,\n enabled: shouldPoll,\n stopStatuses: ['completed', 'error', 'waiting_for_tool_response', 'handed_off'],\n onUpdate: async (data: RealtimeChatHistory) => {\n logRef.current.log('[useDevicChat] onUpdate called, status:', data.status);\n\n // Merge realtime data with optimistic messages\n setMessages((prev) => {\n const realtimeUIDs = new Set(data.chatHistory.map((m) => m.uid));\n const realtimeUserMessages = new Set(\n data.chatHistory\n .filter((m) => m.role === 'user')\n .map((m) => m.content?.message)\n );\n\n // Keep optimistic messages not yet in realtime data\n const optimistic = prev.filter((m) => {\n if (realtimeUIDs.has(m.uid)) return false;\n if (m.role === 'user' && realtimeUserMessages.has(m.content?.message)) return false;\n return true;\n });\n\n return [...data.chatHistory, ...optimistic];\n });\n setStatus(data.status);\n\n // Notify about new messages\n const lastMessage = data.chatHistory[data.chatHistory.length - 1];\n if (lastMessage && lastMessage.role === 'assistant') {\n onMessageReceivedRef.current?.(lastMessage);\n }\n\n // Handle model interface - check for pending tool calls\n if (data.status === 'waiting_for_tool_response' || data.pendingToolCalls?.length) {\n await handlePendingToolCalls(data);\n }\n },\n onStop: (data) => {\n logRef.current.log('[useDevicChat] onStop called, status:', data?.status);\n setShouldPoll(false);\n\n if (data?.status === 'error') {\n setIsLoading(false);\n const err = new Error('Chat processing failed');\n setError(err);\n onErrorRef.current?.(err);\n } else if (data?.status === 'completed') {\n setIsLoading(false);\n } else if (data?.status === 'handed_off') {\n // Subagent is working — keep isLoading true so the UI stays in loading state.\n // Set handoff state directly from the realtime status.\n setHandedOff(true);\n\n const subThreadId = data.handedOffSubThreadId || null;\n logRef.current.log('[useDevicChat] Handoff state set:', { handedOff: true, subThreadId });\n if (subThreadId) {\n setHandedOffSubThreadId(subThreadId);\n }\n }\n // Note: waiting_for_tool_response is handled in onUpdate to avoid double execution\n },\n onError: (err) => {\n logRef.current.error('[useDevicChat] onError called:', err);\n setError(err);\n setIsLoading(false);\n setShouldPoll(false);\n onErrorRef.current?.(err);\n },\n debug,\n }\n );\n\n // Handle pending tool calls from model interface\n const handlePendingToolCalls = useCallback(\n async (data: RealtimeChatHistory) => {\n if (!clientRef.current || !chatUid) return;\n\n // Get pending tool calls\n const pendingCalls = data.pendingToolCalls || extractPendingToolCalls(data.chatHistory);\n\n if (pendingCalls.length === 0) return;\n\n try {\n // Execute client-side tools\n const responses = await handleToolCalls(pendingCalls);\n\n if (responses.length > 0) {\n // Send tool responses back to the API\n await clientRef.current.sendToolResponses(assistantId, chatUid, responses);\n\n // Resume polling\n setShouldPoll(true);\n setIsLoading(true);\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n }\n },\n [chatUid, assistantId, handleToolCalls, extractPendingToolCalls]\n );\n\n // Send a message\n const sendMessage = useCallback(\n async (\n message: string,\n sendOptions?: {\n files?: ChatFile[];\n metadata?: Record<string, any>;\n }\n ) => {\n if (!clientRef.current) {\n const err = new Error(\n 'API client not configured. Please provide an API key.'\n );\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n setStatus('processing');\n\n // Add user message optimistically\n const userMessage: ChatMessage = {\n uid: `temp-${Date.now()}`,\n role: 'user',\n content: {\n message,\n files: sendOptions?.files?.map((f) => ({\n name: f.name,\n url: f.downloadUrl || '',\n type: f.fileType || 'other',\n })),\n },\n timestamp: Date.now(),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n onMessageSent?.(userMessage);\n\n try {\n // Build request DTO\n const dto = {\n message,\n chatUid: chatUid || undefined,\n files: sendOptions?.files,\n metadata: {\n ...resolvedTenantMetadata,\n ...sendOptions?.metadata,\n },\n tenantId: resolvedTenantId,\n enabledTools,\n // Include model interface tools if any\n ...(toolSchemas.length > 0 && { tools: toolSchemas }),\n };\n\n // Send message in async mode\n logRef.current.log('[useDevicChat] Sending message async...');\n const response = await clientRef.current.sendMessageAsync(assistantId, dto);\n logRef.current.log('[useDevicChat] sendMessageAsync response:', response);\n\n // Update chat UID if this is a new chat\n if (response.chatUid && response.chatUid !== chatUid) {\n logRef.current.log('[useDevicChat] Setting chatUid:', response.chatUid);\n setChatUid(response.chatUid);\n onChatCreatedRef.current?.(response.chatUid);\n }\n\n // Start polling for results\n logRef.current.log('[useDevicChat] Setting shouldPoll to true');\n setShouldPoll(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setIsLoading(false);\n setStatus('error');\n onErrorRef.current?.(error);\n\n // Remove optimistic user message on error\n setMessages((prev) => prev.filter((m) => m.uid !== userMessage.uid));\n }\n },\n [\n chatUid,\n assistantId,\n enabledTools,\n resolvedTenantId,\n resolvedTenantMetadata,\n toolSchemas,\n onMessageSent,\n ]\n );\n\n // Clear chat\n const clearChat = useCallback(() => {\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setMessages([]);\n setChatUid(null);\n setIsLoading(false);\n setStatus('idle');\n setError(null);\n }, []);\n\n // Load existing chat\n const loadChat = useCallback(\n async (loadChatUid: string) => {\n if (!clientRef.current) {\n const err = new Error('API client not configured');\n setError(err);\n onErrorRef.current?.(err);\n return;\n }\n\n // Reset any active polling/handoff state from previous conversation\n setShouldPoll(false);\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const history = await clientRef.current.getChatHistory(\n assistantId,\n loadChatUid,\n { tenantId: resolvedTenantId }\n );\n\n setMessages(history.chatContent);\n setChatUid(loadChatUid);\n\n // Check realtime status to resume in-progress conversations\n await resumeFromRealtimeStatus(loadChatUid);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n setIsLoading(false);\n }\n },\n [assistantId, resolvedTenantId, resumeFromRealtimeStatus]\n );\n\n // Handoff polling: while handedOff is true, poll the realtime endpoint every 5s\n // to detect when the parent thread is no longer in handed_off state.\n useEffect(() => {\n if (!handedOff || !chatUid || !clientRef.current) return;\n\n const pollHandoff = async () => {\n try {\n const realtime = await clientRef.current!.getRealtimeHistory(assistantId, chatUid!);\n logRef.current.log('[useDevicChat] Handoff poll - realtime status:', realtime.status);\n if (realtime.status !== 'handed_off') {\n // Handoff completed — clear handoff state and resume main polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n // Resume main polling to pick up the parent thread's continuation\n setShouldPoll(true);\n }\n } catch {}\n };\n\n handoffPollRef.current = setInterval(pollHandoff, 5000);\n return () => {\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n };\n }, [handedOff, chatUid, assistantId]);\n\n // Called by HandoffSubagentWidget when the subthread reaches a terminal state\n const onHandoffCompleted = useCallback(() => {\n logRef.current.log('[useDevicChat] onHandoffCompleted called');\n // Clear the handoff polling\n if (handoffPollRef.current) {\n clearInterval(handoffPollRef.current);\n handoffPollRef.current = null;\n }\n // Clear handoff state and resume main polling\n setHandedOff(false);\n setHandedOffSubThreadId(null);\n setShouldPoll(true);\n }, []);\n\n // Stop current conversation — calls the server-side stop endpoint\n // then stops polling and resets loading state.\n const stopChat = useCallback(async () => {\n const uid = chatUidRef.current;\n logRef.current.log('[useDevicChat] stopChat called, chatUid:', uid);\n if (clientRef.current && uid) {\n try {\n await clientRef.current.stopChat(assistantId, uid);\n logRef.current.log('[useDevicChat] stopChat API call succeeded');\n } catch (err) {\n logRef.current.warn('[useDevicChat] stopChat API call failed:', err);\n }\n }\n setShouldPoll(false);\n setIsLoading(false);\n setStatus('idle');\n }, [assistantId]);\n\n return {\n messages,\n chatUid,\n isLoading,\n status,\n error,\n handedOff,\n handedOffSubThreadId,\n sendMessage,\n clearChat,\n loadChat,\n onHandoffCompleted,\n stopChat,\n };\n}\n"],"names":["useOptionalDevicContext","useMemo","createLogger","useRef","useState","useEffect","DevicApiClient","useCallback","useModelInterface","usePolling"],"mappings":";;;;;;;;;;AAoKA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,MAAM,EACJ,WAAW,EACX,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,EACrB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,mBAAmB,GAAG,EAAE,EACxB,eAAe,GAAG,IAAI,EACtB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,aAAa,EACb,KAAK,EAAE,UAAU,GAClB,GAAG,OAAO;;AAGX,IAAA,MAAM,OAAO,GAAGA,oCAAuB,EAAE;;AAGzC,IAAA,MAAM,MAAM,GAAG,WAAW,IAAI,OAAO,EAAE,MAAM;IAC7C,MAAM,OAAO,GAAG,YAAY,IAAI,OAAO,EAAE,OAAO,IAAI,sBAAsB;AAC1E,IAAA,MAAM,gBAAgB,GAAG,QAAQ,IAAI,OAAO,EAAE,QAAQ;IACtD,MAAM,sBAAsB,GAAG,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;IAChF,MAAM,KAAK,GAAG,UAAU,IAAI,OAAO,EAAE,KAAK,IAAI,KAAK;AACnD,IAAA,MAAM,GAAG,GAAGC,aAAO,CAAC,MAAMC,mBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACvD,IAAA,MAAM,MAAM,GAAGC,YAAM,CAAC,GAAG,CAAC;AAC1B,IAAA,MAAM,CAAC,OAAO,GAAG,GAAG;;IAGpB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAGC,cAAQ,CAAgB,EAAE,CAAC;AAC3D,IAAA,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGA,cAAQ,CAAgB,cAAc,IAAI,IAAI,CAAC;IAC7E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IACjD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAGA,cAAQ,CAA0B,MAAM,CAAC;IACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAGA,cAAQ,CAAe,IAAI,CAAC;;IAGtD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IACjD,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAGA,cAAQ,CAAgB,IAAI,CAAC;AACrF,IAAA,MAAM,cAAc,GAAGD,YAAM,CAAwC,IAAI,CAAC;;IAG1E,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAGC,cAAQ,CAAC,KAAK,CAAC;;AAGnD,IAAA,MAAM,UAAU,GAAGD,YAAM,CAAC,OAAO,CAAC;AAClC,IAAA,UAAU,CAAC,OAAO,GAAG,OAAO;;AAG5B,IAAA,MAAM,oBAAoB,GAAGA,YAAM,CAAC,iBAAiB,CAAC;AACtD,IAAA,MAAM,UAAU,GAAGA,YAAM,CAAC,OAAO,CAAC;AAClC,IAAA,MAAM,gBAAgB,GAAGA,YAAM,CAAC,aAAa,CAAC;IAE9CE,eAAS,CAAC,MAAK;AACb,QAAA,oBAAoB,CAAC,OAAO,GAAG,iBAAiB;AAChD,QAAA,UAAU,CAAC,OAAO,GAAG,OAAO;AAC5B,QAAA,gBAAgB,CAAC,OAAO,GAAG,aAAa;AAC1C,IAAA,CAAC,CAAC;;AAGF,IAAA,MAAM,SAAS,GAAGF,YAAM,CAAwB,IAAI,CAAC;AACrD,IAAA,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,MAAM,EAAE;AAChC,QAAA,SAAS,CAAC,OAAO,GAAG,IAAIG,qBAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7D;;IAGAD,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,MAAM,EAAE;YAC/B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAClD;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;IAIrB,MAAM,wBAAwB,GAAGE,iBAAW,CAC1C,OAAO,aAAqB,KAAI;QAC9B,IAAI,CAAC,SAAS,CAAC,OAAO;YAAE;AACxB,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC;YACvF,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,QAAQ,CAAC,MAAM,CAAC;;AAG/E,YAAA,IAAI,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE;AAChC,gBAAA,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC;YACnC;AACA,YAAA,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;AAE1B,YAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE;;gBAEpC,YAAY,CAAC,IAAI,CAAC;gBAClB,aAAa,CAAC,IAAI,CAAC;YACrB;AAAO,iBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,2BAA2B,EAAE;;gBAE1D,YAAY,CAAC,IAAI,CAAC;gBAClB,aAAa,CAAC,IAAI,CAAC;YACrB;AAAO,iBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE;;gBAE3C,YAAY,CAAC,IAAI,CAAC;gBAClB,YAAY,CAAC,IAAI,CAAC;AAClB,gBAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,oBAAoB,IAAI,IAAI;gBACzD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,EAAE,WAAW,EAAE,CAAC;gBAC7E,IAAI,WAAW,EAAE;oBACf,uBAAuB,CAAC,WAAW,CAAC;gBACtC;YACF;iBAAO;;gBAEL,YAAY,CAAC,KAAK,CAAC;YACrB;QACF;QAAE,OAAO,GAAG,EAAE;;YAEZ,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,GAAG,CAAC;YAC3E,YAAY,CAAC,KAAK,CAAC;QACrB;AACF,IAAA,CAAC,EACD,CAAC,WAAW,CAAC,CACd;;;AAID,IAAA,MAAM,oBAAoB,GAAGJ,YAAM,CAAC,KAAK,CAAC;IAC1CE,eAAS,CAAC,MAAK;QACb,IAAI,cAAc,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE;AACxE,YAAA,oBAAoB,CAAC,OAAO,GAAG,IAAI;AAEnC,YAAA,MAAM,eAAe,GAAG,YAAW;gBACjC,YAAY,CAAC,IAAI,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC;AACd,gBAAA,IAAI;AACF,oBAAA,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAQ,CAAC,cAAc,CACrD,WAAW,EACX,cAAc,EACd,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAC/B;AACD,oBAAA,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC;oBAChC,UAAU,CAAC,cAAc,CAAC;;AAG1B,oBAAA,MAAM,wBAAwB,CAAC,cAAc,CAAC;gBAChD;gBAAE,OAAO,GAAG,EAAE;oBACZ,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjE,QAAQ,CAAC,KAAK,CAAC;AACf,oBAAA,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;oBAC3B,YAAY,CAAC,KAAK,CAAC;gBACrB;AACF,YAAA,CAAC;AAED,YAAA,eAAe,EAAE;QACnB;IACF,CAAC,EAAE,CAAC,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;;IAG7E,MAAM,EACJ,WAAW,EACX,eAAe,EACf,uBAAuB,GACxB,GAAGG,mCAAiB,CAAC;AACpB,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,aAAa,EAAE,UAAU;AAC1B,KAAA,CAAC;;AAGF,IAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC;AAC1F,IAAAC,qBAAU,CACR,UAAU,GAAG,OAAO,GAAG,IAAI,EAC3B,YAAW;QACT,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yCAAyC,EAAE,OAAO,CAAC;QACtE,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE;AAClC,YAAA,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC;QAC1D;AACA,QAAA,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC;QAC/E,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,MAAM,CAAC;AACvE,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,EACD;AACE,QAAA,QAAQ,EAAE,eAAe;AACzB,QAAA,OAAO,EAAE,UAAU;QACnB,YAAY,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,2BAA2B,EAAE,YAAY,CAAC;AAC/E,QAAA,QAAQ,EAAE,OAAO,IAAyB,KAAI;YAC5C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yCAAyC,EAAE,IAAI,CAAC,MAAM,CAAC;;AAG1E,YAAA,WAAW,CAAC,CAAC,IAAI,KAAI;gBACnB,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AAChE,gBAAA,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,IAAI,CAAC;qBACF,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM;AAC/B,qBAAA,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAClC;;gBAGD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AACnC,oBAAA,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAAE,wBAAA,OAAO,KAAK;AACzC,oBAAA,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;AAAE,wBAAA,OAAO,KAAK;AACnF,oBAAA,OAAO,IAAI;AACb,gBAAA,CAAC,CAAC;gBAEF,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC;AAC7C,YAAA,CAAC,CAAC;AACF,YAAA,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;;AAGtB,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;YACjE,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE;AACnD,gBAAA,oBAAoB,CAAC,OAAO,GAAG,WAAW,CAAC;YAC7C;;AAGA,YAAA,IAAI,IAAI,CAAC,MAAM,KAAK,2BAA2B,IAAI,IAAI,CAAC,gBAAgB,EAAE,MAAM,EAAE;AAChF,gBAAA,MAAM,sBAAsB,CAAC,IAAI,CAAC;YACpC;QACF,CAAC;AACD,QAAA,MAAM,EAAE,CAAC,IAAI,KAAI;YACf,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,IAAI,EAAE,MAAM,CAAC;YACzE,aAAa,CAAC,KAAK,CAAC;AAEpB,YAAA,IAAI,IAAI,EAAE,MAAM,KAAK,OAAO,EAAE;gBAC5B,YAAY,CAAC,KAAK,CAAC;AACnB,gBAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,wBAAwB,CAAC;gBAC/C,QAAQ,CAAC,GAAG,CAAC;AACb,gBAAA,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC;YAC3B;AAAO,iBAAA,IAAI,IAAI,EAAE,MAAM,KAAK,WAAW,EAAE;gBACvC,YAAY,CAAC,KAAK,CAAC;YACrB;AAAO,iBAAA,IAAI,IAAI,EAAE,MAAM,KAAK,YAAY,EAAE;;;gBAGxC,YAAY,CAAC,IAAI,CAAC;AAElB,gBAAA,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI;AACrD,gBAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;gBACzF,IAAI,WAAW,EAAE;oBACf,uBAAuB,CAAC,WAAW,CAAC;gBACtC;YACF;;QAEF,CAAC;AACD,QAAA,OAAO,EAAE,CAAC,GAAG,KAAI;YACf,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC;YAC3D,QAAQ,CAAC,GAAG,CAAC;YACb,YAAY,CAAC,KAAK,CAAC;YACnB,aAAa,CAAC,KAAK,CAAC;AACpB,YAAA,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC;QAC3B,CAAC;QACD,KAAK;AACN,KAAA,CACF;;IAGD,MAAM,sBAAsB,GAAGF,iBAAW,CACxC,OAAO,IAAyB,KAAI;AAClC,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO;YAAE;;AAGpC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,CAAC,IAAI,CAAC,WAAW,CAAC;AAEvF,QAAA,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE;AAE/B,QAAA,IAAI;;AAEF,YAAA,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC;AAErD,YAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;;AAExB,gBAAA,MAAM,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,CAAC;;gBAG1E,aAAa,CAAC,IAAI,CAAC;gBACnB,YAAY,CAAC,IAAI,CAAC;YACpB;QACF;QAAE,OAAO,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,QAAQ,CAAC,KAAK,CAAC;AACf,YAAA,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;QAC7B;IACF,CAAC,EACD,CAAC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,uBAAuB,CAAC,CACjE;;IAGD,MAAM,WAAW,GAAGA,iBAAW,CAC7B,OACE,OAAe,EACf,WAGC,KACC;AACF,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;AACtB,YAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,uDAAuD,CACxD;YACD,QAAQ,CAAC,GAAG,CAAC;AACb,YAAA,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC;YACzB;QACF;QAEA,YAAY,CAAC,IAAI,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC;QACd,SAAS,CAAC,YAAY,CAAC;;AAGvB,QAAA,MAAM,WAAW,GAAgB;AAC/B,YAAA,GAAG,EAAE,CAAA,KAAA,EAAQ,IAAI,CAAC,GAAG,EAAE,CAAA,CAAE;AACzB,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,OAAO,EAAE;gBACP,OAAO;AACP,gBAAA,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM;oBACrC,IAAI,EAAE,CAAC,CAAC,IAAI;AACZ,oBAAA,GAAG,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;AACxB,oBAAA,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,OAAO;AAC5B,iBAAA,CAAC,CAAC;AACJ,aAAA;AACD,YAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB;AAED,QAAA,WAAW,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC;AAC7C,QAAA,aAAa,GAAG,WAAW,CAAC;AAE5B,QAAA,IAAI;;AAEF,YAAA,MAAM,GAAG,GAAG;gBACV,OAAO;gBACP,OAAO,EAAE,OAAO,IAAI,SAAS;gBAC7B,KAAK,EAAE,WAAW,EAAE,KAAK;AACzB,gBAAA,QAAQ,EAAE;AACR,oBAAA,GAAG,sBAAsB;oBACzB,GAAG,WAAW,EAAE,QAAQ;AACzB,iBAAA;AACD,gBAAA,QAAQ,EAAE,gBAAgB;gBAC1B,YAAY;;AAEZ,gBAAA,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;aACtD;;AAGD,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC;AAC7D,YAAA,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC;YAC3E,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,QAAQ,CAAC;;YAGzE,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,OAAO,EAAE;gBACpD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,QAAQ,CAAC,OAAO,CAAC;AACvE,gBAAA,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC5B,gBAAgB,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YAC9C;;AAGA,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC;YAC/D,aAAa,CAAC,IAAI,CAAC;QACrB;QAAE,OAAO,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,QAAQ,CAAC,KAAK,CAAC;YACf,YAAY,CAAC,KAAK,CAAC;YACnB,SAAS,CAAC,OAAO,CAAC;AAClB,YAAA,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;;YAG3B,WAAW,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,WAAW,CAAC,GAAG,CAAC,CAAC;QACtE;AACF,IAAA,CAAC,EACD;QACE,OAAO;QACP,WAAW;QACX,YAAY;QACZ,gBAAgB;QAChB,sBAAsB;QACtB,WAAW;QACX,aAAa;AACd,KAAA,CACF;;AAGD,IAAA,MAAM,SAAS,GAAGA,iBAAW,CAAC,MAAK;QACjC,aAAa,CAAC,KAAK,CAAC;QACpB,YAAY,CAAC,KAAK,CAAC;QACnB,uBAAuB,CAAC,IAAI,CAAC;AAC7B,QAAA,IAAI,cAAc,CAAC,OAAO,EAAE;AAC1B,YAAA,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC;AACrC,YAAA,cAAc,CAAC,OAAO,GAAG,IAAI;QAC/B;QACA,WAAW,CAAC,EAAE,CAAC;QACf,UAAU,CAAC,IAAI,CAAC;QAChB,YAAY,CAAC,KAAK,CAAC;QACnB,SAAS,CAAC,MAAM,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC;;IAGN,MAAM,QAAQ,GAAGA,iBAAW,CAC1B,OAAO,WAAmB,KAAI;AAC5B,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;AACtB,YAAA,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,2BAA2B,CAAC;YAClD,QAAQ,CAAC,GAAG,CAAC;AACb,YAAA,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC;YACzB;QACF;;QAGA,aAAa,CAAC,KAAK,CAAC;QACpB,YAAY,CAAC,KAAK,CAAC;QACnB,uBAAuB,CAAC,IAAI,CAAC;AAC7B,QAAA,IAAI,cAAc,CAAC,OAAO,EAAE;AAC1B,YAAA,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC;AACrC,YAAA,cAAc,CAAC,OAAO,GAAG,IAAI;QAC/B;QAEA,YAAY,CAAC,IAAI,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC;AAEd,QAAA,IAAI;AACF,YAAA,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,cAAc,CACpD,WAAW,EACX,WAAW,EACX,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAC/B;AAED,YAAA,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC;YAChC,UAAU,CAAC,WAAW,CAAC;;AAGvB,YAAA,MAAM,wBAAwB,CAAC,WAAW,CAAC;QAC7C;QAAE,OAAO,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,QAAQ,CAAC,KAAK,CAAC;AACf,YAAA,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;YAC3B,YAAY,CAAC,KAAK,CAAC;QACrB;IACF,CAAC,EACD,CAAC,WAAW,EAAE,gBAAgB,EAAE,wBAAwB,CAAC,CAC1D;;;IAIDF,eAAS,CAAC,MAAK;QACb,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO;YAAE;AAElD,QAAA,MAAM,WAAW,GAAG,YAAW;AAC7B,YAAA,IAAI;AACF,gBAAA,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAQ,CAAC,kBAAkB,CAAC,WAAW,EAAE,OAAQ,CAAC;gBACnF,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gDAAgD,EAAE,QAAQ,CAAC,MAAM,CAAC;AACrF,gBAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE;;AAEpC,oBAAA,IAAI,cAAc,CAAC,OAAO,EAAE;AAC1B,wBAAA,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC;AACrC,wBAAA,cAAc,CAAC,OAAO,GAAG,IAAI;oBAC/B;oBACA,YAAY,CAAC,KAAK,CAAC;oBACnB,uBAAuB,CAAC,IAAI,CAAC;;oBAE7B,aAAa,CAAC,IAAI,CAAC;gBACrB;YACF;YAAE,MAAM,EAAC;AACX,QAAA,CAAC;QAED,cAAc,CAAC,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC;AACvD,QAAA,OAAO,MAAK;AACV,YAAA,IAAI,cAAc,CAAC,OAAO,EAAE;AAC1B,gBAAA,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC;AACrC,gBAAA,cAAc,CAAC,OAAO,GAAG,IAAI;YAC/B;AACF,QAAA,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;;AAGrC,IAAA,MAAM,kBAAkB,GAAGE,iBAAW,CAAC,MAAK;AAC1C,QAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC;;AAE9D,QAAA,IAAI,cAAc,CAAC,OAAO,EAAE;AAC1B,YAAA,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC;AACrC,YAAA,cAAc,CAAC,OAAO,GAAG,IAAI;QAC/B;;QAEA,YAAY,CAAC,KAAK,CAAC;QACnB,uBAAuB,CAAC,IAAI,CAAC;QAC7B,aAAa,CAAC,IAAI,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC;;;AAIN,IAAA,MAAM,QAAQ,GAAGA,iBAAW,CAAC,YAAW;AACtC,QAAA,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,GAAG,CAAC;AACnE,QAAA,IAAI,SAAS,CAAC,OAAO,IAAI,GAAG,EAAE;AAC5B,YAAA,IAAI;gBACF,MAAM,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;AAClD,gBAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC;YAClE;YAAE,OAAO,GAAG,EAAE;gBACZ,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,GAAG,CAAC;YACtE;QACF;QACA,aAAa,CAAC,KAAK,CAAC;QACpB,YAAY,CAAC,KAAK,CAAC;QACnB,SAAS,CAAC,MAAM,CAAC;AACnB,IAAA,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IAEjB,OAAO;QACL,QAAQ;QACR,OAAO;QACP,SAAS;QACT,MAAM;QACN,KAAK;QACL,SAAS;QACT,oBAAoB;QACpB,WAAW;QACX,SAAS;QACT,QAAQ;QACR,kBAAkB;QAClB,QAAQ;KACT;AACH;;;;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
+
var logger = require('../utils/logger.js');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Hook for polling real-time chat history
|
|
@@ -10,7 +11,10 @@ var React = require('react');
|
|
|
10
11
|
* @param options - Polling options
|
|
11
12
|
*/
|
|
12
13
|
function usePolling(chatUid, fetchFn, options = {}) {
|
|
13
|
-
const { interval = 1000, enabled = true, stopStatuses = ['completed', 'error'], onStop, onUpdate, onError, } = options;
|
|
14
|
+
const { interval = 1000, enabled = true, stopStatuses = ['completed', 'error'], onStop, onUpdate, onError, debug = false, } = options;
|
|
15
|
+
const log = React.useMemo(() => logger.createLogger(debug), [debug]);
|
|
16
|
+
const logRef = React.useRef(log);
|
|
17
|
+
logRef.current = log;
|
|
14
18
|
const [data, setData] = React.useState(null);
|
|
15
19
|
const [isPolling, setIsPolling] = React.useState(false);
|
|
16
20
|
const [error, setError] = React.useState(null);
|
|
@@ -40,13 +44,13 @@ function usePolling(chatUid, fetchFn, options = {}) {
|
|
|
40
44
|
isPollingRef.current = false;
|
|
41
45
|
}, []);
|
|
42
46
|
const fetchData = React.useCallback(async () => {
|
|
43
|
-
|
|
47
|
+
logRef.current.log('[usePolling] fetchData called, isMounted:', isMountedRef.current);
|
|
44
48
|
if (!isMountedRef.current)
|
|
45
49
|
return;
|
|
46
50
|
try {
|
|
47
|
-
|
|
51
|
+
logRef.current.log('[usePolling] Fetching...');
|
|
48
52
|
const result = await fetchFnRef.current();
|
|
49
|
-
|
|
53
|
+
logRef.current.log('[usePolling] Fetch result:', { status: result.status, messageCount: result.chatHistory?.length });
|
|
50
54
|
if (!isMountedRef.current)
|
|
51
55
|
return;
|
|
52
56
|
setData(result);
|
|
@@ -54,16 +58,16 @@ function usePolling(chatUid, fetchFn, options = {}) {
|
|
|
54
58
|
onUpdateRef.current?.(result);
|
|
55
59
|
// Check if we should stop polling
|
|
56
60
|
const shouldStop = stopStatusesRef.current.includes(result.status);
|
|
57
|
-
|
|
61
|
+
logRef.current.log('[usePolling] Should stop?', shouldStop, 'stopStatuses:', stopStatusesRef.current, 'current status:', result.status);
|
|
58
62
|
if (shouldStop) {
|
|
59
|
-
|
|
63
|
+
logRef.current.log('[usePolling] Stopping polling due to status:', result.status);
|
|
60
64
|
clearPolling();
|
|
61
65
|
setIsPolling(false);
|
|
62
66
|
onStopRef.current?.(result);
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
catch (err) {
|
|
66
|
-
|
|
70
|
+
logRef.current.error('[usePolling] Fetch error:', err);
|
|
67
71
|
if (!isMountedRef.current)
|
|
68
72
|
return;
|
|
69
73
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -94,9 +98,9 @@ function usePolling(chatUid, fetchFn, options = {}) {
|
|
|
94
98
|
}, [fetchData]);
|
|
95
99
|
// Auto-start polling when enabled and chatUid is set
|
|
96
100
|
React.useEffect(() => {
|
|
97
|
-
|
|
101
|
+
logRef.current.log('[usePolling] Auto-start effect triggered:', { enabled, chatUid, isPollingRef: isPollingRef.current, intervalRef: !!intervalRef.current });
|
|
98
102
|
if (!enabled || !chatUid) {
|
|
99
|
-
|
|
103
|
+
logRef.current.log('[usePolling] Not enabled or no chatUid, stopping if active');
|
|
100
104
|
// Stop polling if disabled or no chatUid
|
|
101
105
|
if (isPollingRef.current) {
|
|
102
106
|
clearPolling();
|
|
@@ -106,7 +110,7 @@ function usePolling(chatUid, fetchFn, options = {}) {
|
|
|
106
110
|
}
|
|
107
111
|
// Start polling if not already polling
|
|
108
112
|
if (!isPollingRef.current) {
|
|
109
|
-
|
|
113
|
+
logRef.current.log('[usePolling] Starting polling, interval:', intervalValueRef.current);
|
|
110
114
|
isPollingRef.current = true;
|
|
111
115
|
setIsPolling(true);
|
|
112
116
|
setError(null);
|
|
@@ -114,10 +118,10 @@ function usePolling(chatUid, fetchFn, options = {}) {
|
|
|
114
118
|
fetchData();
|
|
115
119
|
// Set up interval
|
|
116
120
|
intervalRef.current = setInterval(fetchData, intervalValueRef.current);
|
|
117
|
-
|
|
121
|
+
logRef.current.log('[usePolling] Interval set:', intervalRef.current);
|
|
118
122
|
}
|
|
119
123
|
else {
|
|
120
|
-
|
|
124
|
+
logRef.current.log('[usePolling] Already polling, skipping start');
|
|
121
125
|
}
|
|
122
126
|
// Only cleanup on unmount, not on every dependency change
|
|
123
127
|
}, [enabled, chatUid, fetchData, clearPolling]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePolling.js","sources":["../../../../src/hooks/usePolling.ts"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport type { RealtimeChatHistory, RealtimeStatus } from '../api/types';\n\nexport interface UsePollingOptions {\n /**\n * Polling interval in milliseconds\n * @default 1000\n */\n interval?: number;\n\n /**\n * Whether polling is enabled\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Statuses that should stop polling\n * @default ['completed', 'error']\n */\n stopStatuses?: RealtimeStatus[];\n\n /**\n * Callback when polling stops\n */\n onStop?: (data: RealtimeChatHistory | null) => void;\n\n /**\n * Callback on each poll update\n */\n onUpdate?: (data: RealtimeChatHistory) => void;\n\n /**\n * Callback on poll error\n */\n onError?: (error: Error) => void;\n}\n\nexport interface UsePollingResult {\n /**\n * Current polling data\n */\n data: RealtimeChatHistory | null;\n\n /**\n * Whether polling is currently active\n */\n isPolling: boolean;\n\n /**\n * Last error that occurred\n */\n error: Error | null;\n\n /**\n * Start polling\n */\n start: () => void;\n\n /**\n * Stop polling\n */\n stop: () => void;\n\n /**\n * Manually trigger a fetch\n */\n refetch: () => Promise<void>;\n}\n\n/**\n * Hook for polling real-time chat history\n *\n * @param chatUid - The chat UID to poll for\n * @param fetchFn - Function that fetches the realtime history\n * @param options - Polling options\n */\nexport function usePolling(\n chatUid: string | null,\n fetchFn: () => Promise<RealtimeChatHistory>,\n options: UsePollingOptions = {}\n): UsePollingResult {\n const {\n interval = 1000,\n enabled = true,\n stopStatuses = ['completed', 'error'],\n onStop,\n onUpdate,\n onError,\n } = options;\n\n const [data, setData] = useState<RealtimeChatHistory | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const isMountedRef = useRef(true);\n\n // Refs for callbacks and options to avoid stale closures and unnecessary re-renders\n const onStopRef = useRef(onStop);\n const onUpdateRef = useRef(onUpdate);\n const onErrorRef = useRef(onError);\n const fetchFnRef = useRef(fetchFn);\n const stopStatusesRef = useRef(stopStatuses);\n const intervalValueRef = useRef(interval);\n const isPollingRef = useRef(false);\n\n useEffect(() => {\n onStopRef.current = onStop;\n onUpdateRef.current = onUpdate;\n onErrorRef.current = onError;\n fetchFnRef.current = fetchFn;\n stopStatusesRef.current = stopStatuses;\n intervalValueRef.current = interval;\n });\n\n const clearPolling = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n isPollingRef.current = false;\n }, []);\n\n const fetchData = useCallback(async () => {\n console.log('[usePolling] fetchData called, isMounted:', isMountedRef.current);\n if (!isMountedRef.current) return;\n\n try {\n console.log('[usePolling] Fetching...');\n const result = await fetchFnRef.current();\n console.log('[usePolling] Fetch result:', { status: result.status, messageCount: result.chatHistory?.length });\n\n if (!isMountedRef.current) return;\n\n setData(result);\n setError(null);\n onUpdateRef.current?.(result);\n\n // Check if we should stop polling\n const shouldStop = stopStatusesRef.current.includes(result.status);\n console.log('[usePolling] Should stop?', shouldStop, 'stopStatuses:', stopStatusesRef.current, 'current status:', result.status);\n if (shouldStop) {\n console.log('[usePolling] Stopping polling due to status:', result.status);\n clearPolling();\n setIsPolling(false);\n onStopRef.current?.(result);\n }\n } catch (err) {\n console.error('[usePolling] Fetch error:', err);\n if (!isMountedRef.current) return;\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n\n // Stop polling on error\n clearPolling();\n setIsPolling(false);\n }\n }, [clearPolling]);\n\n const start = useCallback(() => {\n if (intervalRef.current) return;\n\n isPollingRef.current = true;\n setIsPolling(true);\n setError(null);\n\n // Immediate first fetch\n fetchData();\n\n // Set up interval\n intervalRef.current = setInterval(fetchData, intervalValueRef.current);\n }, [fetchData]);\n\n const stop = useCallback(() => {\n clearPolling();\n setIsPolling(false);\n }, [clearPolling]);\n\n const refetch = useCallback(async () => {\n await fetchData();\n }, [fetchData]);\n\n // Auto-start polling when enabled and chatUid is set\n useEffect(() => {\n console.log('[usePolling] Auto-start effect triggered:', { enabled, chatUid, isPollingRef: isPollingRef.current, intervalRef: !!intervalRef.current });\n\n if (!enabled || !chatUid) {\n console.log('[usePolling] Not enabled or no chatUid, stopping if active');\n // Stop polling if disabled or no chatUid\n if (isPollingRef.current) {\n clearPolling();\n setIsPolling(false);\n }\n return;\n }\n\n // Start polling if not already polling\n if (!isPollingRef.current) {\n console.log('[usePolling] Starting polling, interval:', intervalValueRef.current);\n isPollingRef.current = true;\n setIsPolling(true);\n setError(null);\n\n // Immediate first fetch\n fetchData();\n\n // Set up interval\n intervalRef.current = setInterval(fetchData, intervalValueRef.current);\n console.log('[usePolling] Interval set:', intervalRef.current);\n } else {\n console.log('[usePolling] Already polling, skipping start');\n }\n\n // Only cleanup on unmount, not on every dependency change\n }, [enabled, chatUid, fetchData, clearPolling]);\n\n // Cleanup on unmount\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n clearPolling();\n };\n }, [clearPolling]);\n\n return {\n data,\n isPolling,\n error,\n start,\n stop,\n refetch,\n };\n}\n"],"names":["useState","useRef","useEffect","useCallback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePolling.js","sources":["../../../../src/hooks/usePolling.ts"],"sourcesContent":["import { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport type { RealtimeChatHistory, RealtimeStatus } from '../api/types';\nimport { createLogger } from '../utils/logger';\n\nexport interface UsePollingOptions {\n /**\n * Polling interval in milliseconds\n * @default 1000\n */\n interval?: number;\n\n /**\n * Whether polling is enabled\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Statuses that should stop polling\n * @default ['completed', 'error']\n */\n stopStatuses?: RealtimeStatus[];\n\n /**\n * Callback when polling stops\n */\n onStop?: (data: RealtimeChatHistory | null) => void;\n\n /**\n * Callback on each poll update\n */\n onUpdate?: (data: RealtimeChatHistory) => void;\n\n /**\n * Callback on poll error\n */\n onError?: (error: Error) => void;\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean;\n}\n\nexport interface UsePollingResult {\n /**\n * Current polling data\n */\n data: RealtimeChatHistory | null;\n\n /**\n * Whether polling is currently active\n */\n isPolling: boolean;\n\n /**\n * Last error that occurred\n */\n error: Error | null;\n\n /**\n * Start polling\n */\n start: () => void;\n\n /**\n * Stop polling\n */\n stop: () => void;\n\n /**\n * Manually trigger a fetch\n */\n refetch: () => Promise<void>;\n}\n\n/**\n * Hook for polling real-time chat history\n *\n * @param chatUid - The chat UID to poll for\n * @param fetchFn - Function that fetches the realtime history\n * @param options - Polling options\n */\nexport function usePolling(\n chatUid: string | null,\n fetchFn: () => Promise<RealtimeChatHistory>,\n options: UsePollingOptions = {}\n): UsePollingResult {\n const {\n interval = 1000,\n enabled = true,\n stopStatuses = ['completed', 'error'],\n onStop,\n onUpdate,\n onError,\n debug = false,\n } = options;\n\n const log = useMemo(() => createLogger(debug), [debug]);\n const logRef = useRef(log);\n logRef.current = log;\n\n const [data, setData] = useState<RealtimeChatHistory | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const isMountedRef = useRef(true);\n\n // Refs for callbacks and options to avoid stale closures and unnecessary re-renders\n const onStopRef = useRef(onStop);\n const onUpdateRef = useRef(onUpdate);\n const onErrorRef = useRef(onError);\n const fetchFnRef = useRef(fetchFn);\n const stopStatusesRef = useRef(stopStatuses);\n const intervalValueRef = useRef(interval);\n const isPollingRef = useRef(false);\n\n useEffect(() => {\n onStopRef.current = onStop;\n onUpdateRef.current = onUpdate;\n onErrorRef.current = onError;\n fetchFnRef.current = fetchFn;\n stopStatusesRef.current = stopStatuses;\n intervalValueRef.current = interval;\n });\n\n const clearPolling = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n isPollingRef.current = false;\n }, []);\n\n const fetchData = useCallback(async () => {\n logRef.current.log('[usePolling] fetchData called, isMounted:', isMountedRef.current);\n if (!isMountedRef.current) return;\n\n try {\n logRef.current.log('[usePolling] Fetching...');\n const result = await fetchFnRef.current();\n logRef.current.log('[usePolling] Fetch result:', { status: result.status, messageCount: result.chatHistory?.length });\n\n if (!isMountedRef.current) return;\n\n setData(result);\n setError(null);\n onUpdateRef.current?.(result);\n\n // Check if we should stop polling\n const shouldStop = stopStatusesRef.current.includes(result.status);\n logRef.current.log('[usePolling] Should stop?', shouldStop, 'stopStatuses:', stopStatusesRef.current, 'current status:', result.status);\n if (shouldStop) {\n logRef.current.log('[usePolling] Stopping polling due to status:', result.status);\n clearPolling();\n setIsPolling(false);\n onStopRef.current?.(result);\n }\n } catch (err) {\n logRef.current.error('[usePolling] Fetch error:', err);\n if (!isMountedRef.current) return;\n\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n onErrorRef.current?.(error);\n\n // Stop polling on error\n clearPolling();\n setIsPolling(false);\n }\n }, [clearPolling]);\n\n const start = useCallback(() => {\n if (intervalRef.current) return;\n\n isPollingRef.current = true;\n setIsPolling(true);\n setError(null);\n\n // Immediate first fetch\n fetchData();\n\n // Set up interval\n intervalRef.current = setInterval(fetchData, intervalValueRef.current);\n }, [fetchData]);\n\n const stop = useCallback(() => {\n clearPolling();\n setIsPolling(false);\n }, [clearPolling]);\n\n const refetch = useCallback(async () => {\n await fetchData();\n }, [fetchData]);\n\n // Auto-start polling when enabled and chatUid is set\n useEffect(() => {\n logRef.current.log('[usePolling] Auto-start effect triggered:', { enabled, chatUid, isPollingRef: isPollingRef.current, intervalRef: !!intervalRef.current });\n\n if (!enabled || !chatUid) {\n logRef.current.log('[usePolling] Not enabled or no chatUid, stopping if active');\n // Stop polling if disabled or no chatUid\n if (isPollingRef.current) {\n clearPolling();\n setIsPolling(false);\n }\n return;\n }\n\n // Start polling if not already polling\n if (!isPollingRef.current) {\n logRef.current.log('[usePolling] Starting polling, interval:', intervalValueRef.current);\n isPollingRef.current = true;\n setIsPolling(true);\n setError(null);\n\n // Immediate first fetch\n fetchData();\n\n // Set up interval\n intervalRef.current = setInterval(fetchData, intervalValueRef.current);\n logRef.current.log('[usePolling] Interval set:', intervalRef.current);\n } else {\n logRef.current.log('[usePolling] Already polling, skipping start');\n }\n\n // Only cleanup on unmount, not on every dependency change\n }, [enabled, chatUid, fetchData, clearPolling]);\n\n // Cleanup on unmount\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n clearPolling();\n };\n }, [clearPolling]);\n\n return {\n data,\n isPolling,\n error,\n start,\n stop,\n refetch,\n };\n}\n"],"names":["useMemo","createLogger","useRef","useState","useEffect","useCallback"],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ const DEFAULT_BASE_URL = 'https://api.devic.ai';
|
|
|
21
21
|
* </DevicProvider>
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
function DevicProvider({ apiKey, baseUrl = DEFAULT_BASE_URL, tenantId, tenantMetadata, children, }) {
|
|
24
|
+
function DevicProvider({ apiKey, baseUrl = DEFAULT_BASE_URL, tenantId, tenantMetadata, debug, children, }) {
|
|
25
25
|
const contextValue = React.useMemo(() => {
|
|
26
26
|
const client$1 = new client.DevicApiClient({
|
|
27
27
|
apiKey,
|
|
@@ -34,8 +34,9 @@ function DevicProvider({ apiKey, baseUrl = DEFAULT_BASE_URL, tenantId, tenantMet
|
|
|
34
34
|
tenantId,
|
|
35
35
|
tenantMetadata,
|
|
36
36
|
isConfigured: !!apiKey,
|
|
37
|
+
debug,
|
|
37
38
|
};
|
|
38
|
-
}, [apiKey, baseUrl, tenantId, tenantMetadata]);
|
|
39
|
+
}, [apiKey, baseUrl, tenantId, tenantMetadata, debug]);
|
|
39
40
|
return (jsxRuntime.jsx(DevicContext.DevicContext.Provider, { value: contextValue, children: children }));
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevicProvider.js","sources":["../../../../src/provider/DevicProvider.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { DevicContext } from './DevicContext';\nimport { DevicApiClient } from '../api/client';\nimport type { DevicProviderProps, DevicContextValue } from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.devic.ai';\n\n/**\n * Provider component for Devic UI configuration\n *\n * @example\n * ```tsx\n * <DevicProvider\n * apiKey=\"devic-xxx\"\n * baseUrl=\"https://api.devic.ai\"\n * tenantId=\"tenant-123\"\n * tenantMetadata={{ userId: '456' }}\n * >\n * <App />\n * </DevicProvider>\n * ```\n */\nexport function DevicProvider({\n apiKey,\n baseUrl = DEFAULT_BASE_URL,\n tenantId,\n tenantMetadata,\n children,\n}: DevicProviderProps): JSX.Element {\n const contextValue = useMemo<DevicContextValue>(() => {\n const client = new DevicApiClient({\n apiKey,\n baseUrl,\n });\n\n return {\n client,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n isConfigured: !!apiKey,\n };\n }, [apiKey, baseUrl, tenantId, tenantMetadata]);\n\n return (\n <DevicContext.Provider value={contextValue}>\n {children}\n </DevicContext.Provider>\n );\n}\n"],"names":["useMemo","client","DevicApiClient","_jsx","DevicContext"],"mappings":";;;;;;;AAKA,MAAM,gBAAgB,GAAG,sBAAsB;AAE/C;;;;;;;;;;;;;;AAcG;
|
|
1
|
+
{"version":3,"file":"DevicProvider.js","sources":["../../../../src/provider/DevicProvider.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { DevicContext } from './DevicContext';\nimport { DevicApiClient } from '../api/client';\nimport type { DevicProviderProps, DevicContextValue } from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.devic.ai';\n\n/**\n * Provider component for Devic UI configuration\n *\n * @example\n * ```tsx\n * <DevicProvider\n * apiKey=\"devic-xxx\"\n * baseUrl=\"https://api.devic.ai\"\n * tenantId=\"tenant-123\"\n * tenantMetadata={{ userId: '456' }}\n * >\n * <App />\n * </DevicProvider>\n * ```\n */\nexport function DevicProvider({\n apiKey,\n baseUrl = DEFAULT_BASE_URL,\n tenantId,\n tenantMetadata,\n debug,\n children,\n}: DevicProviderProps): JSX.Element {\n const contextValue = useMemo<DevicContextValue>(() => {\n const client = new DevicApiClient({\n apiKey,\n baseUrl,\n });\n\n return {\n client,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n isConfigured: !!apiKey,\n debug,\n };\n }, [apiKey, baseUrl, tenantId, tenantMetadata, debug]);\n\n return (\n <DevicContext.Provider value={contextValue}>\n {children}\n </DevicContext.Provider>\n );\n}\n"],"names":["useMemo","client","DevicApiClient","_jsx","DevicContext"],"mappings":";;;;;;;AAKA,MAAM,gBAAgB,GAAG,sBAAsB;AAE/C;;;;;;;;;;;;;;AAcG;SACa,aAAa,CAAC,EAC5B,MAAM,EACN,OAAO,GAAG,gBAAgB,EAC1B,QAAQ,EACR,cAAc,EACd,KAAK,EACL,QAAQ,GACW,EAAA;AACnB,IAAA,MAAM,YAAY,GAAGA,aAAO,CAAoB,MAAK;AACnD,QAAA,MAAMC,QAAM,GAAG,IAAIC,qBAAc,CAAC;YAChC,MAAM;YACN,OAAO;AACR,SAAA,CAAC;QAEF,OAAO;oBACLD,QAAM;YACN,MAAM;YACN,OAAO;YACP,QAAQ;YACR,cAAc;YACd,YAAY,EAAE,CAAC,CAAC,MAAM;YACtB,KAAK;SACN;AACH,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;AAEtD,IAAA,QACEE,cAAA,CAACC,yBAAY,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,QAAA,EACvC,QAAQ,EAAA,CACa;AAE5B;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/utils/index.ts"],"sourcesContent":["export { segmentToolCalls } from './toolGroups';\nexport type { ToolGroupSegment } from './toolGroups';\n\n/**\n * Generate a unique ID\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (\n sourceValue &&\n typeof sourceValue === 'object' &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === 'object' &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(targetValue, sourceValue as any);\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as any;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Debounce a function\n */\nexport function debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n return (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n}\n\n/**\n * Throttle a function\n */\nexport function throttle<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n\n return (...args: Parameters<T>) => {\n const now = Date.now();\n if (now - lastCall >= delay) {\n lastCall = now;\n fn(...args);\n }\n };\n}\n\n/**\n * Format file size for display\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${units[i]}`;\n}\n\n/**\n * Check if running in browser\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\n/**\n * Local storage helper with JSON serialization\n */\nexport const storage = {\n get<T>(key: string, defaultValue?: T): T | null {\n if (!isBrowser()) return defaultValue ?? null;\n\n try {\n const item = localStorage.getItem(key);\n return item ? JSON.parse(item) : (defaultValue ?? null);\n } catch {\n return defaultValue ?? null;\n }\n },\n\n set<T>(key: string, value: T): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Storage full or other error\n }\n },\n\n remove(key: string): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.removeItem(key);\n } catch {\n // Error removing item\n }\n },\n};\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/utils/index.ts"],"sourcesContent":["export { segmentToolCalls } from './toolGroups';\nexport { createLogger } from './logger';\nexport type { DevicLogger } from './logger';\nexport type { ToolGroupSegment } from './toolGroups';\n\n/**\n * Generate a unique ID\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (\n sourceValue &&\n typeof sourceValue === 'object' &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === 'object' &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(targetValue, sourceValue as any);\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as any;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Debounce a function\n */\nexport function debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n return (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n}\n\n/**\n * Throttle a function\n */\nexport function throttle<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n\n return (...args: Parameters<T>) => {\n const now = Date.now();\n if (now - lastCall >= delay) {\n lastCall = now;\n fn(...args);\n }\n };\n}\n\n/**\n * Format file size for display\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${units[i]}`;\n}\n\n/**\n * Check if running in browser\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\n/**\n * Local storage helper with JSON serialization\n */\nexport const storage = {\n get<T>(key: string, defaultValue?: T): T | null {\n if (!isBrowser()) return defaultValue ?? null;\n\n try {\n const item = localStorage.getItem(key);\n return item ? JSON.parse(item) : (defaultValue ?? null);\n } catch {\n return defaultValue ?? null;\n }\n },\n\n set<T>(key: string, value: T): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // Storage full or other error\n }\n },\n\n remove(key: string): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.removeItem(key);\n } catch {\n // Error removing item\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Conditional logger for devic-ui.
|
|
5
|
+
* Only outputs when debug mode is enabled via the Provider or component props.
|
|
6
|
+
*/
|
|
7
|
+
function createLogger(enabled) {
|
|
8
|
+
const noop = () => { };
|
|
9
|
+
return {
|
|
10
|
+
log: enabled ? console.log.bind(console) : noop,
|
|
11
|
+
warn: enabled ? console.warn.bind(console) : noop,
|
|
12
|
+
error: enabled ? console.error.bind(console) : noop,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.createLogger = createLogger;
|
|
17
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sources":["../../../../src/utils/logger.ts"],"sourcesContent":["/**\n * Conditional logger for devic-ui.\n * Only outputs when debug mode is enabled via the Provider or component props.\n */\nexport function createLogger(enabled: boolean) {\n const noop = () => {};\n return {\n log: enabled ? console.log.bind(console) : noop,\n warn: enabled ? console.warn.bind(console) : noop,\n error: enabled ? console.error.bind(console) : noop,\n };\n}\n\nexport type DevicLogger = ReturnType<typeof createLogger>;\n"],"names":[],"mappings":";;AAAA;;;AAGG;AACG,SAAU,YAAY,CAAC,OAAgB,EAAA;AAC3C,IAAA,MAAM,IAAI,GAAG,MAAK,EAAE,CAAC;IACrB,OAAO;AACL,QAAA,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;AAC/C,QAAA,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;AACjD,QAAA,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;KACpD;AACH;;;;"}
|
|
@@ -46,6 +46,7 @@ const DEFAULT_OPTIONS = {
|
|
|
46
46
|
handoffWidgetRenderer: undefined,
|
|
47
47
|
toolGroups: undefined,
|
|
48
48
|
stopButtonContent: undefined,
|
|
49
|
+
debug: false,
|
|
49
50
|
};
|
|
50
51
|
/**
|
|
51
52
|
* Chat drawer component for Devic assistants
|
|
@@ -97,6 +98,7 @@ function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, e
|
|
|
97
98
|
onToolCall,
|
|
98
99
|
onError,
|
|
99
100
|
onChatCreated,
|
|
101
|
+
debug: mergedOptions.debug,
|
|
100
102
|
});
|
|
101
103
|
// Fetch assistant avatar when showAvatar is enabled
|
|
102
104
|
const context = useOptionalDevicContext();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatDrawer.js","sources":["../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport { ConversationSelector } from './ConversationSelector';\nimport { ChatDrawerErrorBoundary } from './ErrorBoundary';\nimport type { ChatDrawerProps, ChatDrawerOptions, ChatDrawerHandle } from './ChatDrawer.types';\nimport './styles.css';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: '100%',\n defaultOpen: false,\n color: '#1890ff',\n welcomeMessage: '',\n suggestedMessages: [],\n enableFileUploads: false,\n allowedFileTypes: { images: true, documents: true },\n maxFileSize: 10 * 1024 * 1024,\n inputPlaceholder: 'Type a message...',\n title: 'Chat',\n showAvatar: false,\n showToolTimeline: true,\n zIndex: 1000,\n borderRadius: 0,\n resizable: false,\n minWidth: 300,\n maxWidth: 800,\n style: {},\n fontFamily: undefined as any,\n backgroundColor: undefined as any,\n textColor: undefined as any,\n secondaryBackgroundColor: undefined as any,\n borderColor: undefined as any,\n userBubbleColor: undefined as any,\n userBubbleTextColor: undefined as any,\n assistantBubbleColor: undefined as any,\n assistantBubbleTextColor: undefined as any,\n sendButtonColor: undefined as any,\n loadingIndicator: undefined as any,\n sendButtonContent: undefined as any,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n showFeedback: true,\n handoffWidgetRenderer: undefined as any,\n toolGroups: undefined as any,\n stopButtonContent: undefined as any,\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\n * ref={drawerRef}\n * assistantId=\"my-assistant\"\n * options={{\n * position: 'right',\n * width: 400,\n * welcomeMessage: 'Hello! How can I help you?',\n * suggestedMessages: ['Help me with...', 'Tell me about...'],\n * }}\n * modelInterfaceTools={[\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ]}\n * onMessageReceived={(msg) => console.log('Received:', msg)}\n * />\n * ```\n */\nexport const ChatDrawer = forwardRef<ChatDrawerHandle, ChatDrawerProps>(\n function ChatDrawer(props, ref) {\n return (\n <ChatDrawerErrorBoundary>\n <ChatDrawerInner {...props} forwardedRef={ref} />\n </ChatDrawerErrorBoundary>\n );\n }\n);\n\ninterface ChatDrawerInnerProps extends ChatDrawerProps {\n forwardedRef?: React.Ref<ChatDrawerHandle>;\n}\n\nfunction ChatDrawerInner({\n assistantId,\n chatUid: initialChatUid,\n options = {},\n enabledTools,\n modelInterfaceTools,\n tenantId,\n tenantMetadata,\n apiKey,\n baseUrl,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onOpen,\n onClose,\n isOpen: controlledIsOpen,\n className,\n mode = 'drawer',\n onConversationChange,\n forwardedRef,\n}: ChatDrawerInnerProps): JSX.Element {\n // Merge options with defaults\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n // Drawer open state (can be controlled or uncontrolled; inline mode is always open)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isInline = mode === 'inline';\n const isOpen = isInline ? true : (controlledIsOpen ?? internalIsOpen);\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: initialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n });\n\n // Fetch assistant avatar when showAvatar is enabled\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const [avatarUrl, setAvatarUrl] = useState<string | null>(null);\n const avatarFetchedRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!mergedOptions.showAvatar || !resolvedApiKey || avatarFetchedRef.current === assistantId) return;\n avatarFetchedRef.current = assistantId;\n const client = new DevicApiClient({ apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl });\n client.getAssistant(assistantId).then((a) => {\n if (a.imgUrl) setAvatarUrl(a.imgUrl);\n }).catch(() => {});\n }, [mergedOptions.showAvatar, assistantId, resolvedApiKey, resolvedBaseUrl]);\n\n // Handle open/close\n const handleOpen = useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleToggle = useCallback(() => {\n setInternalIsOpen((prev) => !prev);\n }, []);\n\n // Expose handle for programmatic control\n useImperativeHandle(forwardedRef, () => ({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n setChatUid: (chatUid: string) => {\n chat.loadChat(chatUid);\n },\n sendMessage: (message: string) => {\n chat.sendMessage(message);\n },\n }), [handleOpen, handleClose, handleToggle, chat]);\n\n // Handle send message\n const handleSend = useCallback(\n (message: string, files?: any[]) => {\n chat.sendMessage(message, { files });\n },\n [chat]\n );\n\n // Handle conversation selection\n const handleConversationSelect = useCallback(\n (chatUid: string) => {\n chat.loadChat(chatUid);\n onConversationChange?.(chatUid);\n },\n [chat, onConversationChange]\n );\n\n const handleNewChat = useCallback(() => {\n chat.clearChat();\n }, [chat]);\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Feedback state\n const [feedbackMap, setFeedbackMap] = useState<Map<string, 'positive' | 'negative'>>(new Map());\n const feedbackClientRef = useRef<DevicApiClient | null>(null);\n\n // Initialize feedback client\n useEffect(() => {\n if (resolvedApiKey && !feedbackClientRef.current) {\n feedbackClientRef.current = new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n });\n }\n }, [resolvedApiKey, resolvedBaseUrl]);\n\n // Load existing feedback when chat changes\n useEffect(() => {\n if (!chat.chatUid || !feedbackClientRef.current || !mergedOptions.showFeedback) return;\n\n feedbackClientRef.current.getChatFeedback(assistantId, chat.chatUid)\n .then((entries) => {\n const newMap = new Map<string, 'positive' | 'negative'>();\n for (const entry of entries) {\n if (entry.feedback !== undefined) {\n newMap.set(entry.requestId, entry.feedback ? 'positive' : 'negative');\n }\n }\n setFeedbackMap(newMap);\n })\n .catch(() => {\n // Silently ignore feedback loading errors\n });\n }, [chat.chatUid, assistantId, mergedOptions.showFeedback]);\n\n // Handle feedback submission\n const handleFeedback = useCallback(\n async (messageId: string, positive: boolean, comment?: string) => {\n if (!chat.chatUid || !feedbackClientRef.current) return;\n\n try {\n await feedbackClientRef.current.submitChatFeedback(assistantId, chat.chatUid, {\n messageId,\n feedback: positive,\n feedbackComment: comment,\n });\n\n setFeedbackMap((prev) => {\n const newMap = new Map(prev);\n newMap.set(messageId, positive ? 'positive' : 'negative');\n return newMap;\n });\n } catch (err) {\n console.error('Failed to submit feedback:', err);\n throw err;\n }\n },\n [chat.chatUid, assistantId]\n );\n\n // Apply CSS variables for theming on the drawer element itself\n // (must target the component root so they override the defaults defined on .devic-chat-drawer)\n const drawerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = drawerRef.current;\n if (!el) return;\n const vars: [string, string | undefined][] = [\n ['--devic-primary', mergedOptions.color !== DEFAULT_OPTIONS.color ? mergedOptions.color : undefined],\n ['--devic-font-family', mergedOptions.fontFamily],\n ['--devic-bg', mergedOptions.backgroundColor],\n ['--devic-text', mergedOptions.textColor],\n ['--devic-bg-secondary', mergedOptions.secondaryBackgroundColor],\n ['--devic-border', mergedOptions.borderColor],\n ['--devic-user-bubble', mergedOptions.userBubbleColor],\n ['--devic-user-bubble-text', mergedOptions.userBubbleTextColor],\n ['--devic-assistant-bubble', mergedOptions.assistantBubbleColor],\n ['--devic-assistant-bubble-text', mergedOptions.assistantBubbleTextColor],\n ['--devic-send-btn', mergedOptions.sendButtonColor],\n ];\n for (const [name, value] of vars) {\n if (value) {\n el.style.setProperty(name, value);\n } else {\n el.style.removeProperty(name);\n }\n }\n }, [mergedOptions.color, mergedOptions.fontFamily, mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.secondaryBackgroundColor, mergedOptions.borderColor, mergedOptions.userBubbleColor, mergedOptions.userBubbleTextColor, mergedOptions.assistantBubbleColor, mergedOptions.assistantBubbleTextColor, mergedOptions.sendButtonColor]);\n\n // Resizable drawer\n const [resizedWidth, setResizedWidth] = useState<number | null>(null);\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const startX = e.clientX;\n const startWidth = drawerRef.current?.offsetWidth ?? 0;\n const isLeft = mergedOptions.position === 'left';\n\n const onMove = (ev: MouseEvent) => {\n const delta = ev.clientX - startX;\n const newWidth = startWidth + (isLeft ? delta : -delta);\n const clamped = Math.min(\n mergedOptions.maxWidth,\n Math.max(mergedOptions.minWidth, newWidth)\n );\n setResizedWidth(clamped);\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n },\n [mergedOptions.position, mergedOptions.minWidth, mergedOptions.maxWidth]\n );\n\n // Build style object\n const baseWidth = resizedWidth\n ? `${resizedWidth}px`\n : typeof mergedOptions.width === 'number'\n ? `${mergedOptions.width}px`\n : mergedOptions.width;\n\n const drawerStyle = useMemo(\n () => ({\n width: baseWidth,\n zIndex: mergedOptions.zIndex,\n borderRadius: typeof mergedOptions.borderRadius === 'number'\n ? `${mergedOptions.borderRadius}px`\n : mergedOptions.borderRadius,\n ...mergedOptions.style,\n }),\n [baseWidth, mergedOptions.zIndex, mergedOptions.borderRadius, mergedOptions.style]\n );\n\n const overlayStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n }),\n [mergedOptions.zIndex]\n );\n\n const triggerStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n [mergedOptions.position]: 20,\n bottom: 20,\n }),\n [mergedOptions.zIndex, mergedOptions.position]\n );\n\n return (\n <>\n {/* Overlay (drawer mode only) */}\n {!isInline && (\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n )}\n\n {/* Drawer */}\n <div\n ref={drawerRef}\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n data-mode={mode}\n style={drawerStyle}\n >\n {/* Resize handle */}\n {mergedOptions.resizable && (\n <div\n className=\"devic-resize-handle\"\n data-position={mergedOptions.position}\n onMouseDown={handleResizeStart}\n />\n )}\n\n {/* Header */}\n <div className=\"devic-drawer-header\">\n {avatarUrl && (\n <img\n className=\"devic-drawer-avatar\"\n src={avatarUrl}\n alt=\"\"\n aria-hidden=\"true\"\n />\n )}\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <ConversationSelector\n assistantId={assistantId}\n currentChatUid={chat.chatUid}\n onSelect={handleConversationSelect}\n onNewChat={handleNewChat}\n apiKey={apiKey}\n baseUrl={baseUrl}\n tenantId={tenantId}\n />\n <div className=\"devic-drawer-header-actions\">\n <button\n className=\"devic-new-chat-btn\"\n onClick={handleNewChat}\n type=\"button\"\n aria-label=\"New chat\"\n title=\"New chat\"\n >\n <PlusIcon />\n </button>\n {!isInline && (\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {chat.error && (\n <div className=\"devic-error\">\n {chat.error.message}\n </div>\n )}\n\n {/* Messages */}\n <ChatMessages\n messages={chat.messages}\n allMessages={chat.messages}\n isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n toolRenderers={mergedOptions.toolRenderers}\n toolIcons={mergedOptions.toolIcons}\n loadingIndicator={mergedOptions.loadingIndicator}\n showFeedback={mergedOptions.showFeedback}\n feedbackMap={feedbackMap}\n onFeedback={handleFeedback}\n handedOffSubThreadId={chat.handedOffSubThreadId || undefined}\n onHandoffCompleted={chat.onHandoffCompleted}\n handoffWidgetRenderer={mergedOptions.handoffWidgetRenderer}\n toolGroups={mergedOptions.toolGroups}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n />\n\n {/* Input */}\n <ChatInput\n onSend={handleSend}\n disabled={chat.isLoading || chat.handedOff}\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n sendButtonContent={mergedOptions.sendButtonContent}\n disabledMessage={chat.handedOff ? 'Waiting for subagent to complete' : undefined}\n isProcessing={chat.isLoading && !chat.handedOff}\n onStop={chat.stopChat}\n stopButtonContent={mergedOptions.stopButtonContent}\n />\n </div>\n\n {/* Trigger button (drawer mode only, when closed) */}\n {!isInline && !isOpen && (\n <button\n className=\"devic-trigger\"\n onClick={handleOpen}\n style={triggerStyle}\n type=\"button\"\n aria-label=\"Open chat\"\n >\n <ChatIcon />\n </button>\n )}\n </>\n );\n}\n\n/**\n * Close icon\n */\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Plus icon for new chat button\n */\nfunction PlusIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n\n/**\n * Chat icon for trigger button\n */\nfunction ChatIcon(): JSX.Element {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z\" />\n </svg>\n );\n}\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatDrawer.js","sources":["../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport { ConversationSelector } from './ConversationSelector';\nimport { ChatDrawerErrorBoundary } from './ErrorBoundary';\nimport type { ChatDrawerProps, ChatDrawerOptions, ChatDrawerHandle } from './ChatDrawer.types';\nimport './styles.css';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: '100%',\n defaultOpen: false,\n color: '#1890ff',\n welcomeMessage: '',\n suggestedMessages: [],\n enableFileUploads: false,\n allowedFileTypes: { images: true, documents: true },\n maxFileSize: 10 * 1024 * 1024,\n inputPlaceholder: 'Type a message...',\n title: 'Chat',\n showAvatar: false,\n showToolTimeline: true,\n zIndex: 1000,\n borderRadius: 0,\n resizable: false,\n minWidth: 300,\n maxWidth: 800,\n style: {},\n fontFamily: undefined as any,\n backgroundColor: undefined as any,\n textColor: undefined as any,\n secondaryBackgroundColor: undefined as any,\n borderColor: undefined as any,\n userBubbleColor: undefined as any,\n userBubbleTextColor: undefined as any,\n assistantBubbleColor: undefined as any,\n assistantBubbleTextColor: undefined as any,\n sendButtonColor: undefined as any,\n loadingIndicator: undefined as any,\n sendButtonContent: undefined as any,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n showFeedback: true,\n handoffWidgetRenderer: undefined as any,\n toolGroups: undefined as any,\n stopButtonContent: undefined as any,\n debug: false,\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\n * ref={drawerRef}\n * assistantId=\"my-assistant\"\n * options={{\n * position: 'right',\n * width: 400,\n * welcomeMessage: 'Hello! How can I help you?',\n * suggestedMessages: ['Help me with...', 'Tell me about...'],\n * }}\n * modelInterfaceTools={[\n * {\n * toolName: 'get_user_location',\n * schema: { ... },\n * callback: async () => ({ lat: 40.7, lng: -74.0 })\n * }\n * ]}\n * onMessageReceived={(msg) => console.log('Received:', msg)}\n * />\n * ```\n */\nexport const ChatDrawer = forwardRef<ChatDrawerHandle, ChatDrawerProps>(\n function ChatDrawer(props, ref) {\n return (\n <ChatDrawerErrorBoundary>\n <ChatDrawerInner {...props} forwardedRef={ref} />\n </ChatDrawerErrorBoundary>\n );\n }\n);\n\ninterface ChatDrawerInnerProps extends ChatDrawerProps {\n forwardedRef?: React.Ref<ChatDrawerHandle>;\n}\n\nfunction ChatDrawerInner({\n assistantId,\n chatUid: initialChatUid,\n options = {},\n enabledTools,\n modelInterfaceTools,\n tenantId,\n tenantMetadata,\n apiKey,\n baseUrl,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n onOpen,\n onClose,\n isOpen: controlledIsOpen,\n className,\n mode = 'drawer',\n onConversationChange,\n forwardedRef,\n}: ChatDrawerInnerProps): JSX.Element {\n // Merge options with defaults\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n // Drawer open state (can be controlled or uncontrolled; inline mode is always open)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isInline = mode === 'inline';\n const isOpen = isInline ? true : (controlledIsOpen ?? internalIsOpen);\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: initialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n debug: mergedOptions.debug,\n });\n\n // Fetch assistant avatar when showAvatar is enabled\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\n const [avatarUrl, setAvatarUrl] = useState<string | null>(null);\n const avatarFetchedRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!mergedOptions.showAvatar || !resolvedApiKey || avatarFetchedRef.current === assistantId) return;\n avatarFetchedRef.current = assistantId;\n const client = new DevicApiClient({ apiKey: resolvedApiKey, baseUrl: resolvedBaseUrl });\n client.getAssistant(assistantId).then((a) => {\n if (a.imgUrl) setAvatarUrl(a.imgUrl);\n }).catch(() => {});\n }, [mergedOptions.showAvatar, assistantId, resolvedApiKey, resolvedBaseUrl]);\n\n // Handle open/close\n const handleOpen = useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleToggle = useCallback(() => {\n setInternalIsOpen((prev) => !prev);\n }, []);\n\n // Expose handle for programmatic control\n useImperativeHandle(forwardedRef, () => ({\n open: handleOpen,\n close: handleClose,\n toggle: handleToggle,\n setChatUid: (chatUid: string) => {\n chat.loadChat(chatUid);\n },\n sendMessage: (message: string) => {\n chat.sendMessage(message);\n },\n }), [handleOpen, handleClose, handleToggle, chat]);\n\n // Handle send message\n const handleSend = useCallback(\n (message: string, files?: any[]) => {\n chat.sendMessage(message, { files });\n },\n [chat]\n );\n\n // Handle conversation selection\n const handleConversationSelect = useCallback(\n (chatUid: string) => {\n chat.loadChat(chatUid);\n onConversationChange?.(chatUid);\n },\n [chat, onConversationChange]\n );\n\n const handleNewChat = useCallback(() => {\n chat.clearChat();\n }, [chat]);\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Feedback state\n const [feedbackMap, setFeedbackMap] = useState<Map<string, 'positive' | 'negative'>>(new Map());\n const feedbackClientRef = useRef<DevicApiClient | null>(null);\n\n // Initialize feedback client\n useEffect(() => {\n if (resolvedApiKey && !feedbackClientRef.current) {\n feedbackClientRef.current = new DevicApiClient({\n apiKey: resolvedApiKey,\n baseUrl: resolvedBaseUrl,\n });\n }\n }, [resolvedApiKey, resolvedBaseUrl]);\n\n // Load existing feedback when chat changes\n useEffect(() => {\n if (!chat.chatUid || !feedbackClientRef.current || !mergedOptions.showFeedback) return;\n\n feedbackClientRef.current.getChatFeedback(assistantId, chat.chatUid)\n .then((entries) => {\n const newMap = new Map<string, 'positive' | 'negative'>();\n for (const entry of entries) {\n if (entry.feedback !== undefined) {\n newMap.set(entry.requestId, entry.feedback ? 'positive' : 'negative');\n }\n }\n setFeedbackMap(newMap);\n })\n .catch(() => {\n // Silently ignore feedback loading errors\n });\n }, [chat.chatUid, assistantId, mergedOptions.showFeedback]);\n\n // Handle feedback submission\n const handleFeedback = useCallback(\n async (messageId: string, positive: boolean, comment?: string) => {\n if (!chat.chatUid || !feedbackClientRef.current) return;\n\n try {\n await feedbackClientRef.current.submitChatFeedback(assistantId, chat.chatUid, {\n messageId,\n feedback: positive,\n feedbackComment: comment,\n });\n\n setFeedbackMap((prev) => {\n const newMap = new Map(prev);\n newMap.set(messageId, positive ? 'positive' : 'negative');\n return newMap;\n });\n } catch (err) {\n console.error('Failed to submit feedback:', err);\n throw err;\n }\n },\n [chat.chatUid, assistantId]\n );\n\n // Apply CSS variables for theming on the drawer element itself\n // (must target the component root so they override the defaults defined on .devic-chat-drawer)\n const drawerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = drawerRef.current;\n if (!el) return;\n const vars: [string, string | undefined][] = [\n ['--devic-primary', mergedOptions.color !== DEFAULT_OPTIONS.color ? mergedOptions.color : undefined],\n ['--devic-font-family', mergedOptions.fontFamily],\n ['--devic-bg', mergedOptions.backgroundColor],\n ['--devic-text', mergedOptions.textColor],\n ['--devic-bg-secondary', mergedOptions.secondaryBackgroundColor],\n ['--devic-border', mergedOptions.borderColor],\n ['--devic-user-bubble', mergedOptions.userBubbleColor],\n ['--devic-user-bubble-text', mergedOptions.userBubbleTextColor],\n ['--devic-assistant-bubble', mergedOptions.assistantBubbleColor],\n ['--devic-assistant-bubble-text', mergedOptions.assistantBubbleTextColor],\n ['--devic-send-btn', mergedOptions.sendButtonColor],\n ];\n for (const [name, value] of vars) {\n if (value) {\n el.style.setProperty(name, value);\n } else {\n el.style.removeProperty(name);\n }\n }\n }, [mergedOptions.color, mergedOptions.fontFamily, mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.secondaryBackgroundColor, mergedOptions.borderColor, mergedOptions.userBubbleColor, mergedOptions.userBubbleTextColor, mergedOptions.assistantBubbleColor, mergedOptions.assistantBubbleTextColor, mergedOptions.sendButtonColor]);\n\n // Resizable drawer\n const [resizedWidth, setResizedWidth] = useState<number | null>(null);\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const startX = e.clientX;\n const startWidth = drawerRef.current?.offsetWidth ?? 0;\n const isLeft = mergedOptions.position === 'left';\n\n const onMove = (ev: MouseEvent) => {\n const delta = ev.clientX - startX;\n const newWidth = startWidth + (isLeft ? delta : -delta);\n const clamped = Math.min(\n mergedOptions.maxWidth,\n Math.max(mergedOptions.minWidth, newWidth)\n );\n setResizedWidth(clamped);\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n },\n [mergedOptions.position, mergedOptions.minWidth, mergedOptions.maxWidth]\n );\n\n // Build style object\n const baseWidth = resizedWidth\n ? `${resizedWidth}px`\n : typeof mergedOptions.width === 'number'\n ? `${mergedOptions.width}px`\n : mergedOptions.width;\n\n const drawerStyle = useMemo(\n () => ({\n width: baseWidth,\n zIndex: mergedOptions.zIndex,\n borderRadius: typeof mergedOptions.borderRadius === 'number'\n ? `${mergedOptions.borderRadius}px`\n : mergedOptions.borderRadius,\n ...mergedOptions.style,\n }),\n [baseWidth, mergedOptions.zIndex, mergedOptions.borderRadius, mergedOptions.style]\n );\n\n const overlayStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n }),\n [mergedOptions.zIndex]\n );\n\n const triggerStyle = useMemo(\n () => ({\n zIndex: mergedOptions.zIndex - 1,\n [mergedOptions.position]: 20,\n bottom: 20,\n }),\n [mergedOptions.zIndex, mergedOptions.position]\n );\n\n return (\n <>\n {/* Overlay (drawer mode only) */}\n {!isInline && (\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n )}\n\n {/* Drawer */}\n <div\n ref={drawerRef}\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n data-mode={mode}\n style={drawerStyle}\n >\n {/* Resize handle */}\n {mergedOptions.resizable && (\n <div\n className=\"devic-resize-handle\"\n data-position={mergedOptions.position}\n onMouseDown={handleResizeStart}\n />\n )}\n\n {/* Header */}\n <div className=\"devic-drawer-header\">\n {avatarUrl && (\n <img\n className=\"devic-drawer-avatar\"\n src={avatarUrl}\n alt=\"\"\n aria-hidden=\"true\"\n />\n )}\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <ConversationSelector\n assistantId={assistantId}\n currentChatUid={chat.chatUid}\n onSelect={handleConversationSelect}\n onNewChat={handleNewChat}\n apiKey={apiKey}\n baseUrl={baseUrl}\n tenantId={tenantId}\n />\n <div className=\"devic-drawer-header-actions\">\n <button\n className=\"devic-new-chat-btn\"\n onClick={handleNewChat}\n type=\"button\"\n aria-label=\"New chat\"\n title=\"New chat\"\n >\n <PlusIcon />\n </button>\n {!isInline && (\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {chat.error && (\n <div className=\"devic-error\">\n {chat.error.message}\n </div>\n )}\n\n {/* Messages */}\n <ChatMessages\n messages={chat.messages}\n allMessages={chat.messages}\n isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n toolRenderers={mergedOptions.toolRenderers}\n toolIcons={mergedOptions.toolIcons}\n loadingIndicator={mergedOptions.loadingIndicator}\n showFeedback={mergedOptions.showFeedback}\n feedbackMap={feedbackMap}\n onFeedback={handleFeedback}\n handedOffSubThreadId={chat.handedOffSubThreadId || undefined}\n onHandoffCompleted={chat.onHandoffCompleted}\n handoffWidgetRenderer={mergedOptions.handoffWidgetRenderer}\n toolGroups={mergedOptions.toolGroups}\n apiKey={resolvedApiKey}\n baseUrl={resolvedBaseUrl}\n />\n\n {/* Input */}\n <ChatInput\n onSend={handleSend}\n disabled={chat.isLoading || chat.handedOff}\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n sendButtonContent={mergedOptions.sendButtonContent}\n disabledMessage={chat.handedOff ? 'Waiting for subagent to complete' : undefined}\n isProcessing={chat.isLoading && !chat.handedOff}\n onStop={chat.stopChat}\n stopButtonContent={mergedOptions.stopButtonContent}\n />\n </div>\n\n {/* Trigger button (drawer mode only, when closed) */}\n {!isInline && !isOpen && (\n <button\n className=\"devic-trigger\"\n onClick={handleOpen}\n style={triggerStyle}\n type=\"button\"\n aria-label=\"Open chat\"\n >\n <ChatIcon />\n </button>\n )}\n </>\n );\n}\n\n/**\n * Close icon\n */\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Plus icon for new chat button\n */\nfunction PlusIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n\n/**\n * Chat icon for trigger button\n */\nfunction ChatIcon(): JSX.Element {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z\" />\n </svg>\n );\n}\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -187,6 +187,12 @@ export interface ChatDrawerOptions {
|
|
|
187
187
|
* If not provided, a default square stop icon is rendered.
|
|
188
188
|
*/
|
|
189
189
|
stopButtonContent?: React.ReactNode;
|
|
190
|
+
/**
|
|
191
|
+
* Enable debug logging to the browser console.
|
|
192
|
+
* Overrides the provider-level debug setting when provided.
|
|
193
|
+
* @default false
|
|
194
|
+
*/
|
|
195
|
+
debug?: boolean;
|
|
190
196
|
}
|
|
191
197
|
/**
|
|
192
198
|
* Props for the ChatDrawer component
|