@assistant-ui/react-ag-ui 0.0.48 → 0.0.49
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/agUiExtras.d.ts +1 -1
- package/dist/agUiExtras.d.ts.map +1 -1
- package/dist/agUiExtras.js +1 -1
- package/dist/agUiExtras.js.map +1 -1
- package/dist/hooks.d.ts +6 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +10 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts +3 -0
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js +78 -16
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +63 -1
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/run-aggregator.d.ts +6 -1
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +57 -1
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/event-parser.js +5 -2
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/mcp-tool-result.d.ts.map +1 -1
- package/dist/runtime/mcp-tool-result.js +6 -3
- package/dist/runtime/mcp-tool-result.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/useAgUiRuntime.js +2 -1
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +5 -4
- package/src/agUiExtras.ts +1 -1
- package/src/hooks.ts +14 -0
- package/src/index.ts +1 -0
- package/src/runtime/AgUiThreadRuntimeCore.ts +132 -16
- package/src/runtime/adapter/conversions.ts +107 -1
- package/src/runtime/adapter/run-aggregator.ts +82 -0
- package/src/runtime/event-parser.ts +12 -5
- package/src/runtime/mcp-tool-result.ts +8 -6
- package/src/runtime/types.ts +3 -0
- package/src/useAgUiRuntime.ts +1 -0
package/dist/agUiExtras.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AgUiRuntimeExtras } from "./runtime/types.js";
|
|
2
2
|
//#region src/agUiExtras.d.ts
|
|
3
|
-
declare const agUiExtras: import("@assistant-ui/core/
|
|
3
|
+
declare const agUiExtras: import("@assistant-ui/core/react").RuntimeExtras<AgUiRuntimeExtras>;
|
|
4
4
|
//#endregion
|
|
5
5
|
export { agUiExtras };
|
|
6
6
|
//# sourceMappingURL=agUiExtras.d.ts.map
|
package/dist/agUiExtras.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agUiExtras.d.ts","names":[],"sources":["../src/agUiExtras.ts"],"mappings":";;cAGa,
|
|
1
|
+
{"version":3,"file":"agUiExtras.d.ts","names":[],"sources":["../src/agUiExtras.ts"],"mappings":";;cAGa,+CAAU,cAAA"}
|
package/dist/agUiExtras.js
CHANGED
package/dist/agUiExtras.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agUiExtras.js","names":[],"sources":["../src/agUiExtras.ts"],"sourcesContent":["import { createRuntimeExtras } from \"@assistant-ui/core/
|
|
1
|
+
{"version":3,"file":"agUiExtras.js","names":[],"sources":["../src/agUiExtras.ts"],"sourcesContent":["import { createRuntimeExtras } from \"@assistant-ui/core/react\";\nimport type { AgUiRuntimeExtras } from \"./runtime/types\";\n\nexport const agUiExtras =\n createRuntimeExtras<AgUiRuntimeExtras>(\"useAgUiRuntime\");\n"],"mappings":";;AAGA,MAAa,aACX,oBAAuC,gBAAgB"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -7,6 +7,11 @@ import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
|
7
7
|
* array when no interrupts are pending, so consumers can `.map` without a guard.
|
|
8
8
|
*/
|
|
9
9
|
declare const useAgUiInterrupts: () => readonly AgUiInterrupt[];
|
|
10
|
+
/**
|
|
11
|
+
* Returns a stable function that sends an A2UI action back to the agent and
|
|
12
|
+
* resumes the run.
|
|
13
|
+
*/
|
|
14
|
+
declare const useAgUiSendA2uiAction: () => (action: Record<string, unknown>) => void;
|
|
10
15
|
/**
|
|
11
16
|
* Returns a function that submits responses (each `resolved` or `cancelled`)
|
|
12
17
|
* for the pending AG-UI interrupts and resumes the run.
|
|
@@ -29,5 +34,5 @@ declare const useAgUiSteerAway: () => (message: CreateAppendMessage, responses?:
|
|
|
29
34
|
declare const useAgUiState: <TState = ReadonlyJSONValue>() => TState | undefined;
|
|
30
35
|
declare const useAgUiSetState: <TState = ReadonlyJSONValue>() => (next: TState | ((prev: TState | undefined) => TState)) => void;
|
|
31
36
|
//#endregion
|
|
32
|
-
export { useAgUiInterrupts, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
37
|
+
export { useAgUiInterrupts, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
33
38
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;;;;;cAea,kCAAiC;;;;;cAOjC,8BAAqB,QAGrB;;;;;cAUA,wCAEH,oBAAoB,sBAAoB;;;;;;;;;;;;;;cAiBrC,yBAGT,SAAS,qBACT,qBAAqB,sBACpB;cAGQ,eAAgB,SAAS,wBAClC;cAIS,kBAAmB,SAAS,yBAE/B,MAAM,WAAW,MAAM,uBAAuB"}
|
package/dist/hooks.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { agUiExtras } from "./agUiExtras.js";
|
|
3
|
+
import { useCallback } from "react";
|
|
3
4
|
import { useAui } from "@assistant-ui/store";
|
|
4
5
|
//#region src/hooks.ts
|
|
5
6
|
const EMPTY_INTERRUPTS = [];
|
|
@@ -9,6 +10,14 @@ const EMPTY_INTERRUPTS = [];
|
|
|
9
10
|
*/
|
|
10
11
|
const useAgUiInterrupts = () => agUiExtras.use((e) => e.interrupts, EMPTY_INTERRUPTS);
|
|
11
12
|
/**
|
|
13
|
+
* Returns a stable function that sends an A2UI action back to the agent and
|
|
14
|
+
* resumes the run.
|
|
15
|
+
*/
|
|
16
|
+
const useAgUiSendA2uiAction = () => {
|
|
17
|
+
const aui = useAui();
|
|
18
|
+
return useCallback((action) => agUiExtras.get(aui).sendA2uiAction(action), [aui]);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
12
21
|
* Returns a function that submits responses (each `resolved` or `cancelled`)
|
|
13
22
|
* for the pending AG-UI interrupts and resumes the run.
|
|
14
23
|
*/
|
|
@@ -39,6 +48,6 @@ const useAgUiSetState = () => {
|
|
|
39
48
|
return (next) => agUiExtras.get(aui).setState(next);
|
|
40
49
|
};
|
|
41
50
|
//#endregion
|
|
42
|
-
export { useAgUiInterrupts, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
51
|
+
export { useAgUiInterrupts, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
43
52
|
|
|
44
53
|
//# sourceMappingURL=hooks.js.map
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useAui } from \"@assistant-ui/store\";\nimport type { CreateAppendMessage } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { AgUiInterrupt, AgUiResumeEntry } from \"./runtime/types\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\n\n/**\n * Read the pending AG-UI interrupts on the current thread. Returns an empty\n * array when no interrupts are pending, so consumers can `.map` without a guard.\n */\nexport const useAgUiInterrupts = (): readonly AgUiInterrupt[] =>\n agUiExtras.use((e) => e.interrupts, EMPTY_INTERRUPTS);\n\n/**\n * Returns a function that submits responses (each `resolved` or `cancelled`)\n * for the pending AG-UI interrupts and resumes the run.\n */\nexport const useAgUiSubmitInterruptResponses = () => {\n const aui = useAui();\n return (responses: readonly AgUiResumeEntry[]): Promise<void> =>\n agUiExtras.get(aui).submitInterruptResponses(responses);\n};\n\n/**\n * Returns a function that discards the pending AG-UI interrupts or pending\n * client-side tool calls and appends the given user message, starting a fresh\n * run. Use this when the user sends a new message instead of resolving them:\n * every open interrupt is reported to the agent as cancelled, and every\n * unresolved client-side tool call receives an error result. The message\n * accepts a plain string or a partial `AppendMessage` (the parent defaults to\n * the current head). Pass `responses` to override the status of specific\n * interrupts; the rest still default to cancelled. `responses` throws when\n * tool calls rather than interrupts are pending. Unlike the\n * `autoCancelPendingToolCalls` runtime option, this hook cancels regardless\n * of that option's value.\n */\nexport const useAgUiSteerAway = () => {\n const aui = useAui();\n return (\n message: CreateAppendMessage,\n responses?: readonly AgUiResumeEntry[],\n ): Promise<void> => agUiExtras.get(aui).steerAway(message, responses);\n};\n\nexport const useAgUiState = <TState = ReadonlyJSONValue>():\n | TState\n | undefined =>\n agUiExtras.use((e) => e.state as TState | undefined, undefined);\n\nexport const useAgUiSetState = <TState = ReadonlyJSONValue>() => {\n const aui = useAui();\n return (next: TState | ((prev: TState | undefined) => TState)): void =>\n agUiExtras\n .get(aui)\n .setState(\n next as\n | ReadonlyJSONValue\n | ((prev: ReadonlyJSONValue | undefined) => ReadonlyJSONValue),\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { CreateAppendMessage } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { AgUiInterrupt, AgUiResumeEntry } from \"./runtime/types\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\n\n/**\n * Read the pending AG-UI interrupts on the current thread. Returns an empty\n * array when no interrupts are pending, so consumers can `.map` without a guard.\n */\nexport const useAgUiInterrupts = (): readonly AgUiInterrupt[] =>\n agUiExtras.use((e) => e.interrupts, EMPTY_INTERRUPTS);\n\n/**\n * Returns a stable function that sends an A2UI action back to the agent and\n * resumes the run.\n */\nexport const useAgUiSendA2uiAction = () => {\n const aui = useAui();\n return useCallback(\n (action: Record<string, unknown>): void =>\n agUiExtras.get(aui).sendA2uiAction(action),\n [aui],\n );\n};\n\n/**\n * Returns a function that submits responses (each `resolved` or `cancelled`)\n * for the pending AG-UI interrupts and resumes the run.\n */\nexport const useAgUiSubmitInterruptResponses = () => {\n const aui = useAui();\n return (responses: readonly AgUiResumeEntry[]): Promise<void> =>\n agUiExtras.get(aui).submitInterruptResponses(responses);\n};\n\n/**\n * Returns a function that discards the pending AG-UI interrupts or pending\n * client-side tool calls and appends the given user message, starting a fresh\n * run. Use this when the user sends a new message instead of resolving them:\n * every open interrupt is reported to the agent as cancelled, and every\n * unresolved client-side tool call receives an error result. The message\n * accepts a plain string or a partial `AppendMessage` (the parent defaults to\n * the current head). Pass `responses` to override the status of specific\n * interrupts; the rest still default to cancelled. `responses` throws when\n * tool calls rather than interrupts are pending. Unlike the\n * `autoCancelPendingToolCalls` runtime option, this hook cancels regardless\n * of that option's value.\n */\nexport const useAgUiSteerAway = () => {\n const aui = useAui();\n return (\n message: CreateAppendMessage,\n responses?: readonly AgUiResumeEntry[],\n ): Promise<void> => agUiExtras.get(aui).steerAway(message, responses);\n};\n\nexport const useAgUiState = <TState = ReadonlyJSONValue>():\n | TState\n | undefined =>\n agUiExtras.use((e) => e.state as TState | undefined, undefined);\n\nexport const useAgUiSetState = <TState = ReadonlyJSONValue>() => {\n const aui = useAui();\n return (next: TState | ((prev: TState | undefined) => TState)): void =>\n agUiExtras\n .get(aui)\n .setState(\n next as\n | ReadonlyJSONValue\n | ((prev: ReadonlyJSONValue | undefined) => ReadonlyJSONValue),\n );\n};\n"],"mappings":";;;;;AASA,MAAM,mBAA6C,CAAC;;;;;AAMpD,MAAa,0BACX,WAAW,KAAK,MAAM,EAAE,YAAY,gBAAgB;;;;;AAMtD,MAAa,8BAA8B;CACzC,MAAM,MAAM,OAAO;CACnB,OAAO,aACJ,WACC,WAAW,IAAI,GAAG,CAAC,CAAC,eAAe,MAAM,GAC3C,CAAC,GAAG,CACN;AACF;;;;;AAMA,MAAa,wCAAwC;CACnD,MAAM,MAAM,OAAO;CACnB,QAAQ,cACN,WAAW,IAAI,GAAG,CAAC,CAAC,yBAAyB,SAAS;AAC1D;;;;;;;;;;;;;;AAeA,MAAa,yBAAyB;CACpC,MAAM,MAAM,OAAO;CACnB,QACE,SACA,cACkB,WAAW,IAAI,GAAG,CAAC,CAAC,UAAU,SAAS,SAAS;AACtE;AAEA,MAAa,qBAGX,WAAW,KAAK,MAAM,EAAE,OAA6B,KAAA,CAAS;AAEhE,MAAa,wBAAoD;CAC/D,MAAM,MAAM,OAAO;CACnB,QAAQ,SACN,WACG,IAAI,GAAG,CAAC,CACR,SACC,IAGF;AACN"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgUiInterrupt, AgUiInterruptReason, AgUiResumeEntry, AgUiRunFinishedOutcome, UseAgUiRuntimeAdapters, UseAgUiRuntimeOptions, UseAgUiThreadListAdapter } from "./runtime/types.js";
|
|
2
|
-
import { useAgUiInterrupts, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses } from "./hooks.js";
|
|
2
|
+
import { useAgUiInterrupts, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses } from "./hooks.js";
|
|
3
3
|
import { AgUiAssistantRuntime, useAgUiRuntime } from "./useAgUiRuntime.js";
|
|
4
4
|
import { FromAgUiMessagesOptions, fromAgUiMessages } from "./runtime/adapter/conversions.js";
|
|
5
|
-
export { type AgUiAssistantRuntime, type AgUiInterrupt, type AgUiInterruptReason, type AgUiResumeEntry, type AgUiRunFinishedOutcome, type FromAgUiMessagesOptions, type UseAgUiRuntimeAdapters, type UseAgUiRuntimeOptions, type UseAgUiThreadListAdapter, fromAgUiMessages, useAgUiInterrupts, useAgUiRuntime, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
5
|
+
export { type AgUiAssistantRuntime, type AgUiInterrupt, type AgUiInterruptReason, type AgUiResumeEntry, type AgUiRunFinishedOutcome, type FromAgUiMessagesOptions, type UseAgUiRuntimeAdapters, type UseAgUiRuntimeOptions, type UseAgUiThreadListAdapter, fromAgUiMessages, useAgUiInterrupts, useAgUiRuntime, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useAgUiInterrupts, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses } from "./hooks.js";
|
|
1
|
+
import { useAgUiInterrupts, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses } from "./hooks.js";
|
|
2
2
|
import { fromAgUiMessages } from "./runtime/adapter/conversions.js";
|
|
3
3
|
import { useAgUiRuntime } from "./useAgUiRuntime.js";
|
|
4
|
-
export { fromAgUiMessages, useAgUiInterrupts, useAgUiRuntime, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
4
|
+
export { fromAgUiMessages, useAgUiInterrupts, useAgUiRuntime, useAgUiSendA2uiAction, useAgUiSetState, useAgUiState, useAgUiSteerAway, useAgUiSubmitInterruptResponses };
|
|
@@ -44,6 +44,8 @@ declare class AgUiThreadRuntimeCore {
|
|
|
44
44
|
private _isLoading;
|
|
45
45
|
private _loadPromise;
|
|
46
46
|
private pendingResumeMessageId;
|
|
47
|
+
private pendingA2uiResume;
|
|
48
|
+
private pendingA2uiAction;
|
|
47
49
|
constructor(options: CoreOptions);
|
|
48
50
|
updateOptions(options: Omit<CoreOptions, "notifyUpdate">): void;
|
|
49
51
|
attachRuntime(runtime: AssistantRuntime): void;
|
|
@@ -93,6 +95,7 @@ declare class AgUiThreadRuntimeCore {
|
|
|
93
95
|
findMessageIdForToolCall(toolCallId: string): string | undefined;
|
|
94
96
|
private cancelUnresolvedToolCalls;
|
|
95
97
|
addToolResult(options: AddToolResultOptions): void;
|
|
98
|
+
sendA2uiAction(action: Record<string, unknown>): void;
|
|
96
99
|
private maybeResumeAfterToolResults;
|
|
97
100
|
private maybeCompleteAfterToolResults;
|
|
98
101
|
private startResumeRun;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgUiThreadRuntimeCore.d.ts","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"mappings":";;;;;;KAsDK,YAAY,YAAY;KACxB,gBACH,SAAS,wBACN,eAAe;KACf;EACH;EACA;EACA,WAAW;EACX,SAAS;;KAGN;EACH,OAAO;EACP,QAAQ;EACR;EACA;EACA,WAAW,OAAO;EAClB;EACA,UAAU;EACV;;cAKW;UACH;UACA;UACA;UACA;UACA;UACA;mBACS;UAET;mBACS;UACT;UACA;UACA;UACA;UACA;UACA;UACA;mBACS;mBACA;UACT;UACA;UACA;EAEI,YAAA,SAAS;EAYrB,cAAc,SAAS,KAAK;EAW5B,cAAc,SAAS;EAIvB;EAIA,wBAAwB;EAIxB,wBAAwB;UAmBhB;UAQA;UAUA;UAIA;UAQA;UAQA;UAMA;UAKA;UAKA;UAKA;EAYR,YAAY;EAIZ;MAII;EAIJ,mBAAmB;EA2Cb,OAAO,SAAS,gBAAgB;UAW9B;UAQA;EAiBF,KAAK,SAAS,gBAAgB;EAI9B,OACJ,yBACA;IAAU,YAAY;MACrB;EAMG,UAAU;EAKV,OAAO,QAAQ,kBAAkB;EAUjC,kBAAkB,mBAAmB,kBAAkB;UAwBrD;UAOA;EAgBR;IACE;IACA,qBAAqB;;EAavB;IACE;IACA;;EAcI,yBACJ,oBAAoB,oBACnB;EAoDG,UACJ,SAAS,qBACT,qBAAqB,oBACpB;UAyCK;UAkBA;UAiCA;UA0BA;EA+BR,yBAAyB;UAkBjB;EAiBR,cAAc,SAAS;UA4Bf;UAYA;UA6BA;EAMR,sBAAsB,mBAAmB;
|
|
1
|
+
{"version":3,"file":"AgUiThreadRuntimeCore.d.ts","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"mappings":";;;;;;KAsDK,YAAY,YAAY;KACxB,gBACH,SAAS,wBACN,eAAe;KACf;EACH;EACA;EACA,WAAW;EACX,SAAS;;KAGN;EACH,OAAO;EACP,QAAQ;EACR;EACA;EACA,WAAW,OAAO;EAClB;EACA,UAAU;EACV;;cAKW;UACH;UACA;UACA;UACA;UACA;UACA;mBACS;UAET;mBACS;UACT;UACA;UACA;UACA;UACA;UACA;UACA;mBACS;mBACA;UACT;UACA;UACA;UACA;UACA;EAEI,YAAA,SAAS;EAYrB,cAAc,SAAS,KAAK;EAW5B,cAAc,SAAS;EAIvB;EAIA,wBAAwB;EAIxB,wBAAwB;UAmBhB;UAQA;UAUA;UAIA;UAQA;UAQA;UAMA;UAKA;UAKA;UAKA;EAYR,YAAY;EAIZ;MAII;EAIJ,mBAAmB;EA2Cb,OAAO,SAAS,gBAAgB;UAW9B;UAQA;EAiBF,KAAK,SAAS,gBAAgB;EAI9B,OACJ,yBACA;IAAU,YAAY;MACrB;EAMG,UAAU;EAKV,OAAO,QAAQ,kBAAkB;EAUjC,kBAAkB,mBAAmB,kBAAkB;UAwBrD;UAOA;EAgBR;IACE;IACA,qBAAqB;;EAavB;IACE;IACA;;EAcI,yBACJ,oBAAoB,oBACnB;EAoDG,UACJ,SAAS,qBACT,qBAAqB,oBACpB;UAyCK;UAkBA;UAiCA;UA0BA;EA+BR,yBAAyB;UAkBjB;EAiBR,cAAc,SAAS;EAyBvB,eAAe,QAAQ;UA4Bf;UAYA;UA6BA;EAMR,sBAAsB,mBAAmB;UAkDjC;EAgER,kBAAkB,OAAO;EAKzB,SACE,MACI,sBACE,MAAM,kCAAkC;EAOhD;UAKc;UAoMA;UA2DN;UAkCA;UAqBA;UAKA;UAOA;UAyBA;UA2CA;UAiDA;UA4BA;UA6BA;UAgEA;UA2EA;UA8DA;UAgDA;UAQA;UAIA;UAKA;UAIA;UAQA;UAWA"}
|
|
@@ -3,8 +3,8 @@ import { readMcpAppResourceUri } from "./mcp-tool-result.js";
|
|
|
3
3
|
import { AG_UI_METADATA_NAMESPACE, RunAggregator, isPlainObject, tryParseJSON } from "./adapter/run-aggregator.js";
|
|
4
4
|
import { fromAgUiMessages, toAgUiMessages, toAgUiTools } from "./adapter/conversions.js";
|
|
5
5
|
import { createAgUiSubscriber } from "./adapter/subscriber.js";
|
|
6
|
-
import { MessageRepository } from "@assistant-ui/core/internal";
|
|
7
6
|
import { fromThreadMessageLike, generateId, isMcpAppUri } from "@assistant-ui/core";
|
|
7
|
+
import { MessageRepository } from "@assistant-ui/core/internal";
|
|
8
8
|
import jsonpatch from "fast-json-patch";
|
|
9
9
|
//#region src/runtime/AgUiThreadRuntimeCore.ts
|
|
10
10
|
const optimisticPrefix = "__optimistic__";
|
|
@@ -38,6 +38,8 @@ var AgUiThreadRuntimeCore = class {
|
|
|
38
38
|
_isLoading = false;
|
|
39
39
|
_loadPromise;
|
|
40
40
|
pendingResumeMessageId = null;
|
|
41
|
+
pendingA2uiResume = false;
|
|
42
|
+
pendingA2uiAction;
|
|
41
43
|
constructor(options) {
|
|
42
44
|
this.agent = options.agent;
|
|
43
45
|
this.logger = options.logger;
|
|
@@ -424,6 +426,24 @@ var AgUiThreadRuntimeCore = class {
|
|
|
424
426
|
this.notifyUpdate();
|
|
425
427
|
this.maybeResumeAfterToolResults(options.messageId);
|
|
426
428
|
}
|
|
429
|
+
sendA2uiAction(action) {
|
|
430
|
+
this.assertNoPendingInterrupts();
|
|
431
|
+
this.maybeAutoCancelPendingToolCalls();
|
|
432
|
+
const parentId = this.repository.headId;
|
|
433
|
+
if (parentId === null) {
|
|
434
|
+
this.logger.debug("[agui] sendA2uiAction: no messages to resume, dropping action");
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const userAction = { ...action };
|
|
438
|
+
delete userAction.type;
|
|
439
|
+
if (!("timestamp" in userAction)) userAction.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
440
|
+
this.pendingA2uiAction = userAction;
|
|
441
|
+
if (this.isRunningFlag) {
|
|
442
|
+
this.pendingA2uiResume = true;
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this.startResumeRun(parentId);
|
|
446
|
+
}
|
|
427
447
|
maybeResumeAfterToolResults(messageId) {
|
|
428
448
|
if (!this.maybeCompleteAfterToolResults(messageId)) return;
|
|
429
449
|
if (this.isRunningFlag) {
|
|
@@ -455,6 +475,8 @@ var AgUiThreadRuntimeCore = class {
|
|
|
455
475
|
});
|
|
456
476
|
}
|
|
457
477
|
applyExternalMessages(messages) {
|
|
478
|
+
this.pendingA2uiResume = false;
|
|
479
|
+
this.pendingA2uiAction = void 0;
|
|
458
480
|
this.assistantHistoryParents.clear();
|
|
459
481
|
if (messages.length === 0) this.clearRepository();
|
|
460
482
|
else {
|
|
@@ -564,16 +586,21 @@ var AgUiThreadRuntimeCore = class {
|
|
|
564
586
|
this.pendingError = null;
|
|
565
587
|
const assistantParentId = parent ? parentId : this.repository.headId;
|
|
566
588
|
let assistantMessageId;
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const
|
|
589
|
+
let assistantCollided = false;
|
|
590
|
+
const ensureAssistant = (allowRecreate = false) => {
|
|
591
|
+
const cached = assistantMessageId;
|
|
592
|
+
if (cached !== void 0 && this.tryGetMessage(cached)) return cached;
|
|
593
|
+
if (cached !== void 0 && (assistantCollided || !allowRecreate)) return cached;
|
|
594
|
+
const parentId = cached === void 0 && assistantParentId && this.hasMessage(assistantParentId) ? assistantParentId : this.repository.headId;
|
|
595
|
+
const created = this.insertAssistantPlaceholder(parentId, cached);
|
|
570
596
|
assistantMessageId = created;
|
|
571
|
-
this.markPendingAssistantHistory(created,
|
|
597
|
+
this.markPendingAssistantHistory(created, parentId);
|
|
572
598
|
return created;
|
|
573
599
|
};
|
|
574
600
|
if (shouldEagerlyInsertAssistant) ensureAssistant();
|
|
575
601
|
const applyUpdate = (update) => {
|
|
576
|
-
const
|
|
602
|
+
const hasContent = Array.isArray(update.content) && update.content.length > 0;
|
|
603
|
+
const resolved = this.updateAssistantMessage(ensureAssistant(hasContent), update);
|
|
577
604
|
if (resolved !== assistantMessageId) assistantMessageId = resolved;
|
|
578
605
|
};
|
|
579
606
|
const aggregator = new RunAggregator({
|
|
@@ -581,12 +608,13 @@ var AgUiThreadRuntimeCore = class {
|
|
|
581
608
|
logger: this.logger,
|
|
582
609
|
emit: applyUpdate,
|
|
583
610
|
onServerMessageId: (serverId) => {
|
|
584
|
-
const placeholder = ensureAssistant();
|
|
611
|
+
const placeholder = ensureAssistant(true);
|
|
585
612
|
if (placeholder === serverId) return;
|
|
586
613
|
if (this.reassignAssistantId(placeholder, serverId)) assistantMessageId = serverId;
|
|
614
|
+
else assistantCollided = true;
|
|
587
615
|
}
|
|
588
616
|
});
|
|
589
|
-
const dispatch = (event) => this.handleEvent(aggregator, event);
|
|
617
|
+
const dispatch = (event) => this.handleEvent(aggregator, event, assistantMessageId);
|
|
590
618
|
const abortController = new AbortController();
|
|
591
619
|
const abortSignal = abortController.signal;
|
|
592
620
|
this.abortController = abortController;
|
|
@@ -653,15 +681,37 @@ var AgUiThreadRuntimeCore = class {
|
|
|
653
681
|
const err = this.pendingError;
|
|
654
682
|
this.pendingError = null;
|
|
655
683
|
this.pendingResumeMessageId = null;
|
|
684
|
+
this.pendingA2uiResume = false;
|
|
685
|
+
this.pendingA2uiAction = void 0;
|
|
656
686
|
throw err;
|
|
657
687
|
}
|
|
658
688
|
if (this.pendingResumeMessageId !== null) {
|
|
659
689
|
const resumeMessageId = this.pendingResumeMessageId;
|
|
660
690
|
this.pendingResumeMessageId = null;
|
|
661
691
|
if (!abortSignal.aborted) this.startResumeRun(resumeMessageId);
|
|
692
|
+
else this.pendingA2uiAction = void 0;
|
|
693
|
+
}
|
|
694
|
+
if (this.pendingA2uiResume) {
|
|
695
|
+
this.pendingA2uiResume = false;
|
|
696
|
+
if (!abortSignal.aborted && this.pendingA2uiAction !== void 0) {
|
|
697
|
+
if (this.getPendingInterrupts()) {
|
|
698
|
+
this.pendingA2uiAction = void 0;
|
|
699
|
+
this.logger.debug("[agui] sendA2uiAction: pending interrupts, dropping action");
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
this.maybeAutoCancelPendingToolCalls();
|
|
703
|
+
const parentId = this.repository.headId;
|
|
704
|
+
if (parentId !== null) this.startResumeRun(parentId);
|
|
705
|
+
else {
|
|
706
|
+
this.pendingA2uiAction = void 0;
|
|
707
|
+
this.logger.debug("[agui] sendA2uiAction: no messages to resume, dropping action");
|
|
708
|
+
}
|
|
709
|
+
} else this.pendingA2uiAction = void 0;
|
|
662
710
|
}
|
|
663
711
|
}
|
|
664
712
|
async consumeResumeStream(stream, ctx) {
|
|
713
|
+
this.pendingA2uiAction = void 0;
|
|
714
|
+
this.pendingA2uiResume = false;
|
|
665
715
|
const assistantId = ctx.ensureAssistant();
|
|
666
716
|
const currentId = () => ctx.getAssistantMessageId() ?? assistantId;
|
|
667
717
|
const options = {
|
|
@@ -706,7 +756,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
706
756
|
const threadId = this.agent.threadId || "main";
|
|
707
757
|
const messages = toAgUiMessages(historyMessages ?? this.repository.getMessages());
|
|
708
758
|
const context = this.runtime?.thread.getModelContext();
|
|
709
|
-
|
|
759
|
+
const input = {
|
|
710
760
|
threadId,
|
|
711
761
|
runId,
|
|
712
762
|
state: this.stateSnapshot ?? null,
|
|
@@ -719,10 +769,13 @@ var AgUiThreadRuntimeCore = class {
|
|
|
719
769
|
forwardedProps: {
|
|
720
770
|
...context?.callSettings ?? {},
|
|
721
771
|
...context?.config ?? {},
|
|
722
|
-
...runConfig?.custom ? { runConfig: runConfig.custom } : {}
|
|
772
|
+
...runConfig?.custom ? { runConfig: runConfig.custom } : {},
|
|
773
|
+
...this.pendingA2uiAction ? { a2uiAction: { userAction: this.pendingA2uiAction } } : {}
|
|
723
774
|
},
|
|
724
775
|
...resume !== void 0 ? { resume } : {}
|
|
725
776
|
};
|
|
777
|
+
this.pendingA2uiAction = void 0;
|
|
778
|
+
return input;
|
|
726
779
|
}
|
|
727
780
|
installResumeShim() {
|
|
728
781
|
const agent = this.agent;
|
|
@@ -747,8 +800,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
747
800
|
if (this.abortController === controller) this.abortController = null;
|
|
748
801
|
this.setRunning(false);
|
|
749
802
|
}
|
|
750
|
-
insertAssistantPlaceholder(parentId) {
|
|
751
|
-
const id = generateOptimisticId();
|
|
803
|
+
insertAssistantPlaceholder(parentId, id = generateOptimisticId()) {
|
|
752
804
|
const assistant = {
|
|
753
805
|
id,
|
|
754
806
|
role: "assistant",
|
|
@@ -760,7 +812,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
760
812
|
unstable_annotations: [],
|
|
761
813
|
unstable_data: [],
|
|
762
814
|
steps: [],
|
|
763
|
-
isOptimistic:
|
|
815
|
+
isOptimistic: isOptimisticId(id),
|
|
764
816
|
custom: {}
|
|
765
817
|
}
|
|
766
818
|
};
|
|
@@ -863,7 +915,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
863
915
|
} : current.custom
|
|
864
916
|
};
|
|
865
917
|
}
|
|
866
|
-
handleEvent(aggregator, event) {
|
|
918
|
+
handleEvent(aggregator, event, activeAssistantId) {
|
|
867
919
|
switch (event.type) {
|
|
868
920
|
case "STATE_SNAPSHOT":
|
|
869
921
|
this.stateSnapshot = event.snapshot;
|
|
@@ -881,7 +933,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
881
933
|
}
|
|
882
934
|
return;
|
|
883
935
|
case "MESSAGES_SNAPSHOT":
|
|
884
|
-
this.importMessagesSnapshot(event.messages);
|
|
936
|
+
this.importMessagesSnapshot(event.messages, activeAssistantId);
|
|
885
937
|
return;
|
|
886
938
|
case "TOOL_CALL_RESULT":
|
|
887
939
|
if (!aggregator.hasToolCall(event.toolCallId)) {
|
|
@@ -986,8 +1038,10 @@ var AgUiThreadRuntimeCore = class {
|
|
|
986
1038
|
this.notifyUpdate();
|
|
987
1039
|
this.maybeCompleteAfterToolResults(messageId);
|
|
988
1040
|
}
|
|
989
|
-
importMessagesSnapshot(rawMessages) {
|
|
1041
|
+
importMessagesSnapshot(rawMessages, activeAssistantId) {
|
|
990
1042
|
try {
|
|
1043
|
+
const activeMessage = activeAssistantId ? this.tryGetMessage(activeAssistantId)?.message : void 0;
|
|
1044
|
+
const activeAssistant = activeMessage?.role === "assistant" ? activeMessage : void 0;
|
|
991
1045
|
const normalized = fromAgUiMessages(rawMessages, { showThinking: this.showThinking });
|
|
992
1046
|
const converted = [];
|
|
993
1047
|
for (const message of normalized) try {
|
|
@@ -995,7 +1049,15 @@ var AgUiThreadRuntimeCore = class {
|
|
|
995
1049
|
} catch (error) {
|
|
996
1050
|
this.logger.error?.("[agui] failed to import message from snapshot", error);
|
|
997
1051
|
}
|
|
1052
|
+
const snapshotHeadId = converted.at(-1)?.id ?? null;
|
|
1053
|
+
const snapshotContainsActiveAssistant = converted.some((message) => message.id === activeAssistant?.id);
|
|
1054
|
+
const preservesActiveAssistant = activeAssistant !== void 0 && !snapshotContainsActiveAssistant && (activeAssistant.metadata.isOptimistic !== true || converted.at(-1)?.role !== "assistant");
|
|
1055
|
+
if (preservesActiveAssistant) converted.push(activeAssistant);
|
|
998
1056
|
this.applyExternalMessages(converted);
|
|
1057
|
+
if (preservesActiveAssistant) {
|
|
1058
|
+
this.recordedHistoryIds.delete(activeAssistant.id);
|
|
1059
|
+
this.markPendingAssistantHistory(activeAssistant.id, snapshotHeadId);
|
|
1060
|
+
}
|
|
999
1061
|
} catch (error) {
|
|
1000
1062
|
this.logger.error?.("[agui] failed to import messages snapshot", error);
|
|
1001
1063
|
}
|