@assistant-ui/react 0.0.6 → 0.0.8
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 +66 -13
- package/dist/index.d.ts +66 -13
- package/dist/index.js +410 -209
- package/dist/index.mjs +402 -198
- package/package.json +2 -2
package/dist/index.js
CHANGED
@@ -35,7 +35,8 @@ __export(src_exports, {
|
|
35
35
|
ComposerPrimitive: () => composer_exports,
|
36
36
|
MessagePrimitive: () => message_exports,
|
37
37
|
ThreadPrimitive: () => thread_exports,
|
38
|
-
VercelAIAssistantProvider: () =>
|
38
|
+
VercelAIAssistantProvider: () => VercelAIAssistantProvider,
|
39
|
+
unstable_VercelRSCAssistantProvider: () => VercelRSCAssistantProvider,
|
39
40
|
unstable_useMessageContext: () => useMessageContext,
|
40
41
|
useBeginMessageEdit: () => useBeginMessageEdit,
|
41
42
|
useCopyMessage: () => useCopyMessage,
|
@@ -52,6 +53,7 @@ __export(thread_exports, {
|
|
52
53
|
If: () => ThreadIf,
|
53
54
|
Messages: () => ThreadMessages,
|
54
55
|
Root: () => ThreadRoot,
|
56
|
+
ScrollToBottom: () => ThreadScrollToBottom,
|
55
57
|
Viewport: () => ThreadViewport
|
56
58
|
});
|
57
59
|
|
@@ -102,10 +104,10 @@ var ThreadEmpty = ({ children }) => {
|
|
102
104
|
};
|
103
105
|
|
104
106
|
// src/primitives/thread/ThreadViewport.tsx
|
105
|
-
var import_react4 = require("react");
|
106
|
-
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
107
|
-
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
108
107
|
var import_primitive = require("@radix-ui/primitive");
|
108
|
+
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
109
|
+
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
110
|
+
var import_react5 = require("react");
|
109
111
|
|
110
112
|
// src/utils/hooks/useOnResizeContent.tsx
|
111
113
|
var import_react3 = require("react");
|
@@ -138,34 +140,60 @@ var useOnResizeContent = (ref, callback) => {
|
|
138
140
|
mutationObserver.observe(el, { childList: true });
|
139
141
|
for (const child of el.children) {
|
140
142
|
resizeObserver.observe(child);
|
141
|
-
console.log("observing child", child);
|
142
143
|
}
|
143
144
|
return () => {
|
144
|
-
console.log("disconnecting");
|
145
145
|
resizeObserver.disconnect();
|
146
146
|
mutationObserver.disconnect();
|
147
147
|
};
|
148
148
|
}, [ref.current]);
|
149
149
|
};
|
150
150
|
|
151
|
+
// src/utils/hooks/useOnScrollToBottom.tsx
|
152
|
+
var import_react4 = require("react");
|
153
|
+
var useOnScrollToBottom = (callback) => {
|
154
|
+
const callbackRef = (0, import_react4.useRef)(callback);
|
155
|
+
callbackRef.current = callback;
|
156
|
+
const { useThread } = useAssistantContext();
|
157
|
+
(0, import_react4.useEffect)(() => {
|
158
|
+
return useThread.getState().onScrollToBottom(() => {
|
159
|
+
callbackRef.current();
|
160
|
+
});
|
161
|
+
}, [useThread]);
|
162
|
+
};
|
163
|
+
|
151
164
|
// src/primitives/thread/ThreadViewport.tsx
|
152
|
-
var ThreadViewport = (0,
|
153
|
-
const
|
165
|
+
var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
|
166
|
+
const messagesEndRef = (0, import_react5.useRef)(null);
|
167
|
+
const divRef = (0, import_react5.useRef)(null);
|
154
168
|
const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
|
155
|
-
const
|
169
|
+
const { useThread } = useAssistantContext();
|
170
|
+
const firstRenderRef = (0, import_react5.useRef)(true);
|
171
|
+
const scrollToBottom = () => {
|
172
|
+
const div = messagesEndRef.current;
|
173
|
+
if (!div || !autoScroll)
|
174
|
+
return;
|
175
|
+
const behavior = firstRenderRef.current ? "instant" : "auto";
|
176
|
+
firstRenderRef.current = false;
|
177
|
+
div.scrollIntoView({ behavior });
|
178
|
+
};
|
156
179
|
useOnResizeContent(divRef, () => {
|
157
|
-
|
158
|
-
if (!div || !isAtBottom)
|
180
|
+
if (!useThread.getState().isAtBottom)
|
159
181
|
return;
|
160
|
-
|
182
|
+
scrollToBottom();
|
183
|
+
});
|
184
|
+
useOnScrollToBottom(() => {
|
185
|
+
scrollToBottom();
|
161
186
|
});
|
162
187
|
const handleScroll = () => {
|
163
188
|
const div = divRef.current;
|
164
189
|
if (!div)
|
165
190
|
return;
|
166
|
-
|
191
|
+
const isAtBottom = useThread.getState().isAtBottom;
|
192
|
+
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 50;
|
193
|
+
if (newIsAtBottom !== isAtBottom) {
|
194
|
+
useThread.setState({ isAtBottom: newIsAtBottom });
|
195
|
+
}
|
167
196
|
};
|
168
|
-
console.log(isAtBottom);
|
169
197
|
return /* @__PURE__ */ React.createElement(
|
170
198
|
import_react_primitive2.Primitive.div,
|
171
199
|
{
|
@@ -173,12 +201,13 @@ var ThreadViewport = (0, import_react4.forwardRef)(({ onScroll, children, ...res
|
|
173
201
|
onScroll: (0, import_primitive.composeEventHandlers)(onScroll, handleScroll),
|
174
202
|
ref
|
175
203
|
},
|
176
|
-
children
|
204
|
+
children,
|
205
|
+
/* @__PURE__ */ React.createElement("div", { ref: messagesEndRef })
|
177
206
|
);
|
178
207
|
});
|
179
208
|
|
180
209
|
// src/vercel/useVercelAIBranches.tsx
|
181
|
-
var
|
210
|
+
var import_react6 = require("react");
|
182
211
|
var ROOT_ID = "__ROOT_ID__";
|
183
212
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
184
213
|
var updateBranchData = (data, messages) => {
|
@@ -245,20 +274,20 @@ var sliceMessagesUntil = (messages, message) => {
|
|
245
274
|
throw new Error("Unexpected: Message not found");
|
246
275
|
return messages.slice(0, messageIdx);
|
247
276
|
};
|
248
|
-
var useVercelAIBranches = (chat) => {
|
249
|
-
const data = (0,
|
277
|
+
var useVercelAIBranches = (chat, context) => {
|
278
|
+
const data = (0, import_react6.useRef)({
|
250
279
|
parentMap: /* @__PURE__ */ new Map(),
|
251
280
|
branchMap: /* @__PURE__ */ new Map(),
|
252
281
|
snapshots: /* @__PURE__ */ new Map()
|
253
282
|
}).current;
|
254
283
|
updateBranchData(data, chat.messages);
|
255
|
-
const getBranchState = (0,
|
284
|
+
const getBranchState = (0, import_react6.useCallback)(
|
256
285
|
(message) => {
|
257
286
|
return getBranchStateImpl(data, chat.messages, message);
|
258
287
|
},
|
259
288
|
[data, chat.messages]
|
260
289
|
);
|
261
|
-
const switchToBranch = (0,
|
290
|
+
const switchToBranch = (0, import_react6.useCallback)(
|
262
291
|
(message, branchId) => {
|
263
292
|
const newMessages = switchToBranchImpl(
|
264
293
|
data,
|
@@ -270,28 +299,33 @@ var useVercelAIBranches = (chat) => {
|
|
270
299
|
},
|
271
300
|
[data, chat.messages, chat.setMessages]
|
272
301
|
);
|
273
|
-
const
|
302
|
+
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
303
|
+
const reloadAt = (0, import_react6.useCallback)(
|
274
304
|
async (message) => {
|
305
|
+
if (!reloadMaybe)
|
306
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
275
307
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
276
308
|
chat.setMessages(newMessages);
|
277
|
-
|
309
|
+
context.useThread.getState().scrollToBottom();
|
310
|
+
await reloadMaybe();
|
278
311
|
},
|
279
|
-
[chat.messages, chat.setMessages,
|
312
|
+
[context, chat.messages, chat.setMessages, reloadMaybe]
|
280
313
|
);
|
281
|
-
const editAt = (0,
|
314
|
+
const editAt = (0, import_react6.useCallback)(
|
282
315
|
async (message, newMessage) => {
|
283
316
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
284
317
|
chat.setMessages(newMessages);
|
285
318
|
if (newMessage.content[0]?.type !== "text")
|
286
319
|
throw new Error("Only text content is currently supported");
|
320
|
+
context.useThread.getState().scrollToBottom();
|
287
321
|
await chat.append({
|
288
322
|
role: "user",
|
289
323
|
content: newMessage.content[0].text
|
290
324
|
});
|
291
325
|
},
|
292
|
-
[chat.messages, chat.setMessages, chat.append]
|
326
|
+
[context, chat.messages, chat.setMessages, chat.append]
|
293
327
|
);
|
294
|
-
return (0,
|
328
|
+
return (0, import_react6.useMemo)(
|
295
329
|
() => ({
|
296
330
|
getBranchState,
|
297
331
|
switchToBranch,
|
@@ -305,24 +339,27 @@ var hasUpcomingMessage = (thread) => {
|
|
305
339
|
return thread.isLoading && thread.messages[thread.messages.length - 1]?.role !== "assistant";
|
306
340
|
};
|
307
341
|
|
308
|
-
// src/utils/context/
|
309
|
-
var
|
342
|
+
// src/utils/context/useComposerContext.ts
|
343
|
+
var import_react8 = require("react");
|
310
344
|
|
311
|
-
// src/utils/context/
|
312
|
-
var
|
313
|
-
var MessageContext = (0,
|
345
|
+
// src/utils/context/useMessageContext.ts
|
346
|
+
var import_react7 = require("react");
|
347
|
+
var MessageContext = (0, import_react7.createContext)(null);
|
314
348
|
var useMessageContext = () => {
|
315
|
-
const context = (0,
|
349
|
+
const context = (0, import_react7.useContext)(MessageContext);
|
316
350
|
if (!context)
|
317
351
|
throw new Error("useMessageContext must be used within a MessageProvider");
|
318
352
|
return context;
|
319
353
|
};
|
320
354
|
|
321
|
-
// src/utils/context/
|
355
|
+
// src/utils/context/useComposerContext.ts
|
322
356
|
var useComposerContext = () => {
|
323
357
|
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
324
|
-
const { useComposer: useMessageComposer } = (0,
|
325
|
-
return {
|
358
|
+
const { useComposer: useMessageComposer } = (0, import_react8.useContext)(MessageContext) ?? {};
|
359
|
+
return {
|
360
|
+
useComposer: useMessageComposer ?? useAssisstantComposer,
|
361
|
+
type: useMessageComposer ? "message" : "assistant"
|
362
|
+
};
|
326
363
|
};
|
327
364
|
|
328
365
|
// src/primitives/composer/ComposerIf.tsx
|
@@ -351,7 +388,7 @@ __export(message_exports, {
|
|
351
388
|
});
|
352
389
|
|
353
390
|
// src/primitives/message/MessageProvider.tsx
|
354
|
-
var
|
391
|
+
var import_react9 = require("react");
|
355
392
|
var import_zustand = require("zustand");
|
356
393
|
var import_shallow = require("zustand/react/shallow");
|
357
394
|
var getIsLast = (thread, message) => {
|
@@ -360,7 +397,7 @@ var getIsLast = (thread, message) => {
|
|
360
397
|
};
|
361
398
|
var useMessageContext2 = () => {
|
362
399
|
const { useBranchObserver } = useAssistantContext();
|
363
|
-
const [context] = (0,
|
400
|
+
const [context] = (0, import_react9.useState)(() => {
|
364
401
|
const useMessage = (0, import_zustand.create)(() => ({
|
365
402
|
message: null,
|
366
403
|
isLast: false,
|
@@ -417,9 +454,9 @@ var MessageProvider = ({
|
|
417
454
|
(0, import_shallow.useShallow)((b) => b.getBranchState(message))
|
418
455
|
);
|
419
456
|
const isLast = useThread((thread) => getIsLast(thread, message));
|
420
|
-
const [isCopied, setIsCopied] = (0,
|
421
|
-
const [isHovering, setIsHovering] = (0,
|
422
|
-
(0,
|
457
|
+
const [isCopied, setIsCopied] = (0, import_react9.useState)(false);
|
458
|
+
const [isHovering, setIsHovering] = (0, import_react9.useState)(false);
|
459
|
+
(0, import_react9.useMemo)(() => {
|
423
460
|
context.useMessage.setState(
|
424
461
|
{
|
425
462
|
message,
|
@@ -439,8 +476,8 @@ var MessageProvider = ({
|
|
439
476
|
// src/primitives/message/MessageRoot.tsx
|
440
477
|
var import_primitive2 = require("@radix-ui/primitive");
|
441
478
|
var import_react_primitive3 = require("@radix-ui/react-primitive");
|
442
|
-
var
|
443
|
-
var MessageRoot = (0,
|
479
|
+
var import_react10 = require("react");
|
480
|
+
var MessageRoot = (0, import_react10.forwardRef)(
|
444
481
|
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
445
482
|
const { useMessage } = useMessageContext();
|
446
483
|
const setIsHovering = useMessage((s) => s.setIsHovering);
|
@@ -495,12 +532,41 @@ var MessageIf = ({ children, ...query }) => {
|
|
495
532
|
};
|
496
533
|
|
497
534
|
// src/primitives/message/MessageContent.tsx
|
498
|
-
var
|
535
|
+
var defaultComponents = {
|
536
|
+
Text: ({ part }) => /* @__PURE__ */ React.createElement(React.Fragment, null, part.text),
|
537
|
+
Image: () => null,
|
538
|
+
UI: ({ part }) => part.display,
|
539
|
+
tools: {
|
540
|
+
Fallback: () => null
|
541
|
+
}
|
542
|
+
};
|
543
|
+
var MessageContent = ({
|
544
|
+
components: {
|
545
|
+
Text = defaultComponents.Text,
|
546
|
+
Image = defaultComponents.Image,
|
547
|
+
UI = defaultComponents.UI,
|
548
|
+
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
549
|
+
} = {}
|
550
|
+
}) => {
|
499
551
|
const { useMessage } = useMessageContext();
|
500
552
|
const content = useMessage((s) => s.message.content);
|
501
|
-
|
502
|
-
|
503
|
-
|
553
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, content.map((part, i) => {
|
554
|
+
const key = i;
|
555
|
+
switch (part.type) {
|
556
|
+
case "text":
|
557
|
+
return /* @__PURE__ */ React.createElement(Text, { key, part });
|
558
|
+
case "image":
|
559
|
+
return /* @__PURE__ */ React.createElement(Image, { key, part });
|
560
|
+
case "ui":
|
561
|
+
return /* @__PURE__ */ React.createElement(UI, { key, part });
|
562
|
+
case "tool-call": {
|
563
|
+
const Tool = by_name[part.name] || Fallback;
|
564
|
+
return /* @__PURE__ */ React.createElement(Tool, { key, part });
|
565
|
+
}
|
566
|
+
default:
|
567
|
+
return null;
|
568
|
+
}
|
569
|
+
}));
|
504
570
|
};
|
505
571
|
|
506
572
|
// src/primitives/thread/ThreadMessages.tsx
|
@@ -536,6 +602,29 @@ var ThreadMessages = ({ components }) => {
|
|
536
602
|
));
|
537
603
|
};
|
538
604
|
|
605
|
+
// src/primitives/thread/ThreadScrollToBottom.tsx
|
606
|
+
var import_primitive3 = require("@radix-ui/primitive");
|
607
|
+
var import_react_primitive4 = require("@radix-ui/react-primitive");
|
608
|
+
var import_react11 = require("react");
|
609
|
+
var ThreadScrollToBottom = (0, import_react11.forwardRef)(({ onClick, ...rest }, ref) => {
|
610
|
+
const { useThread } = useAssistantContext();
|
611
|
+
const isAtBottom = useThread((s) => s.isAtBottom);
|
612
|
+
const handleScrollToBottom = () => {
|
613
|
+
const thread = useThread.getState();
|
614
|
+
thread.scrollToBottom();
|
615
|
+
};
|
616
|
+
if (isAtBottom)
|
617
|
+
return null;
|
618
|
+
return /* @__PURE__ */ React.createElement(
|
619
|
+
import_react_primitive4.Primitive.button,
|
620
|
+
{
|
621
|
+
...rest,
|
622
|
+
ref,
|
623
|
+
onClick: (0, import_primitive3.composeEventHandlers)(onClick, handleScrollToBottom)
|
624
|
+
}
|
625
|
+
);
|
626
|
+
});
|
627
|
+
|
539
628
|
// src/primitives/composer/index.ts
|
540
629
|
var composer_exports = {};
|
541
630
|
__export(composer_exports, {
|
@@ -547,33 +636,15 @@ __export(composer_exports, {
|
|
547
636
|
});
|
548
637
|
|
549
638
|
// src/primitives/composer/ComposerRoot.tsx
|
550
|
-
var
|
639
|
+
var import_primitive4 = require("@radix-ui/primitive");
|
551
640
|
var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
|
552
|
-
var
|
553
|
-
var
|
554
|
-
var
|
555
|
-
var useComposerFormContext = () => {
|
556
|
-
const context = (0, import_react10.useContext)(ComposerFormContext);
|
557
|
-
if (!context) {
|
558
|
-
throw new Error(
|
559
|
-
"Composer compound components cannot be rendered outside the Composer component"
|
560
|
-
);
|
561
|
-
}
|
562
|
-
return context;
|
563
|
-
};
|
564
|
-
var ComposerRoot = (0, import_react10.forwardRef)(
|
641
|
+
var import_react_primitive5 = require("@radix-ui/react-primitive");
|
642
|
+
var import_react12 = require("react");
|
643
|
+
var ComposerRoot = (0, import_react12.forwardRef)(
|
565
644
|
({ onSubmit, ...rest }, forwardedRef) => {
|
566
645
|
const { useComposer } = useComposerContext();
|
567
|
-
const formRef = (0,
|
646
|
+
const formRef = (0, import_react12.useRef)(null);
|
568
647
|
const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
|
569
|
-
const composerContextValue = (0, import_react10.useMemo)(
|
570
|
-
() => ({
|
571
|
-
submit: () => formRef.current?.dispatchEvent(
|
572
|
-
new Event("submit", { cancelable: true, bubbles: true })
|
573
|
-
)
|
574
|
-
}),
|
575
|
-
[]
|
576
|
-
);
|
577
648
|
const handleSubmit = (e) => {
|
578
649
|
const composerState = useComposer.getState();
|
579
650
|
if (!composerState.isEditing)
|
@@ -581,73 +652,96 @@ var ComposerRoot = (0, import_react10.forwardRef)(
|
|
581
652
|
e.preventDefault();
|
582
653
|
composerState.send();
|
583
654
|
};
|
584
|
-
return /* @__PURE__ */ React.createElement(
|
585
|
-
|
655
|
+
return /* @__PURE__ */ React.createElement(
|
656
|
+
import_react_primitive5.Primitive.form,
|
586
657
|
{
|
587
658
|
...rest,
|
588
659
|
ref,
|
589
|
-
onSubmit: (0,
|
660
|
+
onSubmit: (0, import_primitive4.composeEventHandlers)(onSubmit, handleSubmit)
|
590
661
|
}
|
591
|
-
)
|
662
|
+
);
|
592
663
|
}
|
593
664
|
);
|
594
665
|
|
595
666
|
// src/primitives/composer/ComposerInput.tsx
|
596
|
-
var
|
667
|
+
var import_primitive5 = require("@radix-ui/primitive");
|
668
|
+
var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
|
597
669
|
var import_react_slot = require("@radix-ui/react-slot");
|
598
|
-
var
|
670
|
+
var import_react13 = require("react");
|
599
671
|
var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
|
600
|
-
var ComposerInput = (0,
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
}
|
639
|
-
|
640
|
-
|
672
|
+
var ComposerInput = (0, import_react13.forwardRef)(
|
673
|
+
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
674
|
+
const { useThread } = useAssistantContext();
|
675
|
+
const { useComposer, type } = useComposerContext();
|
676
|
+
const value = useComposer((c) => {
|
677
|
+
if (!c.isEditing)
|
678
|
+
return "";
|
679
|
+
return c.value;
|
680
|
+
});
|
681
|
+
const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
|
682
|
+
const handleKeyPress = (e) => {
|
683
|
+
if (disabled)
|
684
|
+
return;
|
685
|
+
const composer = useComposer.getState();
|
686
|
+
if (e.key === "Escape" && composer.canCancel) {
|
687
|
+
e.preventDefault();
|
688
|
+
useComposer.getState().cancel();
|
689
|
+
}
|
690
|
+
if (e.key === "Enter" && e.shiftKey === false) {
|
691
|
+
const isLoading = useThread.getState().isLoading;
|
692
|
+
if (!isLoading) {
|
693
|
+
e.preventDefault();
|
694
|
+
composer.send();
|
695
|
+
}
|
696
|
+
}
|
697
|
+
};
|
698
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
699
|
+
const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
|
700
|
+
const autoFocusEnabled = autoFocus !== false && !disabled;
|
701
|
+
const focus = (0, import_react13.useCallback)(() => {
|
702
|
+
const textarea = textareaRef.current;
|
703
|
+
if (!textarea || !autoFocusEnabled)
|
704
|
+
return;
|
705
|
+
textarea.focus();
|
706
|
+
textarea.setSelectionRange(
|
707
|
+
textareaRef.current.value.length,
|
708
|
+
textareaRef.current.value.length
|
709
|
+
);
|
710
|
+
}, [autoFocusEnabled]);
|
711
|
+
(0, import_react13.useEffect)(() => focus(), [focus]);
|
712
|
+
useOnScrollToBottom(() => {
|
713
|
+
if (type === "assistant") {
|
714
|
+
focus();
|
715
|
+
}
|
716
|
+
});
|
717
|
+
return /* @__PURE__ */ React.createElement(
|
718
|
+
Component,
|
719
|
+
{
|
720
|
+
value,
|
721
|
+
...rest,
|
722
|
+
ref,
|
723
|
+
disabled,
|
724
|
+
onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
|
725
|
+
const composerState = useComposer.getState();
|
726
|
+
if (!composerState.isEditing)
|
727
|
+
return;
|
728
|
+
return composerState.setValue(e.target.value);
|
729
|
+
}),
|
730
|
+
onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
|
731
|
+
}
|
732
|
+
);
|
733
|
+
}
|
734
|
+
);
|
641
735
|
|
642
736
|
// src/primitives/composer/ComposerSend.tsx
|
643
|
-
var
|
644
|
-
var
|
645
|
-
var ComposerSend = (0,
|
737
|
+
var import_react_primitive6 = require("@radix-ui/react-primitive");
|
738
|
+
var import_react14 = require("react");
|
739
|
+
var ComposerSend = (0, import_react14.forwardRef)(
|
646
740
|
({ disabled, ...rest }, ref) => {
|
647
741
|
const { useComposer } = useComposerContext();
|
648
742
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
649
743
|
return /* @__PURE__ */ React.createElement(
|
650
|
-
|
744
|
+
import_react_primitive6.Primitive.button,
|
651
745
|
{
|
652
746
|
type: "submit",
|
653
747
|
...rest,
|
@@ -659,22 +753,22 @@ var ComposerSend = (0, import_react12.forwardRef)(
|
|
659
753
|
);
|
660
754
|
|
661
755
|
// src/primitives/composer/ComposerCancel.tsx
|
662
|
-
var
|
663
|
-
var
|
664
|
-
var
|
665
|
-
var ComposerCancel = (0,
|
756
|
+
var import_primitive6 = require("@radix-ui/primitive");
|
757
|
+
var import_react_primitive7 = require("@radix-ui/react-primitive");
|
758
|
+
var import_react15 = require("react");
|
759
|
+
var ComposerCancel = (0, import_react15.forwardRef)(({ disabled, onClick, ...rest }, ref) => {
|
666
760
|
const { useComposer } = useComposerContext();
|
667
761
|
const hasValue = useComposer((c) => c.canCancel);
|
668
762
|
const handleClose = () => {
|
669
763
|
useComposer.getState().cancel();
|
670
764
|
};
|
671
765
|
return /* @__PURE__ */ React.createElement(
|
672
|
-
|
766
|
+
import_react_primitive7.Primitive.button,
|
673
767
|
{
|
674
768
|
type: "button",
|
675
769
|
...rest,
|
676
770
|
ref,
|
677
|
-
onClick: (0,
|
771
|
+
onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleClose),
|
678
772
|
disabled: disabled || !hasValue
|
679
773
|
}
|
680
774
|
);
|
@@ -690,16 +784,41 @@ __export(branchPicker_exports, {
|
|
690
784
|
Root: () => BranchPickerRoot
|
691
785
|
});
|
692
786
|
|
787
|
+
// src/utils/context/combined/useCombinedStore.ts
|
788
|
+
var import_react17 = require("react");
|
789
|
+
|
790
|
+
// src/utils/context/combined/createCombinedStore.ts
|
791
|
+
var import_react16 = require("react");
|
792
|
+
var createCombinedStore = (stores) => {
|
793
|
+
const subscribe = (callback) => {
|
794
|
+
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
795
|
+
return () => {
|
796
|
+
for (const unsub of unsubscribes) {
|
797
|
+
unsub();
|
798
|
+
}
|
799
|
+
};
|
800
|
+
};
|
801
|
+
return (selector) => {
|
802
|
+
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
803
|
+
return (0, import_react16.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
804
|
+
};
|
805
|
+
};
|
806
|
+
|
807
|
+
// src/utils/context/combined/useCombinedStore.ts
|
808
|
+
var useCombinedStore = (stores, selector) => {
|
809
|
+
const useCombined = (0, import_react17.useMemo)(() => createCombinedStore(stores), stores);
|
810
|
+
return useCombined(selector);
|
811
|
+
};
|
812
|
+
|
693
813
|
// src/actions/useGoToNextBranch.tsx
|
694
814
|
var useGoToNextBranch = () => {
|
695
815
|
const { useThread, useBranchObserver } = useAssistantContext();
|
696
816
|
const { useComposer, useMessage } = useMessageContext();
|
697
|
-
const
|
698
|
-
|
699
|
-
|
700
|
-
({ branchState: { branchId, branchCount } }) => branchId + 1 < branchCount
|
817
|
+
const disabled = useCombinedStore(
|
818
|
+
[useThread, useComposer, useMessage],
|
819
|
+
(t, c, m) => t.isLoading || c.isEditing || m.branchState.branchId + 1 >= m.branchState.branchCount
|
701
820
|
);
|
702
|
-
if (
|
821
|
+
if (disabled)
|
703
822
|
return null;
|
704
823
|
return () => {
|
705
824
|
const {
|
@@ -711,21 +830,21 @@ var useGoToNextBranch = () => {
|
|
711
830
|
};
|
712
831
|
|
713
832
|
// src/utils/createActionButton.tsx
|
714
|
-
var
|
715
|
-
var
|
716
|
-
var
|
833
|
+
var import_react18 = require("react");
|
834
|
+
var import_react_primitive8 = require("@radix-ui/react-primitive");
|
835
|
+
var import_primitive7 = require("@radix-ui/primitive");
|
717
836
|
var createActionButton = (useActionButton) => {
|
718
|
-
return (0,
|
837
|
+
return (0, import_react18.forwardRef)(
|
719
838
|
(props, forwardedRef) => {
|
720
839
|
const onClick = useActionButton(props);
|
721
840
|
return /* @__PURE__ */ React.createElement(
|
722
|
-
|
841
|
+
import_react_primitive8.Primitive.button,
|
723
842
|
{
|
724
843
|
type: "button",
|
725
844
|
disabled: !onClick,
|
726
845
|
...props,
|
727
846
|
ref: forwardedRef,
|
728
|
-
onClick: (0,
|
847
|
+
onClick: (0, import_primitive7.composeEventHandlers)(props.onClick, onClick ?? void 0)
|
729
848
|
}
|
730
849
|
);
|
731
850
|
}
|
@@ -739,10 +858,11 @@ var BranchPickerNext = createActionButton(useGoToNextBranch);
|
|
739
858
|
var useGoToPreviousBranch = () => {
|
740
859
|
const { useThread, useBranchObserver } = useAssistantContext();
|
741
860
|
const { useComposer, useMessage } = useMessageContext();
|
742
|
-
const
|
743
|
-
|
744
|
-
|
745
|
-
|
861
|
+
const disabled = useCombinedStore(
|
862
|
+
[useThread, useComposer, useMessage],
|
863
|
+
(t, c, m) => t.isLoading || c.isEditing || m.branchState.branchId <= 0
|
864
|
+
);
|
865
|
+
if (disabled)
|
746
866
|
return null;
|
747
867
|
return () => {
|
748
868
|
const {
|
@@ -771,10 +891,10 @@ var BranchPickerNumber = () => {
|
|
771
891
|
};
|
772
892
|
|
773
893
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
774
|
-
var
|
775
|
-
var
|
776
|
-
var BranchPickerRoot = (0,
|
777
|
-
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(
|
894
|
+
var import_react_primitive9 = require("@radix-ui/react-primitive");
|
895
|
+
var import_react19 = require("react");
|
896
|
+
var BranchPickerRoot = (0, import_react19.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
897
|
+
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(import_react_primitive9.Primitive.div, { ...rest, ref }));
|
778
898
|
});
|
779
899
|
|
780
900
|
// src/primitives/actionBar/index.ts
|
@@ -787,28 +907,30 @@ __export(actionBar_exports, {
|
|
787
907
|
});
|
788
908
|
|
789
909
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
790
|
-
var
|
791
|
-
var
|
792
|
-
var ActionBarRoot = (0,
|
910
|
+
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
911
|
+
var import_react20 = require("react");
|
912
|
+
var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenBusy, autohide, autohideFloat, ...rest }, ref) => {
|
793
913
|
const { useThread } = useAssistantContext();
|
794
914
|
const { useMessage } = useMessageContext();
|
795
|
-
const hideAndfloatStatus =
|
796
|
-
|
797
|
-
|
915
|
+
const hideAndfloatStatus = useCombinedStore(
|
916
|
+
[useThread, useMessage],
|
917
|
+
(t, m) => {
|
918
|
+
if (hideWhenBusy && t.isLoading)
|
919
|
+
return "hidden" /* Hidden */;
|
920
|
+
const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
|
921
|
+
if (!autohideEnabled)
|
922
|
+
return "normal" /* Normal */;
|
923
|
+
if (!m.isHovering)
|
924
|
+
return "hidden" /* Hidden */;
|
925
|
+
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
926
|
+
return "floating" /* Floating */;
|
798
927
|
return "normal" /* Normal */;
|
799
|
-
|
800
|
-
|
801
|
-
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
802
|
-
return "floating" /* Floating */;
|
803
|
-
return "normal" /* Normal */;
|
804
|
-
});
|
805
|
-
const busy = useThread((t) => t.isLoading);
|
806
|
-
if (hideWhenBusy && busy)
|
807
|
-
return null;
|
928
|
+
}
|
929
|
+
);
|
808
930
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
809
931
|
return null;
|
810
932
|
return /* @__PURE__ */ React.createElement(
|
811
|
-
|
933
|
+
import_react_primitive10.Primitive.div,
|
812
934
|
{
|
813
935
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
814
936
|
...rest,
|
@@ -840,9 +962,11 @@ var ActionBarCopy = createActionButton(useCopyMessage);
|
|
840
962
|
var useReloadMessage = () => {
|
841
963
|
const { useThread, useBranchObserver } = useAssistantContext();
|
842
964
|
const { useMessage } = useMessageContext();
|
843
|
-
const
|
844
|
-
|
845
|
-
|
965
|
+
const disabled = useCombinedStore(
|
966
|
+
[useThread, useMessage],
|
967
|
+
(t, m) => t.isLoading || m.message.role !== "assistant"
|
968
|
+
);
|
969
|
+
if (disabled)
|
846
970
|
return null;
|
847
971
|
return () => {
|
848
972
|
const message = useMessage.getState().message;
|
@@ -858,9 +982,11 @@ var ActionBarReload = createActionButton(useReloadMessage);
|
|
858
982
|
// src/actions/useBeginMessageEdit.tsx
|
859
983
|
var useBeginMessageEdit = () => {
|
860
984
|
const { useMessage, useComposer } = useMessageContext();
|
861
|
-
const
|
862
|
-
|
863
|
-
|
985
|
+
const disabled = useCombinedStore(
|
986
|
+
[useMessage, useComposer],
|
987
|
+
(m, c) => m.message.role !== "user" || c.isEditing
|
988
|
+
);
|
989
|
+
if (disabled)
|
864
990
|
return null;
|
865
991
|
return () => {
|
866
992
|
const { edit } = useComposer.getState();
|
@@ -872,25 +998,42 @@ var useBeginMessageEdit = () => {
|
|
872
998
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
873
999
|
|
874
1000
|
// src/vercel/VercelAIAssistantProvider.tsx
|
875
|
-
var
|
1001
|
+
var import_react22 = require("react");
|
1002
|
+
|
1003
|
+
// src/vercel/useDummyAIAssistantContext.tsx
|
1004
|
+
var import_react21 = require("react");
|
876
1005
|
var import_zustand2 = require("zustand");
|
877
|
-
var
|
878
|
-
const [context] = (0,
|
1006
|
+
var useDummyAIAssistantContext = () => {
|
1007
|
+
const [context] = (0, import_react21.useState)(() => {
|
1008
|
+
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
879
1009
|
const useThread = (0, import_zustand2.create)()(() => ({
|
880
1010
|
messages: [],
|
881
1011
|
isLoading: false,
|
882
|
-
reload: async () => {
|
883
|
-
},
|
884
1012
|
append: async () => {
|
1013
|
+
throw new Error("Not implemented");
|
885
1014
|
},
|
886
1015
|
stop: () => {
|
1016
|
+
throw new Error("Not implemented");
|
1017
|
+
},
|
1018
|
+
isAtBottom: true,
|
1019
|
+
scrollToBottom: () => {
|
1020
|
+
for (const listener of scrollToBottomListeners) {
|
1021
|
+
listener();
|
1022
|
+
}
|
1023
|
+
},
|
1024
|
+
onScrollToBottom: (callback) => {
|
1025
|
+
scrollToBottomListeners.add(callback);
|
1026
|
+
return () => {
|
1027
|
+
scrollToBottomListeners.delete(callback);
|
1028
|
+
};
|
887
1029
|
}
|
888
1030
|
}));
|
889
1031
|
const useComposer = (0, import_zustand2.create)()(() => ({
|
890
1032
|
isEditing: true,
|
891
1033
|
canCancel: false,
|
892
1034
|
value: "",
|
893
|
-
setValue: () => {
|
1035
|
+
setValue: (value) => {
|
1036
|
+
useComposer.setState({ value });
|
894
1037
|
},
|
895
1038
|
edit: () => {
|
896
1039
|
throw new Error("Not implemented");
|
@@ -909,19 +1052,24 @@ var useAIAssistantContext = () => {
|
|
909
1052
|
const useBranchObserver = (0, import_zustand2.create)()(() => ({
|
910
1053
|
getBranchState: () => ({
|
911
1054
|
branchId: 0,
|
912
|
-
branchCount:
|
1055
|
+
branchCount: 1
|
913
1056
|
}),
|
914
1057
|
switchToBranch: () => {
|
1058
|
+
throw new Error("Not implemented");
|
915
1059
|
},
|
916
1060
|
editAt: async () => {
|
1061
|
+
throw new Error("Not implemented");
|
917
1062
|
},
|
918
1063
|
reloadAt: async () => {
|
1064
|
+
throw new Error("Not implemented");
|
919
1065
|
}
|
920
1066
|
}));
|
921
1067
|
return { useThread, useComposer, useBranchObserver };
|
922
1068
|
});
|
923
1069
|
return context;
|
924
1070
|
};
|
1071
|
+
|
1072
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
925
1073
|
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
926
1074
|
var vercelToThreadMessage = (message) => {
|
927
1075
|
if (message.role !== "user" && message.role !== "assistant")
|
@@ -942,58 +1090,110 @@ var vercelToCachedThreadMessages = (messages) => {
|
|
942
1090
|
return newMessage;
|
943
1091
|
});
|
944
1092
|
};
|
945
|
-
var
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
const
|
951
|
-
|
952
|
-
|
953
|
-
|
1093
|
+
var VercelAIAssistantProvider = ({
|
1094
|
+
children,
|
1095
|
+
...rest
|
1096
|
+
}) => {
|
1097
|
+
const context = useDummyAIAssistantContext();
|
1098
|
+
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1099
|
+
const messages = (0, import_react22.useMemo)(() => {
|
1100
|
+
return vercelToCachedThreadMessages(vercel.messages);
|
1101
|
+
}, [vercel.messages]);
|
1102
|
+
const append = (0, import_react22.useCallback)(
|
954
1103
|
async (message) => {
|
955
1104
|
if (message.content[0]?.type !== "text") {
|
956
1105
|
throw new Error("Only text content is currently supported");
|
957
1106
|
}
|
958
|
-
|
1107
|
+
context.useThread.getState().scrollToBottom();
|
1108
|
+
await vercel.append({
|
959
1109
|
role: message.role,
|
960
1110
|
content: message.content[0].text
|
961
1111
|
});
|
962
1112
|
},
|
963
|
-
[
|
1113
|
+
[context, vercel.append]
|
964
1114
|
);
|
965
|
-
const stop = (0,
|
966
|
-
const lastMessage =
|
967
|
-
|
1115
|
+
const stop = (0, import_react22.useCallback)(() => {
|
1116
|
+
const lastMessage = vercel.messages.at(-1);
|
1117
|
+
vercel.stop();
|
968
1118
|
if (lastMessage?.role === "user") {
|
969
|
-
|
1119
|
+
vercel.setInput(lastMessage.content);
|
970
1120
|
}
|
971
|
-
}, [
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
);
|
983
|
-
}, [context, messages, reload, append, stop, chat.isLoading]);
|
984
|
-
(0, import_react17.useMemo)(() => {
|
1121
|
+
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1122
|
+
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1123
|
+
(0, import_react22.useMemo)(() => {
|
1124
|
+
context.useThread.setState({
|
1125
|
+
messages,
|
1126
|
+
isLoading,
|
1127
|
+
append,
|
1128
|
+
stop
|
1129
|
+
});
|
1130
|
+
}, [context, messages, append, stop, isLoading]);
|
1131
|
+
(0, import_react22.useMemo)(() => {
|
985
1132
|
context.useComposer.setState({
|
986
|
-
canCancel:
|
987
|
-
value:
|
988
|
-
setValue:
|
1133
|
+
canCancel: isLoading,
|
1134
|
+
value: vercel.input,
|
1135
|
+
setValue: vercel.setInput
|
989
1136
|
});
|
990
|
-
}, [context,
|
991
|
-
const branches = useVercelAIBranches(
|
992
|
-
(0,
|
1137
|
+
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1138
|
+
const branches = useVercelAIBranches(vercel, context);
|
1139
|
+
(0, import_react22.useMemo)(() => {
|
993
1140
|
context.useBranchObserver.setState(branches, true);
|
994
1141
|
}, [context, branches]);
|
995
1142
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
996
1143
|
};
|
1144
|
+
|
1145
|
+
// src/vercel/VercelRSCAssistantProvider.tsx
|
1146
|
+
var import_react23 = require("react");
|
1147
|
+
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
1148
|
+
var vercelToThreadMessage2 = (message) => {
|
1149
|
+
if (message.role !== "user" && message.role !== "assistant")
|
1150
|
+
throw new Error("Unsupported role");
|
1151
|
+
return {
|
1152
|
+
id: message.id,
|
1153
|
+
role: message.role,
|
1154
|
+
content: [{ type: "ui", display: message.display }]
|
1155
|
+
};
|
1156
|
+
};
|
1157
|
+
var vercelToCachedThreadMessages2 = (messages) => {
|
1158
|
+
return messages.map((m) => {
|
1159
|
+
const cached = ThreadMessageCache2.get(m);
|
1160
|
+
if (cached)
|
1161
|
+
return cached;
|
1162
|
+
const newMessage = vercelToThreadMessage2(m);
|
1163
|
+
ThreadMessageCache2.set(m, newMessage);
|
1164
|
+
return newMessage;
|
1165
|
+
});
|
1166
|
+
};
|
1167
|
+
var VercelRSCAssistantProvider = ({
|
1168
|
+
children,
|
1169
|
+
messages: vercelMessages,
|
1170
|
+
append: vercelAppend
|
1171
|
+
}) => {
|
1172
|
+
const context = useDummyAIAssistantContext();
|
1173
|
+
const messages = (0, import_react23.useMemo)(() => {
|
1174
|
+
return vercelToCachedThreadMessages2(vercelMessages);
|
1175
|
+
}, [vercelMessages]);
|
1176
|
+
const append = (0, import_react23.useCallback)(
|
1177
|
+
async (message) => {
|
1178
|
+
if (message.content[0]?.type !== "text") {
|
1179
|
+
throw new Error("Only text content is currently supported");
|
1180
|
+
}
|
1181
|
+
context.useThread.getState().scrollToBottom();
|
1182
|
+
await vercelAppend({
|
1183
|
+
role: message.role,
|
1184
|
+
content: [{ type: "text", text: message.content[0].text }]
|
1185
|
+
});
|
1186
|
+
},
|
1187
|
+
[context, vercelAppend]
|
1188
|
+
);
|
1189
|
+
(0, import_react23.useMemo)(() => {
|
1190
|
+
context.useThread.setState({
|
1191
|
+
messages,
|
1192
|
+
append
|
1193
|
+
});
|
1194
|
+
}, [context, messages, append]);
|
1195
|
+
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
1196
|
+
};
|
997
1197
|
// Annotate the CommonJS export names for ESM import in node:
|
998
1198
|
0 && (module.exports = {
|
999
1199
|
ActionBarPrimitive,
|
@@ -1002,6 +1202,7 @@ var VercelAIChatAssistantProvider = ({ chat, children }) => {
|
|
1002
1202
|
MessagePrimitive,
|
1003
1203
|
ThreadPrimitive,
|
1004
1204
|
VercelAIAssistantProvider,
|
1205
|
+
unstable_VercelRSCAssistantProvider,
|
1005
1206
|
unstable_useMessageContext,
|
1006
1207
|
useBeginMessageEdit,
|
1007
1208
|
useCopyMessage,
|