@devicai/ui 0.2.0 → 0.4.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.
- package/dist/cjs/api/client.js +31 -15
- package/dist/cjs/api/client.js.map +1 -1
- package/dist/cjs/components/AICommandBar/AICommandBar.js +314 -0
- package/dist/cjs/components/AICommandBar/AICommandBar.js.map +1 -0
- package/dist/cjs/components/AICommandBar/useAICommandBar.js +595 -0
- package/dist/cjs/components/AICommandBar/useAICommandBar.js.map +1 -0
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js +73 -5
- package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/cjs/components/ChatDrawer/ChatMessages.js +5 -2
- package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/cjs/components/Feedback/FeedbackModal.js +87 -0
- package/dist/cjs/components/Feedback/FeedbackModal.js.map +1 -0
- package/dist/cjs/components/Feedback/MessageActions.js +74 -0
- package/dist/cjs/components/Feedback/MessageActions.js.map +1 -0
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/esm/api/client.d.ts +10 -2
- package/dist/esm/api/client.js +31 -15
- package/dist/esm/api/client.js.map +1 -1
- package/dist/esm/api/types.d.ts +25 -0
- package/dist/esm/components/AICommandBar/AICommandBar.d.ts +22 -0
- package/dist/esm/components/AICommandBar/AICommandBar.js +312 -0
- package/dist/esm/components/AICommandBar/AICommandBar.js.map +1 -0
- package/dist/esm/components/AICommandBar/AICommandBar.types.d.ts +321 -0
- package/dist/esm/components/AICommandBar/index.d.ts +3 -0
- package/dist/esm/components/AICommandBar/useAICommandBar.d.ts +57 -0
- package/dist/esm/components/AICommandBar/useAICommandBar.js +592 -0
- package/dist/esm/components/AICommandBar/useAICommandBar.js.map +1 -0
- package/dist/esm/components/AutocompleteInput/AutocompleteInput.d.ts +4 -0
- package/dist/esm/components/AutocompleteInput/AutocompleteInput.types.d.ts +50 -0
- package/dist/esm/components/AutocompleteInput/index.d.ts +4 -0
- package/dist/esm/components/AutocompleteInput/useAutocomplete.d.ts +29 -0
- package/dist/esm/components/ChatDrawer/ChatDrawer.d.ts +4 -2
- package/dist/esm/components/ChatDrawer/ChatDrawer.js +74 -6
- package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
- package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +36 -0
- package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +2 -1
- package/dist/esm/components/ChatDrawer/ChatMessages.js +5 -2
- package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
- package/dist/esm/components/ChatDrawer/index.d.ts +1 -1
- package/dist/esm/components/Feedback/Feedback.types.d.ts +50 -0
- package/dist/esm/components/Feedback/FeedbackModal.d.ts +5 -0
- package/dist/esm/components/Feedback/FeedbackModal.js +85 -0
- package/dist/esm/components/Feedback/FeedbackModal.js.map +1 -0
- package/dist/esm/components/Feedback/MessageActions.d.ts +5 -0
- package/dist/esm/components/Feedback/MessageActions.js +72 -0
- package/dist/esm/components/Feedback/MessageActions.js.map +1 -0
- package/dist/esm/components/Feedback/index.d.ts +3 -0
- package/dist/esm/index.d.ts +6 -2
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/styles.css +1 -1
- package/package.json +1 -1
package/dist/cjs/api/client.js
CHANGED
|
@@ -19,8 +19,8 @@ class DevicApiClient {
|
|
|
19
19
|
async request(endpoint, options = {}) {
|
|
20
20
|
const url = `${this.config.baseUrl}${endpoint}`;
|
|
21
21
|
const headers = {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
24
24
|
...options.headers,
|
|
25
25
|
};
|
|
26
26
|
const response = await fetch(url, {
|
|
@@ -43,7 +43,7 @@ class DevicApiClient {
|
|
|
43
43
|
// Handle responses that may have a wrapper structure
|
|
44
44
|
const data = await response.json();
|
|
45
45
|
// If the response has a data property, extract it (common wrapper pattern)
|
|
46
|
-
if (data && typeof data ===
|
|
46
|
+
if (data && typeof data === "object" && "data" in data) {
|
|
47
47
|
return data.data;
|
|
48
48
|
}
|
|
49
49
|
return data;
|
|
@@ -52,7 +52,7 @@ class DevicApiClient {
|
|
|
52
52
|
* Get all assistant specializations
|
|
53
53
|
*/
|
|
54
54
|
async getAssistants(external = false) {
|
|
55
|
-
const query = external ?
|
|
55
|
+
const query = external ? "?external=true" : "";
|
|
56
56
|
return this.request(`/api/v1/assistants${query}`);
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
@@ -64,18 +64,19 @@ class DevicApiClient {
|
|
|
64
64
|
/**
|
|
65
65
|
* Send a message to an assistant (sync mode)
|
|
66
66
|
*/
|
|
67
|
-
async sendMessage(assistantId, dto) {
|
|
68
|
-
return this.request(`/api/v1/assistants/${assistantId}/messages`, {
|
|
69
|
-
method:
|
|
67
|
+
async sendMessage(assistantId, dto, signal) {
|
|
68
|
+
return this.request(`/api/v1/assistants/${assistantId}/messages${dto.skipSummarization ? "?skipSummarization=true" : ""}`, {
|
|
69
|
+
method: "POST",
|
|
70
70
|
body: JSON.stringify(dto),
|
|
71
|
+
signal,
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
75
|
* Send a message to an assistant (async mode)
|
|
75
76
|
*/
|
|
76
77
|
async sendMessageAsync(assistantId, dto) {
|
|
77
|
-
return this.request(`/api/v1/assistants/${assistantId}/messages?async=true`, {
|
|
78
|
-
method:
|
|
78
|
+
return this.request(`/api/v1/assistants/${assistantId}/messages?async=true${dto.skipSummarization ? "&skipSummarization=true" : ""}`, {
|
|
79
|
+
method: "POST",
|
|
79
80
|
body: JSON.stringify(dto),
|
|
80
81
|
});
|
|
81
82
|
}
|
|
@@ -91,10 +92,10 @@ class DevicApiClient {
|
|
|
91
92
|
async getChatHistory(assistantId, chatUid, options) {
|
|
92
93
|
const params = new URLSearchParams();
|
|
93
94
|
if (options?.tenantId) {
|
|
94
|
-
params.set(
|
|
95
|
+
params.set("tenantId", options.tenantId);
|
|
95
96
|
}
|
|
96
97
|
const query = params.toString();
|
|
97
|
-
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}${query ? `?${query}` :
|
|
98
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}${query ? `?${query}` : ""}`);
|
|
98
99
|
}
|
|
99
100
|
/**
|
|
100
101
|
* List conversations for an assistant
|
|
@@ -102,10 +103,10 @@ class DevicApiClient {
|
|
|
102
103
|
async listConversations(assistantId, options) {
|
|
103
104
|
const params = new URLSearchParams();
|
|
104
105
|
if (options?.tenantId) {
|
|
105
|
-
params.set(
|
|
106
|
+
params.set("tenantId", options.tenantId);
|
|
106
107
|
}
|
|
107
108
|
const query = params.toString();
|
|
108
|
-
const response = await this.request(`/api/v1/assistants/${assistantId}/chats${query ? `?${query}` :
|
|
109
|
+
const response = await this.request(`/api/v1/assistants/${assistantId}/chats${query ? `?${query}` : ""}`);
|
|
109
110
|
return response.histories;
|
|
110
111
|
}
|
|
111
112
|
/**
|
|
@@ -113,10 +114,25 @@ class DevicApiClient {
|
|
|
113
114
|
*/
|
|
114
115
|
async sendToolResponses(assistantId, chatUid, responses) {
|
|
115
116
|
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/tool-response`, {
|
|
116
|
-
method:
|
|
117
|
+
method: "POST",
|
|
117
118
|
body: JSON.stringify({ responses }),
|
|
118
119
|
});
|
|
119
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Submit feedback for a chat message
|
|
123
|
+
*/
|
|
124
|
+
async submitChatFeedback(assistantId, chatUid, data) {
|
|
125
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
body: JSON.stringify(data),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get all feedback for a chat
|
|
132
|
+
*/
|
|
133
|
+
async getChatFeedback(assistantId, chatUid) {
|
|
134
|
+
return this.request(`/api/v1/assistants/${assistantId}/chats/${chatUid}/feedback`);
|
|
135
|
+
}
|
|
120
136
|
}
|
|
121
137
|
/**
|
|
122
138
|
* Custom error class for API errors
|
|
@@ -124,7 +140,7 @@ class DevicApiClient {
|
|
|
124
140
|
class DevicApiError extends Error {
|
|
125
141
|
constructor(error) {
|
|
126
142
|
super(error.message);
|
|
127
|
-
this.name =
|
|
143
|
+
this.name = "DevicApiError";
|
|
128
144
|
this.statusCode = error.statusCode;
|
|
129
145
|
this.errorType = error.error;
|
|
130
146
|
}
|
|
@@ -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} 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 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/**\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} 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[]>(\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/**\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,314 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var useAICommandBar = require('./useAICommandBar.js');
|
|
6
|
+
var MessageActions = require('../Feedback/MessageActions.js');
|
|
7
|
+
var DevicContext = require('../../provider/DevicContext.js');
|
|
8
|
+
var client = require('../../api/client.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect if a color is dark based on perceived brightness
|
|
12
|
+
*/
|
|
13
|
+
function isColorDark(color) {
|
|
14
|
+
// Handle hex colors
|
|
15
|
+
const hex = color.replace('#', '');
|
|
16
|
+
if (hex.length === 3 || hex.length === 6) {
|
|
17
|
+
const r = parseInt(hex.length === 3 ? hex[0] + hex[0] : hex.slice(0, 2), 16);
|
|
18
|
+
const g = parseInt(hex.length === 3 ? hex[1] + hex[1] : hex.slice(2, 4), 16);
|
|
19
|
+
const b = parseInt(hex.length === 3 ? hex[2] + hex[2] : hex.slice(4, 6), 16);
|
|
20
|
+
// Perceived brightness formula
|
|
21
|
+
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
22
|
+
return brightness < 128;
|
|
23
|
+
}
|
|
24
|
+
// Handle rgb/rgba
|
|
25
|
+
const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
26
|
+
if (rgbMatch) {
|
|
27
|
+
const r = parseInt(rgbMatch[1], 10);
|
|
28
|
+
const g = parseInt(rgbMatch[2], 10);
|
|
29
|
+
const b = parseInt(rgbMatch[3], 10);
|
|
30
|
+
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
31
|
+
return brightness < 128;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Lighten or darken a hex color
|
|
37
|
+
*/
|
|
38
|
+
function adjustColor(color, amount) {
|
|
39
|
+
const hex = color.replace('#', '');
|
|
40
|
+
const r = Math.min(255, Math.max(0, parseInt(hex.slice(0, 2), 16) + amount));
|
|
41
|
+
const g = Math.min(255, Math.max(0, parseInt(hex.slice(2, 4), 16) + amount));
|
|
42
|
+
const b = Math.min(255, Math.max(0, parseInt(hex.slice(4, 6), 16) + amount));
|
|
43
|
+
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
44
|
+
}
|
|
45
|
+
const DEFAULT_OPTIONS = {
|
|
46
|
+
position: 'inline',
|
|
47
|
+
fixedPlacement: {},
|
|
48
|
+
shortcut: '',
|
|
49
|
+
showShortcutHint: true,
|
|
50
|
+
placeholder: 'Ask AI...',
|
|
51
|
+
icon: undefined,
|
|
52
|
+
width: 400,
|
|
53
|
+
maxWidth: '100%',
|
|
54
|
+
zIndex: 9999,
|
|
55
|
+
showResultCard: true,
|
|
56
|
+
resultCardMaxHeight: 300,
|
|
57
|
+
color: '#3b82f6',
|
|
58
|
+
backgroundColor: '#ffffff',
|
|
59
|
+
textColor: '#1f2937',
|
|
60
|
+
borderColor: '#e5e7eb',
|
|
61
|
+
borderRadius: 12,
|
|
62
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
63
|
+
fontSize: 14,
|
|
64
|
+
padding: '12px 16px',
|
|
65
|
+
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.1)',
|
|
66
|
+
animationDuration: 200,
|
|
67
|
+
toolRenderers: undefined,
|
|
68
|
+
toolIcons: undefined,
|
|
69
|
+
processingMessage: 'Processing...',
|
|
70
|
+
enableHistory: true,
|
|
71
|
+
maxHistoryItems: 50,
|
|
72
|
+
historyStorageKey: 'devic-command-bar-history',
|
|
73
|
+
commands: undefined,
|
|
74
|
+
showHistoryCommand: true,
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* AI Command Bar component - a floating input for quick AI interactions
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```tsx
|
|
81
|
+
* <AICommandBar
|
|
82
|
+
* assistantId="support-assistant"
|
|
83
|
+
* options={{
|
|
84
|
+
* position: 'fixed',
|
|
85
|
+
* fixedPlacement: { bottom: 20, right: 20 },
|
|
86
|
+
* shortcut: 'cmd+j',
|
|
87
|
+
* placeholder: 'Ask AI...',
|
|
88
|
+
* }}
|
|
89
|
+
* onResponse={({ message }) => console.log('Response:', message.content)}
|
|
90
|
+
* />
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
const AICommandBar = React.forwardRef(function AICommandBar(props, ref) {
|
|
94
|
+
const { assistantId, apiKey, baseUrl, tenantId, tenantMetadata, options = {}, isVisible: controlledVisible, onVisibilityChange, onExecute = 'callback', chatDrawerRef, onResponse, modelInterfaceTools, onSubmit, onToolCall, onError, onOpen, onClose, className, } = props;
|
|
95
|
+
const mergedOptions = React.useMemo(() => ({ ...DEFAULT_OPTIONS, ...options }), [options]);
|
|
96
|
+
const hook = useAICommandBar.useAICommandBar({
|
|
97
|
+
assistantId,
|
|
98
|
+
apiKey,
|
|
99
|
+
baseUrl,
|
|
100
|
+
tenantId,
|
|
101
|
+
tenantMetadata,
|
|
102
|
+
options: mergedOptions,
|
|
103
|
+
isVisible: controlledVisible,
|
|
104
|
+
onVisibilityChange,
|
|
105
|
+
onExecute,
|
|
106
|
+
chatDrawerRef,
|
|
107
|
+
onResponse,
|
|
108
|
+
modelInterfaceTools,
|
|
109
|
+
onSubmit,
|
|
110
|
+
onToolCall,
|
|
111
|
+
onError,
|
|
112
|
+
onOpen,
|
|
113
|
+
onClose,
|
|
114
|
+
});
|
|
115
|
+
// Expose handle
|
|
116
|
+
React.useImperativeHandle(ref, () => ({
|
|
117
|
+
open: hook.open,
|
|
118
|
+
close: hook.close,
|
|
119
|
+
toggle: hook.toggle,
|
|
120
|
+
focus: hook.focus,
|
|
121
|
+
submit: hook.submit,
|
|
122
|
+
reset: hook.reset,
|
|
123
|
+
}));
|
|
124
|
+
// Tool list expansion state
|
|
125
|
+
const [toolsExpanded, setToolsExpanded] = React.useState(false);
|
|
126
|
+
// Feedback state
|
|
127
|
+
const [feedbackState, setFeedbackState] = React.useState('none');
|
|
128
|
+
const feedbackClientRef = React.useRef(null);
|
|
129
|
+
// Get context for API client
|
|
130
|
+
const context = DevicContext.useOptionalDevicContext();
|
|
131
|
+
const resolvedApiKey = apiKey || context?.apiKey;
|
|
132
|
+
const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';
|
|
133
|
+
// Initialize feedback client
|
|
134
|
+
React.useEffect(() => {
|
|
135
|
+
if (resolvedApiKey && !feedbackClientRef.current) {
|
|
136
|
+
feedbackClientRef.current = new client.DevicApiClient({
|
|
137
|
+
apiKey: resolvedApiKey,
|
|
138
|
+
baseUrl: resolvedBaseUrl,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}, [resolvedApiKey, resolvedBaseUrl]);
|
|
142
|
+
// Reset feedback state when result changes
|
|
143
|
+
React.useEffect(() => {
|
|
144
|
+
if (hook.result) {
|
|
145
|
+
setFeedbackState('none');
|
|
146
|
+
}
|
|
147
|
+
}, [hook.result?.chatUid, hook.result?.message.uid]);
|
|
148
|
+
// Handle feedback submission
|
|
149
|
+
const handleFeedback = React.useCallback(async (messageId, positive, comment) => {
|
|
150
|
+
if (!hook.result?.chatUid || !feedbackClientRef.current)
|
|
151
|
+
return;
|
|
152
|
+
try {
|
|
153
|
+
await feedbackClientRef.current.submitChatFeedback(assistantId, hook.result.chatUid, {
|
|
154
|
+
messageId,
|
|
155
|
+
feedback: positive,
|
|
156
|
+
feedbackComment: comment,
|
|
157
|
+
});
|
|
158
|
+
setFeedbackState(positive ? 'positive' : 'negative');
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
console.error('Failed to submit feedback:', err);
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}, [hook.result?.chatUid, assistantId]);
|
|
165
|
+
// Container ref for theming
|
|
166
|
+
const containerRef = React.useRef(null);
|
|
167
|
+
// Apply CSS variables for theming
|
|
168
|
+
React.useEffect(() => {
|
|
169
|
+
const el = containerRef.current;
|
|
170
|
+
if (!el)
|
|
171
|
+
return;
|
|
172
|
+
const vars = [
|
|
173
|
+
['--devic-cmd-bg-override', mergedOptions.backgroundColor],
|
|
174
|
+
['--devic-cmd-text-override', mergedOptions.textColor],
|
|
175
|
+
['--devic-cmd-border-override', mergedOptions.borderColor],
|
|
176
|
+
['--devic-cmd-primary-override', mergedOptions.color],
|
|
177
|
+
['--devic-cmd-font-family-override', mergedOptions.fontFamily],
|
|
178
|
+
['--devic-cmd-font-size-override', typeof mergedOptions.fontSize === 'number' ? `${mergedOptions.fontSize}px` : mergedOptions.fontSize],
|
|
179
|
+
['--devic-cmd-radius-override', typeof mergedOptions.borderRadius === 'number' ? `${mergedOptions.borderRadius}px` : mergedOptions.borderRadius],
|
|
180
|
+
['--devic-cmd-shadow-override', mergedOptions.boxShadow],
|
|
181
|
+
['--devic-cmd-animation-duration-override', `${mergedOptions.animationDuration}ms`],
|
|
182
|
+
];
|
|
183
|
+
for (const [name, value] of vars) {
|
|
184
|
+
if (value) {
|
|
185
|
+
el.style.setProperty(name, value);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
el.style.removeProperty(name);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}, [mergedOptions]);
|
|
192
|
+
// Click-outside detection to close the bar
|
|
193
|
+
React.useEffect(() => {
|
|
194
|
+
if (!hook.isVisible)
|
|
195
|
+
return;
|
|
196
|
+
const handleClickOutside = (e) => {
|
|
197
|
+
const container = containerRef.current;
|
|
198
|
+
if (container && !container.contains(e.target)) {
|
|
199
|
+
// Reset if there's a result, otherwise just close
|
|
200
|
+
if (hook.result) {
|
|
201
|
+
hook.reset();
|
|
202
|
+
}
|
|
203
|
+
hook.close();
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
// Use mousedown instead of click to prevent race conditions
|
|
207
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
208
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
209
|
+
}, [hook.isVisible, hook.result, hook.reset, hook.close]);
|
|
210
|
+
// Feedback theme derived from command bar options
|
|
211
|
+
const feedbackTheme = React.useMemo(() => {
|
|
212
|
+
const bg = mergedOptions.backgroundColor;
|
|
213
|
+
const text = mergedOptions.textColor;
|
|
214
|
+
const border = mergedOptions.borderColor;
|
|
215
|
+
const primary = mergedOptions.color;
|
|
216
|
+
// Only create theme if we have some custom colors
|
|
217
|
+
if (!bg && !text)
|
|
218
|
+
return undefined;
|
|
219
|
+
const isDark = bg ? isColorDark(bg) : false;
|
|
220
|
+
return {
|
|
221
|
+
backgroundColor: bg,
|
|
222
|
+
textColor: text,
|
|
223
|
+
textMutedColor: text && bg ? (isDark ? adjustColor(text, -60) : adjustColor(text, 60)) : undefined,
|
|
224
|
+
secondaryBackgroundColor: bg ? (isDark ? adjustColor(bg, 20) : adjustColor(bg, -15)) : undefined,
|
|
225
|
+
borderColor: border,
|
|
226
|
+
primaryColor: primary,
|
|
227
|
+
primaryHoverColor: primary ? (isDark ? adjustColor(primary, 20) : adjustColor(primary, -20)) : undefined,
|
|
228
|
+
};
|
|
229
|
+
}, [mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.borderColor, mergedOptions.color]);
|
|
230
|
+
// Container styles
|
|
231
|
+
const containerStyle = React.useMemo(() => {
|
|
232
|
+
const style = {
|
|
233
|
+
width: typeof mergedOptions.width === 'number' ? `${mergedOptions.width}px` : mergedOptions.width,
|
|
234
|
+
maxWidth: typeof mergedOptions.maxWidth === 'number' ? `${mergedOptions.maxWidth}px` : mergedOptions.maxWidth,
|
|
235
|
+
zIndex: mergedOptions.zIndex,
|
|
236
|
+
};
|
|
237
|
+
if (mergedOptions.position === 'fixed') {
|
|
238
|
+
const { top, right, bottom, left } = mergedOptions.fixedPlacement || {};
|
|
239
|
+
if (top !== undefined)
|
|
240
|
+
style.top = typeof top === 'number' ? `${top}px` : top;
|
|
241
|
+
if (right !== undefined)
|
|
242
|
+
style.right = typeof right === 'number' ? `${right}px` : right;
|
|
243
|
+
if (bottom !== undefined)
|
|
244
|
+
style.bottom = typeof bottom === 'number' ? `${bottom}px` : bottom;
|
|
245
|
+
if (left !== undefined)
|
|
246
|
+
style.left = typeof left === 'number' ? `${left}px` : left;
|
|
247
|
+
}
|
|
248
|
+
return style;
|
|
249
|
+
}, [mergedOptions]);
|
|
250
|
+
// Bar padding style
|
|
251
|
+
const barStyle = React.useMemo(() => {
|
|
252
|
+
if (!mergedOptions.padding || mergedOptions.padding === DEFAULT_OPTIONS.padding) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
padding: typeof mergedOptions.padding === 'number' ? `${mergedOptions.padding}px` : mergedOptions.padding,
|
|
257
|
+
};
|
|
258
|
+
}, [mergedOptions.padding]);
|
|
259
|
+
// Result card max height style
|
|
260
|
+
const resultMessageStyle = React.useMemo(() => {
|
|
261
|
+
if (!mergedOptions.resultCardMaxHeight || mergedOptions.resultCardMaxHeight === DEFAULT_OPTIONS.resultCardMaxHeight) {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
maxHeight: typeof mergedOptions.resultCardMaxHeight === 'number'
|
|
266
|
+
? `${mergedOptions.resultCardMaxHeight}px`
|
|
267
|
+
: mergedOptions.resultCardMaxHeight,
|
|
268
|
+
};
|
|
269
|
+
}, [mergedOptions.resultCardMaxHeight]);
|
|
270
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `devic-command-bar-container ${className || ''}`, "data-position": mergedOptions.position, "data-visible": hook.isVisible, style: containerStyle, children: [hook.showingCommands && hook.filteredCommands.length > 0 && (jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown", children: [jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown-header", children: [jsxRuntime.jsx("span", { children: "Commands" }), jsxRuntime.jsxs("span", { className: "devic-command-bar-dropdown-hint", children: [jsxRuntime.jsx("kbd", { children: "\u2191" }), jsxRuntime.jsx("kbd", { children: "\u2193" }), " to navigate, ", jsxRuntime.jsx("kbd", { children: "Enter" }), " to select"] })] }), jsxRuntime.jsx("div", { className: "devic-command-bar-dropdown-list", children: hook.filteredCommands.map((cmd, index) => (jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown-item", "data-selected": index === hook.selectedCommandIndex, onClick: () => hook.selectCommand(cmd), onMouseEnter: () => { }, children: [cmd.icon && (jsxRuntime.jsx("span", { className: "devic-command-bar-dropdown-icon", children: cmd.icon })), jsxRuntime.jsxs("span", { className: "devic-command-bar-dropdown-keyword", children: ["/", cmd.keyword] }), jsxRuntime.jsx("span", { className: "devic-command-bar-dropdown-desc", children: cmd.description })] }, cmd.keyword))) })] })), hook.showingHistory && (jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown", children: [jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown-header", children: [jsxRuntime.jsx("span", { children: "Command History" }), hook.history.length > 0 && (jsxRuntime.jsx("button", { className: "devic-command-bar-dropdown-clear", onClick: () => {
|
|
271
|
+
hook.clearHistory();
|
|
272
|
+
hook.setShowingHistory(false);
|
|
273
|
+
}, type: "button", children: "Clear" }))] }), jsxRuntime.jsx("div", { className: "devic-command-bar-dropdown-list", style: resultMessageStyle, children: hook.history.length === 0 ? (jsxRuntime.jsx("div", { className: "devic-command-bar-dropdown-empty", children: "No history yet" })) : (hook.history.map((item, index) => (jsxRuntime.jsxs("div", { className: "devic-command-bar-dropdown-item devic-command-bar-history-item", onClick: () => {
|
|
274
|
+
hook.setShowingHistory(false);
|
|
275
|
+
hook.setInputValue(item);
|
|
276
|
+
hook.focus();
|
|
277
|
+
}, children: [jsxRuntime.jsx(HistoryIcon, { className: "devic-command-bar-dropdown-icon" }), jsxRuntime.jsx("span", { className: "devic-command-bar-history-text", children: item })] }, `${item}-${index}`)))) })] })), mergedOptions.showResultCard && hook.result && !hook.showingHistory && !hook.showingCommands && (jsxRuntime.jsxs("div", { className: "devic-command-bar-result", children: [hook.result.toolCalls.length > 0 && (jsxRuntime.jsxs("div", { className: "devic-command-bar-result-tools", children: [jsxRuntime.jsxs("div", { className: "devic-command-bar-result-tools-header", "data-expanded": toolsExpanded, onClick: () => setToolsExpanded(!toolsExpanded), children: [jsxRuntime.jsx(ChevronIcon, { className: "devic-command-bar-result-tools-chevron" }), jsxRuntime.jsx("span", { children: "Tool calls" }), jsxRuntime.jsx("span", { className: "devic-command-bar-result-tools-count", children: hook.result.toolCalls.length })] }), jsxRuntime.jsx("div", { className: "devic-command-bar-result-tools-list", "data-expanded": toolsExpanded, children: hook.result.toolCalls.map((tc) => {
|
|
278
|
+
// Check for custom renderer
|
|
279
|
+
const customRenderer = mergedOptions.toolRenderers?.[tc.name];
|
|
280
|
+
if (customRenderer) {
|
|
281
|
+
return (jsxRuntime.jsx("div", { className: "devic-command-bar-result-tool-item devic-command-bar-result-tool-custom", children: customRenderer(tc.input, tc.output) }, tc.id));
|
|
282
|
+
}
|
|
283
|
+
// Use custom icon or default check icon
|
|
284
|
+
const customIcon = mergedOptions.toolIcons?.[tc.name];
|
|
285
|
+
return (jsxRuntime.jsxs("div", { className: "devic-command-bar-result-tool-item", children: [customIcon ? (jsxRuntime.jsx("span", { className: "devic-command-bar-result-tool-icon", children: customIcon })) : (jsxRuntime.jsx(CheckIcon, { className: "devic-command-bar-result-tool-icon" })), jsxRuntime.jsx("span", { className: "devic-command-bar-result-tool-name", children: tc.summary || tc.name })] }, tc.id));
|
|
286
|
+
}) })] })), jsxRuntime.jsx("div", { className: "devic-command-bar-result-message", style: resultMessageStyle, children: hook.result.message.content?.message || (jsxRuntime.jsx("span", { className: "devic-command-bar-result-empty", children: "No response" })) }), jsxRuntime.jsx("div", { className: "devic-cmd-result-actions", children: jsxRuntime.jsx(MessageActions.MessageActions, { messageId: hook.result.message.uid, messageContent: hook.result.message.content?.message, currentFeedback: feedbackState, onFeedback: handleFeedback, showCopy: true, showFeedback: true, theme: feedbackTheme }) })] })), hook.error && !hook.isProcessing && (jsxRuntime.jsx("div", { className: "devic-command-bar-error", children: hook.error.message })), jsxRuntime.jsxs("div", { className: "devic-command-bar", style: barStyle, children: [jsxRuntime.jsx("div", { className: "devic-command-bar-icon", children: hook.isProcessing ? (jsxRuntime.jsx("div", { className: "devic-command-bar-spinner" })) : (mergedOptions.icon || jsxRuntime.jsx(SparklesIcon, {})) }), hook.isProcessing ? (jsxRuntime.jsxs("div", { className: "devic-command-bar-summary", children: [hook.currentToolSummary || mergedOptions.processingMessage, "..."] })) : (jsxRuntime.jsx("input", { ref: hook.inputRef, type: "text", className: "devic-command-bar-input", placeholder: mergedOptions.placeholder, value: hook.inputValue, onChange: (e) => hook.setInputValue(e.target.value), onKeyDown: hook.handleKeyDown })), mergedOptions.showShortcutHint && mergedOptions.shortcut && !hook.isProcessing && (jsxRuntime.jsx("div", { className: "devic-command-bar-shortcut", children: useAICommandBar.formatShortcut(mergedOptions.shortcut) }))] })] }));
|
|
287
|
+
});
|
|
288
|
+
/**
|
|
289
|
+
* Sparkles icon (default)
|
|
290
|
+
*/
|
|
291
|
+
function SparklesIcon() {
|
|
292
|
+
return (jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.jsx("path", { d: "M10 2L11.5 8.5L18 10L11.5 11.5L10 18L8.5 11.5L2 10L8.5 8.5L10 2Z", fill: "currentColor", opacity: "0.9" }), jsxRuntime.jsx("path", { d: "M16 3L16.5 5L18.5 5.5L16.5 6L16 8L15.5 6L13.5 5.5L15.5 5L16 3Z", fill: "currentColor", opacity: "0.6" }), jsxRuntime.jsx("circle", { cx: "4", cy: "15", r: "1", fill: "currentColor", opacity: "0.4" })] }));
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Chevron right icon
|
|
296
|
+
*/
|
|
297
|
+
function ChevronIcon({ className }) {
|
|
298
|
+
return (jsxRuntime.jsx("svg", { className: className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }));
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Check icon
|
|
302
|
+
*/
|
|
303
|
+
function CheckIcon({ className }) {
|
|
304
|
+
return (jsxRuntime.jsx("svg", { className: className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* History icon
|
|
308
|
+
*/
|
|
309
|
+
function HistoryIcon({ className }) {
|
|
310
|
+
return (jsxRuntime.jsxs("svg", { className: className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M3 3v5h5" }), jsxRuntime.jsx("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }), jsxRuntime.jsx("path", { d: "M12 7v5l4 2" })] }));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
exports.AICommandBar = AICommandBar;
|
|
314
|
+
//# sourceMappingURL=AICommandBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AICommandBar.js","sources":["../../../../../src/components/AICommandBar/AICommandBar.tsx"],"sourcesContent":["import React, { forwardRef, useImperativeHandle, useState, useMemo, useEffect, useRef, useCallback } from 'react';\nimport { useAICommandBar, formatShortcut } from './useAICommandBar';\nimport { MessageActions } from '../Feedback';\nimport { useOptionalDevicContext } from '../../provider';\nimport { DevicApiClient } from '../../api/client';\nimport type { AICommandBarProps, AICommandBarHandle, AICommandBarOptions } from './AICommandBar.types';\nimport type { FeedbackState, FeedbackTheme } from '../Feedback';\nimport './AICommandBar.css';\nimport '../Feedback/Feedback.css';\n\n/**\n * Detect if a color is dark based on perceived brightness\n */\nfunction isColorDark(color: string): boolean {\n // Handle hex colors\n const hex = color.replace('#', '');\n if (hex.length === 3 || hex.length === 6) {\n const r = parseInt(hex.length === 3 ? hex[0] + hex[0] : hex.slice(0, 2), 16);\n const g = parseInt(hex.length === 3 ? hex[1] + hex[1] : hex.slice(2, 4), 16);\n const b = parseInt(hex.length === 3 ? hex[2] + hex[2] : hex.slice(4, 6), 16);\n // Perceived brightness formula\n const brightness = (r * 299 + g * 587 + b * 114) / 1000;\n return brightness < 128;\n }\n // Handle rgb/rgba\n const rgbMatch = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgbMatch) {\n const r = parseInt(rgbMatch[1], 10);\n const g = parseInt(rgbMatch[2], 10);\n const b = parseInt(rgbMatch[3], 10);\n const brightness = (r * 299 + g * 587 + b * 114) / 1000;\n return brightness < 128;\n }\n return false;\n}\n\n/**\n * Lighten or darken a hex color\n */\nfunction adjustColor(color: string, amount: number): string {\n const hex = color.replace('#', '');\n const r = Math.min(255, Math.max(0, parseInt(hex.slice(0, 2), 16) + amount));\n const g = Math.min(255, Math.max(0, parseInt(hex.slice(2, 4), 16) + amount));\n const b = Math.min(255, Math.max(0, parseInt(hex.slice(4, 6), 16) + amount));\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\nconst DEFAULT_OPTIONS: Required<AICommandBarOptions> = {\n position: 'inline',\n fixedPlacement: {},\n shortcut: '',\n showShortcutHint: true,\n placeholder: 'Ask AI...',\n icon: undefined as any,\n width: 400,\n maxWidth: '100%',\n zIndex: 9999,\n showResultCard: true,\n resultCardMaxHeight: 300,\n color: '#3b82f6',\n backgroundColor: '#ffffff',\n textColor: '#1f2937',\n borderColor: '#e5e7eb',\n borderRadius: 12,\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n fontSize: 14,\n padding: '12px 16px',\n boxShadow: '0 4px 20px rgba(0, 0, 0, 0.1)',\n animationDuration: 200,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n processingMessage: 'Processing...',\n enableHistory: true,\n maxHistoryItems: 50,\n historyStorageKey: 'devic-command-bar-history',\n commands: undefined as any,\n showHistoryCommand: true,\n};\n\n/**\n * AI Command Bar component - a floating input for quick AI interactions\n *\n * @example\n * ```tsx\n * <AICommandBar\n * assistantId=\"support-assistant\"\n * options={{\n * position: 'fixed',\n * fixedPlacement: { bottom: 20, right: 20 },\n * shortcut: 'cmd+j',\n * placeholder: 'Ask AI...',\n * }}\n * onResponse={({ message }) => console.log('Response:', message.content)}\n * />\n * ```\n */\nexport const AICommandBar = forwardRef<AICommandBarHandle, AICommandBarProps>(\n function AICommandBar(props, ref) {\n const {\n assistantId,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n options = {},\n isVisible: controlledVisible,\n onVisibilityChange,\n onExecute = 'callback',\n chatDrawerRef,\n onResponse,\n modelInterfaceTools,\n onSubmit,\n onToolCall,\n onError,\n onOpen,\n onClose,\n className,\n } = props;\n\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n const hook = useAICommandBar({\n assistantId,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n options: mergedOptions,\n isVisible: controlledVisible,\n onVisibilityChange,\n onExecute,\n chatDrawerRef,\n onResponse,\n modelInterfaceTools,\n onSubmit,\n onToolCall,\n onError,\n onOpen,\n onClose,\n });\n\n // Expose handle\n useImperativeHandle(ref, () => ({\n open: hook.open,\n close: hook.close,\n toggle: hook.toggle,\n focus: hook.focus,\n submit: hook.submit,\n reset: hook.reset,\n }));\n\n // Tool list expansion state\n const [toolsExpanded, setToolsExpanded] = useState(false);\n\n // Feedback state\n const [feedbackState, setFeedbackState] = useState<FeedbackState>('none');\n const feedbackClientRef = useRef<DevicApiClient | null>(null);\n\n // Get context for API client\n const context = useOptionalDevicContext();\n const resolvedApiKey = apiKey || context?.apiKey;\n const resolvedBaseUrl = baseUrl || context?.baseUrl || 'https://api.devic.ai';\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 // Reset feedback state when result changes\n useEffect(() => {\n if (hook.result) {\n setFeedbackState('none');\n }\n }, [hook.result?.chatUid, hook.result?.message.uid]);\n\n // Handle feedback submission\n const handleFeedback = useCallback(\n async (messageId: string, positive: boolean, comment?: string) => {\n if (!hook.result?.chatUid || !feedbackClientRef.current) return;\n\n try {\n await feedbackClientRef.current.submitChatFeedback(assistantId, hook.result.chatUid, {\n messageId,\n feedback: positive,\n feedbackComment: comment,\n });\n\n setFeedbackState(positive ? 'positive' : 'negative');\n } catch (err) {\n console.error('Failed to submit feedback:', err);\n throw err;\n }\n },\n [hook.result?.chatUid, assistantId]\n );\n\n // Container ref for theming\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Apply CSS variables for theming\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const vars: [string, string | undefined][] = [\n ['--devic-cmd-bg-override', mergedOptions.backgroundColor],\n ['--devic-cmd-text-override', mergedOptions.textColor],\n ['--devic-cmd-border-override', mergedOptions.borderColor],\n ['--devic-cmd-primary-override', mergedOptions.color],\n ['--devic-cmd-font-family-override', mergedOptions.fontFamily],\n ['--devic-cmd-font-size-override', typeof mergedOptions.fontSize === 'number' ? `${mergedOptions.fontSize}px` : mergedOptions.fontSize],\n ['--devic-cmd-radius-override', typeof mergedOptions.borderRadius === 'number' ? `${mergedOptions.borderRadius}px` : mergedOptions.borderRadius],\n ['--devic-cmd-shadow-override', mergedOptions.boxShadow],\n ['--devic-cmd-animation-duration-override', `${mergedOptions.animationDuration}ms`],\n ];\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]);\n\n // Click-outside detection to close the bar\n useEffect(() => {\n if (!hook.isVisible) return;\n\n const handleClickOutside = (e: MouseEvent) => {\n const container = containerRef.current;\n if (container && !container.contains(e.target as Node)) {\n // Reset if there's a result, otherwise just close\n if (hook.result) {\n hook.reset();\n }\n hook.close();\n }\n };\n\n // Use mousedown instead of click to prevent race conditions\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [hook.isVisible, hook.result, hook.reset, hook.close]);\n\n // Feedback theme derived from command bar options\n const feedbackTheme = useMemo((): FeedbackTheme | undefined => {\n const bg = mergedOptions.backgroundColor;\n const text = mergedOptions.textColor;\n const border = mergedOptions.borderColor;\n const primary = mergedOptions.color;\n\n // Only create theme if we have some custom colors\n if (!bg && !text) return undefined;\n\n const isDark = bg ? isColorDark(bg) : false;\n\n return {\n backgroundColor: bg,\n textColor: text,\n textMutedColor: text && bg ? (isDark ? adjustColor(text, -60) : adjustColor(text, 60)) : undefined,\n secondaryBackgroundColor: bg ? (isDark ? adjustColor(bg, 20) : adjustColor(bg, -15)) : undefined,\n borderColor: border,\n primaryColor: primary,\n primaryHoverColor: primary ? (isDark ? adjustColor(primary, 20) : adjustColor(primary, -20)) : undefined,\n };\n }, [mergedOptions.backgroundColor, mergedOptions.textColor, mergedOptions.borderColor, mergedOptions.color]);\n\n // Container styles\n const containerStyle = useMemo(() => {\n const style: React.CSSProperties = {\n width: typeof mergedOptions.width === 'number' ? `${mergedOptions.width}px` : mergedOptions.width,\n maxWidth: typeof mergedOptions.maxWidth === 'number' ? `${mergedOptions.maxWidth}px` : mergedOptions.maxWidth,\n zIndex: mergedOptions.zIndex,\n };\n\n if (mergedOptions.position === 'fixed') {\n const { top, right, bottom, left } = mergedOptions.fixedPlacement || {};\n if (top !== undefined) style.top = typeof top === 'number' ? `${top}px` : top;\n if (right !== undefined) style.right = typeof right === 'number' ? `${right}px` : right;\n if (bottom !== undefined) style.bottom = typeof bottom === 'number' ? `${bottom}px` : bottom;\n if (left !== undefined) style.left = typeof left === 'number' ? `${left}px` : left;\n }\n\n return style;\n }, [mergedOptions]);\n\n // Bar padding style\n const barStyle = useMemo(() => {\n if (!mergedOptions.padding || mergedOptions.padding === DEFAULT_OPTIONS.padding) {\n return undefined;\n }\n return {\n padding: typeof mergedOptions.padding === 'number' ? `${mergedOptions.padding}px` : mergedOptions.padding,\n };\n }, [mergedOptions.padding]);\n\n // Result card max height style\n const resultMessageStyle = useMemo(() => {\n if (!mergedOptions.resultCardMaxHeight || mergedOptions.resultCardMaxHeight === DEFAULT_OPTIONS.resultCardMaxHeight) {\n return undefined;\n }\n return {\n maxHeight: typeof mergedOptions.resultCardMaxHeight === 'number'\n ? `${mergedOptions.resultCardMaxHeight}px`\n : mergedOptions.resultCardMaxHeight,\n };\n }, [mergedOptions.resultCardMaxHeight]);\n\n return (\n <div\n ref={containerRef}\n className={`devic-command-bar-container ${className || ''}`}\n data-position={mergedOptions.position}\n data-visible={hook.isVisible}\n style={containerStyle}\n >\n {/* Commands dropdown */}\n {hook.showingCommands && hook.filteredCommands.length > 0 && (\n <div className=\"devic-command-bar-dropdown\">\n <div className=\"devic-command-bar-dropdown-header\">\n <span>Commands</span>\n <span className=\"devic-command-bar-dropdown-hint\">\n <kbd>↑</kbd><kbd>↓</kbd> to navigate, <kbd>Enter</kbd> to select\n </span>\n </div>\n <div className=\"devic-command-bar-dropdown-list\">\n {hook.filteredCommands.map((cmd, index) => (\n <div\n key={cmd.keyword}\n className=\"devic-command-bar-dropdown-item\"\n data-selected={index === hook.selectedCommandIndex}\n onClick={() => hook.selectCommand(cmd)}\n onMouseEnter={() => {/* Could update selectedCommandIndex on hover */}}\n >\n {cmd.icon && (\n <span className=\"devic-command-bar-dropdown-icon\">{cmd.icon}</span>\n )}\n <span className=\"devic-command-bar-dropdown-keyword\">/{cmd.keyword}</span>\n <span className=\"devic-command-bar-dropdown-desc\">{cmd.description}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* History list */}\n {hook.showingHistory && (\n <div className=\"devic-command-bar-dropdown\">\n <div className=\"devic-command-bar-dropdown-header\">\n <span>Command History</span>\n {hook.history.length > 0 && (\n <button\n className=\"devic-command-bar-dropdown-clear\"\n onClick={() => {\n hook.clearHistory();\n hook.setShowingHistory(false);\n }}\n type=\"button\"\n >\n Clear\n </button>\n )}\n </div>\n <div className=\"devic-command-bar-dropdown-list\" style={resultMessageStyle}>\n {hook.history.length === 0 ? (\n <div className=\"devic-command-bar-dropdown-empty\">No history yet</div>\n ) : (\n hook.history.map((item, index) => (\n <div\n key={`${item}-${index}`}\n className=\"devic-command-bar-dropdown-item devic-command-bar-history-item\"\n onClick={() => {\n hook.setShowingHistory(false);\n hook.setInputValue(item);\n hook.focus();\n }}\n >\n <HistoryIcon className=\"devic-command-bar-dropdown-icon\" />\n <span className=\"devic-command-bar-history-text\">{item}</span>\n </div>\n ))\n )}\n </div>\n </div>\n )}\n\n {/* Result card (above bar when completed) */}\n {mergedOptions.showResultCard && hook.result && !hook.showingHistory && !hook.showingCommands && (\n <div className=\"devic-command-bar-result\">\n {/* Tool calls section */}\n {hook.result.toolCalls.length > 0 && (\n <div className=\"devic-command-bar-result-tools\">\n <div\n className=\"devic-command-bar-result-tools-header\"\n data-expanded={toolsExpanded}\n onClick={() => setToolsExpanded(!toolsExpanded)}\n >\n <ChevronIcon className=\"devic-command-bar-result-tools-chevron\" />\n <span>Tool calls</span>\n <span className=\"devic-command-bar-result-tools-count\">\n {hook.result.toolCalls.length}\n </span>\n </div>\n <div\n className=\"devic-command-bar-result-tools-list\"\n data-expanded={toolsExpanded}\n >\n {hook.result.toolCalls.map((tc) => {\n // Check for custom renderer\n const customRenderer = mergedOptions.toolRenderers?.[tc.name];\n if (customRenderer) {\n return (\n <div key={tc.id} className=\"devic-command-bar-result-tool-item devic-command-bar-result-tool-custom\">\n {customRenderer(tc.input, tc.output)}\n </div>\n );\n }\n\n // Use custom icon or default check icon\n const customIcon = mergedOptions.toolIcons?.[tc.name];\n\n return (\n <div key={tc.id} className=\"devic-command-bar-result-tool-item\">\n {customIcon ? (\n <span className=\"devic-command-bar-result-tool-icon\">{customIcon}</span>\n ) : (\n <CheckIcon className=\"devic-command-bar-result-tool-icon\" />\n )}\n <span className=\"devic-command-bar-result-tool-name\">{tc.summary || tc.name}</span>\n </div>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Message section */}\n <div className=\"devic-command-bar-result-message\" style={resultMessageStyle}>\n {hook.result.message.content?.message || (\n <span className=\"devic-command-bar-result-empty\">No response</span>\n )}\n </div>\n\n {/* Feedback actions */}\n <div className=\"devic-cmd-result-actions\">\n <MessageActions\n messageId={hook.result.message.uid}\n messageContent={hook.result.message.content?.message}\n currentFeedback={feedbackState}\n onFeedback={handleFeedback}\n showCopy={true}\n showFeedback={true}\n theme={feedbackTheme}\n />\n </div>\n </div>\n )}\n\n {/* Error display */}\n {hook.error && !hook.isProcessing && (\n <div className=\"devic-command-bar-error\">\n {hook.error.message}\n </div>\n )}\n\n {/* Main bar */}\n <div className=\"devic-command-bar\" style={barStyle}>\n {/* Left: Icon or Loader */}\n <div className=\"devic-command-bar-icon\">\n {hook.isProcessing ? (\n <div className=\"devic-command-bar-spinner\" />\n ) : (\n mergedOptions.icon || <SparklesIcon />\n )}\n </div>\n\n {/* Center: Input or Processing Summary */}\n {hook.isProcessing ? (\n <div className=\"devic-command-bar-summary\">\n {hook.currentToolSummary || mergedOptions.processingMessage}...\n </div>\n ) : (\n <input\n ref={hook.inputRef}\n type=\"text\"\n className=\"devic-command-bar-input\"\n placeholder={mergedOptions.placeholder}\n value={hook.inputValue}\n onChange={(e) => hook.setInputValue(e.target.value)}\n onKeyDown={hook.handleKeyDown}\n />\n )}\n\n {/* Right: Shortcut hint */}\n {mergedOptions.showShortcutHint && mergedOptions.shortcut && !hook.isProcessing && (\n <div className=\"devic-command-bar-shortcut\">\n {formatShortcut(mergedOptions.shortcut)}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\n\n/**\n * Sparkles icon (default)\n */\nfunction SparklesIcon(): JSX.Element {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Main star - 4-point diamond */}\n <path\n d=\"M10 2L11.5 8.5L18 10L11.5 11.5L10 18L8.5 11.5L2 10L8.5 8.5L10 2Z\"\n fill=\"currentColor\"\n opacity=\"0.9\"\n />\n {/* Small accent star - top right */}\n <path\n d=\"M16 3L16.5 5L18.5 5.5L16.5 6L16 8L15.5 6L13.5 5.5L15.5 5L16 3Z\"\n fill=\"currentColor\"\n opacity=\"0.6\"\n />\n {/* Tiny accent dot - bottom left */}\n <circle cx=\"4\" cy=\"15\" r=\"1\" fill=\"currentColor\" opacity=\"0.4\" />\n </svg>\n );\n}\n\n/**\n * Chevron right icon\n */\nfunction ChevronIcon({ className }: { className?: string }): JSX.Element {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n );\n}\n\n/**\n * Check icon\n */\nfunction CheckIcon({ className }: { className?: string }): JSX.Element {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\n/**\n * History icon\n */\nfunction HistoryIcon({ className }: { className?: string }): JSX.Element {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\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=\"M3 3v5h5\" />\n <path d=\"M3.05 13A9 9 0 1 0 6 5.3L3 8\" />\n <path d=\"M12 7v5l4 2\" />\n </svg>\n );\n}\n"],"names":["forwardRef","useMemo","useAICommandBar","useImperativeHandle","useState","useRef","useOptionalDevicContext","useEffect","DevicApiClient","useCallback","_jsxs","_jsx","MessageActions","formatShortcut"],"mappings":"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"}
|