@hsafa/ui-sdk 0.2.5 → 0.3.1
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/index.cjs +35 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +339 -424
- package/dist/index.d.ts +339 -424
- package/dist/index.js +35 -31
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
|
+
import React__default, { ComponentType } from 'react';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Props for the Button component
|
|
7
7
|
*/
|
|
8
|
-
interface ButtonProps extends
|
|
8
|
+
interface ButtonProps extends React__default.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
9
9
|
/** Visual style variant of the button */
|
|
10
10
|
variant?: "primary" | "secondary" | "outline" | "ghost";
|
|
11
11
|
/** Size of the button */
|
|
@@ -13,7 +13,7 @@ interface ButtonProps extends react__default.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
13
13
|
/** Whether the button is in a loading state */
|
|
14
14
|
loading?: boolean;
|
|
15
15
|
/** Content to be displayed inside the button */
|
|
16
|
-
children:
|
|
16
|
+
children: React__default.ReactNode;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* A versatile button component with multiple variants, sizes, and states.
|
|
@@ -33,173 +33,7 @@ interface ButtonProps extends react__default.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
33
33
|
* <Button onClick={() => console.log('Clicked!')}>Click me</Button>
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
|
-
declare const Button:
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Vercel AI SDK compatible message types
|
|
40
|
-
* Based on https://sdk.vercel.ai/docs/ai-sdk-core/messages
|
|
41
|
-
*/
|
|
42
|
-
type TextPart = {
|
|
43
|
-
type: 'text';
|
|
44
|
-
text: string;
|
|
45
|
-
};
|
|
46
|
-
type ImagePart = {
|
|
47
|
-
type: 'image';
|
|
48
|
-
image: string | URL;
|
|
49
|
-
mediaType?: string;
|
|
50
|
-
};
|
|
51
|
-
type FilePart = {
|
|
52
|
-
type: 'file';
|
|
53
|
-
data: string | URL;
|
|
54
|
-
mediaType: string;
|
|
55
|
-
name?: string;
|
|
56
|
-
};
|
|
57
|
-
type UserContentPart = TextPart | ImagePart | FilePart;
|
|
58
|
-
type AssistantTextPart = {
|
|
59
|
-
type: 'text';
|
|
60
|
-
text: string;
|
|
61
|
-
};
|
|
62
|
-
type ReasoningPart = {
|
|
63
|
-
type: 'reasoning';
|
|
64
|
-
text: string;
|
|
65
|
-
};
|
|
66
|
-
type AssistantFilePart = {
|
|
67
|
-
type: 'file';
|
|
68
|
-
data: string | URL;
|
|
69
|
-
mediaType: string;
|
|
70
|
-
filename?: string;
|
|
71
|
-
};
|
|
72
|
-
type ToolCallPart = {
|
|
73
|
-
type: 'tool-call';
|
|
74
|
-
toolCallId: string;
|
|
75
|
-
toolName: string;
|
|
76
|
-
input: any;
|
|
77
|
-
};
|
|
78
|
-
type AssistantContentPart = AssistantTextPart | ReasoningPart | AssistantFilePart | ToolCallPart;
|
|
79
|
-
interface Attachment {
|
|
80
|
-
id: string;
|
|
81
|
-
name: string;
|
|
82
|
-
url: string;
|
|
83
|
-
mimeType: string;
|
|
84
|
-
size: number;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Type definitions for the HsafaChat component
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
type MainAgentAction$1 = {
|
|
92
|
-
type: 'reasoning';
|
|
93
|
-
reasoning: string;
|
|
94
|
-
status: 'streaming' | 'finished';
|
|
95
|
-
startDate?: number;
|
|
96
|
-
endDate?: number;
|
|
97
|
-
durationMs?: number;
|
|
98
|
-
} | {
|
|
99
|
-
type: 'tool-call';
|
|
100
|
-
toolCallId?: string;
|
|
101
|
-
toolName?: string;
|
|
102
|
-
input?: any;
|
|
103
|
-
inputText?: string;
|
|
104
|
-
output?: any;
|
|
105
|
-
status: 'input_streaming' | 'running' | 'finished' | 'error';
|
|
106
|
-
error?: string;
|
|
107
|
-
startDate?: number;
|
|
108
|
-
endDate?: number;
|
|
109
|
-
durationMs?: number;
|
|
110
|
-
} | {
|
|
111
|
-
type: 'step';
|
|
112
|
-
stepNumber?: number;
|
|
113
|
-
finishReason?: string;
|
|
114
|
-
usage?: any;
|
|
115
|
-
startDate?: number;
|
|
116
|
-
endDate?: number;
|
|
117
|
-
durationMs?: number;
|
|
118
|
-
} | {
|
|
119
|
-
type: 'text';
|
|
120
|
-
text: string;
|
|
121
|
-
status: 'streaming' | 'finished';
|
|
122
|
-
startDate?: number;
|
|
123
|
-
endDate?: number;
|
|
124
|
-
durationMs?: number;
|
|
125
|
-
} | {
|
|
126
|
-
type: 'source';
|
|
127
|
-
source: any;
|
|
128
|
-
durationMs?: number;
|
|
129
|
-
} | {
|
|
130
|
-
type: 'file';
|
|
131
|
-
file: any;
|
|
132
|
-
durationMs?: number;
|
|
133
|
-
} | {
|
|
134
|
-
type: 'response';
|
|
135
|
-
items: any[];
|
|
136
|
-
[key: string]: any;
|
|
137
|
-
startDate?: number;
|
|
138
|
-
endDate?: number;
|
|
139
|
-
durationMs?: number;
|
|
140
|
-
};
|
|
141
|
-
type ChatMessage = {
|
|
142
|
-
id: string;
|
|
143
|
-
role: 'user';
|
|
144
|
-
content: string | UserContentPart[];
|
|
145
|
-
createdAt?: number;
|
|
146
|
-
text?: string;
|
|
147
|
-
attachments?: Attachment[];
|
|
148
|
-
} | {
|
|
149
|
-
id: string;
|
|
150
|
-
role: 'assistant';
|
|
151
|
-
content?: string | AssistantContentPart[];
|
|
152
|
-
items: any[];
|
|
153
|
-
reasoning?: string;
|
|
154
|
-
reasoningOpen?: boolean;
|
|
155
|
-
reasoningTokens?: number;
|
|
156
|
-
createdAt?: number;
|
|
157
|
-
requestParams?: any;
|
|
158
|
-
mcpToolCalls?: Array<{
|
|
159
|
-
toolName: string;
|
|
160
|
-
args: any;
|
|
161
|
-
timestamp: number;
|
|
162
|
-
status?: 'pending' | 'running' | 'completed' | 'failed';
|
|
163
|
-
}>;
|
|
164
|
-
mcpToolResults?: Record<string, any>;
|
|
165
|
-
mainAgentActions?: MainAgentAction$1[];
|
|
166
|
-
firstAgentMessage?: string;
|
|
167
|
-
firstAgentContinue?: boolean;
|
|
168
|
-
autoGenerated?: boolean;
|
|
169
|
-
hidden?: boolean;
|
|
170
|
-
turnIndex?: number;
|
|
171
|
-
controlDecision?: 'continue' | 'done';
|
|
172
|
-
followUpPrompt?: string;
|
|
173
|
-
};
|
|
174
|
-
interface HsafaChatProps {
|
|
175
|
-
agentId: string;
|
|
176
|
-
theme?: 'dark' | 'light';
|
|
177
|
-
primaryColor?: string;
|
|
178
|
-
backgroundColor?: string;
|
|
179
|
-
borderColor?: string;
|
|
180
|
-
textColor?: string;
|
|
181
|
-
accentColor?: string;
|
|
182
|
-
width?: number | string;
|
|
183
|
-
maxWidth?: number | string;
|
|
184
|
-
height?: string;
|
|
185
|
-
expandable?: boolean;
|
|
186
|
-
alwaysOpen?: boolean;
|
|
187
|
-
defaultOpen?: boolean;
|
|
188
|
-
floatingButtonPosition?: {
|
|
189
|
-
bottom?: number | string;
|
|
190
|
-
right?: number | string;
|
|
191
|
-
top?: number | string;
|
|
192
|
-
left?: number | string;
|
|
193
|
-
};
|
|
194
|
-
placeholder?: string;
|
|
195
|
-
title?: string;
|
|
196
|
-
className?: string;
|
|
197
|
-
chatContainerClassName?: string;
|
|
198
|
-
dir?: 'rtl' | 'ltr';
|
|
199
|
-
language?: 'en' | 'ar';
|
|
200
|
-
defaultReasoningOpen?: boolean;
|
|
201
|
-
hideReasoningContent?: boolean;
|
|
202
|
-
}
|
|
36
|
+
declare const Button: React__default.FC<ButtonProps>;
|
|
203
37
|
|
|
204
38
|
declare const themeColors: {
|
|
205
39
|
dark: {
|
|
@@ -227,57 +61,6 @@ declare const themeColors: {
|
|
|
227
61
|
};
|
|
228
62
|
type ThemeColors = typeof themeColors.dark;
|
|
229
63
|
|
|
230
|
-
type TranslationKeys = {
|
|
231
|
-
'header.maximize': string;
|
|
232
|
-
'header.minimize': string;
|
|
233
|
-
'header.new': string;
|
|
234
|
-
'header.history': string;
|
|
235
|
-
'header.close': string;
|
|
236
|
-
'input.placeholder': string;
|
|
237
|
-
'input.attachFiles': string;
|
|
238
|
-
'input.insertLink': string;
|
|
239
|
-
'input.send': string;
|
|
240
|
-
'input.stop': string;
|
|
241
|
-
'input.uploadingFiles': string;
|
|
242
|
-
'input.previewImage': string;
|
|
243
|
-
'input.removeFile': string;
|
|
244
|
-
'editor.cancel': string;
|
|
245
|
-
'editor.saveAndRegenerate': string;
|
|
246
|
-
'editor.clickToEdit': string;
|
|
247
|
-
'messages.empty': string;
|
|
248
|
-
'messages.error': string;
|
|
249
|
-
'history.search': string;
|
|
250
|
-
'history.noChatsFound': string;
|
|
251
|
-
'history.untitledChat': string;
|
|
252
|
-
'history.deleteChat': string;
|
|
253
|
-
'general.agent': string;
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
interface MessageListProps {
|
|
257
|
-
messages: ChatMessage[];
|
|
258
|
-
streaming: boolean;
|
|
259
|
-
editingMessageId: string | null;
|
|
260
|
-
editingMessageText: string;
|
|
261
|
-
editingAttachments?: Attachment[];
|
|
262
|
-
error: string | null;
|
|
263
|
-
actionStatuses: Map<string, 'executing' | 'executed'>;
|
|
264
|
-
components: Map<string, react__default.ComponentType<any>>;
|
|
265
|
-
theme: 'light' | 'dark';
|
|
266
|
-
resolvedColors: ThemeColors;
|
|
267
|
-
onEditingTextChange: (text: string) => void;
|
|
268
|
-
onRemoveAttachment?: (id: string) => void;
|
|
269
|
-
onAddAttachments?: (files: FileList) => void;
|
|
270
|
-
uploading?: boolean;
|
|
271
|
-
onStartEdit: (messageId: string, text: string) => void;
|
|
272
|
-
onCancelEdit: () => void;
|
|
273
|
-
onSaveEdit: (messageId: string, text: string) => void;
|
|
274
|
-
onToggleReasoning: (messageId: string) => void;
|
|
275
|
-
scrollAnchorRef: react__default.RefObject<HTMLDivElement>;
|
|
276
|
-
hideReasoningContent?: boolean;
|
|
277
|
-
t: (key: keyof TranslationKeys) => string;
|
|
278
|
-
}
|
|
279
|
-
declare function MessageList({ messages, streaming, editingMessageId, editingMessageText, editingAttachments, error, actionStatuses, components, theme, resolvedColors, onEditingTextChange, onRemoveAttachment, onAddAttachments, uploading, onStartEdit, onCancelEdit, onSaveEdit, onToggleReasoning, scrollAnchorRef, hideReasoningContent, t }: MessageListProps): react_jsx_runtime.JSX.Element;
|
|
280
|
-
|
|
281
64
|
interface FloatingChatButtonProps {
|
|
282
65
|
show: boolean;
|
|
283
66
|
onClick: () => void;
|
|
@@ -291,26 +74,67 @@ interface FloatingChatButtonProps {
|
|
|
291
74
|
}
|
|
292
75
|
declare function FloatingChatButton({ show, onClick, resolvedColors, floatingButtonPosition }: FloatingChatButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
293
76
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
on: boolean;
|
|
297
|
-
/** Toggle the state */
|
|
298
|
-
toggle: () => void;
|
|
299
|
-
/** Set the state directly */
|
|
300
|
-
setOn: (value: boolean | ((prev: boolean) => boolean)) => void;
|
|
301
|
-
/** Set state to true */
|
|
302
|
-
setTrue: () => void;
|
|
303
|
-
/** Set state to false */
|
|
304
|
-
setFalse: () => void;
|
|
305
|
-
}
|
|
77
|
+
declare function useAutoScroll<T extends HTMLElement>(shouldScroll?: boolean): React$1.MutableRefObject<T | null>;
|
|
78
|
+
|
|
306
79
|
/**
|
|
307
|
-
*
|
|
308
|
-
* @param initial - Initial state value (default: false)
|
|
309
|
-
* @returns Object with toggle state and control functions
|
|
80
|
+
* Type definitions for the Hsafa SDK - minimal exports used across the SDK
|
|
310
81
|
*/
|
|
311
|
-
|
|
82
|
+
type Attachment = {
|
|
83
|
+
id: string;
|
|
84
|
+
name?: string;
|
|
85
|
+
url: string;
|
|
86
|
+
mimeType?: string;
|
|
87
|
+
size?: number;
|
|
88
|
+
};
|
|
89
|
+
type HsafaTool = ((input: any) => any | Promise<any>) | {
|
|
90
|
+
tool: (input: any) => any | Promise<any>;
|
|
91
|
+
executeEachToken?: boolean;
|
|
92
|
+
};
|
|
93
|
+
interface HsafaChatProps {
|
|
94
|
+
agentId: string;
|
|
95
|
+
theme?: 'dark' | 'light';
|
|
96
|
+
primaryColor?: string;
|
|
97
|
+
primaryColorDark?: string;
|
|
98
|
+
primaryColorLight?: string;
|
|
99
|
+
backgroundColor?: string;
|
|
100
|
+
borderColor?: string;
|
|
101
|
+
textColor?: string;
|
|
102
|
+
accentColor?: string;
|
|
103
|
+
width?: number | string;
|
|
104
|
+
maxWidth?: number | string;
|
|
105
|
+
height?: string;
|
|
106
|
+
expandable?: boolean;
|
|
107
|
+
alwaysOpen?: boolean;
|
|
108
|
+
defaultOpen?: boolean;
|
|
109
|
+
floatingButtonPosition?: {
|
|
110
|
+
bottom?: number | string;
|
|
111
|
+
right?: number | string;
|
|
112
|
+
top?: number | string;
|
|
113
|
+
left?: number | string;
|
|
114
|
+
};
|
|
115
|
+
placeholder?: string;
|
|
116
|
+
title?: string;
|
|
117
|
+
className?: string;
|
|
118
|
+
chatContainerClassName?: string;
|
|
119
|
+
dir?: 'rtl' | 'ltr';
|
|
120
|
+
language?: 'en' | 'ar';
|
|
121
|
+
defaultReasoningOpen?: boolean;
|
|
122
|
+
hideReasoningContent?: boolean;
|
|
123
|
+
UIComponents?: Record<string, React.ComponentType<any>>;
|
|
124
|
+
HsafaTools?: Record<string, HsafaTool>;
|
|
125
|
+
}
|
|
312
126
|
|
|
313
|
-
declare function
|
|
127
|
+
declare function useFileUpload(baseUrl: string): {
|
|
128
|
+
attachments: Attachment[];
|
|
129
|
+
uploading: boolean;
|
|
130
|
+
fileInputRef: React$1.MutableRefObject<HTMLInputElement | null>;
|
|
131
|
+
formatBytes: (bytes: number) => string;
|
|
132
|
+
handleRemoveAttachment: (id: string) => void;
|
|
133
|
+
handleFileSelection: (fileList: FileList | File[] | null, setError: (error: string | null) => void) => Promise<void>;
|
|
134
|
+
buildUserContent: (text: string, attachments: Attachment[]) => any[];
|
|
135
|
+
clearAttachments: () => void;
|
|
136
|
+
MAX_UPLOAD_SIZE: number;
|
|
137
|
+
};
|
|
314
138
|
|
|
315
139
|
/**
|
|
316
140
|
* Handler function for custom actions that can be triggered by the AI agent
|
|
@@ -333,6 +157,10 @@ type HsafaActionHandler = (params: any, meta: {
|
|
|
333
157
|
interface HsafaConfig {
|
|
334
158
|
/** Base URL for agent API calls, e.g. "" (same origin) or "https://example.com" */
|
|
335
159
|
baseUrl?: string;
|
|
160
|
+
/** Default text direction for SDK components */
|
|
161
|
+
dir?: 'ltr' | 'rtl';
|
|
162
|
+
/** Default theme for SDK components */
|
|
163
|
+
theme?: 'dark' | 'light';
|
|
336
164
|
}
|
|
337
165
|
/**
|
|
338
166
|
* Context value provided by HsafaProvider
|
|
@@ -341,15 +169,15 @@ interface HsafaContextValue extends HsafaConfig {
|
|
|
341
169
|
/** Registered custom actions */
|
|
342
170
|
actions: Map<string, HsafaActionHandler>;
|
|
343
171
|
/** Registered custom components */
|
|
344
|
-
components: Map<string,
|
|
172
|
+
components: Map<string, React__default.ComponentType<any>>;
|
|
345
173
|
/** Register a custom action handler */
|
|
346
174
|
registerAction: (name: string, handler: HsafaActionHandler) => () => void;
|
|
347
175
|
/** Unregister a custom action handler */
|
|
348
176
|
unregisterAction: (name: string, handler?: HsafaActionHandler) => void;
|
|
349
177
|
/** Register a custom component */
|
|
350
|
-
registerComponent: (name: string, component:
|
|
178
|
+
registerComponent: (name: string, component: React__default.ComponentType<any>) => () => void;
|
|
351
179
|
/** Unregister a custom component */
|
|
352
|
-
unregisterComponent: (name: string, component?:
|
|
180
|
+
unregisterComponent: (name: string, component?: React__default.ComponentType<any>) => void;
|
|
353
181
|
/** Global streaming state - true if any chat is streaming */
|
|
354
182
|
isAnyStreaming: boolean;
|
|
355
183
|
/** Set streaming state for a specific chat instance */
|
|
@@ -364,7 +192,7 @@ interface HsafaContextValue extends HsafaConfig {
|
|
|
364
192
|
*/
|
|
365
193
|
interface HsafaProviderProps extends HsafaConfig {
|
|
366
194
|
/** Child components that will have access to the Hsafa context */
|
|
367
|
-
children:
|
|
195
|
+
children: React__default.ReactNode;
|
|
368
196
|
}
|
|
369
197
|
/**
|
|
370
198
|
* Provider component that sets up the Hsafa context for the SDK.
|
|
@@ -377,7 +205,7 @@ interface HsafaProviderProps extends HsafaConfig {
|
|
|
377
205
|
* </HsafaProvider>
|
|
378
206
|
* ```
|
|
379
207
|
*/
|
|
380
|
-
declare function HsafaProvider({ baseUrl, children }: HsafaProviderProps): react_jsx_runtime.JSX.Element;
|
|
208
|
+
declare function HsafaProvider({ baseUrl, dir, theme, children }: HsafaProviderProps): react_jsx_runtime.JSX.Element;
|
|
381
209
|
/**
|
|
382
210
|
* Hook to access the Hsafa context.
|
|
383
211
|
* Must be used within a HsafaProvider.
|
|
@@ -404,187 +232,14 @@ declare function HsafaProvider({ baseUrl, children }: HsafaProviderProps): react
|
|
|
404
232
|
*/
|
|
405
233
|
declare function useHsafa(): HsafaContextValue;
|
|
406
234
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
* @param handler - Function to execute when action is triggered
|
|
413
|
-
*
|
|
414
|
-
* @example
|
|
415
|
-
* ```tsx
|
|
416
|
-
* useHsafaAction('submitForm', async (params, meta) => {
|
|
417
|
-
* console.log('Form submitted:', params);
|
|
418
|
-
* return { success: true };
|
|
419
|
-
* });
|
|
420
|
-
* ```
|
|
421
|
-
*/
|
|
422
|
-
declare function useHsafaAction(name: string, handler: HsafaActionHandler): void;
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Register a UI component by name within the nearest HsafaProvider.
|
|
426
|
-
* The component will be automatically unregistered on unmount.
|
|
427
|
-
*
|
|
428
|
-
* @param name - Unique name for the component (matches agent's component field)
|
|
429
|
-
* @param component - React component to render when agent requests this component
|
|
430
|
-
*
|
|
431
|
-
* @example
|
|
432
|
-
* ```tsx
|
|
433
|
-
* function ProductCard({ name, price }: { name: string; price: number }) {
|
|
434
|
-
* return <div>{name}: ${price}</div>;
|
|
435
|
-
* }
|
|
436
|
-
*
|
|
437
|
-
* useHsafaComponent('ProductCard', ProductCard);
|
|
438
|
-
* ```
|
|
439
|
-
*/
|
|
440
|
-
declare function useHsafaComponent<T = any>(name: string, component: ComponentType<T>): void;
|
|
441
|
-
|
|
442
|
-
interface ChatMeta {
|
|
443
|
-
id: string;
|
|
444
|
-
title: string;
|
|
445
|
-
createdAt: number;
|
|
446
|
-
updatedAt: number;
|
|
447
|
-
}
|
|
448
|
-
interface ChatData {
|
|
449
|
-
id: string;
|
|
450
|
-
messages: ChatMessage[];
|
|
451
|
-
agentId?: string;
|
|
452
|
-
}
|
|
453
|
-
declare function useChatStorage(agentId: string): {
|
|
454
|
-
currentChatId: string | null;
|
|
455
|
-
setCurrentChatId: react.Dispatch<react.SetStateAction<string | null>>;
|
|
456
|
-
hasChatRecordRef: react.MutableRefObject<boolean>;
|
|
457
|
-
pendingFirstTitleRef: react.MutableRefObject<string | null>;
|
|
458
|
-
loadChatsIndex: () => ChatMeta[];
|
|
459
|
-
loadChat: (id: string) => ChatData | null;
|
|
460
|
-
saveChat: (data: ChatData) => void;
|
|
461
|
-
deleteChat: (id: string, onChatDeleted?: (wasCurrentChat: boolean) => void) => void;
|
|
462
|
-
loadChatPreferences: () => ChatMessage[];
|
|
463
|
-
persistChatData: (messages: ChatMessage[]) => void;
|
|
464
|
-
createNewChat: (firstMessage?: string) => string;
|
|
465
|
-
upsertChatMeta: (meta: ChatMeta) => void;
|
|
466
|
-
showChatKey: string;
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
declare function useStreaming(): {
|
|
470
|
-
streaming: boolean;
|
|
471
|
-
setStreaming: react.Dispatch<react.SetStateAction<boolean>>;
|
|
472
|
-
error: string | null;
|
|
473
|
-
setError: react.Dispatch<react.SetStateAction<string | null>>;
|
|
474
|
-
actionStatuses: Map<string, "executing" | "executed">;
|
|
475
|
-
setActionStatuses: react.Dispatch<react.SetStateAction<Map<string, "executing" | "executed">>>;
|
|
476
|
-
abortControllerRef: react.MutableRefObject<AbortController | null>;
|
|
477
|
-
actionExecMapRef: react.MutableRefObject<Record<string, boolean>>;
|
|
478
|
-
assistantMsgIdRef: react.MutableRefObject<string | undefined>;
|
|
479
|
-
calledFinalActionsRef: react.MutableRefObject<Set<string>>;
|
|
480
|
-
actionParamsHistoryRef: react.MutableRefObject<Map<string, any[]>>;
|
|
481
|
-
actionExecutionStatusRef: react.MutableRefObject<Map<string, "executing" | "executed">>;
|
|
482
|
-
processActions: (items: any[] | undefined, trigger: "partial" | "final", actions: Map<string, any>, currentChatId: string | null) => void;
|
|
483
|
-
handleStop: () => void;
|
|
484
|
-
resetActionTracking: () => void;
|
|
485
|
-
cleanupTimeouts: () => void;
|
|
486
|
-
hasActionParamsStabilized: (actionKey: string, currentParams: any) => boolean;
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
declare function useFileUpload(baseUrl: string): {
|
|
490
|
-
attachments: Attachment[];
|
|
491
|
-
uploading: boolean;
|
|
492
|
-
fileInputRef: react.MutableRefObject<HTMLInputElement | null>;
|
|
493
|
-
formatBytes: (bytes: number) => string;
|
|
494
|
-
handleRemoveAttachment: (id: string) => void;
|
|
495
|
-
handleFileSelection: (fileList: FileList | File[] | null, setError: (error: string | null) => void) => Promise<void>;
|
|
496
|
-
buildUserContent: (text: string, attachments: Attachment[]) => any[];
|
|
497
|
-
clearAttachments: () => void;
|
|
498
|
-
MAX_UPLOAD_SIZE: number;
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Types matching the structure from getAgentStreamingResponse
|
|
503
|
-
*/
|
|
504
|
-
type FirstAgentData = {
|
|
505
|
-
message: string;
|
|
506
|
-
continue: boolean;
|
|
507
|
-
startDate?: number;
|
|
508
|
-
endDate?: number;
|
|
509
|
-
durationMs?: number;
|
|
510
|
-
};
|
|
511
|
-
type MainAgentAction = {
|
|
512
|
-
type: 'reasoning';
|
|
513
|
-
reasoning: string;
|
|
514
|
-
status: 'streaming' | 'finished';
|
|
515
|
-
startDate?: number;
|
|
516
|
-
endDate?: number;
|
|
517
|
-
durationMs?: number;
|
|
518
|
-
} | {
|
|
519
|
-
type: 'tool-call';
|
|
520
|
-
toolCallId?: string;
|
|
521
|
-
toolName?: string;
|
|
522
|
-
input?: any;
|
|
523
|
-
inputText?: string;
|
|
524
|
-
output?: any;
|
|
525
|
-
status: 'input_streaming' | 'running' | 'finished' | 'error';
|
|
526
|
-
error?: string;
|
|
527
|
-
startDate?: number;
|
|
528
|
-
endDate?: number;
|
|
529
|
-
durationMs?: number;
|
|
530
|
-
} | {
|
|
531
|
-
type: 'step';
|
|
532
|
-
stepNumber?: number;
|
|
533
|
-
finishReason?: string;
|
|
534
|
-
usage?: any;
|
|
535
|
-
startDate?: number;
|
|
536
|
-
endDate?: number;
|
|
537
|
-
durationMs?: number;
|
|
538
|
-
} | {
|
|
539
|
-
type: 'text';
|
|
540
|
-
text: string;
|
|
541
|
-
status: 'streaming' | 'finished';
|
|
542
|
-
startDate?: number;
|
|
543
|
-
endDate?: number;
|
|
544
|
-
durationMs?: number;
|
|
545
|
-
} | {
|
|
546
|
-
type: 'source';
|
|
547
|
-
source: any;
|
|
548
|
-
durationMs?: number;
|
|
549
|
-
} | {
|
|
550
|
-
type: 'file';
|
|
551
|
-
file: any;
|
|
552
|
-
durationMs?: number;
|
|
553
|
-
} | {
|
|
554
|
-
type: 'response';
|
|
555
|
-
items: any[];
|
|
556
|
-
[key: string]: any;
|
|
557
|
-
startDate?: number;
|
|
558
|
-
endDate?: number;
|
|
559
|
-
durationMs?: number;
|
|
560
|
-
};
|
|
561
|
-
type AgentStreamData = {
|
|
562
|
-
first_agent: FirstAgentData;
|
|
563
|
-
main_agent: MainAgentAction[];
|
|
564
|
-
};
|
|
565
|
-
/**
|
|
566
|
-
* Hook to handle agent streaming responses
|
|
567
|
-
* Returns streaming state and a function to start streaming
|
|
568
|
-
*/
|
|
569
|
-
declare function useAgentStreaming(): {
|
|
570
|
-
streaming: boolean;
|
|
571
|
-
error: string | null;
|
|
572
|
-
streamData: AgentStreamData | null;
|
|
573
|
-
startStreaming: ({ agentId, body, baseUrl, onUpdate, signal, }: {
|
|
574
|
-
agentId: string;
|
|
575
|
-
body: any;
|
|
576
|
-
baseUrl?: string;
|
|
577
|
-
onUpdate?: (data: AgentStreamData) => void;
|
|
578
|
-
signal?: AbortSignal;
|
|
579
|
-
}) => Promise<AgentStreamData | null>;
|
|
580
|
-
stopStreaming: () => void;
|
|
581
|
-
reset: () => void;
|
|
582
|
-
};
|
|
583
|
-
|
|
584
|
-
declare function HsafaChat(props: HsafaChatProps): react__default.ReactPortal | null;
|
|
235
|
+
declare function HsafaChat({ agentId, theme, primaryColor, primaryColorDark, primaryColorLight, backgroundColor, borderColor, textColor, accentColor, baseUrl, initialMessages, onMessagesChange, defaultOpen, floatingButtonPosition, UIComponents, HsafaTools, }: HsafaChatProps & {
|
|
236
|
+
baseUrl?: string;
|
|
237
|
+
initialMessages?: any[];
|
|
238
|
+
onMessagesChange?: (messages: any[]) => void;
|
|
239
|
+
}): react_jsx_runtime.JSX.Element;
|
|
585
240
|
|
|
586
241
|
interface ContentContainerProps {
|
|
587
|
-
children:
|
|
242
|
+
children: React__default.ReactNode;
|
|
588
243
|
theme?: "dark" | "light";
|
|
589
244
|
primaryColor?: string;
|
|
590
245
|
backgroundColor?: string;
|
|
@@ -642,4 +297,264 @@ interface ContentContainerProps {
|
|
|
642
297
|
*/
|
|
643
298
|
declare function ContentContainer({ children, theme, primaryColor, backgroundColor, borderColor, textColor, mutedTextColor, enableBorderAnimation, borderRadius, enableContentBorder, className, enableMargin, chatWidth, dir, }: ContentContainerProps): react_jsx_runtime.JSX.Element;
|
|
644
299
|
|
|
645
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Component Registry for custom UI components
|
|
302
|
+
* Allows users to register their own React components to be rendered in chat responses
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
interface UIComponentProps {
|
|
306
|
+
props: any;
|
|
307
|
+
resolvedColors?: any;
|
|
308
|
+
}
|
|
309
|
+
declare class ComponentRegistry {
|
|
310
|
+
private components;
|
|
311
|
+
/**
|
|
312
|
+
* Register a custom UI component
|
|
313
|
+
* @param name - The component name (should match the 'component' field from the agent response)
|
|
314
|
+
* @param component - The React component to render
|
|
315
|
+
*/
|
|
316
|
+
register(name: string, component: ComponentType<UIComponentProps>): void;
|
|
317
|
+
/**
|
|
318
|
+
* Unregister a component
|
|
319
|
+
* @param name - The component name to remove
|
|
320
|
+
*/
|
|
321
|
+
unregister(name: string): void;
|
|
322
|
+
/**
|
|
323
|
+
* Get a registered component
|
|
324
|
+
* @param name - The component name
|
|
325
|
+
* @returns The component or undefined if not found
|
|
326
|
+
*/
|
|
327
|
+
get(name: string): ComponentType<UIComponentProps> | undefined;
|
|
328
|
+
/**
|
|
329
|
+
* Check if a component is registered
|
|
330
|
+
* @param name - The component name
|
|
331
|
+
*/
|
|
332
|
+
has(name: string): boolean;
|
|
333
|
+
/**
|
|
334
|
+
* Clear all registered components
|
|
335
|
+
*/
|
|
336
|
+
clear(): void;
|
|
337
|
+
/**
|
|
338
|
+
* Get all registered component names
|
|
339
|
+
*/
|
|
340
|
+
getRegisteredNames(): string[];
|
|
341
|
+
}
|
|
342
|
+
declare const registry: ComponentRegistry;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* getDomComponents - Scan and analyze all interactive DOM elements inside ContentContainer
|
|
346
|
+
*
|
|
347
|
+
* Returns a structured list of all inputs, buttons, links, and interactive elements
|
|
348
|
+
* that the agent can interact with using the web controller tools.
|
|
349
|
+
*/
|
|
350
|
+
interface DomComponent {
|
|
351
|
+
id: string | null;
|
|
352
|
+
tag: string;
|
|
353
|
+
type?: string;
|
|
354
|
+
name?: string;
|
|
355
|
+
label?: string;
|
|
356
|
+
placeholder?: string;
|
|
357
|
+
value?: string | boolean | string[];
|
|
358
|
+
options?: Array<{
|
|
359
|
+
value: string;
|
|
360
|
+
label: string;
|
|
361
|
+
selected: boolean;
|
|
362
|
+
disabled: boolean;
|
|
363
|
+
}>;
|
|
364
|
+
checked?: boolean;
|
|
365
|
+
disabled?: boolean;
|
|
366
|
+
required?: boolean;
|
|
367
|
+
className?: string;
|
|
368
|
+
text?: string;
|
|
369
|
+
href?: string;
|
|
370
|
+
role?: string;
|
|
371
|
+
ariaLabel?: string;
|
|
372
|
+
selector?: string;
|
|
373
|
+
isVisible: boolean;
|
|
374
|
+
isInteractive: boolean;
|
|
375
|
+
}
|
|
376
|
+
interface GetDomComponentsOptions {
|
|
377
|
+
includeHidden?: boolean;
|
|
378
|
+
selector?: string;
|
|
379
|
+
what?: 'inputs' | 'content';
|
|
380
|
+
limit?: number;
|
|
381
|
+
}
|
|
382
|
+
interface GetDomComponentsResult {
|
|
383
|
+
ok: boolean;
|
|
384
|
+
components: DomComponent[];
|
|
385
|
+
count: number;
|
|
386
|
+
total: number;
|
|
387
|
+
truncated?: boolean;
|
|
388
|
+
containerFound: boolean;
|
|
389
|
+
error?: string;
|
|
390
|
+
}
|
|
391
|
+
declare function getDomComponents(options?: GetDomComponentsOptions): Promise<GetDomComponentsResult>;
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* CursorController
|
|
395
|
+
*
|
|
396
|
+
* Mount this component once on a page (e.g. in the demo at `/demo`). It registers a
|
|
397
|
+
* global function `window.__cursorGuide(stepsOrTarget, options?)` that moves a fake
|
|
398
|
+
* cursor to a target and optionally performs actions (click, drag).
|
|
399
|
+
*
|
|
400
|
+
* In `app/demo/page.tsx`, a convenience wrapper `guideCursorTo(targetOrSteps, options?)`
|
|
401
|
+
* is also exported and exposed globally as `window.guideCursorTo`.
|
|
402
|
+
*
|
|
403
|
+
* Quick examples (run in DevTools on /demo):
|
|
404
|
+
* ```js
|
|
405
|
+
* // Move to a screen position
|
|
406
|
+
* await window.guideCursorTo({ position: { x: 140, y: 160 } }, { durationMs: 700 });
|
|
407
|
+
*
|
|
408
|
+
* // Click an element by selector or id
|
|
409
|
+
* await window.guideCursorTo('#submitBtn', { action: 'click', anchor: 'center' });
|
|
410
|
+
*
|
|
411
|
+
* // Drag from one element to another
|
|
412
|
+
* await window.guideCursorTo({ selector: '#cardBacklog0' }, { action: 'drag', dragTo: '#doingDrop' });
|
|
413
|
+
*
|
|
414
|
+
* // Multi-step sequence
|
|
415
|
+
* await window.guideCursorTo([
|
|
416
|
+
* { target: '#tabStats', action: 'click', options: { durationMs: 600 } },
|
|
417
|
+
* { target: { position: { x: 100, y: 120 } } },
|
|
418
|
+
* { target: '#progressStartBtn', action: 'click' },
|
|
419
|
+
* ]);
|
|
420
|
+
* ```
|
|
421
|
+
*
|
|
422
|
+
* Options highlights (see `GuideOptions`):
|
|
423
|
+
* - action: 'none' | 'click' | 'drag'
|
|
424
|
+
* - durationMs, easing: control motion speed/curve
|
|
425
|
+
* - path: 'straight' | 'curve', curveStrength, curveDirection
|
|
426
|
+
* - anchor: where inside the element to aim (e.g. 'center', 'top-left' or {x:0..1,y:0..1})
|
|
427
|
+
* - cursorHotspot: px offset to the click location
|
|
428
|
+
* - dragTo: target for drag action
|
|
429
|
+
*/
|
|
430
|
+
type GuideAction = "none" | "click" | "drag";
|
|
431
|
+
type GuideTarget = string | Element | {
|
|
432
|
+
selector: string;
|
|
433
|
+
nth?: number;
|
|
434
|
+
within?: Element | string;
|
|
435
|
+
} | {
|
|
436
|
+
position: {
|
|
437
|
+
x: number;
|
|
438
|
+
y: number;
|
|
439
|
+
};
|
|
440
|
+
};
|
|
441
|
+
type Anchor = "center" | "top-left" | "bottom-right" | {
|
|
442
|
+
x: number;
|
|
443
|
+
y: number;
|
|
444
|
+
};
|
|
445
|
+
type GuideOptions = {
|
|
446
|
+
action?: GuideAction;
|
|
447
|
+
durationMs?: number;
|
|
448
|
+
easing?: "ease" | "ease-in" | "ease-out" | "ease-in-out" | "linear";
|
|
449
|
+
offset?: {
|
|
450
|
+
x?: number;
|
|
451
|
+
y?: number;
|
|
452
|
+
};
|
|
453
|
+
highlight?: boolean;
|
|
454
|
+
path?: "straight" | "curve";
|
|
455
|
+
curveStrength?: number;
|
|
456
|
+
curveDirection?: "auto" | "left" | "right";
|
|
457
|
+
anchor?: Anchor;
|
|
458
|
+
cursorHotspot?: {
|
|
459
|
+
x?: number;
|
|
460
|
+
y?: number;
|
|
461
|
+
};
|
|
462
|
+
dragTo?: GuideTarget;
|
|
463
|
+
};
|
|
464
|
+
type GuideStep = {
|
|
465
|
+
target: GuideTarget;
|
|
466
|
+
action?: GuideAction;
|
|
467
|
+
options?: GuideOptions;
|
|
468
|
+
};
|
|
469
|
+
type GuideStepResult = {
|
|
470
|
+
ok: boolean;
|
|
471
|
+
action: GuideAction;
|
|
472
|
+
targetKind: "element" | "position";
|
|
473
|
+
durationMs: number;
|
|
474
|
+
clickedElementId?: string | null;
|
|
475
|
+
error?: string;
|
|
476
|
+
};
|
|
477
|
+
type GuideRunResult = {
|
|
478
|
+
ok: boolean;
|
|
479
|
+
steps: GuideStepResult[];
|
|
480
|
+
};
|
|
481
|
+
declare function CursorController(): null;
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* guideCursor - Wrapper for window.__cursorGuide
|
|
485
|
+
*
|
|
486
|
+
* Move the visual cursor to elements and perform click/drag actions.
|
|
487
|
+
* Requires CursorController component to be mounted on the page.
|
|
488
|
+
*/
|
|
489
|
+
|
|
490
|
+
interface GuideCursorOptions extends GuideOptions {
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Guide the cursor to a target element or position
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* // Move to an element and click it
|
|
498
|
+
* await guideCursor('#submitBtn', { action: 'click' });
|
|
499
|
+
*
|
|
500
|
+
* // Move to a position
|
|
501
|
+
* await guideCursor({ position: { x: 100, y: 200 } });
|
|
502
|
+
*
|
|
503
|
+
* // Drag from one element to another
|
|
504
|
+
* await guideCursor('#item1', { action: 'drag', dragTo: '#dropzone' });
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
declare function guideCursor(target: GuideTarget, options?: GuideCursorOptions): Promise<GuideRunResult>;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* FillInput utilities
|
|
511
|
+
*
|
|
512
|
+
* Exports two helpers for programmatically filling inputs while dispatching the
|
|
513
|
+
* same DOM events a user would normally trigger (input/change/click):
|
|
514
|
+
*
|
|
515
|
+
* - FillInput(inputId, value, options?)
|
|
516
|
+
* Fill a single field by its element id with the provided value.
|
|
517
|
+
*
|
|
518
|
+
* - FillActiveInput(value, options?)
|
|
519
|
+
* Fill the currently focused field without needing its id.
|
|
520
|
+
*
|
|
521
|
+
* Basic example:
|
|
522
|
+
* ```ts
|
|
523
|
+
* import { FillInput, FillActiveInput } from "./FillInput";
|
|
524
|
+
*
|
|
525
|
+
* // Fill individual fields by id
|
|
526
|
+
* await FillInput("fi_name", "Jane Doe");
|
|
527
|
+
* await FillInput("fi_email", "jane@example.com");
|
|
528
|
+
* await FillInput("fi_role_admin", true); // radio -> check this option
|
|
529
|
+
* await FillInput("fi_country2", "sa"); // select value
|
|
530
|
+
* await FillInput("fi_tags", ["a", "c"]); // multi-select values
|
|
531
|
+
* await FillInput("fi_newsletter", true); // checkbox
|
|
532
|
+
* await FillInput("fi_dob", "1995-05-15"); // date input
|
|
533
|
+
* await FillInput("about", "Hello there"); // contenteditable by id
|
|
534
|
+
*
|
|
535
|
+
* // Fill the currently focused field
|
|
536
|
+
* (document.getElementById("fi_name") as HTMLElement)?.focus();
|
|
537
|
+
* await FillActiveInput("Alice");
|
|
538
|
+
* ```
|
|
539
|
+
*
|
|
540
|
+
* Notes:
|
|
541
|
+
* - Scrolling is disabled; these helpers will not scroll the page.
|
|
542
|
+
* - typingDelayMs is ignored; filling is instantaneous.
|
|
543
|
+
* - For file inputs, pass a File or File[]; browsers may restrict programmatic assignment.
|
|
544
|
+
*/
|
|
545
|
+
type FillInputOptions = {
|
|
546
|
+
typingDelayMs?: number;
|
|
547
|
+
scrollIntoView?: boolean;
|
|
548
|
+
};
|
|
549
|
+
type FillResult = {
|
|
550
|
+
ok: boolean;
|
|
551
|
+
filled: Array<{
|
|
552
|
+
key: string;
|
|
553
|
+
status: "ok" | "skipped" | "error";
|
|
554
|
+
message?: string;
|
|
555
|
+
}>;
|
|
556
|
+
errors?: string[];
|
|
557
|
+
};
|
|
558
|
+
declare function FillActiveInput(value: any, options?: FillInputOptions): Promise<FillResult>;
|
|
559
|
+
|
|
560
|
+
export { type Anchor, Button, type ButtonProps, ContentContainer, type ContentContainerProps, CursorController, type DomComponent, FillActiveInput, type FillInputOptions, type FillResult, FloatingChatButton, type GetDomComponentsOptions, type GetDomComponentsResult, type GuideAction, type GuideCursorOptions, type GuideOptions, type GuideRunResult, type GuideStep, type GuideStepResult, type GuideTarget, HsafaChat, type HsafaChatProps, HsafaProvider, type UIComponentProps, registry as componentRegistry, guideCursor as controlCursor, getDomComponents, guideCursor, useAutoScroll, useFileUpload, useHsafa };
|