@devicai/ui 0.1.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.
Files changed (70) hide show
  1. package/README.md +363 -0
  2. package/dist/cjs/api/client.js +118 -0
  3. package/dist/cjs/api/client.js.map +1 -0
  4. package/dist/cjs/components/ChatDrawer/ChatDrawer.js +122 -0
  5. package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -0
  6. package/dist/cjs/components/ChatDrawer/ChatInput.js +128 -0
  7. package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -0
  8. package/dist/cjs/components/ChatDrawer/ChatMessages.js +56 -0
  9. package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -0
  10. package/dist/cjs/components/ChatDrawer/ToolTimeline.js +26 -0
  11. package/dist/cjs/components/ChatDrawer/ToolTimeline.js.map +1 -0
  12. package/dist/cjs/hooks/useDevicChat.js +258 -0
  13. package/dist/cjs/hooks/useDevicChat.js.map +1 -0
  14. package/dist/cjs/hooks/useModelInterface.js +130 -0
  15. package/dist/cjs/hooks/useModelInterface.js.map +1 -0
  16. package/dist/cjs/hooks/usePolling.js +109 -0
  17. package/dist/cjs/hooks/usePolling.js.map +1 -0
  18. package/dist/cjs/index.js +36 -0
  19. package/dist/cjs/index.js.map +1 -0
  20. package/dist/cjs/provider/DevicContext.js +32 -0
  21. package/dist/cjs/provider/DevicContext.js.map +1 -0
  22. package/dist/cjs/provider/DevicProvider.js +43 -0
  23. package/dist/cjs/provider/DevicProvider.js.map +1 -0
  24. package/dist/cjs/styles.css +1 -0
  25. package/dist/cjs/utils/index.js +117 -0
  26. package/dist/cjs/utils/index.js.map +1 -0
  27. package/dist/esm/api/client.d.ts +56 -0
  28. package/dist/esm/api/client.js +115 -0
  29. package/dist/esm/api/client.js.map +1 -0
  30. package/dist/esm/api/types.d.ts +184 -0
  31. package/dist/esm/components/ChatDrawer/ChatDrawer.d.ts +27 -0
  32. package/dist/esm/components/ChatDrawer/ChatDrawer.js +120 -0
  33. package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -0
  34. package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +197 -0
  35. package/dist/esm/components/ChatDrawer/ChatInput.d.ts +5 -0
  36. package/dist/esm/components/ChatDrawer/ChatInput.js +126 -0
  37. package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -0
  38. package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +5 -0
  39. package/dist/esm/components/ChatDrawer/ChatMessages.js +54 -0
  40. package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -0
  41. package/dist/esm/components/ChatDrawer/ToolTimeline.d.ts +5 -0
  42. package/dist/esm/components/ChatDrawer/ToolTimeline.js +24 -0
  43. package/dist/esm/components/ChatDrawer/ToolTimeline.js.map +1 -0
  44. package/dist/esm/components/ChatDrawer/index.d.ts +5 -0
  45. package/dist/esm/hooks/index.d.ts +6 -0
  46. package/dist/esm/hooks/useDevicChat.d.ts +120 -0
  47. package/dist/esm/hooks/useDevicChat.js +256 -0
  48. package/dist/esm/hooks/useDevicChat.js.map +1 -0
  49. package/dist/esm/hooks/useModelInterface.d.ts +68 -0
  50. package/dist/esm/hooks/useModelInterface.js +128 -0
  51. package/dist/esm/hooks/useModelInterface.js.map +1 -0
  52. package/dist/esm/hooks/usePolling.d.ts +64 -0
  53. package/dist/esm/hooks/usePolling.js +107 -0
  54. package/dist/esm/hooks/usePolling.js.map +1 -0
  55. package/dist/esm/index.d.ts +10 -0
  56. package/dist/esm/index.js +12 -0
  57. package/dist/esm/index.js.map +1 -0
  58. package/dist/esm/provider/DevicContext.d.ts +15 -0
  59. package/dist/esm/provider/DevicContext.js +28 -0
  60. package/dist/esm/provider/DevicContext.js.map +1 -0
  61. package/dist/esm/provider/DevicProvider.d.ts +17 -0
  62. package/dist/esm/provider/DevicProvider.js +41 -0
  63. package/dist/esm/provider/DevicProvider.js.map +1 -0
  64. package/dist/esm/provider/index.d.ts +3 -0
  65. package/dist/esm/provider/types.d.ts +58 -0
  66. package/dist/esm/styles.css +1 -0
  67. package/dist/esm/utils/index.d.ts +32 -0
  68. package/dist/esm/utils/index.js +109 -0
  69. package/dist/esm/utils/index.js.map +1 -0
  70. package/package.json +68 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Devic API client using native fetch
