@chatsdk-dev/elements 0.0.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.
Files changed (218) hide show
  1. package/README.md +43 -0
  2. package/dist/chunk-2LHKM7RD.js +14 -0
  3. package/dist/chunk-5UMYP6MD.js +10 -0
  4. package/dist/chunk-AP4MG32M.js +36 -0
  5. package/dist/chunk-CFM57HOS.js +358 -0
  6. package/dist/chunk-EGIUE7H2.js +37 -0
  7. package/dist/chunk-M5OONVIO.js +90 -0
  8. package/dist/chunk-MXTBCHYC.js +31 -0
  9. package/dist/chunk-NIC3MOMY.js +55 -0
  10. package/dist/chunk-QTRMNIG3.js +83 -0
  11. package/dist/chunk-R7G3RQLU.js +36 -0
  12. package/dist/chunk-RJG5D2TM.js +113 -0
  13. package/dist/chunk-SLJNKQ2G.js +125 -0
  14. package/dist/chunk-TDEFIW2L.js +9 -0
  15. package/dist/chunk-TDP6D7U7.js +551 -0
  16. package/dist/chunk-V2ITXC65.js +24 -0
  17. package/dist/chunk-VS55HRUS.js +16 -0
  18. package/dist/chunk-VYDYCGJL.js +25 -0
  19. package/dist/chunk-X5YUF2YM.js +113 -0
  20. package/dist/chunk-YX46JVQN.js +78 -0
  21. package/dist/chunk-YXAMLTTT.js +16 -0
  22. package/dist/chunk-YXFVHSY4.js +51 -0
  23. package/dist/chunk-ZCSZX3OI.js +4 -0
  24. package/dist/common/use-copy-to-clipboard.d.ts +3 -0
  25. package/dist/common/use-copy-to-clipboard.js +33 -0
  26. package/dist/common/utilts.d.ts +8 -0
  27. package/dist/common/utilts.js +28 -0
  28. package/dist/components/ai-elements/actions.d.ts +13 -0
  29. package/dist/components/ai-elements/actions.js +42 -0
  30. package/dist/components/ai-elements/agent.d.ts +31 -0
  31. package/dist/components/ai-elements/agent.js +77 -0
  32. package/dist/components/ai-elements/artifact.d.ts +27 -0
  33. package/dist/components/ai-elements/artifact.js +108 -0
  34. package/dist/components/ai-elements/attachments.d.ts +57 -0
  35. package/dist/components/ai-elements/attachments.js +258 -0
  36. package/dist/components/ai-elements/audio-player.d.ts +33 -0
  37. package/dist/components/ai-elements/audio-player.js +199 -0
  38. package/dist/components/ai-elements/canvas.d.ts +10 -0
  39. package/dist/components/ai-elements/canvas.js +24 -0
  40. package/dist/components/ai-elements/chain-of-thought.d.ts +34 -0
  41. package/dist/components/ai-elements/chain-of-thought.js +159 -0
  42. package/dist/components/ai-elements/checkpoint.d.ts +16 -0
  43. package/dist/components/ai-elements/checkpoint.js +47 -0
  44. package/dist/components/ai-elements/code-block.d.ts +48 -0
  45. package/dist/components/ai-elements/code-block.js +1 -0
  46. package/dist/components/ai-elements/commit.d.ts +68 -0
  47. package/dist/components/ai-elements/commit.js +314 -0
  48. package/dist/components/ai-elements/confirmation.d.ts +52 -0
  49. package/dist/components/ai-elements/confirmation.js +76 -0
  50. package/dist/components/ai-elements/connection.d.ts +5 -0
  51. package/dist/components/ai-elements/connection.js +34 -0
  52. package/dist/components/ai-elements/context.d.ts +36 -0
  53. package/dist/components/ai-elements/context.js +320 -0
  54. package/dist/components/ai-elements/controls.d.ts +8 -0
  55. package/dist/components/ai-elements/controls.js +17 -0
  56. package/dist/components/ai-elements/conversation.d.ts +27 -0
  57. package/dist/components/ai-elements/conversation.js +119 -0
  58. package/dist/components/ai-elements/edge.d.ts +9 -0
  59. package/dist/components/ai-elements/edge.js +111 -0
  60. package/dist/components/ai-elements/environment-variables.d.ts +42 -0
  61. package/dist/components/ai-elements/environment-variables.js +208 -0
  62. package/dist/components/ai-elements/file-tree.d.ts +30 -0
  63. package/dist/components/ai-elements/file-tree.js +212 -0
  64. package/dist/components/ai-elements/image.d.ts +10 -0
  65. package/dist/components/ai-elements/image.js +23 -0
  66. package/dist/components/ai-elements/inline-citation.d.ts +42 -0
  67. package/dist/components/ai-elements/inline-citation.js +203 -0
  68. package/dist/components/ai-elements/jsx-preview.d.ts +33 -0
  69. package/dist/components/ai-elements/jsx-preview.js +206 -0
  70. package/dist/components/ai-elements/loader.d.ts +9 -0
  71. package/dist/components/ai-elements/loader.js +115 -0
  72. package/dist/components/ai-elements/message.d.ts +42 -0
  73. package/dist/components/ai-elements/message.js +259 -0
  74. package/dist/components/ai-elements/mic-selector.d.ts +49 -0
  75. package/dist/components/ai-elements/mic-selector.js +252 -0
  76. package/dist/components/ai-elements/model-selector.d.ts +39 -0
  77. package/dist/components/ai-elements/model-selector.js +73 -0
  78. package/dist/components/ai-elements/node.d.ts +25 -0
  79. package/dist/components/ai-elements/node.js +41 -0
  80. package/dist/components/ai-elements/open-in-chat.d.ts +32 -0
  81. package/dist/components/ai-elements/open-in-chat.js +366 -0
  82. package/dist/components/ai-elements/package-info.d.ts +32 -0
  83. package/dist/components/ai-elements/package-info.js +162 -0
  84. package/dist/components/ai-elements/panel.d.ts +8 -0
  85. package/dist/components/ai-elements/panel.js +17 -0
  86. package/dist/components/ai-elements/persona.d.ts +50 -0
  87. package/dist/components/ai-elements/persona.js +209 -0
  88. package/dist/components/ai-elements/plan.d.ts +29 -0
  89. package/dist/components/ai-elements/plan.js +95 -0
  90. package/dist/components/ai-elements/prompt-input.d.ts +153 -0
  91. package/dist/components/ai-elements/prompt-input.js +939 -0
  92. package/dist/components/ai-elements/queue.d.ts +65 -0
  93. package/dist/components/ai-elements/queue.js +179 -0
  94. package/dist/components/ai-elements/reasoning.d.ts +30 -0
  95. package/dist/components/ai-elements/reasoning.js +161 -0
  96. package/dist/components/ai-elements/response.d.ts +9 -0
  97. package/dist/components/ai-elements/response.js +33 -0
  98. package/dist/components/ai-elements/sandbox.d.ts +28 -0
  99. package/dist/components/ai-elements/sandbox.js +98 -0
  100. package/dist/components/ai-elements/schema-display.d.ts +58 -0
  101. package/dist/components/ai-elements/schema-display.js +313 -0
  102. package/dist/components/ai-elements/shimmer.d.ts +14 -0
  103. package/dist/components/ai-elements/shimmer.js +1 -0
  104. package/dist/components/ai-elements/snippet.d.ts +22 -0
  105. package/dist/components/ai-elements/snippet.js +90 -0
  106. package/dist/components/ai-elements/sources.d.ts +16 -0
  107. package/dist/components/ai-elements/sources.js +62 -0
  108. package/dist/components/ai-elements/speech-input.d.ts +57 -0
  109. package/dist/components/ai-elements/speech-input.js +206 -0
  110. package/dist/components/ai-elements/stack-trace.d.ts +42 -0
  111. package/dist/components/ai-elements/stack-trace.js +377 -0
  112. package/dist/components/ai-elements/suggestion.d.ts +14 -0
  113. package/dist/components/ai-elements/suggestion.js +41 -0
  114. package/dist/components/ai-elements/task.d.ts +18 -0
  115. package/dist/components/ai-elements/task.js +60 -0
  116. package/dist/components/ai-elements/terminal.d.ts +31 -0
  117. package/dist/components/ai-elements/terminal.js +203 -0
  118. package/dist/components/ai-elements/test-results.d.ts +61 -0
  119. package/dist/components/ai-elements/test-results.js +349 -0
  120. package/dist/components/ai-elements/tool.d.ts +35 -0
  121. package/dist/components/ai-elements/tool.js +2 -0
  122. package/dist/components/ai-elements/toolbar.d.ts +8 -0
  123. package/dist/components/ai-elements/toolbar.js +18 -0
  124. package/dist/components/ai-elements/transcription.d.ts +19 -0
  125. package/dist/components/ai-elements/transcription.js +90 -0
  126. package/dist/components/ai-elements/voice-selector.d.ts +66 -0
  127. package/dist/components/ai-elements/voice-selector.js +332 -0
  128. package/dist/components/ai-elements/web-preview.d.ts +38 -0
  129. package/dist/components/ai-elements/web-preview.js +214 -0
  130. package/dist/components/info-card.d.ts +14 -0
  131. package/dist/components/info-card.js +1 -0
  132. package/dist/components/responsive-alert-dialog.d.ts +19 -0
  133. package/dist/components/responsive-alert-dialog.js +1 -0
  134. package/dist/components/responsive-dialog.d.ts +14 -0
  135. package/dist/components/responsive-dialog.js +1 -0
  136. package/dist/config-IcWUmjwj.d.ts +239 -0
  137. package/dist/features/chat/chat-card.d.ts +5 -0
  138. package/dist/features/chat/chat-card.js +14 -0
  139. package/dist/features/chat/chat-element/chat-element.d.ts +8 -0
  140. package/dist/features/chat/chat-element/chat-element.js +14 -0
  141. package/dist/features/chat/chat-element/use-chat.d.ts +21 -0
  142. package/dist/features/chat/chat-element/use-chat.js +14 -0
  143. package/dist/features/chat/chat-element/use-initial-messages.d.ts +20 -0
  144. package/dist/features/chat/chat-element/use-initial-messages.js +14 -0
  145. package/dist/features/chat/chat-header/chat-header.d.ts +8 -0
  146. package/dist/features/chat/chat-header/chat-header.js +14 -0
  147. package/dist/features/chat/chat-header/chat-menu.d.ts +5 -0
  148. package/dist/features/chat/chat-header/chat-menu.js +2 -0
  149. package/dist/features/chat/chat-history/chat-history-empty.d.ts +5 -0
  150. package/dist/features/chat/chat-history/chat-history-empty.js +1 -0
  151. package/dist/features/chat/chat-history/chat-history.d.ts +5 -0
  152. package/dist/features/chat/chat-history/chat-history.js +14 -0
  153. package/dist/features/chat/chat-message.d.ts +10 -0
  154. package/dist/features/chat/chat-message.js +1 -0
  155. package/dist/features/chat/chat-molecule.d.ts +35 -0
  156. package/dist/features/chat/chat-molecule.js +14 -0
  157. package/dist/features/chat/chat-prompt-input.d.ts +16 -0
  158. package/dist/features/chat/chat-prompt-input.js +14 -0
  159. package/dist/features/chat/chat.context.d.ts +26 -0
  160. package/dist/features/chat/chat.context.js +13 -0
  161. package/dist/features/chat/index.d.ts +14 -0
  162. package/dist/features/chat/index.js +14 -0
  163. package/dist/features/chat/queries/query-keys.d.ts +8 -0
  164. package/dist/features/chat/queries/query-keys.js +1 -0
  165. package/dist/features/chat/queries/use-create-conversation-mutation.d.ts +29 -0
  166. package/dist/features/chat/queries/use-create-conversation-mutation.js +38 -0
  167. package/dist/features/chat/queries/use-get-chat-query.d.ts +9 -0
  168. package/dist/features/chat/queries/use-get-chat-query.js +14 -0
  169. package/dist/features/chat/queries/use-get-conversation-query.d.ts +62 -0
  170. package/dist/features/chat/queries/use-get-conversation-query.js +14 -0
  171. package/dist/features/chat/queries/use-list-conversations-query.d.ts +29 -0
  172. package/dist/features/chat/queries/use-list-conversations-query.js +14 -0
  173. package/dist/features/chat/store.d.ts +13 -0
  174. package/dist/features/chat/store.js +1 -0
  175. package/dist/features/chat/utils.d.ts +5 -0
  176. package/dist/features/chat/utils.js +1 -0
  177. package/dist/features/data-fetching/use-api-client.d.ts +5 -0
  178. package/dist/features/data-fetching/use-api-client.js +14 -0
  179. package/dist/features/logger/logger.d.ts +9 -0
  180. package/dist/features/logger/logger.js +1 -0
  181. package/dist/features/molecule/chatsdk-provider.d.ts +19 -0
  182. package/dist/features/molecule/chatsdk-provider.js +26 -0
  183. package/dist/features/molecule/constants.d.ts +3 -0
  184. package/dist/features/molecule/constants.js +1 -0
  185. package/dist/features/molecule/molecule-provider.d.ts +39 -0
  186. package/dist/features/molecule/molecule-provider.js +1 -0
  187. package/dist/features/molecule/store.d.ts +53 -0
  188. package/dist/features/molecule/store.js +3 -0
  189. package/dist/features/molecule/types/api.d.ts +8 -0
  190. package/dist/features/molecule/types/api.js +1 -0
  191. package/dist/features/molecule/types/callbacks.d.ts +22 -0
  192. package/dist/features/molecule/types/callbacks.js +1 -0
  193. package/dist/features/molecule/types/config.d.ts +10 -0
  194. package/dist/features/molecule/types/config.js +1 -0
  195. package/dist/features/molecule/types/context.d.ts +11 -0
  196. package/dist/features/molecule/types/context.js +1 -0
  197. package/dist/features/molecule/types/locale.d.ts +9 -0
  198. package/dist/features/molecule/types/locale.js +1 -0
  199. package/dist/features/molecule/types/theme.d.ts +38 -0
  200. package/dist/features/molecule/types/theme.js +1 -0
  201. package/dist/features/molecule/types/translations.d.ts +10 -0
  202. package/dist/features/molecule/types/translations.js +1 -0
  203. package/dist/features/molecule/use-merge-global-config.d.ts +22 -0
  204. package/dist/features/molecule/use-merge-global-config.js +5 -0
  205. package/dist/features/molecule/use-molecule-config.d.ts +41 -0
  206. package/dist/features/molecule/use-molecule-config.js +6 -0
  207. package/dist/features/molecule/utils.d.ts +10 -0
  208. package/dist/features/molecule/utils.js +1 -0
  209. package/dist/i18n/config.d.ts +61 -0
  210. package/dist/i18n/config.js +1 -0
  211. package/dist/i18n/i18next.d.ts +11 -0
  212. package/dist/i18n/i18next.js +2 -0
  213. package/dist/i18n/utils.d.ts +11 -0
  214. package/dist/i18n/utils.js +6 -0
  215. package/dist/index.d.ts +20 -0
  216. package/dist/index.js +20 -0
  217. package/dist/styles.css +6811 -0
  218. package/package.json +123 -0
