@assistant-ui/react 0.10.42 → 0.10.44
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/primitives/composer/ComposerAttachments.d.ts +24 -0
- package/dist/primitives/composer/ComposerAttachments.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAttachments.js +14 -13
- package/dist/primitives/composer/ComposerAttachments.js.map +1 -1
- package/dist/primitives/composer/index.d.ts +1 -0
- package/dist/primitives/composer/index.d.ts.map +1 -1
- package/dist/primitives/composer/index.js +2 -0
- package/dist/primitives/composer/index.js.map +1 -1
- package/dist/primitives/message/MessageAttachments.d.ts +24 -0
- package/dist/primitives/message/MessageAttachments.d.ts.map +1 -1
- package/dist/primitives/message/MessageAttachments.js +14 -13
- package/dist/primitives/message/MessageAttachments.js.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts +24 -0
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.js +16 -15
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message/index.d.ts +2 -0
- package/dist/primitives/message/index.d.ts.map +1 -1
- package/dist/primitives/message/index.js +4 -0
- package/dist/primitives/message/index.js.map +1 -1
- package/dist/primitives/thread/ThreadMessages.d.ts +24 -0
- package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadMessages.js +20 -15
- package/dist/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/primitives/thread/index.d.ts +1 -0
- package/dist/primitives/thread/index.d.ts.map +1 -1
- package/dist/primitives/thread/index.js +2 -0
- package/dist/primitives/thread/index.js.map +1 -1
- package/dist/primitives/threadList/ThreadListItems.d.ts +24 -0
- package/dist/primitives/threadList/ThreadListItems.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListItems.js +15 -18
- package/dist/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/primitives/threadList/index.d.ts +1 -0
- package/dist/primitives/threadList/index.d.ts.map +1 -1
- package/dist/primitives/threadList/index.js +2 -0
- package/dist/primitives/threadList/index.js.map +1 -1
- package/dist/runtimes/composer/BaseComposerRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/composer/BaseComposerRuntimeCore.js +5 -4
- package/dist/runtimes/composer/BaseComposerRuntimeCore.js.map +1 -1
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.d.ts +4 -1
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.js +25 -10
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
- package/dist/types/MessagePartTypes.d.ts +2 -0
- package/dist/types/MessagePartTypes.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/primitives/composer/ComposerAttachments.tsx +48 -24
- package/src/primitives/composer/index.ts +1 -0
- package/src/primitives/message/MessageAttachments.tsx +48 -24
- package/src/primitives/message/MessageParts.tsx +53 -33
- package/src/primitives/message/index.ts +2 -0
- package/src/primitives/thread/ThreadMessages.tsx +47 -27
- package/src/primitives/thread/index.ts +1 -0
- package/src/primitives/threadList/ThreadListItems.tsx +48 -33
- package/src/primitives/threadList/index.ts +1 -0
- package/src/runtimes/composer/BaseComposerRuntimeCore.tsx +5 -4
- package/src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx +29 -11
- package/src/types/MessagePartTypes.ts +2 -0
package/package.json
CHANGED
@@ -48,31 +48,55 @@ const AttachmentComponent: FC<{
|
|
48
48
|
return <Component />;
|
49
49
|
};
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
export namespace ComposerPrimitiveAttachmentByIndex {
|
52
|
+
export type Props = {
|
53
|
+
index: number;
|
54
|
+
components?: ComposerPrimitiveAttachments.Props["components"];
|
55
|
+
};
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Renders a single attachment at the specified index within the composer.
|
60
|
+
*
|
61
|
+
* This component provides direct access to render a specific attachment
|
62
|
+
* from the composer's attachment list using the provided component configuration.
|
63
|
+
*
|
64
|
+
* @example
|
65
|
+
* ```tsx
|
66
|
+
* <ComposerPrimitive.AttachmentByIndex
|
67
|
+
* index={0}
|
68
|
+
* components={{
|
69
|
+
* Image: MyImageAttachment,
|
70
|
+
* Document: MyDocumentAttachment
|
71
|
+
* }}
|
72
|
+
* />
|
73
|
+
* ```
|
74
|
+
*/
|
75
|
+
export const ComposerPrimitiveAttachmentByIndex: FC<ComposerPrimitiveAttachmentByIndex.Props> =
|
76
|
+
memo(
|
77
|
+
({ index, components }) => {
|
78
|
+
const composerRuntime = useComposerRuntime();
|
79
|
+
const runtime = useMemo(
|
80
|
+
() => composerRuntime.getAttachmentByIndex(index),
|
81
|
+
[composerRuntime, index],
|
82
|
+
);
|
59
83
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
84
|
+
return (
|
85
|
+
<AttachmentRuntimeProvider runtime={runtime}>
|
86
|
+
<AttachmentComponent components={components} />
|
87
|
+
</AttachmentRuntimeProvider>
|
88
|
+
);
|
89
|
+
},
|
90
|
+
(prev, next) =>
|
91
|
+
prev.index === next.index &&
|
92
|
+
prev.components?.Image === next.components?.Image &&
|
93
|
+
prev.components?.Document === next.components?.Document &&
|
94
|
+
prev.components?.File === next.components?.File &&
|
95
|
+
prev.components?.Attachment === next.components?.Attachment,
|
64
96
|
);
|
65
|
-
};
|
66
97
|
|
67
|
-
|
68
|
-
|
69
|
-
(prev, next) =>
|
70
|
-
prev.attachmentIndex === next.attachmentIndex &&
|
71
|
-
prev.components?.Image === next.components?.Image &&
|
72
|
-
prev.components?.Document === next.components?.Document &&
|
73
|
-
prev.components?.File === next.components?.File &&
|
74
|
-
prev.components?.Attachment === next.components?.Attachment,
|
75
|
-
);
|
98
|
+
ComposerPrimitiveAttachmentByIndex.displayName =
|
99
|
+
"ComposerPrimitive.AttachmentByIndex";
|
76
100
|
|
77
101
|
export const ComposerPrimitiveAttachments: FC<
|
78
102
|
ComposerPrimitiveAttachments.Props
|
@@ -81,9 +105,9 @@ export const ComposerPrimitiveAttachments: FC<
|
|
81
105
|
|
82
106
|
const attachmentElements = useMemo(() => {
|
83
107
|
return Array.from({ length: attachmentsCount }, (_, index) => (
|
84
|
-
<
|
108
|
+
<ComposerPrimitiveAttachmentByIndex
|
85
109
|
key={index}
|
86
|
-
|
110
|
+
index={index}
|
87
111
|
components={components}
|
88
112
|
/>
|
89
113
|
));
|
@@ -4,4 +4,5 @@ export { ComposerPrimitiveSend as Send } from "./ComposerSend";
|
|
4
4
|
export { ComposerPrimitiveCancel as Cancel } from "./ComposerCancel";
|
5
5
|
export { ComposerPrimitiveAddAttachment as AddAttachment } from "./ComposerAddAttachment";
|
6
6
|
export { ComposerPrimitiveAttachments as Attachments } from "./ComposerAttachments";
|
7
|
+
export { ComposerPrimitiveAttachmentByIndex as AttachmentByIndex } from "./ComposerAttachments";
|
7
8
|
export { ComposerPrimitiveIf as If } from "./ComposerIf";
|
@@ -46,31 +46,55 @@ const AttachmentComponent: FC<{
|
|
46
46
|
return <Component />;
|
47
47
|
};
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
export namespace MessagePrimitiveAttachmentByIndex {
|
50
|
+
export type Props = {
|
51
|
+
index: number;
|
52
|
+
components?: MessagePrimitiveAttachments.Props["components"];
|
53
|
+
};
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Renders a single attachment at the specified index within the current message.
|
58
|
+
*
|
59
|
+
* This component provides direct access to render a specific attachment
|
60
|
+
* from the message's attachment list using the provided component configuration.
|
61
|
+
*
|
62
|
+
* @example
|
63
|
+
* ```tsx
|
64
|
+
* <MessagePrimitive.AttachmentByIndex
|
65
|
+
* index={0}
|
66
|
+
* components={{
|
67
|
+
* Image: MyImageAttachment,
|
68
|
+
* Document: MyDocumentAttachment
|
69
|
+
* }}
|
70
|
+
* />
|
71
|
+
* ```
|
72
|
+
*/
|
73
|
+
export const MessagePrimitiveAttachmentByIndex: FC<MessagePrimitiveAttachmentByIndex.Props> =
|
74
|
+
memo(
|
75
|
+
({ index, components }) => {
|
76
|
+
const messageRuntime = useMessageRuntime();
|
77
|
+
const runtime = useMemo(
|
78
|
+
() => messageRuntime.getAttachmentByIndex(index),
|
79
|
+
[messageRuntime, index],
|
80
|
+
);
|
57
81
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
82
|
+
return (
|
83
|
+
<AttachmentRuntimeProvider runtime={runtime}>
|
84
|
+
<AttachmentComponent components={components} />
|
85
|
+
</AttachmentRuntimeProvider>
|
86
|
+
);
|
87
|
+
},
|
88
|
+
(prev, next) =>
|
89
|
+
prev.index === next.index &&
|
90
|
+
prev.components?.Image === next.components?.Image &&
|
91
|
+
prev.components?.Document === next.components?.Document &&
|
92
|
+
prev.components?.File === next.components?.File &&
|
93
|
+
prev.components?.Attachment === next.components?.Attachment,
|
62
94
|
);
|
63
|
-
};
|
64
95
|
|
65
|
-
|
66
|
-
|
67
|
-
(prev, next) =>
|
68
|
-
prev.attachmentIndex === next.attachmentIndex &&
|
69
|
-
prev.components?.Image === next.components?.Image &&
|
70
|
-
prev.components?.Document === next.components?.Document &&
|
71
|
-
prev.components?.File === next.components?.File &&
|
72
|
-
prev.components?.Attachment === next.components?.Attachment,
|
73
|
-
);
|
96
|
+
MessagePrimitiveAttachmentByIndex.displayName =
|
97
|
+
"MessagePrimitive.AttachmentByIndex";
|
74
98
|
|
75
99
|
export const MessagePrimitiveAttachments: FC<
|
76
100
|
MessagePrimitiveAttachments.Props
|
@@ -82,9 +106,9 @@ export const MessagePrimitiveAttachments: FC<
|
|
82
106
|
|
83
107
|
const attachmentElements = useMemo(() => {
|
84
108
|
return Array.from({ length: attachmentsCount }, (_, index) => (
|
85
|
-
<
|
109
|
+
<MessagePrimitiveAttachmentByIndex
|
86
110
|
key={index}
|
87
|
-
|
111
|
+
index={index}
|
88
112
|
components={components}
|
89
113
|
/>
|
90
114
|
));
|
@@ -279,38 +279,58 @@ const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
279
279
|
}
|
280
280
|
};
|
281
281
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
const messageRuntime = useMessageRuntime();
|
289
|
-
const runtime = useMemo(
|
290
|
-
() => messageRuntime.getMessagePartByIndex(partIndex),
|
291
|
-
[messageRuntime, partIndex],
|
292
|
-
);
|
282
|
+
export namespace MessagePrimitivePartByIndex {
|
283
|
+
export type Props = {
|
284
|
+
index: number;
|
285
|
+
components: MessagePrimitiveParts.Props["components"];
|
286
|
+
};
|
287
|
+
}
|
293
288
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
289
|
+
/**
|
290
|
+
* Renders a single message part at the specified index.
|
291
|
+
*
|
292
|
+
* This component provides direct access to render a specific message part
|
293
|
+
* within the current message context, using the provided component configuration.
|
294
|
+
*
|
295
|
+
* @example
|
296
|
+
* ```tsx
|
297
|
+
* <MessagePrimitive.PartByIndex
|
298
|
+
* index={0}
|
299
|
+
* components={{
|
300
|
+
* Text: MyTextComponent,
|
301
|
+
* Image: MyImageComponent
|
302
|
+
* }}
|
303
|
+
* />
|
304
|
+
* ```
|
305
|
+
*/
|
306
|
+
export const MessagePrimitivePartByIndex: FC<MessagePrimitivePartByIndex.Props> =
|
307
|
+
memo(
|
308
|
+
({ index, components }) => {
|
309
|
+
const messageRuntime = useMessageRuntime();
|
310
|
+
const runtime = useMemo(
|
311
|
+
() => messageRuntime.getMessagePartByIndex(index),
|
312
|
+
[messageRuntime, index],
|
313
|
+
);
|
314
|
+
|
315
|
+
return (
|
316
|
+
<MessagePartRuntimeProvider runtime={runtime}>
|
317
|
+
<MessagePartComponent components={components} />
|
318
|
+
</MessagePartRuntimeProvider>
|
319
|
+
);
|
320
|
+
},
|
321
|
+
(prev, next) =>
|
322
|
+
prev.index === next.index &&
|
323
|
+
prev.components?.Text === next.components?.Text &&
|
324
|
+
prev.components?.Reasoning === next.components?.Reasoning &&
|
325
|
+
prev.components?.Source === next.components?.Source &&
|
326
|
+
prev.components?.Image === next.components?.Image &&
|
327
|
+
prev.components?.File === next.components?.File &&
|
328
|
+
prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&
|
329
|
+
prev.components?.tools === next.components?.tools &&
|
330
|
+
prev.components?.ToolGroup === next.components?.ToolGroup,
|
298
331
|
);
|
299
|
-
};
|
300
332
|
|
301
|
-
|
302
|
-
MessagePartImpl,
|
303
|
-
(prev, next) =>
|
304
|
-
prev.partIndex === next.partIndex &&
|
305
|
-
prev.components?.Text === next.components?.Text &&
|
306
|
-
prev.components?.Reasoning === next.components?.Reasoning &&
|
307
|
-
prev.components?.Source === next.components?.Source &&
|
308
|
-
prev.components?.Image === next.components?.Image &&
|
309
|
-
prev.components?.File === next.components?.File &&
|
310
|
-
prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&
|
311
|
-
prev.components?.tools === next.components?.tools &&
|
312
|
-
prev.components?.ToolGroup === next.components?.ToolGroup,
|
313
|
-
);
|
333
|
+
MessagePrimitivePartByIndex.displayName = "MessagePrimitive.PartByIndex";
|
314
334
|
|
315
335
|
const COMPLETE_STATUS: MessagePartStatus = Object.freeze({
|
316
336
|
type: "complete",
|
@@ -386,9 +406,9 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
386
406
|
return messageRanges.map((range) => {
|
387
407
|
if (range.type === "single") {
|
388
408
|
return (
|
389
|
-
<
|
409
|
+
<MessagePrimitivePartByIndex
|
390
410
|
key={range.index}
|
391
|
-
|
411
|
+
index={range.index}
|
392
412
|
components={components}
|
393
413
|
/>
|
394
414
|
);
|
@@ -404,9 +424,9 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
404
424
|
{Array.from(
|
405
425
|
{ length: range.endIndex - range.startIndex + 1 },
|
406
426
|
(_, i) => (
|
407
|
-
<
|
427
|
+
<MessagePrimitivePartByIndex
|
408
428
|
key={i}
|
409
|
-
|
429
|
+
index={range.startIndex + i}
|
410
430
|
components={components}
|
411
431
|
/>
|
412
432
|
),
|
@@ -1,8 +1,10 @@
|
|
1
1
|
export { MessagePrimitiveRoot as Root } from "./MessageRoot";
|
2
2
|
export { MessagePrimitiveParts as Parts } from "./MessageParts";
|
3
|
+
export { MessagePrimitivePartByIndex as PartByIndex } from "./MessageParts";
|
3
4
|
export { MessagePrimitiveParts as Content } from "./MessageParts";
|
4
5
|
export { MessagePrimitiveIf as If } from "./MessageIf";
|
5
6
|
export { MessagePrimitiveAttachments as Attachments } from "./MessageAttachments";
|
7
|
+
export { MessagePrimitiveAttachmentByIndex as AttachmentByIndex } from "./MessageAttachments";
|
6
8
|
export { MessagePrimitiveError as Error } from "./MessageError";
|
7
9
|
export {
|
8
10
|
MessagePrimitiveUnstable_PartsGrouped as Unstable_PartsGrouped,
|
@@ -136,35 +136,51 @@ const ThreadMessageComponent: FC<ThreadMessageComponentProps> = ({
|
|
136
136
|
|
137
137
|
return <Component />;
|
138
138
|
};
|
139
|
+
export namespace ThreadPrimitiveMessageByIndex {
|
140
|
+
export type Props = {
|
141
|
+
index: number;
|
142
|
+
components: ThreadPrimitiveMessages.Props["components"];
|
143
|
+
};
|
144
|
+
}
|
139
145
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
146
|
+
/**
|
147
|
+
* Renders a single message at the specified index in the current thread.
|
148
|
+
*
|
149
|
+
* This component provides message context for a specific message in the thread
|
150
|
+
* and renders it using the provided component configuration.
|
151
|
+
*
|
152
|
+
* @example
|
153
|
+
* ```tsx
|
154
|
+
* <ThreadPrimitive.MessageByIndex
|
155
|
+
* index={0}
|
156
|
+
* components={{
|
157
|
+
* UserMessage: MyUserMessage,
|
158
|
+
* AssistantMessage: MyAssistantMessage
|
159
|
+
* }}
|
160
|
+
* />
|
161
|
+
* ```
|
162
|
+
*/
|
163
|
+
export const ThreadPrimitiveMessageByIndex: FC<ThreadPrimitiveMessageByIndex.Props> =
|
164
|
+
memo(
|
165
|
+
({ index, components }) => {
|
166
|
+
const threadRuntime = useThreadRuntime();
|
167
|
+
const runtime = useMemo(
|
168
|
+
() => threadRuntime.getMesssageByIndex(index),
|
169
|
+
[threadRuntime, index],
|
170
|
+
);
|
171
|
+
|
172
|
+
return (
|
173
|
+
<MessageRuntimeProvider runtime={runtime}>
|
174
|
+
<ThreadMessageComponent components={components} />
|
175
|
+
</MessageRuntimeProvider>
|
176
|
+
);
|
177
|
+
},
|
178
|
+
(prev, next) =>
|
179
|
+
prev.index === next.index &&
|
180
|
+
isComponentsSame(prev.components, next.components),
|
159
181
|
);
|
160
|
-
};
|
161
182
|
|
162
|
-
|
163
|
-
ThreadMessageImpl,
|
164
|
-
(prev, next) =>
|
165
|
-
prev.messageIndex === next.messageIndex &&
|
166
|
-
isComponentsSame(prev.components, next.components),
|
167
|
-
);
|
183
|
+
ThreadPrimitiveMessageByIndex.displayName = "ThreadPrimitive.MessageByIndex";
|
168
184
|
|
169
185
|
/**
|
170
186
|
* Renders all messages in the current thread using the provided component configuration.
|
@@ -192,7 +208,11 @@ export const ThreadPrimitiveMessagesImpl: FC<ThreadPrimitiveMessages.Props> = ({
|
|
192
208
|
const messageElements = useMemo(() => {
|
193
209
|
if (messagesLength === 0) return null;
|
194
210
|
return Array.from({ length: messagesLength }, (_, index) => (
|
195
|
-
<
|
211
|
+
<ThreadPrimitiveMessageByIndex
|
212
|
+
key={index}
|
213
|
+
index={index}
|
214
|
+
components={components}
|
215
|
+
/>
|
196
216
|
));
|
197
217
|
}, [messagesLength, components]);
|
198
218
|
|
@@ -3,5 +3,6 @@ export { ThreadPrimitiveEmpty as Empty } from "./ThreadEmpty";
|
|
3
3
|
export { ThreadPrimitiveIf as If } from "./ThreadIf";
|
4
4
|
export { ThreadPrimitiveViewport as Viewport } from "./ThreadViewport";
|
5
5
|
export { ThreadPrimitiveMessages as Messages } from "./ThreadMessages";
|
6
|
+
export { ThreadPrimitiveMessageByIndex as MessageByIndex } from "./ThreadMessages";
|
6
7
|
export { ThreadPrimitiveScrollToBottom as ScrollToBottom } from "./ThreadScrollToBottom";
|
7
8
|
export { ThreadPrimitiveSuggestion as Suggestion } from "./ThreadSuggestion";
|
@@ -13,42 +13,57 @@ export namespace ThreadListPrimitiveItems {
|
|
13
13
|
};
|
14
14
|
}
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
export namespace ThreadListPrimitiveItemByIndex {
|
17
|
+
export type Props = {
|
18
|
+
index: number;
|
19
|
+
archived?: boolean | undefined;
|
20
|
+
components: ThreadListPrimitiveItems.Props["components"];
|
21
|
+
};
|
22
|
+
}
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
/**
|
25
|
+
* Renders a single thread list item at the specified index.
|
26
|
+
*
|
27
|
+
* This component provides direct access to render a specific thread
|
28
|
+
* from the thread list using the provided component configuration.
|
29
|
+
*
|
30
|
+
* @example
|
31
|
+
* ```tsx
|
32
|
+
* <ThreadListPrimitive.ItemByIndex
|
33
|
+
* index={0}
|
34
|
+
* components={{
|
35
|
+
* ThreadListItem: MyThreadListItem
|
36
|
+
* }}
|
37
|
+
* />
|
38
|
+
* ```
|
39
|
+
*/
|
40
|
+
export const ThreadListPrimitiveItemByIndex: FC<ThreadListPrimitiveItemByIndex.Props> =
|
41
|
+
memo(
|
42
|
+
({ index, archived = false, components }) => {
|
43
|
+
const assistantRuntime = useAssistantRuntime();
|
44
|
+
const runtime = useMemo(
|
45
|
+
() =>
|
46
|
+
archived
|
47
|
+
? assistantRuntime.threads.getArchivedItemByIndex(index)
|
48
|
+
: assistantRuntime.threads.getItemByIndex(index),
|
49
|
+
[assistantRuntime, index, archived],
|
50
|
+
);
|
35
51
|
|
36
|
-
|
52
|
+
const ThreadListItemComponent = components.ThreadListItem;
|
37
53
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
54
|
+
return (
|
55
|
+
<ThreadListItemRuntimeProvider runtime={runtime}>
|
56
|
+
<ThreadListItemComponent />
|
57
|
+
</ThreadListItemRuntimeProvider>
|
58
|
+
);
|
59
|
+
},
|
60
|
+
(prev, next) =>
|
61
|
+
prev.index === next.index &&
|
62
|
+
prev.archived === next.archived &&
|
63
|
+
prev.components.ThreadListItem === next.components.ThreadListItem,
|
42
64
|
);
|
43
|
-
};
|
44
65
|
|
45
|
-
|
46
|
-
ThreadListItemImpl,
|
47
|
-
(prev, next) =>
|
48
|
-
prev.partIndex === next.partIndex &&
|
49
|
-
prev.archived === next.archived &&
|
50
|
-
prev.components.ThreadListItem === next.components.ThreadListItem,
|
51
|
-
);
|
66
|
+
ThreadListPrimitiveItemByIndex.displayName = "ThreadListPrimitive.ItemByIndex";
|
52
67
|
|
53
68
|
export const ThreadListPrimitiveItems: FC<ThreadListPrimitiveItems.Props> = ({
|
54
69
|
archived = false,
|
@@ -60,9 +75,9 @@ export const ThreadListPrimitiveItems: FC<ThreadListPrimitiveItems.Props> = ({
|
|
60
75
|
|
61
76
|
const listElements = useMemo(() => {
|
62
77
|
return Array.from({ length: contentLength }, (_, index) => (
|
63
|
-
<
|
78
|
+
<ThreadListPrimitiveItemByIndex
|
64
79
|
key={index}
|
65
|
-
|
80
|
+
index={index}
|
66
81
|
archived={archived}
|
67
82
|
components={components}
|
68
83
|
/>
|
@@ -1,3 +1,4 @@
|
|
1
1
|
export { ThreadListPrimitiveNew as New } from "./ThreadListNew";
|
2
2
|
export { ThreadListPrimitiveItems as Items } from "./ThreadListItems";
|
3
|
+
export { ThreadListPrimitiveItemByIndex as ItemByIndex } from "./ThreadListItems";
|
3
4
|
export { ThreadListPrimitiveRoot as Root } from "./ThreadListRoot";
|
@@ -124,7 +124,7 @@ export abstract class BaseComposerRuntimeCore
|
|
124
124
|
const adapter = this.getAttachmentAdapter();
|
125
125
|
const attachments =
|
126
126
|
adapter && this.attachments.length > 0
|
127
|
-
?
|
127
|
+
? Promise.all(
|
128
128
|
this.attachments.map(async (a) => {
|
129
129
|
if (isAttachmentComplete(a)) return a;
|
130
130
|
const result = await adapter.send(a);
|
@@ -133,15 +133,16 @@ export abstract class BaseComposerRuntimeCore
|
|
133
133
|
)
|
134
134
|
: [];
|
135
135
|
|
136
|
+
const text = this.text;
|
137
|
+
this._emptyTextAndAttachments();
|
136
138
|
const message: Omit<AppendMessage, "parentId" | "sourceId"> = {
|
137
139
|
createdAt: new Date(),
|
138
140
|
role: this.role,
|
139
|
-
content:
|
140
|
-
attachments,
|
141
|
+
content: text ? [{ type: "text", text }] : [],
|
142
|
+
attachments: await attachments,
|
141
143
|
runConfig: this.runConfig,
|
142
144
|
metadata: { custom: {} },
|
143
145
|
};
|
144
|
-
this._emptyTextAndAttachments();
|
145
146
|
|
146
147
|
this.handleSend(message);
|
147
148
|
this._notifyEventSubscribers("send");
|
@@ -12,7 +12,7 @@ import {
|
|
12
12
|
} from "./getExternalStoreMessage";
|
13
13
|
import { ThreadMessageConverter } from "./ThreadMessageConverter";
|
14
14
|
import { getAutoStatus, isAutoStatus } from "./auto-status";
|
15
|
-
import { fromThreadMessageLike } from "./ThreadMessageLike";
|
15
|
+
import { fromThreadMessageLike, ThreadMessageLike } from "./ThreadMessageLike";
|
16
16
|
import { getThreadMessageText } from "../../utils/getThreadMessageText";
|
17
17
|
import {
|
18
18
|
RuntimeCapabilities,
|
@@ -20,6 +20,10 @@ import {
|
|
20
20
|
} from "../core/ThreadRuntimeCore";
|
21
21
|
import { BaseThreadRuntimeCore } from "../core/BaseThreadRuntimeCore";
|
22
22
|
import { ModelContextProvider } from "../../model-context";
|
23
|
+
import {
|
24
|
+
ExportedMessageRepository,
|
25
|
+
MessageRepository,
|
26
|
+
} from "../utils/MessageRepository";
|
23
27
|
|
24
28
|
const EMPTY_ARRAY = Object.freeze([]);
|
25
29
|
|
@@ -34,7 +38,8 @@ export class ExternalStoreThreadRuntimeCore
|
|
34
38
|
extends BaseThreadRuntimeCore
|
35
39
|
implements ThreadRuntimeCore
|
36
40
|
{
|
37
|
-
private
|
41
|
+
private _resetScheduled = false;
|
42
|
+
private _assistantOptimisticId: string | null = null;
|
38
43
|
|
39
44
|
private _capabilities: RuntimeCapabilities = {
|
40
45
|
switchToBranch: false,
|
@@ -123,7 +128,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
123
128
|
|
124
129
|
// Clear and import the message repository
|
125
130
|
this.repository.clear();
|
126
|
-
this.
|
131
|
+
this._assistantOptimisticId = null;
|
127
132
|
this.repository.import(store.messageRepository);
|
128
133
|
|
129
134
|
messages = this.repository.getMessages();
|
@@ -170,6 +175,12 @@ export class ExternalStoreThreadRuntimeCore
|
|
170
175
|
return newMessage;
|
171
176
|
});
|
172
177
|
|
178
|
+
// special case: branches should be reset if an empty array is provided
|
179
|
+
if (this._resetScheduled || messages.length === 0) {
|
180
|
+
this._resetScheduled = false;
|
181
|
+
this.repository.clear();
|
182
|
+
}
|
183
|
+
|
173
184
|
for (let i = 0; i < messages.length; i++) {
|
174
185
|
const message = messages[i]!;
|
175
186
|
const parent = messages[i - 1];
|
@@ -192,13 +203,13 @@ export class ExternalStoreThreadRuntimeCore
|
|
192
203
|
}
|
193
204
|
}
|
194
205
|
|
195
|
-
if (this.
|
196
|
-
this.repository.deleteMessage(this.
|
197
|
-
this.
|
206
|
+
if (this._assistantOptimisticId) {
|
207
|
+
this.repository.deleteMessage(this._assistantOptimisticId);
|
208
|
+
this._assistantOptimisticId = null;
|
198
209
|
}
|
199
210
|
|
200
211
|
if (hasUpcomingMessage(isRunning, messages)) {
|
201
|
-
this.
|
212
|
+
this._assistantOptimisticId = this.repository.appendOptimisticMessage(
|
202
213
|
messages.at(-1)?.id ?? null,
|
203
214
|
{
|
204
215
|
role: "assistant",
|
@@ -208,7 +219,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
208
219
|
}
|
209
220
|
|
210
221
|
this.repository.resetHead(
|
211
|
-
this.
|
222
|
+
this._assistantOptimisticId ?? messages.at(-1)?.id ?? null,
|
212
223
|
);
|
213
224
|
|
214
225
|
this._messages = this.repository.getMessages();
|
@@ -250,9 +261,9 @@ export class ExternalStoreThreadRuntimeCore
|
|
250
261
|
|
251
262
|
this._store.onCancel();
|
252
263
|
|
253
|
-
if (this.
|
254
|
-
this.repository.deleteMessage(this.
|
255
|
-
this.
|
264
|
+
if (this._assistantOptimisticId) {
|
265
|
+
this.repository.deleteMessage(this._assistantOptimisticId);
|
266
|
+
this._assistantOptimisticId = null;
|
256
267
|
}
|
257
268
|
|
258
269
|
let messages = this.repository.getMessages();
|
@@ -283,6 +294,13 @@ export class ExternalStoreThreadRuntimeCore
|
|
283
294
|
this._store.onAddToolResult?.(options);
|
284
295
|
}
|
285
296
|
|
297
|
+
public override reset(initialMessages?: readonly ThreadMessageLike[]) {
|
298
|
+
const repo = new MessageRepository();
|
299
|
+
repo.import(ExportedMessageRepository.fromArray(initialMessages ?? []));
|
300
|
+
this._resetScheduled = true;
|
301
|
+
this.updateMessages(repo.getMessages());
|
302
|
+
}
|
303
|
+
|
286
304
|
private updateMessages = (messages: readonly ThreadMessage[]) => {
|
287
305
|
const hasConverter = this._store.convertMessage !== undefined;
|
288
306
|
if (hasConverter) {
|
@@ -24,10 +24,12 @@ export type SourceMessagePart = {
|
|
24
24
|
export type ImageMessagePart = {
|
25
25
|
readonly type: "image";
|
26
26
|
readonly image: string;
|
27
|
+
readonly filename?: string;
|
27
28
|
};
|
28
29
|
|
29
30
|
export type FileMessagePart = {
|
30
31
|
readonly type: "file";
|
32
|
+
readonly filename?: string;
|
31
33
|
readonly data: string;
|
32
34
|
readonly mimeType: string;
|
33
35
|
};
|