@assistant-ui/react 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
};
|