@@ -0,0 +1,206 @@
1
+ import { Button } from '@chatsdk-dev/ui/components/button';
2
+ import { Spinner } from '@chatsdk-dev/ui/components/spinner';
3
+ import { cn } from '@chatsdk-dev/ui/lib/utils';
4
+ import { SquareIcon, MicIcon } from 'lucide-react';
5
+ import { useState, useRef, useEffect, useCallback } from 'react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var detectSpeechInputMode = () => {
9
+ if (typeof window === "undefined") {
10
+ return "none";
11
+ }
12
+ if ("SpeechRecognition" in window || "webkitSpeechRecognition" in window) {
13
+ return "speech-recognition";
14
+ }
15
+ if ("MediaRecorder" in window && "mediaDevices" in navigator) {
16
+ return "media-recorder";
17
+ }
18
+ return "none";
19
+ };
20
+ var SpeechInput = ({
21
+ className,
22
+ onTranscriptionChange,
23
+ onAudioRecorded,
24
+ lang = "en-US",
25
+ ...props
26
+ }) => {
27
+ const [isListening, setIsListening] = useState(false);
28
+ const [isProcessing, setIsProcessing] = useState(false);
29
+ const [mode] = useState(detectSpeechInputMode);
30
+ const [isRecognitionReady, setIsRecognitionReady] = useState(false);
31
+ const recognitionRef = useRef(null);
32
+ const mediaRecorderRef = useRef(null);
33
+ const streamRef = useRef(null);
34
+ const audioChunksRef = useRef([]);
35
+ const onTranscriptionChangeRef = useRef(onTranscriptionChange);
36
+ const onAudioRecordedRef = useRef(onAudioRecorded);
37
+ onTranscriptionChangeRef.current = onTranscriptionChange;
38
+ onAudioRecordedRef.current = onAudioRecorded;
39
+ useEffect(() => {
40
+ if (mode !== "speech-recognition") {
41
+ return;
42
+ }
43
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
44
+ const speechRecognition = new SpeechRecognition();
45
+ speechRecognition.continuous = true;
46
+ speechRecognition.interimResults = true;
47
+ speechRecognition.lang = lang;
48
+ const handleStart = () => {
49
+ setIsListening(true);
50
+ };
51
+ const handleEnd = () => {
52
+ setIsListening(false);
53
+ };
54
+ const handleResult = (event) => {
55
+ const speechEvent = event;
56
+ let finalTranscript = "";
57
+ for (let i = speechEvent.resultIndex; i < speechEvent.results.length; i += 1) {
58
+ const result = speechEvent.results[i];
59
+ if (result?.isFinal) {
60
+ finalTranscript += result[0]?.transcript ?? "";
61
+ }
62
+ }
63
+ if (finalTranscript) {
64
+ onTranscriptionChangeRef.current?.(finalTranscript);
65
+ }
66
+ };
67
+ const handleError = () => {
68
+ setIsListening(false);
69
+ };
70
+ speechRecognition.addEventListener("start", handleStart);
71
+ speechRecognition.addEventListener("end", handleEnd);
72
+ speechRecognition.addEventListener("result", handleResult);
73
+ speechRecognition.addEventListener("error", handleError);
74
+ recognitionRef.current = speechRecognition;
75
+ setIsRecognitionReady(true);
76
+ return () => {
77
+ speechRecognition.removeEventListener("start", handleStart);
78
+ speechRecognition.removeEventListener("end", handleEnd);
79
+ speechRecognition.removeEventListener("result", handleResult);
80
+ speechRecognition.removeEventListener("error", handleError);
81
+ speechRecognition.stop();
82
+ recognitionRef.current = null;
83
+ setIsRecognitionReady(false);
84
+ };
85
+ }, [mode, lang]);
86
+ useEffect(
87
+ () => () => {
88
+ if (mediaRecorderRef.current?.state === "recording") {
89
+ mediaRecorderRef.current.stop();
90
+ }
91
+ if (streamRef.current) {
92
+ for (const track of streamRef.current.getTracks()) {
93
+ track.stop();
94
+ }
95
+ }
96
+ },
97
+ []
98
+ );
99
+ const startMediaRecorder = useCallback(async () => {
100
+ if (!onAudioRecordedRef.current) {
101
+ return;
102
+ }
103
+ try {
104
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
105
+ streamRef.current = stream;
106
+ const mediaRecorder = new MediaRecorder(stream);
107
+ audioChunksRef.current = [];
108
+ const handleDataAvailable = (event) => {
109
+ if (event.data.size > 0) {
110
+ audioChunksRef.current.push(event.data);
111
+ }
112
+ };
113
+ const handleStop = async () => {
114
+ for (const track of stream.getTracks()) {
115
+ track.stop();
116
+ }
117
+ streamRef.current = null;
118
+ const audioBlob = new Blob(audioChunksRef.current, {
119
+ type: "audio/webm"
120
+ });
121
+ if (audioBlob.size > 0 && onAudioRecordedRef.current) {
122
+ setIsProcessing(true);
123
+ try {
124
+ const transcript = await onAudioRecordedRef.current(audioBlob);
125
+ if (transcript) {
126
+ onTranscriptionChangeRef.current?.(transcript);
127
+ }
128
+ } catch {
129
+ } finally {
130
+ setIsProcessing(false);
131
+ }
132
+ }
133
+ };
134
+ const handleError = () => {
135
+ setIsListening(false);
136
+ for (const track of stream.getTracks()) {
137
+ track.stop();
138
+ }
139
+ streamRef.current = null;
140
+ };
141
+ mediaRecorder.addEventListener("dataavailable", handleDataAvailable);
142
+ mediaRecorder.addEventListener("stop", handleStop);
143
+ mediaRecorder.addEventListener("error", handleError);
144
+ mediaRecorderRef.current = mediaRecorder;
145
+ mediaRecorder.start();
146
+ setIsListening(true);
147
+ } catch {
148
+ setIsListening(false);
149
+ }
150
+ }, []);
151
+ const stopMediaRecorder = useCallback(() => {
152
+ if (mediaRecorderRef.current?.state === "recording") {
153
+ mediaRecorderRef.current.stop();
154
+ }
155
+ setIsListening(false);
156
+ }, []);
157
+ const toggleListening = useCallback(() => {
158
+ if (mode === "speech-recognition" && recognitionRef.current) {
159
+ if (isListening) {
160
+ recognitionRef.current.stop();
161
+ } else {
162
+ recognitionRef.current.start();
163
+ }
164
+ } else if (mode === "media-recorder") {
165
+ if (isListening) {
166
+ stopMediaRecorder();
167
+ } else {
168
+ startMediaRecorder();
169
+ }
170
+ }
171
+ }, [mode, isListening, startMediaRecorder, stopMediaRecorder]);
172
+ const isDisabled = mode === "none" || mode === "speech-recognition" && !isRecognitionReady || mode === "media-recorder" && !onAudioRecorded || isProcessing;
173
+ return /* @__PURE__ */ jsxs("div", { className: "relative inline-flex items-center justify-center", children: [
174
+ isListening && [0, 1, 2].map((index) => /* @__PURE__ */ jsx(
175
+ "div",
176
+ {
177
+ className: "absolute inset-0 animate-ping rounded-full border-2 border-red-400/30",
178
+ style: {
179
+ animationDelay: `${index * 0.3}s`,
180
+ animationDuration: "2s"
181
+ }
182
+ },
183
+ index
184
+ )),
185
+ /* @__PURE__ */ jsxs(
186
+ Button,
187
+ {
188
+ className: cn(
189
+ "relative z-10 rounded-full transition-all duration-300",
190
+ isListening ? "bg-destructive text-white hover:bg-destructive/80 hover:text-white" : "bg-primary text-primary-foreground hover:bg-primary/80 hover:text-primary-foreground",
191
+ className
192
+ ),
193
+ disabled: isDisabled,
194
+ onClick: toggleListening,
195
+ ...props,
196
+ children: [
197
+ isProcessing && /* @__PURE__ */ jsx(Spinner, {}),
198
+ !isProcessing && isListening && /* @__PURE__ */ jsx(SquareIcon, { className: "size-4" }),
199
+ !(isProcessing || isListening) && /* @__PURE__ */ jsx(MicIcon, { className: "size-4" })
200
+ ]
201
+ }
202
+ )
203
+ ] });
204
+ };
205
+
206
+ export { SpeechInput };
@@ -0,0 +1,42 @@
1
+ import * as react from 'react';
2
+ import { ComponentProps } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Button } from '@chatsdk-dev/ui/components/button';
5
+ import { CollapsibleContent, CollapsibleTrigger } from '@chatsdk-dev/ui/components/collapsible';
6
+
7
+ type StackTraceProps = ComponentProps<"div"> & {
8
+ trace: string;
9
+ open?: boolean;
10
+ defaultOpen?: boolean;
11
+ onOpenChange?: (open: boolean) => void;
12
+ onFilePathClick?: (filePath: string, line?: number, column?: number) => void;
13
+ };
14
+ declare const StackTrace: react.MemoExoticComponent<({ trace, className, open, defaultOpen, onOpenChange, onFilePathClick, children, ...props }: StackTraceProps) => react_jsx_runtime.JSX.Element>;
15
+ type StackTraceHeaderProps = ComponentProps<typeof CollapsibleTrigger>;
16
+ declare const StackTraceHeader: react.MemoExoticComponent<({ className, children, ...props }: StackTraceHeaderProps) => react_jsx_runtime.JSX.Element>;
17
+ type StackTraceErrorProps = ComponentProps<"div">;
18
+ declare const StackTraceError: react.MemoExoticComponent<({ className, children, ...props }: StackTraceErrorProps) => react_jsx_runtime.JSX.Element>;
19
+ type StackTraceErrorTypeProps = ComponentProps<"span">;
20
+ declare const StackTraceErrorType: react.MemoExoticComponent<({ className, children, ...props }: StackTraceErrorTypeProps) => react_jsx_runtime.JSX.Element>;
21
+ type StackTraceErrorMessageProps = ComponentProps<"span">;
22
+ declare const StackTraceErrorMessage: react.MemoExoticComponent<({ className, children, ...props }: StackTraceErrorMessageProps) => react_jsx_runtime.JSX.Element>;
23
+ type StackTraceActionsProps = ComponentProps<"div">;
24
+ declare const StackTraceActions: react.MemoExoticComponent<({ className, children, ...props }: StackTraceActionsProps) => react_jsx_runtime.JSX.Element>;
25
+ type StackTraceCopyButtonProps = ComponentProps<typeof Button> & {
26
+ onCopy?: () => void;
27
+ onError?: (error: Error) => void;
28
+ timeout?: number;
29
+ };
30
+ declare const StackTraceCopyButton: react.MemoExoticComponent<({ onCopy, onError, timeout, className, children, ...props }: StackTraceCopyButtonProps) => react_jsx_runtime.JSX.Element>;
31
+ type StackTraceExpandButtonProps = ComponentProps<"div">;
32
+ declare const StackTraceExpandButton: react.MemoExoticComponent<({ className, ...props }: StackTraceExpandButtonProps) => react_jsx_runtime.JSX.Element>;
33
+ type StackTraceContentProps = ComponentProps<typeof CollapsibleContent> & {
34
+ maxHeight?: number;
35
+ };
36
+ declare const StackTraceContent: react.MemoExoticComponent<({ className, maxHeight, children, ...props }: StackTraceContentProps) => react_jsx_runtime.JSX.Element>;
37
+ type StackTraceFramesProps = ComponentProps<"div"> & {
38
+ showInternalFrames?: boolean;
39
+ };
40
+ declare const StackTraceFrames: react.MemoExoticComponent<({ className, showInternalFrames, ...props }: StackTraceFramesProps) => react_jsx_runtime.JSX.Element>;
41
+
42
+ export { StackTrace, StackTraceActions, type StackTraceActionsProps, StackTraceContent, type StackTraceContentProps, StackTraceCopyButton, type StackTraceCopyButtonProps, StackTraceError, StackTraceErrorMessage, type StackTraceErrorMessageProps, type StackTraceErrorProps, StackTraceErrorType, type StackTraceErrorTypeProps, StackTraceExpandButton, type StackTraceExpandButtonProps, StackTraceFrames, type StackTraceFramesProps, StackTraceHeader, type StackTraceHeaderProps, type StackTraceProps };
@@ -0,0 +1,377 @@
1
+ import { useControllableState } from '@radix-ui/react-use-controllable-state';
2
+ import { Button } from '@chatsdk-dev/ui/components/button';
3
+ import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@chatsdk-dev/ui/components/collapsible';
4
+ import { cn } from '@chatsdk-dev/ui/lib/utils';
5
+ import { AlertTriangleIcon, CheckIcon, CopyIcon, ChevronDownIcon } from 'lucide-react';
6
+ import { createContext, memo, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ var STACK_FRAME_WITH_PARENS_REGEX = /^at\s+(.+?)\s+\((.+):(\d+):(\d+)\)$/;
10
+ var STACK_FRAME_WITHOUT_FN_REGEX = /^at\s+(.+):(\d+):(\d+)$/;
11
+ var ERROR_TYPE_REGEX = /^(\w+Error|Error):\s*(.*)$/;
12
+ var AT_PREFIX_REGEX = /^at\s+/;
13
+ var StackTraceContext = createContext(null);
14
+ var useStackTrace = () => {
15
+ const context = useContext(StackTraceContext);
16
+ if (!context) {
17
+ throw new Error("StackTrace components must be used within StackTrace");
18
+ }
19
+ return context;
20
+ };
21
+ var parseStackFrame = (line) => {
22
+ const trimmed = line.trim();
23
+ const withParensMatch = trimmed.match(STACK_FRAME_WITH_PARENS_REGEX);
24
+ if (withParensMatch) {
25
+ const [, functionName, filePath, lineNum, colNum] = withParensMatch;
26
+ const isInternal = filePath?.includes("node_modules") || filePath?.startsWith("node:") || !!filePath?.includes("internal/");
27
+ return {
28
+ columnNumber: colNum ? Number.parseInt(colNum, 10) : null,
29
+ filePath: filePath ?? null,
30
+ functionName: functionName ?? null,
31
+ isInternal,
32
+ lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,
33
+ raw: trimmed
34
+ };
35
+ }
36
+ const withoutFnMatch = trimmed.match(STACK_FRAME_WITHOUT_FN_REGEX);
37
+ if (withoutFnMatch) {
38
+ const [, filePath, lineNum, colNum] = withoutFnMatch;
39
+ const isInternal = (filePath?.includes("node_modules") ?? false) || (filePath?.startsWith("node:") ?? false) || (filePath?.includes("internal/") ?? false);
40
+ return {
41
+ columnNumber: colNum ? Number.parseInt(colNum, 10) : null,
42
+ filePath: filePath ?? null,
43
+ functionName: null,
44
+ isInternal,
45
+ lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,
46
+ raw: trimmed
47
+ };
48
+ }
49
+ return {
50
+ columnNumber: null,
51
+ filePath: null,
52
+ functionName: null,
53
+ isInternal: trimmed.includes("node_modules") || trimmed.includes("node:"),
54
+ lineNumber: null,
55
+ raw: trimmed
56
+ };
57
+ };
58
+ var parseStackTrace = (trace) => {
59
+ const lines = trace.split("\n").filter((line) => line.trim());
60
+ if (lines.length === 0) {
61
+ return {
62
+ errorMessage: trace,
63
+ errorType: null,
64
+ frames: [],
65
+ raw: trace
66
+ };
67
+ }
68
+ const firstLine = lines[0]?.trim() ?? "";
69
+ let errorType = null;
70
+ let errorMessage = firstLine;
71
+ const errorMatch = firstLine.match(ERROR_TYPE_REGEX);
72
+ if (errorMatch) {
73
+ const [, type, msg] = errorMatch;
74
+ errorType = type ?? null;
75
+ errorMessage = msg || "";
76
+ }
77
+ const frames = lines.slice(1).filter((line) => line.trim().startsWith("at ")).map(parseStackFrame);
78
+ return {
79
+ errorMessage,
80
+ errorType,
81
+ frames,
82
+ raw: trace
83
+ };
84
+ };
85
+ var StackTrace = memo(
86
+ ({
87
+ trace,
88
+ className,
89
+ open,
90
+ defaultOpen = false,
91
+ onOpenChange,
92
+ onFilePathClick,
93
+ children,
94
+ ...props
95
+ }) => {
96
+ const [isOpen, setIsOpen] = useControllableState({
97
+ defaultProp: defaultOpen,
98
+ onChange: onOpenChange,
99
+ prop: open
100
+ });
101
+ const parsedTrace = useMemo(() => parseStackTrace(trace), [trace]);
102
+ const contextValue = useMemo(
103
+ () => ({
104
+ isOpen,
105
+ onFilePathClick,
106
+ raw: trace,
107
+ setIsOpen,
108
+ trace: parsedTrace
109
+ }),
110
+ [parsedTrace, trace, isOpen, setIsOpen, onFilePathClick]
111
+ );
112
+ return /* @__PURE__ */ jsx(StackTraceContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
113
+ "div",
114
+ {
115
+ className: cn(
116
+ "not-prose w-full overflow-hidden rounded-lg border bg-background font-mono text-sm",
117
+ className
118
+ ),
119
+ ...props,
120
+ children
121
+ }
122
+ ) });
123
+ }
124
+ );
125
+ var StackTraceHeader = memo(
126
+ ({ className, children, ...props }) => {
127
+ const { isOpen, setIsOpen } = useStackTrace();
128
+ return /* @__PURE__ */ jsx(Collapsible, { onOpenChange: setIsOpen, open: isOpen, children: /* @__PURE__ */ jsx(
129
+ CollapsibleTrigger,
130
+ {
131
+ render: () => /* @__PURE__ */ jsx(
132
+ "button",
133
+ {
134
+ className: cn(
135
+ "flex w-full cursor-pointer items-center gap-3 p-3 text-left transition-colors hover:bg-muted/50",
136
+ className
137
+ ),
138
+ ...props,
139
+ children
140
+ }
141
+ )
142
+ }
143
+ ) });
144
+ }
145
+ );
146
+ var StackTraceError = memo(
147
+ ({ className, children, ...props }) => /* @__PURE__ */ jsxs(
148
+ "div",
149
+ {
150
+ className: cn(
151
+ "flex flex-1 items-center gap-2 overflow-hidden",
152
+ className
153
+ ),
154
+ ...props,
155
+ children: [
156
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4 shrink-0 text-destructive" }),
157
+ children
158
+ ]
159
+ }
160
+ )
161
+ );
162
+ var StackTraceErrorType = memo(
163
+ ({ className, children, ...props }) => {
164
+ const { trace } = useStackTrace();
165
+ return /* @__PURE__ */ jsx(
166
+ "span",
167
+ {
168
+ className: cn("shrink-0 font-semibold text-destructive", className),
169
+ ...props,
170
+ children: children ?? trace.errorType
171
+ }
172
+ );
173
+ }
174
+ );
175
+ var StackTraceErrorMessage = memo(
176
+ ({ className, children, ...props }) => {
177
+ const { trace } = useStackTrace();
178
+ return /* @__PURE__ */ jsx("span", { className: cn("truncate text-foreground", className), ...props, children: children ?? trace.errorMessage });
179
+ }
180
+ );
181
+ var handleActionsClick = (e) => e.stopPropagation();
182
+ var handleActionsKeyDown = (e) => {
183
+ if (e.key === "Enter" || e.key === " ") {
184
+ e.stopPropagation();
185
+ }
186
+ };
187
+ var StackTraceActions = memo(
188
+ ({ className, children, ...props }) => /* @__PURE__ */ jsx(
189
+ "div",
190
+ {
191
+ className: cn("flex shrink-0 items-center gap-1", className),
192
+ onClick: handleActionsClick,
193
+ onKeyDown: handleActionsKeyDown,
194
+ role: "group",
195
+ ...props,
196
+ children
197
+ }
198
+ )
199
+ );
200
+ var StackTraceCopyButton = memo(
201
+ ({
202
+ onCopy,
203
+ onError,
204
+ timeout = 2e3,
205
+ className,
206
+ children,
207
+ ...props
208
+ }) => {
209
+ const [isCopied, setIsCopied] = useState(false);
210
+ const timeoutRef = useRef(0);
211
+ const { raw } = useStackTrace();
212
+ const copyToClipboard = useCallback(async () => {
213
+ if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
214
+ onError?.(new Error("Clipboard API not available"));
215
+ return;
216
+ }
217
+ try {
218
+ await navigator.clipboard.writeText(raw);
219
+ setIsCopied(true);
220
+ onCopy?.();
221
+ timeoutRef.current = window.setTimeout(
222
+ () => setIsCopied(false),
223
+ timeout
224
+ );
225
+ } catch (error) {
226
+ onError?.(error);
227
+ }
228
+ }, [raw, onCopy, onError, timeout]);
229
+ useEffect(
230
+ () => () => {
231
+ window.clearTimeout(timeoutRef.current);
232
+ },
233
+ []
234
+ );
235
+ const Icon = isCopied ? CheckIcon : CopyIcon;
236
+ return /* @__PURE__ */ jsx(
237
+ Button,
238
+ {
239
+ className: cn("size-7", className),
240
+ onClick: copyToClipboard,
241
+ size: "icon",
242
+ variant: "ghost",
243
+ ...props,
244
+ children: children ?? /* @__PURE__ */ jsx(Icon, { size: 14 })
245
+ }
246
+ );
247
+ }
248
+ );
249
+ var StackTraceExpandButton = memo(
250
+ ({ className, ...props }) => {
251
+ const { isOpen } = useStackTrace();
252
+ return /* @__PURE__ */ jsx(
253
+ "div",
254
+ {
255
+ className: cn("flex size-7 items-center justify-center", className),
256
+ ...props,
257
+ children: /* @__PURE__ */ jsx(
258
+ ChevronDownIcon,
259
+ {
260
+ className: cn(
261
+ "size-4 text-muted-foreground transition-transform",
262
+ isOpen ? "rotate-180" : "rotate-0"
263
+ )
264
+ }
265
+ )
266
+ }
267
+ );
268
+ }
269
+ );
270
+ var StackTraceContent = memo(
271
+ ({
272
+ className,
273
+ maxHeight = 400,
274
+ children,
275
+ ...props
276
+ }) => {
277
+ const { isOpen } = useStackTrace();
278
+ return /* @__PURE__ */ jsx(Collapsible, { open: isOpen, children: /* @__PURE__ */ jsx(
279
+ CollapsibleContent,
280
+ {
281
+ className: cn(
282
+ "overflow-auto border-t bg-muted/30",
283
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=open]:animate-in",
284
+ className
285
+ ),
286
+ style: { maxHeight },
287
+ ...props,
288
+ children
289
+ }
290
+ ) });
291
+ }
292
+ );
293
+ var FilePathButton = memo(
294
+ ({ frame, onFilePathClick }) => {
295
+ const handleClick = useCallback(() => {
296
+ if (frame.filePath) {
297
+ onFilePathClick?.(
298
+ frame.filePath,
299
+ frame.lineNumber ?? void 0,
300
+ frame.columnNumber ?? void 0
301
+ );
302
+ }
303
+ }, [frame, onFilePathClick]);
304
+ return /* @__PURE__ */ jsxs(
305
+ "button",
306
+ {
307
+ className: cn(
308
+ "underline decoration-dotted hover:text-primary",
309
+ onFilePathClick && "cursor-pointer"
310
+ ),
311
+ disabled: !onFilePathClick,
312
+ onClick: handleClick,
313
+ type: "button",
314
+ children: [
315
+ frame.filePath,
316
+ frame.lineNumber !== null && `:${frame.lineNumber}`,
317
+ frame.columnNumber !== null && `:${frame.columnNumber}`
318
+ ]
319
+ }
320
+ );
321
+ }
322
+ );
323
+ FilePathButton.displayName = "FilePathButton";
324
+ var StackTraceFrames = memo(
325
+ ({
326
+ className,
327
+ showInternalFrames = true,
328
+ ...props
329
+ }) => {
330
+ const { trace, onFilePathClick } = useStackTrace();
331
+ const framesToShow = showInternalFrames ? trace.frames : trace.frames.filter((f) => !f.isInternal);
332
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1 p-3", className), ...props, children: [
333
+ framesToShow.map((frame) => /* @__PURE__ */ jsxs(
334
+ "div",
335
+ {
336
+ className: cn(
337
+ "text-xs",
338
+ frame.isInternal ? "text-muted-foreground/50" : "text-foreground/90"
339
+ ),
340
+ children: [
341
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "at " }),
342
+ frame.functionName && /* @__PURE__ */ jsxs("span", { className: frame.isInternal ? "" : "text-foreground", children: [
343
+ frame.functionName,
344
+ " "
345
+ ] }),
346
+ frame.filePath && /* @__PURE__ */ jsxs(Fragment, { children: [
347
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "(" }),
348
+ /* @__PURE__ */ jsx(
349
+ FilePathButton,
350
+ {
351
+ frame,
352
+ onFilePathClick
353
+ }
354
+ ),
355
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: ")" })
356
+ ] }),
357
+ !(frame.filePath || frame.functionName) && /* @__PURE__ */ jsx("span", { children: frame.raw.replace(AT_PREFIX_REGEX, "") })
358
+ ]
359
+ },
360
+ frame.raw
361
+ )),
362
+ framesToShow.length === 0 && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground text-xs", children: "No stack frames" })
363
+ ] });
364
+ }
365
+ );
366
+ StackTrace.displayName = "StackTrace";
367
+ StackTraceHeader.displayName = "StackTraceHeader";
368
+ StackTraceError.displayName = "StackTraceError";
369
+ StackTraceErrorType.displayName = "StackTraceErrorType";
370
+ StackTraceErrorMessage.displayName = "StackTraceErrorMessage";
371
+ StackTraceActions.displayName = "StackTraceActions";
372
+ StackTraceCopyButton.displayName = "StackTraceCopyButton";
373
+ StackTraceExpandButton.displayName = "StackTraceExpandButton";
374
+ StackTraceContent.displayName = "StackTraceContent";
375
+ StackTraceFrames.displayName = "StackTraceFrames";
376
+
377
+ export { StackTrace, StackTraceActions, StackTraceContent, StackTraceCopyButton, StackTraceError, StackTraceErrorMessage, StackTraceErrorType, StackTraceExpandButton, StackTraceFrames, StackTraceHeader };
@@ -0,0 +1,14 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { Button } from '@chatsdk-dev/ui/components/button';
3
+ import { ScrollArea } from '@chatsdk-dev/ui/components/scroll-area';
4
+ import { ComponentProps } from 'react';
5
+
6
+ type SuggestionsProps = ComponentProps<typeof ScrollArea>;
7
+ declare const Suggestions: ({ className, children, ...props }: SuggestionsProps) => react_jsx_runtime.JSX.Element;
8
+ type SuggestionProps = Omit<ComponentProps<typeof Button>, "onClick"> & {
9
+ suggestion: string;
10
+ onClick?: (suggestion: string) => void;
11
+ };
12
+ declare const Suggestion: ({ suggestion, onClick, className, variant, size, children, ...props }: SuggestionProps) => react_jsx_runtime.JSX.Element;
13
+
14
+ export { Suggestion, type SuggestionProps, Suggestions, type SuggestionsProps };
@@ -0,0 +1,41 @@
1
+ import { Button } from '@chatsdk-dev/ui/components/button';
2
+ import { ScrollArea, ScrollBar } from '@chatsdk-dev/ui/components/scroll-area';
3
+ import { cn } from '@chatsdk-dev/ui/lib/utils';
4
+ import { useCallback } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var Suggestions = ({
8
+ className,
9
+ children,
10
+ ...props
11
+ }) => /* @__PURE__ */ jsxs(ScrollArea, { className: "w-full overflow-x-auto whitespace-nowrap", ...props, children: [
12
+ /* @__PURE__ */ jsx("div", { className: cn("flex w-max flex-nowrap items-center gap-2", className), children }),
13
+ /* @__PURE__ */ jsx(ScrollBar, { className: "hidden", orientation: "horizontal" })
14
+ ] });
15
+ var Suggestion = ({
16
+ suggestion,
17
+ onClick,
18
+ className,
19
+ variant = "outline",
20
+ size = "sm",
21
+ children,
22
+ ...props
23
+ }) => {
24
+ const handleClick = useCallback(() => {
25
+ onClick?.(suggestion);
26
+ }, [onClick, suggestion]);
27
+ return /* @__PURE__ */ jsx(
28
+ Button,
29
+ {
30
+ className: cn("cursor-pointer rounded-full px-4", className),
31
+ onClick: handleClick,
32
+ size,
33
+ type: "button",
34
+ variant,
35
+ ...props,
36
+ children: children || suggestion
37
+ }
38
+ );
39
+ };
40
+
41
+ export { Suggestion, Suggestions };