@devicai/ui 0.10.4 → 0.11.0

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.
@@ -106,9 +106,15 @@ class DevicApiClient {
106
106
  if (options?.tenantId) {
107
107
  params.set("tenantId", options.tenantId);
108
108
  }
109
+ if (options?.offset != null) {
110
+ params.set("offset", String(options.offset));
111
+ }
112
+ if (options?.limit != null) {
113
+ params.set("limit", String(options.limit));
114
+ }
115
+ params.set("omitContent", "true");
109
116
  const query = params.toString();
110
- const response = await this.request(`/api/v1/assistants/${assistantId}/chats${query ? `?${query}` : ""}`);
111
- return response.histories;
117
+ return this.request(`/api/v1/assistants/${assistantId}/chats${query ? `?${query}` : ""}`);
112
118
  }
113
119
  /**
114
120
  * Send tool call responses back to the assistant
@@ -192,6 +198,40 @@ class DevicApiClient {
192
198
  async stopChat(assistantId, chatUid) {
193
199
  return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/stop`, { method: "POST" });
194
200
  }
201
+ /**
202
+ * Upload a file and get a download URL
203
+ */
204
+ async uploadFile(file) {
205
+ const url = `${this.config.baseUrl}/api/v1/files/upload`;
206
+ const formData = new FormData();
207
+ formData.append("file", file);
208
+ const response = await fetch(url, {
209
+ method: "POST",
210
+ headers: {
211
+ Authorization: `Bearer ${this.config.apiKey}`,
212
+ "devic-api-source": "ui",
213
+ },
214
+ body: formData,
215
+ });
216
+ if (!response.ok) {
217
+ let errorData;
218
+ try {
219
+ errorData = await response.json();
220
+ }
221
+ catch {
222
+ errorData = {
223
+ statusCode: response.status,
224
+ message: response.statusText,
225
+ };
226
+ }
227
+ throw new DevicApiError(errorData);
228
+ }
229
+ const data = await response.json();
230
+ if (data && typeof data === "object" && "data" in data) {
231
+ return data.data;
232
+ }
233
+ return data;
234
+ }
195
235
  /**
196
236
  * Get chat history content (full conversation after handoff)
197
237
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../../../src/api/client.ts"],"sourcesContent":["import type {\n ProcessMessageDto,\n ChatMessage,\n AsyncResponse,\n RealtimeChatHistory,\n ChatHistory,\n AssistantSpecialization,\n ApiError,\n ToolCallResponse,\n ConversationSummary,\n ListConversationsResponse,\n FeedbackSubmission,\n FeedbackEntry,\n AgentThreadDto,\n AgentDto,\n} from \"./types\";\n\nexport interface DevicApiClientConfig {\n apiKey: string;\n baseUrl: string;\n}\n\n/**\n * Devic API client using native fetch\n */\nexport class DevicApiClient {\n private config: DevicApiClientConfig;\n\n constructor(config: DevicApiClientConfig) {\n this.config = config;\n }\n\n /**\n * Update client configuration\n */\n setConfig(config: Partial<DevicApiClientConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.config.apiKey}`,\n \"devic-api-source\": \"ui\",\n ...options.headers,\n };\n\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n let errorData: ApiError;\n try {\n errorData = await response.json();\n } catch {\n errorData = {\n statusCode: response.status,\n message: response.statusText,\n };\n }\n throw new DevicApiError(errorData);\n }\n\n // Handle responses that may have a wrapper structure\n const data = await response.json();\n\n // If the response has a data property, extract it (common wrapper pattern)\n if (data && typeof data === \"object\" && \"data\" in data) {\n return data.data as T;\n }\n\n return data as T;\n }\n\n /**\n * Get all assistant specializations\n */\n async getAssistants(external = false): Promise<AssistantSpecialization[]> {\n const query = external ? \"?external=true\" : \"\";\n return this.request<AssistantSpecialization[]>(\n `/api/v1/assistants${query}`,\n );\n }\n\n /**\n * Get a specific assistant specialization\n */\n async getAssistant(identifier: string): Promise<AssistantSpecialization> {\n return this.request<AssistantSpecialization>(\n `/api/v1/assistants/${identifier}`,\n );\n }\n\n /**\n * Send a message to an assistant (sync mode)\n */\n async sendMessage(\n assistantId: string,\n dto: ProcessMessageDto,\n signal?: AbortSignal,\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/messages${dto.skipSummarization ? \"?skipSummarization=true\" : \"\"}`,\n {\n method: \"POST\",\n body: JSON.stringify(dto),\n signal,\n },\n );\n }\n\n /**\n * Send a message to an assistant (async mode)\n */\n async sendMessageAsync(\n assistantId: string,\n dto: ProcessMessageDto,\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/messages?async=true${dto.skipSummarization ? \"&skipSummarization=true\" : \"\"}`,\n {\n method: \"POST\",\n body: JSON.stringify(dto),\n },\n );\n }\n\n /**\n * Get real-time chat history (for polling in async mode)\n */\n async getRealtimeHistory(\n assistantId: string,\n chatUid: string,\n ): Promise<RealtimeChatHistory> {\n return this.request<RealtimeChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/realtime`,\n );\n }\n\n /**\n * Get chat history for a specific conversation\n */\n async getChatHistory(\n assistantId: string,\n chatUid: string,\n options?: { tenantId?: string },\n ): Promise<ChatHistory> {\n const params = new URLSearchParams();\n if (options?.tenantId) {\n params.set(\"tenantId\", options.tenantId);\n }\n const query = params.toString();\n return this.request<ChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}${query ? `?${query}` : \"\"}`,\n );\n }\n\n /**\n * List conversations for an assistant\n */\n async listConversations(\n assistantId: string,\n options?: { tenantId?: string },\n ): Promise<ConversationSummary[]> {\n const params = new URLSearchParams();\n if (options?.tenantId) {\n params.set(\"tenantId\", options.tenantId);\n }\n const query = params.toString();\n const response = await this.request<ListConversationsResponse>(\n `/api/v1/assistants/${assistantId}/chats${query ? `?${query}` : \"\"}`,\n );\n return response.histories;\n }\n\n /**\n * Send tool call responses back to the assistant\n */\n async sendToolResponses(\n assistantId: string,\n chatUid: string,\n responses: ToolCallResponse[],\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`,\n {\n method: \"POST\",\n body: JSON.stringify({ responses }),\n },\n );\n }\n\n /**\n * Submit feedback for a chat message\n */\n async submitChatFeedback(\n assistantId: string,\n chatUid: string,\n data: FeedbackSubmission,\n ): Promise<FeedbackEntry> {\n return this.request<FeedbackEntry>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`,\n {\n method: \"POST\",\n body: JSON.stringify(data),\n },\n );\n }\n\n /**\n * Get all feedback for a chat\n */\n async getChatFeedback(\n assistantId: string,\n chatUid: string,\n ): Promise<FeedbackEntry[]> {\n return this.request<FeedbackEntry[]>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`,\n );\n }\n\n /**\n * Get an agent thread by ID\n */\n async getThreadById(\n threadId: string,\n withTasks = false,\n ): Promise<AgentThreadDto> {\n const query = withTasks ? \"?withTasks=true\" : \"\";\n return this.request<AgentThreadDto>(\n `/api/v1/agents/threads/${threadId}${query}`,\n );\n }\n\n /**\n * Get agent details\n */\n async getAgentDetails(agentId: string): Promise<AgentDto> {\n return this.request<AgentDto>(`/api/v1/agents/${agentId}`);\n }\n\n /**\n * Get an AI-generated explanation of a thread's execution\n */\n async explainAgentThread(threadId: string): Promise<string> {\n return this.request<string>(\n `/api/v1/agents/threads/${threadId}/explain`,\n );\n }\n\n /**\n * Pause or resume a thread\n */\n async pauseResumeThread(\n threadId: string,\n action: \"paused\" | \"queued\",\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/pause-resume`,\n {\n method: \"POST\",\n body: JSON.stringify({ action }),\n },\n );\n }\n\n /**\n * Handle thread approval (approve/reject)\n */\n async handleThreadApproval(\n threadId: string,\n approved: boolean,\n retry: boolean,\n message: string,\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/approval`,\n {\n method: \"POST\",\n body: JSON.stringify({\n action: approved ? \"approved\" : \"rejected\",\n message,\n retry,\n }),\n },\n );\n }\n\n /**\n * Manually complete a thread\n */\n async completeThread(\n threadId: string,\n completionState: string,\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/complete`,\n {\n method: \"POST\",\n body: JSON.stringify({ state: completionState }),\n },\n );\n }\n\n /**\n * Stop an in-progress async chat.\n * The current LLM call or tool execution will finish, then the chat\n * will be marked as completed with the history accumulated so far.\n */\n async stopChat(\n assistantId: string,\n chatUid: string,\n ): Promise<{ chatUid: string; message: string }> {\n return this.request<{ chatUid: string; message: string }>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/stop`,\n { method: \"POST\" },\n );\n }\n\n /**\n * Get chat history content (full conversation after handoff)\n */\n async getChatHistoryContent(\n assistantId: string,\n chatUid: string,\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/content`,\n );\n }\n}\n\n/**\n * Custom error class for API errors\n */\nexport class DevicApiError extends Error {\n public statusCode: number;\n public errorType?: string;\n\n constructor(error: ApiError) {\n super(error.message);\n this.name = \"DevicApiError\";\n this.statusCode = error.statusCode;\n this.errorType = error.error;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sources":["../../../../src/api/client.ts"],"sourcesContent":["import type {\n ProcessMessageDto,\n ChatMessage,\n AsyncResponse,\n RealtimeChatHistory,\n ChatHistory,\n AssistantSpecialization,\n ApiError,\n ToolCallResponse,\n ConversationSummary,\n ListConversationsResponse,\n FeedbackSubmission,\n FeedbackEntry,\n AgentThreadDto,\n AgentDto,\n} from \"./types\";\n\nexport interface DevicApiClientConfig {\n apiKey: string;\n baseUrl: string;\n}\n\n/**\n * Devic API client using native fetch\n */\nexport class DevicApiClient {\n private config: DevicApiClientConfig;\n\n constructor(config: DevicApiClientConfig) {\n this.config = config;\n }\n\n /**\n * Update client configuration\n */\n setConfig(config: Partial<DevicApiClientConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.config.apiKey}`,\n \"devic-api-source\": \"ui\",\n ...options.headers,\n };\n\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n let errorData: ApiError;\n try {\n errorData = await response.json();\n } catch {\n errorData = {\n statusCode: response.status,\n message: response.statusText,\n };\n }\n throw new DevicApiError(errorData);\n }\n\n // Handle responses that may have a wrapper structure\n const data = await response.json();\n\n // If the response has a data property, extract it (common wrapper pattern)\n if (data && typeof data === \"object\" && \"data\" in data) {\n return data.data as T;\n }\n\n return data as T;\n }\n\n /**\n * Get all assistant specializations\n */\n async getAssistants(external = false): Promise<AssistantSpecialization[]> {\n const query = external ? \"?external=true\" : \"\";\n return this.request<AssistantSpecialization[]>(\n `/api/v1/assistants${query}`,\n );\n }\n\n /**\n * Get a specific assistant specialization\n */\n async getAssistant(identifier: string): Promise<AssistantSpecialization> {\n return this.request<AssistantSpecialization>(\n `/api/v1/assistants/${identifier}`,\n );\n }\n\n /**\n * Send a message to an assistant (sync mode)\n */\n async sendMessage(\n assistantId: string,\n dto: ProcessMessageDto,\n signal?: AbortSignal,\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/messages${dto.skipSummarization ? \"?skipSummarization=true\" : \"\"}`,\n {\n method: \"POST\",\n body: JSON.stringify(dto),\n signal,\n },\n );\n }\n\n /**\n * Send a message to an assistant (async mode)\n */\n async sendMessageAsync(\n assistantId: string,\n dto: ProcessMessageDto,\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/messages?async=true${dto.skipSummarization ? \"&skipSummarization=true\" : \"\"}`,\n {\n method: \"POST\",\n body: JSON.stringify(dto),\n },\n );\n }\n\n /**\n * Get real-time chat history (for polling in async mode)\n */\n async getRealtimeHistory(\n assistantId: string,\n chatUid: string,\n ): Promise<RealtimeChatHistory> {\n return this.request<RealtimeChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/realtime`,\n );\n }\n\n /**\n * Get chat history for a specific conversation\n */\n async getChatHistory(\n assistantId: string,\n chatUid: string,\n options?: { tenantId?: string },\n ): Promise<ChatHistory> {\n const params = new URLSearchParams();\n if (options?.tenantId) {\n params.set(\"tenantId\", options.tenantId);\n }\n const query = params.toString();\n return this.request<ChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}${query ? `?${query}` : \"\"}`,\n );\n }\n\n /**\n * List conversations for an assistant\n */\n async listConversations(\n assistantId: string,\n options?: { tenantId?: string; offset?: number; limit?: number },\n ): Promise<ListConversationsResponse> {\n const params = new URLSearchParams();\n if (options?.tenantId) {\n params.set(\"tenantId\", options.tenantId);\n }\n if (options?.offset != null) {\n params.set(\"offset\", String(options.offset));\n }\n if (options?.limit != null) {\n params.set(\"limit\", String(options.limit));\n }\n params.set(\"omitContent\", \"true\");\n const query = params.toString();\n return this.request<ListConversationsResponse>(\n `/api/v1/assistants/${assistantId}/chats${query ? `?${query}` : \"\"}`,\n );\n }\n\n /**\n * Send tool call responses back to the assistant\n */\n async sendToolResponses(\n assistantId: string,\n chatUid: string,\n responses: ToolCallResponse[],\n ): Promise<AsyncResponse> {\n return this.request<AsyncResponse>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`,\n {\n method: \"POST\",\n body: JSON.stringify({ responses }),\n },\n );\n }\n\n /**\n * Submit feedback for a chat message\n */\n async submitChatFeedback(\n assistantId: string,\n chatUid: string,\n data: FeedbackSubmission,\n ): Promise<FeedbackEntry> {\n return this.request<FeedbackEntry>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`,\n {\n method: \"POST\",\n body: JSON.stringify(data),\n },\n );\n }\n\n /**\n * Get all feedback for a chat\n */\n async getChatFeedback(\n assistantId: string,\n chatUid: string,\n ): Promise<FeedbackEntry[]> {\n return this.request<FeedbackEntry[]>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`,\n );\n }\n\n /**\n * Get an agent thread by ID\n */\n async getThreadById(\n threadId: string,\n withTasks = false,\n ): Promise<AgentThreadDto> {\n const query = withTasks ? \"?withTasks=true\" : \"\";\n return this.request<AgentThreadDto>(\n `/api/v1/agents/threads/${threadId}${query}`,\n );\n }\n\n /**\n * Get agent details\n */\n async getAgentDetails(agentId: string): Promise<AgentDto> {\n return this.request<AgentDto>(`/api/v1/agents/${agentId}`);\n }\n\n /**\n * Get an AI-generated explanation of a thread's execution\n */\n async explainAgentThread(threadId: string): Promise<string> {\n return this.request<string>(\n `/api/v1/agents/threads/${threadId}/explain`,\n );\n }\n\n /**\n * Pause or resume a thread\n */\n async pauseResumeThread(\n threadId: string,\n action: \"paused\" | \"queued\",\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/pause-resume`,\n {\n method: \"POST\",\n body: JSON.stringify({ action }),\n },\n );\n }\n\n /**\n * Handle thread approval (approve/reject)\n */\n async handleThreadApproval(\n threadId: string,\n approved: boolean,\n retry: boolean,\n message: string,\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/approval`,\n {\n method: \"POST\",\n body: JSON.stringify({\n action: approved ? \"approved\" : \"rejected\",\n message,\n retry,\n }),\n },\n );\n }\n\n /**\n * Manually complete a thread\n */\n async completeThread(\n threadId: string,\n completionState: string,\n ): Promise<void> {\n return this.request<void>(\n `/api/v1/agents/threads/${threadId}/complete`,\n {\n method: \"POST\",\n body: JSON.stringify({ state: completionState }),\n },\n );\n }\n\n /**\n * Stop an in-progress async chat.\n * The current LLM call or tool execution will finish, then the chat\n * will be marked as completed with the history accumulated so far.\n */\n async stopChat(\n assistantId: string,\n chatUid: string,\n ): Promise<{ chatUid: string; message: string }> {\n return this.request<{ chatUid: string; message: string }>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/stop`,\n { method: \"POST\" },\n );\n }\n\n /**\n * Upload a file and get a download URL\n */\n async uploadFile(\n file: File,\n ): Promise<{ name: string; downloadUrl: string; fileType: string }> {\n const url = `${this.config.baseUrl}/api/v1/files/upload`;\n\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n \"devic-api-source\": \"ui\",\n },\n body: formData,\n });\n\n if (!response.ok) {\n let errorData: { statusCode: number; message: string };\n try {\n errorData = await response.json();\n } catch {\n errorData = {\n statusCode: response.status,\n message: response.statusText,\n };\n }\n throw new DevicApiError(errorData);\n }\n\n const data = await response.json();\n if (data && typeof data === \"object\" && \"data\" in data) {\n return data.data;\n }\n return data;\n }\n\n /**\n * Get chat history content (full conversation after handoff)\n */\n async getChatHistoryContent(\n assistantId: string,\n chatUid: string,\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}/content`,\n );\n }\n}\n\n/**\n * Custom error class for API errors\n */\nexport class DevicApiError extends Error {\n public statusCode: number;\n public errorType?: string;\n\n constructor(error: ApiError) {\n super(error.message);\n this.name = \"DevicApiError\";\n this.statusCode = error.statusCode;\n this.errorType = error.error;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -49,6 +49,7 @@ const DEFAULT_OPTIONS = {
49
49
  toolGroups: undefined,
50
50
  stopButtonContent: undefined,
51
51
  debug: false,
52
+ persistConversation: false,
52
53
  };
53
54
  /**
54
55
  * Chat drawer component for Devic assistants
@@ -78,17 +79,45 @@ const DEFAULT_OPTIONS = {
78
79
  const ChatDrawer = React.forwardRef(function ChatDrawer(props, ref) {
79
80
  return (jsxRuntime.jsx(ErrorBoundary.ChatDrawerErrorBoundary, { children: jsxRuntime.jsx(ChatDrawerInner, { ...props, forwardedRef: ref }) }));
80
81
  });
81
- function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onOpen, onClose, isOpen: controlledIsOpen, className, mode = 'drawer', onConversationChange, forwardedRef, }) {
82
+ function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onFileUpload, onOpen, onClose, isOpen: controlledIsOpen, className, mode = 'drawer', onConversationChange, forwardedRef, }) {
82
83
  // Merge options with defaults
83
84
  const mergedOptions = React.useMemo(() => ({ ...DEFAULT_OPTIONS, ...options }), [options]);
85
+ // localStorage key for persisting selected conversation
86
+ const storageKey = mergedOptions.persistConversation
87
+ ? `devic-ui-chatUid-${assistantId}`
88
+ : null;
89
+ // Resolve initial chatUid: prop takes priority, then localStorage
90
+ const resolvedInitialChatUid = React.useMemo(() => {
91
+ if (initialChatUid)
92
+ return initialChatUid;
93
+ if (storageKey) {
94
+ try {
95
+ return localStorage.getItem(storageKey) || undefined;
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ return undefined;
102
+ }, [initialChatUid, storageKey]);
84
103
  // Drawer open state (can be controlled or uncontrolled; inline mode is always open)
85
104
  const [internalIsOpen, setInternalIsOpen] = React.useState(mergedOptions.defaultOpen);
86
105
  const isInline = mode === 'inline';
87
106
  const isOpen = isInline ? true : (controlledIsOpen ?? internalIsOpen);
107
+ // Wrap onChatCreated to persist chatUid in localStorage
108
+ const handleChatCreated = React.useCallback((chatUid) => {
109
+ if (storageKey) {
110
+ try {
111
+ localStorage.setItem(storageKey, chatUid);
112
+ }
113
+ catch { }
114
+ }
115
+ onChatCreated?.(chatUid);
116
+ }, [storageKey, onChatCreated]);
88
117
  // Use chat hook
89
118
  const chat = useDevicChat.useDevicChat({
90
119
  assistantId,
91
- chatUid: initialChatUid,
120
+ chatUid: resolvedInitialChatUid,
92
121
  apiKey,
93
122
  baseUrl,
94
123
  tenantId,
@@ -99,7 +128,8 @@ function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, e
99
128
  onMessageReceived,
100
129
  onToolCall,
101
130
  onError,
102
- onChatCreated,
131
+ onChatCreated: handleChatCreated,
132
+ onFileUpload,
103
133
  debug: mergedOptions.debug,
104
134
  });
105
135
  // Fetch assistant avatar when showAvatar is enabled
@@ -150,10 +180,22 @@ function ChatDrawerInner({ assistantId, chatUid: initialChatUid, options = {}, e
150
180
  const handleConversationSelect = React.useCallback((chatUid) => {
151
181
  chat.loadChat(chatUid);
152
182
  onConversationChange?.(chatUid);
153
- }, [chat, onConversationChange]);
183
+ if (storageKey) {
184
+ try {
185
+ localStorage.setItem(storageKey, chatUid);
186
+ }
187
+ catch { }
188
+ }
189
+ }, [chat, onConversationChange, storageKey]);
154
190
  const handleNewChat = React.useCallback(() => {
155
191
  chat.clearChat();
156
- }, [chat]);
192
+ if (storageKey) {
193
+ try {
194
+ localStorage.removeItem(storageKey);
195
+ }
196
+ catch { }
197
+ }
198
+ }, [chat, storageKey]);
157
199
  // Handle suggested message click
158
200
  const handleSuggestedClick = React.useCallback((message) => {
159
201
  chat.sendMessage(message);
@@ -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 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":["forwardRef","_jsx","ChatDrawerErrorBoundary","useMemo","useState","useDevicChat","useOptionalDevicContext","useRef","useEffect","client","DevicApiClient","useCallback","useImperativeHandle","_jsxs","ConversationSelector","ChatMessages","ChatInput"],"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 persistConversation: 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 onFileUpload,\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 // localStorage key for persisting selected conversation\n const storageKey = mergedOptions.persistConversation\n ? `devic-ui-chatUid-${assistantId}`\n : null;\n\n // Resolve initial chatUid: prop takes priority, then localStorage\n const resolvedInitialChatUid = useMemo(() => {\n if (initialChatUid) return initialChatUid;\n if (storageKey) {\n try { return localStorage.getItem(storageKey) || undefined; } catch { return undefined; }\n }\n return undefined;\n }, [initialChatUid, storageKey]);\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 // Wrap onChatCreated to persist chatUid in localStorage\n const handleChatCreated = useCallback(\n (chatUid: string) => {\n if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n onChatCreated?.(chatUid);\n },\n [storageKey, onChatCreated]\n );\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: resolvedInitialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated: handleChatCreated,\n onFileUpload,\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?: File[]) => {\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 if (storageKey) {\n try { localStorage.setItem(storageKey, chatUid); } catch {}\n }\n },\n [chat, onConversationChange, storageKey]\n );\n\n const handleNewChat = useCallback(() => {\n chat.clearChat();\n if (storageKey) {\n try { localStorage.removeItem(storageKey); } catch {}\n }\n }, [chat, storageKey]);\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":["forwardRef","_jsx","ChatDrawerErrorBoundary","useMemo","useState","useCallback","useDevicChat","useOptionalDevicContext","useRef","useEffect","client","DevicApiClient","useImperativeHandle","_jsxs","ConversationSelector","ChatMessages","ChatInput"],"mappings":";;;;;;;;;;;;AAWA,MAAM,eAAe,GAAgC;AACnD,IAAA,QAAQ,EAAE,OAAO;AACjB,IAAA,KAAK,EAAE,MAAM;AACb,IAAA,WAAW,EAAE,KAAK;AAClB,IAAA,KAAK,EAAE,SAAS;AAChB,IAAA,cAAc,EAAE,EAAE;AAClB,IAAA,iBAAiB,EAAE,EAAE;AACrB,IAAA,iBAAiB,EAAE,KAAK;IACxB,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;AACnD,IAAA,WAAW,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;AAC7B,IAAA,gBAAgB,EAAE,mBAAmB;AACrC,IAAA,KAAK,EAAE,MAAM;AACb,IAAA,UAAU,EAAE,KAAK;AACjB,IAAA,gBAAgB,EAAE,IAAI;AACtB,IAAA,MAAM,EAAE,IAAI;AACZ,IAAA,YAAY,EAAE,CAAC;AACf,IAAA,SAAS,EAAE,KAAK;AAChB,IAAA,QAAQ,EAAE,GAAG;AACb,IAAA,QAAQ,EAAE,GAAG;AACb,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,UAAU,EAAE,SAAgB;AAC5B,IAAA,eAAe,EAAE,SAAgB;AACjC,IAAA,SAAS,EAAE,SAAgB;AAC3B,IAAA,wBAAwB,EAAE,SAAgB;AAC1C,IAAA,WAAW,EAAE,SAAgB;AAC7B,IAAA,eAAe,EAAE,SAAgB;AACjC,IAAA,mBAAmB,EAAE,SAAgB;AACrC,IAAA,oBAAoB,EAAE,SAAgB;AACtC,IAAA,wBAAwB,EAAE,SAAgB;AAC1C,IAAA,eAAe,EAAE,SAAgB;AACjC,IAAA,gBAAgB,EAAE,SAAgB;AAClC,IAAA,iBAAiB,EAAE,SAAgB;AACnC,IAAA,aAAa,EAAE,SAAgB;AAC/B,IAAA,SAAS,EAAE,SAAgB;AAC3B,IAAA,YAAY,EAAE,IAAI;AAClB,IAAA,qBAAqB,EAAE,SAAgB;AACvC,IAAA,UAAU,EAAE,SAAgB;AAC5B,IAAA,iBAAiB,EAAE,SAAgB;AACnC,IAAA,KAAK,EAAE,KAAK;AACZ,IAAA,mBAAmB,EAAE,KAAK;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACI,MAAM,UAAU,GAAGA,gBAAU,CAClC,SAAS,UAAU,CAAC,KAAK,EAAE,GAAG,EAAA;AAC5B,IAAA,QACEC,cAAA,CAACC,qCAAuB,EAAA,EAAA,QAAA,EACtBD,eAAC,eAAe,EAAA,EAAA,GAAK,KAAK,EAAE,YAAY,EAAE,GAAG,EAAA,CAAI,EAAA,CACzB;AAE9B,CAAC;AAOH,SAAS,eAAe,CAAC,EACvB,WAAW,EACX,OAAO,EAAE,cAAc,EACvB,OAAO,GAAG,EAAE,EACZ,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,MAAM,EACN,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,aAAa,EACb,YAAY,EACZ,MAAM,EACN,OAAO,EACP,MAAM,EAAE,gBAAgB,EACxB,SAAS,EACT,IAAI,GAAG,QAAQ,EACf,oBAAoB,EACpB,YAAY,GACS,EAAA;;IAErB,MAAM,aAAa,GAAGE,aAAO,CAC3B,OAAO,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAC,EAC1C,CAAC,OAAO,CAAC,CACV;;AAGD,IAAA,MAAM,UAAU,GAAG,aAAa,CAAC;UAC7B,CAAA,iBAAA,EAAoB,WAAW,CAAA;UAC/B,IAAI;;AAGR,IAAA,MAAM,sBAAsB,GAAGA,aAAO,CAAC,MAAK;AAC1C,QAAA,IAAI,cAAc;AAAE,YAAA,OAAO,cAAc;QACzC,IAAI,UAAU,EAAE;AACd,YAAA,IAAI;gBAAE,OAAO,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,SAAS;YAAE;AAAE,YAAA,MAAM;AAAE,gBAAA,OAAO,SAAS;YAAE;QAC1F;AACA,QAAA,OAAO,SAAS;AAClB,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;;AAGhC,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAGC,cAAQ,CAAC,aAAa,CAAC,WAAW,CAAC;AAC/E,IAAA,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ;AAClC,IAAA,MAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,IAAI,gBAAgB,IAAI,cAAc,CAAC;;AAGrE,IAAA,MAAM,iBAAiB,GAAGC,iBAAW,CACnC,CAAC,OAAe,KAAI;QAClB,IAAI,UAAU,EAAE;AACd,YAAA,IAAI;AAAE,gBAAA,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;YAAE;YAAE,MAAM,EAAC;QAC5D;AACA,QAAA,aAAa,GAAG,OAAO,CAAC;AAC1B,IAAA,CAAC,EACD,CAAC,UAAU,EAAE,aAAa,CAAC,CAC5B;;IAGD,MAAM,IAAI,GAAGC,yBAAY,CAAC;QACxB,WAAW;AACX,QAAA,OAAO,EAAE,sBAAsB;QAC/B,MAAM;QACN,OAAO;QACP,QAAQ;QACR,cAAc;QACd,YAAY;QACZ,mBAAmB;QACnB,aAAa;QACb,iBAAiB;QACjB,UAAU;QACV,OAAO;AACP,QAAA,aAAa,EAAE,iBAAiB;QAChC,YAAY;QACZ,KAAK,EAAE,aAAa,CAAC,KAAK;AAC3B,KAAA,CAAC;;AAGF,IAAA,MAAM,OAAO,GAAGC,oCAAuB,EAAE;AACzC,IAAA,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,EAAE,MAAM;IAChD,MAAM,eAAe,GAAG,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,sBAAsB;IAC7E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAGH,cAAQ,CAAgB,IAAI,CAAC;AAC/D,IAAA,MAAM,gBAAgB,GAAGI,YAAM,CAAgB,IAAI,CAAC;IAEpDC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,aAAa,CAAC,UAAU,IAAI,CAAC,cAAc,IAAI,gBAAgB,CAAC,OAAO,KAAK,WAAW;YAAE;AAC9F,QAAA,gBAAgB,CAAC,OAAO,GAAG,WAAW;AACtC,QAAA,MAAMC,QAAM,GAAG,IAAIC,qBAAc,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QACvFD,QAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAI;YAC1C,IAAI,CAAC,CAAC,MAAM;AAAE,gBAAA,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;QACtC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;AACpB,IAAA,CAAC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;;AAG5E,IAAA,MAAM,UAAU,GAAGL,iBAAW,CAAC,MAAK;QAClC,iBAAiB,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI;AACZ,IAAA,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AAEZ,IAAA,MAAM,WAAW,GAAGA,iBAAW,CAAC,MAAK;QACnC,iBAAiB,CAAC,KAAK,CAAC;QACxB,OAAO,IAAI;AACb,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,MAAM,YAAY,GAAGA,iBAAW,CAAC,MAAK;QACpC,iBAAiB,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IACpC,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAAO,yBAAmB,CAAC,YAAY,EAAE,OAAO;AACvC,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,KAAK,EAAE,WAAW;AAClB,QAAA,MAAM,EAAE,YAAY;AACpB,QAAA,UAAU,EAAE,CAAC,OAAe,KAAI;AAC9B,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxB,CAAC;AACD,QAAA,WAAW,EAAE,CAAC,OAAe,KAAI;AAC/B,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;QAC3B,CAAC;KACF,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;;IAGlD,MAAM,UAAU,GAAGP,iBAAW,CAC5B,CAAC,OAAe,EAAE,KAAc,KAAI;QAClC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC;AACtC,IAAA,CAAC,EACD,CAAC,IAAI,CAAC,CACP;;AAGD,IAAA,MAAM,wBAAwB,GAAGA,iBAAW,CAC1C,CAAC,OAAe,KAAI;AAClB,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;AACtB,QAAA,oBAAoB,GAAG,OAAO,CAAC;QAC/B,IAAI,UAAU,EAAE;AACd,YAAA,IAAI;AAAE,gBAAA,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;YAAE;YAAE,MAAM,EAAC;QAC5D;IACF,CAAC,EACD,CAAC,IAAI,EAAE,oBAAoB,EAAE,UAAU,CAAC,CACzC;AAED,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAAC,MAAK;QACrC,IAAI,CAAC,SAAS,EAAE;QAChB,IAAI,UAAU,EAAE;AACd,YAAA,IAAI;AAAE,gBAAA,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE;YAAE,MAAM,EAAC;QACtD;AACF,IAAA,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;;AAGtB,IAAA,MAAM,oBAAoB,GAAGA,iBAAW,CACtC,CAAC,OAAe,KAAI;AAClB,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AAC3B,IAAA,CAAC,EACD,CAAC,IAAI,CAAC,CACP;;AAGD,IAAA,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAGD,cAAQ,CAAuC,IAAI,GAAG,EAAE,CAAC;AAC/F,IAAA,MAAM,iBAAiB,GAAGI,YAAM,CAAwB,IAAI,CAAC;;IAG7DC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,cAAc,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE;AAChD,YAAA,iBAAiB,CAAC,OAAO,GAAG,IAAIE,qBAAc,CAAC;AAC7C,gBAAA,MAAM,EAAE,cAAc;AACtB,gBAAA,OAAO,EAAE,eAAe;AACzB,aAAA,CAAC;QACJ;AACF,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;;IAGrCF,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY;YAAE;QAEhF,iBAAiB,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO;AAChE,aAAA,IAAI,CAAC,CAAC,OAAO,KAAI;AAChB,YAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmC;AACzD,YAAA,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;AAC3B,gBAAA,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE;AAChC,oBAAA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;gBACvE;YACF;YACA,cAAc,CAAC,MAAM,CAAC;AACxB,QAAA,CAAC;aACA,KAAK,CAAC,MAAK;;AAEZ,QAAA,CAAC,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;;AAG3D,IAAA,MAAM,cAAc,GAAGJ,iBAAW,CAChC,OAAO,SAAiB,EAAE,QAAiB,EAAE,OAAgB,KAAI;QAC/D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO;YAAE;AAEjD,QAAA,IAAI;YACF,MAAM,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE;gBAC5E,SAAS;AACT,gBAAA,QAAQ,EAAE,QAAQ;AAClB,gBAAA,eAAe,EAAE,OAAO;AACzB,aAAA,CAAC;AAEF,YAAA,cAAc,CAAC,CAAC,IAAI,KAAI;AACtB,gBAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC;AAC5B,gBAAA,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AACzD,gBAAA,OAAO,MAAM;AACf,YAAA,CAAC,CAAC;QACJ;QAAE,OAAO,GAAG,EAAE;AACZ,YAAA,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC;AAChD,YAAA,MAAM,GAAG;QACX;IACF,CAAC,EACD,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAC5B;;;AAID,IAAA,MAAM,SAAS,GAAGG,YAAM,CAAiB,IAAI,CAAC;IAC9CC,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO;AAC5B,QAAA,IAAI,CAAC,EAAE;YAAE;AACT,QAAA,MAAM,IAAI,GAAmC;AAC3C,YAAA,CAAC,iBAAiB,EAAE,aAAa,CAAC,KAAK,KAAK,eAAe,CAAC,KAAK,GAAG,aAAa,CAAC,KAAK,GAAG,SAAS,CAAC;AACpG,YAAA,CAAC,qBAAqB,EAAE,aAAa,CAAC,UAAU,CAAC;AACjD,YAAA,CAAC,YAAY,EAAE,aAAa,CAAC,eAAe,CAAC;AAC7C,YAAA,CAAC,cAAc,EAAE,aAAa,CAAC,SAAS,CAAC;AACzC,YAAA,CAAC,sBAAsB,EAAE,aAAa,CAAC,wBAAwB,CAAC;AAChE,YAAA,CAAC,gBAAgB,EAAE,aAAa,CAAC,WAAW,CAAC;AAC7C,YAAA,CAAC,qBAAqB,EAAE,aAAa,CAAC,eAAe,CAAC;AACtD,YAAA,CAAC,0BAA0B,EAAE,aAAa,CAAC,mBAAmB,CAAC;AAC/D,YAAA,CAAC,0BAA0B,EAAE,aAAa,CAAC,oBAAoB,CAAC;AAChE,YAAA,CAAC,+BAA+B,EAAE,aAAa,CAAC,wBAAwB,CAAC;AACzE,YAAA,CAAC,kBAAkB,EAAE,aAAa,CAAC,eAAe,CAAC;SACpD;QACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;YAChC,IAAI,KAAK,EAAE;gBACT,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC;YACnC;iBAAO;AACL,gBAAA,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;YAC/B;QACF;IACF,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,EAAE,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,wBAAwB,EAAE,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,eAAe,EAAE,aAAa,CAAC,mBAAmB,EAAE,aAAa,CAAC,oBAAoB,EAAE,aAAa,CAAC,wBAAwB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;;IAG3V,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAGL,cAAQ,CAAgB,IAAI,CAAC;AAErE,IAAA,MAAM,iBAAiB,GAAGC,iBAAW,CACnC,CAAC,CAAmB,KAAI;QACtB,CAAC,CAAC,cAAc,EAAE;AAClB,QAAA,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO;QACxB,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,WAAW,IAAI,CAAC;AACtD,QAAA,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,KAAK,MAAM;AAEhD,QAAA,MAAM,MAAM,GAAG,CAAC,EAAc,KAAI;AAChC,YAAA,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,GAAG,MAAM;AACjC,YAAA,MAAM,QAAQ,GAAG,UAAU,IAAI,MAAM,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,aAAa,CAAC,QAAQ,EACtB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAC3C;YACD,eAAe,CAAC,OAAO,CAAC;AAC1B,QAAA,CAAC;QAED,MAAM,IAAI,GAAG,MAAK;AAChB,YAAA,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC;AACjD,YAAA,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC;AAC/C,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC;AAC9C,QAAA,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC;AAC5C,IAAA,CAAC,EACD,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,CACzE;;IAGD,MAAM,SAAS,GAAG;UACd,CAAA,EAAG,YAAY,CAAA,EAAA;AACjB,UAAE,OAAO,aAAa,CAAC,KAAK,KAAK;AAC/B,cAAE,CAAA,EAAG,aAAa,CAAC,KAAK,CAAA,EAAA;AACxB,cAAE,aAAa,CAAC,KAAK;AAEzB,IAAA,MAAM,WAAW,GAAGF,aAAO,CACzB,OAAO;AACL,QAAA,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,aAAa,CAAC,MAAM;AAC5B,QAAA,YAAY,EAAE,OAAO,aAAa,CAAC,YAAY,KAAK;AAClD,cAAE,CAAA,EAAG,aAAa,CAAC,YAAY,CAAA,EAAA;cAC7B,aAAa,CAAC,YAAY;QAC9B,GAAG,aAAa,CAAC,KAAK;AACvB,KAAA,CAAC,EACF,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC,CACnF;AAED,IAAA,MAAM,YAAY,GAAGA,aAAO,CAC1B,OAAO;AACL,QAAA,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC;AACjC,KAAA,CAAC,EACF,CAAC,aAAa,CAAC,MAAM,CAAC,CACvB;AAED,IAAA,MAAM,YAAY,GAAGA,aAAO,CAC1B,OAAO;AACL,QAAA,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC;AAChC,QAAA,CAAC,aAAa,CAAC,QAAQ,GAAG,EAAE;AAC5B,QAAA,MAAM,EAAE,EAAE;KACX,CAAC,EACF,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAC/C;IAED,QACEU,kDAEG,CAAC,QAAQ,KACRZ,cAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,sBAAsB,EAAA,WAAA,EACrB,MAAM,EACjB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,WAAW,EAAA,CACpB,CACH,EAGDY,eAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,CAAA,kBAAA,EAAqB,SAAS,IAAI,EAAE,CAAA,CAAE,EAAA,eAAA,EAClC,aAAa,CAAC,QAAQ,eAC1B,MAAM,EAAA,WAAA,EACN,IAAI,EACf,KAAK,EAAE,WAAW,EAAA,QAAA,EAAA,CAGjB,aAAa,CAAC,SAAS,KACtBZ,wBACE,SAAS,EAAC,qBAAqB,EAAA,eAAA,EAChB,aAAa,CAAC,QAAQ,EACrC,WAAW,EAAE,iBAAiB,EAAA,CAC9B,CACH,EAGDY,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,EAAA,QAAA,EAAA,CACjC,SAAS,KACRZ,cAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,qBAAqB,EAC/B,GAAG,EAAE,SAAS,EACd,GAAG,EAAC,EAAE,iBACM,MAAM,EAAA,CAClB,CACH,EACDA,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,oBAAoB,EAAA,QAAA,EAAE,aAAa,CAAC,KAAK,EAAA,CAAM,EAC7DA,cAAA,CAACa,yCAAoB,EAAA,EACnB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,IAAI,CAAC,OAAO,EAC5B,QAAQ,EAAE,wBAAwB,EAClC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAAA,CAClB,EACFD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6BAA6B,EAAA,QAAA,EAAA,CAC1CZ,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,oBAAoB,EAC9B,OAAO,EAAE,aAAa,EACtB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACF,UAAU,EACrB,KAAK,EAAC,UAAU,EAAA,QAAA,EAEhBA,cAAA,CAAC,QAAQ,EAAA,EAAA,CAAG,GACL,EACR,CAAC,QAAQ,KACRA,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,oBAAoB,EAC9B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACF,YAAY,EAAA,QAAA,EAEvBA,eAAC,SAAS,EAAA,EAAA,CAAG,EAAA,CACN,CACV,CAAA,EAAA,CACG,CAAA,EAAA,CACF,EAGL,IAAI,CAAC,KAAK,KACTA,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,aAAa,EAAA,QAAA,EACzB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA,CACf,CACP,EAGDA,cAAA,CAACc,yBAAY,IACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,WAAW,EAAE,IAAI,CAAC,QAAQ,EAC1B,SAAS,EAAE,IAAI,CAAC,SAAS,EACzB,cAAc,EAAE,aAAa,CAAC,cAAc,EAC5C,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,EAChD,aAAa,EAAE,aAAa,CAAC,aAAa,EAC1C,SAAS,EAAE,aAAa,CAAC,SAAS,EAClC,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,EAChD,YAAY,EAAE,aAAa,CAAC,YAAY,EACxC,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,cAAc,EAC1B,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,IAAI,SAAS,EAC5D,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAC3C,qBAAqB,EAAE,aAAa,CAAC,qBAAqB,EAC1D,UAAU,EAAE,aAAa,CAAC,UAAU,EACpC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,eAAe,EAAA,CACxB,EAGFd,cAAA,CAACe,mBAAS,EAAA,EACR,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAC1C,WAAW,EAAE,aAAa,CAAC,gBAAgB,EAC3C,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,EAChD,WAAW,EAAE,aAAa,CAAC,WAAW,EACtC,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,eAAe,EAAE,IAAI,CAAC,SAAS,GAAG,kCAAkC,GAAG,SAAS,EAChF,YAAY,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,EAC/C,MAAM,EAAE,IAAI,CAAC,QAAQ,EACrB,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAAA,CAClD,CAAA,EAAA,CACE,EAGL,CAAC,QAAQ,IAAI,CAAC,MAAM,KACnBf,2BACE,SAAS,EAAC,eAAe,EACzB,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,YAAY,EACnB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACF,WAAW,EAAA,QAAA,EAEtBA,cAAA,CAAC,QAAQ,KAAG,EAAA,CACL,CACV,CAAA,EAAA,CACA;AAEP;AAEA;;AAEG;AACH,SAAS,SAAS,GAAA;AAChB,IAAA,QACEY,eAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBZ,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACtCA,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CAClC;AAEV;AAEA;;AAEG;AACH,SAAS,QAAQ,GAAA;AACf,IAAA,QACEY,eAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBZ,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACvCA,cAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CACnC;AAEV;AAEA;;AAEG;AACH,SAAS,QAAQ,GAAA;IACf,QACEA,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,cAAc,EAAA,QAAA,EAEnBA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,yFAAyF,EAAA,CAAG,EAAA,CAChG;AAEV;;;;"}
@@ -42,12 +42,7 @@ sendButtonContent, disabledMessage, isProcessing = false, onStop, stopButtonCont
42
42
  const trimmedMessage = message.trim();
43
43
  if (!trimmedMessage && files.length === 0)
44
44
  return;
45
- // Convert File objects to ChatFile format
46
- const chatFiles = files.map((file) => ({
47
- name: file.name,
48
- fileType: getFileType(file.type),
49
- }));
50
- onSend(trimmedMessage, chatFiles.length > 0 ? chatFiles : undefined);
45
+ onSend(trimmedMessage, files.length > 0 ? files : undefined);
51
46
  setMessage('');
52
47
  setFiles([]);
53
48
  // Reset textarea height
@@ -86,24 +81,7 @@ sendButtonContent, disabledMessage, isProcessing = false, onStop, stopButtonCont
86
81
  return (jsxRuntime.jsxs("div", { className: "devic-input-area", children: [disabledMessage && disabled && (jsxRuntime.jsxs("div", { className: "devic-input-disabled-notice", children: [jsxRuntime.jsx(WaitingIcon, {}), disabledMessage] })), files.length > 0 && (jsxRuntime.jsx("div", { className: "devic-file-preview", children: files.map((file, idx) => (jsxRuntime.jsxs("div", { className: "devic-file-preview-item", children: [jsxRuntime.jsx(FileIcon, {}), jsxRuntime.jsx("span", { children: file.name }), jsxRuntime.jsx("button", { className: "devic-file-remove", onClick: () => removeFile(idx), type: "button", children: "\u00D7" })] }, idx))) })), jsxRuntime.jsxs("div", { className: "devic-input-wrapper", children: [enableFileUploads && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", accept: acceptedTypes, multiple: true, onChange: handleFileSelect, style: { display: 'none' } }), jsxRuntime.jsx("button", { className: "devic-input-btn", onClick: () => fileInputRef.current?.click(), disabled: disabled, type: "button", title: "Attach file", children: jsxRuntime.jsx(AttachIcon, {}) })] })), jsxRuntime.jsx("textarea", { ref: textareaRef, className: "devic-input", value: message, onChange: (e) => {
87
82
  setMessage(e.target.value);
88
83
  handleInput();
89
- }, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1 }), isProcessing ? (stopButtonContent ? (jsxRuntime.jsxs("div", { className: "devic-send-btn-wrapper", children: [jsxRuntime.jsx("div", { className: "devic-send-btn-custom", "aria-hidden": "true", children: stopButtonContent }), jsxRuntime.jsx("button", { className: "devic-send-btn-overlay", onClick: onStop, type: "button", title: "Stop" })] })) : (jsxRuntime.jsx("button", { className: "devic-input-btn devic-send-btn", onClick: onStop, type: "button", title: "Stop", children: jsxRuntime.jsx(StopIcon, {}) }))) : sendButtonContent ? (jsxRuntime.jsxs("div", { className: "devic-send-btn-wrapper", children: [jsxRuntime.jsx("div", { className: "devic-send-btn-custom", "aria-hidden": "true", children: sendButtonContent }), jsxRuntime.jsx("button", { className: "devic-send-btn-overlay", onClick: handleSend, disabled: disabled || (!message.trim() && files.length === 0), type: "button", title: "Send message" })] })) : (jsxRuntime.jsx("button", { className: "devic-input-btn devic-send-btn", onClick: handleSend, disabled: disabled || (!message.trim() && files.length === 0), type: "button", title: "Send message", children: jsxRuntime.jsx(SendIcon, {}) }))] })] }));
90
- }
91
- /**
92
- * Get file type category from MIME type
93
- */
94
- function getFileType(mimeType) {
95
- if (mimeType.startsWith('image/'))
96
- return 'image';
97
- if (mimeType.startsWith('audio/'))
98
- return 'audio';
99
- if (mimeType.startsWith('video/'))
100
- return 'video';
101
- if (mimeType.startsWith('application/pdf') ||
102
- mimeType.startsWith('application/msword') ||
103
- mimeType.startsWith('text/')) {
104
- return 'document';
105
- }
106
- return 'other';
84
+ }, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1 }), isProcessing ? (stopButtonContent ? (jsxRuntime.jsxs("div", { className: "devic-send-btn-wrapper", children: [jsxRuntime.jsx("div", { className: "devic-send-btn-custom", "aria-hidden": "true", children: stopButtonContent }), jsxRuntime.jsx("button", { className: "devic-send-btn-overlay", onClick: onStop, type: "button", title: "Stop" })] })) : (jsxRuntime.jsx("button", { className: "devic-input-btn devic-stop-btn", onClick: onStop, type: "button", title: "Stop", children: jsxRuntime.jsx(StopIcon, {}) }))) : sendButtonContent ? (jsxRuntime.jsxs("div", { className: "devic-send-btn-wrapper", children: [jsxRuntime.jsx("div", { className: "devic-send-btn-custom", "aria-hidden": "true", children: sendButtonContent }), jsxRuntime.jsx("button", { className: "devic-send-btn-overlay", onClick: handleSend, disabled: disabled || (!message.trim() && files.length === 0), type: "button", title: "Send message" })] })) : (jsxRuntime.jsx("button", { className: "devic-input-btn devic-send-btn", onClick: handleSend, disabled: disabled || (!message.trim() && files.length === 0), type: "button", title: "Send message", children: jsxRuntime.jsx(SendIcon, {}) }))] })] }));
107
85
  }