3
+ */
4
+ class DevicApiClient {
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ /**
9
+ * Update client configuration
10
+ */
11
+ setConfig(config) {
12
+ this.config = { ...this.config, ...config };
13
+ }
14
+ /**
15
+ * Make an authenticated request to the API
16
+ */
17
+ async request(endpoint, options = {}) {
18
+ const url = `${this.config.baseUrl}${endpoint}`;
19
+ const headers = {
20
+ 'Content-Type': 'application/json',
21
+ 'Authorization': `Bearer ${this.config.apiKey}`,
22
+ ...options.headers,
23
+ };
24
+ const response = await fetch(url, {
25
+ ...options,
26
+ headers,
27
+ });
28
+ if (!response.ok) {
29
+ let errorData;
30
+ try {
31
+ errorData = await response.json();
32
+ }
33
+ catch {
34
+ errorData = {
35
+ statusCode: response.status,
36
+ message: response.statusText,
37
+ };
38
+ }
39
+ throw new DevicApiError(errorData);
40
+ }
41
+ // Handle responses that may have a wrapper structure
42
+ const data = await response.json();
43
+ // If the response has a data property, extract it (common wrapper pattern)
44
+ if (data && typeof data === 'object' && 'data' in data) {
45
+ return data.data;
46
+ }
47
+ return data;
48
+ }
49
+ /**
50
+ * Get all assistant specializations
51
+ */
52
+ async getAssistants(external = false) {
53
+ const query = external ? '?external=true' : '';
54
+ return this.request(`/api/v1/assistants${query}`);
55
+ }
56
+ /**
57
+ * Get a specific assistant specialization
58
+ */
59
+ async getAssistant(identifier) {
60
+ return this.request(`/api/v1/assistants/${identifier}`);
61
+ }
62
+ /**
63
+ * Send a message to an assistant (sync mode)
64
+ */
65
+ async sendMessage(assistantId, dto) {
66
+ return this.request(`/api/v1/assistants/${assistantId}/messages`, {
67
+ method: 'POST',
68
+ body: JSON.stringify(dto),
69
+ });
70
+ }
71
+ /**
72
+ * Send a message to an assistant (async mode)
73
+ */
74
+ async sendMessageAsync(assistantId, dto) {
75
+ return this.request(`/api/v1/assistants/${assistantId}/messages?async=true`, {
76
+ method: 'POST',
77
+ body: JSON.stringify(dto),
78
+ });
79
+ }
80
+ /**
81
+ * Get real-time chat history (for polling in async mode)
82
+ */
83
+ async getRealtimeHistory(assistantId, chatUid) {
84
+ return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/realtime`);
85
+ }
86
+ /**
87
+ * Get chat history for a specific conversation
88
+ */
89
+ async getChatHistory(assistantId, chatUid) {
90
+ return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}`);
91
+ }
92
+ /**
93
+ * Send tool call responses back to the assistant
94
+ */
95
+ async sendToolResponses(assistantId, chatUid, responses) {
96
+ return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`, {
97
+ method: 'POST',
98
+ body: JSON.stringify({ responses }),
99
+ });
100
+ }
101
+ }
102
+ /**
103
+ * Custom error class for API errors
104
+ */
105
+ class DevicApiError extends Error {
106
+ constructor(error) {
107
+ super(error.message);
108
+ this.name = 'DevicApiError';
109
+ this.statusCode = error.statusCode;
110
+ this.errorType = error.error;
111
+ }
112
+ }
113
+
114
+ export { DevicApiClient, DevicApiError };
115
+ //# sourceMappingURL=client.js.map
@@ -0,0 +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} 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 ...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[]>(`/api/v1/assistants${query}`);\n }\n\n /**\n * Get a specific assistant specialization\n */\n async getAssistant(identifier: string): Promise<AssistantSpecialization> {\n return this.request<AssistantSpecialization>(`/api/v1/assistants/${identifier}`);\n }\n\n /**\n * Send a message to an assistant (sync mode)\n */\n async sendMessage(\n assistantId: string,\n dto: ProcessMessageDto\n ): Promise<ChatMessage[]> {\n return this.request<ChatMessage[]>(\n `/api/v1/assistants/${assistantId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify(dto),\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`,\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 ): Promise<ChatHistory> {\n return this.request<ChatHistory>(\n `/api/v1/assistants/${assistantId}/chats/${chatUid}`\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/**\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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"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * File attachment for messages
3
+ */
4
+ export interface ChatFile {
5
+ name: string;
6
+ downloadUrl?: string;
7
+ fileType?: 'image' | 'document' | 'audio' | 'video' | 'other';
8
+ }
9
+ /**
10
+ * Message content structure
11
+ */
12
+ export interface MessageContent {
13
+ message?: string;
14
+ data?: any;
15
+ files?: Array<{
16
+ name: string;
17
+ url: string;
18
+ type: string;
19
+ }>;
20
+ }
21
+ /**
22
+ * Tool call from the model
23
+ */
24
+ export interface ToolCall {
25
+ id: string;
26
+ type: 'function';
27
+ function: {
28
+ name: string;
29
+ arguments: string;
30
+ };
31
+ }
32
+ /**
33
+ * Chat message structure
34
+ */
35
+ export interface ChatMessage {
36
+ uid: string;
37
+ role: 'user' | 'assistant' | 'developer' | 'tool';
38
+ content: MessageContent;
39
+ timestamp: number;
40
+ chatUid?: string;
41
+ tool_calls?: ToolCall[];
42
+ tool_call_id?: string;
43
+ summary?: string;
44
+ }
45
+ /**
46
+ * Previous conversation message for initialization
47
+ */
48
+ export interface PreviousMessage {
49
+ message: string;
50
+ role: 'user' | 'assistant';
51
+ }
52
+ /**
53
+ * Model interface tool schema following OpenAI function calling format
54
+ */
55
+ export interface ModelInterfaceToolSchema {
56
+ type: 'function';
57
+ function: {
58
+ name: string;
59
+ description: string;
60
+ parameters: {
61
+ type: 'object';
62
+ properties: Record<string, any>;
63
+ required?: string[];
64
+ };
65
+ };
66
+ }
67
+ /**
68
+ * Model interface tool definition for client-side tools
69
+ */
70
+ export interface ModelInterfaceTool {
71
+ toolName: string;
72
+ schema: ModelInterfaceToolSchema;
73
+ callback: (params: any) => Promise<any> | any;
74
+ }
75
+ /**
76
+ * Tool call response to send back to the API
77
+ */
78
+ export interface ToolCallResponse {
79
+ tool_call_id: string;
80
+ content: any;
81
+ role: 'tool';
82
+ }
83
+ /**
84
+ * DTO for sending messages to the assistant
85
+ */
86
+ export interface ProcessMessageDto {
87
+ message: string;
88
+ chatUid?: string;
89
+ userName?: string;
90
+ files?: ChatFile[];
91
+ metadata?: {
92
+ promptTemplateParams?: Record<string, any>;
93
+ tenantToken?: string;
94
+ [key: string]: any;
95
+ };
96
+ tenantId?: string;
97
+ previousConversation?: PreviousMessage[];
98
+ enabledTools?: string[];
99
+ provider?: string;
100
+ model?: string;
101
+ tools?: ModelInterfaceToolSchema[];
102
+ applicationState?: Record<string, any>;
103
+ }
104
+ /**
105
+ * Response from the assistant
106
+ */
107
+ export interface AssistantResponse {
108
+ messages: ChatMessage[];
109
+ chatUid: string;
110
+ inputTokens?: number;
111
+ outputTokens?: number;
112
+ }
113
+ /**
114
+ * Async mode response
115
+ */
116
+ export interface AsyncResponse {
117
+ chatUid: string;
118
+ message?: string;
119
+ error?: string;
120
+ }
121
+ /**
122
+ * Real-time chat history status
123
+ */
124
+ export type RealtimeStatus = 'processing' | 'completed' | 'error' | 'waiting_for_tool_response';
125
+ /**
126
+ * Real-time chat history response
127
+ */
128
+ export interface RealtimeChatHistory {
129
+ chatUID: string;
130
+ clientUID: string;
131
+ chatHistory: ChatMessage[];
132
+ status: RealtimeStatus;
133
+ lastUpdatedAt: number;
134
+ pendingToolCalls?: ToolCall[];
135
+ }
136
+ /**
137
+ * Chat history structure
138
+ */
139
+ export interface ChatHistory {
140
+ chatUID: string;
141
+ clientUID: string;
142
+ userUID: string;
143
+ chatContent: ChatMessage[];
144
+ name?: string;
145
+ assistantSpecializationIdentifier: string;
146
+ creationTimestampMs: number;
147
+ lastEditTimestampMs?: number;
148
+ llm?: string;
149
+ inputTokens?: number;
150
+ outputTokens?: number;
151
+ metadata?: Record<string, any>;
152
+ tenantId?: string;
153
+ }
154
+ /**
155
+ * Assistant specialization info
156
+ */
157
+ export interface AssistantSpecialization {
158
+ identifier: string;
159
+ name: string;
160
+ description: string;
161
+ state: 'active' | 'inactive' | 'coming_soon';
162
+ imgUrl?: string;
163
+ availableToolsGroups?: Array<{
164
+ name: string;
165
+ description?: string;
166
+ uid?: string;
167
+ iconUrl?: string;
168
+ tools?: Array<{
169
+ name: string;
170
+ description: string;
171
+ }>;
172
+ }>;
173
+ model?: string;
174
+ isCustom?: boolean;
175
+ creationTimestampMs?: number;
176
+ }
177
+ /**
178
+ * API error response
179
+ */
180
+ export interface ApiError {
181
+ statusCode: number;
182
+ message: string;
183
+ error?: string;
184
+ }
@@ -0,0 +1,27 @@
1
+ import type { ChatDrawerProps } from './ChatDrawer.types';
2
+ import './styles.css';
3
+ /**
4
+ * Chat drawer component for Devic assistants
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * <ChatDrawer
9
+ * assistantId="my-assistant"
10
+ * options={{
11
+ * position: 'right',
12
+ * width: 400,
13
+ * welcomeMessage: 'Hello! How can I help you?',
14
+ * suggestedMessages: ['Help me with...', 'Tell me about...'],
15
+ * }}
16
+ * modelInterfaceTools={[
17
+ * {
18
+ * toolName: 'get_user_location',
19
+ * schema: { ... },
20
+ * callback: async () => ({ lat: 40.7, lng: -74.0 })
21
+ * }
22
+ * ]}
23
+ * onMessageReceived={(msg) => console.log('Received:', msg)}
24
+ * />
25
+ * ```
26
+ */
27
+ export declare function ChatDrawer({ assistantId, chatUid: initialChatUid, options, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onOpen, onClose, isOpen: controlledIsOpen, className, }: ChatDrawerProps): JSX.Element;
@@ -0,0 +1,120 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useMemo, useState, useCallback, useEffect } from 'react';
3
+ import { useDevicChat } from '../../hooks/useDevicChat.js';
4
+ import { ChatMessages } from './ChatMessages.js';
5
+ import { ChatInput } from './ChatInput.js';
6
+
7
+ const DEFAULT_OPTIONS = {
8
+ position: 'right',
9
+ width: 400,
10
+ defaultOpen: false,
11
+ color: '#1890ff',
12
+ welcomeMessage: '',
13
+ suggestedMessages: [],
14
+ enableFileUploads: false,
15
+ allowedFileTypes: { images: true, documents: true },
16
+ maxFileSize: 10 * 1024 * 1024,
17
+ inputPlaceholder: 'Type a message...',
18
+ title: 'Chat',
19
+ showToolTimeline: true,
20
+ zIndex: 1000,
21
+ };
22
+ /**
23
+ * Chat drawer component for Devic assistants
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <ChatDrawer
28
+ * assistantId="my-assistant"
29
+ * options={{
30
+ * position: 'right',
31
+ * width: 400,
32
+ * welcomeMessage: 'Hello! How can I help you?',
33
+ * suggestedMessages: ['Help me with...', 'Tell me about...'],
34
+ * }}
35
+ * modelInterfaceTools={[
36
+ * {
37
+ * toolName: 'get_user_location',
38
+ * schema: { ... },
39
+ * callback: async () => ({ lat: 40.7, lng: -74.0 })
40
+ * }
41
+ * ]}
42
+ * onMessageReceived={(msg) => console.log('Received:', msg)}
43
+ * />
44
+ * ```
45
+ */
46
+ function ChatDrawer({ assistantId, chatUid: initialChatUid, options = {}, enabledTools, modelInterfaceTools, tenantId, tenantMetadata, apiKey, baseUrl, onMessageSent, onMessageReceived, onToolCall, onError, onChatCreated, onOpen, onClose, isOpen: controlledIsOpen, className, }) {
47
+ // Merge options with defaults
48
+ const mergedOptions = useMemo(() => ({ ...DEFAULT_OPTIONS, ...options }), [options]);
49
+ // Drawer open state (can be controlled or uncontrolled)
50
+ const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);
51
+ const isOpen = controlledIsOpen ?? internalIsOpen;
52
+ // Use chat hook
53
+ const chat = useDevicChat({
54
+ assistantId,
55
+ chatUid: initialChatUid,
56
+ apiKey,
57
+ baseUrl,
58
+ tenantId,
59
+ tenantMetadata,
60
+ enabledTools,
61
+ modelInterfaceTools,
62
+ onMessageSent,
63
+ onMessageReceived,
64
+ onToolCall,
65
+ onError,
66
+ onChatCreated,
67
+ });
68
+ // Handle open/close
69
+ const handleOpen = useCallback(() => {
70
+ setInternalIsOpen(true);
71
+ onOpen?.();
72
+ }, [onOpen]);
73
+ const handleClose = useCallback(() => {
74
+ setInternalIsOpen(false);
75
+ onClose?.();
76
+ }, [onClose]);
77
+ // Handle send message
78
+ const handleSend = useCallback((message, files) => {
79
+ chat.sendMessage(message, { files });
80
+ }, [chat]);
81
+ // Handle suggested message click
82
+ const handleSuggestedClick = useCallback((message) => {
83
+ chat.sendMessage(message);
84
+ }, [chat]);
85
+ // Apply CSS variable for primary color
86
+ useEffect(() => {
87
+ if (mergedOptions.color !== DEFAULT_OPTIONS.color) {
88
+ document.documentElement.style.setProperty('--devic-primary', mergedOptions.color);
89
+ }
90
+ }, [mergedOptions.color]);
91
+ // Build style object
92
+ const drawerStyle = useMemo(() => ({
93
+ width: mergedOptions.width,
94
+ zIndex: mergedOptions.zIndex,
95
+ }), [mergedOptions.width, mergedOptions.zIndex]);
96
+ const overlayStyle = useMemo(() => ({
97
+ zIndex: mergedOptions.zIndex - 1,
98
+ }), [mergedOptions.zIndex]);
99
+ const triggerStyle = useMemo(() => ({
100
+ zIndex: mergedOptions.zIndex - 1,
101
+ [mergedOptions.position]: 20,
102
+ bottom: 20,
103
+ }), [mergedOptions.zIndex, mergedOptions.position]);
104
+ return (jsxs(Fragment, { children: [jsx("div", { className: "devic-drawer-overlay", "data-open": isOpen, style: overlayStyle, onClick: handleClose }), jsxs("div", { className: `devic-chat-drawer ${className || ''}`, "data-position": mergedOptions.position, "data-open": isOpen, style: drawerStyle, children: [jsxs("div", { className: "devic-drawer-header", children: [jsx("h2", { className: "devic-drawer-title", children: mergedOptions.title }), jsx("button", { className: "devic-drawer-close", onClick: handleClose, type: "button", "aria-label": "Close chat", children: jsx(CloseIcon, {}) })] }), chat.error && (jsx("div", { className: "devic-error", children: chat.error.message })), jsx(ChatMessages, { messages: chat.messages, isLoading: chat.isLoading, welcomeMessage: mergedOptions.welcomeMessage, suggestedMessages: mergedOptions.suggestedMessages, onSuggestedClick: handleSuggestedClick, showToolTimeline: mergedOptions.showToolTimeline }), jsx(ChatInput, { onSend: handleSend, disabled: chat.isLoading, placeholder: mergedOptions.inputPlaceholder, enableFileUploads: mergedOptions.enableFileUploads, allowedFileTypes: mergedOptions.allowedFileTypes, maxFileSize: mergedOptions.maxFileSize })] }), !isOpen && (jsx("button", { className: "devic-trigger", onClick: handleOpen, style: triggerStyle, type: "button", "aria-label": "Open chat", children: jsx(ChatIcon, {}) }))] }));
105
+ }
106
+ /**
107
+ * Close icon
108
+ */
109
+ function CloseIcon() {
110
+ return (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
111
+ }
112
+ /**
113
+ * Chat icon for trigger button
114
+ */
115
+ function ChatIcon() {
116
+ return (jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("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" }) }));
117
+ }
118
+
119
+ export { ChatDrawer };
120
+ //# sourceMappingURL=ChatDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatDrawer.js","sources":["../../../../src/components/ChatDrawer/ChatDrawer.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useDevicChat } from '../../hooks/useDevicChat';\nimport { ChatMessages } from './ChatMessages';\nimport { ChatInput } from './ChatInput';\nimport type { ChatDrawerProps, ChatDrawerOptions } from './ChatDrawer.types';\nimport './styles.css';\n\nconst DEFAULT_OPTIONS: Required<ChatDrawerOptions> = {\n position: 'right',\n width: 400,\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 showToolTimeline: true,\n zIndex: 1000,\n};\n\n/**\n * Chat drawer component for Devic assistants\n *\n * @example\n * ```tsx\n * <ChatDrawer\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 function ChatDrawer({\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}: ChatDrawerProps): 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)\n const [internalIsOpen, setInternalIsOpen] = useState(mergedOptions.defaultOpen);\n const isOpen = controlledIsOpen ?? internalIsOpen;\n\n // Use chat hook\n const chat = useDevicChat({\n assistantId,\n chatUid: initialChatUid,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n enabledTools,\n modelInterfaceTools,\n onMessageSent,\n onMessageReceived,\n onToolCall,\n onError,\n onChatCreated,\n });\n\n // 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 // Handle send message\n const handleSend = useCallback(\n (message: string, files?: any[]) => {\n chat.sendMessage(message, { files });\n },\n [chat]\n );\n\n // Handle suggested message click\n const handleSuggestedClick = useCallback(\n (message: string) => {\n chat.sendMessage(message);\n },\n [chat]\n );\n\n // Apply CSS variable for primary color\n useEffect(() => {\n if (mergedOptions.color !== DEFAULT_OPTIONS.color) {\n document.documentElement.style.setProperty(\n '--devic-primary',\n mergedOptions.color\n );\n }\n }, [mergedOptions.color]);\n\n // Build style object\n const drawerStyle = useMemo(\n () => ({\n width: mergedOptions.width,\n zIndex: mergedOptions.zIndex,\n }),\n [mergedOptions.width, mergedOptions.zIndex]\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 */}\n <div\n className=\"devic-drawer-overlay\"\n data-open={isOpen}\n style={overlayStyle}\n onClick={handleClose}\n />\n\n {/* Drawer */}\n <div\n className={`devic-chat-drawer ${className || ''}`}\n data-position={mergedOptions.position}\n data-open={isOpen}\n style={drawerStyle}\n >\n {/* Header */}\n <div className=\"devic-drawer-header\">\n <h2 className=\"devic-drawer-title\">{mergedOptions.title}</h2>\n <button\n className=\"devic-drawer-close\"\n onClick={handleClose}\n type=\"button\"\n aria-label=\"Close chat\"\n >\n <CloseIcon />\n </button>\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 isLoading={chat.isLoading}\n welcomeMessage={mergedOptions.welcomeMessage}\n suggestedMessages={mergedOptions.suggestedMessages}\n onSuggestedClick={handleSuggestedClick}\n showToolTimeline={mergedOptions.showToolTimeline}\n />\n\n {/* Input */}\n <ChatInput\n onSend={handleSend}\n disabled={chat.isLoading}\n placeholder={mergedOptions.inputPlaceholder}\n enableFileUploads={mergedOptions.enableFileUploads}\n allowedFileTypes={mergedOptions.allowedFileTypes}\n maxFileSize={mergedOptions.maxFileSize}\n />\n </div>\n\n {/* Trigger button (when drawer is closed) */}\n {!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 * 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":["_jsxs","_jsx"],"mappings":";;;;;;AAOA,MAAM,eAAe,GAAgC;AACnD,IAAA,QAAQ,EAAE,OAAO;AACjB,IAAA,KAAK,EAAE,GAAG;AACV,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,gBAAgB,EAAE,IAAI;AACtB,IAAA,MAAM,EAAE,IAAI;CACb;AAED;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,UAAU,CAAC,EACzB,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,MAAM,EACN,OAAO,EACP,MAAM,EAAE,gBAAgB,EACxB,SAAS,GACO,EAAA;;IAEhB,MAAM,aAAa,GAAG,OAAO,CAC3B,OAAO,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAC,EAC1C,CAAC,OAAO,CAAC,CACV;;AAGD,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC;AAC/E,IAAA,MAAM,MAAM,GAAG,gBAAgB,IAAI,cAAc;;IAGjD,MAAM,IAAI,GAAG,YAAY,CAAC;QACxB,WAAW;AACX,QAAA,OAAO,EAAE,cAAc;QACvB,MAAM;QACN,OAAO;QACP,QAAQ;QACR,cAAc;QACd,YAAY;QACZ,mBAAmB;QACnB,aAAa;QACb,iBAAiB;QACjB,UAAU;QACV,OAAO;QACP,aAAa;AACd,KAAA,CAAC;;AAGF,IAAA,MAAM,UAAU,GAAG,WAAW,CAAC,MAAK;QAClC,iBAAiB,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI;AACZ,IAAA,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AAEZ,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAK;QACnC,iBAAiB,CAAC,KAAK,CAAC;QACxB,OAAO,IAAI;AACb,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;;IAGb,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,OAAe,EAAE,KAAa,KAAI;QACjC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC;AACtC,IAAA,CAAC,EACD,CAAC,IAAI,CAAC,CACP;;AAGD,IAAA,MAAM,oBAAoB,GAAG,WAAW,CACtC,CAAC,OAAe,KAAI;AAClB,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AAC3B,IAAA,CAAC,EACD,CAAC,IAAI,CAAC,CACP;;IAGD,SAAS,CAAC,MAAK;QACb,IAAI,aAAa,CAAC,KAAK,KAAK,eAAe,CAAC,KAAK,EAAE;AACjD,YAAA,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CACxC,iBAAiB,EACjB,aAAa,CAAC,KAAK,CACpB;QACH;AACF,IAAA,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;;AAGzB,IAAA,MAAM,WAAW,GAAG,OAAO,CACzB,OAAO;QACL,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,MAAM,EAAE,aAAa,CAAC,MAAM;KAC7B,CAAC,EACF,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAC5C;AAED,IAAA,MAAM,YAAY,GAAG,OAAO,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,GAAG,OAAO,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,QACEA,4BAEEC,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,sBAAsB,EAAA,WAAA,EACrB,MAAM,EACjB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,WAAW,GACpB,EAGFD,IAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,CAAA,kBAAA,EAAqB,SAAS,IAAI,EAAE,CAAA,CAAE,mBAClC,aAAa,CAAC,QAAQ,EAAA,WAAA,EAC1B,MAAM,EACjB,KAAK,EAAE,WAAW,EAAA,QAAA,EAAA,CAGlBA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,aAClCC,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,oBAAoB,EAAA,QAAA,EAAE,aAAa,CAAC,KAAK,EAAA,CAAM,EAC7DA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,oBAAoB,EAC9B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACF,YAAY,YAEvBA,GAAA,CAAC,SAAS,EAAA,EAAA,CAAG,EAAA,CACN,CAAA,EAAA,CACL,EAGL,IAAI,CAAC,KAAK,KACTA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,aAAa,EAAA,QAAA,EACzB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA,CACf,CACP,EAGDA,GAAA,CAAC,YAAY,EAAA,EACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,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,GAChD,EAGFA,GAAA,CAAC,SAAS,EAAA,EACR,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,CAAC,SAAS,EACxB,WAAW,EAAE,aAAa,CAAC,gBAAgB,EAC3C,iBAAiB,EAAE,aAAa,CAAC,iBAAiB,EAClD,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,EAChD,WAAW,EAAE,aAAa,CAAC,WAAW,EAAA,CACtC,CAAA,EAAA,CACE,EAGL,CAAC,MAAM,KACNA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,eAAe,EACzB,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,YAAY,EACnB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACF,WAAW,YAEtBA,GAAA,CAAC,QAAQ,KAAG,EAAA,CACL,CACV,CAAA,EAAA,CACA;AAEP;AAEA;;AAEG;AACH,SAAS,SAAS,GAAA;AAChB,IAAA,QACED,IAAA,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,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACtCA,GAAA,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;IACf,QACEA,GAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,cAAc,EAAA,QAAA,EAEnBA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,yFAAyF,EAAA,CAAG,EAAA,CAChG;AAEV;;;;"}
@@ -0,0 +1,197 @@
1
+ import type { ChatMessage, ModelInterfaceTool, ChatFile } from '../../api/types';
2
+ /**
3
+ * Allowed file types for upload
4
+ */
5
+ export interface AllowedFileTypes {
6
+ images?: boolean;
7
+ documents?: boolean;
8
+ audio?: boolean;
9
+ video?: boolean;
10
+ }
11
+ /**
12
+ * ChatDrawer display options
13
+ */
14
+ export interface ChatDrawerOptions {
15
+ /**
16
+ * Drawer position
17
+ * @default 'right'
18
+ */
19
+ position?: 'left' | 'right';
20
+ /**
21
+ * Drawer width in pixels
22
+ * @default 400
23
+ */
24
+ width?: number;
25
+ /**
26
+ * Whether drawer starts open
27
+ * @default false
28
+ */
29
+ defaultOpen?: boolean;
30
+ /**
31
+ * Primary color for theming
32
+ * @default '#1890ff'
33
+ */
34
+ color?: string;
35
+ /**
36
+ * Welcome message shown at start
37
+ */
38
+ welcomeMessage?: string;
39
+ /**
40
+ * Suggested messages to display as quick actions
41
+ */
42
+ suggestedMessages?: string[];
43
+ /**
44
+ * Enable file uploads
45
+ * @default false
46
+ */
47
+ enableFileUploads?: boolean;
48
+ /**
49
+ * Allowed file types for upload
50
+ */
51
+ allowedFileTypes?: AllowedFileTypes;
52
+ /**
53
+ * Maximum file size in bytes
54
+ * @default 10485760 (10MB)
55
+ */
56
+ maxFileSize?: number;
57
+ /**
58
+ * Placeholder text for input
59
+ * @default 'Type a message...'
60
+ */
61
+ inputPlaceholder?: string;
62
+ /**
63
+ * Title displayed in header
64
+ */
65
+ title?: string;
66
+ /**
67
+ * Show tool execution timeline
68
+ * @default true
69
+ */
70
+ showToolTimeline?: boolean;
71
+ /**
72
+ * Z-index for the drawer
73
+ * @default 1000
74
+ */
75
+ zIndex?: number;
76
+ }
77
+ /**
78
+ * Props for the ChatDrawer component
79
+ */
80
+ export interface ChatDrawerProps {
81
+ /**
82
+ * Assistant identifier
83
+ */
84
+ assistantId: string;
85
+ /**
86
+ * Existing chat UID to continue conversation
87
+ */
88
+ chatUid?: string;
89
+ /**
90
+ * Display and behavior options
91
+ */
92
+ options?: ChatDrawerOptions;
93
+ /**
94
+ * Tools enabled from assistant's configured tool groups
95
+ */
96
+ enabledTools?: string[];
97
+ /**
98
+ * Client-side tools for model interface protocol
99
+ */
100
+ modelInterfaceTools?: ModelInterfaceTool[];
101
+ /**
102
+ * Tenant ID (overrides provider)
103
+ */
104
+ tenantId?: string;
105
+ /**
106
+ * Tenant metadata (overrides provider)
107
+ */
108
+ tenantMetadata?: Record<string, any>;
109
+ /**
110
+ * API key (overrides provider)
111
+ */
112
+ apiKey?: string;
113
+ /**
114
+ * Base URL (overrides provider)
115
+ */
116
+ baseUrl?: string;
117
+ /**
118
+ * Callback when a message is sent
119
+ */
120
+ onMessageSent?: (message: ChatMessage) => void;
121
+ /**
122
+ * Callback when a message is received
123
+ */
124
+ onMessageReceived?: (message: ChatMessage) => void;
125
+ /**
126
+ * Callback when a tool is called
127
+ */
128
+ onToolCall?: (toolName: string, params: any) => void;
129
+ /**
130
+ * Callback when an error occurs
131
+ */
132
+ onError?: (error: Error) => void;
133
+ /**
134
+ * Callback when chat is created
135
+ */
136
+ onChatCreated?: (chatUid: string) => void;
137
+ /**
138
+ * Callback when drawer opens
139
+ */
140
+ onOpen?: () => void;
141
+ /**
142
+ * Callback when drawer closes
143
+ */
144
+ onClose?: () => void;
145
+ /**
146
+ * External control of open state
147
+ */
148
+ isOpen?: boolean;
149
+ /**
150
+ * Additional class name
151
+ */
152
+ className?: string;
153
+ }
154
+ /**
155
+ * Props for ChatMessages component
156
+ */
157
+ export interface ChatMessagesProps {
158
+ messages: ChatMessage[];
159
+ isLoading: boolean;
160
+ welcomeMessage?: string;
161
+ suggestedMessages?: string[];
162
+ onSuggestedClick?: (message: string) => void;
163
+ showToolTimeline?: boolean;
164
+ }
165
+ /**
166
+ * Props for ChatInput component
167
+ */
168
+ export interface ChatInputProps {
169
+ onSend: (message: string, files?: ChatFile[]) => void;
170
+ disabled?: boolean;
171
+ placeholder?: string;
172
+ enableFileUploads?: boolean;
173
+ allowedFileTypes?: AllowedFileTypes;
174
+ maxFileSize?: number;
175
+ }
176
+ /**
177
+ * Props for ToolTimeline component
178
+ */
179
+ export interface ToolTimelineProps {
180
+ toolCalls: Array<{
181
+ id: string;
182
+ name: string;
183
+ status: 'pending' | 'executing' | 'completed' | 'error';
184
+ result?: any;
185
+ error?: string;
186
+ timestamp: number;
187
+ }>;
188
+ }
189
+ /**
190
+ * Trigger button position
191
+ */
192
+ export interface TriggerPosition {
193
+ bottom?: number;
194
+ right?: number;
195
+ left?: number;
196
+ top?: number;
197
+ }