@assistant-ui/react-ag-ui 0.0.64 → 0.0.66

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 (35) hide show
  1. package/dist/runtime/AgUiThreadRuntimeCore.d.ts +19 -3
  2. package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
  3. package/dist/runtime/AgUiThreadRuntimeCore.js +193 -39
  4. package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
  5. package/dist/runtime/adapter/conversions.d.ts.map +1 -1
  6. package/dist/runtime/adapter/conversions.js +19 -29
  7. package/dist/runtime/adapter/conversions.js.map +1 -1
  8. package/dist/runtime/adapter/run-aggregator.d.ts +4 -16
  9. package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
  10. package/dist/runtime/adapter/run-aggregator.js +100 -23
  11. package/dist/runtime/adapter/run-aggregator.js.map +1 -1
  12. package/dist/runtime/event-parser.d.ts.map +1 -1
  13. package/dist/runtime/event-parser.js +16 -8
  14. package/dist/runtime/event-parser.js.map +1 -1
  15. package/dist/runtime/types.d.ts +30 -5
  16. package/dist/runtime/types.d.ts.map +1 -1
  17. package/dist/runtime/types.js +8 -0
  18. package/dist/runtime/types.js.map +1 -0
  19. package/dist/useAgUiRuntime.d.ts.map +1 -1
  20. package/dist/useAgUiRuntime.js +80 -33
  21. package/dist/useAgUiRuntime.js.map +1 -1
  22. package/package.json +7 -6
  23. package/src/runtime/AgUiThreadRuntimeCore.test.ts +380 -6
  24. package/src/runtime/AgUiThreadRuntimeCore.ts +314 -70
  25. package/src/runtime/adapter/conversions.content.test.ts +41 -0
  26. package/src/runtime/adapter/conversions.nested-tool-calls.test.ts +107 -0
  27. package/src/runtime/adapter/conversions.ts +37 -64
  28. package/src/runtime/adapter/run-aggregator.reasoning.test.ts +143 -0
  29. package/src/runtime/adapter/run-aggregator.ts +163 -40
  30. package/src/runtime/event-parser.ts +18 -4
  31. package/src/runtime/types.ts +43 -11
  32. package/src/useAgUiRuntime.external-store.test.tsx +51 -0
  33. package/src/useAgUiRuntime.queue.test.tsx +63 -2
  34. package/src/useAgUiRuntime.thread-switch.test.tsx +587 -3
  35. package/src/useAgUiRuntime.ts +106 -44
@@ -3,11 +3,26 @@ import type { AbstractAgent } from "@ag-ui/client";
3
3
  import type { Logger } from "./logger.js";
4
4
  import type { ReadonlyJSONValue } from "assistant-stream/utils";
5
5
  import type { McpToolCallResult } from "./mcp-tool-result.js";
6
+ export declare const AG_UI_METADATA_NAMESPACE = "agui";
7
+ export declare const MCP_APPS_ACTIVITY_TYPE = "mcp-apps";
8
+ export declare const A2UI_SURFACE_ACTIVITY_TYPE = "a2ui-surface";
9
+ export type AgUiOpaqueReasoning = {
10
+ id: string;
11
+ encryptedValue: string;
12
+ after?: boolean;
13
+ };
14
+ export type AgUiCustomMetadata = {
15
+ /** Wire role restored on export for messages the internal model cannot
16
+ * represent (a developer record rides as a system message). */
17
+ role?: "developer";
18
+ interrupts?: AgUiInterrupt[];
19
+ opaqueReasoning?: AgUiOpaqueReasoning[];
20
+ };
6
21
  /**
7
- * @experimental This API is still under active development and might change without notice.
8
- *
9
22
  * Same as ExternalStoreThreadListAdapter, except `onSwitchToThread` returns
10
23
  * the messages (and optional state) to hydrate the thread with.
24
+ *
25
+ * @deprecated Experimental since 2026-06-13. Not scheduled for removal; the API may change in any release.
11
26
  */
