@assistant-ui/react 0.10.33 → 0.10.35
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/message/MessagePartsGrouped.d.ts +182 -0
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -0
- package/dist/primitives/message/{MessagePartsGroupedByParentId.js → MessagePartsGrouped.js} +23 -11
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -0
- package/dist/primitives/message/index.d.ts +1 -1
- package/dist/primitives/message/index.d.ts.map +1 -1
- package/dist/primitives/message/index.js +5 -1
- package/dist/primitives/message/index.js.map +1 -1
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.js +1 -1
- package/dist/runtimes/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.js +3 -1
- package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/tests/setup.js +8 -8
- package/dist/tests/setup.js.map +1 -1
- package/package.json +7 -7
- package/src/primitives/message/{MessagePartsGroupedByParentId.tsx → MessagePartsGrouped.tsx} +129 -56
- package/src/primitives/message/index.ts +4 -1
- package/src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx +1 -1
- package/src/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +3 -1
- package/dist/primitives/message/MessagePartsGroupedByParentId.d.ts +0 -122
- package/dist/primitives/message/MessagePartsGroupedByParentId.d.ts.map +0 -1
- package/dist/primitives/message/MessagePartsGroupedByParentId.js.map +0 -1
package/package.json
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
"conversational-ui",
|
29
29
|
"conversational-ai"
|
30
30
|
],
|
31
|
-
"version": "0.10.
|
31
|
+
"version": "0.10.35",
|
32
32
|
"license": "MIT",
|
33
33
|
"type": "module",
|
34
34
|
"exports": {
|
@@ -57,13 +57,13 @@
|
|
57
57
|
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
58
58
|
"@radix-ui/react-use-escape-keydown": "^1.1.1",
|
59
59
|
"@standard-schema/spec": "^1.0.0",
|
60
|
-
"assistant-stream": "^0.2.
|
60
|
+
"assistant-stream": "^0.2.22",
|
61
61
|
"json-schema": "^0.4.0",
|
62
62
|
"nanoid": "5.1.5",
|
63
63
|
"react-textarea-autosize": "^8.5.9",
|
64
|
-
"zod": "^
|
65
|
-
"zustand": "^5.0.
|
66
|
-
"assistant-cloud": "0.0.
|
64
|
+
"zod": "^4.0.14",
|
65
|
+
"zustand": "^5.0.7",
|
66
|
+
"assistant-cloud": "0.0.4"
|
67
67
|
},
|
68
68
|
"peerDependencies": {
|
69
69
|
"@types/react": "*",
|
@@ -83,9 +83,9 @@
|
|
83
83
|
"@stryker-mutator/core": "^9.0.1",
|
84
84
|
"@stryker-mutator/vitest-runner": "^9.0.1",
|
85
85
|
"@types/json-schema": "^7.0.15",
|
86
|
-
"@types/node": "^24.0
|
86
|
+
"@types/node": "^24.1.0",
|
87
87
|
"eslint": "^9",
|
88
|
-
"eslint-config-next": "15.
|
88
|
+
"eslint-config-next": "15.4.5",
|
89
89
|
"tsx": "^4.20.3",
|
90
90
|
"vitest": "^3.2.4",
|
91
91
|
"@assistant-ui/x-buildutils": "0.0.1"
|
package/src/primitives/message/{MessagePartsGroupedByParentId.tsx → MessagePartsGrouped.tsx}
RENAMED
@@ -35,16 +35,18 @@ import { MessagePartPrimitiveInProgress } from "../messagePart/MessagePartInProg
|
|
35
35
|
import { MessagePartStatus } from "../../types/AssistantTypes";
|
36
36
|
|
37
37
|
type MessagePartGroup = {
|
38
|
-
|
38
|
+
groupKey: string | undefined;
|
39
39
|
indices: number[];
|
40
40
|
};
|
41
41
|
|
42
|
+
export type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];
|
43
|
+
|
42
44
|
/**
|
43
45
|
* Groups message parts by their parent ID.
|
44
46
|
* Parts without a parent ID appear in their chronological position as individual groups.
|
45
47
|
* Parts with the same parent ID are grouped together at the position of their first occurrence.
|
46
48
|
*/
|
47
|
-
const groupMessagePartsByParentId = (
|
49
|
+
const groupMessagePartsByParentId: GroupingFunction = (
|
48
50
|
parts: readonly any[],
|
49
51
|
): MessagePartGroup[] => {
|
50
52
|
// Map maintains insertion order, so groups appear in order of first occurrence
|
@@ -68,33 +70,80 @@ const groupMessagePartsByParentId = (
|
|
68
70
|
const groups: MessagePartGroup[] = [];
|
69
71
|
for (const [groupId, indices] of groupMap) {
|
70
72
|
// Extract parentId (undefined for ungrouped parts)
|
71
|
-
const
|
72
|
-
groups.push({
|
73
|
+
const groupKey = groupId.startsWith("__ungrouped_") ? undefined : groupId;
|
74
|
+
groups.push({ groupKey, indices });
|
73
75
|
}
|
74
76
|
|
75
77
|
return groups;
|
76
78
|
};
|
77
79
|
|
78
|
-
const
|
80
|
+
const useMessagePartsGrouped = (
|
81
|
+
groupingFunction: GroupingFunction,
|
82
|
+
): MessagePartGroup[] => {
|
79
83
|
const parts = useMessage((m) => m.content);
|
80
84
|
|
81
85
|
return useMemo(() => {
|
82
86
|
if (parts.length === 0) {
|
83
87
|
return [];
|
84
88
|
}
|
85
|
-
return
|
86
|
-
}, [parts]);
|
89
|
+
return groupingFunction(parts);
|
90
|
+
}, [parts, groupingFunction]);
|
87
91
|
};
|
88
92
|
|
89
|
-
export namespace
|
93
|
+
export namespace MessagePrimitiveUnstable_PartsGrouped {
|
90
94
|
export type Props = {
|
95
|
+
/**
|
96
|
+
* Function that takes an array of message parts and returns an array of groups.
|
97
|
+
* Each group contains a key (for identification) and an array of indices.
|
98
|
+
*
|
99
|
+
* @example
|
100
|
+
* ```tsx
|
101
|
+
* // Group by parent ID (default behavior)
|
102
|
+
* groupingFunction={(parts) => {
|
103
|
+
* const groups = new Map<string, number[]>();
|
104
|
+
* parts.forEach((part, i) => {
|
105
|
+
* const key = part.parentId ?? `__ungrouped_${i}`;
|
106
|
+
* const indices = groups.get(key) ?? [];
|
107
|
+
* indices.push(i);
|
108
|
+
* groups.set(key, indices);
|
109
|
+
* });
|
110
|
+
* return Array.from(groups.entries()).map(([key, indices]) => ({
|
111
|
+
* key: key.startsWith("__ungrouped_") ? undefined : key,
|
112
|
+
* indices
|
113
|
+
* }));
|
114
|
+
* }}
|
115
|
+
* ```
|
116
|
+
*
|
117
|
+
* @example
|
118
|
+
* ```tsx
|
119
|
+
* // Group by tool name
|
120
|
+
* import { groupMessagePartsByToolName } from "@assistant-ui/react";
|
121
|
+
*
|
122
|
+
* <MessagePrimitive.Unstable_PartsGrouped
|
123
|
+
* groupingFunction={groupMessagePartsByToolName}
|
124
|
+
* components={{
|
125
|
+
* Group: ({ key, indices, children }) => {
|
126
|
+
* if (!key) return <>{children}</>;
|
127
|
+
* return (
|
128
|
+
* <div className="tool-group">
|
129
|
+
* <h4>Tool: {key}</h4>
|
130
|
+
* {children}
|
131
|
+
* </div>
|
132
|
+
* );
|
133
|
+
* }
|
134
|
+
* }}
|
135
|
+
* />
|
136
|
+
* ```
|
137
|
+
*/
|
138
|
+
groupingFunction: GroupingFunction;
|
139
|
+
|
91
140
|
/**
|
92
141
|
* Component configuration for rendering different types of message content.
|
93
142
|
*
|
94
143
|
* You can provide custom components for each content type (text, image, file, etc.)
|
95
144
|
* and configure tool rendering behavior. If not provided, default components will be used.
|
96
145
|
*/
|
97
|
-
components
|
146
|
+
components:
|
98
147
|
| {
|
99
148
|
/** Component for rendering empty messages */
|
100
149
|
Empty?: EmptyMessagePartComponent | undefined;
|
@@ -127,28 +176,27 @@ export namespace MessagePrimitiveUnstable_PartsGroupedByParentId {
|
|
127
176
|
| undefined;
|
128
177
|
|
129
178
|
/**
|
130
|
-
* Component for rendering grouped message parts
|
179
|
+
* Component for rendering grouped message parts.
|
131
180
|
*
|
132
181
|
* When provided, this component will automatically wrap message parts that share
|
133
|
-
* the same
|
134
|
-
* or other grouped presentations.
|
182
|
+
* the same group key as determined by the groupingFunction.
|
135
183
|
*
|
136
184
|
* The component receives:
|
137
|
-
* - `
|
185
|
+
* - `groupKey`: The group key (or undefined for ungrouped parts)
|
138
186
|
* - `indices`: Array of indices for the parts in this group
|
139
187
|
* - `children`: The rendered message part components
|
140
188
|
*
|
141
189
|
* @example
|
142
190
|
* ```tsx
|
143
|
-
* // Collapsible
|
144
|
-
* Group: ({
|
145
|
-
* if (!
|
191
|
+
* // Collapsible group
|
192
|
+
* Group: ({ groupKey, indices, children }) => {
|
193
|
+
* if (!groupKey) return <>{children}</>;
|
146
194
|
* return (
|
147
|
-
* <details className="
|
195
|
+
* <details className="message-group">
|
148
196
|
* <summary>
|
149
|
-
* Group {
|
197
|
+
* Group {groupKey} ({indices.length} parts)
|
150
198
|
* </summary>
|
151
|
-
* <div className="
|
199
|
+
* <div className="group-content">
|
152
200
|
* {children}
|
153
201
|
* </div>
|
154
202
|
* </details>
|
@@ -156,31 +204,13 @@ export namespace MessagePrimitiveUnstable_PartsGroupedByParentId {
|
|
156
204
|
* }
|
157
205
|
* ```
|
158
206
|
*
|
159
|
-
* @
|
160
|
-
* ```tsx
|
161
|
-
* // Custom styled parent ID group
|
162
|
-
* Group: ({ parentId, indices, children }) => {
|
163
|
-
* if (!parentId) return <>{children}</>;
|
164
|
-
* return (
|
165
|
-
* <div className="border rounded-lg p-4 my-2">
|
166
|
-
* <div className="text-sm text-gray-600 mb-2">
|
167
|
-
* Related content ({parentId})
|
168
|
-
* </div>
|
169
|
-
* <div className="space-y-2">
|
170
|
-
* {children}
|
171
|
-
* </div>
|
172
|
-
* </div>
|
173
|
-
* );
|
174
|
-
* }
|
175
|
-
* ```
|
176
|
-
*
|
177
|
-
* @param parentId - The parent ID shared by all parts in this group (undefined for ungrouped parts)
|
207
|
+
* @param groupKey - The group key (undefined for ungrouped parts)
|
178
208
|
* @param indices - Array of indices for the parts in this group
|
179
209
|
* @param children - Rendered message part components to display within the group
|
180
210
|
*/
|
181
211
|
Group?: ComponentType<
|
182
212
|
PropsWithChildren<{
|
183
|
-
|
213
|
+
groupKey: string | undefined;
|
184
214
|
indices: number[];
|
185
215
|
}>
|
186
216
|
>;
|
@@ -215,10 +245,10 @@ const defaultComponents = {
|
|
215
245
|
File: () => null,
|
216
246
|
Unstable_Audio: () => null,
|
217
247
|
Group: ({ children }) => children,
|
218
|
-
} satisfies
|
248
|
+
} satisfies MessagePrimitiveUnstable_PartsGrouped.Props["components"];
|
219
249
|
|
220
250
|
type MessagePartComponentProps = {
|
221
|
-
components:
|
251
|
+
components: MessagePrimitiveUnstable_PartsGrouped.Props["components"];
|
222
252
|
};
|
223
253
|
|
224
254
|
const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
@@ -276,7 +306,7 @@ const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
276
306
|
|
277
307
|
type MessagePartProps = {
|
278
308
|
partIndex: number;
|
279
|
-
components:
|
309
|
+
components: MessagePrimitiveUnstable_PartsGrouped.Props["components"];
|
280
310
|
};
|
281
311
|
|
282
312
|
const MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {
|
@@ -344,23 +374,45 @@ const EmptyParts = memo(
|
|
344
374
|
);
|
345
375
|
|
346
376
|
/**
|
347
|
-
* Renders the parts of a message grouped by
|
377
|
+
* Renders the parts of a message grouped by a custom grouping function.
|
348
378
|
*
|
349
|
-
* This component
|
350
|
-
*
|
351
|
-
*
|
379
|
+
* This component allows you to group message parts based on any criteria you define.
|
380
|
+
* The grouping function receives all message parts and returns an array of groups,
|
381
|
+
* where each group has a key and an array of part indices.
|
352
382
|
*
|
353
383
|
* @example
|
354
384
|
* ```tsx
|
355
|
-
*
|
385
|
+
* // Group by parent ID (default behavior)
|
386
|
+
* <MessagePrimitive.Unstable_PartsGrouped
|
356
387
|
* components={{
|
357
388
|
* Text: ({ text }) => <p className="message-text">{text}</p>,
|
358
389
|
* Image: ({ image }) => <img src={image} alt="Message image" />,
|
359
|
-
* Group: ({
|
360
|
-
* if (!
|
390
|
+
* Group: ({ groupKey, indices, children }) => {
|
391
|
+
* if (!groupKey) return <>{children}</>;
|
361
392
|
* return (
|
362
393
|
* <div className="parent-group border rounded p-4">
|
363
|
-
* <h4>
|
394
|
+
* <h4>Parent ID: {groupKey}</h4>
|
395
|
+
* {children}
|
396
|
+
* </div>
|
397
|
+
* );
|
398
|
+
* }
|
399
|
+
* }}
|
400
|
+
* />
|
401
|
+
* ```
|
402
|
+
*
|
403
|
+
* @example
|
404
|
+
* ```tsx
|
405
|
+
* // Group by tool name
|
406
|
+
* import { groupMessagePartsByToolName } from "@assistant-ui/react";
|
407
|
+
*
|
408
|
+
* <MessagePrimitive.Unstable_PartsGrouped
|
409
|
+
* groupingFunction={groupMessagePartsByToolName}
|
410
|
+
* components={{
|
411
|
+
* Group: ({ groupKey, indices, children }) => {
|
412
|
+
* if (!groupKey) return <>{children}</>;
|
413
|
+
* return (
|
414
|
+
* <div className="tool-group">
|
415
|
+
* <h4>Tool: {groupKey}</h4>
|
364
416
|
* {children}
|
365
417
|
* </div>
|
366
418
|
* );
|
@@ -369,11 +421,11 @@ const EmptyParts = memo(
|
|
369
421
|
* />
|
370
422
|
* ```
|
371
423
|
*/
|
372
|
-
export const
|
373
|
-
|
374
|
-
> = ({ components }) => {
|
424
|
+
export const MessagePrimitiveUnstable_PartsGrouped: FC<
|
425
|
+
MessagePrimitiveUnstable_PartsGrouped.Props
|
426
|
+
> = ({ groupingFunction, components }) => {
|
375
427
|
const contentLength = useMessage((s) => s.content.length);
|
376
|
-
const messageGroups =
|
428
|
+
const messageGroups = useMessagePartsGrouped(groupingFunction);
|
377
429
|
|
378
430
|
const partsElements = useMemo(() => {
|
379
431
|
if (contentLength === 0) {
|
@@ -385,8 +437,8 @@ export const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<
|
|
385
437
|
|
386
438
|
return (
|
387
439
|
<GroupComponent
|
388
|
-
key={`group-${groupIndex}-${group.
|
389
|
-
|
440
|
+
key={`group-${groupIndex}-${group.groupKey ?? "ungrouped"}`}
|
441
|
+
groupKey={group.groupKey}
|
390
442
|
indices={group.indices}
|
391
443
|
>
|
392
444
|
{group.indices.map((partIndex) => (
|
@@ -404,5 +456,26 @@ export const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<
|
|
404
456
|
return <>{partsElements}</>;
|
405
457
|
};
|
406
458
|
|
459
|
+
MessagePrimitiveUnstable_PartsGrouped.displayName =
|
460
|
+
"MessagePrimitive.Unstable_PartsGrouped";
|
461
|
+
|
462
|
+
/**
|
463
|
+
* Renders the parts of a message grouped by their parent ID.
|
464
|
+
* This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.
|
465
|
+
*
|
466
|
+
* @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility
|
467
|
+
*/
|
468
|
+
export const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<
|
469
|
+
Omit<MessagePrimitiveUnstable_PartsGrouped.Props, "groupingFunction">
|
470
|
+
> = ({ components, ...props }) => {
|
471
|
+
return (
|
472
|
+
<MessagePrimitiveUnstable_PartsGrouped
|
473
|
+
{...props}
|
474
|
+
components={components}
|
475
|
+
groupingFunction={groupMessagePartsByParentId}
|
476
|
+
/>
|
477
|
+
);
|
478
|
+
};
|
479
|
+
|
407
480
|
MessagePrimitiveUnstable_PartsGroupedByParentId.displayName =
|
408
481
|
"MessagePrimitive.Unstable_PartsGroupedByParentId";
|
@@ -4,4 +4,7 @@ export { MessagePrimitiveParts as Content } from "./MessageParts";
|
|
4
4
|
export { MessagePrimitiveIf as If } from "./MessageIf";
|
5
5
|
export { MessagePrimitiveAttachments as Attachments } from "./MessageAttachments";
|
6
6
|
export { MessagePrimitiveError as Error } from "./MessageError";
|
7
|
-
export {
|
7
|
+
export {
|
8
|
+
MessagePrimitiveUnstable_PartsGrouped as Unstable_PartsGrouped,
|
9
|
+
MessagePrimitiveUnstable_PartsGroupedByParentId as Unstable_PartsGroupedByParentId,
|
10
|
+
} from "./MessagePartsGrouped";
|
@@ -184,7 +184,7 @@ export class ExternalStoreThreadRuntimeCore
|
|
184
184
|
// Common logic for both paths
|
185
185
|
if (messages.length > 0) this.ensureInitialized();
|
186
186
|
|
187
|
-
if (oldStore?.isRunning ?? false !== store.isRunning ?? false) {
|
187
|
+
if ((oldStore?.isRunning ?? false) !== (store.isRunning ?? false)) {
|
188
188
|
if (store.isRunning) {
|
189
189
|
this._notifyEventSubscribers("run-start");
|
190
190
|
} else {
|
@@ -113,7 +113,8 @@ export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
|
|
113
113
|
// auto initialize thread
|
114
114
|
useEffect(() => {
|
115
115
|
return runtime.threads.main.unstable_on("initialize", () => {
|
116
|
-
const threadListItemRuntime = runtime.threads.
|
116
|
+
const threadListItemRuntime = runtime.threads.mainItem;
|
117
|
+
if (threadListItemRuntime.getState().id !== id) return;
|
117
118
|
|
118
119
|
if (threadListItemRuntime.getState().status === "new") {
|
119
120
|
threadListItemRuntime.initialize();
|
@@ -122,6 +123,7 @@ export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
|
|
122
123
|
const dispose = runtime.thread.unstable_on("run-end", () => {
|
123
124
|
dispose();
|
124
125
|
|
126
|
+
if (threadListItemRuntime.getState().id !== id) return;
|
125
127
|
threadListItemRuntime.generateTitle();
|
126
128
|
});
|
127
129
|
}
|
@@ -1,122 +0,0 @@
|
|
1
|
-
import { type ComponentType, type FC, PropsWithChildren } from "react";
|
2
|
-
import type { Unstable_AudioMessagePartComponent, EmptyMessagePartComponent, TextMessagePartComponent, ImageMessagePartComponent, SourceMessagePartComponent, ToolCallMessagePartComponent, ToolCallMessagePartProps, FileMessagePartComponent, ReasoningMessagePartComponent } from "../../types/MessagePartComponentTypes";
|
3
|
-
export declare namespace MessagePrimitiveUnstable_PartsGroupedByParentId {
|
4
|
-
type Props = {
|
5
|
-
/**
|
6
|
-
* Component configuration for rendering different types of message content.
|
7
|
-
*
|
8
|
-
* You can provide custom components for each content type (text, image, file, etc.)
|
9
|
-
* and configure tool rendering behavior. If not provided, default components will be used.
|
10
|
-
*/
|
11
|
-
components?: {
|
12
|
-
/** Component for rendering empty messages */
|
13
|
-
Empty?: EmptyMessagePartComponent | undefined;
|
14
|
-
/** Component for rendering text content */
|
15
|
-
Text?: TextMessagePartComponent | undefined;
|
16
|
-
/** Component for rendering reasoning content (typically hidden) */
|
17
|
-
Reasoning?: ReasoningMessagePartComponent | undefined;
|
18
|
-
/** Component for rendering source content */
|
19
|
-
Source?: SourceMessagePartComponent | undefined;
|
20
|
-
/** Component for rendering image content */
|
21
|
-
Image?: ImageMessagePartComponent | undefined;
|
22
|
-
/** Component for rendering file content */
|
23
|
-
File?: FileMessagePartComponent | undefined;
|
24
|
-
/** Component for rendering audio content (experimental) */
|
25
|
-
Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;
|
26
|
-
/** Configuration for tool call rendering */
|
27
|
-
tools?: {
|
28
|
-
/** Map of tool names to their specific components */
|
29
|
-
by_name?: Record<string, ToolCallMessagePartComponent | undefined> | undefined;
|
30
|
-
/** Fallback component for unregistered tools */
|
31
|
-
Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;
|
32
|
-
} | {
|
33
|
-
/** Override component that handles all tool calls */
|
34
|
-
Override: ComponentType<ToolCallMessagePartProps>;
|
35
|
-
} | undefined;
|
36
|
-
/**
|
37
|
-
* Component for rendering grouped message parts with the same parent ID.
|
38
|
-
*
|
39
|
-
* When provided, this component will automatically wrap message parts that share
|
40
|
-
* the same parent ID, allowing you to create collapsible sections, custom styling,
|
41
|
-
* or other grouped presentations.
|
42
|
-
*
|
43
|
-
* The component receives:
|
44
|
-
* - `parentId`: The parent ID shared by all parts in the group (or undefined for ungrouped parts)
|
45
|
-
* - `indices`: Array of indices for the parts in this group
|
46
|
-
* - `children`: The rendered message part components
|
47
|
-
*
|
48
|
-
* @example
|
49
|
-
* ```tsx
|
50
|
-
* // Collapsible parent ID group
|
51
|
-
* Group: ({ parentId, indices, children }) => {
|
52
|
-
* if (!parentId) return <>{children}</>;
|
53
|
-
* return (
|
54
|
-
* <details className="parent-group">
|
55
|
-
* <summary>
|
56
|
-
* Group {parentId} ({indices.length} parts)
|
57
|
-
* </summary>
|
58
|
-
* <div className="parent-group-content">
|
59
|
-
* {children}
|
60
|
-
* </div>
|
61
|
-
* </details>
|
62
|
-
* );
|
63
|
-
* }
|
64
|
-
* ```
|
65
|
-
*
|
66
|
-
* @example
|
67
|
-
* ```tsx
|
68
|
-
* // Custom styled parent ID group
|
69
|
-
* Group: ({ parentId, indices, children }) => {
|
70
|
-
* if (!parentId) return <>{children}</>;
|
71
|
-
* return (
|
72
|
-
* <div className="border rounded-lg p-4 my-2">
|
73
|
-
* <div className="text-sm text-gray-600 mb-2">
|
74
|
-
* Related content ({parentId})
|
75
|
-
* </div>
|
76
|
-
* <div className="space-y-2">
|
77
|
-
* {children}
|
78
|
-
* </div>
|
79
|
-
* </div>
|
80
|
-
* );
|
81
|
-
* }
|
82
|
-
* ```
|
83
|
-
*
|
84
|
-
* @param parentId - The parent ID shared by all parts in this group (undefined for ungrouped parts)
|
85
|
-
* @param indices - Array of indices for the parts in this group
|
86
|
-
* @param children - Rendered message part components to display within the group
|
87
|
-
*/
|
88
|
-
Group?: ComponentType<PropsWithChildren<{
|
89
|
-
parentId: string | undefined;
|
90
|
-
indices: number[];
|
91
|
-
}>>;
|
92
|
-
} | undefined;
|
93
|
-
};
|
94
|
-
}
|
95
|
-
/**
|
96
|
-
* Renders the parts of a message grouped by their parent ID.
|
97
|
-
*
|
98
|
-
* This component automatically groups message parts that share the same parent ID,
|
99
|
-
* allowing you to create hierarchical or related content presentations. Parts without
|
100
|
-
* a parent ID appear after grouped parts and remain ungrouped.
|
101
|
-
*
|
102
|
-
* @example
|
103
|
-
* ```tsx
|
104
|
-
* <MessagePrimitive.Unstable_PartsGroupedByParentId
|
105
|
-
* components={{
|
106
|
-
* Text: ({ text }) => <p className="message-text">{text}</p>,
|
107
|
-
* Image: ({ image }) => <img src={image} alt="Message image" />,
|
108
|
-
* Group: ({ parentId, indices, children }) => {
|
109
|
-
* if (!parentId) return <>{children}</>;
|
110
|
-
* return (
|
111
|
-
* <div className="parent-group border rounded p-4">
|
112
|
-
* <h4>Related Content</h4>
|
113
|
-
* {children}
|
114
|
-
* </div>
|
115
|
-
* );
|
116
|
-
* }
|
117
|
-
* }}
|
118
|
-
* />
|
119
|
-
* ```
|
120
|
-
*/
|
121
|
-
export declare const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<MessagePrimitiveUnstable_PartsGroupedByParentId.Props>;
|
122
|
-
//# sourceMappingURL=MessagePartsGroupedByParentId.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"MessagePartsGroupedByParentId.d.ts","sourceRoot":"","sources":["../../../src/primitives/message/MessagePartsGroupedByParentId.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EAEP,iBAAiB,EAElB,MAAM,OAAO,CAAC;AAcf,OAAO,KAAK,EACV,kCAAkC,EAClC,yBAAyB,EACzB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,uCAAuC,CAAC;AAwD/C,yBAAiB,+CAA+C,CAAC;IAC/D,KAAY,KAAK,GAAG;QAClB;;;;;WAKG;QACH,UAAU,CAAC,EACP;YACE,6CAA6C;YAC7C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,mEAAmE;YACnE,SAAS,CAAC,EAAE,6BAA6B,GAAG,SAAS,CAAC;YACtD,6CAA6C;YAC7C,MAAM,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;YAChD,4CAA4C;YAC5C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,2DAA2D;YAC3D,cAAc,CAAC,EAAE,kCAAkC,GAAG,SAAS,CAAC;YAChE,4CAA4C;YAC5C,KAAK,CAAC,EACF;gBACE,qDAAqD;gBACrD,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC,GACxD,SAAS,CAAC;gBACd,gDAAgD;gBAChD,QAAQ,CAAC,EAAE,aAAa,CAAC,wBAAwB,CAAC,GAAG,SAAS,CAAC;aAChE,GACD;gBACE,qDAAqD;gBACrD,QAAQ,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;aACnD,GACD,SAAS,CAAC;YAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAmDG;YACH,KAAK,CAAC,EAAE,aAAa,CACnB,iBAAiB,CAAC;gBAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;gBAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;aACnB,CAAC,CACH,CAAC;SACH,GACD,SAAS,CAAC;KACf,CAAC;CACH;AA4JD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,+CAA+C,EAAE,EAAE,CAC9D,+CAA+C,CAAC,KAAK,CAgCtD,CAAC"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/primitives/message/MessagePartsGroupedByParentId.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n PropsWithChildren,\n useMemo,\n} from \"react\";\nimport {\n TextMessagePartProvider,\n useMessagePart,\n useMessagePartRuntime,\n useToolUIs,\n} from \"../../context\";\nimport {\n useMessage,\n useMessageRuntime,\n} from \"../../context/react/MessageContext\";\nimport { MessagePartRuntimeProvider } from \"../../context/providers/MessagePartRuntimeProvider\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\nimport type {\n Unstable_AudioMessagePartComponent,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n} from \"../../types/MessagePartComponentTypes\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport { MessagePartStatus } from \"../../types/AssistantTypes\";\n\ntype MessagePartGroup = {\n parentId: string | undefined;\n indices: number[];\n};\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? `__ungrouped_${i}`;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const parentId = groupId.startsWith(\"__ungrouped_\") ? undefined : groupId;\n groups.push({ parentId, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGroupedByParentId = (): MessagePartGroup[] => {\n const parts = useMessage((m) => m.content);\n\n return useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupMessagePartsByParentId(parts);\n }, [parts]);\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGroupedByParentId {\n export type Props = {\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components?:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /** Component for rendering audio content (experimental) */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped message parts with the same parent ID.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same parent ID, allowing you to create collapsible sections, custom styling,\n * or other grouped presentations.\n *\n * The component receives:\n * - `parentId`: The parent ID shared by all parts in the group (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible parent ID group\n * Group: ({ parentId, indices, children }) => {\n * if (!parentId) return <>{children}</>;\n * return (\n * <details className=\"parent-group\">\n * <summary>\n * Group {parentId} ({indices.length} parts)\n * </summary>\n * <div className=\"parent-group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Custom styled parent ID group\n * Group: ({ parentId, indices, children }) => {\n * if (!parentId) return <>{children}</>;\n * return (\n * <div className=\"border rounded-lg p-4 my-2\">\n * <div className=\"text-sm text-gray-600 mb-2\">\n * Related content ({parentId})\n * </div>\n * <div className=\"space-y-2\">\n * {children}\n * </div>\n * </div>\n * );\n * }\n * ```\n *\n * @param parentId - The parent ID shared by all parts in this group (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n parentId: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useToolUIs((s) => s.getToolUI(props.toolName)) ?? Fallback;\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGroupedByParentId.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGroupedByParentId.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n } = {},\n}) => {\n const MessagePartRuntime = useMessagePartRuntime();\n\n const part = useMessagePart();\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = (result: any) => MessagePartRuntime.addToolResult(result);\n if (\"Override\" in tools)\n return <tools.Override {...part} addResult={addResult} />;\n const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;\n return <ToolUIDisplay {...part} Fallback={Tool} addResult={addResult} />;\n }\n\n if (part.status.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n // eslint-disable-next-line jsx-a11y/alt-text\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n default:\n const unhandledType: never = type;\n throw new Error(`Unknown message part type: ${unhandledType}`);\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGroupedByParentId.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n const messageRuntime = useMessageRuntime();\n const runtime = useMemo(\n () => messageRuntime.getMessagePartByIndex(partIndex),\n [messageRuntime, partIndex],\n );\n\n return (\n <MessagePartRuntimeProvider runtime={runtime}>\n <MessagePartComponent components={components} />\n </MessagePartRuntimeProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.Group === next.components?.Group,\n);\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status =\n useMessage((s) => s.status as MessagePartStatus) ?? COMPLETE_STATUS;\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n *\n * This component automatically groups message parts that share the same parent ID,\n * allowing you to create hierarchical or related content presentations. Parts without\n * a parent ID appear after grouped parts and remain ungrouped.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.Unstable_PartsGroupedByParentId\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ parentId, indices, children }) => {\n * if (!parentId) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Related Content</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n MessagePrimitiveUnstable_PartsGroupedByParentId.Props\n> = ({ components }) => {\n const contentLength = useMessage((s) => s.content.length);\n const messageGroups = useMessagePartsGroupedByParentId();\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n\n return (\n <GroupComponent\n key={`group-${groupIndex}-${group.parentId ?? \"ungrouped\"}`}\n parentId={group.parentId}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partIndex}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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","names":[]}
|