@assistant-ui/react-ag-ui 0.0.53 → 0.0.54

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.
Files changed (31) hide show
  1. package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
  2. package/dist/runtime/AgUiThreadRuntimeCore.js +14 -4
  3. package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
  4. package/dist/runtime/adapter/conversions.d.ts +6 -0
  5. package/dist/runtime/adapter/conversions.d.ts.map +1 -1
  6. package/dist/runtime/adapter/conversions.js +139 -10
  7. package/dist/runtime/adapter/conversions.js.map +1 -1
  8. package/dist/runtime/adapter/run-aggregator.d.ts +10 -1
  9. package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
  10. package/dist/runtime/adapter/run-aggregator.js +36 -9
  11. package/dist/runtime/adapter/run-aggregator.js.map +1 -1
  12. package/dist/runtime/adapter/subscriber.d.ts +3 -0
  13. package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
  14. package/dist/runtime/adapter/subscriber.js +1 -0
  15. package/dist/runtime/adapter/subscriber.js.map +1 -1
  16. package/dist/runtime/event-parser.js +13 -0
  17. package/dist/runtime/event-parser.js.map +1 -1
  18. package/dist/runtime/types.d.ts +5 -0
  19. package/dist/runtime/types.d.ts.map +1 -1
  20. package/dist/useAgUiRuntime.js +1 -1
  21. package/dist/useAgUiRuntime.js.map +1 -1
  22. package/package.json +4 -4
  23. package/src/runtime/AgUiThreadRuntimeCore.ts +21 -1
  24. package/src/runtime/adapter/conversions.content.test.ts +220 -0
  25. package/src/runtime/adapter/conversions.ts +215 -11
  26. package/src/runtime/adapter/run-aggregator.ts +59 -4
  27. package/src/runtime/adapter/subscriber.ts +3 -0
  28. package/src/runtime/event-parser.ts +13 -0
  29. package/src/runtime/types.ts +6 -0
  30. package/src/useAgUiRuntime.queue.test.tsx +68 -1
  31. package/src/useAgUiRuntime.ts +1 -1