12
27
  type SwitchToThreadResult = {
13
28
  messages: readonly ThreadMessage[];
@@ -16,6 +31,8 @@ type SwitchToThreadResult = {
16
31
  * Set when the thread has a run in flight. The runtime resumes the run
17
32
  * after hydrating, the same way `ThreadHistoryAdapter.load()` does when it
18
33
  * returns `unstable_resume: true`.
34
+ *
35
+ * @deprecated Experimental since 2025-03-31. Not scheduled for removal; the API may change in any release.
19
36
  */
20
37
  unstable_resume?: boolean;
21
38
  };
@@ -29,9 +46,7 @@ export type UseAgUiRuntimeAdapters = {
29
46
  voice?: RealtimeVoiceAdapter;
30
47
  feedback?: FeedbackAdapter;
31
48
  history?: ThreadHistoryAdapter;
32
- /**
33
- * @experimental This API is still under active development and might change without notice.
34
- */
49
+ /** @deprecated Experimental since 2026-01-28. Not scheduled for removal; the API may change in any release. */
35
50
  threadList?: UseAgUiThreadListAdapter;
36
51
  };
37
52
  export type AgUiResumeTranscript = "full" | "appended";
@@ -79,6 +94,8 @@ export type UseAgUiRuntimeOptions = ExternalStoreSharedOptions & {
79
94
  * settles, exposing it on `composer.queue` for `ComposerPrimitive.Queue`.
80
95
  * The runtime owns the queue lifecycle because flushing needs the agent's
81
96
  * send path and the run's own busy and idle edges.
97
+ *
98
+ * @deprecated Experimental since 2026-06-04. Not scheduled for removal; the API may change in any release.
82
99
  */
83
100
  unstable_enableMessageQueue?: boolean | undefined;
84
101
  onError?: (e: Error) => void;
@@ -155,23 +172,29 @@ export type AgUiEvent = {
155
172
  } | {
156
173
  type: "THINKING_START";
157
174
  title?: string;
175
+ timestamp?: number;
158
176
  } | {
159
177
  type: "THINKING_TEXT_MESSAGE_START";
178
+ timestamp?: number;
160
179
  } | {
161
180
  type: "THINKING_TEXT_MESSAGE_CONTENT";
162
181
  delta: string;
163
182
  } | {
164
183
  type: "THINKING_TEXT_MESSAGE_END";
184
+ timestamp?: number;
165
185
  } | {
166
186
  type: "THINKING_END";
187
+ timestamp?: number;
167
188
  } | {
168
189
  type: "REASONING_START";
169
190
  messageId?: string;
170
191
  subagentRunId?: string;
192
+ timestamp?: number;
171
193
  } | {
172
194
  type: "REASONING_MESSAGE_START";
173
195
  messageId?: string;
174
196
  subagentRunId?: string;
197
+ timestamp?: number;
175
198
  } | {
176
199
  type: "REASONING_MESSAGE_CONTENT";
177
200
  messageId?: string;
@@ -181,6 +204,7 @@ export type AgUiEvent = {
181
204
  type: "REASONING_MESSAGE_END";
182
205
  messageId?: string;
183
206
  subagentRunId?: string;
207
+ timestamp?: number;
184
208
  } | {
185
209
  type: "REASONING_ENCRYPTED_VALUE";
186
210
  subtype: "message" | "tool-call";
@@ -191,6 +215,7 @@ export type AgUiEvent = {
191
215
  type: "REASONING_END";
192
216
  messageId?: string;
193
217
  subagentRunId?: string;
218
+ timestamp?: number;
194
219
  } | {
195
220
  type: "TOOL_CALL_START";
196
221
  toolCallId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ //#region src/runtime/types.ts
2
+ const AG_UI_METADATA_NAMESPACE = "agui";
3
+ const MCP_APPS_ACTIVITY_TYPE = "mcp-apps";
4
+ const A2UI_SURFACE_ACTIVITY_TYPE = "a2ui-surface";
5
+ //#endregion
6
+ export { A2UI_SURFACE_ACTIVITY_TYPE, AG_UI_METADATA_NAMESPACE, MCP_APPS_ACTIVITY_TYPE };
7
+
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/runtime/types.ts"],"sourcesContent":["import type {\n CreateAppendMessage,\n AttachmentAdapter,\n DictationAdapter,\n ExternalStoreSharedOptions,\n ExternalStoreThreadListAdapter,\n FeedbackAdapter,\n RealtimeVoiceAdapter,\n SpeechSynthesisAdapter,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { Logger } from \"./logger\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { McpToolCallResult } from \"./mcp-tool-result\";\n\nexport const AG_UI_METADATA_NAMESPACE = \"agui\";\nexport const MCP_APPS_ACTIVITY_TYPE = \"mcp-apps\";\nexport const A2UI_SURFACE_ACTIVITY_TYPE = \"a2ui-surface\";\n\nexport type AgUiOpaqueReasoning = {\n id: string;\n encryptedValue: string;\n after?: boolean;\n};\n\nexport type AgUiCustomMetadata = {\n /** Wire role restored on export for messages the internal model cannot\n * represent (a developer record rides as a system message). */\n role?: \"developer\";\n interrupts?: AgUiInterrupt[];\n opaqueReasoning?: AgUiOpaqueReasoning[];\n};\n\n/**\n * Same as ExternalStoreThreadListAdapter, except `onSwitchToThread` returns\n * the messages (and optional state) to hydrate the thread with.\n *\n * @deprecated Experimental since 2026-06-13. Not scheduled for removal; the API may change in any release.\n */\ntype SwitchToThreadResult = {\n messages: readonly ThreadMessage[];\n state?: ReadonlyJSONValue;\n /**\n * Set when the thread has a run in flight. The runtime resumes the run\n * after hydrating, the same way `ThreadHistoryAdapter.load()` does when it\n * returns `unstable_resume: true`.\n *\n * @deprecated Experimental since 2025-03-31. Not scheduled for removal; the API may change in any release.\n */\n unstable_resume?: boolean;\n};\n\nexport type UseAgUiThreadListAdapter = Omit<\n ExternalStoreThreadListAdapter,\n \"onSwitchToThread\"\n> & {\n onSwitchToThread?:\n | ((\n threadId: string,\n ) => Promise<SwitchToThreadResult> | SwitchToThreadResult)\n | undefined;\n};\n\nexport type UseAgUiRuntimeAdapters = {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n dictation?: DictationAdapter;\n voice?: RealtimeVoiceAdapter;\n feedback?: FeedbackAdapter;\n history?: ThreadHistoryAdapter;\n /** @deprecated Experimental since 2026-01-28. Not scheduled for removal; the API may change in any release. */\n threadList?: UseAgUiThreadListAdapter;\n};\n\nexport type AgUiResumeTranscript = \"full\" | \"appended\";\n\nexport type UseAgUiRuntimeOptions = ExternalStoreSharedOptions & {\n agent: AbstractAgent;\n logger?: Partial<Logger>;\n showThinking?: boolean;\n /**\n * What `messages` carries on a resume run, meaning a `RunAgentInput` that\n * also carries `resume`. The AG-UI interrupt spec leaves this undefined: its\n * contract rules constrain the thread id, interrupt coverage, idempotency,\n * and expiry, and none of them mentions `messages`. Hosts therefore disagree,\n * and both readings are conformant.\n *\n * `\"full\"` sends the whole thread, which is what `@ag-ui/client` itself does.\n * Hosts that resume from a checkpoint ignore the transcript, and hosts that\n * rebuild the interrupted run from it need it.\n *\n * `\"appended\"` sends only what was appended locally after the interrupted\n * assistant message, which is nothing for an approval or a denial and the new\n * user turn for `steerAway`. Choose it for a host that owns the thread and\n * seeds a resume request from its own stored snapshot, because such a host\n * appends the request body to that snapshot and a re-sent transcript\n * duplicates the interrupted turn in its stored history. A host that rebuilds\n * the run from `messages` has nothing to resume from under `\"appended\"`, and\n * a host that derives its outgoing `MESSAGES_SNAPSHOT` from the request body\n * emits a truncated one.\n *\n * Defaults to `\"full\"`.\n */\n resumeTranscript?: AgUiResumeTranscript | undefined;\n /**\n * When the user sends, edits, or reloads a message while client-side tool\n * calls are still pending, automatically cancel the unresolved tool calls\n * with an error result so the agent's tool-call accounting stays\n * consistent. Pending AG-UI interrupts are exempt: they still reject the\n * run and must be answered with `useAgUiSubmitInterruptResponses` or\n * discarded with `useAgUiSteerAway`. When disabled, `useAgUiSteerAway`\n * remains the explicit way to cancel pending tool calls.\n * Defaults to `true`.\n */\n autoCancelPendingToolCalls?: boolean | undefined;\n /**\n * Buffer a message sent while a run is in flight and send it once the run\n * settles, exposing it on `composer.queue` for `ComposerPrimitive.Queue`.\n * The runtime owns the queue lifecycle because flushing needs the agent's\n * send path and the run's own busy and idle edges.\n *\n * @deprecated Experimental since 2026-06-04. Not scheduled for removal; the API may change in any release.\n */\n unstable_enableMessageQueue?: boolean | undefined;\n onError?: (e: Error) => void;\n onCancel?: () => void;\n adapters?: UseAgUiRuntimeAdapters;\n};\n\nexport type AgUiInterruptReason =\n | \"tool_call\"\n | \"input_required\"\n | \"confirmation\"\n | (string & {});\n\nexport type AgUiInterrupt = {\n id: string;\n reason: AgUiInterruptReason;\n message?: string;\n toolCallId?: string;\n responseSchema?: Record<string, unknown>;\n expiresAt?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type AgUiResumeEntry = {\n interruptId: string;\n status: \"resolved\" | \"cancelled\";\n payload?: unknown;\n};\n\nexport type AgUiRuntimeExtras = {\n interrupts: readonly AgUiInterrupt[];\n sendA2uiAction: (action: Record<string, unknown>) => void;\n submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n steerAway: (\n message: CreateAppendMessage,\n responses?: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n state: ReadonlyJSONValue | undefined;\n setState: (\n next:\n | ReadonlyJSONValue\n | ((prev: ReadonlyJSONValue | undefined) => ReadonlyJSONValue),\n ) => void;\n};\n\nexport type AgUiRunFinishedOutcome =\n | { type: \"success\" }\n | { type: \"interrupt\"; interrupts: AgUiInterrupt[] };\n\nexport type AgUiSubagentFinishedOutcome =\n | { type: \"success\" }\n | { type: \"suspended\"; interruptIds?: string[] };\n\nexport type AgUiEvent =\n | { type: \"RUN_STARTED\"; runId: string }\n | {\n type: \"RUN_FINISHED\";\n runId: string;\n outcome?: AgUiRunFinishedOutcome;\n }\n | { type: \"RUN_CANCELLED\"; runId?: string }\n | { type: \"RUN_ERROR\"; message?: string; code?: string }\n | { type: \"TEXT_MESSAGE_START\"; messageId?: string; subagentRunId?: string }\n | {\n type: \"TEXT_MESSAGE_CONTENT\";\n messageId?: string;\n delta: string;\n subagentRunId?: string;\n }\n | { type: \"TEXT_MESSAGE_END\"; messageId?: string; subagentRunId?: string }\n | {\n type: \"TEXT_MESSAGE_CHUNK\";\n messageId?: string;\n delta: string;\n subagentRunId?: string;\n }\n | { type: \"THINKING_START\"; title?: string; timestamp?: number }\n | { type: \"THINKING_TEXT_MESSAGE_START\"; timestamp?: number }\n | { type: \"THINKING_TEXT_MESSAGE_CONTENT\"; delta: string }\n | { type: \"THINKING_TEXT_MESSAGE_END\"; timestamp?: number }\n | { type: \"THINKING_END\"; timestamp?: number }\n | {\n type: \"REASONING_START\";\n messageId?: string;\n subagentRunId?: string;\n timestamp?: number;\n }\n | {\n type: \"REASONING_MESSAGE_START\";\n messageId?: string;\n subagentRunId?: string;\n timestamp?: number;\n }\n | {\n type: \"REASONING_MESSAGE_CONTENT\";\n messageId?: string;\n delta: string;\n subagentRunId?: string;\n }\n | {\n type: \"REASONING_MESSAGE_END\";\n messageId?: string;\n subagentRunId?: string;\n timestamp?: number;\n }\n | {\n type: \"REASONING_ENCRYPTED_VALUE\";\n subtype: \"message\" | \"tool-call\";\n entityId: string;\n encryptedValue: string;\n subagentRunId?: string;\n }\n | {\n type: \"REASONING_END\";\n messageId?: string;\n subagentRunId?: string;\n timestamp?: number;\n }\n | {\n type: \"TOOL_CALL_START\";\n toolCallId: string;\n toolCallName?: string;\n parentMessageId?: string;\n subagentRunId?: string;\n }\n | {\n type: \"TOOL_CALL_ARGS\";\n toolCallId: string;\n delta: string;\n subagentRunId?: string;\n }\n | { type: \"TOOL_CALL_END\"; toolCallId: string; subagentRunId?: string }\n | {\n type: \"TOOL_CALL_CHUNK\";\n toolCallId?: string;\n toolCallName?: string;\n parentMessageId?: string;\n delta?: string;\n subagentRunId?: string;\n }\n | {\n type: \"TOOL_CALL_RESULT\";\n messageId?: string;\n toolCallId: string;\n content: string;\n role?: \"tool\";\n mcpResult?: McpToolCallResult;\n subagentRunId?: string;\n }\n | {\n type: \"ACTIVITY_SNAPSHOT\";\n activityType: string;\n content: Record<string, unknown>;\n messageId?: string;\n replace?: boolean;\n subagentRunId?: string;\n }\n | {\n type: \"ACTIVITY_DELTA\";\n messageId: string;\n activityType: string;\n patch: any[];\n subagentRunId?: string;\n }\n | { type: \"RAW\"; event: any; source?: string }\n | { type: \"CUSTOM\"; name: string; value: any }\n | { type: \"STATE_SNAPSHOT\"; snapshot: any }\n | { type: \"STATE_DELTA\"; delta: any[] }\n | { type: \"MESSAGES_SNAPSHOT\"; messages: any[] }\n | {\n type: \"SUBAGENT_STARTED\";\n subagentRunId: string;\n name: string;\n description?: string;\n parentSubagentRunId?: string;\n parentToolCallId?: string;\n parentMessageId?: string;\n }\n | {\n type: \"SUBAGENT_FINISHED\";\n subagentRunId: string;\n result?: unknown;\n outcome?: AgUiSubagentFinishedOutcome;\n }\n | {\n type: \"SUBAGENT_ERROR\";\n subagentRunId: string;\n message: string;\n code?: string;\n };\n"],"mappings":";AAiBA,MAAa,2BAA2B;AACxC,MAAa,yBAAyB;AACtC,MAAa,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAgUiRuntime.d.ts","sourceRoot":"","sources":["../src/useAgUiRuntime.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACtB,2BAAwB;AASzB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD;;;OAGG;IACH,6BAA6B,EAAE,MAAM,SAAS,aAAa,EAAE,CAAC;IAC9D;;;;OAIG;IACH,iCAAiC,EAAE,CACjC,SAAS,EAAE,SAAS,eAAe,EAAE,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAqStB"}
1
+ {"version":3,"file":"useAgUiRuntime.d.ts","sourceRoot":"","sources":["../src/useAgUiRuntime.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACtB,2BAAwB;AASzB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD;;;OAGG;IACH,6BAA6B,EAAE,MAAM,SAAS,aAAa,EAAE,CAAC;IAC9D;;;;OAIG;IACH,iCAAiC,EAAE,CACjC,SAAS,EAAE,SAAS,eAAe,EAAE,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAoWtB"}
@@ -3,7 +3,7 @@ import { agUiExtras } from "./agUiExtras.js";
3
3
  import { makeLogger } from "./runtime/logger.js";
4
4
  import { AgUiThreadRuntimeCore } from "./runtime/AgUiThreadRuntimeCore.js";
5
5
  import { useExternalStoreRuntime, useExternalStoreSharedOptions, useRuntimeAdapters } from "@assistant-ui/core/react";
6
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
+ import { useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
7
7
  import { useReplaySafeEffect } from "@assistant-ui/store/internal";
8
8
  import { createMessageQueue } from "@assistant-ui/core";
9
9
  //#region src/useAgUiRuntime.ts
@@ -12,10 +12,9 @@ const EMPTY_QUEUE_ITEMS = Object.freeze([]);
12
12
  const subscribeNoop = () => () => {};
13
13
  function useAgUiRuntime(options) {
14
14
  const logger = useMemo(() => makeLogger(options.logger), [options.logger]);
15
- const [_version, setVersion] = useState(0);
16
- const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);
17
15
  const coreRef = useRef(null);
18
16
  const threadSwitchGenerationRef = useRef(0);
17
+ const switchingGenerationRef = useRef(null);
19
18
  const runtimeAdapters = useRuntimeAdapters();
20
19
  const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;
21
20
  const threadListAdapter = options.adapters?.threadList;
@@ -28,9 +27,10 @@ function useAgUiRuntime(options) {
28
27
  ...options.onError && { onError: options.onError },
29
28
  ...options.onCancel && { onCancel: options.onCancel },
30
29
  ...historyAdapter && { history: historyAdapter },
31
- notifyUpdate
30
+ isThreadSwitching: () => switchingGenerationRef.current !== null
32
31
  });
33
32
  const core = coreRef.current;
33
+ const snapshot = useSyncExternalStore(core.subscribe, core.getSnapshot, core.getSnapshot);
34
34
  useEffect(() => {
35
35
  core.updateOptions({
36
36
  agent: options.agent,
@@ -45,12 +45,16 @@ function useAgUiRuntime(options) {
45
45
  });
46
46
  const [toolStatuses, setToolStatuses] = useState({});
47
47
  const hasExecutingTools = Object.values(toolStatuses).some((s) => s?.type === "executing");
48
- const isRunning = core.isRunning() || hasExecutingTools;
48
+ const isRunning = snapshot.isRunning || hasExecutingTools;
49
49
  const queueRef = useRef(null);
50
50
  const busyEdgesRef = useRef(0);
51
51
  const lastQueueEdgeRef = useRef(null);
52
52
  if (options.unstable_enableMessageQueue && !queueRef.current) queueRef.current = createMessageQueue({ run: (message) => {
53
53
  const controller = queueRef.current;
54
+ if (switchingGenerationRef.current !== null) {
55
+ controller?.notifyIdle();
56
+ return;
57
+ }
54
58
  const edgesAtDispatch = busyEdgesRef.current;
55
59
  const releaseIfNoRun = () => {
56
60
  if (queueRef.current !== controller || busyEdgesRef.current !== edgesAtDispatch || core.getPendingInterrupts() !== null) return;
@@ -71,6 +75,10 @@ function useAgUiRuntime(options) {
71
75
  const queueItems = useSyncExternalStore(queueController?.subscribe ?? subscribeNoop, () => queueController?.adapter.items ?? EMPTY_QUEUE_ITEMS, () => EMPTY_QUEUE_ITEMS);
72
76
  const steerQueueItems = useSyncExternalStore(queueController?.subscribe ?? subscribeNoop, () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS, () => EMPTY_QUEUE_ITEMS);
73
77
  const queueBusy = isRunning || core.getPendingInterrupts() !== null;
78
+ useEffect(() => {
79
+ if (options.isSendDisabled === true) queueController?.hold();
80
+ else queueController?.release();
81
+ }, [options.isSendDisabled, queueController]);
74
82
  useEffect(() => {
75
83
  if (!queueController) return;
76
84
  if (lastQueueEdgeRef.current?.controller === queueController && lastQueueEdgeRef.current.busy === queueBusy) return;
@@ -86,31 +94,65 @@ function useAgUiRuntime(options) {
86
94
  const threadList = useMemo(() => {
87
95
  if (!threadListAdapter) return void 0;
88
96
  const { onSwitchToNewThread, onSwitchToThread, ...rest } = threadListAdapter;
97
+ const abandonPreviousThread = () => {
98
+ queueRef.current?.notifyCancelled();
99
+ if (core.isRunning()) core.cancel().catch((error) => {
100
+ logger.error?.("[agui] cancelling the run on thread switch failed", error);
101
+ });
102
+ queueRef.current?.clear();
103
+ };
104
+ const releaseSwitch = (generation) => {
105
+ if (switchingGenerationRef.current === generation) switchingGenerationRef.current = null;
106
+ };
89
107
  return {
90
108
  ...rest,
91
109
  onSwitchToNewThread: onSwitchToNewThread ? async () => {
92
110
  const generation = ++threadSwitchGenerationRef.current;
93
- core.applyExternalMessages([]);
94
- core.resetThreadState();
95
- await onSwitchToNewThread();
96
- if (generation !== threadSwitchGenerationRef.current) return;
97
- core.applyExternalMessages([]);
98
- core.resetThreadState();
111
+ switchingGenerationRef.current = generation;
112
+ try {
113
+ abandonPreviousThread();
114
+ if (generation !== threadSwitchGenerationRef.current) return;
115
+ core.applyExternalMessages([]);
116
+ core.resetThreadState();
117
+ await onSwitchToNewThread();
118
+ if (generation !== threadSwitchGenerationRef.current) return;
119
+ abandonPreviousThread();
120
+ if (generation !== threadSwitchGenerationRef.current) return;
121
+ core.applyExternalMessages([]);
122
+ core.resetThreadState();
123
+ } finally {
124
+ releaseSwitch(generation);
125
+ }
99
126
  } : void 0,
100
127
  onSwitchToThread: onSwitchToThread ? async (threadId) => {
101
128
  const generation = ++threadSwitchGenerationRef.current;
102
- core.applyExternalMessages([]);
103
- core.resetThreadState();
104
- const result = await onSwitchToThread(threadId);
105
- if (generation !== threadSwitchGenerationRef.current) return;
106
- core.applyExternalMessages([]);
107
- core.resetThreadState();
108
- core.applyExternalMessages(result.messages);
109
- if (result.state !== void 0) core.loadExternalState(result.state);
110
- if (result.unstable_resume) core.resumeInFlightRun(result.messages);
129
+ switchingGenerationRef.current = generation;
130
+ try {
131
+ abandonPreviousThread();
132
+ if (generation !== threadSwitchGenerationRef.current) return;
133
+ core.applyExternalMessages([]);
134
+ core.resetThreadState();
135
+ const result = await onSwitchToThread(threadId);
136
+ if (generation !== threadSwitchGenerationRef.current) return;
137
+ abandonPreviousThread();
138
+ if (generation !== threadSwitchGenerationRef.current) return;
139
+ core.applyExternalMessages([]);
140
+ core.resetThreadState();
141
+ core.applyExternalMessages(result.messages);
142
+ if (result.state !== void 0) core.loadExternalState(result.state);
143
+ if (generation !== threadSwitchGenerationRef.current) return;
144
+ releaseSwitch(generation);
145
+ if (result.unstable_resume) core.resumeInFlightRun(result.messages);
146
+ } finally {
147
+ releaseSwitch(generation);
148
+ }
111
149
  } : void 0
112
150
  };
113
- }, [threadListAdapter, core]);
151
+ }, [
152
+ threadListAdapter,
153
+ core,
154
+ logger
155
+ ]);
114
156
  const adapters = options.adapters;
115
157
  const adapterAdapters = useMemo(() => ({
116
158
  attachments: adapters?.attachments ?? runtimeAdapters?.attachments,
@@ -128,22 +170,22 @@ function useAgUiRuntime(options) {
128
170
  const store = useMemo(() => {
129
171
  return {
130
172
  ...shared,
131
- isLoading: core.isLoading,
132
- messageRepository: core.getMessageRepository(),
133
- state: core.getState(),
134
- isRunning: core.isRunning(),
173
+ isLoading: snapshot.isLoading,
174
+ messageRepository: snapshot.messageRepository,
175
+ state: snapshot.state,
176
+ isRunning: snapshot.isRunning,
135
177
  extras: agUiExtras.provide({
136
178
  interrupts: core.getPendingInterrupts()?.interrupts ?? EMPTY_INTERRUPTS,
137
179
  sendA2uiAction: (action) => core.sendA2uiAction(action),
138
180
  submitInterruptResponses: (responses) => core.submitInterruptResponses(responses),
139
181
  steerAway: (message, responses) => core.steerAway(message, responses),
140
- state: core.getState(),
182
+ state: snapshot.state,
141
183
  setState: (next) => core.setState(next)
142
184
  }),
143
185
  unstable_enableToolInvocations: true,
144
186
  unstable_persistsHistory: true,
145
187
  setToolStatuses,
146
- onNew: (message) => core.append(message),
188
+ onNew: (message) => switchingGenerationRef.current !== null ? Promise.resolve() : core.append(message),
147
189
  onVoiceTranscript: (message) => core.appendVoiceTranscript(message),
148
190
  onEdit: (message) => {
149
191
  queueController?.clear();
@@ -173,19 +215,24 @@ function useAgUiRuntime(options) {
173
215
  }, [
174
216
  adapterAdapters,
175
217
  core,
176
- _version,
177
218
  isRunning,
178
219
  queueController,
179
220
  queueItems,
180
221
  steerQueueItems,
181
- shared
222
+ shared,
223
+ snapshot
182
224
  ]);
183
225
  const baseRuntime = useExternalStoreRuntime(store);
184
226
  const createRuntime = () => {
185
- const wrapper = Object.create(baseRuntime);
186
- wrapper.unstable_getPendingInterrupts = () => core.getPendingInterrupts()?.interrupts ?? [];
187
- wrapper.unstable_submitInterruptResponses = (responses) => core.submitInterruptResponses(responses);
188
- return wrapper;
227
+ return {
228
+ threads: baseRuntime.threads,
229
+ get thread() {
230
+ return baseRuntime.thread;
231
+ },
232
+ registerModelContextProvider: (provider) => baseRuntime.registerModelContextProvider(provider),
233
+ unstable_getPendingInterrupts: () => core.getPendingInterrupts()?.interrupts ?? [],
234
+ unstable_submitInterruptResponses: (responses) => core.submitInterruptResponses(responses)
235
+ };
189
236
  };
190
237
  const [pinnedRuntime, setPinnedRuntime] = useState(() => ({
191
238
  baseRuntime,
@@ -1 +1 @@
1
- {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { useReplaySafeEffect } from \"@assistant-ui/store/internal\";\nimport { createMessageQueue } from \"@assistant-ui/core\";\nimport type {\n MessageQueueController,\n ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);\nconst subscribeNoop = () => () => {};\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n /**\n * @deprecated Use the `useAgUiInterrupts()` hook instead. This method is kept\n * for backward compatibility and will be removed in a future major release.\n */\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n /**\n * @deprecated Use the `useAgUiSubmitInterruptResponses()` hook instead. This\n * method is kept for backward compatibility and will be removed in a future\n * major release.\n */\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const threadSwitchGenerationRef = useRef(0);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n resumeTranscript: options.resumeTranscript,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n useEffect(() => {\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n resumeTranscript: options.resumeTranscript,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning = core.isRunning() || hasExecutingTools;\n\n // The driver sends through the agent core rather than the runtime, because\n // the runtime's append routes every tail append back into this queue.\n const queueRef = useRef<MessageQueueController | null>(null);\n // Counts rendered busy edges, whether a run start or an interrupt arriving.\n // A dispatch whose count never moves was never observed as busy, so no\n // falling edge is coming to release the queue.\n const busyEdgesRef = useRef(0);\n const lastQueueEdgeRef = useRef<{\n controller: MessageQueueController;\n busy: boolean;\n } | null>(null);\n if (options.unstable_enableMessageQueue && !queueRef.current) {\n queueRef.current = createMessageQueue({\n run: (message) => {\n const controller = queueRef.current;\n const edgesAtDispatch = busyEdgesRef.current;\n // The queue drops the item before dispatching and stays busy until an\n // idle edge. An append observed as busy is released by that falling\n // edge, and releasing again here would advance the queue twice; one\n // that never runs (a pre-run rejection, or startRun false) has to be\n // released here or every later send buffers forever. An interrupt is\n // rechecked because a run that resolves without yielding to React\n // reaches here before the effect below has seen either edge.\n const releaseIfNoRun = () => {\n if (\n queueRef.current !== controller ||\n busyEdgesRef.current !== edgesAtDispatch ||\n core.getPendingInterrupts() !== null\n )\n return;\n controller?.notifyIdle();\n };\n void core.append(message).then(releaseIfNoRun, (e: unknown) => {\n releaseIfNoRun();\n logger.error?.(\"[agui] queued message failed to send\", e);\n });\n },\n });\n }\n const queueController = options.unstable_enableMessageQueue\n ? queueRef.current\n : null;\n useLayoutEffect(() => {\n if (options.unstable_enableMessageQueue || !queueRef.current) return;\n const controller = queueRef.current;\n queueRef.current = null;\n controller.clear();\n }, [options.unstable_enableMessageQueue]);\n\n // Feeds the store memo below: the runtime core skips an adapter whose\n // identity is unchanged, so queue items have to move the store reference or\n // subscribers never see composer.queue change.\n const queueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.items ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n const steerQueueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n\n // Holds the queue while client-side tools are still executing, and while an\n // interrupt is unanswered: `append` refuses a new run until it is resolved,\n // and the queue drops an item before dispatching it, so draining into that\n // refusal would lose the message instead of keeping it visible.\n const queueBusy = isRunning || core.getPendingInterrupts() !== null;\n useEffect(() => {\n if (!queueController) return;\n if (\n lastQueueEdgeRef.current?.controller === queueController &&\n lastQueueEdgeRef.current.busy === queueBusy\n )\n return;\n lastQueueEdgeRef.current = { controller: queueController, busy: queueBusy };\n if (queueBusy) {\n busyEdgesRef.current++;\n queueController.notifyBusy();\n } else {\n queueController.notifyIdle();\n }\n }, [queueBusy, queueController]);\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread, ...rest } =\n threadListAdapter;\n\n return {\n ...rest,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n const generation = ++threadSwitchGenerationRef.current;\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n core.resetThreadState();\n await onSwitchToNewThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n core.applyExternalMessages([]);\n core.resetThreadState();\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const generation = ++threadSwitchGenerationRef.current;\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n core.resetThreadState();\n const result = await onSwitchToThread(threadId);\n if (generation !== threadSwitchGenerationRef.current) return;\n core.applyExternalMessages([]);\n core.resetThreadState();\n core.applyExternalMessages(result.messages);\n if (result.state !== undefined) {\n core.loadExternalState(result.state);\n }\n if (result.unstable_resume) {\n void core.resumeInFlightRun(result.messages);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(\n () => {\n void _version; // rerender on version change\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messageRepository: core.getMessageRepository(),\n state: core.getState(),\n isRunning: core.isRunning(),\n extras: agUiExtras.provide({\n interrupts:\n core.getPendingInterrupts()?.interrupts ?? EMPTY_INTERRUPTS,\n sendA2uiAction: (action) => core.sendA2uiAction(action),\n submitInterruptResponses: (responses) =>\n core.submitInterruptResponses(responses),\n steerAway: (message, responses) => core.steerAway(message, responses),\n state: core.getState(),\n setState: (next) => core.setState(next),\n }),\n unstable_enableToolInvocations: true,\n unstable_persistsHistory: true,\n setToolStatuses,\n onNew: (message: AppendMessage) => core.append(message),\n onVoiceTranscript: (message) => core.appendVoiceTranscript(message),\n onEdit: (message: AppendMessage) => {\n queueController?.clear();\n return core.edit(message);\n },\n onReload: (parentId: string | null, config: { runConfig?: any }) => {\n queueController?.clear();\n return core.reload(parentId, config);\n },\n onCancel: async () => {\n queueController?.notifyCancelled();\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n unstable_onRecordToolInteraction: (options) =>\n core.recordToolInteraction(options),\n onRespondToToolApproval: (options) =>\n core.respondToToolApproval(options).catch((error: unknown) => {\n core.reportError(error);\n throw error;\n }),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n ...(queueController && { queue: queueController.adapter }),\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [\n adapterAdapters,\n core,\n _version,\n isRunning,\n queueController,\n queueItems,\n steerQueueItems,\n shared,\n ],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const createRuntime = (): AgUiAssistantRuntime => {\n const wrapper = Object.create(baseRuntime) as AgUiAssistantRuntime;\n wrapper.unstable_getPendingInterrupts = () =>\n core.getPendingInterrupts()?.interrupts ?? [];\n wrapper.unstable_submitInterruptResponses = (responses) =>\n core.submitInterruptResponses(responses);\n return wrapper;\n };\n const [pinnedRuntime, setPinnedRuntime] = useState(() => ({\n baseRuntime,\n runtime: createRuntime(),\n }));\n let currentRuntime = pinnedRuntime;\n if (pinnedRuntime.baseRuntime !== baseRuntime) {\n currentRuntime = { baseRuntime, runtime: createRuntime() };\n setPinnedRuntime(currentRuntime);\n }\n const runtime = currentRuntime.runtime;\n\n useReplaySafeEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { useReplaySafeEffect } from \"@assistant-ui/store/internal\";\nimport { createMessageQueue } from \"@assistant-ui/core\";\nimport type {\n MessageQueueController,\n ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);\nconst subscribeNoop = () => () => {};\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n /**\n * @deprecated Use the `useAgUiInterrupts()` hook instead. This method is kept\n * for backward compatibility and will be removed in a future major release.\n */\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n /**\n * @deprecated Use the `useAgUiSubmitInterruptResponses()` hook instead. This\n * method is kept for backward compatibility and will be removed in a future\n * major release.\n */\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const threadSwitchGenerationRef = useRef(0);\n const switchingGenerationRef = useRef<number | null>(null);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n resumeTranscript: options.resumeTranscript,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n isThreadSwitching: () => switchingGenerationRef.current !== null,\n });\n }\n\n const core = coreRef.current;\n const snapshot = useSyncExternalStore(\n core.subscribe,\n core.getSnapshot,\n core.getSnapshot,\n );\n useEffect(() => {\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n resumeTranscript: options.resumeTranscript,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning = snapshot.isRunning || hasExecutingTools;\n\n // The driver sends through the agent core rather than the runtime, because\n // the runtime's append routes every tail append back into this queue.\n const queueRef = useRef<MessageQueueController | null>(null);\n // Counts rendered busy edges, whether a run start or an interrupt arriving.\n // A dispatch whose count never moves was never observed as busy, so no\n // falling edge is coming to release the queue.\n const busyEdgesRef = useRef(0);\n const lastQueueEdgeRef = useRef<{\n controller: MessageQueueController;\n busy: boolean;\n } | null>(null);\n if (options.unstable_enableMessageQueue && !queueRef.current) {\n queueRef.current = createMessageQueue({\n run: (message) => {\n const controller = queueRef.current;\n // A send dispatched mid-switch is dropped, and the queue released, or\n // it would wait for an idle edge that never comes.\n if (switchingGenerationRef.current !== null) {\n controller?.notifyIdle();\n return;\n }\n const edgesAtDispatch = busyEdgesRef.current;\n // The queue drops the item before dispatching and stays busy until an\n // idle edge. An append observed as busy is released by that falling\n // edge, and releasing again here would advance the queue twice; one\n // that never runs (a pre-run rejection, or startRun false) has to be\n // released here or every later send buffers forever. An interrupt is\n // rechecked because a run that resolves without yielding to React\n // reaches here before the effect below has seen either edge.\n const releaseIfNoRun = () => {\n if (\n queueRef.current !== controller ||\n busyEdgesRef.current !== edgesAtDispatch ||\n core.getPendingInterrupts() !== null\n )\n return;\n controller?.notifyIdle();\n };\n void core.append(message).then(releaseIfNoRun, (e: unknown) => {\n releaseIfNoRun();\n logger.error?.(\"[agui] queued message failed to send\", e);\n });\n },\n });\n }\n const queueController = options.unstable_enableMessageQueue\n ? queueRef.current\n : null;\n useLayoutEffect(() => {\n if (options.unstable_enableMessageQueue || !queueRef.current) return;\n const controller = queueRef.current;\n queueRef.current = null;\n controller.clear();\n }, [options.unstable_enableMessageQueue]);\n\n // Feeds the store memo below: the runtime core skips an adapter whose\n // identity is unchanged, so queue items have to move the store reference or\n // subscribers never see composer.queue change.\n const queueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.items ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n const steerQueueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n\n // Holds the queue while client-side tools are still executing, and while an\n // interrupt is unanswered: `append` refuses a new run until it is resolved,\n // and the queue drops an item before dispatching it, so draining into that\n // refusal would lose the message instead of keeping it visible.\n const queueBusy = isRunning || core.getPendingInterrupts() !== null;\n useEffect(() => {\n if (options.isSendDisabled === true) {\n queueController?.hold();\n } else {\n queueController?.release();\n }\n }, [options.isSendDisabled, queueController]);\n\n useEffect(() => {\n if (!queueController) return;\n if (\n lastQueueEdgeRef.current?.controller === queueController &&\n lastQueueEdgeRef.current.busy === queueBusy\n )\n return;\n lastQueueEdgeRef.current = { controller: queueController, busy: queueBusy };\n if (queueBusy) {\n busyEdgesRef.current++;\n queueController.notifyBusy();\n } else {\n queueController.notifyIdle();\n }\n }, [queueBusy, queueController]);\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread, ...rest } =\n threadListAdapter;\n\n const abandonPreviousThread = () => {\n queueRef.current?.notifyCancelled();\n if (core.isRunning()) {\n void core.cancel().catch((error: unknown) => {\n logger.error?.(\n \"[agui] cancelling the run on thread switch failed\",\n error,\n );\n });\n }\n queueRef.current?.clear();\n };\n\n const releaseSwitch = (generation: number) => {\n if (switchingGenerationRef.current === generation) {\n switchingGenerationRef.current = null;\n }\n };\n\n return {\n ...rest,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n const generation = ++threadSwitchGenerationRef.current;\n switchingGenerationRef.current = generation;\n try {\n abandonPreviousThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n core.resetThreadState();\n await onSwitchToNewThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n abandonPreviousThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n core.applyExternalMessages([]);\n core.resetThreadState();\n } finally {\n releaseSwitch(generation);\n }\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const generation = ++threadSwitchGenerationRef.current;\n switchingGenerationRef.current = generation;\n try {\n abandonPreviousThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n core.resetThreadState();\n const result = await onSwitchToThread(threadId);\n if (generation !== threadSwitchGenerationRef.current) return;\n abandonPreviousThread();\n if (generation !== threadSwitchGenerationRef.current) return;\n core.applyExternalMessages([]);\n core.resetThreadState();\n core.applyExternalMessages(result.messages);\n if (result.state !== undefined) {\n core.loadExternalState(result.state);\n }\n if (generation !== threadSwitchGenerationRef.current) return;\n releaseSwitch(generation);\n if (result.unstable_resume) {\n void core.resumeInFlightRun(result.messages);\n }\n } finally {\n releaseSwitch(generation);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core, logger]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(\n () => {\n return {\n ...shared,\n isLoading: snapshot.isLoading,\n messageRepository: snapshot.messageRepository,\n state: snapshot.state,\n isRunning: snapshot.isRunning,\n extras: agUiExtras.provide({\n interrupts:\n core.getPendingInterrupts()?.interrupts ?? EMPTY_INTERRUPTS,\n sendA2uiAction: (action) => core.sendA2uiAction(action),\n submitInterruptResponses: (responses) =>\n core.submitInterruptResponses(responses),\n steerAway: (message, responses) => core.steerAway(message, responses),\n state: snapshot.state,\n setState: (next) => core.setState(next),\n }),\n unstable_enableToolInvocations: true,\n unstable_persistsHistory: true,\n setToolStatuses,\n onNew: (message: AppendMessage) =>\n switchingGenerationRef.current !== null\n ? Promise.resolve()\n : core.append(message),\n onVoiceTranscript: (message) => core.appendVoiceTranscript(message),\n onEdit: (message: AppendMessage) => {\n queueController?.clear();\n return core.edit(message);\n },\n onReload: (parentId: string | null, config: { runConfig?: any }) => {\n queueController?.clear();\n return core.reload(parentId, config);\n },\n onCancel: async () => {\n queueController?.notifyCancelled();\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n unstable_onRecordToolInteraction: (options) =>\n core.recordToolInteraction(options),\n onRespondToToolApproval: (options) =>\n core.respondToToolApproval(options).catch((error: unknown) => {\n core.reportError(error);\n throw error;\n }),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n ...(queueController && { queue: queueController.adapter }),\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [\n adapterAdapters,\n core,\n isRunning,\n queueController,\n queueItems,\n steerQueueItems,\n shared,\n snapshot,\n ],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const createRuntime = (): AgUiAssistantRuntime => {\n return {\n threads: baseRuntime.threads,\n get thread() {\n return baseRuntime.thread;\n },\n registerModelContextProvider: (provider) =>\n baseRuntime.registerModelContextProvider(provider),\n unstable_getPendingInterrupts: () =>\n core.getPendingInterrupts()?.interrupts ?? [],\n unstable_submitInterruptResponses: (responses) =>\n core.submitInterruptResponses(responses),\n };\n };\n const [pinnedRuntime, setPinnedRuntime] = useState(() => ({\n baseRuntime,\n runtime: createRuntime(),\n }));\n let currentRuntime = pinnedRuntime;\n if (pinnedRuntime.baseRuntime !== baseRuntime) {\n currentRuntime = { baseRuntime, runtime: createRuntime() };\n setPinnedRuntime(currentRuntime);\n }\n const runtime = currentRuntime.runtime;\n\n useReplaySafeEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":";;;;;;;;;AAsCA,MAAM,mBAA6C,CAAC;AACpD,MAAM,oBAA+C,OAAO,OAAO,CAAC,CAAC;AACrE,MAAM,4BAA4B,CAAC;AAkBnC,SAAgB,eACd,SACsB;CACtB,MAAM,SAAS,cAAc,WAAW,QAAQ,MAAM,GAAG,CAAC,QAAQ,MAAM,CAAC;CACzE,MAAM,UAAU,OAAqC,IAAI;CACzD,MAAM,4BAA4B,OAAO,CAAC;CAC1C,MAAM,yBAAyB,OAAsB,IAAI;CACzD,MAAM,kBAAkB,mBAAmB;CAE3C,MAAM,iBAAiB,QAAQ,UAAU,WAAW,iBAAiB;CACrE,MAAM,oBAAoB,QAAQ,UAAU;CAE5C,IAAI,CAAC,QAAQ,SACX,QAAQ,UAAU,IAAI,sBAAsB;EAC1C,OAAO,QAAQ;EACf;EACA,cAAc,QAAQ,gBAAgB;EACtC,kBAAkB,QAAQ;EAC1B,4BAA4B,QAAQ;EACpC,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,QAAQ;EAClD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;EACrD,GAAI,kBAAkB,EAAE,SAAS,eAAe;EAChD,yBAAyB,uBAAuB,YAAY;CAC9D,CAAC;CAGH,MAAM,OAAO,QAAQ;CACrB,MAAM,WAAW,qBACf,KAAK,WACL,KAAK,aACL,KAAK,WACP;CACA,gBAAgB;EACd,KAAK,cAAc;GACjB,OAAO,QAAQ;GACf;GACA,cAAc,QAAQ,gBAAgB;GACtC,kBAAkB,QAAQ;GAC1B,4BAA4B,QAAQ;GACpC,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,QAAQ;GAClD,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;GACrD,GAAI,kBAAkB,EAAE,SAAS,eAAe;EAClD,CAAC;CACH,CAAC;CAED,MAAM,CAAC,cAAc,mBAAmB,SAEtC,CAAC,CAAC;CAEJ,MAAM,oBAAoB,OAAO,OAAO,YAAY,CAAC,CAAC,MACnD,MAAM,GAAG,SAAS,WACrB;CACA,MAAM,YAAY,SAAS,aAAa;CAIxC,MAAM,WAAW,OAAsC,IAAI;CAI3D,MAAM,eAAe,OAAO,CAAC;CAC7B,MAAM,mBAAmB,OAGf,IAAI;CACd,IAAI,QAAQ,+BAA+B,CAAC,SAAS,SACnD,SAAS,UAAU,mBAAmB,EACpC,MAAM,YAAY;EAChB,MAAM,aAAa,SAAS;EAG5B,IAAI,uBAAuB,YAAY,MAAM;GAC3C,YAAY,WAAW;GACvB;EACF;EACA,MAAM,kBAAkB,aAAa;EAQrC,MAAM,uBAAuB;GAC3B,IACE,SAAS,YAAY,cACrB,aAAa,YAAY,mBACzB,KAAK,qBAAqB,MAAM,MAEhC;GACF,YAAY,WAAW;EACzB;EACA,KAAU,OAAO,OAAO,CAAC,CAAC,KAAK,iBAAiB,MAAe;GAC7D,eAAe;GACf,OAAO,QAAQ,wCAAwC,CAAC;EAC1D,CAAC;CACH,EACF,CAAC;CAEH,MAAM,kBAAkB,QAAQ,8BAC5B,SAAS,UACT;CACJ,sBAAsB;EACpB,IAAI,QAAQ,+BAA+B,CAAC,SAAS,SAAS;EAC9D,MAAM,aAAa,SAAS;EAC5B,SAAS,UAAU;EACnB,WAAW,MAAM;CACnB,GAAG,CAAC,QAAQ,2BAA2B,CAAC;CAKxC,MAAM,aAAa,qBACjB,iBAAiB,aAAa,qBACxB,iBAAiB,QAAQ,SAAS,yBAClC,iBACR;CACA,MAAM,kBAAkB,qBACtB,iBAAiB,aAAa,qBACxB,iBAAiB,QAAQ,cAAc,yBACvC,iBACR;CAMA,MAAM,YAAY,aAAa,KAAK,qBAAqB,MAAM;CAC/D,gBAAgB;EACd,IAAI,QAAQ,mBAAmB,MAC7B,iBAAiB,KAAK;OAEtB,iBAAiB,QAAQ;CAE7B,GAAG,CAAC,QAAQ,gBAAgB,eAAe,CAAC;CAE5C,gBAAgB;EACd,IAAI,CAAC,iBAAiB;EACtB,IACE,iBAAiB,SAAS,eAAe,mBACzC,iBAAiB,QAAQ,SAAS,WAElC;EACF,iBAAiB,UAAU;GAAE,YAAY;GAAiB,MAAM;EAAU;EAC1E,IAAI,WAAW;GACb,aAAa;GACb,gBAAgB,WAAW;EAC7B,OACE,gBAAgB,WAAW;CAE/B,GAAG,CAAC,WAAW,eAAe,CAAC;CAE/B,MAAM,aAAa,cAAc;EAC/B,IAAI,CAAC,mBAAmB,OAAO,KAAA;EAE/B,MAAM,EAAE,qBAAqB,kBAAkB,GAAG,SAChD;EAEF,MAAM,8BAA8B;GAClC,SAAS,SAAS,gBAAgB;GAClC,IAAI,KAAK,UAAU,GACjB,KAAU,OAAO,CAAC,CAAC,OAAO,UAAmB;IAC3C,OAAO,QACL,qDACA,KACF;GACF,CAAC;GAEH,SAAS,SAAS,MAAM;EAC1B;EAEA,MAAM,iBAAiB,eAAuB;GAC5C,IAAI,uBAAuB,YAAY,YACrC,uBAAuB,UAAU;EAErC;EAEA,OAAO;GACL,GAAG;GACH,qBAAqB,sBACjB,YAAY;IACV,MAAM,aAAa,EAAE,0BAA0B;IAC/C,uBAAuB,UAAU;IACjC,IAAI;KACF,sBAAsB;KACtB,IAAI,eAAe,0BAA0B,SAAS;KAGtD,KAAK,sBAAsB,CAAC,CAAC;KAC7B,KAAK,iBAAiB;KACtB,MAAM,oBAAoB;KAC1B,IAAI,eAAe,0BAA0B,SAAS;KACtD,sBAAsB;KACtB,IAAI,eAAe,0BAA0B,SAAS;KACtD,KAAK,sBAAsB,CAAC,CAAC;KAC7B,KAAK,iBAAiB;IACxB,UAAU;KACR,cAAc,UAAU;IAC1B;GACF,IACA,KAAA;GACJ,kBAAkB,mBACd,OAAO,aAAqB;IAC1B,MAAM,aAAa,EAAE,0BAA0B;IAC/C,uBAAuB,UAAU;IACjC,IAAI;KACF,sBAAsB;KACtB,IAAI,eAAe,0BAA0B,SAAS;KAGtD,KAAK,sBAAsB,CAAC,CAAC;KAC7B,KAAK,iBAAiB;KACtB,MAAM,SAAS,MAAM,iBAAiB,QAAQ;KAC9C,IAAI,eAAe,0BAA0B,SAAS;KACtD,sBAAsB;KACtB,IAAI,eAAe,0BAA0B,SAAS;KACtD,KAAK,sBAAsB,CAAC,CAAC;KAC7B,KAAK,iBAAiB;KACtB,KAAK,sBAAsB,OAAO,QAAQ;KAC1C,IAAI,OAAO,UAAU,KAAA,GACnB,KAAK,kBAAkB,OAAO,KAAK;KAErC,IAAI,eAAe,0BAA0B,SAAS;KACtD,cAAc,UAAU;KACxB,IAAI,OAAO,iBACT,KAAU,kBAAkB,OAAO,QAAQ;IAE/C,UAAU;KACR,cAAc,UAAU;IAC1B;GACF,IACA,KAAA;EACN;CACF,GAAG;EAAC;EAAmB;EAAM;CAAM,CAAC;CAEpC,MAAM,WAAW,QAAQ;CACzB,MAAM,kBAAkB,eACf;EACL,aAAa,UAAU,eAAe,iBAAiB;EACvD,QAAQ,UAAU;EAClB,WAAW,UAAU;EACrB,OAAO,UAAU;EACjB,UAAU,UAAU;EACpB;CACF,IACA;EAAC;EAAU;EAAiB;CAAU,CACxC;CAEA,MAAM,SAAS,8BAA8B,OAAO;CACpD,MAAM,QAAQ,cACN;EACJ,OAAO;GACL,GAAG;GACH,WAAW,SAAS;GACpB,mBAAmB,SAAS;GAC5B,OAAO,SAAS;GAChB,WAAW,SAAS;GACpB,QAAQ,WAAW,QAAQ;IACzB,YACE,KAAK,qBAAqB,CAAC,EAAE,cAAc;IAC7C,iBAAiB,WAAW,KAAK,eAAe,MAAM;IACtD,2BAA2B,cACzB,KAAK,yBAAyB,SAAS;IACzC,YAAY,SAAS,cAAc,KAAK,UAAU,SAAS,SAAS;IACpE,OAAO,SAAS;IAChB,WAAW,SAAS,KAAK,SAAS,IAAI;GACxC,CAAC;GACD,gCAAgC;GAChC,0BAA0B;GAC1B;GACA,QAAQ,YACN,uBAAuB,YAAY,OAC/B,QAAQ,QAAQ,IAChB,KAAK,OAAO,OAAO;GACzB,oBAAoB,YAAY,KAAK,sBAAsB,OAAO;GAClE,SAAS,YAA2B;IAClC,iBAAiB,MAAM;IACvB,OAAO,KAAK,KAAK,OAAO;GAC1B;GACA,WAAW,UAAyB,WAAgC;IAClE,iBAAiB,MAAM;IACvB,OAAO,KAAK,OAAO,UAAU,MAAM;GACrC;GACA,UAAU,YAAY;IACpB,iBAAiB,gBAAgB;IACjC,KAAK,OAAO;GACd;GACA,kBAAkB,YAAY,KAAK,cAAc,OAAO;GACxD,mCAAmC,YACjC,KAAK,sBAAsB,OAAO;GACpC,0BAA0B,YACxB,KAAK,sBAAsB,OAAO,CAAC,CAAC,OAAO,UAAmB;IAC5D,KAAK,YAAY,KAAK;IACtB,MAAM;GACR,CAAC;GACH,WAAW,WAAW,KAAK,OAAO,MAAM;GACxC,cAAc,aACZ,KAAK,sBAAsB,QAAQ;GACrC,WAAW,aACT,KAAK,sBAAsB,QAAQ;GACrC,sBAAsB,UACpB,KAAK,kBAAkB,KAAK;GAC9B,UAAU;GACV,GAAI,mBAAmB,EAAE,OAAO,gBAAgB,QAAQ;EAC1D;CACF,GAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,cAAc,wBAAwB,KAAK;CAEjD,MAAM,sBAA4C;EAChD,OAAO;GACL,SAAS,YAAY;GACrB,IAAI,SAAS;IACX,OAAO,YAAY;GACrB;GACA,+BAA+B,aAC7B,YAAY,6BAA6B,QAAQ;GACnD,qCACE,KAAK,qBAAqB,CAAC,EAAE,cAAc,CAAC;GAC9C,oCAAoC,cAClC,KAAK,yBAAyB,SAAS;EAC3C;CACF;CACA,MAAM,CAAC,eAAe,oBAAoB,gBAAgB;EACxD;EACA,SAAS,cAAc;CACzB,EAAE;CACF,IAAI,iBAAiB;CACrB,IAAI,cAAc,gBAAgB,aAAa;EAC7C,iBAAiB;GAAE;GAAa,SAAS,cAAc;EAAE;EACzD,iBAAiB,cAAc;CACjC;CACA,MAAM,UAAU,eAAe;CAE/B,0BAA0B;EACxB,KAAK,cAAc,OAAO;EAC1B,aAAa;GACX,KAAK,cAAc;EACrB;CACF,GAAG,CAAC,MAAM,OAAO,CAAC;CAElB,gBAAgB;EACd,KAAK,gBAAgB;CACvB,GAAG,CAAC,IAAI,CAAC;CAET,OAAO;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-ag-ui",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
4
4
  "description": "AG-UI protocol adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "ag-ui",
@@ -30,10 +30,10 @@
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
32
  "@ag-ui/client": "^0.0.59",
33
- "@assistant-ui/core": "^0.3.23",
34
- "@assistant-ui/react-generative-ui": "^0.0.23",
35
- "@assistant-ui/store": "^0.3.17",
36
- "assistant-stream": "^0.3.47",
33
+ "@assistant-ui/core": "^0.3.25",
34
+ "@assistant-ui/generative-ui": "^0.0.1",
35
+ "@assistant-ui/store": "^0.3.18",
36
+ "assistant-stream": "^0.3.49",
37
37
  "fast-json-patch": "^3.1.1"
38
38
  },
39
39
  "peerDependencies": {
@@ -51,7 +51,7 @@
51
51
  "@testing-library/dom": "^10.4.2",
52
52
  "@testing-library/react": "^16.3.3",
53
53
  "@types/react": "^19.3.0",
54
- "jsdom": "^30.0.1",
54
+ "jsdom": "^30.1.2",
55
55
  "react": "^19.3.0",
56
56
  "vitest": "^5.0.3",
57
57
  "zod": "^4.6.5"
@@ -72,6 +72,7 @@
72
72
  "scripts": {
73
73
  "build": "aui-build",
74
74
  "test": "vitest run",
75
+ "test:coverage": "vitest run --coverage --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary",
75
76
  "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
76
77
  "test:peer-react18": "vitest run --config vitest.peer-react18.config.ts",
77
78
  "test:types:peer-react18": "aui-react18-types",