@assistant-ui/react 0.11.23 → 0.11.25
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/legacy-runtime/hooks/AttachmentContext.d.ts +48 -48
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +65 -58
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.d.ts +35 -3
- package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.js +17 -5
- package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
- package/dist/tests/setup.js +8 -8
- package/dist/tests/setup.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/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +73 -60
- package/src/primitives/thread/ThreadSuggestion.tsx +43 -5
- package/src/types/MessagePartTypes.ts +2 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
import { ReadonlyJSONObject } from "assistant-stream/utils";
|
2
|
+
import type { ThreadMessage } from "./AssistantTypes";
|
2
3
|
export type TextMessagePart = {
|
3
4
|
readonly type: "text";
|
4
5
|
readonly text: string;
|
@@ -49,6 +50,7 @@ export type ToolCallMessagePart<TArgs = ReadonlyJSONObject, TResult = unknown> =
|
|
49
50
|
payload: unknown;
|
50
51
|
};
|
51
52
|
readonly parentId?: string;
|
53
|
+
readonly messages?: readonly ThreadMessage[];
|
52
54
|
};
|
53
55
|
export type ThreadUserMessagePart = TextMessagePart | ImageMessagePart | FileMessagePart | Unstable_AudioMessagePart;
|
54
56
|
export type ThreadAssistantMessagePart = TextMessagePart | ReasoningMessagePart | ToolCallMessagePart | SourceMessagePart | FileMessagePart | ImageMessagePart;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MessagePartTypes.d.ts","sourceRoot":"","sources":["../../src/types/MessagePartTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;
|
1
|
+
{"version":3,"file":"MessagePartTypes.d.ts","sourceRoot":"","sources":["../../src/types/MessagePartTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC7B,KAAK,GAAG,kBAAkB,EAC1B,OAAO,GAAG,OAAO,IACf;IACF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,yBAAyB,CAAC;AAE9B,MAAM,MAAM,0BAA0B,GAClC,eAAe,GACf,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,GACf,gBAAgB,CAAC"}
|
package/package.json
CHANGED
@@ -87,7 +87,10 @@ export function useToolInvocations({
|
|
87
87
|
humanInputRef.current.set(toolCallId, { resolve, reject });
|
88
88
|
setToolStatuses((prev) => ({
|
89
89
|
...prev,
|
90
|
-
[toolCallId]: {
|
90
|
+
[toolCallId]: {
|
91
|
+
type: "interrupt",
|
92
|
+
payload: { type: "human", payload },
|
93
|
+
},
|
91
94
|
}));
|
92
95
|
});
|
93
96
|
},
|
@@ -130,78 +133,86 @@ export function useToolInvocations({
|
|
130
133
|
const isInititialState = useRef(true);
|
131
134
|
|
132
135
|
useEffect(() => {
|
133
|
-
|
134
|
-
state.messages
|
136
|
+
const processMessages = (
|
137
|
+
messages: readonly (typeof state.messages)[number][],
|
138
|
+
) => {
|
139
|
+
messages.forEach((message) => {
|
135
140
|
message.content.forEach((content) => {
|
136
141
|
if (content.type === "tool-call") {
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
142
|
+
if (isInititialState.current) {
|
143
|
+
ignoredToolIds.current.add(content.toolCallId);
|
144
|
+
} else {
|
145
|
+
if (ignoredToolIds.current.has(content.toolCallId)) {
|
146
|
+
return;
|
147
|
+
}
|
148
|
+
let lastState = lastToolStates.current[content.toolCallId];
|
149
|
+
if (!lastState) {
|
150
|
+
const toolCallController = controller.addToolCallPart({
|
151
|
+
toolName: content.toolName,
|
152
|
+
toolCallId: content.toolCallId,
|
153
|
+
});
|
154
|
+
lastState = {
|
155
|
+
argsText: "",
|
156
|
+
hasResult: false,
|
157
|
+
controller: toolCallController,
|
158
|
+
};
|
159
|
+
lastToolStates.current[content.toolCallId] = lastState;
|
160
|
+
}
|
161
|
+
|
162
|
+
if (content.argsText !== lastState.argsText) {
|
163
|
+
if (!content.argsText.startsWith(lastState.argsText)) {
|
164
|
+
throw new Error(
|
165
|
+
`Tool call argsText can only be appended, not updated: ${content.argsText} does not start with ${lastState.argsText}`,
|
166
|
+
);
|
167
|
+
}
|
162
168
|
|
163
|
-
|
164
|
-
|
165
|
-
throw new Error(
|
166
|
-
`Tool call argsText can only be appended, not updated: ${content.argsText} does not start with ${lastState.argsText}`,
|
169
|
+
const argsTextDelta = content.argsText.slice(
|
170
|
+
lastState.argsText.length,
|
167
171
|
);
|
168
|
-
|
172
|
+
lastState.controller.argsText.append(argsTextDelta);
|
169
173
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
lastState.controller.argsText.append(argsTextDelta);
|
174
|
+
if (isArgsTextComplete(content.argsText)) {
|
175
|
+
lastState.controller.argsText.close();
|
176
|
+
}
|
174
177
|
|
175
|
-
|
176
|
-
|
178
|
+
lastToolStates.current[content.toolCallId] = {
|
179
|
+
argsText: content.argsText,
|
180
|
+
hasResult: lastState.hasResult,
|
181
|
+
controller: lastState.controller,
|
182
|
+
};
|
177
183
|
}
|
178
184
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
185
|
+
if (content.result !== undefined && !lastState.hasResult) {
|
186
|
+
lastState.controller.setResponse(
|
187
|
+
new ToolResponse({
|
188
|
+
result: content.result as ReadonlyJSONValue,
|
189
|
+
artifact: content.artifact as ReadonlyJSONValue | undefined,
|
190
|
+
isError: content.isError,
|
191
|
+
}),
|
192
|
+
);
|
193
|
+
lastState.controller.close();
|
194
|
+
|
195
|
+
lastToolStates.current[content.toolCallId] = {
|
196
|
+
hasResult: true,
|
197
|
+
argsText: lastState.argsText,
|
198
|
+
controller: lastState.controller,
|
199
|
+
};
|
200
|
+
}
|
184
201
|
}
|
185
202
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
result: content.result as ReadonlyJSONValue,
|
190
|
-
artifact: content.artifact as ReadonlyJSONValue | undefined,
|
191
|
-
isError: content.isError,
|
192
|
-
}),
|
193
|
-
);
|
194
|
-
lastState.controller.close();
|
195
|
-
|
196
|
-
lastToolStates.current[content.toolCallId] = {
|
197
|
-
hasResult: true,
|
198
|
-
argsText: lastState.argsText,
|
199
|
-
controller: lastState.controller,
|
200
|
-
};
|
203
|
+
// Recursively process nested messages
|
204
|
+
if (content.messages) {
|
205
|
+
processMessages(content.messages);
|
201
206
|
}
|
202
207
|
}
|
203
208
|
});
|
204
209
|
});
|
210
|
+
};
|
211
|
+
|
212
|
+
processMessages(state.messages);
|
213
|
+
|
214
|
+
if (isInititialState.current) {
|
215
|
+
isInititialState.current = false;
|
205
216
|
}
|
206
217
|
}, [state, controller, onResult]);
|
207
218
|
|
@@ -233,7 +244,9 @@ export function useToolInvocations({
|
|
233
244
|
});
|
234
245
|
handlers.resolve(payload);
|
235
246
|
} else {
|
236
|
-
throw new Error(
|
247
|
+
throw new Error(
|
248
|
+
`Tool call ${toolCallId} is not waiting for human input`,
|
249
|
+
);
|
237
250
|
}
|
238
251
|
},
|
239
252
|
};
|
@@ -10,23 +10,61 @@ import { useAssistantState, useAssistantApi } from "../../context";
|
|
10
10
|
|
11
11
|
const useThreadSuggestion = ({
|
12
12
|
prompt,
|
13
|
+
send,
|
14
|
+
clearComposer = true,
|
13
15
|
autoSend,
|
16
|
+
method: _method,
|
14
17
|
}: {
|
18
|
+
/** The suggestion prompt. */
|
15
19
|
prompt: string;
|
16
|
-
|
20
|
+
|
21
|
+
/**
|
22
|
+
* When true, automatically sends the message.
|
23
|
+
* When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`.
|
24
|
+
*/
|
25
|
+
send?: boolean | undefined;
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Whether to clear the composer after sending.
|
29
|
+
* When send is set to false, determines if composer text is replaced with suggestion (true, default),
|
30
|
+
* or if it's appended to the composer text (false).
|
31
|
+
*
|
32
|
+
* @default true
|
33
|
+
*/
|
34
|
+
clearComposer?: boolean | undefined;
|
35
|
+
|
36
|
+
/** @deprecated Use `send` instead. */
|
17
37
|
autoSend?: boolean | undefined;
|
38
|
+
|
39
|
+
/** @deprecated Use `clearComposer` instead. */
|
40
|
+
method?: "replace";
|
18
41
|
}) => {
|
19
42
|
const api = useAssistantApi();
|
20
43
|
const disabled = useAssistantState(({ thread }) => thread.isDisabled);
|
21
44
|
|
45
|
+
// ========== Deprecation Mapping ==========
|
46
|
+
const resolvedSend = send ?? autoSend ?? false;
|
47
|
+
// ==========================================
|
48
|
+
|
22
49
|
const callback = useCallback(() => {
|
23
50
|
const isRunning = api.thread().getState().isRunning;
|
24
|
-
|
51
|
+
|
52
|
+
if (resolvedSend && !isRunning) {
|
25
53
|
api.thread().append(prompt);
|
54
|
+
if (clearComposer) {
|
55
|
+
api.composer().setText("");
|
56
|
+
}
|
26
57
|
} else {
|
27
|
-
|
58
|
+
if (clearComposer) {
|
59
|
+
api.composer().setText(prompt);
|
60
|
+
} else {
|
61
|
+
const currentText = api.composer().getState().text;
|
62
|
+
api
|
63
|
+
.composer()
|
64
|
+
.setText(currentText.trim() ? `${currentText} ${prompt}` : prompt);
|
65
|
+
}
|
28
66
|
}
|
29
|
-
}, [api,
|
67
|
+
}, [api, resolvedSend, clearComposer, prompt]);
|
30
68
|
|
31
69
|
if (disabled) return null;
|
32
70
|
return callback;
|
@@ -40,5 +78,5 @@ export namespace ThreadPrimitiveSuggestion {
|
|
40
78
|
export const ThreadPrimitiveSuggestion = createActionButton(
|
41
79
|
"ThreadPrimitive.Suggestion",
|
42
80
|
useThreadSuggestion,
|
43
|
-
["prompt", "autoSend", "method"],
|
81
|
+
["prompt", "send", "clearComposer", "autoSend", "method"],
|
44
82
|
);
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { ReadonlyJSONObject } from "assistant-stream/utils";
|
2
|
+
import type { ThreadMessage } from "./AssistantTypes";
|
2
3
|
|
3
4
|
export type TextMessagePart = {
|
4
5
|
readonly type: "text";
|
@@ -56,6 +57,7 @@ export type ToolCallMessagePart<
|
|
56
57
|
readonly artifact?: unknown;
|
57
58
|
readonly interrupt?: { type: "human"; payload: unknown };
|
58
59
|
readonly parentId?: string;
|
60
|
+
readonly messages?: readonly ThreadMessage[];
|
59
61
|
};
|
60
62
|
|
61
63
|
export type ThreadUserMessagePart =
|