@@ -22,6 +22,7 @@ type Subscriber = {
22
22
  onReasoningMessageStartEvent?: (payload: { event: unknown }) => void;
23
23
  onReasoningMessageContentEvent?: (payload: { event: unknown }) => void;
24
24
  onReasoningMessageEndEvent?: (payload: { event: unknown }) => void;
25
+ onReasoningEncryptedValueEvent?: (payload: { event: unknown }) => void;
25
26
  onToolCallStartEvent?: (payload: { event: unknown }) => void;
26
27
  onToolCallArgsEvent?: (payload: { event: unknown }) => void;
27
28
  onToolCallEndEvent?: (payload: { event: unknown }) => void;
@@ -124,6 +125,8 @@ export const createAgUiSubscriber = (
124
125
  dispatchIfValid(event, "REASONING_MESSAGE_CONTENT"),
125
126
  onReasoningMessageEndEvent: ({ event }) =>
126
127
  dispatchIfValid(event, "REASONING_MESSAGE_END"),
128
+ onReasoningEncryptedValueEvent: ({ event }) =>
129
+ dispatchIfValid(event, "REASONING_ENCRYPTED_VALUE"),
127
130
  onToolCallStartEvent: ({ event }) =>
128
131
  dispatchIfValid(event, "TOOL_CALL_START"),
129
132
  onToolCallArgsEvent: ({ event }) =>
@@ -171,6 +171,19 @@ export const parseAgUiEvent = (
171
171
  { type: "REASONING_MESSAGE_END" as const },
172
172
  { messageId: getString("messageId") },
173
173
  );
174
+ case "REASONING_ENCRYPTED_VALUE": {
175
+ const entityId = getString("entityId");
176
+ const encryptedValue = getString("encryptedValue");
177
+ const subtype = getString("subtype");
178
+ if (!entityId || !encryptedValue) return null;
179
+ if (subtype !== "message" && subtype !== "tool-call") return null;
180
+ return {
181
+ type: "REASONING_ENCRYPTED_VALUE" as const,
182
+ subtype,
183
+ entityId,
184
+ encryptedValue,
185
+ };
186
+ }
174
187
  case "REASONING_END":
175
188
  return withOptional(
176
189
  { type: "REASONING_END" as const },
@@ -149,6 +149,12 @@ export type AgUiEvent =
149
149
  | { type: "REASONING_MESSAGE_START"; messageId?: string }
150
150
  | { type: "REASONING_MESSAGE_CONTENT"; messageId?: string; delta: string }
151
151
  | { type: "REASONING_MESSAGE_END"; messageId?: string }
152
+ | {
153
+ type: "REASONING_ENCRYPTED_VALUE";
154
+ subtype: "message" | "tool-call";
155
+ entityId: string;
156
+ encryptedValue: string;
157
+ }
152
158
  | { type: "REASONING_END"; messageId?: string }
153
159
  | {
154
160
  type: "TOOL_CALL_START";
@@ -27,7 +27,7 @@ const gatedAgent = () => {
27
27
  },
28
28
  );
29
29
  return {
30
- agent: { runAgent } as unknown as HttpAgent,
30
+ agent: { runAgent, abortRun: vi.fn() } as unknown as HttpAgent,
31
31
  runAgent,
32
32
  release: () => release(),
33
33
  };
@@ -95,6 +95,73 @@ describe("useAgUiRuntime unstable_enableMessageQueue", () => {
95
95
  );
96
96
  });
97
97
 
98
+ it("preserves queued sends when the active run is cancelled", async () => {
99
+ const { agent, runAgent, release } = gatedAgent();
100
+
101
+ const { result } = renderHook(() =>
102
+ useAgUiRuntime({ agent, unstable_enableMessageQueue: true }),
103
+ );
104
+ mount(result.current);
105
+
106
+ await act(async () => {
107
+ await result.current.thread.append({
108
+ role: "user",
109
+ content: [{ type: "text", text: "first" }],
110
+ });
111
+ });
112
+ await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(1));
113
+
114
+ await act(async () => {
115
+ await result.current.thread.append({
116
+ role: "user",
117
+ content: [{ type: "text", text: "second" }],
118
+ parentId: result.current.thread.getState().messages.at(-1)?.id ?? null,
119
+ });
120
+ });
121
+ await waitFor(() =>
122
+ expect(screen.getByTestId("queued").textContent).toBe("second"),
123
+ );
124
+
125
+ act(() => {
126
+ result.current.thread.cancelRun();
127
+ });
128
+ await act(async () => {
129
+ release();
130
+ });
131
+
132
+ expect(runAgent).toHaveBeenCalledTimes(1);
133
+ await waitFor(() =>
134
+ expect(screen.getByTestId("queued").textContent).toBe("second"),
135
+ );
136
+
137
+ await act(async () => {
138
+ await result.current.thread.append({
139
+ role: "user",
140
+ content: [{ type: "text", text: "third" }],
141
+ parentId: result.current.thread.getState().messages.at(-1)?.id ?? null,
142
+ });
143
+ });
144
+
145
+ await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(3));
146
+ expect(runAgent.mock.calls[1]?.[0]).toEqual(
147
+ expect.objectContaining({
148
+ messages: expect.arrayContaining([
149
+ expect.objectContaining({ role: "user", content: "second" }),
150
+ ]),
151
+ }),
152
+ );
153
+ expect(runAgent.mock.calls[2]?.[0]).toEqual(
154
+ expect.objectContaining({
155
+ messages: expect.arrayContaining([
156
+ expect.objectContaining({ role: "user", content: "third" }),
157
+ ]),
158
+ }),
159
+ );
160
+ await waitFor(() =>
161
+ expect(screen.getByTestId("queued").textContent).toBe(""),
162
+ );
163
+ });
164
+
98
165
  it("keeps accepting sends after a queued run fails", async () => {
99
166
  const runAgent = vi.fn(
100
167
  async (_input: unknown, subscriber: { onRunFinalized?: () => void }) => {
@@ -251,7 +251,7 @@ export function useAgUiRuntime(
251
251
  return core.reload(parentId, config);
252
252
  },
253
253
  onCancel: async () => {
254
- queueController?.clear();
254
+ queueController?.notifyCancelled();
255
255
  core.cancel();
256
256
  },
257
257
  onAddToolResult: (options) => core.addToolResult(options),