@assistant-ui/react 0.12.7 → 0.12.9
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/client/ChainOfThoughtClient.d.ts +15 -0
- package/dist/client/ChainOfThoughtClient.d.ts.map +1 -0
- package/dist/client/ChainOfThoughtClient.js +21 -0
- package/dist/client/ChainOfThoughtClient.js.map +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/context/providers/ChainOfThoughtByIndicesProvider.d.ts +6 -0
- package/dist/context/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -0
- package/dist/context/providers/ChainOfThoughtByIndicesProvider.js +21 -0
- package/dist/context/providers/ChainOfThoughtByIndicesProvider.js.map +1 -0
- package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts +5 -0
- package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -0
- package/dist/context/providers/ChainOfThoughtPartByIndexProvider.js +14 -0
- package/dist/context/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +28 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +27 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtParts.d.ts +39 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtParts.js +40 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +28 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts.map +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +25 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -0
- package/dist/primitives/chainOfThought/index.d.ts +4 -0
- package/dist/primitives/chainOfThought/index.d.ts.map +1 -0
- package/dist/primitives/chainOfThought/index.js +4 -0
- package/dist/primitives/chainOfThought/index.js.map +1 -0
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +1 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts +145 -109
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.js +48 -23
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/types/scopes/chainOfThought.d.ts +40 -0
- package/dist/types/scopes/chainOfThought.d.ts.map +1 -0
- package/dist/types/scopes/chainOfThought.js +2 -0
- package/dist/types/scopes/chainOfThought.js.map +1 -0
- package/dist/types/scopes/index.d.ts +1 -0
- package/dist/types/scopes/index.d.ts.map +1 -1
- package/dist/types/scopes/part.d.ts +6 -0
- package/dist/types/scopes/part.d.ts.map +1 -1
- package/dist/types/store-augmentation.d.ts +2 -0
- package/dist/types/store-augmentation.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/client/ChainOfThoughtClient.ts +43 -0
- package/src/client/index.ts +1 -0
- package/src/context/providers/ChainOfThoughtByIndicesProvider.tsx +36 -0
- package/src/context/providers/ChainOfThoughtPartByIndexProvider.tsx +20 -0
- package/src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.tsx +51 -0
- package/src/primitives/chainOfThought/ChainOfThoughtParts.tsx +89 -0
- package/src/primitives/chainOfThought/ChainOfThoughtRoot.tsx +36 -0
- package/src/primitives/chainOfThought/index.ts +14 -0
- package/src/primitives/index.ts +1 -0
- package/src/primitives/message/MessageParts.tsx +214 -142
- package/src/types/scopes/chainOfThought.ts +42 -0
- package/src/types/scopes/index.ts +7 -0
- package/src/types/scopes/part.ts +11 -6
- package/src/types/store-augmentation.ts +2 -0
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
PartByIndexProvider,
|
|
13
13
|
TextMessagePartProvider,
|
|
14
14
|
} from "../../context/providers";
|
|
15
|
+
import { ChainOfThoughtByIndicesProvider } from "../../context/providers/ChainOfThoughtByIndicesProvider";
|
|
15
16
|
import { MessagePartPrimitiveText } from "../messagePart/MessagePartText";
|
|
16
17
|
import { MessagePartPrimitiveImage } from "../messagePart/MessagePartImage";
|
|
17
18
|
import type {
|
|
@@ -33,13 +34,16 @@ import { useShallow } from "zustand/shallow";
|
|
|
33
34
|
type MessagePartRange =
|
|
34
35
|
| { type: "single"; index: number }
|
|
35
36
|
| { type: "toolGroup"; startIndex: number; endIndex: number }
|
|
36
|
-
| { type: "reasoningGroup"; startIndex: number; endIndex: number }
|
|
37
|
+
| { type: "reasoningGroup"; startIndex: number; endIndex: number }
|
|
38
|
+
| { type: "chainOfThoughtGroup"; startIndex: number; endIndex: number };
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
41
|
* Creates a group state manager for a specific part type.
|
|
40
42
|
* Returns functions to start, end, and finalize groups.
|
|
41
43
|
*/
|
|
42
|
-
const createGroupState = <
|
|
44
|
+
const createGroupState = <
|
|
45
|
+
T extends "toolGroup" | "reasoningGroup" | "chainOfThoughtGroup",
|
|
46
|
+
>(
|
|
43
47
|
groupType: T,
|
|
44
48
|
) => {
|
|
45
49
|
let start = -1;
|
|
@@ -75,37 +79,59 @@ const createGroupState = <T extends "toolGroup" | "reasoningGroup">(
|
|
|
75
79
|
/**
|
|
76
80
|
* Groups consecutive tool-call and reasoning message parts into ranges.
|
|
77
81
|
* Always groups tool calls and reasoning parts, even if there's only one.
|
|
82
|
+
* When useChainOfThought is true, groups tool-call and reasoning parts together.
|
|
78
83
|
*/
|
|
79
84
|
const groupMessageParts = (
|
|
80
85
|
messageTypes: readonly string[],
|
|
86
|
+
useChainOfThought: boolean,
|
|
81
87
|
): MessagePartRange[] => {
|
|
82
88
|
const ranges: MessagePartRange[] = [];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
89
|
+
|
|
90
|
+
if (useChainOfThought) {
|
|
91
|
+
const chainOfThoughtGroup = createGroupState("chainOfThoughtGroup");
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < messageTypes.length; i++) {
|
|
94
|
+
const type = messageTypes[i];
|
|
95
|
+
|
|
96
|
+
if (type === "tool-call" || type === "reasoning") {
|
|
97
|
+
chainOfThoughtGroup.startGroup(i);
|
|
98
|
+
} else {
|
|
99
|
+
chainOfThoughtGroup.endGroup(i - 1, ranges);
|
|
100
|
+
ranges.push({ type: "single", index: i });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
chainOfThoughtGroup.finalize(messageTypes.length - 1, ranges);
|
|
105
|
+
} else {
|
|
106
|
+
const toolGroup = createGroupState("toolGroup");
|
|
107
|
+
const reasoningGroup = createGroupState("reasoningGroup");
|
|
108
|
+
|
|
109
|
+
for (let i = 0; i < messageTypes.length; i++) {
|
|
110
|
+
const type = messageTypes[i];
|
|
111
|
+
|
|
112
|
+
if (type === "tool-call") {
|
|
113
|
+
reasoningGroup.endGroup(i - 1, ranges);
|
|
114
|
+
toolGroup.startGroup(i);
|
|
115
|
+
} else if (type === "reasoning") {
|
|
116
|
+
toolGroup.endGroup(i - 1, ranges);
|
|
117
|
+
reasoningGroup.startGroup(i);
|
|
118
|
+
} else {
|
|
119
|
+
toolGroup.endGroup(i - 1, ranges);
|
|
120
|
+
reasoningGroup.endGroup(i - 1, ranges);
|
|
121
|
+
ranges.push({ type: "single", index: i });
|
|
122
|
+
}
|
|
99
123
|
}
|
|
100
|
-
}
|
|
101
124
|
|
|
102
|
-
|
|
103
|
-
|
|
125
|
+
toolGroup.finalize(messageTypes.length - 1, ranges);
|
|
126
|
+
reasoningGroup.finalize(messageTypes.length - 1, ranges);
|
|
127
|
+
}
|
|
104
128
|
|
|
105
129
|
return ranges;
|
|
106
130
|
};
|
|
107
131
|
|
|
108
|
-
const useMessagePartsGroups = (
|
|
132
|
+
const useMessagePartsGroups = (
|
|
133
|
+
useChainOfThought: boolean,
|
|
134
|
+
): MessagePartRange[] => {
|
|
109
135
|
const messageTypes = useAuiState(
|
|
110
136
|
useShallow((s) => s.message.parts.map((c: any) => c.type)),
|
|
111
137
|
);
|
|
@@ -114,134 +140,167 @@ const useMessagePartsGroups = (): MessagePartRange[] => {
|
|
|
114
140
|
if (messageTypes.length === 0) {
|
|
115
141
|
return [];
|
|
116
142
|
}
|
|
117
|
-
return groupMessageParts(messageTypes);
|
|
118
|
-
}, [messageTypes]);
|
|
143
|
+
return groupMessageParts(messageTypes, useChainOfThought);
|
|
144
|
+
}, [messageTypes, useChainOfThought]);
|
|
119
145
|
};
|
|
120
146
|
|
|
121
147
|
export namespace MessagePrimitiveParts {
|
|
148
|
+
type BaseComponents = {
|
|
149
|
+
/** Component for rendering empty messages */
|
|
150
|
+
Empty?: EmptyMessagePartComponent | undefined;
|
|
151
|
+
/** Component for rendering text content */
|
|
152
|
+
Text?: TextMessagePartComponent | undefined;
|
|
153
|
+
/** Component for rendering source content */
|
|
154
|
+
Source?: SourceMessagePartComponent | undefined;
|
|
155
|
+
/** Component for rendering image content */
|
|
156
|
+
Image?: ImageMessagePartComponent | undefined;
|
|
157
|
+
/** Component for rendering file content */
|
|
158
|
+
File?: FileMessagePartComponent | undefined;
|
|
159
|
+
/** Component for rendering audio content (experimental) */
|
|
160
|
+
Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
type ToolsConfig =
|
|
164
|
+
| {
|
|
165
|
+
/** Map of tool names to their specific components */
|
|
166
|
+
by_name?:
|
|
167
|
+
| Record<string, ToolCallMessagePartComponent | undefined>
|
|
168
|
+
| undefined;
|
|
169
|
+
/** Fallback component for unregistered tools */
|
|
170
|
+
Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;
|
|
171
|
+
}
|
|
172
|
+
| {
|
|
173
|
+
/** Override component that handles all tool calls */
|
|
174
|
+
Override: ComponentType<ToolCallMessagePartProps>;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Standard component configuration for rendering reasoning and tool-call parts
|
|
179
|
+
* individually (with optional grouping).
|
|
180
|
+
*
|
|
181
|
+
* Cannot be combined with `ChainOfThought`.
|
|
182
|
+
*/
|
|
183
|
+
type StandardComponents = BaseComponents & {
|
|
184
|
+
/** Component for rendering reasoning content (typically hidden) */
|
|
185
|
+
Reasoning?: ReasoningMessagePartComponent | undefined;
|
|
186
|
+
/** Configuration for tool call rendering */
|
|
187
|
+
tools?: ToolsConfig | undefined;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Component for rendering grouped consecutive tool calls.
|
|
191
|
+
*
|
|
192
|
+
* When provided, this component will automatically wrap consecutive tool-call
|
|
193
|
+
* message parts, allowing you to create collapsible sections, custom styling,
|
|
194
|
+
* or other grouped presentations for multiple tool calls.
|
|
195
|
+
*
|
|
196
|
+
* The component receives:
|
|
197
|
+
* - `startIndex`: The index of the first tool call in the group
|
|
198
|
+
* - `endIndex`: The index of the last tool call in the group
|
|
199
|
+
* - `children`: The rendered tool call components
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```tsx
|
|
203
|
+
* // Collapsible tool group
|
|
204
|
+
* ToolGroup: ({ startIndex, endIndex, children }) => (
|
|
205
|
+
* <details className="tool-group">
|
|
206
|
+
* <summary>
|
|
207
|
+
* {endIndex - startIndex + 1} tool calls
|
|
208
|
+
* </summary>
|
|
209
|
+
* <div className="tool-group-content">
|
|
210
|
+
* {children}
|
|
211
|
+
* </div>
|
|
212
|
+
* </details>
|
|
213
|
+
* )
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @param startIndex - Index of the first tool call in the group
|
|
217
|
+
* @param endIndex - Index of the last tool call in the group
|
|
218
|
+
* @param children - Rendered tool call components to display within the group
|
|
219
|
+
*
|
|
220
|
+
* @deprecated This feature is still experimental and subject to change.
|
|
221
|
+
*/
|
|
222
|
+
ToolGroup?: ComponentType<
|
|
223
|
+
PropsWithChildren<{ startIndex: number; endIndex: number }>
|
|
224
|
+
>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Component for rendering grouped reasoning parts.
|
|
228
|
+
*
|
|
229
|
+
* When provided, this component will automatically wrap reasoning message parts
|
|
230
|
+
* (one or more consecutive) in a group container. Each reasoning part inside
|
|
231
|
+
* renders its own text independently - no text merging occurs.
|
|
232
|
+
*
|
|
233
|
+
* The component receives:
|
|
234
|
+
* - `startIndex`: The index of the first reasoning part in the group
|
|
235
|
+
* - `endIndex`: The index of the last reasoning part in the group
|
|
236
|
+
* - `children`: The rendered Reasoning components (one per part)
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```tsx
|
|
240
|
+
* // Collapsible reasoning group
|
|
241
|
+
* ReasoningGroup: ({ children }) => (
|
|
242
|
+
* <details className="reasoning-group">
|
|
243
|
+
* <summary>Reasoning</summary>
|
|
244
|
+
* <div className="reasoning-content">
|
|
245
|
+
* {children}
|
|
246
|
+
* </div>
|
|
247
|
+
* </details>
|
|
248
|
+
* )
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* @param startIndex - Index of the first reasoning part in the group
|
|
252
|
+
* @param endIndex - Index of the last reasoning part in the group
|
|
253
|
+
* @param children - Rendered reasoning part components
|
|
254
|
+
*/
|
|
255
|
+
ReasoningGroup?: ReasoningGroupComponent;
|
|
256
|
+
|
|
257
|
+
ChainOfThought?: never;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Chain of thought component configuration.
|
|
262
|
+
*
|
|
263
|
+
* When `ChainOfThought` is set, it takes control of rendering ALL reasoning and
|
|
264
|
+
* tool-call parts in the message. The `Reasoning`, `tools`, `ReasoningGroup`, and
|
|
265
|
+
* `ToolGroup` components cannot be used alongside it.
|
|
266
|
+
*
|
|
267
|
+
* The component is automatically wrapped in a ChainOfThoughtByIndicesProvider
|
|
268
|
+
* that sets up the chainOfThought client scope with the correct parts.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```tsx
|
|
272
|
+
* // Chain of thought with accordion
|
|
273
|
+
* ChainOfThought: () => (
|
|
274
|
+
* <ChainOfThoughtPrimitive.Root>
|
|
275
|
+
* <ChainOfThoughtPrimitive.AccordionTrigger>
|
|
276
|
+
* Toggle reasoning
|
|
277
|
+
* </ChainOfThoughtPrimitive.AccordionTrigger>
|
|
278
|
+
* <ChainOfThoughtPrimitive.Parts />
|
|
279
|
+
* </ChainOfThoughtPrimitive.Root>
|
|
280
|
+
* )
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
type ChainOfThoughtComponents = BaseComponents & {
|
|
284
|
+
ChainOfThought: ComponentType;
|
|
285
|
+
|
|
286
|
+
Reasoning?: never;
|
|
287
|
+
tools?: never;
|
|
288
|
+
ToolGroup?: never;
|
|
289
|
+
ReasoningGroup?: never;
|
|
290
|
+
};
|
|
291
|
+
|
|
122
292
|
export type Props = {
|
|
123
293
|
/**
|
|
124
294
|
* Component configuration for rendering different types of message content.
|
|
125
295
|
*
|
|
126
296
|
* You can provide custom components for each content type (text, image, file, etc.)
|
|
127
297
|
* and configure tool rendering behavior. If not provided, default components will be used.
|
|
298
|
+
*
|
|
299
|
+
* Use either `Reasoning`/`tools`/`ToolGroup`/`ReasoningGroup` for standard rendering,
|
|
300
|
+
* or `ChainOfThought` to group all reasoning and tool-call parts into a single
|
|
301
|
+
* collapsible component. These two modes are mutually exclusive.
|
|
128
302
|
*/
|
|
129
|
-
components?:
|
|
130
|
-
| {
|
|
131
|
-
/** Component for rendering empty messages */
|
|
132
|
-
Empty?: EmptyMessagePartComponent | undefined;
|
|
133
|
-
/** Component for rendering text content */
|
|
134
|
-
Text?: TextMessagePartComponent | undefined;
|
|
135
|
-
/** Component for rendering reasoning content (typically hidden) */
|
|
136
|
-
Reasoning?: ReasoningMessagePartComponent | undefined;
|
|
137
|
-
/** Component for rendering source content */
|
|
138
|
-
Source?: SourceMessagePartComponent | undefined;
|
|
139
|
-
/** Component for rendering image content */
|
|
140
|
-
Image?: ImageMessagePartComponent | undefined;
|
|
141
|
-
/** Component for rendering file content */
|
|
142
|
-
File?: FileMessagePartComponent | undefined;
|
|
143
|
-
/** Component for rendering audio content (experimental) */
|
|
144
|
-
Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;
|
|
145
|
-
/** Configuration for tool call rendering */
|
|
146
|
-
tools?:
|
|
147
|
-
| {
|
|
148
|
-
/** Map of tool names to their specific components */
|
|
149
|
-
by_name?:
|
|
150
|
-
| Record<string, ToolCallMessagePartComponent | undefined>
|
|
151
|
-
| undefined;
|
|
152
|
-
/** Fallback component for unregistered tools */
|
|
153
|
-
Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;
|
|
154
|
-
}
|
|
155
|
-
| {
|
|
156
|
-
/** Override component that handles all tool calls */
|
|
157
|
-
Override: ComponentType<ToolCallMessagePartProps>;
|
|
158
|
-
}
|
|
159
|
-
| undefined;
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Component for rendering grouped consecutive tool calls.
|
|
163
|
-
*
|
|
164
|
-
* When provided, this component will automatically wrap consecutive tool-call
|
|
165
|
-
* message parts, allowing you to create collapsible sections, custom styling,
|
|
166
|
-
* or other grouped presentations for multiple tool calls.
|
|
167
|
-
*
|
|
168
|
-
* The component receives:
|
|
169
|
-
* - `startIndex`: The index of the first tool call in the group
|
|
170
|
-
* - `endIndex`: The index of the last tool call in the group
|
|
171
|
-
* - `children`: The rendered tool call components
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```tsx
|
|
175
|
-
* // Collapsible tool group
|
|
176
|
-
* ToolGroup: ({ startIndex, endIndex, children }) => (
|
|
177
|
-
* <details className="tool-group">
|
|
178
|
-
* <summary>
|
|
179
|
-
* {endIndex - startIndex + 1} tool calls
|
|
180
|
-
* </summary>
|
|
181
|
-
* <div className="tool-group-content">
|
|
182
|
-
* {children}
|
|
183
|
-
* </div>
|
|
184
|
-
* </details>
|
|
185
|
-
* )
|
|
186
|
-
* ```
|
|
187
|
-
*
|
|
188
|
-
* @example
|
|
189
|
-
* ```tsx
|
|
190
|
-
* // Custom styled tool group with header
|
|
191
|
-
* ToolGroup: ({ startIndex, endIndex, children }) => (
|
|
192
|
-
* <div className="border rounded-lg p-4 my-2">
|
|
193
|
-
* <div className="text-sm text-gray-600 mb-2">
|
|
194
|
-
* Tool execution #{startIndex + 1}-{endIndex + 1}
|
|
195
|
-
* </div>
|
|
196
|
-
* <div className="space-y-2">
|
|
197
|
-
* {children}
|
|
198
|
-
* </div>
|
|
199
|
-
* </div>
|
|
200
|
-
* )
|
|
201
|
-
* ```
|
|
202
|
-
*
|
|
203
|
-
* @param startIndex - Index of the first tool call in the group
|
|
204
|
-
* @param endIndex - Index of the last tool call in the group
|
|
205
|
-
* @param children - Rendered tool call components to display within the group
|
|
206
|
-
*
|
|
207
|
-
* @deprecated This feature is still experimental and subject to change.
|
|
208
|
-
*/
|
|
209
|
-
ToolGroup?: ComponentType<
|
|
210
|
-
PropsWithChildren<{ startIndex: number; endIndex: number }>
|
|
211
|
-
>;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Component for rendering grouped reasoning parts.
|
|
215
|
-
*
|
|
216
|
-
* When provided, this component will automatically wrap reasoning message parts
|
|
217
|
-
* (one or more consecutive) in a group container. Each reasoning part inside
|
|
218
|
-
* renders its own text independently - no text merging occurs.
|
|
219
|
-
*
|
|
220
|
-
* The component receives:
|
|
221
|
-
* - `startIndex`: The index of the first reasoning part in the group
|
|
222
|
-
* - `endIndex`: The index of the last reasoning part in the group
|
|
223
|
-
* - `children`: The rendered Reasoning components (one per part)
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* ```tsx
|
|
227
|
-
* // Collapsible reasoning group
|
|
228
|
-
* ReasoningGroup: ({ children }) => (
|
|
229
|
-
* <details className="reasoning-group">
|
|
230
|
-
* <summary>Reasoning</summary>
|
|
231
|
-
* <div className="reasoning-content">
|
|
232
|
-
* {children}
|
|
233
|
-
* </div>
|
|
234
|
-
* </details>
|
|
235
|
-
* )
|
|
236
|
-
* ```
|
|
237
|
-
*
|
|
238
|
-
* @param startIndex - Index of the first reasoning part in the group
|
|
239
|
-
* @param endIndex - Index of the last reasoning part in the group
|
|
240
|
-
* @param children - Rendered reasoning part components
|
|
241
|
-
*/
|
|
242
|
-
ReasoningGroup?: ReasoningGroupComponent;
|
|
243
|
-
}
|
|
244
|
-
| undefined;
|
|
303
|
+
components?: StandardComponents | ChainOfThoughtComponents | undefined;
|
|
245
304
|
/**
|
|
246
305
|
* When enabled, shows the Empty component if the last part in the message
|
|
247
306
|
* is anything other than Text or Reasoning.
|
|
@@ -293,7 +352,7 @@ type MessagePartComponentProps = {
|
|
|
293
352
|
components: MessagePrimitiveParts.Props["components"];
|
|
294
353
|
};
|
|
295
354
|
|
|
296
|
-
const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
355
|
+
export const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
297
356
|
components: {
|
|
298
357
|
Text = defaultComponents.Text,
|
|
299
358
|
Reasoning = defaultComponents.Reasoning,
|
|
@@ -493,7 +552,8 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
|
493
552
|
unstable_showEmptyOnNonTextEnd = true,
|
|
494
553
|
}) => {
|
|
495
554
|
const contentLength = useAuiState(({ message }) => message.parts.length);
|
|
496
|
-
const
|
|
555
|
+
const useChainOfThought = !!components?.ChainOfThought;
|
|
556
|
+
const messageRanges = useMessagePartsGroups(useChainOfThought);
|
|
497
557
|
|
|
498
558
|
const partsElements = useMemo(() => {
|
|
499
559
|
if (contentLength === 0) {
|
|
@@ -509,6 +569,18 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
|
509
569
|
components={components}
|
|
510
570
|
/>
|
|
511
571
|
);
|
|
572
|
+
} else if (range.type === "chainOfThoughtGroup") {
|
|
573
|
+
const ChainOfThoughtComponent = components?.ChainOfThought;
|
|
574
|
+
if (!ChainOfThoughtComponent) return null;
|
|
575
|
+
return (
|
|
576
|
+
<ChainOfThoughtByIndicesProvider
|
|
577
|
+
key={`chainOfThought-${range.startIndex}`}
|
|
578
|
+
startIndex={range.startIndex}
|
|
579
|
+
endIndex={range.endIndex}
|
|
580
|
+
>
|
|
581
|
+
<ChainOfThoughtComponent />
|
|
582
|
+
</ChainOfThoughtByIndicesProvider>
|
|
583
|
+
);
|
|
512
584
|
} else if (range.type === "toolGroup") {
|
|
513
585
|
const ToolGroupComponent =
|
|
514
586
|
components?.ToolGroup ?? defaultComponents.ToolGroup;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MessagePartStatus,
|
|
3
|
+
ToolCallMessagePartStatus,
|
|
4
|
+
} from "../AssistantTypes";
|
|
5
|
+
import type { PartMethods, PartState } from "./part";
|
|
6
|
+
|
|
7
|
+
export type ChainOfThoughtPart = Extract<
|
|
8
|
+
PartState,
|
|
9
|
+
{ type: "tool-call" } | { type: "reasoning" }
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
export type ChainOfThoughtState = {
|
|
13
|
+
readonly parts: readonly ChainOfThoughtPart[];
|
|
14
|
+
readonly collapsed: boolean;
|
|
15
|
+
readonly status: MessagePartStatus | ToolCallMessagePartStatus;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type ChainOfThoughtMethods = {
|
|
19
|
+
/**
|
|
20
|
+
* Get the current state of the chain of thought.
|
|
21
|
+
*/
|
|
22
|
+
getState(): ChainOfThoughtState;
|
|
23
|
+
/**
|
|
24
|
+
* Set the collapsed state of the chain of thought accordion.
|
|
25
|
+
*/
|
|
26
|
+
setCollapsed(collapsed: boolean): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the part methods for a specific part within this chain of thought.
|
|
29
|
+
*/
|
|
30
|
+
part(selector: { index: number }): PartMethods;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ChainOfThoughtMeta = {
|
|
34
|
+
source: "message";
|
|
35
|
+
query: { type: "chainOfThought" };
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ChainOfThoughtClientSchema = {
|
|
39
|
+
state: ChainOfThoughtState;
|
|
40
|
+
methods: ChainOfThoughtMethods;
|
|
41
|
+
meta: ChainOfThoughtMeta;
|
|
42
|
+
};
|
|
@@ -60,3 +60,10 @@ export type {
|
|
|
60
60
|
ModelContextMethods,
|
|
61
61
|
ModelContextClientSchema,
|
|
62
62
|
} from "./modelContext";
|
|
63
|
+
export type {
|
|
64
|
+
ChainOfThoughtState,
|
|
65
|
+
ChainOfThoughtMethods,
|
|
66
|
+
ChainOfThoughtMeta,
|
|
67
|
+
ChainOfThoughtClientSchema,
|
|
68
|
+
ChainOfThoughtPart,
|
|
69
|
+
} from "./chainOfThought";
|
package/src/types/scopes/part.ts
CHANGED
|
@@ -30,12 +30,17 @@ export type PartMethods = {
|
|
|
30
30
|
__internal_getRuntime?(): MessagePartRuntime;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export type PartMeta =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
};
|
|
33
|
+
export type PartMeta =
|
|
34
|
+
| {
|
|
35
|
+
source: "message";
|
|
36
|
+
query:
|
|
37
|
+
| { type: "index"; index: number }
|
|
38
|
+
| { type: "toolCallId"; toolCallId: string };
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
source: "chainOfThought";
|
|
42
|
+
query: { type: "index"; index: number };
|
|
43
|
+
};
|
|
39
44
|
|
|
40
45
|
export type PartClientSchema = {
|
|
41
46
|
state: PartState;
|
|
@@ -11,6 +11,7 @@ import type { ToolsClientSchema } from "./scopes/tools";
|
|
|
11
11
|
import type { ModelContextClientSchema } from "./scopes/modelContext";
|
|
12
12
|
import type { SuggestionsClientSchema } from "./scopes/suggestions";
|
|
13
13
|
import type { SuggestionClientSchema } from "./scopes/suggestion";
|
|
14
|
+
import type { ChainOfThoughtClientSchema } from "./scopes/chainOfThought";
|
|
14
15
|
|
|
15
16
|
declare module "@assistant-ui/store" {
|
|
16
17
|
interface ClientRegistry {
|
|
@@ -25,5 +26,6 @@ declare module "@assistant-ui/store" {
|
|
|
25
26
|
modelContext: ModelContextClientSchema;
|
|
26
27
|
suggestions: SuggestionsClientSchema;
|
|
27
28
|
suggestion: SuggestionClientSchema;
|
|
29
|
+
chainOfThought: ChainOfThoughtClientSchema;
|
|
28
30
|
}
|
|
29
31
|
}
|