veryfront 0.0.3 → 0.0.5

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.
@@ -0,0 +1,713 @@
1
+ // src/ai/react/components/theme.ts
2
+ var defaultChatTheme = {
3
+ container: "flex flex-col h-full bg-white dark:bg-gray-950",
4
+ message: {
5
+ user: "bg-blue-600 text-white rounded-lg px-4 py-2 max-w-[70%] ml-auto",
6
+ assistant: "bg-gray-200 dark:bg-gray-800 text-gray-900 dark:text-gray-100 rounded-lg px-4 py-2 max-w-[70%]",
7
+ system: "bg-yellow-100 dark:bg-yellow-900/20 text-yellow-900 dark:text-yellow-100 rounded px-3 py-1 text-sm",
8
+ tool: "bg-purple-100 dark:bg-purple-900/20 text-purple-900 dark:text-purple-100 rounded px-3 py-1 text-sm font-mono"
9
+ },
10
+ input: "flex-1 px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-gray-100",
11
+ button: "px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
12
+ loading: "w-5 h-5 border-2 border-gray-400 border-t-transparent rounded-full animate-spin"
13
+ };
14
+ var defaultAgentTheme = {
15
+ container: "border border-gray-200 dark:border-gray-800 rounded-lg p-6 space-y-4 bg-white dark:bg-gray-950",
16
+ status: "inline-flex items-center px-3 py-1 rounded-full text-sm font-medium",
17
+ thinking: "bg-yellow-50 dark:bg-yellow-900/20 border-l-4 border-yellow-500 pl-4 py-2 italic text-gray-700 dark:text-gray-300",
18
+ tool: "border-l-4 border-blue-500 pl-4 py-2 bg-blue-50 dark:bg-blue-900/20",
19
+ toolResult: "mt-2 p-3 bg-gray-100 dark:bg-gray-900 rounded font-mono text-sm overflow-x-auto"
20
+ };
21
+ function mergeThemes(defaultTheme, userTheme) {
22
+ if (!userTheme)
23
+ return defaultTheme;
24
+ const merged = { ...defaultTheme };
25
+ for (const key in userTheme) {
26
+ const value = userTheme[key];
27
+ if (value === void 0) {
28
+ continue;
29
+ }
30
+ if (typeof value === "object" && !Array.isArray(value)) {
31
+ merged[key] = { ...defaultTheme[key], ...value };
32
+ } else {
33
+ merged[key] = value;
34
+ }
35
+ }
36
+ return merged;
37
+ }
38
+ function cn(...classes) {
39
+ return classes.filter(Boolean).join(" ");
40
+ }
41
+
42
+ // src/ai/react/components/chat.tsx
43
+ import * as React6 from "react";
44
+
45
+ // src/ai/react/primitives/chat-container.tsx
46
+ import * as React from "react";
47
+ import { jsx } from "react/jsx-runtime";
48
+ var ChatContainer = React.forwardRef(
49
+ ({ className, children, ...props }, ref) => {
50
+ return /* @__PURE__ */ jsx(
51
+ "div",
52
+ {
53
+ ref,
54
+ className,
55
+ "data-chat-container": "",
56
+ ...props,
57
+ children
58
+ }
59
+ );
60
+ }
61
+ );
62
+ ChatContainer.displayName = "ChatContainer";
63
+
64
+ // src/ai/react/primitives/message-list.tsx
65
+ import * as React2 from "react";
66
+ import { jsx as jsx2 } from "react/jsx-runtime";
67
+ var MessageList = React2.forwardRef(
68
+ ({ className, children, ...props }, ref) => {
69
+ return /* @__PURE__ */ jsx2(
70
+ "div",
71
+ {
72
+ ref,
73
+ className,
74
+ "data-message-list": "",
75
+ role: "log",
76
+ "aria-live": "polite",
77
+ ...props,
78
+ children
79
+ }
80
+ );
81
+ }
82
+ );
83
+ MessageList.displayName = "MessageList";
84
+ var MessageItem = React2.forwardRef(
85
+ ({ className, role, content, children, ...props }, ref) => {
86
+ return /* @__PURE__ */ jsx2(
87
+ "div",
88
+ {
89
+ ref,
90
+ className,
91
+ "data-message-item": "",
92
+ "data-role": role,
93
+ ...props,
94
+ children: children || content
95
+ }
96
+ );
97
+ }
98
+ );
99
+ MessageItem.displayName = "MessageItem";
100
+ var MessageRole = React2.forwardRef(
101
+ ({ className, children, ...props }, ref) => {
102
+ return /* @__PURE__ */ jsx2(
103
+ "span",
104
+ {
105
+ ref,
106
+ className,
107
+ "data-message-role": "",
108
+ ...props,
109
+ children
110
+ }
111
+ );
112
+ }
113
+ );
114
+ MessageRole.displayName = "MessageRole";
115
+ var MessageContent = React2.forwardRef(({ className, children, ...props }, ref) => {
116
+ return /* @__PURE__ */ jsx2(
117
+ "div",
118
+ {
119
+ ref,
120
+ className,
121
+ "data-message-content": "",
122
+ ...props,
123
+ children
124
+ }
125
+ );
126
+ });
127
+ MessageContent.displayName = "MessageContent";
128
+
129
+ // src/ai/react/primitives/input-box.tsx
130
+ import * as React3 from "react";
131
+ import { jsx as jsx3 } from "react/jsx-runtime";
132
+ var InputBox = React3.forwardRef(({ className, value, onChange, onSubmit, multiline, ...props }, ref) => {
133
+ const handleKeyDown = (e) => {
134
+ if (e.key === "Enter" && !e.shiftKey && onSubmit) {
135
+ e.preventDefault();
136
+ onSubmit();
137
+ }
138
+ };
139
+ if (multiline) {
140
+ return /* @__PURE__ */ jsx3(
141
+ "textarea",
142
+ {
143
+ ref,
144
+ className,
145
+ value,
146
+ onChange,
147
+ onKeyDown: handleKeyDown,
148
+ "data-input-box": "",
149
+ "data-multiline": "true",
150
+ rows: 3,
151
+ ...props
152
+ }
153
+ );
154
+ }
155
+ return /* @__PURE__ */ jsx3(
156
+ "input",
157
+ {
158
+ ref,
159
+ type: "text",
160
+ className,
161
+ value,
162
+ onChange,
163
+ onKeyDown: handleKeyDown,
164
+ "data-input-box": "",
165
+ ...props
166
+ }
167
+ );
168
+ });
169
+ InputBox.displayName = "InputBox";
170
+ var SubmitButton = React3.forwardRef(({ className, isLoading, disabled, children, ...props }, ref) => {
171
+ return /* @__PURE__ */ jsx3(
172
+ "button",
173
+ {
174
+ ref,
175
+ type: "submit",
176
+ className,
177
+ disabled: disabled || isLoading,
178
+ "data-submit-button": "",
179
+ "data-loading": isLoading,
180
+ "aria-label": "Submit message",
181
+ ...props,
182
+ children: children || "Send"
183
+ }
184
+ );
185
+ });
186
+ SubmitButton.displayName = "SubmitButton";
187
+ var LoadingIndicator = React3.forwardRef(({ className, ...props }, ref) => {
188
+ return /* @__PURE__ */ jsx3(
189
+ "div",
190
+ {
191
+ ref,
192
+ className,
193
+ "data-loading-indicator": "",
194
+ role: "status",
195
+ "aria-label": "Loading",
196
+ ...props
197
+ }
198
+ );
199
+ });
200
+ LoadingIndicator.displayName = "LoadingIndicator";
201
+
202
+ // src/ai/react/primitives/agent-primitives.tsx
203
+ import * as React4 from "react";
204
+ import { jsx as jsx4 } from "react/jsx-runtime";
205
+ var AgentContainer = React4.forwardRef(({ className, children, ...props }, ref) => {
206
+ return /* @__PURE__ */ jsx4(
207
+ "div",
208
+ {
209
+ ref,
210
+ className,
211
+ "data-agent-container": "",
212
+ ...props,
213
+ children
214
+ }
215
+ );
216
+ });
217
+ AgentContainer.displayName = "AgentContainer";
218
+ var AgentStatus = React4.forwardRef(
219
+ ({ className, status, label, ...props }, ref) => {
220
+ const displayLabel = label || formatStatus(status);
221
+ return /* @__PURE__ */ jsx4(
222
+ "div",
223
+ {
224
+ ref,
225
+ className,
226
+ "data-agent-status": "",
227
+ "data-status": status,
228
+ role: "status",
229
+ "aria-label": `Agent status: ${displayLabel}`,
230
+ ...props,
231
+ children: displayLabel
232
+ }
233
+ );
234
+ }
235
+ );
236
+ AgentStatus.displayName = "AgentStatus";
237
+ var ThinkingIndicator = React4.forwardRef(({ className, children, ...props }, ref) => {
238
+ return /* @__PURE__ */ jsx4(
239
+ "div",
240
+ {
241
+ ref,
242
+ className,
243
+ "data-thinking-indicator": "",
244
+ role: "status",
245
+ "aria-live": "polite",
246
+ ...props,
247
+ children
248
+ }
249
+ );
250
+ });
251
+ ThinkingIndicator.displayName = "ThinkingIndicator";
252
+ function formatStatus(status) {
253
+ switch (status) {
254
+ case "idle":
255
+ return "Idle";
256
+ case "thinking":
257
+ return "Thinking...";
258
+ case "tool_execution":
259
+ return "Using tools...";
260
+ case "streaming":
261
+ return "Responding...";
262
+ case "completed":
263
+ return "Completed";
264
+ case "error":
265
+ return "Error";
266
+ default:
267
+ return String(status);
268
+ }
269
+ }
270
+
271
+ // src/ai/react/primitives/tool-primitives.tsx
272
+ import * as React5 from "react";
273
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
274
+ var ToolInvocation = React5.forwardRef(({ className, name, args, status, children, ...props }, ref) => {
275
+ return /* @__PURE__ */ jsxs(
276
+ "div",
277
+ {
278
+ ref,
279
+ className,
280
+ "data-tool-invocation": "",
281
+ "data-tool-name": name,
282
+ "data-status": status,
283
+ ...props,
284
+ children: [
285
+ /* @__PURE__ */ jsxs("div", { "data-tool-header": "", children: [
286
+ /* @__PURE__ */ jsx5("span", { "data-tool-name": "", children: name }),
287
+ status && /* @__PURE__ */ jsxs("span", { "data-tool-status": "", children: [
288
+ "(",
289
+ status,
290
+ ")"
291
+ ] })
292
+ ] }),
293
+ args && /* @__PURE__ */ jsx5("div", { "data-tool-args": "", children: /* @__PURE__ */ jsx5("pre", { children: JSON.stringify(args, null, 2) }) }),
294
+ children
295
+ ]
296
+ }
297
+ );
298
+ });
299
+ ToolInvocation.displayName = "ToolInvocation";
300
+ var ToolResult = React5.forwardRef(
301
+ ({ className, result, renderResult, ...props }, ref) => {
302
+ const content = renderResult ? renderResult(result) : JSON.stringify(result, null, 2);
303
+ return /* @__PURE__ */ jsx5(
304
+ "div",
305
+ {
306
+ ref,
307
+ className,
308
+ "data-tool-result": "",
309
+ ...props,
310
+ children: typeof content === "string" ? /* @__PURE__ */ jsx5("pre", { children: content }) : content
311
+ }
312
+ );
313
+ }
314
+ );
315
+ ToolResult.displayName = "ToolResult";
316
+ var ToolList = React5.forwardRef(
317
+ ({ className, toolCalls, renderTool, ...props }, ref) => {
318
+ return /* @__PURE__ */ jsx5(
319
+ "div",
320
+ {
321
+ ref,
322
+ className,
323
+ "data-tool-list": "",
324
+ ...props,
325
+ children: toolCalls.map(
326
+ (tool) => renderTool ? /* @__PURE__ */ jsx5(React5.Fragment, { children: renderTool(tool) }, tool.id) : /* @__PURE__ */ jsx5(
327
+ ToolInvocation,
328
+ {
329
+ name: tool.name,
330
+ args: tool.args,
331
+ status: tool.status,
332
+ children: tool.result !== void 0 && /* @__PURE__ */ jsx5(ToolResult, { result: tool.result })
333
+ },
334
+ tool.id
335
+ )
336
+ )
337
+ }
338
+ );
339
+ }
340
+ );
341
+ ToolList.displayName = "ToolList";
342
+
343
+ // src/ai/react/components/chat.tsx
344
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
345
+ var Chat = React6.forwardRef(
346
+ ({
347
+ messages,
348
+ input,
349
+ onChange,
350
+ onSubmit,
351
+ isLoading,
352
+ error,
353
+ placeholder = "Type a message...",
354
+ maxHeight = "100%",
355
+ className,
356
+ theme: userTheme,
357
+ renderMessage,
358
+ renderTool: _renderTool,
359
+ multiline = false
360
+ }, ref) => {
361
+ const theme = mergeThemes(defaultChatTheme, userTheme);
362
+ const messagesEndRef = React6.useRef(null);
363
+ React6.useEffect(() => {
364
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
365
+ }, [messages]);
366
+ return /* @__PURE__ */ jsxs2(
367
+ ChatContainer,
368
+ {
369
+ ref,
370
+ className: cn(theme.container, className),
371
+ style: { maxHeight },
372
+ children: [
373
+ /* @__PURE__ */ jsxs2(MessageList, { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
374
+ messages.map(
375
+ (msg) => renderMessage ? /* @__PURE__ */ jsx6(React6.Fragment, { children: renderMessage(msg) }, msg.id) : /* @__PURE__ */ jsx6(
376
+ MessageItem,
377
+ {
378
+ role: msg.role,
379
+ className: cn(
380
+ "flex",
381
+ msg.role === "user" ? "justify-end" : "justify-start"
382
+ ),
383
+ children: /* @__PURE__ */ jsx6("div", { className: theme.message?.[msg.role] || theme.message?.assistant, children: msg.content })
384
+ },
385
+ msg.id
386
+ )
387
+ ),
388
+ isLoading && /* @__PURE__ */ jsx6("div", { className: "flex justify-start", children: /* @__PURE__ */ jsx6("div", { className: "bg-gray-200 dark:bg-gray-800 rounded-lg px-4 py-2", children: /* @__PURE__ */ jsx6(LoadingIndicator, { className: theme.loading }) }) }),
389
+ /* @__PURE__ */ jsx6("div", { ref: messagesEndRef })
390
+ ] }),
391
+ error && /* @__PURE__ */ jsxs2("div", { className: "px-4 py-2 bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500 text-red-900 dark:text-red-100", children: [
392
+ /* @__PURE__ */ jsx6("p", { className: "text-sm font-medium", children: "Error" }),
393
+ /* @__PURE__ */ jsx6("p", { className: "text-sm", children: error.message })
394
+ ] }),
395
+ /* @__PURE__ */ jsx6("form", { onSubmit, className: "border-t border-gray-200 dark:border-gray-800 p-4", children: /* @__PURE__ */ jsxs2("div", { className: "flex gap-2", children: [
396
+ /* @__PURE__ */ jsx6(
397
+ InputBox,
398
+ {
399
+ value: input,
400
+ onChange: onChange || (() => {
401
+ }),
402
+ placeholder,
403
+ disabled: isLoading,
404
+ multiline,
405
+ className: theme.input
406
+ }
407
+ ),
408
+ /* @__PURE__ */ jsx6(
409
+ SubmitButton,
410
+ {
411
+ isLoading,
412
+ disabled: !input.trim() || isLoading,
413
+ className: theme.button,
414
+ children: "Send"
415
+ }
416
+ )
417
+ ] }) })
418
+ ]
419
+ }
420
+ );
421
+ }
422
+ );
423
+ Chat.displayName = "Chat";
424
+ var ChatHeader = React6.forwardRef(({ className, children, ...props }, ref) => {
425
+ return /* @__PURE__ */ jsx6(
426
+ "div",
427
+ {
428
+ ref,
429
+ className: cn(
430
+ "border-b border-gray-200 dark:border-gray-800 p-4 bg-gray-50 dark:bg-gray-900",
431
+ className
432
+ ),
433
+ ...props,
434
+ children
435
+ }
436
+ );
437
+ });
438
+ ChatHeader.displayName = "ChatHeader";
439
+ var ChatMessages = MessageList;
440
+ ChatMessages.displayName = "ChatMessages";
441
+ var ChatInput = React6.forwardRef(({ className, ...props }, ref) => {
442
+ return /* @__PURE__ */ jsx6("div", { className: "border-t border-gray-200 dark:border-gray-800 p-4", children: /* @__PURE__ */ jsx6("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx6(
443
+ InputBox,
444
+ {
445
+ ref,
446
+ className: cn(defaultChatTheme.input, className),
447
+ ...props
448
+ }
449
+ ) }) });
450
+ });
451
+ ChatInput.displayName = "ChatInput";
452
+ var ChatFooter = React6.forwardRef(({ className, children, ...props }, ref) => {
453
+ return /* @__PURE__ */ jsx6(
454
+ "div",
455
+ {
456
+ ref,
457
+ className: cn(
458
+ "border-t border-gray-200 dark:border-gray-800 p-4 text-sm text-gray-500",
459
+ className
460
+ ),
461
+ ...props,
462
+ children
463
+ }
464
+ );
465
+ });
466
+ ChatFooter.displayName = "ChatFooter";
467
+ var ChatComponents = Object.assign(Chat, {
468
+ Header: ChatHeader,
469
+ Messages: ChatMessages,
470
+ Input: ChatInput,
471
+ Footer: ChatFooter
472
+ });
473
+
474
+ // src/ai/react/components/agent-card.tsx
475
+ import * as React7 from "react";
476
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
477
+ var AgentCard = React7.forwardRef(
478
+ ({
479
+ messages,
480
+ toolCalls = [],
481
+ status,
482
+ thinking,
483
+ className,
484
+ theme: userTheme,
485
+ renderTool
486
+ }, ref) => {
487
+ const theme = mergeThemes(defaultAgentTheme, userTheme);
488
+ return /* @__PURE__ */ jsxs3(AgentContainer, { ref, className: cn(theme.container, className), children: [
489
+ /* @__PURE__ */ jsx7(
490
+ AgentStatus,
491
+ {
492
+ status,
493
+ className: cn(theme.status, getStatusColor(status))
494
+ }
495
+ ),
496
+ thinking && /* @__PURE__ */ jsxs3(ThinkingIndicator, { className: theme.thinking, children: [
497
+ /* @__PURE__ */ jsx7("span", { className: "font-semibold", children: "Thinking:" }),
498
+ thinking
499
+ ] }),
500
+ toolCalls.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
501
+ /* @__PURE__ */ jsx7("h3", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300", children: "Tool Calls" }),
502
+ /* @__PURE__ */ jsx7(
503
+ ToolList,
504
+ {
505
+ toolCalls,
506
+ className: "space-y-2",
507
+ renderTool: renderTool || ((tool) => /* @__PURE__ */ jsxs3(
508
+ ToolInvocation,
509
+ {
510
+ name: tool.name,
511
+ args: tool.args,
512
+ status: tool.status,
513
+ className: theme.tool,
514
+ children: [
515
+ tool.result !== void 0 && /* @__PURE__ */ jsx7(ToolResult, { result: tool.result, className: theme.toolResult }),
516
+ tool.error && /* @__PURE__ */ jsxs3("div", { className: "mt-2 p-2 bg-red-50 dark:bg-red-900/20 text-red-900 dark:text-red-100 rounded text-sm", children: [
517
+ "Error: ",
518
+ tool.error
519
+ ] })
520
+ ]
521
+ }
522
+ ))
523
+ }
524
+ )
525
+ ] }),
526
+ messages && messages.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
527
+ /* @__PURE__ */ jsx7("h3", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300", children: "Messages" }),
528
+ /* @__PURE__ */ jsx7("div", { className: "space-y-2 max-h-96 overflow-y-auto", children: messages.map((msg) => /* @__PURE__ */ jsxs3(
529
+ "div",
530
+ {
531
+ className: "text-sm p-2 rounded bg-gray-50 dark:bg-gray-900",
532
+ children: [
533
+ /* @__PURE__ */ jsxs3("span", { className: "font-semibold capitalize", children: [
534
+ msg.role,
535
+ ":"
536
+ ] }),
537
+ /* @__PURE__ */ jsxs3("span", { children: [
538
+ msg.content.substring(0, 200),
539
+ "..."
540
+ ] })
541
+ ]
542
+ },
543
+ msg.id
544
+ )) })
545
+ ] })
546
+ ] });
547
+ }
548
+ );
549
+ AgentCard.displayName = "AgentCard";
550
+ function getStatusColor(status) {
551
+ switch (status) {
552
+ case "idle":
553
+ return "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300";
554
+ case "thinking":
555
+ return "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300";
556
+ case "tool_execution":
557
+ return "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300";
558
+ case "streaming":
559
+ return "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300";
560
+ case "completed":
561
+ return "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300";
562
+ case "error":
563
+ return "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300";
564
+ default:
565
+ return "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300";
566
+ }
567
+ }
568
+
569
+ // src/ai/react/components/message.tsx
570
+ import * as React8 from "react";
571
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
572
+ var Message = React8.forwardRef(
573
+ ({ message, className, theme: userTheme, showRole = false, showTimestamp = false }, ref) => {
574
+ const theme = mergeThemes(defaultChatTheme, userTheme);
575
+ return /* @__PURE__ */ jsx8(
576
+ MessageItem,
577
+ {
578
+ ref,
579
+ role: message.role,
580
+ className: cn(
581
+ "flex",
582
+ message.role === "user" ? "justify-end" : "justify-start",
583
+ className
584
+ ),
585
+ children: /* @__PURE__ */ jsxs4("div", { className: theme.message?.[message.role] || theme.message?.assistant, children: [
586
+ showRole && /* @__PURE__ */ jsx8(MessageRole, { className: "block text-xs font-semibold mb-1 opacity-75 uppercase", children: message.role }),
587
+ /* @__PURE__ */ jsx8(MessageContent, { children: message.content }),
588
+ showTimestamp && message.timestamp && /* @__PURE__ */ jsx8("div", { className: "text-xs opacity-60 mt-1", children: new Date(message.timestamp).toLocaleTimeString() })
589
+ ] })
590
+ }
591
+ );
592
+ }
593
+ );
594
+ Message.displayName = "Message";
595
+ var StreamingMessage = React8.forwardRef(({ content, showCursor = true, className, theme: userTheme }, ref) => {
596
+ const theme = mergeThemes(defaultChatTheme, userTheme);
597
+ return /* @__PURE__ */ jsx8(
598
+ MessageItem,
599
+ {
600
+ ref,
601
+ role: "assistant",
602
+ className: cn("flex justify-start", className),
603
+ children: /* @__PURE__ */ jsx8("div", { className: theme.message?.assistant, children: /* @__PURE__ */ jsxs4(MessageContent, { children: [
604
+ content,
605
+ showCursor && /* @__PURE__ */ jsx8("span", { className: "inline-block w-1 h-4 bg-current ml-1 animate-pulse" })
606
+ ] }) })
607
+ }
608
+ );
609
+ });
610
+ StreamingMessage.displayName = "StreamingMessage";
611
+
612
+ // src/ai/react/components/error-boundary.tsx
613
+ import * as React9 from "react";
614
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
615
+ var AIErrorBoundary = class extends React9.Component {
616
+ constructor(props) {
617
+ super(props);
618
+ this.reset = () => {
619
+ this.setState({ hasError: false, error: null });
620
+ };
621
+ this.state = { hasError: false, error: null };
622
+ }
623
+ static getDerivedStateFromError(error) {
624
+ return { hasError: true, error };
625
+ }
626
+ componentDidCatch(error, errorInfo) {
627
+ console.error("[AIErrorBoundary] Caught error:", error, errorInfo);
628
+ if (this.props.onError) {
629
+ this.props.onError(error, errorInfo);
630
+ }
631
+ }
632
+ render() {
633
+ if (this.state.hasError && this.state.error) {
634
+ if (this.props.fallback) {
635
+ if (typeof this.props.fallback === "function") {
636
+ return this.props.fallback(this.state.error, this.reset);
637
+ }
638
+ return this.props.fallback;
639
+ }
640
+ return /* @__PURE__ */ jsx9(
641
+ "div",
642
+ {
643
+ className: "border border-red-200 bg-red-50 dark:bg-red-900/20 rounded-lg p-6",
644
+ role: "alert",
645
+ children: /* @__PURE__ */ jsxs5("div", { className: "flex items-start gap-3", children: [
646
+ /* @__PURE__ */ jsx9(
647
+ "svg",
648
+ {
649
+ className: "w-5 h-5 text-red-600 dark:text-red-400 mt-0.5",
650
+ fill: "none",
651
+ viewBox: "0 0 24 24",
652
+ stroke: "currentColor",
653
+ children: /* @__PURE__ */ jsx9(
654
+ "path",
655
+ {
656
+ strokeLinecap: "round",
657
+ strokeLinejoin: "round",
658
+ strokeWidth: 2,
659
+ d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
660
+ }
661
+ )
662
+ }
663
+ ),
664
+ /* @__PURE__ */ jsxs5("div", { className: "flex-1", children: [
665
+ /* @__PURE__ */ jsx9("h3", { className: "text-sm font-semibold text-red-900 dark:text-red-100", children: this.props.errorMessage || "An error occurred in the AI component" }),
666
+ /* @__PURE__ */ jsx9("p", { className: "mt-2 text-sm text-red-700 dark:text-red-300", children: this.state.error.message }),
667
+ /* @__PURE__ */ jsx9(
668
+ "button",
669
+ {
670
+ type: "button",
671
+ onClick: this.reset,
672
+ className: "mt-4 px-4 py-2 text-sm font-medium text-red-900 dark:text-red-100 bg-red-100 dark:bg-red-900/40 hover:bg-red-200 dark:hover:bg-red-900/60 rounded-lg transition-colors",
673
+ children: "Try Again"
674
+ }
675
+ )
676
+ ] })
677
+ ] })
678
+ }
679
+ );
680
+ }
681
+ return this.props.children;
682
+ }
683
+ };
684
+ function useAIErrorHandler() {
685
+ const [error, setError] = React9.useState(null);
686
+ const handleError = React9.useCallback((error2) => {
687
+ console.error("[useAIErrorHandler] Error:", error2);
688
+ setError(error2);
689
+ }, []);
690
+ const clearError = React9.useCallback(() => {
691
+ setError(null);
692
+ }, []);
693
+ return {
694
+ error,
695
+ handleError,
696
+ clearError,
697
+ hasError: error !== null
698
+ };
699
+ }
700
+ export {
701
+ AIErrorBoundary,
702
+ AgentCard,
703
+ Chat,
704
+ ChatComponents,
705
+ Message,
706
+ StreamingMessage,
707
+ cn,
708
+ defaultAgentTheme,
709
+ defaultChatTheme,
710
+ mergeThemes,
711
+ useAIErrorHandler
712
+ };
713
+ //# sourceMappingURL=components.js.map