@assistant-ui/react 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +71 -62
- package/dist/index.d.ts +71 -62
- package/dist/index.js +462 -407
- package/dist/index.mjs +468 -409
- package/package.json +4 -8
package/dist/index.mjs
CHANGED
@@ -25,92 +25,22 @@ var ThreadRoot = forwardRef(
|
|
25
25
|
}
|
26
26
|
);
|
27
27
|
|
28
|
-
// src/utils/context/
|
29
|
-
import {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
// src/utils/context/shallow.ts
|
38
|
-
function shallow(objA, objB) {
|
39
|
-
if (Object.is(objA, objB)) {
|
40
|
-
return true;
|
41
|
-
}
|
42
|
-
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
43
|
-
return false;
|
44
|
-
}
|
45
|
-
const keysA = Object.keys(objA);
|
46
|
-
if (keysA.length !== Object.keys(objB).length) {
|
47
|
-
return false;
|
48
|
-
}
|
49
|
-
for (const keyA of keysA) {
|
50
|
-
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
51
|
-
return false;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
return true;
|
55
|
-
}
|
56
|
-
|
57
|
-
// src/utils/context/createStoreContext.tsx
|
58
|
-
var createStoreContext = (providerName) => {
|
59
|
-
const context = createContext(null);
|
60
|
-
const StoreProvider = ({ children, ...rest }) => {
|
61
|
-
const unstableContext = rest;
|
62
|
-
const [store] = useState(() => {
|
63
|
-
let state = unstableContext;
|
64
|
-
const listeners = /* @__PURE__ */ new Set();
|
65
|
-
return {
|
66
|
-
subscribe: (cb) => {
|
67
|
-
listeners.add(cb);
|
68
|
-
return () => listeners.delete(cb);
|
69
|
-
},
|
70
|
-
emit: () => {
|
71
|
-
for (const listener of listeners) {
|
72
|
-
listener();
|
73
|
-
}
|
74
|
-
},
|
75
|
-
snapshot: () => {
|
76
|
-
return state;
|
77
|
-
},
|
78
|
-
setState: (value) => {
|
79
|
-
state = value;
|
80
|
-
store.emit();
|
81
|
-
}
|
82
|
-
};
|
83
|
-
});
|
84
|
-
useMemo(
|
85
|
-
() => store.setState(unstableContext),
|
86
|
-
Object.values(unstableContext)
|
87
|
-
);
|
88
|
-
return /* @__PURE__ */ React.createElement(context.Provider, { value: store }, children);
|
89
|
-
};
|
90
|
-
const useStoreContext = (consumerName, selector) => {
|
91
|
-
const store = useContext(context);
|
92
|
-
if (!store)
|
93
|
-
throw new Error(
|
94
|
-
`${consumerName} can only be used inside ${providerName}.`
|
95
|
-
);
|
96
|
-
return useSyncExternalStoreWithSelector(
|
97
|
-
store.subscribe,
|
98
|
-
store.snapshot,
|
99
|
-
store.snapshot,
|
100
|
-
selector,
|
101
|
-
shallow
|
28
|
+
// src/utils/context/AssistantContext.ts
|
29
|
+
import { createContext, useContext } from "react";
|
30
|
+
var AssistantContext = createContext(null);
|
31
|
+
var useAssistantContext = () => {
|
32
|
+
const context = useContext(AssistantContext);
|
33
|
+
if (!context)
|
34
|
+
throw new Error(
|
35
|
+
"useAssistantContext must be used within a AssistantProvider"
|
102
36
|
);
|
103
|
-
|
104
|
-
return [StoreProvider, useStoreContext];
|
37
|
+
return context;
|
105
38
|
};
|
106
39
|
|
107
|
-
// src/utils/context/ThreadContext.ts
|
108
|
-
var [ThreadContextProvider, useThreadContext] = createStoreContext("Thread.Provider");
|
109
|
-
|
110
40
|
// src/primitives/thread/ThreadIf.tsx
|
111
41
|
var useThreadIf = (props) => {
|
112
|
-
|
113
|
-
|
42
|
+
const { useThread } = useAssistantContext();
|
43
|
+
return useThread((thread) => {
|
114
44
|
if (props.empty === true && thread.messages.length !== 0)
|
115
45
|
return false;
|
116
46
|
if (props.empty === false && thread.messages.length === 0)
|
@@ -133,7 +63,7 @@ var ThreadEmpty = ({ children }) => {
|
|
133
63
|
};
|
134
64
|
|
135
65
|
// src/primitives/thread/ThreadViewport.tsx
|
136
|
-
import { forwardRef as forwardRef2, useRef as useRef2, useState
|
66
|
+
import { forwardRef as forwardRef2, useRef as useRef2, useState } from "react";
|
137
67
|
import {
|
138
68
|
Primitive as Primitive2
|
139
69
|
} from "@radix-ui/react-primitive";
|
@@ -185,7 +115,7 @@ var useOnResizeContent = (ref, callback) => {
|
|
185
115
|
var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef) => {
|
186
116
|
const divRef = useRef2(null);
|
187
117
|
const ref = useComposedRefs(forwardedRef, divRef);
|
188
|
-
const [isAtBottom, setIsAtBottom] =
|
118
|
+
const [isAtBottom, setIsAtBottom] = useState(true);
|
189
119
|
useOnResizeContent(divRef, () => {
|
190
120
|
const div = divRef.current;
|
191
121
|
if (!div || !isAtBottom)
|
@@ -210,8 +140,8 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
|
|
210
140
|
);
|
211
141
|
});
|
212
142
|
|
213
|
-
// src/
|
214
|
-
import { useCallback, useMemo
|
143
|
+
// src/vercel/useVercelAIBranches.tsx
|
144
|
+
import { useCallback, useMemo, useRef as useRef3 } from "react";
|
215
145
|
var ROOT_ID = "__ROOT_ID__";
|
216
146
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
217
147
|
var updateBranchData = (data, messages) => {
|
@@ -278,7 +208,7 @@ var sliceMessagesUntil = (messages, message) => {
|
|
278
208
|
throw new Error("Unexpected: Message not found");
|
279
209
|
return messages.slice(0, messageIdx);
|
280
210
|
};
|
281
|
-
var
|
211
|
+
var useVercelAIBranches = (chat) => {
|
282
212
|
const data = useRef3({
|
283
213
|
parentMap: /* @__PURE__ */ new Map(),
|
284
214
|
branchMap: /* @__PURE__ */ new Map(),
|
@@ -315,87 +245,170 @@ var useChatWithBranches = (chat) => {
|
|
315
245
|
async (message, newMessage) => {
|
316
246
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
317
247
|
chat.setMessages(newMessages);
|
318
|
-
|
248
|
+
if (newMessage.content[0]?.type !== "text")
|
249
|
+
throw new Error("Only text content is currently supported");
|
250
|
+
await chat.append({
|
251
|
+
role: "user",
|
252
|
+
content: newMessage.content[0].text
|
253
|
+
});
|
319
254
|
},
|
320
255
|
[chat.messages, chat.setMessages, chat.append]
|
321
256
|
);
|
322
|
-
return
|
257
|
+
return useMemo(
|
323
258
|
() => ({
|
324
|
-
...chat,
|
325
259
|
getBranchState,
|
326
260
|
switchToBranch,
|
327
261
|
editAt,
|
328
262
|
reloadAt
|
329
263
|
}),
|
330
|
-
[
|
264
|
+
[getBranchState, switchToBranch, editAt, reloadAt]
|
331
265
|
);
|
332
266
|
};
|
333
267
|
var hasUpcomingMessage = (thread) => {
|
334
268
|
return thread.isLoading && thread.messages[thread.messages.length - 1]?.role !== "assistant";
|
335
269
|
};
|
336
270
|
|
271
|
+
// src/utils/context/ComposerState.ts
|
272
|
+
import { useContext as useContext3 } from "react";
|
273
|
+
|
274
|
+
// src/utils/context/MessageContext.ts
|
275
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
276
|
+
var MessageContext = createContext2(null);
|
277
|
+
var useMessageContext = () => {
|
278
|
+
const context = useContext2(MessageContext);
|
279
|
+
if (!context)
|
280
|
+
throw new Error("useMessageContext must be used within a MessageProvider");
|
281
|
+
return context;
|
282
|
+
};
|
283
|
+
|
284
|
+
// src/utils/context/ComposerState.ts
|
285
|
+
var useComposerContext = () => {
|
286
|
+
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
287
|
+
const { useComposer: useMessageComposer } = useContext3(MessageContext) ?? {};
|
288
|
+
return { useComposer: useMessageComposer ?? useAssisstantComposer };
|
289
|
+
};
|
290
|
+
|
291
|
+
// src/primitives/composer/ComposerIf.tsx
|
292
|
+
var useComposerIf = (props) => {
|
293
|
+
const { useComposer } = useComposerContext();
|
294
|
+
return useComposer((composer) => {
|
295
|
+
if (props.editing === true && !composer.isEditing)
|
296
|
+
return false;
|
297
|
+
if (props.editing === false && composer.isEditing)
|
298
|
+
return false;
|
299
|
+
return true;
|
300
|
+
});
|
301
|
+
};
|
302
|
+
var ComposerIf = ({ children, ...query }) => {
|
303
|
+
const result = useComposerIf(query);
|
304
|
+
return result ? children : null;
|
305
|
+
};
|
306
|
+
|
337
307
|
// src/primitives/message/index.ts
|
338
308
|
var message_exports = {};
|
339
309
|
__export(message_exports, {
|
340
310
|
Content: () => MessageContent,
|
341
|
-
EditableContent: () => MessageEditableContent,
|
342
311
|
If: () => MessageIf,
|
343
312
|
Provider: () => MessageProvider,
|
344
313
|
Root: () => MessageRoot
|
345
314
|
});
|
346
315
|
|
347
316
|
// src/primitives/message/MessageProvider.tsx
|
348
|
-
import { useMemo as
|
349
|
-
|
350
|
-
|
351
|
-
var
|
352
|
-
|
353
|
-
|
317
|
+
import { useMemo as useMemo2, useState as useState2 } from "react";
|
318
|
+
import { create } from "zustand";
|
319
|
+
import { useShallow } from "zustand/react/shallow";
|
320
|
+
var getIsLast = (thread, message) => {
|
321
|
+
const hasUpcoming = hasUpcomingMessage(thread);
|
322
|
+
return hasUpcoming ? message.id === UPCOMING_MESSAGE_ID : thread.messages[thread.messages.length - 1]?.id === message.id;
|
323
|
+
};
|
324
|
+
var useMessageContext2 = () => {
|
325
|
+
const { useBranchObserver } = useAssistantContext();
|
326
|
+
const [context] = useState2(() => {
|
327
|
+
const useMessage = create(() => ({
|
328
|
+
message: null,
|
329
|
+
isLast: false,
|
330
|
+
isCopied: false,
|
331
|
+
isHovering: false,
|
332
|
+
setIsCopied: () => {
|
333
|
+
},
|
334
|
+
setIsHovering: () => {
|
335
|
+
},
|
336
|
+
branchState: {
|
337
|
+
branchId: 0,
|
338
|
+
branchCount: 0
|
339
|
+
}
|
340
|
+
}));
|
341
|
+
const useComposer = create((set, get) => ({
|
342
|
+
isEditing: false,
|
343
|
+
canCancel: true,
|
344
|
+
edit: () => {
|
345
|
+
const message = useMessage.getState().message;
|
346
|
+
if (message.role !== "user")
|
347
|
+
throw new Error("Editing is only supported for user messages");
|
348
|
+
if (message.content[0]?.type !== "text")
|
349
|
+
throw new Error("Editing is only supported for text-only messages");
|
350
|
+
return set({
|
351
|
+
isEditing: true,
|
352
|
+
value: message.content[0].text
|
353
|
+
});
|
354
|
+
},
|
355
|
+
cancel: () => set({ isEditing: false }),
|
356
|
+
send: () => {
|
357
|
+
const message = useMessage.getState().message;
|
358
|
+
if (message.role !== "user")
|
359
|
+
throw new Error("Editing is only supported for user messages");
|
360
|
+
useBranchObserver.getState().editAt(message, {
|
361
|
+
role: "user",
|
362
|
+
content: [{ type: "text", text: get().value }]
|
363
|
+
});
|
364
|
+
set({ isEditing: false });
|
365
|
+
},
|
366
|
+
value: "",
|
367
|
+
setValue: (value) => set({ value })
|
368
|
+
}));
|
369
|
+
return { useMessage, useComposer };
|
370
|
+
});
|
371
|
+
return context;
|
372
|
+
};
|
354
373
|
var MessageProvider = ({
|
355
374
|
message,
|
356
375
|
children
|
357
376
|
}) => {
|
358
|
-
const
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
const [editState, setEditState] = useState3({
|
363
|
-
isEditing: false
|
364
|
-
});
|
365
|
-
const [isCopied, setIsCopied] = useState3(false);
|
366
|
-
const [isHovering, setIsHovering] = useState3(false);
|
367
|
-
const branchState = useMemo3(
|
368
|
-
() => getBranchState(message),
|
369
|
-
[getBranchState, message]
|
370
|
-
);
|
371
|
-
return /* @__PURE__ */ React.createElement(
|
372
|
-
MessageContextProvider,
|
373
|
-
{
|
374
|
-
message,
|
375
|
-
editState,
|
376
|
-
setEditState,
|
377
|
-
branchState,
|
378
|
-
isCopied,
|
379
|
-
setIsCopied,
|
380
|
-
isHovering,
|
381
|
-
setIsHovering
|
382
|
-
},
|
383
|
-
children
|
377
|
+
const { useThread, useBranchObserver } = useAssistantContext();
|
378
|
+
const context = useMessageContext2();
|
379
|
+
const branchState = useBranchObserver(
|
380
|
+
useShallow((b) => b.getBranchState(message))
|
384
381
|
);
|
382
|
+
const isLast = useThread((thread) => getIsLast(thread, message));
|
383
|
+
const [isCopied, setIsCopied] = useState2(false);
|
384
|
+
const [isHovering, setIsHovering] = useState2(false);
|
385
|
+
useMemo2(() => {
|
386
|
+
context.useMessage.setState(
|
387
|
+
{
|
388
|
+
message,
|
389
|
+
isLast,
|
390
|
+
isCopied,
|
391
|
+
isHovering,
|
392
|
+
setIsCopied,
|
393
|
+
setIsHovering,
|
394
|
+
branchState
|
395
|
+
},
|
396
|
+
true
|
397
|
+
);
|
398
|
+
}, [context, message, isLast, isCopied, isHovering, branchState]);
|
399
|
+
return /* @__PURE__ */ React.createElement(MessageContext.Provider, { value: context }, children);
|
385
400
|
};
|
386
401
|
|
387
402
|
// src/primitives/message/MessageRoot.tsx
|
388
|
-
import {
|
403
|
+
import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
|
389
404
|
import {
|
390
405
|
Primitive as Primitive3
|
391
406
|
} from "@radix-ui/react-primitive";
|
392
|
-
import {
|
407
|
+
import { forwardRef as forwardRef3 } from "react";
|
393
408
|
var MessageRoot = forwardRef3(
|
394
409
|
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
395
|
-
const
|
396
|
-
|
397
|
-
(s) => s.setIsHovering
|
398
|
-
);
|
410
|
+
const { useMessage } = useMessageContext();
|
411
|
+
const setIsHovering = useMessage((s) => s.setIsHovering);
|
399
412
|
const handleMouseEnter = () => {
|
400
413
|
setIsHovering(true);
|
401
414
|
};
|
@@ -415,27 +428,23 @@ var MessageRoot = forwardRef3(
|
|
415
428
|
);
|
416
429
|
|
417
430
|
// src/primitives/message/MessageIf.tsx
|
418
|
-
var isLast = (thread, message) => {
|
419
|
-
const hasUpcoming = hasUpcomingMessage(thread);
|
420
|
-
return hasUpcoming ? message.id === UPCOMING_MESSAGE_ID : thread.messages[thread.messages.length - 1]?.id === message.id;
|
421
|
-
};
|
422
431
|
var useMessageIf = (props) => {
|
423
|
-
const
|
424
|
-
return
|
425
|
-
|
426
|
-
|
427
|
-
|
432
|
+
const { useMessage } = useMessageContext();
|
433
|
+
return useMessage(
|
434
|
+
({
|
435
|
+
message,
|
436
|
+
isLast,
|
437
|
+
isCopied,
|
438
|
+
isHovering,
|
439
|
+
branchState: { branchCount }
|
440
|
+
}) => {
|
428
441
|
if (props.hasBranches === true && branchCount < 2)
|
429
442
|
return false;
|
430
443
|
if (props.user && message.role !== "user")
|
431
444
|
return false;
|
432
445
|
if (props.assistant && message.role !== "assistant")
|
433
446
|
return false;
|
434
|
-
if (props.
|
435
|
-
return false;
|
436
|
-
if (props.editing === false && isEditing)
|
437
|
-
return false;
|
438
|
-
if (props.lastOrHover === true && !isHovering && !isLast(thread, message))
|
447
|
+
if (props.lastOrHover === true && !isHovering && !isLast)
|
439
448
|
return false;
|
440
449
|
if (props.copied === true && !isCopied)
|
441
450
|
return false;
|
@@ -452,66 +461,40 @@ var MessageIf = ({ children, ...query }) => {
|
|
452
461
|
|
453
462
|
// src/primitives/message/MessageContent.tsx
|
454
463
|
var MessageContent = () => {
|
455
|
-
const
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, content);
|
464
|
+
const { useMessage } = useMessageContext();
|
465
|
+
const content = useMessage((s) => s.message.content);
|
466
|
+
if (content[0]?.type !== "text")
|
467
|
+
throw new Error("Unsupported message content type");
|
468
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, content[0].text);
|
460
469
|
};
|
461
470
|
|
462
|
-
// src/primitives/message/MessageEditableContent.tsx
|
463
|
-
import { forwardRef as forwardRef4 } from "react";
|
464
|
-
import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
|
465
|
-
import TextareaAutosize from "react-textarea-autosize";
|
466
|
-
var MessageEditableContent = forwardRef4(({ onChange, value, ...rest }, forwardedRef) => {
|
467
|
-
const [editState, setEditState] = useMessageContext(
|
468
|
-
"Message.EditableContent",
|
469
|
-
(s) => [s.editState, s.setEditState]
|
470
|
-
);
|
471
|
-
const handleChange = (e) => {
|
472
|
-
setEditState({ isEditing: true, value: e.target.value });
|
473
|
-
};
|
474
|
-
if (!editState.isEditing)
|
475
|
-
throw new Error(
|
476
|
-
"Message.EditableContent may only be rendered when edit mode is enabled. Consider wrapping the component in <Message.If editing>."
|
477
|
-
);
|
478
|
-
return /* @__PURE__ */ React.createElement(
|
479
|
-
TextareaAutosize,
|
480
|
-
{
|
481
|
-
...rest,
|
482
|
-
ref: forwardedRef,
|
483
|
-
onChange: composeEventHandlers3(onChange, handleChange),
|
484
|
-
value: editState.value || value
|
485
|
-
}
|
486
|
-
);
|
487
|
-
});
|
488
|
-
|
489
471
|
// src/primitives/thread/ThreadMessages.tsx
|
490
472
|
var getComponents = (components) => {
|
491
473
|
return {
|
492
|
-
|
474
|
+
EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
|
493
475
|
UserMessage: components.UserMessage ?? components.Message,
|
494
476
|
AssistantMessage: components.AssistantMessage ?? components.Message
|
495
477
|
};
|
496
478
|
};
|
497
479
|
var ThreadMessages = ({ components }) => {
|
498
|
-
const
|
499
|
-
const
|
500
|
-
const
|
480
|
+
const { useThread } = useAssistantContext();
|
481
|
+
const thread = useThread();
|
482
|
+
const messages = thread.messages;
|
483
|
+
const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
|
501
484
|
if (messages.length === 0)
|
502
485
|
return null;
|
503
486
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message, idx) => {
|
504
487
|
return (
|
505
488
|
// biome-ignore lint/suspicious/noArrayIndexKey: fixes a11y issues with branch navigation
|
506
|
-
/* @__PURE__ */ React.createElement(MessageProvider, { key: idx, message }, /* @__PURE__ */ React.createElement(MessageIf, { user: true, editing: false }, /* @__PURE__ */ React.createElement(UserMessage, null)), /* @__PURE__ */ React.createElement(
|
489
|
+
/* @__PURE__ */ React.createElement(MessageProvider, { key: idx, message }, /* @__PURE__ */ React.createElement(MessageIf, { user: true }, /* @__PURE__ */ React.createElement(ComposerIf, { editing: false }, /* @__PURE__ */ React.createElement(UserMessage, null)), /* @__PURE__ */ React.createElement(ComposerIf, { editing: true }, /* @__PURE__ */ React.createElement(EditComposer, null))), /* @__PURE__ */ React.createElement(MessageIf, { assistant: true }, /* @__PURE__ */ React.createElement(AssistantMessage, null)))
|
507
490
|
);
|
508
|
-
}), hasUpcomingMessage(
|
491
|
+
}), hasUpcomingMessage(thread) && /* @__PURE__ */ React.createElement(
|
509
492
|
MessageProvider,
|
510
493
|
{
|
511
494
|
message: {
|
512
495
|
id: UPCOMING_MESSAGE_ID,
|
513
496
|
role: "assistant",
|
514
|
-
content: "..."
|
497
|
+
content: [{ type: "text", text: "..." }]
|
515
498
|
}
|
516
499
|
},
|
517
500
|
/* @__PURE__ */ React.createElement(AssistantMessage, null)
|
@@ -521,22 +504,29 @@ var ThreadMessages = ({ components }) => {
|
|
521
504
|
// src/primitives/composer/index.ts
|
522
505
|
var composer_exports = {};
|
523
506
|
__export(composer_exports, {
|
507
|
+
Cancel: () => ComposerCancel,
|
508
|
+
If: () => ComposerIf,
|
524
509
|
Input: () => ComposerInput,
|
525
510
|
Root: () => ComposerRoot,
|
526
|
-
Send: () => ComposerSend
|
527
|
-
Stop: () => ComposerStop
|
511
|
+
Send: () => ComposerSend
|
528
512
|
});
|
529
513
|
|
530
514
|
// src/primitives/composer/ComposerRoot.tsx
|
531
|
-
import {
|
515
|
+
import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
|
516
|
+
import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
|
532
517
|
import {
|
533
518
|
Primitive as Primitive4
|
534
519
|
} from "@radix-ui/react-primitive";
|
535
|
-
import {
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
520
|
+
import {
|
521
|
+
createContext as createContext3,
|
522
|
+
forwardRef as forwardRef4,
|
523
|
+
useContext as useContext4,
|
524
|
+
useMemo as useMemo3,
|
525
|
+
useRef as useRef4
|
526
|
+
} from "react";
|
527
|
+
var ComposerFormContext = createContext3(null);
|
528
|
+
var useComposerFormContext = () => {
|
529
|
+
const context = useContext4(ComposerFormContext);
|
540
530
|
if (!context) {
|
541
531
|
throw new Error(
|
542
532
|
"Composer compound components cannot be rendered outside the Composer component"
|
@@ -544,15 +534,12 @@ var useComposerContext = () => {
|
|
544
534
|
}
|
545
535
|
return context;
|
546
536
|
};
|
547
|
-
var ComposerRoot =
|
537
|
+
var ComposerRoot = forwardRef4(
|
548
538
|
({ onSubmit, ...rest }, forwardedRef) => {
|
549
|
-
const
|
550
|
-
"Composer.Root",
|
551
|
-
(s) => s.chat.handleSubmit
|
552
|
-
);
|
539
|
+
const { useComposer } = useComposerContext();
|
553
540
|
const formRef = useRef4(null);
|
554
541
|
const ref = useComposedRefs2(forwardedRef, formRef);
|
555
|
-
const composerContextValue =
|
542
|
+
const composerContextValue = useMemo3(
|
556
543
|
() => ({
|
557
544
|
submit: () => formRef.current?.dispatchEvent(
|
558
545
|
new Event("submit", { cancelable: true, bubbles: true })
|
@@ -560,108 +547,115 @@ var ComposerRoot = forwardRef5(
|
|
560
547
|
}),
|
561
548
|
[]
|
562
549
|
);
|
563
|
-
|
550
|
+
const handleSubmit = (e) => {
|
551
|
+
const composerState = useComposer.getState();
|
552
|
+
if (!composerState.isEditing)
|
553
|
+
return;
|
554
|
+
e.preventDefault();
|
555
|
+
composerState.send();
|
556
|
+
};
|
557
|
+
return /* @__PURE__ */ React.createElement(ComposerFormContext.Provider, { value: composerContextValue }, /* @__PURE__ */ React.createElement(
|
564
558
|
Primitive4.form,
|
565
559
|
{
|
566
560
|
...rest,
|
567
561
|
ref,
|
568
|
-
onSubmit:
|
562
|
+
onSubmit: composeEventHandlers3(onSubmit, handleSubmit)
|
569
563
|
}
|
570
564
|
));
|
571
565
|
}
|
572
566
|
);
|
573
567
|
|
574
568
|
// src/primitives/composer/ComposerInput.tsx
|
575
|
-
import {
|
569
|
+
import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
|
576
570
|
import { Slot } from "@radix-ui/react-slot";
|
577
|
-
import {
|
578
|
-
import
|
579
|
-
var ComposerInput =
|
580
|
-
const
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
);
|
588
|
-
const Component = asChild ? Slot :
|
589
|
-
const
|
571
|
+
import { forwardRef as forwardRef5 } from "react";
|
572
|
+
import TextareaAutosize from "react-textarea-autosize";
|
573
|
+
var ComposerInput = forwardRef5(({ asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
574
|
+
const { useThread } = useAssistantContext();
|
575
|
+
const isLoading = useThread((t) => t.isLoading);
|
576
|
+
const { useComposer } = useComposerContext();
|
577
|
+
const value = useComposer((c) => {
|
578
|
+
if (!c.isEditing)
|
579
|
+
return "";
|
580
|
+
return c.value;
|
581
|
+
});
|
582
|
+
const Component = asChild ? Slot : TextareaAutosize;
|
583
|
+
const composerForm = useComposerFormContext();
|
590
584
|
const handleKeyPress = (e) => {
|
591
|
-
if (
|
585
|
+
if (disabled)
|
586
|
+
return;
|
587
|
+
if (e.key === "Escape") {
|
588
|
+
useComposer.getState().cancel();
|
589
|
+
}
|
590
|
+
if (isLoading)
|
592
591
|
return;
|
593
592
|
if (e.key === "Enter" && e.shiftKey === false) {
|
594
593
|
e.preventDefault();
|
595
|
-
|
594
|
+
composerForm.submit();
|
596
595
|
}
|
597
596
|
};
|
598
597
|
return /* @__PURE__ */ React.createElement(
|
599
598
|
Component,
|
600
599
|
{
|
601
|
-
value
|
600
|
+
value,
|
602
601
|
...rest,
|
603
602
|
ref: forwardedRef,
|
604
|
-
|
605
|
-
|
603
|
+
disabled,
|
604
|
+
onChange: composeEventHandlers4(onChange, (e) => {
|
605
|
+
const composerState = useComposer.getState();
|
606
|
+
if (!composerState.isEditing)
|
607
|
+
return;
|
608
|
+
return composerState.setValue(e.target.value);
|
609
|
+
}),
|
610
|
+
onKeyDown: composeEventHandlers4(onKeyDown, handleKeyPress)
|
606
611
|
}
|
607
612
|
);
|
608
613
|
});
|
609
614
|
|
610
615
|
// src/primitives/composer/ComposerSend.tsx
|
611
|
-
import { forwardRef as forwardRef7 } from "react";
|
612
616
|
import {
|
613
617
|
Primitive as Primitive5
|
614
618
|
} from "@radix-ui/react-primitive";
|
615
|
-
|
619
|
+
import { forwardRef as forwardRef6 } from "react";
|
620
|
+
var ComposerSend = forwardRef6(
|
616
621
|
({ disabled, ...rest }, ref) => {
|
617
|
-
const
|
622
|
+
const { useComposer } = useComposerContext();
|
623
|
+
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
618
624
|
return /* @__PURE__ */ React.createElement(
|
619
625
|
Primitive5.button,
|
620
626
|
{
|
621
627
|
type: "submit",
|
622
628
|
...rest,
|
623
629
|
ref,
|
624
|
-
disabled: disabled ||
|
630
|
+
disabled: disabled || !hasValue
|
625
631
|
}
|
626
632
|
);
|
627
633
|
}
|
628
634
|
);
|
629
635
|
|
630
|
-
// src/
|
631
|
-
import {
|
636
|
+
// src/primitives/composer/ComposerCancel.tsx
|
637
|
+
import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
|
632
638
|
import {
|
633
639
|
Primitive as Primitive6
|
634
640
|
} from "@radix-ui/react-primitive";
|
635
|
-
import {
|
636
|
-
var
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
641
|
+
import { forwardRef as forwardRef7 } from "react";
|
642
|
+
var ComposerCancel = forwardRef7(({ disabled, onClick, ...rest }, ref) => {
|
643
|
+
const { useComposer } = useComposerContext();
|
644
|
+
const hasValue = useComposer((c) => c.canCancel);
|
645
|
+
const handleClose = () => {
|
646
|
+
useComposer.getState().cancel();
|
647
|
+
};
|
648
|
+
return /* @__PURE__ */ React.createElement(
|
649
|
+
Primitive6.button,
|
650
|
+
{
|
651
|
+
type: "button",
|
652
|
+
...rest,
|
653
|
+
ref,
|
654
|
+
onClick: composeEventHandlers5(onClick, handleClose),
|
655
|
+
disabled: disabled || !hasValue
|
650
656
|
}
|
651
657
|
);
|
652
|
-
};
|
653
|
-
|
654
|
-
// src/primitives/composer/ComposerStop.tsx
|
655
|
-
var useComposerStop = () => {
|
656
|
-
const [isLoading, stop] = useThreadContext("Composer.Stop", (s) => [
|
657
|
-
s.chat.isLoading,
|
658
|
-
s.chat.stop
|
659
|
-
]);
|
660
|
-
if (!isLoading)
|
661
|
-
return null;
|
662
|
-
return stop;
|
663
|
-
};
|
664
|
-
var ComposerStop = createActionButton(useComposerStop);
|
658
|
+
});
|
665
659
|
|
666
660
|
// src/primitives/branchPicker/index.ts
|
667
661
|
var branchPicker_exports = {};
|
@@ -675,52 +669,66 @@ __export(branchPicker_exports, {
|
|
675
669
|
|
676
670
|
// src/actions/useGoToNextBranch.tsx
|
677
671
|
var useGoToNextBranch = () => {
|
678
|
-
const
|
679
|
-
|
680
|
-
|
672
|
+
const { useThread, useBranchObserver } = useAssistantContext();
|
673
|
+
const { useComposer, useMessage } = useMessageContext();
|
674
|
+
const isLoading = useThread((s) => s.isLoading);
|
675
|
+
const isEditing = useComposer((s) => s.isEditing);
|
676
|
+
const hasNext = useMessage(
|
677
|
+
({ branchState: { branchId, branchCount } }) => branchId + 1 < branchCount
|
681
678
|
);
|
682
|
-
|
683
|
-
const {
|
684
|
-
message: message2,
|
685
|
-
editState: { isEditing },
|
686
|
-
branchState: { branchId: branchId2, branchCount }
|
687
|
-
} = s;
|
688
|
-
if (isEditing || branchCount <= 1 || branchId2 + 1 >= branchCount)
|
689
|
-
return null;
|
690
|
-
return { message: message2, branchId: branchId2 };
|
691
|
-
});
|
692
|
-
if (!context)
|
679
|
+
if (isLoading || isEditing || !hasNext)
|
693
680
|
return null;
|
694
|
-
const { message, branchId } = context;
|
695
681
|
return () => {
|
696
|
-
|
682
|
+
const {
|
683
|
+
message,
|
684
|
+
branchState: { branchId }
|
685
|
+
} = useMessage.getState();
|
686
|
+
useBranchObserver.getState().switchToBranch(message, branchId + 1);
|
697
687
|
};
|
698
688
|
};
|
699
689
|
|
690
|
+
// src/utils/createActionButton.tsx
|
691
|
+
import { forwardRef as forwardRef8 } from "react";
|
692
|
+
import {
|
693
|
+
Primitive as Primitive7
|
694
|
+
} from "@radix-ui/react-primitive";
|
695
|
+
import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
|
696
|
+
var createActionButton = (useActionButton) => {
|
697
|
+
return forwardRef8(
|
698
|
+
(props, forwardedRef) => {
|
699
|
+
const onClick = useActionButton(props);
|
700
|
+
return /* @__PURE__ */ React.createElement(
|
701
|
+
Primitive7.button,
|
702
|
+
{
|
703
|
+
type: "button",
|
704
|
+
disabled: !onClick,
|
705
|
+
...props,
|
706
|
+
ref: forwardedRef,
|
707
|
+
onClick: composeEventHandlers6(props.onClick, onClick ?? void 0)
|
708
|
+
}
|
709
|
+
);
|
710
|
+
}
|
711
|
+
);
|
712
|
+
};
|
713
|
+
|
700
714
|
// src/primitives/branchPicker/BranchPickerNext.tsx
|
701
715
|
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
702
716
|
|
703
717
|
// src/actions/useGoToPreviousBranch.tsx
|
704
718
|
var useGoToPreviousBranch = () => {
|
705
|
-
const
|
706
|
-
|
707
|
-
|
708
|
-
);
|
709
|
-
const
|
710
|
-
|
711
|
-
message: message2,
|
712
|
-
editState: { isEditing },
|
713
|
-
branchState: { branchId: branchId2, branchCount }
|
714
|
-
} = s;
|
715
|
-
if (isEditing || branchCount <= 1 || branchId2 <= 0)
|
716
|
-
return null;
|
717
|
-
return { message: message2, branchId: branchId2 };
|
718
|
-
});
|
719
|
-
if (!context)
|
719
|
+
const { useThread, useBranchObserver } = useAssistantContext();
|
720
|
+
const { useComposer, useMessage } = useMessageContext();
|
721
|
+
const isLoading = useThread((s) => s.isLoading);
|
722
|
+
const isEditing = useComposer((s) => s.isEditing);
|
723
|
+
const hasNext = useMessage(({ branchState: { branchId } }) => branchId > 0);
|
724
|
+
if (isLoading || isEditing || !hasNext)
|
720
725
|
return null;
|
721
|
-
const { message, branchId } = context;
|
722
726
|
return () => {
|
723
|
-
|
727
|
+
const {
|
728
|
+
message,
|
729
|
+
branchState: { branchId }
|
730
|
+
} = useMessage.getState();
|
731
|
+
useBranchObserver.getState().switchToBranch(message, branchId - 1);
|
724
732
|
};
|
725
733
|
};
|
726
734
|
|
@@ -729,29 +737,25 @@ var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
|
729
737
|
|
730
738
|
// src/primitives/branchPicker/BranchPickerCount.tsx
|
731
739
|
var BranchPickerCount = () => {
|
732
|
-
const
|
733
|
-
|
734
|
-
(s) => s.branchState.branchCount
|
735
|
-
);
|
740
|
+
const { useMessage } = useMessageContext();
|
741
|
+
const branchCount = useMessage((s) => s.branchState.branchCount);
|
736
742
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, branchCount);
|
737
743
|
};
|
738
744
|
|
739
745
|
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
740
746
|
var BranchPickerNumber = () => {
|
741
|
-
const
|
742
|
-
|
743
|
-
(s) => s.branchState.branchId
|
744
|
-
);
|
747
|
+
const { useMessage } = useMessageContext();
|
748
|
+
const branchId = useMessage((s) => s.branchState.branchId);
|
745
749
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, branchId + 1);
|
746
750
|
};
|
747
751
|
|
748
752
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
749
753
|
import {
|
750
|
-
Primitive as
|
754
|
+
Primitive as Primitive8
|
751
755
|
} from "@radix-ui/react-primitive";
|
752
756
|
import { forwardRef as forwardRef9 } from "react";
|
753
757
|
var BranchPickerRoot = forwardRef9(({ hideWhenSingleBranch, ...rest }, ref) => {
|
754
|
-
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(
|
758
|
+
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(Primitive8.div, { ...rest, ref }));
|
755
759
|
});
|
756
760
|
|
757
761
|
// src/primitives/actionBar/index.ts
|
@@ -765,30 +769,48 @@ __export(actionBar_exports, {
|
|
765
769
|
|
766
770
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
767
771
|
import {
|
768
|
-
Primitive as
|
772
|
+
Primitive as Primitive9
|
769
773
|
} from "@radix-ui/react-primitive";
|
770
774
|
import { forwardRef as forwardRef10 } from "react";
|
771
|
-
var ActionBarRoot = forwardRef10(({ hideWhenBusy,
|
772
|
-
|
775
|
+
var ActionBarRoot = forwardRef10(({ hideWhenBusy, autohide, autohideFloat, ...rest }, ref) => {
|
776
|
+
const { useThread } = useAssistantContext();
|
777
|
+
const { useMessage } = useMessageContext();
|
778
|
+
const hideAndfloatStatus = useMessage((m) => {
|
779
|
+
const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
|
780
|
+
if (!autohideEnabled)
|
781
|
+
return "normal" /* Normal */;
|
782
|
+
if (!m.isHovering)
|
783
|
+
return "hidden" /* Hidden */;
|
784
|
+
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
785
|
+
return "floating" /* Floating */;
|
786
|
+
return "normal" /* Normal */;
|
787
|
+
});
|
788
|
+
const busy = useThread((t) => t.isLoading);
|
789
|
+
if (hideWhenBusy && busy)
|
790
|
+
return null;
|
791
|
+
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
792
|
+
return null;
|
793
|
+
return /* @__PURE__ */ React.createElement(
|
794
|
+
Primitive9.div,
|
795
|
+
{
|
796
|
+
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
797
|
+
...rest,
|
798
|
+
ref
|
799
|
+
}
|
800
|
+
);
|
773
801
|
});
|
774
802
|
|
775
803
|
// src/actions/useCopyMessage.tsx
|
776
804
|
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
777
|
-
const
|
778
|
-
|
779
|
-
|
780
|
-
message: { content: content2 },
|
781
|
-
setIsCopied: setIsCopied2
|
782
|
-
} = s;
|
783
|
-
if (isEditing)
|
784
|
-
return null;
|
785
|
-
return { content: content2, setIsCopied: setIsCopied2 };
|
786
|
-
});
|
787
|
-
if (!context)
|
805
|
+
const { useMessage, useComposer } = useMessageContext();
|
806
|
+
const isEditing = useComposer((s) => s.isEditing);
|
807
|
+
if (isEditing)
|
788
808
|
return null;
|
789
|
-
const { content, setIsCopied } = context;
|
790
809
|
return () => {
|
791
|
-
|
810
|
+
const { message, setIsCopied } = useMessage.getState();
|
811
|
+
if (message.content[0]?.type !== "text")
|
812
|
+
throw new Error("Copying is only supported for text-only messages");
|
813
|
+
navigator.clipboard.writeText(message.content[0].text);
|
792
814
|
setIsCopied(true);
|
793
815
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
794
816
|
};
|
@@ -799,19 +821,18 @@ var ActionBarCopy = createActionButton(useCopyMessage);
|
|
799
821
|
|
800
822
|
// src/actions/useReloadMessage.tsx
|
801
823
|
var useReloadMessage = () => {
|
802
|
-
const
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
const message2 = s.message;
|
808
|
-
if (message2.role !== "assistant" || isLoading)
|
809
|
-
return null;
|
810
|
-
return message2;
|
811
|
-
});
|
812
|
-
if (!message)
|
824
|
+
const { useThread, useBranchObserver } = useAssistantContext();
|
825
|
+
const { useMessage } = useMessageContext();
|
826
|
+
const isLoading = useThread((s) => s.isLoading);
|
827
|
+
const isAssistant = useMessage((s) => s.message.role === "assistant");
|
828
|
+
if (isLoading || !isAssistant)
|
813
829
|
return null;
|
814
|
-
return () =>
|
830
|
+
return () => {
|
831
|
+
const message = useMessage.getState().message;
|
832
|
+
if (message.role !== "assistant")
|
833
|
+
throw new Error("Reloading is only supported on assistant messages");
|
834
|
+
useBranchObserver.getState().reloadAt(message);
|
835
|
+
};
|
815
836
|
};
|
816
837
|
|
817
838
|
// src/primitives/actionBar/ActionBarReload.tsx
|
@@ -819,116 +840,154 @@ var ActionBarReload = createActionButton(useReloadMessage);
|
|
819
840
|
|
820
841
|
// src/actions/useBeginMessageEdit.tsx
|
821
842
|
var useBeginMessageEdit = () => {
|
822
|
-
const
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
setEditState: setEditState2
|
827
|
-
} = s;
|
828
|
-
if (isEditing)
|
829
|
-
return null;
|
830
|
-
return { content: content2, setEditState: setEditState2 };
|
831
|
-
});
|
832
|
-
if (!context)
|
843
|
+
const { useMessage, useComposer } = useMessageContext();
|
844
|
+
const isUser = useMessage((s) => s.message.role === "user");
|
845
|
+
const isEditing = useComposer((s) => s.isEditing);
|
846
|
+
if (!isUser || isEditing)
|
833
847
|
return null;
|
834
|
-
const { content, setEditState } = context;
|
835
848
|
return () => {
|
836
|
-
|
849
|
+
const { edit } = useComposer.getState();
|
850
|
+
edit();
|
837
851
|
};
|
838
852
|
};
|
839
853
|
|
840
854
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
841
855
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
842
856
|
|
843
|
-
// src/
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
}
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
857
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
858
|
+
import { useCallback as useCallback2, useMemo as useMemo4, useState as useState3 } from "react";
|
859
|
+
import { create as create2 } from "zustand";
|
860
|
+
var useAIAssistantContext = () => {
|
861
|
+
const [context] = useState3(() => {
|
862
|
+
const useThread = create2()(() => ({
|
863
|
+
messages: [],
|
864
|
+
isLoading: false,
|
865
|
+
reload: async () => {
|
866
|
+
},
|
867
|
+
append: async () => {
|
868
|
+
},
|
869
|
+
stop: () => {
|
870
|
+
}
|
871
|
+
}));
|
872
|
+
const useComposer = create2()(() => ({
|
873
|
+
isEditing: true,
|
874
|
+
canCancel: false,
|
875
|
+
value: "",
|
876
|
+
setValue: () => {
|
877
|
+
},
|
878
|
+
edit: () => {
|
879
|
+
throw new Error("Not implemented");
|
880
|
+
},
|
881
|
+
send: () => {
|
882
|
+
useThread.getState().append({
|
883
|
+
role: "user",
|
884
|
+
content: [{ type: "text", text: useComposer.getState().value }]
|
885
|
+
});
|
886
|
+
useComposer.getState().setValue("");
|
887
|
+
},
|
888
|
+
cancel: () => {
|
889
|
+
useThread.getState().stop();
|
890
|
+
}
|
891
|
+
}));
|
892
|
+
const useBranchObserver = create2()(() => ({
|
893
|
+
getBranchState: () => ({
|
894
|
+
branchId: 0,
|
895
|
+
branchCount: 0
|
896
|
+
}),
|
897
|
+
switchToBranch: () => {
|
898
|
+
},
|
899
|
+
editAt: async () => {
|
900
|
+
},
|
901
|
+
reloadAt: async () => {
|
902
|
+
}
|
903
|
+
}));
|
904
|
+
return { useThread, useComposer, useBranchObserver };
|
870
905
|
});
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
}
|
881
|
-
setEditState({ isEditing: false });
|
906
|
+
return context;
|
907
|
+
};
|
908
|
+
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
909
|
+
var vercelToThreadMessage = (message) => {
|
910
|
+
if (message.role !== "user" && message.role !== "assistant")
|
911
|
+
throw new Error("Unsupported role");
|
912
|
+
return {
|
913
|
+
id: message.id,
|
914
|
+
role: message.role,
|
915
|
+
content: [{ type: "text", text: message.content }]
|
882
916
|
};
|
883
917
|
};
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
editState: { isEditing },
|
893
|
-
setEditState: setEditState2
|
894
|
-
} = s;
|
895
|
-
if (!isEditing)
|
896
|
-
return null;
|
897
|
-
return { setEditState: setEditState2 };
|
918
|
+
var vercelToCachedThreadMessages = (messages) => {
|
919
|
+
return messages.map((m) => {
|
920
|
+
const cached = ThreadMessageCache.get(m);
|
921
|
+
if (cached)
|
922
|
+
return cached;
|
923
|
+
const newMessage = vercelToThreadMessage(m);
|
924
|
+
ThreadMessageCache.set(m, newMessage);
|
925
|
+
return newMessage;
|
898
926
|
});
|
899
|
-
if (!context)
|
900
|
-
return null;
|
901
|
-
const { setEditState } = context;
|
902
|
-
return () => {
|
903
|
-
setEditState({ isEditing: false });
|
904
|
-
};
|
905
927
|
};
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
928
|
+
var VercelAIChatAssistantProvider = ({ chat, children }) => {
|
929
|
+
const context = useAIAssistantContext();
|
930
|
+
const messages = useMemo4(() => {
|
931
|
+
return vercelToCachedThreadMessages(chat.messages);
|
932
|
+
}, [chat.messages]);
|
933
|
+
const reload = useCallback2(async () => {
|
934
|
+
await chat.reload();
|
935
|
+
}, [chat.reload]);
|
936
|
+
const append = useCallback2(
|
937
|
+
async (message) => {
|
938
|
+
if (message.content[0]?.type !== "text") {
|
939
|
+
throw new Error("Only text content is currently supported");
|
940
|
+
}
|
941
|
+
await chat.append({
|
942
|
+
role: message.role,
|
943
|
+
content: message.content[0].text
|
944
|
+
});
|
945
|
+
},
|
946
|
+
[chat.append]
|
947
|
+
);
|
948
|
+
const stop = useCallback2(() => {
|
949
|
+
const lastMessage = chat.messages.at(-1);
|
950
|
+
chat.stop();
|
951
|
+
if (lastMessage?.role === "user") {
|
952
|
+
chat.setInput(lastMessage.content);
|
953
|
+
}
|
954
|
+
}, [chat.messages, chat.stop, chat.setInput]);
|
955
|
+
useMemo4(() => {
|
956
|
+
context.useThread.setState(
|
957
|
+
{
|
958
|
+
messages,
|
959
|
+
isLoading: chat.isLoading,
|
960
|
+
reload,
|
961
|
+
append,
|
962
|
+
stop
|
963
|
+
},
|
964
|
+
true
|
965
|
+
);
|
966
|
+
}, [context, messages, reload, append, stop, chat.isLoading]);
|
967
|
+
useMemo4(() => {
|
968
|
+
context.useComposer.setState({
|
969
|
+
canCancel: chat.isLoading,
|
970
|
+
value: chat.input,
|
971
|
+
setValue: chat.setInput
|
972
|
+
});
|
973
|
+
}, [context, chat.isLoading, chat.input, chat.setInput]);
|
974
|
+
const branches = useVercelAIBranches(chat);
|
975
|
+
useMemo4(() => {
|
976
|
+
context.useBranchObserver.setState(branches, true);
|
977
|
+
}, [context, branches]);
|
978
|
+
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
917
979
|
};
|
918
980
|
export {
|
919
981
|
actionBar_exports as ActionBarPrimitive,
|
920
982
|
branchPicker_exports as BranchPickerPrimitive,
|
921
983
|
composer_exports as ComposerPrimitive,
|
922
|
-
editBar_exports as EditBarPrimitive,
|
923
984
|
message_exports as MessagePrimitive,
|
924
985
|
thread_exports as ThreadPrimitive,
|
925
|
-
|
986
|
+
VercelAIChatAssistantProvider as VercelAIAssistantProvider,
|
926
987
|
useMessageContext as unstable_useMessageContext,
|
927
988
|
useBeginMessageEdit,
|
928
|
-
useCancelMessageEdit,
|
929
989
|
useCopyMessage,
|
930
990
|
useGoToNextBranch,
|
931
991
|
useGoToPreviousBranch,
|
932
|
-
useReloadMessage
|
933
|
-
useSaveMessageEdit
|
992
|
+
useReloadMessage
|
934
993
|
};
|