@assistant-ui/react 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js DELETED
@@ -1,1509 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- ActionBarPrimitive: () => actionBar_exports,
34
- AssistantRuntimeProvider: () => AssistantRuntimeProvider,
35
- BranchPickerPrimitive: () => branchPicker_exports,
36
- ComposerPrimitive: () => composer_exports,
37
- ContentPartPrimitive: () => contentPart_exports,
38
- INTERNAL: () => internal_exports,
39
- MessagePrimitive: () => message_exports,
40
- ThreadPrimitive: () => thread_exports,
41
- useBeginMessageEdit: () => useBeginMessageEdit,
42
- useCopyMessage: () => useCopyMessage,
43
- useGoToNextBranch: () => useGoToNextBranch,
44
- useGoToPreviousBranch: () => useGoToPreviousBranch,
45
- useLocalRuntime: () => useLocalRuntime,
46
- useReloadMessage: () => useReloadMessage
47
- });
48
- module.exports = __toCommonJS(src_exports);
49
-
50
- // src/actions/useCopyMessage.tsx
51
- var import_react4 = require("react");
52
-
53
- // src/context/MessageContext.ts
54
- var import_react = require("react");
55
- var MessageContext = (0, import_react.createContext)(null);
56
- var useMessageContext = () => {
57
- const context = (0, import_react.useContext)(MessageContext);
58
- if (!context)
59
- throw new Error(
60
- "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
61
- );
62
- return context;
63
- };
64
-
65
- // src/utils/combined/useCombinedStore.ts
66
- var import_react3 = require("react");
67
-
68
- // src/utils/combined/createCombinedStore.ts
69
- var import_react2 = require("react");
70
- var createCombinedStore = (stores) => {
71
- const subscribe = (callback) => {
72
- const unsubscribes = stores.map((store) => store.subscribe(callback));
73
- return () => {
74
- for (const unsub of unsubscribes) {
75
- unsub();
76
- }
77
- };
78
- };
79
- return (selector) => {
80
- const getSnapshot = () => selector(...stores.map((store) => store.getState()));
81
- return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
82
- };
83
- };
84
-
85
- // src/utils/combined/useCombinedStore.ts
86
- var useCombinedStore = (stores, selector) => {
87
- const useCombined = (0, import_react3.useMemo)(() => createCombinedStore(stores), stores);
88
- return useCombined(selector);
89
- };
90
-
91
- // src/utils/getMessageText.tsx
92
- var getMessageText = (message) => {
93
- const textParts = message.content.filter(
94
- (part) => part.type === "text"
95
- );
96
- return textParts.map((part) => part.text).join("\n\n");
97
- };
98
-
99
- // src/actions/useCopyMessage.tsx
100
- var useCopyMessage = ({ copiedDuration = 3e3 }) => {
101
- const { useMessage, useComposer } = useMessageContext();
102
- const hasCopyableContent = useCombinedStore(
103
- [useMessage, useComposer],
104
- (m, c) => {
105
- return c.isEditing || m.message.content.some((c2) => c2.type === "text");
106
- }
107
- );
108
- const callback = (0, import_react4.useCallback)(() => {
109
- const { isEditing, value: composerValue } = useComposer.getState();
110
- const { message, setIsCopied } = useMessage.getState();
111
- const valueToCopy = isEditing ? composerValue : getMessageText(message);
112
- navigator.clipboard.writeText(valueToCopy);
113
- setIsCopied(true);
114
- setTimeout(() => setIsCopied(false), copiedDuration);
115
- }, [useComposer, useMessage, copiedDuration]);
116
- if (!hasCopyableContent) return null;
117
- return callback;
118
- };
119
-
120
- // src/actions/useReloadMessage.tsx
121
- var import_react6 = require("react");
122
-
123
- // src/context/ThreadContext.ts
124
- var import_react5 = require("react");
125
- var ThreadContext = (0, import_react5.createContext)(null);
126
- var useThreadContext = () => {
127
- const context = (0, import_react5.useContext)(ThreadContext);
128
- if (!context)
129
- throw new Error("This component must be used within an AssistantRuntimeProvider.");
130
- return context;
131
- };
132
-
133
- // src/actions/useReloadMessage.tsx
134
- var useReloadMessage = () => {
135
- const { useThread, useViewport } = useThreadContext();
136
- const { useMessage } = useMessageContext();
137
- const disabled = useCombinedStore(
138
- [useThread, useMessage],
139
- (t, m) => t.isRunning || m.message.role !== "assistant"
140
- );
141
- const callback = (0, import_react6.useCallback)(() => {
142
- const { parentId } = useMessage.getState();
143
- useThread.getState().startRun(parentId);
144
- useViewport.getState().scrollToBottom();
145
- }, [useMessage, useThread, useViewport]);
146
- if (disabled) return null;
147
- return callback;
148
- };
149
-
150
- // src/actions/useBeginMessageEdit.tsx
151
- var import_react7 = require("react");
152
- var useBeginMessageEdit = () => {
153
- const { useMessage, useComposer } = useMessageContext();
154
- const disabled = useCombinedStore(
155
- [useMessage, useComposer],
156
- (m, c) => m.message.role !== "user" || c.isEditing
157
- );
158
- const callback = (0, import_react7.useCallback)(() => {
159
- const { edit } = useComposer.getState();
160
- edit();
161
- }, [useComposer]);
162
- if (disabled) return null;
163
- return callback;
164
- };
165
-
166
- // src/actions/useGoToNextBranch.tsx
167
- var import_react8 = require("react");
168
- var useGoToNextBranch = () => {
169
- const { useThread } = useThreadContext();
170
- const { useMessage, useComposer } = useMessageContext();
171
- const disabled = useCombinedStore(
172
- [useMessage, useComposer],
173
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
174
- );
175
- const callback = (0, import_react8.useCallback)(() => {
176
- const { message, branches } = useMessage.getState();
177
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
178
- }, [useMessage, useThread]);
179
- if (disabled) return null;
180
- return callback;
181
- };
182
-
183
- // src/actions/useGoToPreviousBranch.tsx
184
- var import_react9 = require("react");
185
- var useGoToPreviousBranch = () => {
186
- const { useThread } = useThreadContext();
187
- const { useMessage, useComposer } = useMessageContext();
188
- const disabled = useCombinedStore(
189
- [useMessage, useComposer],
190
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
191
- );
192
- const callback = (0, import_react9.useCallback)(() => {
193
- const { message, branches } = useMessage.getState();
194
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
195
- }, [useMessage, useThread]);
196
- if (disabled) return null;
197
- return callback;
198
- };
199
-
200
- // src/primitives/thread/index.ts
201
- var thread_exports = {};
202
- __export(thread_exports, {
203
- Empty: () => ThreadEmpty,
204
- If: () => ThreadIf,
205
- Messages: () => ThreadMessages,
206
- Root: () => ThreadRoot,
207
- ScrollToBottom: () => ThreadScrollToBottom,
208
- Suggestion: () => ThreadSuggestion,
209
- Viewport: () => ThreadViewport
210
- });
211
-
212
- // src/primitives/thread/ThreadRoot.tsx
213
- var import_react_primitive = require("@radix-ui/react-primitive");
214
- var import_react10 = require("react");
215
- var import_jsx_runtime = require("react/jsx-runtime");
216
- var ThreadRoot = (0, import_react10.forwardRef)(
217
- (props, ref) => {
218
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref });
219
- }
220
- );
221
-
222
- // src/primitives/thread/ThreadIf.tsx
223
- var useThreadIf = (props) => {
224
- const { useThread } = useThreadContext();
225
- return useThread((thread) => {
226
- if (props.empty === true && thread.messages.length !== 0) return false;
227
- if (props.empty === false && thread.messages.length === 0) return false;
228
- if (props.running === true && !thread.isRunning) return false;
229
- if (props.running === false && thread.isRunning) return false;
230
- return true;
231
- });
232
- };
233
- var ThreadIf = ({ children, ...query }) => {
234
- const result = useThreadIf(query);
235
- return result ? children : null;
236
- };
237
-
238
- // src/primitives/thread/ThreadEmpty.tsx
239
- var import_jsx_runtime2 = require("react/jsx-runtime");
240
- var ThreadEmpty = ({ children }) => {
241
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThreadIf, { empty: true, children });
242
- };
243
-
244
- // src/primitives/thread/ThreadViewport.tsx
245
- var import_primitive = require("@radix-ui/primitive");
246
- var import_react_compose_refs = require("@radix-ui/react-compose-refs");
247
- var import_react_primitive2 = require("@radix-ui/react-primitive");
248
- var import_react13 = require("react");
249
-
250
- // src/utils/hooks/useOnResizeContent.tsx
251
- var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
252
- var import_react11 = require("react");
253
- var useOnResizeContent = (ref, callback) => {
254
- const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
255
- (0, import_react11.useEffect)(() => {
256
- const el = ref.current;
257
- if (!el) return;
258
- const resizeObserver = new ResizeObserver(() => {
259
- callbackRef();
260
- });
261
- const mutationObserver = new MutationObserver((mutations) => {
262
- for (const mutation of mutations) {
263
- for (const node of mutation.addedNodes) {
264
- if (node instanceof Element) {
265
- resizeObserver.observe(node);
266
- }
267
- }
268
- for (const node of mutation.removedNodes) {
269
- if (node instanceof Element) {
270
- resizeObserver.unobserve(node);
271
- }
272
- }
273
- }
274
- callbackRef();
275
- });
276
- resizeObserver.observe(el);
277
- mutationObserver.observe(el, { childList: true });
278
- for (const child of el.children) {
279
- resizeObserver.observe(child);
280
- }
281
- return () => {
282
- resizeObserver.disconnect();
283
- mutationObserver.disconnect();
284
- };
285
- }, [ref.current, callbackRef]);
286
- };
287
-
288
- // src/utils/hooks/useOnScrollToBottom.tsx
289
- var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
290
- var import_react12 = require("react");
291
- var useOnScrollToBottom = (callback) => {
292
- const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
293
- const { useViewport } = useThreadContext();
294
- (0, import_react12.useEffect)(() => {
295
- return useViewport.getState().onScrollToBottom(() => {
296
- callbackRef();
297
- });
298
- }, [useViewport, callbackRef]);
299
- };
300
-
301
- // src/primitives/thread/ThreadViewport.tsx
302
- var import_jsx_runtime3 = require("react/jsx-runtime");
303
- var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
304
- const messagesEndRef = (0, import_react13.useRef)(null);
305
- const divRef = (0, import_react13.useRef)(null);
306
- const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
307
- const { useViewport } = useThreadContext();
308
- const firstRenderRef = (0, import_react13.useRef)(true);
309
- const isScrollingToBottomRef = (0, import_react13.useRef)(false);
310
- const lastScrollTop = (0, import_react13.useRef)(0);
311
- const scrollToBottom = () => {
312
- const div = messagesEndRef.current;
313
- if (!div || !autoScroll) return;
314
- const behavior = firstRenderRef.current ? "instant" : "auto";
315
- firstRenderRef.current = false;
316
- isScrollingToBottomRef.current = true;
317
- div.scrollIntoView({ behavior });
318
- };
319
- useOnResizeContent(divRef, () => {
320
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
321
- handleScroll();
322
- } else {
323
- scrollToBottom();
324
- }
325
- });
326
- useOnScrollToBottom(() => {
327
- scrollToBottom();
328
- });
329
- const handleScroll = () => {
330
- const div = divRef.current;
331
- if (!div) return;
332
- const isAtBottom = useViewport.getState().isAtBottom;
333
- const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
334
- if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
335
- } else if (newIsAtBottom !== isAtBottom) {
336
- isScrollingToBottomRef.current = false;
337
- useViewport.setState({ isAtBottom: newIsAtBottom });
338
- }
339
- lastScrollTop.current = div.scrollTop;
340
- };
341
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
342
- import_react_primitive2.Primitive.div,
343
- {
344
- ...rest,
345
- onScroll: (0, import_primitive.composeEventHandlers)(onScroll, handleScroll),
346
- ref,
347
- children: [
348
- children,
349
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: messagesEndRef })
350
- ]
351
- }
352
- );
353
- });
354
-
355
- // src/context/providers/MessageProvider.tsx
356
- var import_react14 = require("react");
357
- var import_zustand2 = require("zustand");
358
-
359
- // src/context/stores/MessageComposer.ts
360
- var import_zustand = require("zustand");
361
-
362
- // src/context/stores/BaseComposer.ts
363
- var makeBaseComposer = (set) => ({
364
- value: "",
365
- setValue: (value) => {
366
- set({ value });
367
- }
368
- });
369
-
370
- // src/context/stores/MessageComposer.ts
371
- var makeEditComposerStore = ({
372
- onEdit,
373
- onSend
374
- }) => (0, import_zustand.create)()((set, get, store) => ({
375
- ...makeBaseComposer(set, get, store),
376
- isEditing: false,
377
- edit: () => {
378
- const value = onEdit();
379
- set({ isEditing: true, value });
380
- },
381
- send: () => {
382
- const value = get().value;
383
- set({ isEditing: false });
384
- onSend(value);
385
- },
386
- cancel: () => {
387
- if (!get().isEditing) return false;
388
- set({ isEditing: false });
389
- return true;
390
- }
391
- }));
392
-
393
- // src/context/providers/MessageProvider.tsx
394
- var import_jsx_runtime4 = require("react/jsx-runtime");
395
- var getIsLast = (thread, message) => {
396
- return thread.messages[thread.messages.length - 1]?.id === message.id;
397
- };
398
- var syncMessage = (thread, useMessage, messageIndex) => {
399
- const parentId = thread.messages[messageIndex - 1]?.id ?? null;
400
- const message = thread.messages[messageIndex];
401
- if (!message) return;
402
- const isLast = getIsLast(thread, message);
403
- const branches = thread.getBranches(message.id);
404
- const currentState = useMessage.getState();
405
- if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
406
- return;
407
- useMessage.setState({
408
- message,
409
- parentId,
410
- branches,
411
- isLast
412
- });
413
- };
414
- var useMessageContext2 = (messageIndex) => {
415
- const { useThread } = useThreadContext();
416
- const [context] = (0, import_react14.useState)(() => {
417
- const useMessage = (0, import_zustand2.create)((set) => ({
418
- message: null,
419
- parentId: null,
420
- branches: [],
421
- isLast: false,
422
- inProgressIndicator: null,
423
- isCopied: false,
424
- isHovering: false,
425
- setInProgressIndicator: (value) => {
426
- set({ inProgressIndicator: value });
427
- },
428
- setIsCopied: (value) => {
429
- set({ isCopied: value });
430
- },
431
- setIsHovering: (value) => {
432
- set({ isHovering: value });
433
- }
434
- }));
435
- const useComposer = makeEditComposerStore({
436
- onEdit: () => {
437
- const message = useMessage.getState().message;
438
- if (message.role !== "user")
439
- throw new Error(
440
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
441
- );
442
- const text = getMessageText(message);
443
- return text;
444
- },
445
- onSend: (text) => {
446
- const { message, parentId } = useMessage.getState();
447
- if (message.role !== "user")
448
- throw new Error(
449
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
450
- );
451
- const nonTextParts = message.content.filter(
452
- (part) => part.type !== "text" && part.type !== "ui"
453
- );
454
- useThread.getState().append({
455
- parentId,
456
- content: [{ type: "text", text }, ...nonTextParts]
457
- });
458
- }
459
- });
460
- syncMessage(useThread.getState(), useMessage, messageIndex);
461
- return { useMessage, useComposer };
462
- });
463
- (0, import_react14.useEffect)(() => {
464
- return useThread.subscribe((thread) => {
465
- syncMessage(thread, context.useMessage, messageIndex);
466
- });
467
- }, [context, useThread, messageIndex]);
468
- return context;
469
- };
470
- var MessageProvider = ({
471
- messageIndex,
472
- children
473
- }) => {
474
- const context = useMessageContext2(messageIndex);
475
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
476
- };
477
-
478
- // src/context/ComposerContext.ts
479
- var import_react15 = require("react");
480
- var useComposerContext = () => {
481
- const { useComposer } = useThreadContext();
482
- const { useComposer: useEditComposer } = (0, import_react15.useContext)(MessageContext) ?? {};
483
- return (0, import_react15.useMemo)(
484
- () => ({
485
- useComposer: useEditComposer ?? useComposer,
486
- type: useEditComposer ? "edit" : "new"
487
- }),
488
- [useEditComposer, useComposer]
489
- );
490
- };
491
-
492
- // src/primitives/composer/ComposerIf.tsx
493
- var useComposerIf = (props) => {
494
- const { useComposer } = useComposerContext();
495
- return useComposer((composer) => {
496
- if (props.editing === true && !composer.isEditing) return false;
497
- if (props.editing === false && composer.isEditing) return false;
498
- return true;
499
- });
500
- };
501
- var ComposerIf = ({ children, ...query }) => {
502
- const result = useComposerIf(query);
503
- return result ? children : null;
504
- };
505
-
506
- // src/primitives/message/MessageIf.tsx
507
- var useMessageIf = (props) => {
508
- const { useMessage } = useMessageContext();
509
- return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
510
- if (props.hasBranches === true && branches.length < 2) return false;
511
- if (props.user && message.role !== "user") return false;
512
- if (props.assistant && message.role !== "assistant") return false;
513
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
514
- if (props.copied === true && !isCopied) return false;
515
- if (props.copied === false && isCopied) return false;
516
- return true;
517
- });
518
- };
519
- var MessageIf = ({ children, ...query }) => {
520
- const result = useMessageIf(query);
521
- return result ? children : null;
522
- };
523
-
524
- // src/primitives/thread/ThreadMessages.tsx
525
- var import_jsx_runtime5 = require("react/jsx-runtime");
526
- var getComponents = (components) => {
527
- return {
528
- EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
529
- UserMessage: components.UserMessage ?? components.Message,
530
- AssistantMessage: components.AssistantMessage ?? components.Message
531
- };
532
- };
533
- var ThreadMessages = ({ components }) => {
534
- const { useThread } = useThreadContext();
535
- const messagesLength = useThread((t) => t.messages.length);
536
- const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
537
- if (messagesLength === 0) return null;
538
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: new Array(messagesLength).fill(null).map((_, idx) => {
539
- const messageIndex = idx;
540
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
541
- MessageProvider,
542
- {
543
- messageIndex,
544
- children: [
545
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageIf, { user: true, children: [
546
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UserMessage, {}) }),
547
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EditComposer, {}) })
548
- ] }),
549
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
550
- ]
551
- },
552
- messageIndex
553
- );
554
- }) });
555
- };
556
-
557
- // src/primitives/thread/ThreadScrollToBottom.tsx
558
- var import_primitive2 = require("@radix-ui/primitive");
559
- var import_react_primitive3 = require("@radix-ui/react-primitive");
560
- var import_react16 = require("react");
561
- var import_jsx_runtime6 = require("react/jsx-runtime");
562
- var ThreadScrollToBottom = (0, import_react16.forwardRef)(({ onClick, ...rest }, ref) => {
563
- const { useViewport } = useThreadContext();
564
- const isAtBottom = useViewport((s) => s.isAtBottom);
565
- const handleScrollToBottom = () => {
566
- useViewport.getState().scrollToBottom();
567
- };
568
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
569
- import_react_primitive3.Primitive.button,
570
- {
571
- ...rest,
572
- disabled: isAtBottom,
573
- ref,
574
- onClick: (0, import_primitive2.composeEventHandlers)(onClick, handleScrollToBottom)
575
- }
576
- );
577
- });
578
-
579
- // src/primitives/thread/ThreadSuggestion.tsx
580
- var import_primitive3 = require("@radix-ui/primitive");
581
- var import_react_primitive4 = require("@radix-ui/react-primitive");
582
- var import_react17 = require("react");
583
- var import_jsx_runtime7 = require("react/jsx-runtime");
584
- var ThreadSuggestion = (0, import_react17.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
585
- const { useThread, useComposer } = useThreadContext();
586
- const isDisabled = useThread((t) => t.isRunning);
587
- const handleApplySuggestion = () => {
588
- const thread = useThread.getState();
589
- const composer = useComposer.getState();
590
- composer.setValue(prompt);
591
- if (send && !thread.isRunning) {
592
- composer.send();
593
- }
594
- };
595
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
596
- import_react_primitive4.Primitive.button,
597
- {
598
- ...rest,
599
- disabled: isDisabled,
600
- ref,
601
- onClick: (0, import_primitive3.composeEventHandlers)(onClick, handleApplySuggestion)
602
- }
603
- );
604
- });
605
-
606
- // src/primitives/composer/index.ts
607
- var composer_exports = {};
608
- __export(composer_exports, {
609
- Cancel: () => ComposerCancel,
610
- If: () => ComposerIf,
611
- Input: () => ComposerInput,
612
- Root: () => ComposerRoot,
613
- Send: () => ComposerSend
614
- });
615
-
616
- // src/primitives/composer/ComposerRoot.tsx
617
- var import_primitive4 = require("@radix-ui/primitive");
618
- var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
619
- var import_react_primitive5 = require("@radix-ui/react-primitive");
620
- var import_react18 = require("react");
621
- var import_jsx_runtime8 = require("react/jsx-runtime");
622
- var ComposerRoot = (0, import_react18.forwardRef)(
623
- ({ onSubmit, ...rest }, forwardedRef) => {
624
- const { useViewport } = useThreadContext();
625
- const { useComposer } = useComposerContext();
626
- const formRef = (0, import_react18.useRef)(null);
627
- const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
628
- const handleSubmit = (e) => {
629
- const composerState = useComposer.getState();
630
- if (!composerState.isEditing) return;
631
- e.preventDefault();
632
- composerState.send();
633
- useViewport.getState().scrollToBottom();
634
- };
635
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
636
- import_react_primitive5.Primitive.form,
637
- {
638
- ...rest,
639
- ref,
640
- onSubmit: (0, import_primitive4.composeEventHandlers)(onSubmit, handleSubmit)
641
- }
642
- );
643
- }
644
- );
645
-
646
- // src/primitives/composer/ComposerInput.tsx
647
- var import_primitive5 = require("@radix-ui/primitive");
648
- var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
649
- var import_react_slot = require("@radix-ui/react-slot");
650
- var import_react19 = require("react");
651
- var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
652
- var import_jsx_runtime9 = require("react/jsx-runtime");
653
- var ComposerInput = (0, import_react19.forwardRef)(
654
- ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
655
- const { useThread, useViewport } = useThreadContext();
656
- const { useComposer, type } = useComposerContext();
657
- const value = useComposer((c) => {
658
- if (!c.isEditing) return "";
659
- return c.value;
660
- });
661
- const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
662
- const handleKeyPress = (e) => {
663
- if (disabled) return;
664
- const composer = useComposer.getState();
665
- if (e.key === "Escape") {
666
- if (useComposer.getState().cancel()) {
667
- e.preventDefault();
668
- }
669
- } else if (e.key === "Enter" && e.shiftKey === false) {
670
- const isRunning = useThread.getState().isRunning;
671
- if (!isRunning) {
672
- e.preventDefault();
673
- composer.send();
674
- useViewport.getState().scrollToBottom();
675
- }
676
- }
677
- };
678
- const textareaRef = (0, import_react19.useRef)(null);
679
- const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
680
- const autoFocusEnabled = autoFocus && !disabled;
681
- const focus = (0, import_react19.useCallback)(() => {
682
- const textarea = textareaRef.current;
683
- if (!textarea || !autoFocusEnabled) return;
684
- textarea.focus();
685
- textarea.setSelectionRange(
686
- textareaRef.current.value.length,
687
- textareaRef.current.value.length
688
- );
689
- }, [autoFocusEnabled]);
690
- (0, import_react19.useEffect)(() => focus(), [focus]);
691
- useOnScrollToBottom(() => {
692
- if (type === "new") {
693
- focus();
694
- }
695
- });
696
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
697
- Component,
698
- {
699
- value,
700
- ...rest,
701
- ref,
702
- disabled,
703
- onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
704
- const composerState = useComposer.getState();
705
- if (!composerState.isEditing) return;
706
- return composerState.setValue(e.target.value);
707
- }),
708
- onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
709
- }
710
- );
711
- }
712
- );
713
-
714
- // src/primitives/composer/ComposerSend.tsx
715
- var import_react_primitive6 = require("@radix-ui/react-primitive");
716
- var import_react20 = require("react");
717
- var import_jsx_runtime10 = require("react/jsx-runtime");
718
- var ComposerSend = (0, import_react20.forwardRef)(
719
- ({ disabled, ...rest }, ref) => {
720
- const { useComposer } = useComposerContext();
721
- const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
722
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
723
- import_react_primitive6.Primitive.button,
724
- {
725
- type: "submit",
726
- ...rest,
727
- ref,
728
- disabled: disabled || !hasValue
729
- }
730
- );
731
- }
732
- );
733
-
734
- // src/primitives/composer/ComposerCancel.tsx
735
- var import_primitive6 = require("@radix-ui/primitive");
736
- var import_react_primitive7 = require("@radix-ui/react-primitive");
737
- var import_react21 = require("react");
738
- var import_jsx_runtime11 = require("react/jsx-runtime");
739
- var ComposerCancel = (0, import_react21.forwardRef)(({ onClick, ...rest }, ref) => {
740
- const { useComposer } = useComposerContext();
741
- const handleCancel = () => {
742
- useComposer.getState().cancel();
743
- };
744
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
745
- import_react_primitive7.Primitive.button,
746
- {
747
- type: "button",
748
- ...rest,
749
- ref,
750
- onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleCancel)
751
- }
752
- );
753
- });
754
-
755
- // src/primitives/message/index.ts
756
- var message_exports = {};
757
- __export(message_exports, {
758
- Content: () => MessageContent,
759
- If: () => MessageIf,
760
- InProgress: () => MessageInProgress,
761
- Root: () => MessageRoot
762
- });
763
-
764
- // src/primitives/message/MessageRoot.tsx
765
- var import_primitive7 = require("@radix-ui/primitive");
766
- var import_react_primitive8 = require("@radix-ui/react-primitive");
767
- var import_react22 = require("react");
768
- var import_jsx_runtime12 = require("react/jsx-runtime");
769
- var MessageRoot = (0, import_react22.forwardRef)(
770
- ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
771
- const { useMessage } = useMessageContext();
772
- const setIsHovering = useMessage((s) => s.setIsHovering);
773
- const handleMouseEnter = () => {
774
- setIsHovering(true);
775
- };
776
- const handleMouseLeave = () => {
777
- setIsHovering(false);
778
- };
779
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
780
- import_react_primitive8.Primitive.div,
781
- {
782
- ...rest,
783
- ref,
784
- onMouseEnter: (0, import_primitive7.composeEventHandlers)(onMouseEnter, handleMouseEnter),
785
- onMouseLeave: (0, import_primitive7.composeEventHandlers)(onMouseLeave, handleMouseLeave)
786
- }
787
- );
788
- }
789
- );
790
-
791
- // src/context/providers/ContentPartProvider.tsx
792
- var import_react24 = require("react");
793
- var import_zustand3 = require("zustand");
794
-
795
- // src/context/ContentPartContext.ts
796
- var import_react23 = require("react");
797
- var ContentPartContext = (0, import_react23.createContext)(
798
- null
799
- );
800
- var useContentPartContext = () => {
801
- const context = (0, import_react23.useContext)(ContentPartContext);
802
- if (!context)
803
- throw new Error(
804
- "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
805
- );
806
- return context;
807
- };
808
-
809
- // src/context/providers/ContentPartProvider.tsx
810
- var import_jsx_runtime13 = require("react/jsx-runtime");
811
- var syncContentPart = ({ message }, useContentPart, partIndex) => {
812
- const part = message.content[partIndex];
813
- if (!part) return;
814
- const messageStatus = message.role === "assistant" ? message.status : "done";
815
- const status = partIndex === message.content.length - 1 ? messageStatus : "done";
816
- useContentPart.setState({ part, status });
817
- };
818
- var useContentPartContext2 = (partIndex) => {
819
- const { useMessage } = useMessageContext();
820
- const [context] = (0, import_react24.useState)(() => {
821
- const useContentPart = (0, import_zustand3.create)(() => ({
822
- part: { type: "text", text: "" },
823
- status: "done"
824
- }));
825
- syncContentPart(useMessage.getState(), useContentPart, partIndex);
826
- return { useContentPart };
827
- });
828
- (0, import_react24.useEffect)(() => {
829
- return useMessage.subscribe((message) => {
830
- syncContentPart(message, context.useContentPart, partIndex);
831
- });
832
- }, [context, useMessage, partIndex]);
833
- return context;
834
- };
835
- var ContentPartProvider = ({
836
- partIndex,
837
- children
838
- }) => {
839
- const context = useContentPartContext2(partIndex);
840
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContentPartContext.Provider, { value: context, children });
841
- };
842
-
843
- // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
844
- var ContentPartInProgressIndicator = () => {
845
- const { useMessage } = useMessageContext();
846
- const { useContentPart } = useContentPartContext();
847
- const indicator = useCombinedStore(
848
- [useMessage, useContentPart],
849
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
850
- );
851
- return indicator;
852
- };
853
-
854
- // src/primitives/message/MessageContent.tsx
855
- var import_jsx_runtime14 = require("react/jsx-runtime");
856
- var defaultComponents = {
857
- Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
858
- part.text,
859
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ContentPartInProgressIndicator, {})
860
- ] }),
861
- Image: () => null,
862
- UI: ({ part }) => part.display,
863
- tools: {
864
- Fallback: () => null
865
- }
866
- };
867
- var MessageContent = ({
868
- components: {
869
- Text = defaultComponents.Text,
870
- Image = defaultComponents.Image,
871
- UI = defaultComponents.UI,
872
- tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
873
- } = {}
874
- }) => {
875
- const { useMessage } = useMessageContext();
876
- const message = useMessage((s) => s.message);
877
- const content = message.content;
878
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: content.map((part, i) => {
879
- const partIndex = i;
880
- const type = part.type;
881
- let component = null;
882
- switch (type) {
883
- case "text":
884
- component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { part });
885
- break;
886
- case "image":
887
- component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Image, { part });
888
- break;
889
- case "ui":
890
- component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(UI, { part });
891
- break;
892
- case "tool-call": {
893
- const Tool = by_name[part.name] || Fallback;
894
- component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Tool, { part });
895
- break;
896
- }
897
- default:
898
- throw new Error(`Unknown content part type: ${type}`);
899
- }
900
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ContentPartProvider, { partIndex, children: component }, partIndex);
901
- }) });
902
- };
903
-
904
- // src/primitives/message/MessageInProgress.tsx
905
- var import_react_primitive9 = require("@radix-ui/react-primitive");
906
- var import_react25 = require("react");
907
- var import_jsx_runtime15 = require("react/jsx-runtime");
908
- var MessageInProgress = (0, import_react25.forwardRef)((props, ref) => {
909
- const { useMessage } = useMessageContext();
910
- (0, import_react25.useMemo)(() => {
911
- useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_primitive9.Primitive.span, { ...props, ref }));
912
- }, [useMessage, props, ref]);
913
- return null;
914
- });
915
-
916
- // src/primitives/branchPicker/index.ts
917
- var branchPicker_exports = {};
918
- __export(branchPicker_exports, {
919
- Count: () => BranchPickerCount,
920
- Next: () => BranchPickerNext,
921
- Number: () => BranchPickerNumber,
922
- Previous: () => BranchPickerPrevious,
923
- Root: () => BranchPickerRoot
924
- });
925
-
926
- // src/utils/createActionButton.tsx
927
- var import_primitive8 = require("@radix-ui/primitive");
928
- var import_react_primitive10 = require("@radix-ui/react-primitive");
929
- var import_react26 = require("react");
930
- var import_jsx_runtime16 = require("react/jsx-runtime");
931
- var createActionButton = (useActionButton) => {
932
- return (0, import_react26.forwardRef)(
933
- (props, forwardedRef) => {
934
- const onClick = useActionButton(props);
935
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
936
- import_react_primitive10.Primitive.button,
937
- {
938
- type: "button",
939
- disabled: !onClick,
940
- ...props,
941
- ref: forwardedRef,
942
- onClick: (0, import_primitive8.composeEventHandlers)(props.onClick, onClick ?? void 0)
943
- }
944
- );
945
- }
946
- );
947
- };
948
-
949
- // src/primitives/branchPicker/BranchPickerNext.tsx
950
- var BranchPickerNext = createActionButton(useGoToNextBranch);
951
-
952
- // src/primitives/branchPicker/BranchPickerPrevious.tsx
953
- var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
954
-
955
- // src/primitives/branchPicker/BranchPickerCount.tsx
956
- var import_jsx_runtime17 = require("react/jsx-runtime");
957
- var BranchPickerCount = () => {
958
- const { useMessage } = useMessageContext();
959
- const branchCount = useMessage((s) => s.branches.length);
960
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: branchCount });
961
- };
962
-
963
- // src/primitives/branchPicker/BranchPickerNumber.tsx
964
- var import_jsx_runtime18 = require("react/jsx-runtime");
965
- var BranchPickerNumber = () => {
966
- const { useMessage } = useMessageContext();
967
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
968
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: branchIdx + 1 });
969
- };
970
-
971
- // src/primitives/branchPicker/BranchPickerRoot.tsx
972
- var import_react_primitive11 = require("@radix-ui/react-primitive");
973
- var import_react27 = require("react");
974
- var import_jsx_runtime19 = require("react/jsx-runtime");
975
- var BranchPickerRoot = (0, import_react27.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
976
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_primitive11.Primitive.div, { ...rest, ref }) });
977
- });
978
-
979
- // src/primitives/actionBar/index.ts
980
- var actionBar_exports = {};
981
- __export(actionBar_exports, {
982
- Copy: () => ActionBarCopy,
983
- Edit: () => ActionBarEdit,
984
- Reload: () => ActionBarReload,
985
- Root: () => ActionBarRoot
986
- });
987
-
988
- // src/primitives/actionBar/ActionBarRoot.tsx
989
- var import_react_primitive12 = require("@radix-ui/react-primitive");
990
- var import_react28 = require("react");
991
- var import_jsx_runtime20 = require("react/jsx-runtime");
992
- var ActionBarRoot = (0, import_react28.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
993
- const { useThread } = useThreadContext();
994
- const { useMessage } = useMessageContext();
995
- const hideAndfloatStatus = useCombinedStore(
996
- [useThread, useMessage],
997
- (t, m) => {
998
- if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
999
- const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1000
- if (!autohideEnabled) return "normal" /* Normal */;
1001
- if (!m.isHovering) return "hidden" /* Hidden */;
1002
- if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1003
- return "floating" /* Floating */;
1004
- return "normal" /* Normal */;
1005
- }
1006
- );
1007
- if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1008
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1009
- import_react_primitive12.Primitive.div,
1010
- {
1011
- "data-floating": hideAndfloatStatus === "floating" /* Floating */,
1012
- ...rest,
1013
- ref
1014
- }
1015
- );
1016
- });
1017
-
1018
- // src/primitives/actionBar/ActionBarCopy.tsx
1019
- var ActionBarCopy = createActionButton(useCopyMessage);
1020
-
1021
- // src/primitives/actionBar/ActionBarReload.tsx
1022
- var ActionBarReload = createActionButton(useReloadMessage);
1023
-
1024
- // src/primitives/actionBar/ActionBarEdit.tsx
1025
- var ActionBarEdit = createActionButton(useBeginMessageEdit);
1026
-
1027
- // src/primitives/contentPart/index.ts
1028
- var contentPart_exports = {};
1029
- __export(contentPart_exports, {
1030
- InProgressIndicator: () => ContentPartInProgressIndicator
1031
- });
1032
-
1033
- // src/runtime/local/useLocalRuntime.tsx
1034
- var import_react29 = require("react");
1035
-
1036
- // src/utils/ModelConfigTypes.ts
1037
- var mergeModelConfigs = (configs) => {
1038
- return configs.reduce((acc, config) => {
1039
- if (config.system) {
1040
- if (acc.system) {
1041
- acc.system += `
1042
-
1043
- ${config.system}`;
1044
- } else {
1045
- acc.system = config.system;
1046
- }
1047
- }
1048
- if (config.tools) {
1049
- acc.tools = { ...acc.tools, ...config.tools };
1050
- }
1051
- return acc;
1052
- }, {});
1053
- };
1054
-
1055
- // src/runtime/utils/idUtils.tsx
1056
- var import_non_secure = require("nanoid/non-secure");
1057
- var generateId = (0, import_non_secure.customAlphabet)(
1058
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
1059
- 7
1060
- );
1061
- var optimisticPrefix = "__optimistic__";
1062
- var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
1063
-
1064
- // src/runtime/utils/MessageRepository.tsx
1065
- var findHead = (message) => {
1066
- if (message.next) return findHead(message.next);
1067
- return message;
1068
- };
1069
- var MessageRepository = class {
1070
- messages = /* @__PURE__ */ new Map();
1071
- // message_id -> item
1072
- head = null;
1073
- root = {
1074
- children: []
1075
- };
1076
- performOp(newParent, child, operation) {
1077
- const parentOrRoot = child.prev ?? this.root;
1078
- const newParentOrRoot = newParent ?? this.root;
1079
- if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
1080
- if (operation !== "link") {
1081
- parentOrRoot.children = parentOrRoot.children.filter(
1082
- (m) => m !== child.current.id
1083
- );
1084
- if (child.prev?.next === child) {
1085
- const fallbackId = child.prev.children.at(-1);
1086
- const fallback = fallbackId ? this.messages.get(fallbackId) : null;
1087
- if (fallback === void 0) {
1088
- throw new Error(
1089
- "MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui."
1090
- );
1091
- }
1092
- child.prev.next = fallback;
1093
- }
1094
- }
1095
- if (operation !== "cut") {
1096
- newParentOrRoot.children = [
1097
- ...newParentOrRoot.children,
1098
- child.current.id
1099
- ];
1100
- if (newParent && (findHead(child) === this.head || newParent.next === null)) {
1101
- newParent.next = child;
1102
- }
1103
- child.prev = newParent;
1104
- }
1105
- }
1106
- getMessages() {
1107
- const messages = new Array(this.head?.level ?? 0);
1108
- for (let current = this.head; current; current = current.prev) {
1109
- messages[current.level] = current.current;
1110
- }
1111
- return messages;
1112
- }
1113
- addOrUpdateMessage(parentId, message) {
1114
- const existingItem = this.messages.get(message.id);
1115
- const prev = parentId ? this.messages.get(parentId) : null;
1116
- if (prev === void 0)
1117
- throw new Error(
1118
- "MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
1119
- );
1120
- if (existingItem) {
1121
- existingItem.current = message;
1122
- this.performOp(prev, existingItem, "relink");
1123
- return;
1124
- }
1125
- const newItem = {
1126
- prev,
1127
- current: message,
1128
- next: null,
1129
- children: [],
1130
- level: prev ? prev.level + 1 : 0
1131
- };
1132
- this.messages.set(message.id, newItem);
1133
- this.performOp(prev, newItem, "link");
1134
- if (this.head === prev) {
1135
- this.head = newItem;
1136
- }
1137
- }
1138
- appendOptimisticMessage(parentId, message) {
1139
- let optimisticId;
1140
- do {
1141
- optimisticId = generateOptimisticId();
1142
- } while (this.messages.has(optimisticId));
1143
- this.addOrUpdateMessage(parentId, {
1144
- ...message,
1145
- id: optimisticId,
1146
- createdAt: /* @__PURE__ */ new Date(),
1147
- ...message.role === "assistant" ? { status: "in_progress" } : void 0
1148
- });
1149
- return optimisticId;
1150
- }
1151
- deleteMessage(messageId, replacementId) {
1152
- const message = this.messages.get(messageId);
1153
- if (!message)
1154
- throw new Error(
1155
- "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
1156
- );
1157
- const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
1158
- if (replacement === void 0)
1159
- throw new Error(
1160
- "MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
1161
- );
1162
- for (const child of message.children) {
1163
- const childMessage = this.messages.get(child);
1164
- if (!childMessage)
1165
- throw new Error(
1166
- "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
1167
- );
1168
- this.performOp(replacement, childMessage, "relink");
1169
- }
1170
- this.performOp(null, message, "cut");
1171
- this.messages.delete(messageId);
1172
- if (this.head === message) {
1173
- this.head = replacement ? findHead(replacement) : null;
1174
- }
1175
- }
1176
- getBranches(messageId) {
1177
- const message = this.messages.get(messageId);
1178
- if (!message)
1179
- throw new Error(
1180
- "MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
1181
- );
1182
- const { children } = message.prev ?? this.root;
1183
- return children;
1184
- }
1185
- switchToBranch(messageId) {
1186
- const message = this.messages.get(messageId);
1187
- if (!message)
1188
- throw new Error(
1189
- "MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui."
1190
- );
1191
- if (message.prev) {
1192
- message.prev.next = message;
1193
- }
1194
- this.head = findHead(message);
1195
- }
1196
- resetHead(messageId) {
1197
- if (messageId === null) {
1198
- this.head = null;
1199
- return;
1200
- }
1201
- const message = this.messages.get(messageId);
1202
- if (!message)
1203
- throw new Error(
1204
- "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
1205
- );
1206
- this.head = message;
1207
- for (let current = message; current; current = current.prev) {
1208
- if (current.prev) {
1209
- current.prev.next = current;
1210
- }
1211
- }
1212
- }
1213
- };
1214
-
1215
- // src/runtime/local/LocalRuntime.tsx
1216
- var LocalRuntime = class {
1217
- constructor(adapter) {
1218
- this.adapter = adapter;
1219
- }
1220
- _subscriptions = /* @__PURE__ */ new Set();
1221
- _configProviders = /* @__PURE__ */ new Set();
1222
- abortController = null;
1223
- repository = new MessageRepository();
1224
- get messages() {
1225
- return this.repository.getMessages();
1226
- }
1227
- get isRunning() {
1228
- return this.abortController != null;
1229
- }
1230
- getBranches(messageId) {
1231
- return this.repository.getBranches(messageId);
1232
- }
1233
- switchToBranch(branchId) {
1234
- this.repository.switchToBranch(branchId);
1235
- this.notifySubscribers();
1236
- }
1237
- async append(message) {
1238
- const userMessageId = generateId();
1239
- const userMessage = {
1240
- id: userMessageId,
1241
- role: "user",
1242
- content: message.content,
1243
- createdAt: /* @__PURE__ */ new Date()
1244
- };
1245
- this.repository.addOrUpdateMessage(message.parentId, userMessage);
1246
- await this.startRun(userMessageId);
1247
- }
1248
- async startRun(parentId) {
1249
- const id = generateId();
1250
- this.repository.resetHead(parentId);
1251
- const messages = this.repository.getMessages();
1252
- const message = {
1253
- id,
1254
- role: "assistant",
1255
- status: "in_progress",
1256
- content: [{ type: "text", text: "" }],
1257
- createdAt: /* @__PURE__ */ new Date()
1258
- };
1259
- this.repository.addOrUpdateMessage(parentId, { ...message });
1260
- this.abortController?.abort();
1261
- this.abortController = new AbortController();
1262
- this.notifySubscribers();
1263
- try {
1264
- const updateHandler = ({ content }) => {
1265
- message.content = content;
1266
- this.repository.addOrUpdateMessage(parentId, { ...message });
1267
- this.notifySubscribers();
1268
- };
1269
- const result = await this.adapter.run({
1270
- messages,
1271
- abortSignal: this.abortController.signal,
1272
- config: mergeModelConfigs([...this._configProviders].map((p) => p())),
1273
- onUpdate: updateHandler
1274
- });
1275
- updateHandler(result);
1276
- message.status = "done";
1277
- this.repository.addOrUpdateMessage(parentId, { ...message });
1278
- } catch (e) {
1279
- message.status = "error";
1280
- this.repository.addOrUpdateMessage(parentId, { ...message });
1281
- console.error(e);
1282
- } finally {
1283
- this.abortController = null;
1284
- this.notifySubscribers();
1285
- }
1286
- }
1287
- cancelRun() {
1288
- if (!this.abortController) return;
1289
- this.abortController.abort();
1290
- this.abortController = null;
1291
- this.notifySubscribers();
1292
- }
1293
- notifySubscribers() {
1294
- for (const callback of this._subscriptions) callback();
1295
- }
1296
- subscribe(callback) {
1297
- this._subscriptions.add(callback);
1298
- return () => this._subscriptions.delete(callback);
1299
- }
1300
- registerModelConfigProvider(provider) {
1301
- this._configProviders.add(provider);
1302
- return () => this._configProviders.delete(provider);
1303
- }
1304
- };
1305
-
1306
- // src/runtime/local/useLocalRuntime.tsx
1307
- var useLocalRuntime = (adapter) => {
1308
- const [runtime] = (0, import_react29.useState)(() => new LocalRuntime(adapter));
1309
- (0, import_react29.useInsertionEffect)(() => {
1310
- runtime.adapter = adapter;
1311
- });
1312
- return runtime;
1313
- };
1314
-
1315
- // src/context/providers/AssistantRuntimeProvider.tsx
1316
- var import_react33 = require("react");
1317
-
1318
- // src/context/providers/AssistantProvider.tsx
1319
- var import_react32 = require("react");
1320
-
1321
- // src/context/AssistantContext.ts
1322
- var import_react30 = require("react");
1323
- var AssistantContext = (0, import_react30.createContext)(
1324
- null
1325
- );
1326
-
1327
- // src/context/stores/AssistantModelConfig.ts
1328
- var import_zustand4 = require("zustand");
1329
-
1330
- // src/utils/ProxyConfigProvider.ts
1331
- var ProxyConfigProvider = class {
1332
- _providers = /* @__PURE__ */ new Set();
1333
- getModelConfig() {
1334
- return mergeModelConfigs([...this._providers].map((p) => p()));
1335
- }
1336
- registerModelConfigProvider(provider) {
1337
- this._providers.add(provider);
1338
- return () => {
1339
- this._providers.delete(provider);
1340
- };
1341
- }
1342
- };
1343
-
1344
- // src/context/stores/AssistantModelConfig.ts
1345
- var makeAssistantModelConfigStore = () => (0, import_zustand4.create)(() => {
1346
- const proxy = new ProxyConfigProvider();
1347
- return {
1348
- getModelConfig: () => {
1349
- return proxy.getModelConfig();
1350
- },
1351
- registerModelConfigProvider: (provider) => {
1352
- return proxy.registerModelConfigProvider(provider);
1353
- }
1354
- };
1355
- });
1356
-
1357
- // src/context/providers/ThreadProvider.tsx
1358
- var import_react31 = require("react");
1359
-
1360
- // src/context/stores/Composer.ts
1361
- var import_zustand5 = require("zustand");
1362
- var makeComposerStore = (useThread) => (0, import_zustand5.create)()((set, get, store) => {
1363
- return {
1364
- ...makeBaseComposer(set, get, store),
1365
- isEditing: true,
1366
- send: () => {
1367
- const { setValue, value } = get();
1368
- setValue("");
1369
- useThread.getState().append({
1370
- parentId: useThread.getState().messages.at(-1)?.id ?? null,
1371
- content: [{ type: "text", text: value }]
1372
- });
1373
- },
1374
- cancel: () => {
1375
- const thread = useThread.getState();
1376
- if (!thread.isRunning) return false;
1377
- useThread.getState().cancelRun();
1378
- return true;
1379
- }
1380
- };
1381
- });
1382
-
1383
- // src/context/stores/Thread.ts
1384
- var import_zustand6 = require("zustand");
1385
- var makeThreadStore = (runtimeRef) => {
1386
- const useThread = (0, import_zustand6.create)(() => ({
1387
- messages: runtimeRef.current.messages,
1388
- isRunning: runtimeRef.current.isRunning,
1389
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1390
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1391
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1392
- append: (message) => runtimeRef.current.append(message),
1393
- cancelRun: () => runtimeRef.current.cancelRun()
1394
- }));
1395
- const onRuntimeUpdate = () => {
1396
- useThread.setState({
1397
- messages: runtimeRef.current.messages,
1398
- isRunning: runtimeRef.current.isRunning
1399
- });
1400
- };
1401
- return {
1402
- useThread,
1403
- onRuntimeUpdate
1404
- };
1405
- };
1406
-
1407
- // src/context/stores/ThreadViewport.tsx
1408
- var import_zustand7 = require("zustand");
1409
- var makeThreadViewportStore = () => {
1410
- const scrollToBottomListeners = /* @__PURE__ */ new Set();
1411
- return (0, import_zustand7.create)(() => ({
1412
- isAtBottom: true,
1413
- scrollToBottom: () => {
1414
- for (const listener of scrollToBottomListeners) {
1415
- listener();
1416
- }
1417
- },
1418
- onScrollToBottom: (callback) => {
1419
- scrollToBottomListeners.add(callback);
1420
- return () => {
1421
- scrollToBottomListeners.delete(callback);
1422
- };
1423
- }
1424
- }));
1425
- };
1426
-
1427
- // src/context/providers/ThreadProvider.tsx
1428
- var import_jsx_runtime21 = require("react/jsx-runtime");
1429
- var ThreadProvider = ({
1430
- children,
1431
- runtime
1432
- }) => {
1433
- const runtimeRef = (0, import_react31.useRef)(runtime);
1434
- (0, import_react31.useInsertionEffect)(() => {
1435
- runtimeRef.current = runtime;
1436
- });
1437
- const [{ context, onRuntimeUpdate }] = (0, import_react31.useState)(() => {
1438
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1439
- const useViewport = makeThreadViewportStore();
1440
- const useComposer = makeComposerStore(useThread);
1441
- return {
1442
- context: {
1443
- useViewport,
1444
- useThread,
1445
- useComposer
1446
- },
1447
- onRuntimeUpdate: onRuntimeUpdate2
1448
- };
1449
- });
1450
- (0, import_react31.useEffect)(() => {
1451
- onRuntimeUpdate();
1452
- return runtime.subscribe(onRuntimeUpdate);
1453
- }, [onRuntimeUpdate, runtime]);
1454
- const RuntimeSynchronizer = runtime.unstable_synchronizer;
1455
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(ThreadContext.Provider, { value: context, children: [
1456
- RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RuntimeSynchronizer, {}),
1457
- children
1458
- ] });
1459
- };
1460
-
1461
- // src/context/providers/AssistantProvider.tsx
1462
- var import_jsx_runtime22 = require("react/jsx-runtime");
1463
- var AssistantProvider = ({ children, runtime }) => {
1464
- const runtimeRef = (0, import_react32.useRef)(runtime);
1465
- (0, import_react32.useInsertionEffect)(() => {
1466
- runtimeRef.current = runtime;
1467
- });
1468
- const [context] = (0, import_react32.useState)(() => {
1469
- const useModelConfig = makeAssistantModelConfigStore();
1470
- return { useModelConfig };
1471
- });
1472
- const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
1473
- (0, import_react32.useEffect)(() => {
1474
- return runtime.registerModelConfigProvider(getModelCOnfig);
1475
- }, [runtime, getModelCOnfig]);
1476
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThreadProvider, { runtime, children }) });
1477
- };
1478
-
1479
- // src/context/providers/AssistantRuntimeProvider.tsx
1480
- var import_jsx_runtime23 = require("react/jsx-runtime");
1481
- var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1482
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantProvider, { runtime, children });
1483
- };
1484
- var AssistantRuntimeProvider = (0, import_react33.memo)(AssistantRuntimeProviderImpl);
1485
-
1486
- // src/internal.ts
1487
- var internal_exports = {};
1488
- __export(internal_exports, {
1489
- MessageRepository: () => MessageRepository,
1490
- ProxyConfigProvider: () => ProxyConfigProvider
1491
- });
1492
- // Annotate the CommonJS export names for ESM import in node:
1493
- 0 && (module.exports = {
1494
- ActionBarPrimitive,
1495
- AssistantRuntimeProvider,
1496
- BranchPickerPrimitive,
1497
- ComposerPrimitive,
1498
- ContentPartPrimitive,
1499
- INTERNAL,
1500
- MessagePrimitive,
1501
- ThreadPrimitive,
1502
- useBeginMessageEdit,
1503
- useCopyMessage,
1504
- useGoToNextBranch,
1505
- useGoToPreviousBranch,
1506
- useLocalRuntime,
1507
- useReloadMessage
1508
- });
1509
- //# sourceMappingURL=index.js.map