@assistant-ui/react-ag-ui 0.0.64 → 0.0.65
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/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +9 -18
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +20 -8
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/event-parser.js +16 -8
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/types.d.ts +8 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/useAgUiRuntime.d.ts.map +1 -1
- package/dist/useAgUiRuntime.js +4 -0
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +5 -4
- package/src/runtime/adapter/conversions.nested-tool-calls.test.ts +107 -0
- package/src/runtime/adapter/conversions.ts +21 -45
- package/src/runtime/adapter/run-aggregator.ts +35 -7
- package/src/runtime/event-parser.ts +18 -4
- package/src/runtime/types.ts +18 -6
- package/src/useAgUiRuntime.queue.test.tsx +63 -2
- package/src/useAgUiRuntime.ts +8 -0
package/src/runtime/types.ts
CHANGED
|
@@ -180,16 +180,22 @@ export type AgUiEvent =
|
|
|
180
180
|
delta: string;
|
|
181
181
|
subagentRunId?: string;
|
|
182
182
|
}
|
|
183
|
-
| { type: "THINKING_START"; title?: string }
|
|
184
|
-
| { type: "THINKING_TEXT_MESSAGE_START" }
|
|
183
|
+
| { type: "THINKING_START"; title?: string; timestamp?: number }
|
|
184
|
+
| { type: "THINKING_TEXT_MESSAGE_START"; timestamp?: number }
|
|
185
185
|
| { type: "THINKING_TEXT_MESSAGE_CONTENT"; delta: string }
|
|
186
|
-
| { type: "THINKING_TEXT_MESSAGE_END" }
|
|
187
|
-
| { type: "THINKING_END" }
|
|
188
|
-
| {
|
|
186
|
+
| { type: "THINKING_TEXT_MESSAGE_END"; timestamp?: number }
|
|
187
|
+
| { type: "THINKING_END"; timestamp?: number }
|
|
188
|
+
| {
|
|
189
|
+
type: "REASONING_START";
|
|
190
|
+
messageId?: string;
|
|
191
|
+
subagentRunId?: string;
|
|
192
|
+
timestamp?: number;
|
|
193
|
+
}
|
|
189
194
|
| {
|
|
190
195
|
type: "REASONING_MESSAGE_START";
|
|
191
196
|
messageId?: string;
|
|
192
197
|
subagentRunId?: string;
|
|
198
|
+
timestamp?: number;
|
|
193
199
|
}
|
|
194
200
|
| {
|
|
195
201
|
type: "REASONING_MESSAGE_CONTENT";
|
|
@@ -201,6 +207,7 @@ export type AgUiEvent =
|
|
|
201
207
|
type: "REASONING_MESSAGE_END";
|
|
202
208
|
messageId?: string;
|
|
203
209
|
subagentRunId?: string;
|
|
210
|
+
timestamp?: number;
|
|
204
211
|
}
|
|
205
212
|
| {
|
|
206
213
|
type: "REASONING_ENCRYPTED_VALUE";
|
|
@@ -209,7 +216,12 @@ export type AgUiEvent =
|
|
|
209
216
|
encryptedValue: string;
|
|
210
217
|
subagentRunId?: string;
|
|
211
218
|
}
|
|
212
|
-
| {
|
|
219
|
+
| {
|
|
220
|
+
type: "REASONING_END";
|
|
221
|
+
messageId?: string;
|
|
222
|
+
subagentRunId?: string;
|
|
223
|
+
timestamp?: number;
|
|
224
|
+
}
|
|
213
225
|
| {
|
|
214
226
|
type: "TOOL_CALL_START";
|
|
215
227
|
toolCallId: string;
|
|
@@ -96,11 +96,67 @@ describe("useAgUiRuntime unstable_enableMessageQueue", () => {
|
|
|
96
96
|
);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
+
it("holds queued sends while sending is disabled", async () => {
|
|
100
|
+
const { agent, runAgent, release } = gatedAgent();
|
|
101
|
+
|
|
102
|
+
const { result, rerender } = renderHook(
|
|
103
|
+
({ isSendDisabled }) =>
|
|
104
|
+
useAgUiRuntime({
|
|
105
|
+
agent,
|
|
106
|
+
unstable_enableMessageQueue: true,
|
|
107
|
+
isSendDisabled,
|
|
108
|
+
}),
|
|
109
|
+
{ initialProps: { isSendDisabled: false } },
|
|
110
|
+
);
|
|
111
|
+
mount(result.current);
|
|
112
|
+
|
|
113
|
+
await act(async () => {
|
|
114
|
+
await result.current.thread.append({
|
|
115
|
+
role: "user",
|
|
116
|
+
content: [{ type: "text", text: "first" }],
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(1));
|
|
120
|
+
|
|
121
|
+
await act(async () => {
|
|
122
|
+
await result.current.thread.append({
|
|
123
|
+
role: "user",
|
|
124
|
+
content: [{ type: "text", text: "second" }],
|
|
125
|
+
parentId: result.current.thread.getState().messages.at(-1)?.id ?? null,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
await waitFor(() =>
|
|
129
|
+
expect(screen.getByTestId("queued").textContent).toBe("second"),
|
|
130
|
+
);
|
|
131
|
+
rerender({ isSendDisabled: true });
|
|
132
|
+
|
|
133
|
+
await act(async () => {
|
|
134
|
+
release();
|
|
135
|
+
});
|
|
136
|
+
await waitFor(() =>
|
|
137
|
+
expect(result.current.thread.getState().isRunning).toBe(false),
|
|
138
|
+
);
|
|
139
|
+
expect(runAgent).toHaveBeenCalledTimes(1);
|
|
140
|
+
expect(screen.getByTestId("queued").textContent).toBe("second");
|
|
141
|
+
|
|
142
|
+
rerender({ isSendDisabled: false });
|
|
143
|
+
await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(2));
|
|
144
|
+
await waitFor(() =>
|
|
145
|
+
expect(screen.getByTestId("queued").textContent).toBe(""),
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
99
149
|
it("preserves queued sends when the active run is cancelled", async () => {
|
|
100
150
|
const { agent, runAgent, release } = gatedAgent();
|
|
101
151
|
|
|
102
|
-
const { result } = renderHook(
|
|
103
|
-
|
|
152
|
+
const { result, rerender } = renderHook(
|
|
153
|
+
({ isSendDisabled }) =>
|
|
154
|
+
useAgUiRuntime({
|
|
155
|
+
agent,
|
|
156
|
+
unstable_enableMessageQueue: true,
|
|
157
|
+
isSendDisabled,
|
|
158
|
+
}),
|
|
159
|
+
{ initialProps: { isSendDisabled: false } },
|
|
104
160
|
);
|
|
105
161
|
mount(result.current);
|
|
106
162
|
|
|
@@ -135,6 +191,11 @@ describe("useAgUiRuntime unstable_enableMessageQueue", () => {
|
|
|
135
191
|
expect(screen.getByTestId("queued").textContent).toBe("second"),
|
|
136
192
|
);
|
|
137
193
|
|
|
194
|
+
rerender({ isSendDisabled: true });
|
|
195
|
+
rerender({ isSendDisabled: false });
|
|
196
|
+
expect(runAgent).toHaveBeenCalledTimes(1);
|
|
197
|
+
expect(screen.getByTestId("queued").textContent).toBe("second");
|
|
198
|
+
|
|
138
199
|
await act(async () => {
|
|
139
200
|
await result.current.thread.append({
|
|
140
201
|
role: "user",
|
package/src/useAgUiRuntime.ts
CHANGED
|
@@ -175,6 +175,14 @@ export function useAgUiRuntime(
|
|
|
175
175
|
// and the queue drops an item before dispatching it, so draining into that
|
|
176
176
|
// refusal would lose the message instead of keeping it visible.
|
|
177
177
|
const queueBusy = isRunning || core.getPendingInterrupts() !== null;
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (options.isSendDisabled === true) {
|
|
180
|
+
queueController?.hold();
|
|
181
|
+
} else {
|
|
182
|
+
queueController?.release();
|
|
183
|
+
}
|
|
184
|
+
}, [options.isSendDisabled, queueController]);
|
|
185
|
+
|
|
178
186
|
useEffect(() => {
|
|
179
187
|
if (!queueController) return;
|
|
180
188
|
if (
|