108
86
  /**
109
87
  * Attach icon
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInput.js","sources":["../../../../../src/components/ChatDrawer/ChatInput.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport type { ChatInputProps } from './ChatDrawer.types';\nimport type { ChatFile } from '../../api/types';\n\nconst FILE_TYPE_ACCEPT: Record<string, string[]> = {\n images: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],\n documents: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'text/plain',\n 'text/csv',\n ],\n audio: ['audio/mpeg', 'audio/wav', 'audio/ogg'],\n video: ['video/mp4', 'video/webm', 'video/ogg'],\n};\n\n/**\n * Chat input component with file upload support\n */\nexport function ChatInput({\n onSend,\n disabled = false,\n placeholder = 'Type a message...',\n enableFileUploads = false,\n allowedFileTypes = { images: true, documents: true },\n maxFileSize = 10 * 1024 * 1024, // 10MB\n sendButtonContent,\n disabledMessage,\n isProcessing = false,\n onStop,\n stopButtonContent,\n}: ChatInputProps): JSX.Element {\n const [message, setMessage] = useState('');\n const [files, setFiles] = useState<File[]>([]);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // Calculate accepted file types\n const acceptedTypes = Object.entries(allowedFileTypes)\n .filter(([, enabled]) => enabled)\n .flatMap(([type]) => FILE_TYPE_ACCEPT[type] || [])\n .join(',');\n\n // Auto-resize textarea\n const handleInput = useCallback(() => {\n const textarea = textareaRef.current;\n if (textarea) {\n textarea.style.height = 'auto';\n textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;\n }\n }, []);\n\n // Handle send\n const handleSend = useCallback(() => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage && files.length === 0) return;\n\n // Convert File objects to ChatFile format\n const chatFiles: ChatFile[] = files.map((file) => ({\n name: file.name,\n fileType: getFileType(file.type),\n }));\n\n onSend(trimmedMessage, chatFiles.length > 0 ? chatFiles : undefined);\n setMessage('');\n setFiles([]);\n\n // Reset textarea height\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n }, [message, files, onSend]);\n\n // Handle key press\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [handleSend]\n );\n\n // Handle file selection\n const handleFileSelect = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const selectedFiles = Array.from(e.target.files || []);\n\n // Filter valid files\n const validFiles = selectedFiles.filter((file) => {\n if (file.size > maxFileSize) {\n console.warn(`File ${file.name} exceeds maximum size`);\n return false;\n }\n return true;\n });\n\n setFiles((prev) => [...prev, ...validFiles]);\n\n // Reset input\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n },\n [maxFileSize]\n );\n\n // Remove file\n const removeFile = useCallback((index: number) => {\n setFiles((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n return (\n <div className=\"devic-input-area\">\n {disabledMessage && disabled && (\n <div className=\"devic-input-disabled-notice\">\n <WaitingIcon />\n {disabledMessage}\n </div>\n )}\n {files.length > 0 && (\n <div className=\"devic-file-preview\">\n {files.map((file, idx) => (\n <div key={idx} className=\"devic-file-preview-item\">\n <FileIcon />\n <span>{file.name}</span>\n <button\n className=\"devic-file-remove\"\n onClick={() => removeFile(idx)}\n type=\"button\"\n >\n &times;\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"devic-input-wrapper\">\n {enableFileUploads && (\n <>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptedTypes}\n multiple\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n <button\n className=\"devic-input-btn\"\n onClick={() => fileInputRef.current?.click()}\n disabled={disabled}\n type=\"button\"\n title=\"Attach file\"\n >\n <AttachIcon />\n </button>\n </>\n )}\n\n <textarea\n ref={textareaRef}\n className=\"devic-input\"\n value={message}\n onChange={(e) => {\n setMessage(e.target.value);\n handleInput();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n />\n\n {isProcessing ? (\n stopButtonContent ? (\n <div className=\"devic-send-btn-wrapper\">\n <div className=\"devic-send-btn-custom\" aria-hidden=\"true\">\n {stopButtonContent}\n </div>\n <button\n className=\"devic-send-btn-overlay\"\n onClick={onStop}\n type=\"button\"\n title=\"Stop\"\n />\n </div>\n ) : (\n <button\n className=\"devic-input-btn devic-send-btn\"\n onClick={onStop}\n type=\"button\"\n title=\"Stop\"\n >\n <StopIcon />\n </button>\n )\n ) : sendButtonContent ? (\n <div className=\"devic-send-btn-wrapper\">\n <div className=\"devic-send-btn-custom\" aria-hidden=\"true\">\n {sendButtonContent}\n </div>\n <button\n className=\"devic-send-btn-overlay\"\n onClick={handleSend}\n disabled={disabled || (!message.trim() && files.length === 0)}\n type=\"button\"\n title=\"Send message\"\n />\n </div>\n ) : (\n <button\n className=\"devic-input-btn devic-send-btn\"\n onClick={handleSend}\n disabled={disabled || (!message.trim() && files.length === 0)}\n type=\"button\"\n title=\"Send message\"\n >\n <SendIcon />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Get file type category from MIME type\n */\nfunction getFileType(\n mimeType: string\n): 'image' | 'document' | 'audio' | 'video' | 'other' {\n if (mimeType.startsWith('image/')) return 'image';\n if (mimeType.startsWith('audio/')) return 'audio';\n if (mimeType.startsWith('video/')) return 'video';\n if (\n mimeType.startsWith('application/pdf') ||\n mimeType.startsWith('application/msword') ||\n mimeType.startsWith('text/')\n ) {\n return 'document';\n }\n return 'other';\n}\n\n/**\n * Attach icon\n */\nfunction AttachIcon(): 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 <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n );\n}\n\n/**\n * Send icon\n */\nfunction SendIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n );\n}\n\n/**\n * File icon\n */\nfunction FileIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14,2 14,8 20,8\" />\n </svg>\n );\n}\n\n/**\n * Stop icon (square)\n */\nfunction StopIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n </svg>\n );\n}\n\n/**\n * Waiting icon (clock)\n */\nfunction WaitingIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12,6 12,12 16,14\" />\n </svg>\n );\n}\n"],"names":["useState","useRef","useCallback","_jsxs","_jsx"],"mappings":";;;;;AAIA,MAAM,gBAAgB,GAA6B;IACjD,MAAM,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC;AAC9D,IAAA,SAAS,EAAE;QACT,iBAAiB;QACjB,oBAAoB;QACpB,yEAAyE;QACzE,YAAY;QACZ,UAAU;AACX,KAAA;AACD,IAAA,KAAK,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;AAC/C,IAAA,KAAK,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC;CAChD;AAED;;AAEG;SACa,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,mBAAmB,EACjC,iBAAiB,GAAG,KAAK,EACzB,gBAAgB,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EACpD,WAAW,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;AAC9B,iBAAiB,EACjB,eAAe,EACf,YAAY,GAAG,KAAK,EACpB,MAAM,EACN,iBAAiB,GACF,EAAA;IACf,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGA,cAAQ,CAAC,EAAE,CAAC;IAC1C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAGA,cAAQ,CAAS,EAAE,CAAC;AAC9C,IAAA,MAAM,WAAW,GAAGC,YAAM,CAAsB,IAAI,CAAC;AACrD,IAAA,MAAM,YAAY,GAAGA,YAAM,CAAmB,IAAI,CAAC;;AAGnD,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB;SAClD,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,OAAO;AAC/B,SAAA,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE;SAChD,IAAI,CAAC,GAAG,CAAC;;AAGZ,IAAA,MAAM,WAAW,GAAGC,iBAAW,CAAC,MAAK;AACnC,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO;QACpC,IAAI,QAAQ,EAAE;AACZ,YAAA,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;AAC9B,YAAA,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI;QACrE;IACF,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAA,MAAM,UAAU,GAAGA,iBAAW,CAAC,MAAK;AAClC,QAAA,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE;AACrC,QAAA,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE;;QAG3C,MAAM,SAAS,GAAe,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;YACjD,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,SAAA,CAAC,CAAC;AAEH,QAAA,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,SAAS,CAAC;QACpE,UAAU,CAAC,EAAE,CAAC;QACd,QAAQ,CAAC,EAAE,CAAC;;AAGZ,QAAA,IAAI,WAAW,CAAC,OAAO,EAAE;YACvB,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;QAC3C;IACF,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;;AAG5B,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAC/B,CAAC,CAAsB,KAAI;QACzB,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;YACpC,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,UAAU,EAAE;QACd;AACF,IAAA,CAAC,EACD,CAAC,UAAU,CAAC,CACb;;AAGD,IAAA,MAAM,gBAAgB,GAAGA,iBAAW,CAClC,CAAC,CAAsC,KAAI;AACzC,QAAA,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;;QAGtD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;AAC/C,YAAA,IAAI,IAAI,CAAC,IAAI,GAAG,WAAW,EAAE;gBAC3B,OAAO,CAAC,IAAI,CAAC,CAAA,KAAA,EAAQ,IAAI,CAAC,IAAI,CAAA,qBAAA,CAAuB,CAAC;AACtD,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;AAEF,QAAA,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC,CAAC;;AAG5C,QAAA,IAAI,YAAY,CAAC,OAAO,EAAE;AACxB,YAAA,YAAY,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE;QACjC;AACF,IAAA,CAAC,EACD,CAAC,WAAW,CAAC,CACd;;AAGD,IAAA,MAAM,UAAU,GAAGA,iBAAW,CAAC,CAAC,KAAa,KAAI;QAC/C,QAAQ,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC;IACxD,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACEC,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,kBAAkB,EAAA,QAAA,EAAA,CAC9B,eAAe,IAAI,QAAQ,KAC1BA,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6BAA6B,aAC1CC,cAAA,CAAC,WAAW,KAAG,EACd,eAAe,CAAA,EAAA,CACZ,CACP,EACA,KAAK,CAAC,MAAM,GAAG,CAAC,KACfA,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,oBAAoB,YAChC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,MACnBD,eAAA,CAAA,KAAA,EAAA,EAAe,SAAS,EAAC,yBAAyB,aAChDC,cAAA,CAAC,QAAQ,KAAG,EACZA,cAAA,CAAA,MAAA,EAAA,EAAA,QAAA,EAAO,IAAI,CAAC,IAAI,GAAQ,EACxBA,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,mBAAmB,EAC7B,OAAO,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,EAC9B,IAAI,EAAC,QAAQ,uBAGN,CAAA,EAAA,EATD,GAAG,CAUP,CACP,CAAC,GACE,CACP,EAEDD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,EAAA,QAAA,EAAA,CACjC,iBAAiB,KAChBA,kDACEC,cAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAA,IAAA,EACR,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAA,CAC1B,EACFA,2BACE,SAAS,EAAC,iBAAiB,EAC3B,OAAO,EAAE,MAAM,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,EAC5C,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,aAAa,EAAA,QAAA,EAEnBA,eAAC,UAAU,EAAA,EAAA,CAAG,GACP,CAAA,EAAA,CACR,CACJ,EAEDA,cAAA,CAAA,UAAA,EAAA,EACE,GAAG,EAAE,WAAW,EAChB,SAAS,EAAC,aAAa,EACvB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,CAAC,KAAI;AACd,4BAAA,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC1B,4BAAA,WAAW,EAAE;wBACf,CAAC,EACD,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,CAAC,GACP,EAED,YAAY,IACX,iBAAiB,IACfD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wBAAwB,aACrCC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uBAAuB,EAAA,aAAA,EAAa,MAAM,EAAA,QAAA,EACtD,iBAAiB,GACd,EACNA,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,wBAAwB,EAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,MAAM,EAAA,CACZ,IACE,KAENA,2BACE,SAAS,EAAC,gCAAgC,EAC1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,MAAM,YAEZA,cAAA,CAAC,QAAQ,KAAG,EAAA,CACL,CACV,IACC,iBAAiB,IACnBD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wBAAwB,aACrCC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uBAAuB,EAAA,aAAA,EAAa,MAAM,EAAA,QAAA,EACtD,iBAAiB,GACd,EACNA,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,wBAAwB,EAClC,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,QAAQ,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAC7D,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,cAAc,EAAA,CACpB,CAAA,EAAA,CACE,KAENA,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,gCAAgC,EAC1C,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,QAAQ,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAC7D,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,cAAc,EAAA,QAAA,EAEpBA,eAAC,QAAQ,EAAA,EAAA,CAAG,GACL,CACV,CAAA,EAAA,CACG,CAAA,EAAA,CACF;AAEV;AAEA;;AAEG;AACH,SAAS,WAAW,CAClB,QAAgB,EAAA;AAEhB,IAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,OAAO;AACjD,IAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,OAAO;AACjD,IAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,OAAO;AACjD,IAAA,IACE,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC;AACtC,QAAA,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;AACzC,QAAA,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAC5B;AACA,QAAA,OAAO,UAAU;IACnB;AACA,IAAA,OAAO,OAAO;AAChB;AAEA;;AAEG;AACH,SAAS,UAAU,GAAA;AACjB,IAAA,QACEA,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAEtBA,yBAAM,CAAC,EAAC,mHAAmH,EAAA,CAAG,EAAA,CAC1H;AAEV;AAEA;;AAEG;AACH,SAAS,QAAQ,GAAA;IACf,QACEA,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,cAAc,EAAA,QAAA,EAEnBA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,uCAAuC,EAAA,CAAG,EAAA,CAC9C;AAEV;AAEA;;AAEG;AACH,SAAS,QAAQ,GAAA;IACf,QACED,yBACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBC,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,4DAA4D,EAAA,CAAG,EACvEA,cAAA,CAAA,UAAA,EAAA,EAAU,MAAM,EAAC,gBAAgB,EAAA,CAAG,CAAA,EAAA,CAChC;AAEV;AAEA;;AAEG;AACH,SAAS,QAAQ,GAAA;AACf,IAAA,QACEA,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,cAAc,YAEnBA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,GAAG,EAAC,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAA,CAAG,EAAA,CAC9C;AAEV;AAEA;;AAEG;AACH,SAAS,WAAW,GAAA;IAClB,QACED,eAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EAAA,QAAA,EAAA,CAEtBC,cAAA,CAAA,QAAA,EAAA,EAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAA,CAAG,EACjCA,cAAA,CAAA,UAAA,EAAA,EAAU,MAAM,EAAC,kBAAkB,EAAA,CAAG,CAAA,EAAA,CAClC;AAEV;;;;"}
1
+ {"version":3,"file":"ChatInput.js","sources":["../../../../../src/components/ChatDrawer/ChatInput.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport type { ChatInputProps } from './ChatDrawer.types';\n\nconst FILE_TYPE_ACCEPT: Record<string, string[]> = {\n images: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],\n documents: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'text/plain',\n 'text/csv',\n ],\n audio: ['audio/mpeg', 'audio/wav', 'audio/ogg'],\n video: ['video/mp4', 'video/webm', 'video/ogg'],\n};\n\n/**\n * Chat input component with file upload support\n */\nexport function ChatInput({\n onSend,\n disabled = false,\n placeholder = 'Type a message...',\n enableFileUploads = false,\n allowedFileTypes = { images: true, documents: true },\n maxFileSize = 10 * 1024 * 1024, // 10MB\n sendButtonContent,\n disabledMessage,\n isProcessing = false,\n onStop,\n stopButtonContent,\n}: ChatInputProps): JSX.Element {\n const [message, setMessage] = useState('');\n const [files, setFiles] = useState<File[]>([]);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // Calculate accepted file types\n const acceptedTypes = Object.entries(allowedFileTypes)\n .filter(([, enabled]) => enabled)\n .flatMap(([type]) => FILE_TYPE_ACCEPT[type] || [])\n .join(',');\n\n // Auto-resize textarea\n const handleInput = useCallback(() => {\n const textarea = textareaRef.current;\n if (textarea) {\n textarea.style.height = 'auto';\n textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;\n }\n }, []);\n\n // Handle send\n const handleSend = useCallback(() => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage && files.length === 0) return;\n\n onSend(trimmedMessage, files.length > 0 ? files : undefined);\n setMessage('');\n setFiles([]);\n\n // Reset textarea height\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n }, [message, files, onSend]);\n\n // Handle key press\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [handleSend]\n );\n\n // Handle file selection\n const handleFileSelect = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const selectedFiles = Array.from(e.target.files || []);\n\n // Filter valid files\n const validFiles = selectedFiles.filter((file) => {\n if (file.size > maxFileSize) {\n console.warn(`File ${file.name} exceeds maximum size`);\n return false;\n }\n return true;\n });\n\n setFiles((prev) => [...prev, ...validFiles]);\n\n // Reset input\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n },\n [maxFileSize]\n );\n\n // Remove file\n const removeFile = useCallback((index: number) => {\n setFiles((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n return (\n <div className=\"devic-input-area\">\n {disabledMessage && disabled && (\n <div className=\"devic-input-disabled-notice\">\n <WaitingIcon />\n {disabledMessage}\n </div>\n )}\n {files.length > 0 && (\n <div className=\"devic-file-preview\">\n {files.map((file, idx) => (\n <div key={idx} className=\"devic-file-preview-item\">\n <FileIcon />\n <span>{file.name}</span>\n <button\n className=\"devic-file-remove\"\n onClick={() => removeFile(idx)}\n type=\"button\"\n >\n &times;\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"devic-input-wrapper\">\n {enableFileUploads && (\n <>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptedTypes}\n multiple\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n <button\n className=\"devic-input-btn\"\n onClick={() => fileInputRef.current?.click()}\n disabled={disabled}\n type=\"button\"\n title=\"Attach file\"\n >\n <AttachIcon />\n </button>\n </>\n )}\n\n <textarea\n ref={textareaRef}\n className=\"devic-input\"\n value={message}\n onChange={(e) => {\n setMessage(e.target.value);\n handleInput();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n />\n\n {isProcessing ? (\n stopButtonContent ? (\n <div className=\"devic-send-btn-wrapper\">\n <div className=\"devic-send-btn-custom\" aria-hidden=\"true\">\n {stopButtonContent}\n </div>\n <button\n className=\"devic-send-btn-overlay\"\n onClick={onStop}\n type=\"button\"\n title=\"Stop\"\n />\n </div>\n ) : (\n <button\n className=\"devic-input-btn devic-stop-btn\"\n onClick={onStop}\n type=\"button\"\n title=\"Stop\"\n >\n <StopIcon />\n </button>\n )\n ) : sendButtonContent ? (\n <div className=\"devic-send-btn-wrapper\">\n <div className=\"devic-send-btn-custom\" aria-hidden=\"true\">\n {sendButtonContent}\n </div>\n <button\n className=\"devic-send-btn-overlay\"\n onClick={handleSend}\n disabled={disabled || (!message.trim() && files.length === 0)}\n type=\"button\"\n title=\"Send message\"\n />\n </div>\n ) : (\n <button\n className=\"devic-input-btn devic-send-btn\"\n onClick={handleSend}\n disabled={disabled || (!message.trim() && files.length === 0)}\n type=\"button\"\n title=\"Send message\"\n >\n <SendIcon />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Attach icon\n */\nfunction AttachIcon(): 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 <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n );\n}\n\n/**\n * Send icon\n */\nfunction SendIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n );\n}\n\n/**\n * File icon\n */\nfunction FileIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14,2 14,8 20,8\" />\n </svg>\n );\n}\n\n/**\n * Stop icon (square)\n */\nfunction StopIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n </svg>\n );\n}\n\n/**\n * Waiting icon (clock)\n */\nfunction WaitingIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12,6 12,12 16,14\" />\n </svg>\n );\n}\n"],"names":["useState","useRef","useCallback","_jsxs","_jsx"],"mappings":"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"}
@@ -5,6 +5,7 @@ var React = require('react');
5
5
  var DevicContext = require('../../provider/DevicContext.js');
6
6
  var client = require('../../api/client.js');
7
7
 
8
+ const PAGE_SIZE = 10;
8
9
  function ConversationSelector({ assistantId, currentChatUid, onSelect, onNewChat, apiKey: propsApiKey, baseUrl: propsBaseUrl, tenantId: propsTenantId, }) {
9
10
  const context = DevicContext.useOptionalDevicContext();
10
11
  const apiKey = propsApiKey || context?.apiKey;
@@ -14,7 +15,10 @@ function ConversationSelector({ assistantId, currentChatUid, onSelect, onNewChat
14
15
  const [conversations, setConversations] = React.useState([]);
15
16
  const [search, setSearch] = React.useState('');
16
17
  const [loading, setLoading] = React.useState(false);
18
+ const [loadingMore, setLoadingMore] = React.useState(false);
19
+ const [hasMore, setHasMore] = React.useState(true);
17
20
  const dropdownRef = React.useRef(null);
21
+ const listRef = React.useRef(null);
18
22
  const clientRef = React.useRef(null);
19
23
  if (!clientRef.current && apiKey) {
20
24
  clientRef.current = new client.DevicApiClient({ apiKey, baseUrl });
@@ -28,26 +32,48 @@ function ConversationSelector({ assistantId, currentChatUid, onSelect, onNewChat
28
32
  clientRef.current = new client.DevicApiClient({ apiKey, baseUrl });
29
33
  }
30
34
  }, [apiKey, baseUrl]);
31
- const fetchConversations = React.useCallback(async () => {
35
+ const fetchConversations = React.useCallback(async (offset = 0, append = false) => {
32
36
  if (!clientRef.current)
33
37
  return;
34
- setLoading(true);
38
+ if (offset === 0) {
39
+ setLoading(true);
40
+ }
41
+ else {
42
+ setLoadingMore(true);
43
+ }
35
44
  try {
36
- const list = await clientRef.current.listConversations(assistantId, { tenantId });
37
- setConversations(list);
45
+ const response = await clientRef.current.listConversations(assistantId, {
46
+ tenantId,
47
+ offset,
48
+ limit: PAGE_SIZE,
49
+ });
50
+ setConversations((prev) => append ? [...prev, ...response.histories] : response.histories);
51
+ setHasMore(offset + response.histories.length < response.total);
38
52
  }
39
53
  catch {
40
54
  // silently fail
41
55
  }
42
56
  finally {
43
57
  setLoading(false);
58
+ setLoadingMore(false);
44
59
  }
45
60
  }, [assistantId, tenantId]);
46
61
  React.useEffect(() => {
47
62
  if (isOpen) {
48
- fetchConversations();
63
+ fetchConversations(0);
49
64
  }
50
65
  }, [isOpen, fetchConversations]);
66
+ // Fetch conversations when currentChatUid changes so the selector label is correct
67
+ React.useEffect(() => {
68
+ if (currentChatUid && conversations.length === 0) {
69
+ fetchConversations(0);
70
+ }
71
+ }, [currentChatUid, conversations.length, fetchConversations]);
72
+ const handleLoadMore = React.useCallback(() => {
73
+ if (!loadingMore && hasMore) {
74
+ fetchConversations(conversations.length, true);
75
+ }
76
+ }, [loadingMore, hasMore, conversations.length, fetchConversations]);
51
77
  // Close on outside click
52
78
  React.useEffect(() => {
53
79
  if (!isOpen)
@@ -65,11 +91,11 @@ function ConversationSelector({ assistantId, currentChatUid, onSelect, onNewChat
65
91
  ? currentConv.name || formatDate(currentConv.creationTimestampMs)
66
92
  : 'New chat';
67
93
  const filtered = conversations.filter((c) => !search || (c.name || '').toLowerCase().includes(search.toLowerCase()));
68
- return (jsxRuntime.jsxs("div", { className: "devic-conversation-selector", ref: dropdownRef, children: [jsxRuntime.jsxs("button", { className: "devic-conversation-selector-trigger", onClick: () => setIsOpen(!isOpen), type: "button", children: [jsxRuntime.jsx("span", { className: "devic-conversation-selector-label", children: currentName }), jsxRuntime.jsx(ChevronIcon, { open: isOpen })] }), isOpen && (jsxRuntime.jsxs("div", { className: "devic-conversation-dropdown", children: [jsxRuntime.jsx("div", { className: "devic-conversation-search-wrapper", children: jsxRuntime.jsx("input", { className: "devic-conversation-search", type: "text", placeholder: "Search conversations...", value: search, onChange: (e) => setSearch(e.target.value), autoFocus: true }) }), jsxRuntime.jsxs("div", { className: "devic-conversation-list", children: [loading && (jsxRuntime.jsx("div", { className: "devic-conversation-loading", children: "Loading..." })), !loading && filtered.length === 0 && (jsxRuntime.jsx("div", { className: "devic-conversation-empty", children: "No conversations" })), !loading &&
94
+ return (jsxRuntime.jsxs("div", { className: "devic-conversation-selector", ref: dropdownRef, children: [jsxRuntime.jsxs("button", { className: "devic-conversation-selector-trigger", onClick: () => setIsOpen(!isOpen), type: "button", children: [jsxRuntime.jsx("span", { className: "devic-conversation-selector-label", children: currentName }), jsxRuntime.jsx(ChevronIcon, { open: isOpen })] }), isOpen && (jsxRuntime.jsxs("div", { className: "devic-conversation-dropdown", children: [jsxRuntime.jsx("div", { className: "devic-conversation-search-wrapper", children: jsxRuntime.jsx("input", { className: "devic-conversation-search", type: "text", placeholder: "Search conversations...", value: search, onChange: (e) => setSearch(e.target.value), autoFocus: true }) }), jsxRuntime.jsxs("div", { className: "devic-conversation-list", ref: listRef, children: [loading && (jsxRuntime.jsx("div", { className: "devic-conversation-loading", children: "Loading..." })), !loading && filtered.length === 0 && (jsxRuntime.jsx("div", { className: "devic-conversation-empty", children: "No conversations" })), !loading &&
69
95
  filtered.map((conv) => (jsxRuntime.jsxs("button", { className: "devic-conversation-item", "data-active": conv.chatUID === currentChatUid, type: "button", onClick: () => {
70
96
  onSelect(conv.chatUID);
71
97
  setIsOpen(false);
72
- }, children: [conv.chatUID === currentChatUid && (jsxRuntime.jsx("span", { className: "devic-conversation-item-check", children: jsxRuntime.jsx(CheckIcon, {}) })), jsxRuntime.jsx("span", { className: "devic-conversation-item-name", children: conv.name || formatDate(conv.creationTimestampMs) }), jsxRuntime.jsx("span", { className: "devic-conversation-item-date", children: formatDate(conv.lastEditTimestampMs || conv.creationTimestampMs) })] }, conv.chatUID)))] }), jsxRuntime.jsx("button", { className: "devic-conversation-new", type: "button", onClick: () => {
98
+ }, children: [conv.chatUID === currentChatUid && (jsxRuntime.jsx("span", { className: "devic-conversation-item-check", children: jsxRuntime.jsx(CheckIcon, {}) })), jsxRuntime.jsx("span", { className: "devic-conversation-item-name", children: conv.name || formatDate(conv.creationTimestampMs) }), jsxRuntime.jsx("span", { className: "devic-conversation-item-date", children: formatDate(conv.lastEditTimestampMs || conv.creationTimestampMs) })] }, conv.chatUID))), loadingMore && (jsxRuntime.jsx("div", { className: "devic-conversation-loading", children: "Loading more..." })), !loadingMore && hasMore && !loading && (jsxRuntime.jsx("button", { className: "devic-conversation-load-more", type: "button", onClick: handleLoadMore, children: "Load more" }))] }), jsxRuntime.jsx("button", { className: "devic-conversation-new", type: "button", onClick: () => {
73
99
  onNewChat();
74
100
  setIsOpen(false);
75
101
  }, children: "+ Start a new chat" })] }))] }));