@assistant-ui/react-ag-ui 0.0.63 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js +14 -9
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/subscriber.js +1 -0
- package/dist/runtime/adapter/subscriber.js.map +1 -1
- package/dist/useAgUiRuntime.d.ts.map +1 -1
- package/dist/useAgUiRuntime.js +9 -2
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +7 -7
- package/src/runtime/AgUiThreadRuntimeCore.ts +16 -14
- package/src/runtime/adapter/subscriber.ts +1 -0
- package/src/useAgUiRuntime.fast-refresh.test.tsx +107 -1
- package/src/useAgUiRuntime.ts +13 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgUiThreadRuntimeCore.d.ts","sourceRoot":"","sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AgUiThreadRuntimeCore.d.ts","sourceRoot":"","sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EAEzB,4BAA4B,EAE5B,oBAAoB,EACpB,aAAa,EAEb,wBAAwB,EACzB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EACV,aAAa,EAId,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAiB;AAEvC,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,EACf,oBAAoB,EACrB,mBAAgB;AACjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAwChE,KAAK,SAAS,GAAG,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;AACzD,KAAK,YAAY,GAAG,CAClB,OAAO,EAAE,mBAAmB,KACzB,cAAc,CAAC,kBAAkB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACvD,KAAK,eAAe,GAAG;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAYF,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACpD,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAmCF,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,0BAA0B,CAAsB;IACxD,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IAExD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAerB;IACH,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAgC;IAGvD,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAoC;IAC5E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CACd;IACP,OAAO,CAAC,sBAAsB,CAAgC;IAC9D,OAAO,CAAC,iBAAiB,CAAsC;gBAEnD,OAAO,EAAE,WAAW;IAYhC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC;IAqBxD,aAAa,CAAC,OAAO,EAAE,gBAAgB;IAIvC,aAAa;IAOb,WAAW,IAAI,SAAS,aAAa,EAAE;IAIvC,oBAAoB,IAAI,yBAAyB;IAIjD,QAAQ,IAAI,iBAAiB,GAAG,SAAS;IAIzC,SAAS,IAAI,OAAO;IAIpB,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD1B,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAQnD,OAAO,CAAC,+BAA+B;IAQvC,OAAO,CAAC,WAAW;IAeb,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,MAAM,CACV,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,GAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO,GACrC,OAAO,CAAC,IAAI,CAAC;IAMV,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAW7B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,kBAAkB;IAapB,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C,iBAAiB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB1E,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,2BAA2B;IAgBnC,oBAAoB,IAAI;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;KACtC,GAAG,IAAI;IAYR,mBAAmB,IAAI;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,GAAG,IAAI;IAYF,wBAAwB,CAC5B,SAAS,EAAE,SAAS,eAAe,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC;IAiChB;;;;;OAKG;YACW,mBAAmB;IAWjC;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAYjC,OAAO,CAAC,0BAA0B;IAwB5B,qBAAqB,CACzB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC;IAsEV,SAAS,CACb,OAAO,EAAE,mBAAmB,EAC5B,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,GACrC,OAAO,CAAC,IAAI,CAAC;IA4ChB,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,yBAAyB;IAiCjC,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,sBAAsB;IAmC9B,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAiBhE,OAAO,CAAC,yBAAyB;IAiBjC,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAqC5C,qBAAqB,CAAC,OAAO,EAAE;QACnC,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,wBAAwB,CAAC;KACvC,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDjB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA6BrD,OAAO,CAAC,2BAA2B;IAanC,OAAO,CAAC,6BAA6B;IAiCrC,OAAO,CAAC,cAAc;IAMtB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI;IAwE/D,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAKjD,QAAQ,CACN,IAAI,EACA,iBAAiB,GACjB,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,SAAS,KAAK,iBAAiB,CAAC,GAC/D,IAAI;IAMP,UAAU,IAAI,IAAI;IAKlB,gBAAgB,IAAI,IAAI;YAyBV,QAAQ;YA6QR,mBAAmB;IA2DjC,OAAO,CAAC,aAAa;IAqCrB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,0BAA0B;IAyBlC,OAAO,CAAC,mBAAmB;IAkE3B,OAAO,CAAC,sBAAsB;IAiD9B,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,sBAAsB;IA6B9B,OAAO,CAAC,WAAW;IAmFnB,OAAO,CAAC,0BAA0B;IAyBlC,OAAO,CAAC,uBAAuB;IA0E/B,OAAO,CAAC,6BAA6B;IA6DrC,OAAO,CAAC,sBAAsB;IA0E9B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,uBAAuB;IAsD/B,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,iBAAiB;CA8B1B"}
|
|
@@ -142,7 +142,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
142
142
|
}
|
|
143
143
|
}).catch((error) => {
|
|
144
144
|
this.logger.error?.("[agui] failed to load history", error);
|
|
145
|
-
|
|
145
|
+
this.reportError(error);
|
|
146
146
|
}).finally(() => {
|
|
147
147
|
this._isLoading = false;
|
|
148
148
|
this.notifyUpdate();
|
|
@@ -577,7 +577,7 @@ var AgUiThreadRuntimeCore = class {
|
|
|
577
577
|
}
|
|
578
578
|
startResumeRun(messageId) {
|
|
579
579
|
this.startRun(messageId, this.lastRunConfig).catch((error) => {
|
|
580
|
-
|
|
580
|
+
this.reportError(error);
|
|
581
581
|
});
|
|
582
582
|
}
|
|
583
583
|
applyExternalMessages(messages) {
|
|
@@ -733,8 +733,10 @@ var AgUiThreadRuntimeCore = class {
|
|
|
733
733
|
},
|
|
734
734
|
onTextMessageStart: (serverId) => adoptServerMessageId(serverId, true)
|
|
735
735
|
});
|
|
736
|
+
let runFinished = false;
|
|
736
737
|
const dispatch = (event) => {
|
|
737
738
|
if (this.abortController !== abortController) return;
|
|
739
|
+
if (event.type === "RUN_FINISHED") runFinished = true;
|
|
738
740
|
const nextAssistantMessageId = this.handleEvent(aggregator, event, assistantMessageId);
|
|
739
741
|
if (event.type === "MESSAGES_SNAPSHOT") assistantMessageId = nextAssistantMessageId;
|
|
740
742
|
};
|
|
@@ -750,10 +752,13 @@ var AgUiThreadRuntimeCore = class {
|
|
|
750
752
|
this.setRunning(true);
|
|
751
753
|
try {
|
|
752
754
|
if (resumeStream) {
|
|
753
|
-
cancelRun = () =>
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
755
|
+
cancelRun = () => {
|
|
756
|
+
if ((assistantMessageId === void 0 ? void 0 : this.session.tryGetMessage(assistantMessageId)?.message)?.status?.type === "complete") return;
|
|
757
|
+
applyUpdate({ status: {
|
|
758
|
+
type: "incomplete",
|
|
759
|
+
reason: "cancelled"
|
|
760
|
+
} });
|
|
761
|
+
};
|
|
757
762
|
pendingError = await this.consumeResumeStream(resumeStream, {
|
|
758
763
|
runConfig: normalizedRunConfig,
|
|
759
764
|
threadId: this.agent.threadId || "main",
|
|
@@ -789,14 +794,14 @@ var AgUiThreadRuntimeCore = class {
|
|
|
789
794
|
await runAgentInstance.runAgent.bind(runAgentInstance)(input, subscriber, { signal: abortSignal });
|
|
790
795
|
}
|
|
791
796
|
} catch (error) {
|
|
792
|
-
if (!abortSignal.aborted) {
|
|
797
|
+
if (!abortSignal.aborted && !pendingError) {
|
|
793
798
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
794
|
-
dispatch({
|
|
799
|
+
if (!runFinished) dispatch({
|
|
795
800
|
type: "RUN_ERROR",
|
|
796
801
|
message: err.message
|
|
797
802
|
});
|
|
798
803
|
invokeRuntimeCallback("onError", this.onError, err);
|
|
799
|
-
pendingError
|
|
804
|
+
pendingError = err;
|
|
800
805
|
}
|
|
801
806
|
} finally {
|
|
802
807
|
this.finishRun(abortController);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgUiThreadRuntimeCore.js","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport {\n generateId,\n fromThreadMessageLike,\n isMcpAppUri,\n} from \"@assistant-ui/core\";\nimport type {\n AddToolResultOptions,\n AppendMessage,\n CreateAppendMessage,\n AssistantRuntime,\n ChatModelRunOptions,\n ChatModelRunResult,\n ExportedMessageRepository,\n MessageStatus,\n RespondToToolApprovalOptions,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n ToolCallMessagePart,\n Unstable_ToolInteraction,\n} from \"@assistant-ui/core\";\nimport {\n appendToolInteraction,\n createMessageRepositorySession,\n invokeUserCallback,\n iterateToolCallParts,\n mapToolCallPartsDeep,\n} from \"@assistant-ui/core/internal\";\nimport type {\n AbstractAgent,\n AgentSubscriber,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport jsonpatch, { type Operation } from \"fast-json-patch\";\nimport type { Logger } from \"./logger\";\nimport { readMcpAppResourceUri } from \"./mcp-tool-result\";\nimport type {\n AgUiEvent,\n AgUiInterrupt,\n AgUiResumeEntry,\n AgUiResumeTranscript,\n} from \"./types\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n type AgUiCustomMetadata,\n isPlainObject,\n MCP_APPS_ACTIVITY_TYPE,\n RunAggregator,\n tryParseJSON,\n} from \"./adapter/run-aggregator\";\nimport {\n fromAgUiMessages,\n toAgUiMessages,\n toAgUiTools,\n} from \"./adapter/conversions\";\nimport { createAgUiSubscriber } from \"./adapter/subscriber\";\nimport {\n buildToolApprovalResume,\n projectAgUiToolApprovals,\n withSettledToolApprovals,\n withToolApprovalDecision,\n} from \"./adapter/tool-approval\";\n\n// AbstractAgent.runAgent declares two parameters. HttpAgent ignores a third and\n// is cancelled through agent.abortRun(); the run options stay for subclasses\n// that inherit the base no-op abortRun and have no other cancellation hook.\ntype RunAgentWithRunOptions = (\n parameters: RunAgentParameters,\n subscriber: AgentSubscriber,\n options: { signal: AbortSignal },\n) => Promise<RunAgentResult>;\n\nconst optimisticPrefix = \"__optimistic__\";\nconst generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;\nconst isOptimisticId = (id: string) => id.startsWith(optimisticPrefix);\n\nconst isResolvedToolCall = (\n part: ThreadAssistantMessage[\"content\"][number],\n): boolean =>\n part.type === \"tool-call\" && \"result\" in part && part.result !== undefined;\n\ntype RunConfig = NonNullable<AppendMessage[\"runConfig\"]>;\ntype ResumeStream = (\n options: ChatModelRunOptions,\n) => AsyncGenerator<ChatModelRunResult, void, unknown>;\ntype ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: ResumeStream;\n};\n\n/**\n * A resume submission, pairing the entries that answer the open interrupts with\n * the assistant message they were opened on. That message anchors the resume\n * transcript: under `resumeTranscript: \"appended\"` only what follows it is sent.\n */\ntype ResumeDispatch = {\n entries: AgUiResumeEntry[];\n interruptedMessageId: string;\n};\n\ntype CoreOptions = {\n agent: AbstractAgent;\n logger: Logger;\n showThinking: boolean;\n resumeTranscript?: AgUiResumeTranscript | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n onError?: (error: Error) => void;\n onCancel?: () => void;\n history?: ThreadHistoryAdapter;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = { type: \"complete\", reason: \"unknown\" } as const;\n\ntype AgUiRuntimeCallbackName = \"onError\" | \"onCancel\";\n\nconst invokeRuntimeCallback = <TArgs extends readonly unknown[]>(\n name: AgUiRuntimeCallbackName,\n callback: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n): void => {\n void invokeUserCallback(\"react-ag-ui\", name, callback, ...args);\n};\n\n// The aggregator sends only the agui keys it owns (interrupts and\n// opaqueReasoning, each as a full replacement), so a shallow spread at the\n// custom level would drop any sibling agui state a snapshot import attached.\nconst mergeAgUiNamespace = (\n current: Record<string, unknown> | undefined,\n incoming: Record<string, unknown>,\n) => {\n const merged = { ...current, ...incoming };\n const currentNs = current?.[AG_UI_METADATA_NAMESPACE];\n const incomingNs = incoming[AG_UI_METADATA_NAMESPACE];\n if (\n typeof currentNs === \"object\" &&\n currentNs !== null &&\n typeof incomingNs === \"object\" &&\n incomingNs !== null\n ) {\n merged[AG_UI_METADATA_NAMESPACE] = { ...currentNs, ...incomingNs };\n }\n return merged;\n};\n\nexport class AgUiThreadRuntimeCore {\n private agent: AbstractAgent;\n private logger: Logger;\n private showThinking: boolean;\n private resumeTranscript: AgUiResumeTranscript;\n private autoCancelPendingToolCalls: boolean | undefined;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private readonly notifyUpdate: () => void;\n private readonly reportedErrors = new WeakSet<object>();\n\n private runtime: AssistantRuntime | undefined;\n private readonly session = createMessageRepositorySession({\n decorateExport: (exported, repository) => {\n let parentId: string | null = null;\n for (const message of repository.getMessages()) {\n if (message.metadata.isOptimistic) {\n exported.messages.push({ parentId, message });\n }\n parentId = message.id;\n }\n\n return {\n ...exported,\n headId: repository.headId,\n };\n },\n });\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n // The agent that started the active run. updateOptions can swap this.agent\n // mid-run, and cancelling has to reach the agent holding the live request.\n private activeRunAgent: AbstractAgent | null = null;\n private stateSnapshot: ReadonlyJSONValue | undefined;\n private history: ThreadHistoryAdapter | undefined;\n private lastRunConfig: RunConfig | undefined;\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly snapshotHistoryIds = new Set<string>();\n private readonly persistedHistoryIds = new Set<string>();\n private readonly historyWrites = new Map<string, Promise<void>>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n private _loadRequested = false;\n private pendingResume: { owner: AbortController; messageId: string } | null =\n null;\n private pendingA2uiResumeOwner: AbortController | null = null;\n private pendingA2uiAction: Record<string, unknown> | undefined;\n\n constructor(options: CoreOptions) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.resumeTranscript = options.resumeTranscript ?? \"full\";\n this.autoCancelPendingToolCalls = options.autoCancelPendingToolCalls;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n }\n\n updateOptions(options: Omit<CoreOptions, \"notifyUpdate\">) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.resumeTranscript = options.resumeTranscript ?? \"full\";\n this.autoCancelPendingToolCalls = options.autoCancelPendingToolCalls;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n const previousHistory = this.history;\n this.history = options.history;\n if (\n this._loadRequested &&\n !this._loadPromise &&\n !previousHistory &&\n options.history &&\n this.session.getMessages().length === 0\n ) {\n void this.__internal_load();\n }\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n void this.cancel().catch((error) => {\n this.logger.error(\"[agui] failed to cancel run during teardown\", error);\n });\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.session.getMessages();\n }\n\n getMessageRepository(): ExportedMessageRepository {\n return this.session.export();\n }\n\n getState(): ReadonlyJSONValue | undefined {\n return this.stateSnapshot;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n this._loadRequested = true;\n if (this._loadPromise) return this._loadPromise;\n if (!this.history) return Promise.resolve();\n\n const promise = this.history.load();\n\n this._isLoading = true;\n\n this._loadPromise = promise\n .then(async (repo) => {\n if (!repo) return;\n\n this.session.applyExternalMessageRepository(repo);\n this.assistantHistoryParents.clear();\n this.snapshotHistoryIds.clear();\n this.persistedHistoryIds.clear();\n for (const { message } of repo.messages) {\n this.persistedHistoryIds.add(message.id);\n }\n this.notifyUpdate();\n\n if (repo.state !== undefined) {\n this.loadExternalState(repo.state);\n }\n\n if (repo.unstable_resume) {\n const parentId = repo.headId ?? this.session.headId;\n const resumeStream = this.history?.resume?.bind(this.history);\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n }\n })\n .catch((error) => {\n this.logger.error?.(\"[agui] failed to load history\", error);\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n let ownsThread = true;\n if (startRun) {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n // Before the message is linked: callers parent it on the in-flight\n // assistant, and settling that assistant reassigns its optimistic id,\n // which would evict it and reparent this message onto a branch.\n ownsThread = this.supersedeActiveRun();\n }\n const threadMessageId = this.appendEntry(message);\n if (!startRun || !ownsThread) return;\n await this.startRun(threadMessageId, message.runConfig);\n }\n\n appendVoiceTranscript(message: ThreadMessage): void {\n const parentId = this.session.headId;\n this.session.addOrUpdateMessage(parentId, message);\n this.session.switchToBranch(message.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, message);\n }\n\n private maybeAutoCancelPendingToolCalls(): void {\n if (this.autoCancelPendingToolCalls === false) return;\n const pending = this.getPendingToolCalls();\n if (!pending) return;\n this.cancelUnresolvedToolCalls(pending.messageId);\n this.maybeCompleteAfterToolResults(pending.messageId);\n }\n\n private appendEntry(message: AppendMessage): string {\n const threadMessage = this.toThreadMessage(message);\n const parentId =\n message.parentId === null\n ? null\n : message.parentId && this.session.hasMessage(message.parentId)\n ? message.parentId\n : this.session.headId;\n this.session.addOrUpdateMessage(parentId, threadMessage);\n this.session.switchToBranch(threadMessage.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, threadMessage);\n return threadMessage.id;\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n config: { runConfig?: RunConfig } = {},\n ): Promise<void> {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n await this.startRun(parentId, config.runConfig);\n }\n\n async cancel(): Promise<void> {\n this.abortActiveRun();\n }\n\n // abortRun is what stops an upstream agent: AbstractAgent.runAgent declares\n // two parameters and HttpAgent binds its request to a controller of its own,\n // so the run options object reaches only subclasses that read it. The local\n // abort comes last and is unconditional: its listener runs onCancel\n // synchronously, so a callback that starts another run must keep the\n // controller it installed, and a throw from a subclass's abortRun would\n // otherwise strand the thread as running.\n private abortActiveRun(): void {\n const controller = this.abortController;\n if (!controller) return;\n try {\n (this.activeRunAgent ?? this.agent).abortRun();\n } finally {\n controller.abort();\n }\n }\n\n // Starting a run supersedes the active one, and reports whether the caller\n // still owns the thread afterwards: the local abort runs onCancel\n // synchronously, so a callback that starts its own run keeps it. abortRun is a\n // subclass's code, and a throw there must not abandon the run being started,\n // unlike cancel(), where the failed operation is the caller's own. Calling\n // this twice for one run is harmless, because the second call finds no active\n // run to supersede.\n private supersedeActiveRun(): boolean {\n try {\n this.abortActiveRun();\n } catch (error) {\n this.logger.error?.(\"[agui] agent abortRun failed\", error);\n }\n if (this.abortController === null) return true;\n this.logger.debug?.(\n \"[agui] onCancel started a replacement run; dropping the superseding send\",\n );\n return false;\n }\n\n async resume(config: ResumeRunConfig): Promise<void> {\n this.assertNoPendingInterrupts();\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\n undefined,\n config.stream,\n );\n }\n\n async resumeInFlightRun(messages: readonly ThreadMessage[]): Promise<void> {\n // Without a resume stream startRun would re-run the agent from scratch.\n const resumeStream = this.history?.resume?.bind(this.history);\n if (!resumeStream) {\n const error = new Error(\n \"[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method; skipping resume after thread switch\",\n );\n this.logger.error?.(error.message);\n invokeRuntimeCallback(\"onError\", this.onError, error);\n return;\n }\n const parentId = messages.at(-1)?.id ?? null;\n try {\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n } catch {\n // startRun already reported via onError; don't reject the switch.\n }\n }\n\n private assertNoPendingInterrupts(): void {\n if (!this.getPendingInterrupts()) return;\n throw new Error(\n \"[agui] cannot start a new run while interrupts are pending; resolve them with submitInterruptResponses()\",\n );\n }\n\n private findRequiresActionAssistant(\n reason: \"interrupt\" | \"tool-calls\",\n ): ThreadAssistantMessage | null {\n const assistant = this.getMessages().findLast(\n (message) => message.role === \"assistant\",\n ) as ThreadAssistantMessage | undefined;\n if (\n !assistant ||\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== reason\n ) {\n return null;\n }\n return assistant;\n }\n\n getPendingInterrupts(): {\n messageId: string;\n interrupts: readonly AgUiInterrupt[];\n } | null {\n const assistant = this.findRequiresActionAssistant(\"interrupt\");\n if (!assistant) return null;\n const stored = (\n assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined\n )?.interrupts;\n if (!stored?.length) return null;\n return { messageId: assistant.id, interrupts: stored };\n }\n\n getPendingToolCalls(): {\n messageId: string;\n toolCallIds: string[];\n } | null {\n const assistant = this.findRequiresActionAssistant(\"tool-calls\");\n if (!assistant) return null;\n const toolCallIds: string[] = [];\n for (const part of iterateToolCallParts(assistant.content)) {\n if (isResolvedToolCall(part)) continue;\n toolCallIds.push(part.toolCallId);\n }\n if (toolCallIds.length === 0) return null;\n return { messageId: assistant.id, toolCallIds };\n }\n\n async submitInterruptResponses(\n responses: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] submitInterruptResponses: no pending interrupts on this thread\",\n );\n }\n\n const responsesById = this.collectInterruptResponses(\n \"submitInterruptResponses\",\n pending.interrupts,\n responses,\n );\n\n const openIds = pending.interrupts.map((i) => i.id);\n const missing = openIds.filter((id) => !responsesById.has(id));\n if (missing.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: missing responses for open interrupts: ${missing.join(\", \")}`,\n );\n }\n\n this.assertInterruptsAnswerable(\n \"submitInterruptResponses\",\n pending.interrupts,\n );\n\n await this.resumeWithResponses(\n pending.messageId,\n openIds.map((id) => responsesById.get(id)!),\n );\n }\n\n /**\n * Resumes with an already validated resume array. Answerability is checked\n * once per submission: re-checking here would let a clock crossing reject a\n * decision this runtime has already recorded, stranding the gate decided and\n * unretryable.\n */\n private async resumeWithResponses(\n messageId: string,\n resume: AgUiResumeEntry[],\n ): Promise<void> {\n this.clearPendingInterrupts(messageId, resume);\n await this.startRun(messageId, this.lastRunConfig, {\n entries: resume,\n interruptedMessageId: messageId,\n });\n }\n\n /**\n * A rejected decision reaches the caller through the approval seam, and\n * `onError` in addition, because a consumer watching only the runtime would\n * otherwise miss it. A failure raised by the resumed run itself was already\n * reported by `startRun` before it rethrew, so reporting it here again would\n * give the consumer two notifications for one failure.\n */\n reportError(error: unknown): void {\n if (this.reportedErrors.has(error as object)) {\n this.reportedErrors.delete(error as object);\n return;\n }\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n private assertInterruptsAnswerable(\n method: \"submitInterruptResponses\" | \"respondToToolApproval\",\n interrupts: readonly AgUiInterrupt[],\n ): void {\n const now = Date.now();\n for (const interrupt of interrupts) {\n if (!interrupt.expiresAt) continue;\n const expiry = new Date(interrupt.expiresAt).getTime();\n if (Number.isNaN(expiry)) {\n throw new Error(\n `[agui] ${method}: interrupt ${interrupt.id} has malformed expiresAt \"${interrupt.expiresAt}\"`,\n );\n }\n if (expiry <= now) {\n throw new Error(\n `[agui] ${method}: interrupt ${interrupt.id} expired at ${interrupt.expiresAt}`,\n );\n }\n }\n if (this.isRunningFlag) {\n throw new Error(`[agui] ${method}: a run is already in progress`);\n }\n }\n\n async respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] respondToToolApproval: no pending interrupts on this thread\",\n );\n }\n\n // Bound against the message the gates landed on, so this check claims a\n // batch only where the projection did.\n const gatedMessage = this.session.tryGetMessage(pending.messageId)\n ?.message as ThreadAssistantMessage | undefined;\n const gated = projectAgUiToolApprovals(\n pending.interrupts,\n new Set(\n Array.from(iterateToolCallParts(gatedMessage?.content ?? [])).map(\n (part) => part.toolCallId,\n ),\n ),\n );\n const isGated = [...gated.values()].some(\n (approval) => approval.id === options.approvalId,\n );\n if (!isGated) {\n throw new Error(\n `[agui] respondToToolApproval: no pending tool-call interrupt for approval id \"${options.approvalId}\"`,\n );\n }\n\n // The decision is recorded only once the batch is known to be answerable:\n // a rejected submission would otherwise leave the gate decided and\n // unretryable, because a second click reports it as already decided.\n this.assertInterruptsAnswerable(\n \"respondToToolApproval\",\n pending.interrupts,\n );\n\n const recorded = this.session.updateMessage(\n pending.messageId,\n (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const content = withToolApprovalDecision(assistant.content, options);\n if (content === assistant.content) return assistant;\n return { ...assistant, content };\n },\n );\n if (!recorded) {\n throw new Error(\n `[agui] respondToToolApproval: approval \"${options.approvalId}\" is already decided`,\n );\n }\n this.notifyUpdate();\n\n const assistant = this.session.tryGetMessage(pending.messageId)?.message as\n | ThreadAssistantMessage\n | undefined;\n if (!assistant) return;\n\n // AG-UI resumes a run with one response per open interrupt, so the run\n // stays paused until every gate in the batch has been answered.\n const resume = buildToolApprovalResume(\n assistant.content,\n pending.interrupts,\n );\n if (!resume) return;\n\n await this.resumeWithResponses(pending.messageId, resume);\n }\n\n async steerAway(\n message: CreateAppendMessage,\n responses?: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n const pendingTools = this.getPendingToolCalls();\n if (pendingTools) {\n if (responses?.length) {\n throw new Error(\n \"[agui] steerAway: responses are only valid for pending interrupts\",\n );\n }\n if (this.isRunningFlag) {\n throw new Error(\"[agui] steerAway: a run is already in progress\");\n }\n this.cancelUnresolvedToolCalls(pendingTools.messageId);\n this.maybeCompleteAfterToolResults(pendingTools.messageId);\n const normalized = this.toAppendMessage(message);\n const threadMessageId = this.appendEntry(normalized);\n await this.startRun(threadMessageId, normalized.runConfig);\n return;\n }\n if (responses?.length) {\n throw new Error(\n \"[agui] steerAway: no pending interrupts on this thread\",\n );\n }\n await this.append(this.toAppendMessage(message));\n return;\n }\n\n const resume = this.resolveSteerAwayResume(pending.interrupts, responses);\n\n if (this.isRunningFlag) {\n throw new Error(\"[agui] steerAway: a run is already in progress\");\n }\n\n const normalized = this.toAppendMessage(message);\n this.clearPendingInterrupts(pending.messageId, resume);\n const threadMessageId = this.appendEntry(normalized);\n await this.startRun(threadMessageId, normalized.runConfig, {\n entries: resume,\n interruptedMessageId: pending.messageId,\n });\n }\n\n private resolveSteerAwayResume(\n interrupts: readonly AgUiInterrupt[],\n responses: readonly AgUiResumeEntry[] | undefined,\n ): AgUiResumeEntry[] {\n const responsesById = this.collectInterruptResponses(\n \"steerAway\",\n interrupts,\n responses ?? [],\n );\n return interrupts.map(\n (interrupt) =>\n responsesById.get(interrupt.id) ?? {\n interruptId: interrupt.id,\n status: \"cancelled\",\n },\n );\n }\n\n private collectInterruptResponses(\n method: \"submitInterruptResponses\" | \"steerAway\",\n interrupts: readonly AgUiInterrupt[],\n responses: readonly AgUiResumeEntry[],\n ): Map<string, AgUiResumeEntry> {\n const known = new Set(interrupts.map((interrupt) => interrupt.id));\n const responsesById = new Map<string, AgUiResumeEntry>();\n for (const entry of responses) {\n if (!entry || typeof entry.interruptId !== \"string\") {\n throw new Error(\n `[agui] ${method}: every entry must have an interruptId`,\n );\n }\n if (entry.status !== \"resolved\" && entry.status !== \"cancelled\") {\n throw new Error(\n `[agui] ${method}: invalid status \"${entry.status}\" for interrupt ${entry.interruptId}`,\n );\n }\n if (!known.has(entry.interruptId)) {\n throw new Error(\n `[agui] ${method}: unknown interrupt id ${entry.interruptId}`,\n );\n }\n if (responsesById.has(entry.interruptId)) {\n throw new Error(\n `[agui] ${method}: duplicate response for interrupt ${entry.interruptId}`,\n );\n }\n responsesById.set(entry.interruptId, entry);\n }\n return responsesById;\n }\n\n private toAppendMessage(message: CreateAppendMessage): AppendMessage {\n if (typeof message === \"string\") {\n return {\n createdAt: new Date(),\n parentId: this.session.headId,\n sourceId: null,\n runConfig: {},\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n attachments: [],\n metadata: { custom: {} },\n };\n }\n return {\n createdAt: message.createdAt ?? new Date(),\n parentId:\n message.parentId === undefined ? this.session.headId : message.parentId,\n sourceId: message.sourceId ?? null,\n role: message.role ?? \"user\",\n content: message.content,\n attachments: message.attachments ?? [],\n metadata: message.metadata ?? { custom: {} },\n runConfig: message.runConfig ?? {},\n startRun: message.startRun,\n } as AppendMessage;\n }\n\n private clearPendingInterrupts(\n messageId: string,\n resume: readonly AgUiResumeEntry[],\n ): void {\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return assistant;\n }\n const aguiMeta = assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined;\n const { interrupts: _drop, ...restAgui } = aguiMeta ?? {};\n const newCustom = { ...assistant.metadata.custom };\n if (Object.keys(restAgui).length > 0) {\n newCustom[AG_UI_METADATA_NAMESPACE] = restAgui;\n } else {\n delete newCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n ...assistant,\n content: withSettledToolApprovals(assistant.content, resume),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n metadata: { ...assistant.metadata, custom: newCustom },\n };\n });\n if (touched) {\n this.notifyUpdate();\n }\n }\n\n findMessageIdForToolCall(toolCallId: string): string | undefined {\n let fallbackMessageId: string | undefined;\n const messages = this.getMessages();\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (!message || message.role !== \"assistant\") continue;\n for (const part of iterateToolCallParts(message.content)) {\n if (part.toolCallId !== toolCallId) continue;\n if (!isResolvedToolCall(part)) {\n return message.id;\n }\n fallbackMessageId ??= message.id;\n }\n }\n return fallbackMessageId;\n }\n\n private cancelUnresolvedToolCalls(messageId: string): void {\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (isResolvedToolCall(part)) return part;\n return {\n ...part,\n result: { error: \"Tool call cancelled by user\" },\n isError: true,\n };\n });\n return { ...assistant, content };\n });\n if (updated) this.notifyUpdate();\n }\n\n addToolResult(options: AddToolResultOptions): void {\n // Core's ToolInvocationTracker resolves a nested call to the nested\n // subagent message's id, which is not a session message; re-anchor on the\n // top-level message that owns the tree so the update can land.\n const sessionMessageId = this.session.tryGetMessage(options.messageId)\n ? options.messageId\n : this.findMessageIdForToolCall(options.toolCallId);\n if (sessionMessageId === undefined) return;\n const updated = this.session.updateMessage(sessionMessageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== options.toolCallId) return part;\n matchedToolCall = true;\n // artifact and modelContent are optional; only override when supplied\n // so a later result that omits them keeps a stored value, and\n // emitToolResult can forward the model-facing content to the agent.\n return {\n ...part,\n result: options.result,\n isError: options.isError,\n ...(options.artifact !== undefined && { artifact: options.artifact }),\n ...(options.modelContent !== undefined && {\n modelContent: options.modelContent,\n }),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeResumeAfterToolResults(sessionMessageId);\n }\n\n async recordToolInteraction(options: {\n messageId: string;\n toolCallId: string;\n interaction: Unstable_ToolInteraction;\n }): Promise<void> {\n const sessionMessageId = this.session.tryGetMessage(options.messageId)\n ? options.messageId\n : this.findMessageIdForToolCall(options.toolCallId);\n if (sessionMessageId === undefined) {\n throw new Error(\n `[agui] recordToolInteraction: message \"${options.messageId}\" was not found`,\n );\n }\n\n const item = this.session.tryGetMessage(sessionMessageId);\n if (!item) {\n throw new Error(\n `[agui] recordToolInteraction: message \"${sessionMessageId}\" was not found`,\n );\n }\n\n let recorded = false;\n const updated = this.session.updateMessage(sessionMessageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== options.toolCallId) return part;\n recorded = true;\n return {\n ...part,\n unstable_interactions: appendToolInteraction(\n part.unstable_interactions,\n options.interaction,\n ),\n };\n });\n return recorded ? { ...assistant, content } : assistant;\n });\n if (!recorded || !updated) {\n throw new Error(\n `[agui] recordToolInteraction: tool call \"${options.toolCallId}\" was not found on message \"${options.messageId}\"`,\n );\n }\n\n this.notifyUpdate();\n\n const message = this.session.tryGetMessage(sessionMessageId)?.message;\n const history = this.history;\n if (\n !message ||\n !history?.update ||\n !this.isPersistableStatus(message.status)\n ) {\n return;\n }\n\n await this.chainHistoryWrite(sessionMessageId, () =>\n history.update!({ parentId: item.parentId, message }),\n );\n }\n\n sendA2uiAction(action: Record<string, unknown>): void {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n const parentId = this.session.headId;\n if (parentId === null) {\n this.logger.debug(\n \"[agui] sendA2uiAction: no messages to resume, dropping action\",\n );\n return;\n }\n\n const userAction = { ...action };\n delete userAction.type;\n if (!(\"timestamp\" in userAction)) {\n userAction.timestamp = new Date().toISOString();\n }\n this.pendingA2uiAction = userAction;\n\n const owner = this.abortController;\n if (owner) {\n this.pendingA2uiResumeOwner = owner;\n return;\n }\n this.startResumeRun(parentId);\n }\n\n // The continuation fires whether the frontend result lands before\n // RUN_FINISHED (the status flips to requires-action only later, while the\n // run is still draining) or after it.\n private maybeResumeAfterToolResults(messageId: string): void {\n if (!this.maybeCompleteAfterToolResults(messageId)) return;\n\n const owner = this.abortController;\n if (owner) {\n // A run is still draining (RUN_FINISHED arrived but the stream has not\n // closed). Defer until startRun's tail so we never start two runs.\n this.pendingResume = { owner, messageId };\n return;\n }\n this.startResumeRun(messageId);\n }\n\n private maybeCompleteAfterToolResults(messageId: string): boolean {\n const message = this.session.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return false;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"tool-calls\"\n ) {\n return false;\n }\n let allResolved = true;\n for (const part of iterateToolCallParts(assistant.content)) {\n if (!isResolvedToolCall(part)) {\n allResolved = false;\n break;\n }\n }\n if (!allResolved) return false;\n\n const updated = this.session.updateMessage(messageId, (current) =>\n current.role === \"assistant\"\n ? {\n ...(current as ThreadAssistantMessage),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n }\n : current,\n );\n if (!updated) return false;\n this.notifyUpdate();\n this.persistAssistantHistory(messageId);\n return true;\n }\n\n private startResumeRun(messageId: string): void {\n void this.startRun(messageId, this.lastRunConfig).catch((error) => {\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n });\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n messages = messages.map((message) => {\n if (message.role === \"system\" || message.metadata.modality !== undefined)\n return message;\n const modality = this.session.tryGetMessage(message.id)?.message.metadata\n .modality;\n if (modality === undefined) return message;\n return {\n ...message,\n metadata: { ...message.metadata, modality },\n } as ThreadMessage;\n });\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n this.assistantHistoryParents.clear();\n\n if (messages.length === 0) {\n this.session.clear();\n } else {\n let expectedParentId: string | null = null;\n let lastAppliedId: string | null = null;\n let hardReplace = false;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n const existing = this.session.tryGetMessage(message.id);\n if (existing && existing.parentId !== expectedParentId) {\n hardReplace = true;\n break;\n }\n this.session.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n\n if (hardReplace) {\n this.session.clear();\n expectedParentId = null;\n lastAppliedId = null;\n seen.clear();\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n this.session.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n }\n\n this.session.resetHead(lastAppliedId);\n }\n\n this.snapshotHistoryIds.clear();\n for (const { message } of this.getMessageRepository().messages) {\n this.snapshotHistoryIds.add(message.id);\n }\n // MESSAGES_SNAPSHOT re-appends the active assistant, so a parked\n // continuation whose target survived the snapshot is still answerable.\n // Membership is the head branch, not the repository: a soft merge leaves\n // the messages it dropped behind as off-branch nodes.\n const resumeTarget = this.pendingResume?.messageId;\n if (\n resumeTarget !== undefined &&\n !this.session.getMessages().some((message) => message.id === resumeTarget)\n ) {\n this.pendingResume = null;\n }\n this.notifyUpdate();\n }\n\n loadExternalState(state: ReadonlyJSONValue): void {\n this.stateSnapshot = state;\n this.notifyUpdate();\n }\n\n setState(\n next:\n | ReadonlyJSONValue\n | ((prev: ReadonlyJSONValue | undefined) => ReadonlyJSONValue),\n ): void {\n this.stateSnapshot =\n typeof next === \"function\" ? next(this.stateSnapshot) : next;\n this.notifyUpdate();\n }\n\n resetState(): void {\n this.stateSnapshot = undefined;\n this.notifyUpdate();\n }\n\n resetThreadState(): void {\n const controller = this.abortController;\n const activeRunAgent = this.activeRunAgent;\n\n this.stateSnapshot = undefined;\n this.pendingResume = null;\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n\n if (controller) {\n this.abortController = null;\n this.activeRunAgent = null;\n this.setRunning(false);\n try {\n (activeRunAgent ?? this.agent).abortRun();\n } catch (error) {\n this.logger.error?.(\"[agui] agent abortRun failed\", error);\n } finally {\n controller.abort();\n }\n } else {\n this.notifyUpdate();\n }\n }\n\n private async startRun(\n parentId: string | null,\n runConfig?: RunConfig,\n resume?: ResumeDispatch,\n resumeStream?: ResumeStream,\n ): Promise<void> {\n // A default AG-UI run supersedes the active run; the hook's opt-in message\n // queue serializes sends instead. append supersedes earlier, before it links\n // its message; this covers the entry points that start a run without one.\n if (!this.supersedeActiveRun()) return;\n\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n const parent =\n parentId === null ? undefined : this.session.tryGetMessage(parentId);\n const shouldEagerlyInsertAssistant =\n parentId !== null &&\n parent !== undefined &&\n parentId !== this.session.headId;\n const historicalMessages = [\n ...(shouldEagerlyInsertAssistant\n ? (this.session.tryGetMessages(parentId) ?? this.session.getMessages())\n : this.session.getMessages()),\n ];\n const runStartMessageIds = new Set(\n this.getMessageRepository().messages.map(({ message }) => message.id),\n );\n\n let pendingError: Error | null = null;\n const assistantParentId = parent ? parentId : this.session.headId;\n let assistantMessageId: string | undefined;\n // A snapshot the preserve gate declines still evicts the in-flight\n // assistant; recreating under the cached id on the next content-bearing\n // emit keeps both the stream and the message identity. Status-only emits,\n // data-only content, and off-branch server-id collisions must not\n // recreate: the snapshot already carries this turn's assistant, so\n // resurrecting for custom-event data would leave a trailing data-only\n // duplicate.\n let assistantCollided = false;\n const ensureAssistant = (allowRecreate = false): string => {\n const cached = assistantMessageId;\n if (cached !== undefined && this.session.tryGetMessage(cached))\n return cached;\n if (cached !== undefined && (assistantCollided || !allowRecreate)) {\n return cached;\n }\n const repositoryHeadId = this.session.headId;\n const shouldUseSelectedParent =\n cached === undefined ||\n (shouldEagerlyInsertAssistant &&\n (repositoryHeadId === null ||\n runStartMessageIds.has(repositoryHeadId)));\n // Branch runs keep their selected parent unless the snapshot advanced to\n // a message introduced during this run.\n const parentId =\n shouldUseSelectedParent &&\n assistantParentId &&\n this.session.hasMessage(assistantParentId)\n ? assistantParentId\n : repositoryHeadId;\n const created = this.insertAssistantPlaceholder(parentId, cached);\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, parentId);\n return created;\n };\n\n if (shouldEagerlyInsertAssistant) ensureAssistant();\n\n const applyUpdate = (update: ChatModelRunResult) => {\n const hasStreamContent =\n Array.isArray(update.content) &&\n update.content.some((part) => part.type !== \"data\");\n const resolved = this.updateAssistantMessage(\n ensureAssistant(hasStreamContent),\n update,\n );\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n };\n\n const adoptServerMessageId = (\n serverId: string,\n startNewMessage: boolean,\n ) => {\n if (startNewMessage && assistantMessageId !== undefined) {\n applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n const previousId = assistantMessageId;\n assistantMessageId = undefined;\n if (this.session.tryGetMessage(previousId)) {\n const created = this.insertAssistantPlaceholder(previousId);\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, previousId);\n }\n }\n const placeholder = ensureAssistant(true);\n if (placeholder === serverId) return;\n const reassigned = this.reassignAssistantId(placeholder, serverId);\n // A collision drops the placeholder before revealing the existing\n // server message as the current head. Only messages introduced during\n // this run can replace the placeholder; regeneration must not rewrite\n // a previous branch when the server incorrectly reuses its id.\n const adoptsVisibleCollision =\n !reassigned &&\n !runStartMessageIds.has(serverId) &&\n this.session.headId === serverId;\n if (reassigned || adoptsVisibleCollision) {\n assistantMessageId = serverId;\n if (adoptsVisibleCollision) {\n const parentId =\n this.session.tryGetMessage(serverId)?.parentId ?? null;\n this.markPendingAssistantHistory(serverId, parentId);\n }\n } else {\n assistantCollided = true;\n }\n };\n\n const abortController = new AbortController();\n const abortSignal = abortController.signal;\n const aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: applyUpdate,\n onServerMessageId: (serverId) => {\n adoptServerMessageId(serverId, false);\n },\n onTextMessageStart: (serverId) => adoptServerMessageId(serverId, true),\n });\n const dispatch = (event: AgUiEvent) => {\n if (this.abortController !== abortController) return;\n const nextAssistantMessageId = this.handleEvent(\n aggregator,\n event,\n assistantMessageId,\n );\n if (event.type === \"MESSAGES_SNAPSHOT\") {\n assistantMessageId = nextAssistantMessageId;\n }\n };\n\n this.abortController = abortController;\n const runAgentInstance = this.agent;\n this.activeRunAgent = runAgentInstance;\n\n let cancelRun = () => dispatch({ type: \"RUN_CANCELLED\" });\n abortSignal.addEventListener(\n \"abort\",\n () => {\n cancelRun();\n this.finishRun(abortController);\n invokeRuntimeCallback(\"onCancel\", this.onCancel);\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n try {\n if (resumeStream) {\n // Cancel flips only the status; an aggregator RUN_CANCELLED would emit an empty snapshot and wipe the replayed content.\n cancelRun = () =>\n applyUpdate({ status: { type: \"incomplete\", reason: \"cancelled\" } });\n pendingError =\n (await this.consumeResumeStream(resumeStream, {\n runConfig: normalizedRunConfig,\n threadId: this.agent.threadId || \"main\",\n parentId: assistantParentId,\n historicalMessages,\n abortSignal,\n ensureAssistant,\n applyUpdate,\n getAssistantMessageId: () => assistantMessageId,\n })) ?? null;\n } else {\n const runId = generateId();\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\n const subscriber = createAgUiSubscriber({\n dispatch,\n runId,\n logger: this.logger,\n onRunFailed: (error) => {\n if (abortSignal.aborted) return;\n pendingError = error;\n invokeRuntimeCallback(\"onError\", this.onError, error);\n },\n });\n try {\n (runAgentInstance as any).messages = input.messages;\n (runAgentInstance as any).threadId = input.threadId;\n (runAgentInstance as any).state = input.state ?? null;\n } catch {\n // ignore\n }\n const runAgent: RunAgentWithRunOptions =\n runAgentInstance.runAgent.bind(runAgentInstance);\n await runAgent(input, subscriber, { signal: abortSignal });\n }\n } catch (error) {\n if (!abortSignal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n dispatch({ type: \"RUN_ERROR\", message: err.message });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n pendingError ??= err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (pendingError) {\n const err = pendingError;\n this.reportedErrors.add(err);\n this.clearDeferredContinuations(abortController);\n throw err;\n }\n\n // A tool result that landed before the run settled deferred its\n // continuation here so a second run never overlaps the first.\n if (this.pendingResume?.owner === abortController) {\n const { messageId } = this.pendingResume;\n this.pendingResume = null;\n if (!abortSignal.aborted) {\n this.startResumeRun(messageId);\n }\n }\n\n if (this.pendingA2uiResumeOwner === abortController) {\n this.pendingA2uiResumeOwner = null;\n if (!abortSignal.aborted && this.pendingA2uiAction !== undefined) {\n if (this.getPendingInterrupts()) {\n this.pendingA2uiAction = undefined;\n this.logger.debug(\n \"[agui] sendA2uiAction: pending interrupts, dropping action\",\n );\n return;\n }\n this.maybeAutoCancelPendingToolCalls();\n const parentId = this.session.headId;\n if (parentId !== null) {\n this.startResumeRun(parentId);\n } else {\n this.pendingA2uiAction = undefined;\n this.logger.debug(\n \"[agui] sendA2uiAction: no messages to resume, dropping action\",\n );\n }\n } else {\n this.pendingA2uiAction = undefined;\n }\n }\n }\n\n // Replays a persisted run's snapshots into the existing assistant message, bypassing agent.runAgent so it is not re-invoked.\n private async consumeResumeStream(\n stream: ResumeStream,\n ctx: {\n runConfig: RunConfig;\n threadId: string;\n parentId: string | null;\n historicalMessages: readonly ThreadMessage[];\n abortSignal: AbortSignal;\n ensureAssistant: () => string;\n applyUpdate: (update: ChatModelRunResult) => void;\n getAssistantMessageId: () => string | undefined;\n },\n ): Promise<Error | undefined> {\n this.pendingA2uiAction = undefined;\n this.pendingA2uiResumeOwner = null;\n const assistantId = ctx.ensureAssistant();\n const currentId = () => ctx.getAssistantMessageId() ?? assistantId;\n const options: ChatModelRunOptions = {\n messages: ctx.historicalMessages,\n runConfig: ctx.runConfig,\n abortSignal: ctx.abortSignal,\n context: this.runtime?.thread.getModelContext() ?? {},\n unstable_assistantMessageId: assistantId,\n unstable_threadId: ctx.threadId,\n unstable_parentId: ctx.parentId,\n unstable_getMessage: () => {\n const message = this.session.tryGetMessage(currentId())?.message;\n if (!message) {\n throw new Error(\n \"[agui] resume stream requested the assistant message before it existed\",\n );\n }\n return message;\n },\n };\n\n try {\n for await (const result of stream(options)) {\n if (ctx.abortSignal.aborted) return undefined;\n ctx.applyUpdate(result);\n }\n } catch (error) {\n if (ctx.abortSignal.aborted) return undefined;\n const err = error instanceof Error ? error : new Error(String(error));\n ctx.applyUpdate({\n status: { type: \"incomplete\", reason: \"error\", error: err.message },\n });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n return err;\n }\n\n if (ctx.abortSignal.aborted) return undefined;\n const current = this.session.tryGetMessage(currentId())?.message;\n if (!current || current.status?.type === \"running\") {\n ctx.applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n }\n return undefined;\n }\n\n private buildRunInput(\n runId: string,\n runConfig: RunConfig | undefined,\n historyMessages: readonly ThreadMessage[] | undefined,\n resume?: ResumeDispatch,\n ) {\n const threadId = this.agent.threadId || \"main\";\n const messages = toAgUiMessages(\n this.selectRunMessages(\n historyMessages ?? this.session.getMessages(),\n resume,\n ),\n );\n const context = this.runtime?.thread.getModelContext();\n const input = {\n threadId,\n runId,\n state: this.stateSnapshot ?? null,\n messages,\n tools: toAgUiTools(context?.tools),\n context: context?.system\n ? [{ description: \"system\", value: context.system }]\n : [],\n forwardedProps: {\n ...(context?.callSettings ?? {}),\n ...(context?.config ?? {}),\n ...(runConfig?.custom ? { runConfig: runConfig.custom } : {}),\n ...(this.pendingA2uiAction\n ? { a2uiAction: { userAction: this.pendingA2uiAction } }\n : {}),\n },\n ...(resume !== undefined ? { resume: resume.entries } : {}),\n };\n this.pendingA2uiAction = undefined;\n return input;\n }\n\n /**\n * An anchor the thread no longer carries falls back to the whole transcript.\n * The anchor is missing exactly when a snapshot import replaced the messages\n * this resume was raised against, and a host that expects a delta tolerates\n * being told more than it knows, while one rebuilding the run from the\n * transcript cannot recover from being told less.\n */\n private selectRunMessages(\n messages: readonly ThreadMessage[],\n resume: ResumeDispatch | undefined,\n ): readonly ThreadMessage[] {\n if (resume === undefined || this.resumeTranscript !== \"appended\")\n return messages;\n const anchor = messages.findIndex(\n (message) => message.id === resume.interruptedMessageId,\n );\n if (anchor === -1) return messages;\n return messages.slice(anchor + 1);\n }\n\n private clearDeferredContinuations(owner: AbortController): void {\n if (this.pendingResume?.owner === owner) {\n this.pendingResume = null;\n }\n if (this.pendingA2uiResumeOwner === owner) {\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n }\n }\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController !== controller) return;\n this.abortController = null;\n this.activeRunAgent = null;\n this.setRunning(false);\n }\n\n private insertAssistantPlaceholder(\n parentId: string | null,\n id: string = generateOptimisticId(),\n ): string {\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.stateSnapshot ?? null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n isOptimistic: isOptimisticId(id),\n custom: {},\n },\n };\n this.session.addOrUpdateMessage(parentId ?? this.session.headId, assistant);\n this.session.switchToBranch(id);\n this.notifyUpdate();\n return id;\n }\n\n private reassignAssistantId(oldId: string, newId: string): boolean {\n if (oldId === newId) return true;\n const oldItem = this.session.tryGetMessage(oldId);\n if (!oldItem) return false;\n\n const collidesWithExisting = this.session.hasMessage(newId);\n\n if (collidesWithExisting) {\n this.logger.debug?.(\n \"[agui] reassignAssistantId: server id already present in messages or repository, dropping placeholder\",\n { oldId, newId },\n );\n this.session.deleteMessage(oldId, oldItem.parentId ?? null);\n } else {\n const { isOptimistic: _, ...metadata } = oldItem.message.metadata;\n this.session.addOrUpdateMessage(oldItem.parentId, {\n ...oldItem.message,\n id: newId,\n metadata,\n } as ThreadMessage);\n this.session.switchToBranch(newId);\n this.session.tryDeleteMessage(oldId);\n }\n\n const pendingParent = this.assistantHistoryParents.get(oldId);\n if (pendingParent !== undefined) {\n this.assistantHistoryParents.delete(oldId);\n if (!collidesWithExisting && !this.assistantHistoryParents.has(newId)) {\n this.assistantHistoryParents.set(newId, pendingParent);\n }\n }\n\n for (const ids of [this.snapshotHistoryIds, this.persistedHistoryIds]) {\n if (ids.has(oldId)) {\n ids.delete(oldId);\n if (!collidesWithExisting) {\n ids.add(newId);\n }\n }\n }\n\n // An in-flight write completes under the id it was started with, so the\n // rename moves the chain entry and transfers the completion mark; without\n // this the resolve records the dead id and the live one appends again.\n const pendingWrite = this.historyWrites.get(oldId);\n if (pendingWrite) {\n this.historyWrites.delete(oldId);\n if (!collidesWithExisting) {\n this.historyWrites.set(newId, pendingWrite);\n const settle = () => {\n if (this.historyWrites.get(newId) === pendingWrite) {\n this.historyWrites.delete(newId);\n }\n };\n void pendingWrite.then(() => {\n this.persistedHistoryIds.delete(oldId);\n this.persistedHistoryIds.add(newId);\n settle();\n }, settle);\n }\n }\n\n this.notifyUpdate();\n return !collidesWithExisting;\n }\n\n private updateAssistantMessage(\n messageId: string,\n update: ChatModelRunResult,\n ): string {\n let latestStatus: MessageStatus | undefined;\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const metadata = update.metadata\n ? this.mergeAssistantMetadata(assistant.metadata, update.metadata)\n : assistant.metadata;\n latestStatus = update.status ?? assistant.status;\n const content =\n update.content !== undefined\n ? this.preserveToolResults(\n assistant.content,\n update.content as ThreadAssistantMessage[\"content\"],\n )\n : assistant.content;\n return {\n ...assistant,\n content,\n status: latestStatus,\n metadata,\n };\n });\n if (!touched) return messageId;\n\n let resolvedMessageId = messageId;\n const isSettled =\n latestStatus !== undefined && latestStatus.type !== \"running\";\n if (isSettled && isOptimisticId(messageId)) {\n const stableId = generateId();\n this.reassignAssistantId(messageId, stableId);\n resolvedMessageId = stableId;\n } else {\n this.notifyUpdate();\n }\n if (this.isPersistableStatus(latestStatus)) {\n this.persistAssistantHistory(resolvedMessageId);\n }\n this.maybeResumeAfterToolResults(resolvedMessageId);\n return resolvedMessageId;\n }\n\n // The RunAggregator rebuilds the assistant content from stream events only,\n // so a fresh snapshot omits results injected via addToolResult (frontend tool\n // execution). Carry those results forward so the aggregator never clobbers\n // them. Results are only ever added in this flow, so preserving is safe.\n private preserveToolResults(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const preserved = new Map<string, ToolCallMessagePart>();\n for (const part of iterateToolCallParts(previous)) {\n if (isResolvedToolCall(part)) {\n preserved.set(part.toolCallId, part);\n }\n }\n if (preserved.size === 0) {\n return this.preserveToolInteractions(previous, next);\n }\n\n const { content: merged, changed } = mapToolCallPartsDeep(next, (part) => {\n const prior = preserved.get(part.toolCallId);\n if (!prior) return part;\n if (!isResolvedToolCall(part) && isResolvedToolCall(prior)) {\n return {\n ...part,\n result: prior.result,\n ...(prior.artifact !== undefined ? { artifact: prior.artifact } : {}),\n ...(prior.isError !== undefined ? { isError: prior.isError } : {}),\n ...(prior.modelContent !== undefined\n ? { modelContent: prior.modelContent }\n : {}),\n };\n }\n return part;\n });\n return this.preserveToolInteractions(previous, changed ? merged : next);\n }\n\n private preserveToolInteractions(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const interactions = new Map<\n string,\n NonNullable<ToolCallMessagePart[\"unstable_interactions\"]>\n >();\n for (const part of iterateToolCallParts(previous)) {\n if (part.unstable_interactions !== undefined) {\n interactions.set(part.toolCallId, part.unstable_interactions);\n }\n }\n if (interactions.size === 0) return next;\n\n const { content, changed } = mapToolCallPartsDeep(next, (part) => {\n const interaction = interactions.get(part.toolCallId);\n if (interaction === undefined || part.unstable_interactions !== undefined)\n return part;\n return { ...part, unstable_interactions: interaction };\n });\n return changed ? content : next;\n }\n\n private mergeAssistantMetadata(\n current: ThreadAssistantMessage[\"metadata\"],\n incoming: NonNullable<ChatModelRunResult[\"metadata\"]>,\n ): ThreadAssistantMessage[\"metadata\"] {\n const annotations = incoming.unstable_annotations\n ? [...current.unstable_annotations, ...incoming.unstable_annotations]\n : current.unstable_annotations;\n const data = incoming.unstable_data\n ? [...current.unstable_data, ...incoming.unstable_data]\n : current.unstable_data;\n const steps = incoming.steps\n ? [...current.steps, ...incoming.steps]\n : current.steps;\n return {\n unstable_state:\n incoming.unstable_state !== undefined\n ? incoming.unstable_state\n : current.unstable_state,\n unstable_annotations: annotations,\n unstable_data: data,\n steps,\n ...(current.isOptimistic ? { isOptimistic: true } : {}),\n ...(incoming.timing ? { timing: incoming.timing } : {}),\n custom: incoming.custom\n ? mergeAgUiNamespace(current.custom, incoming.custom)\n : current.custom,\n };\n }\n\n private handleEvent(\n aggregator: RunAggregator,\n event: AgUiEvent,\n activeAssistantId: string | undefined,\n ): string | undefined {\n switch (event.type) {\n case \"STATE_SNAPSHOT\": {\n this.stateSnapshot = event.snapshot as ReadonlyJSONValue;\n this.updateActiveAssistantState(activeAssistantId);\n break;\n }\n case \"STATE_DELTA\": {\n if (event.delta.length === 0) break;\n try {\n const state = this.stateSnapshot ?? {};\n const result = jsonpatch.applyPatch(\n state,\n event.delta as Operation[],\n /* validateOperation */ true,\n /* mutateDocument */ false,\n );\n this.stateSnapshot = result.newDocument as ReadonlyJSONValue;\n this.updateActiveAssistantState(activeAssistantId);\n } catch (error) {\n this.logger.error?.(\"[agui] failed to apply state delta\", error);\n }\n break;\n }\n case \"MESSAGES_SNAPSHOT\": {\n const previousHeadId = this.session.headId;\n const activeAssistant =\n activeAssistantId === undefined\n ? undefined\n : this.session.tryGetMessage(activeAssistantId)?.message;\n const hasActiveText =\n activeAssistant?.role === \"assistant\" &&\n activeAssistant.content.some((part) => part.type === \"text\");\n this.importMessagesSnapshot(event.messages, activeAssistantId);\n const headId = this.session.headId;\n if (hasActiveText && headId !== previousHeadId) {\n const head =\n headId === null\n ? undefined\n : this.session.tryGetMessage(headId)?.message;\n activeAssistantId =\n head?.role === \"assistant\" ? (headId ?? undefined) : undefined;\n }\n this.updateActiveAssistantState(activeAssistantId);\n break;\n }\n case \"TOOL_CALL_RESULT\": {\n if (!aggregator.hasToolCall(event.toolCallId)) {\n const messageId = this.findMessageIdForToolCall(event.toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunToolResult(messageId, event);\n break;\n }\n }\n aggregator.handle(event);\n break;\n }\n case \"ACTIVITY_SNAPSHOT\": {\n const toolCallId = event.content[\"toolCallId\"];\n if (\n event.activityType === MCP_APPS_ACTIVITY_TYPE &&\n typeof toolCallId === \"string\" &&\n !aggregator.hasToolCall(toolCallId)\n ) {\n const messageId = this.findMessageIdForToolCall(toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunActivitySnapshot(messageId, toolCallId, event);\n break;\n }\n }\n aggregator.handle(event);\n break;\n }\n default:\n aggregator.handle(event);\n }\n return activeAssistantId;\n }\n\n private updateActiveAssistantState(messageId: string | undefined): void {\n const current =\n messageId === undefined\n ? undefined\n : this.session.tryGetMessage(messageId)?.message;\n const activeAssistantId =\n current?.role === \"assistant\" && this.session.headId === messageId\n ? messageId\n : this.session.headId;\n if (activeAssistantId !== null && activeAssistantId !== undefined) {\n this.session.updateMessage(activeAssistantId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n return {\n ...assistant,\n metadata: {\n ...assistant.metadata,\n unstable_state: this.stateSnapshot ?? null,\n },\n };\n });\n }\n this.notifyUpdate();\n }\n\n private applyCrossRunToolResult(\n messageId: string,\n event: Extract<AgUiEvent, { type: \"TOOL_CALL_RESULT\" }>,\n ): void {\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const mcpAppUri = readMcpAppResourceUri(event.mcpResult?._meta);\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== event.toolCallId) return part;\n matchedToolCall = true;\n // An applied activity snapshot owns part.result; a later result only\n // fills what is missing, mirroring the aggregator's finishToolCall.\n // The aggregator's flag is set only when the snapshot carried a\n // result, so app presence alone is not enough: the current result\n // must be CallToolResult-shaped (a required content array).\n const snapshotResultApplied =\n part.mcp?.app !== undefined &&\n isPlainObject(part.result) &&\n Array.isArray((part.result as Record<string, unknown>)[\"content\"]);\n if (snapshotResultApplied) {\n return {\n ...part,\n ...(part.modelContent === undefined && event.content\n ? {\n modelContent: [\n { type: \"text\" as const, text: event.content },\n ],\n }\n : {}),\n ...(part.isError === undefined\n ? typeof event.mcpResult?.isError === \"boolean\"\n ? { isError: event.mcpResult.isError }\n : event.role === \"tool\"\n ? { isError: false }\n : {}\n : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n }\n return {\n ...part,\n result: (event.mcpResult ??\n tryParseJSON(event.content ?? \"\")) as ReadonlyJSONValue,\n ...(event.mcpResult !== undefined\n ? { modelContent: [{ type: \"text\" as const, text: event.content }] }\n : {}),\n ...(typeof event.mcpResult?.isError === \"boolean\"\n ? { isError: event.mcpResult.isError }\n : event.role === \"tool\"\n ? { isError: false }\n : {}),\n ...(part.mcp === undefined && mcpAppUri !== undefined\n ? { mcp: { app: { resourceUri: mcpAppUri } } }\n : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n // Not maybeResumeAfterToolResults: the delivering run is already in\n // flight, and a resume from the owner would reset the head past it.\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private applyCrossRunActivitySnapshot(\n messageId: string,\n toolCallId: string,\n event: Extract<AgUiEvent, { type: \"ACTIVITY_SNAPSHOT\" }>,\n ): void {\n const resourceUri = event.content[\"resourceUri\"];\n if (typeof resourceUri !== \"string\" || !isMcpAppUri(resourceUri)) return;\n const serverId = event.content[\"serverId\"];\n const serverHash = event.content[\"serverHash\"];\n const appServerId =\n typeof serverId === \"string\" && serverId.length > 0\n ? serverId\n : typeof serverHash === \"string\" && serverHash.length > 0\n ? serverHash\n : undefined;\n const result = event.content[\"result\"];\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== toolCallId) return part;\n matchedToolCall = true;\n return {\n ...part,\n mcp: {\n app: {\n resourceUri,\n ...(appServerId ? { serverId: appServerId } : {}),\n },\n },\n ...(isPlainObject(result)\n ? {\n ...(part.result !== undefined && part.modelContent === undefined\n ? {\n modelContent: [\n {\n type: \"text\" as const,\n text:\n typeof part.result === \"string\"\n ? part.result\n : JSON.stringify(part.result),\n },\n ],\n }\n : {}),\n result: result as ReadonlyJSONValue,\n isError: result[\"isError\"] === true,\n }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private importMessagesSnapshot(\n rawMessages: readonly unknown[],\n activeAssistantId: string | undefined,\n ) {\n try {\n const activeMessage = activeAssistantId\n ? this.session.tryGetMessage(activeAssistantId)?.message\n : undefined;\n const activeAssistant =\n activeMessage?.role === \"assistant\" ? activeMessage : undefined;\n const normalized = fromAgUiMessages(rawMessages, {\n showThinking: this.showThinking,\n });\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n const convertedMessage = fromThreadMessageLike(\n message,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n const existing = this.session.tryGetMessage(\n convertedMessage.id,\n )?.message;\n if (\n convertedMessage.role === \"assistant\" &&\n existing?.role === \"assistant\"\n ) {\n converted.push({\n ...convertedMessage,\n content: this.preserveToolInteractions(\n existing.content,\n convertedMessage.content,\n ),\n });\n } else {\n converted.push(convertedMessage);\n }\n } catch (error) {\n this.logger.error?.(\n \"[agui] failed to import message from snapshot\",\n error,\n );\n }\n }\n const snapshotContainsActiveAssistant = converted.some(\n (message) => message.id === activeAssistant?.id,\n );\n const preservesActiveAssistant =\n activeAssistant !== undefined &&\n !snapshotContainsActiveAssistant &&\n (activeAssistant.metadata.isOptimistic !== true ||\n converted.at(-1)?.role !== \"assistant\");\n if (preservesActiveAssistant) {\n converted.push(activeAssistant);\n }\n this.applyExternalMessages(converted);\n if (activeAssistant !== undefined) {\n const activeItem = this.session.tryGetMessage(activeAssistant.id);\n if (activeItem) {\n if (preservesActiveAssistant) {\n this.snapshotHistoryIds.delete(activeAssistant.id);\n }\n this.markPendingAssistantHistory(\n activeAssistant.id,\n activeItem.parentId,\n );\n }\n }\n } catch (error) {\n this.logger.error?.(\"[agui] failed to import messages snapshot\", error);\n }\n }\n\n private toThreadMessage(message: AppendMessage): ThreadMessage {\n return fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n }\n\n private isTerminalStatus(status?: MessageStatus): boolean {\n return status?.type === \"complete\" || status?.type === \"incomplete\";\n }\n\n private isPersistableStatus(status?: MessageStatus): boolean {\n if (this.isTerminalStatus(status)) return true;\n return status?.type === \"requires-action\" && status.reason === \"interrupt\";\n }\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n void this.appendHistoryItem(parentId, message)?.catch((error) => {\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n });\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n const history = this.history;\n if (!history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.session.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return;\n if (!this.isPersistableStatus(message.status)) return;\n const wasPersisted = this.persistedHistoryIds.has(messageId);\n const update = history.update;\n const shouldUpdate =\n update !== undefined &&\n (wasPersisted || this.snapshotHistoryIds.has(messageId));\n\n if (shouldUpdate) {\n const write = this.chainHistoryWrite(messageId, () =>\n update.call(history, { parentId, message }),\n );\n this.assistantHistoryParents.delete(messageId);\n void write.then(\n () => {\n this.persistedHistoryIds.add(messageId);\n },\n (error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, parentId);\n }\n this.logger.error?.(\"[agui] failed to update history entry\", error);\n },\n );\n return;\n }\n\n if (wasPersisted) {\n this.assistantHistoryParents.delete(messageId);\n return;\n }\n\n const write = this.appendHistoryItem(parentId, message);\n if (!write) return;\n this.assistantHistoryParents.delete(messageId);\n void write.then(\n () => {},\n (error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, parentId);\n }\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n },\n );\n }\n\n private appendHistoryItem(\n parentId: string | null,\n message: ThreadMessage,\n ): Promise<void> | undefined {\n if (!this.history || this.persistedHistoryIds.has(message.id)) return;\n const pending = this.historyWrites.get(message.id);\n if (pending) return pending;\n\n const append = this.history.append.bind(this.history);\n const write = this.chainHistoryWrite(message.id, () =>\n append({ parentId, message }),\n );\n void write.then(\n () => {\n this.persistedHistoryIds.add(message.id);\n },\n () => {},\n );\n return write;\n }\n\n private chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const pending = this.historyWrites.get(id);\n let next: Promise<void>;\n if (pending) {\n next = pending.then(write, write);\n } else {\n try {\n next = Promise.resolve(write());\n } catch (error) {\n next = Promise.reject(error);\n }\n }\n this.historyWrites.set(id, next);\n void next.then(\n () => {\n if (this.historyWrites.get(id) === next) {\n this.historyWrites.delete(id);\n }\n },\n () => {\n if (this.historyWrites.get(id) === next) {\n this.historyWrites.delete(id);\n }\n },\n );\n return next;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgUiThreadRuntimeCore.js","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport {\n generateId,\n fromThreadMessageLike,\n isMcpAppUri,\n} from \"@assistant-ui/core\";\nimport type {\n AddToolResultOptions,\n AppendMessage,\n CreateAppendMessage,\n AssistantRuntime,\n ChatModelRunOptions,\n ChatModelRunResult,\n ExportedMessageRepository,\n MessageStatus,\n RespondToToolApprovalOptions,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n ToolCallMessagePart,\n Unstable_ToolInteraction,\n} from \"@assistant-ui/core\";\nimport {\n appendToolInteraction,\n createMessageRepositorySession,\n invokeUserCallback,\n iterateToolCallParts,\n mapToolCallPartsDeep,\n} from \"@assistant-ui/core/internal\";\nimport type {\n AbstractAgent,\n AgentSubscriber,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport jsonpatch, { type Operation } from \"fast-json-patch\";\nimport type { Logger } from \"./logger\";\nimport { readMcpAppResourceUri } from \"./mcp-tool-result\";\nimport type {\n AgUiEvent,\n AgUiInterrupt,\n AgUiResumeEntry,\n AgUiResumeTranscript,\n} from \"./types\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n type AgUiCustomMetadata,\n isPlainObject,\n MCP_APPS_ACTIVITY_TYPE,\n RunAggregator,\n tryParseJSON,\n} from \"./adapter/run-aggregator\";\nimport {\n fromAgUiMessages,\n toAgUiMessages,\n toAgUiTools,\n} from \"./adapter/conversions\";\nimport { createAgUiSubscriber } from \"./adapter/subscriber\";\nimport {\n buildToolApprovalResume,\n projectAgUiToolApprovals,\n withSettledToolApprovals,\n withToolApprovalDecision,\n} from \"./adapter/tool-approval\";\n\n// AbstractAgent.runAgent declares two parameters. HttpAgent ignores a third and\n// is cancelled through agent.abortRun(); the run options stay for subclasses\n// that inherit the base no-op abortRun and have no other cancellation hook.\ntype RunAgentWithRunOptions = (\n parameters: RunAgentParameters,\n subscriber: AgentSubscriber,\n options: { signal: AbortSignal },\n) => Promise<RunAgentResult>;\n\nconst optimisticPrefix = \"__optimistic__\";\nconst generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;\nconst isOptimisticId = (id: string) => id.startsWith(optimisticPrefix);\n\nconst isResolvedToolCall = (\n part: ThreadAssistantMessage[\"content\"][number],\n): boolean =>\n part.type === \"tool-call\" && \"result\" in part && part.result !== undefined;\n\ntype RunConfig = NonNullable<AppendMessage[\"runConfig\"]>;\ntype ResumeStream = (\n options: ChatModelRunOptions,\n) => AsyncGenerator<ChatModelRunResult, void, unknown>;\ntype ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: ResumeStream;\n};\n\n/**\n * A resume submission, pairing the entries that answer the open interrupts with\n * the assistant message they were opened on. That message anchors the resume\n * transcript: under `resumeTranscript: \"appended\"` only what follows it is sent.\n */\ntype ResumeDispatch = {\n entries: AgUiResumeEntry[];\n interruptedMessageId: string;\n};\n\ntype CoreOptions = {\n agent: AbstractAgent;\n logger: Logger;\n showThinking: boolean;\n resumeTranscript?: AgUiResumeTranscript | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n onError?: (error: Error) => void;\n onCancel?: () => void;\n history?: ThreadHistoryAdapter;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = { type: \"complete\", reason: \"unknown\" } as const;\n\ntype AgUiRuntimeCallbackName = \"onError\" | \"onCancel\";\n\nconst invokeRuntimeCallback = <TArgs extends readonly unknown[]>(\n name: AgUiRuntimeCallbackName,\n callback: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n): void => {\n void invokeUserCallback(\"react-ag-ui\", name, callback, ...args);\n};\n\n// The aggregator sends only the agui keys it owns (interrupts and\n// opaqueReasoning, each as a full replacement), so a shallow spread at the\n// custom level would drop any sibling agui state a snapshot import attached.\nconst mergeAgUiNamespace = (\n current: Record<string, unknown> | undefined,\n incoming: Record<string, unknown>,\n) => {\n const merged = { ...current, ...incoming };\n const currentNs = current?.[AG_UI_METADATA_NAMESPACE];\n const incomingNs = incoming[AG_UI_METADATA_NAMESPACE];\n if (\n typeof currentNs === \"object\" &&\n currentNs !== null &&\n typeof incomingNs === \"object\" &&\n incomingNs !== null\n ) {\n merged[AG_UI_METADATA_NAMESPACE] = { ...currentNs, ...incomingNs };\n }\n return merged;\n};\n\nexport class AgUiThreadRuntimeCore {\n private agent: AbstractAgent;\n private logger: Logger;\n private showThinking: boolean;\n private resumeTranscript: AgUiResumeTranscript;\n private autoCancelPendingToolCalls: boolean | undefined;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private readonly notifyUpdate: () => void;\n private readonly reportedErrors = new WeakSet<object>();\n\n private runtime: AssistantRuntime | undefined;\n private readonly session = createMessageRepositorySession({\n decorateExport: (exported, repository) => {\n let parentId: string | null = null;\n for (const message of repository.getMessages()) {\n if (message.metadata.isOptimistic) {\n exported.messages.push({ parentId, message });\n }\n parentId = message.id;\n }\n\n return {\n ...exported,\n headId: repository.headId,\n };\n },\n });\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n // The agent that started the active run. updateOptions can swap this.agent\n // mid-run, and cancelling has to reach the agent holding the live request.\n private activeRunAgent: AbstractAgent | null = null;\n private stateSnapshot: ReadonlyJSONValue | undefined;\n private history: ThreadHistoryAdapter | undefined;\n private lastRunConfig: RunConfig | undefined;\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly snapshotHistoryIds = new Set<string>();\n private readonly persistedHistoryIds = new Set<string>();\n private readonly historyWrites = new Map<string, Promise<void>>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n private _loadRequested = false;\n private pendingResume: { owner: AbortController; messageId: string } | null =\n null;\n private pendingA2uiResumeOwner: AbortController | null = null;\n private pendingA2uiAction: Record<string, unknown> | undefined;\n\n constructor(options: CoreOptions) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.resumeTranscript = options.resumeTranscript ?? \"full\";\n this.autoCancelPendingToolCalls = options.autoCancelPendingToolCalls;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n }\n\n updateOptions(options: Omit<CoreOptions, \"notifyUpdate\">) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.resumeTranscript = options.resumeTranscript ?? \"full\";\n this.autoCancelPendingToolCalls = options.autoCancelPendingToolCalls;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n const previousHistory = this.history;\n this.history = options.history;\n if (\n this._loadRequested &&\n !this._loadPromise &&\n !previousHistory &&\n options.history &&\n this.session.getMessages().length === 0\n ) {\n void this.__internal_load();\n }\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n void this.cancel().catch((error) => {\n this.logger.error(\"[agui] failed to cancel run during teardown\", error);\n });\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.session.getMessages();\n }\n\n getMessageRepository(): ExportedMessageRepository {\n return this.session.export();\n }\n\n getState(): ReadonlyJSONValue | undefined {\n return this.stateSnapshot;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n this._loadRequested = true;\n if (this._loadPromise) return this._loadPromise;\n if (!this.history) return Promise.resolve();\n\n const promise = this.history.load();\n\n this._isLoading = true;\n\n this._loadPromise = promise\n .then(async (repo) => {\n if (!repo) return;\n\n this.session.applyExternalMessageRepository(repo);\n this.assistantHistoryParents.clear();\n this.snapshotHistoryIds.clear();\n this.persistedHistoryIds.clear();\n for (const { message } of repo.messages) {\n this.persistedHistoryIds.add(message.id);\n }\n this.notifyUpdate();\n\n if (repo.state !== undefined) {\n this.loadExternalState(repo.state);\n }\n\n if (repo.unstable_resume) {\n const parentId = repo.headId ?? this.session.headId;\n const resumeStream = this.history?.resume?.bind(this.history);\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n }\n })\n .catch((error) => {\n this.logger.error?.(\"[agui] failed to load history\", error);\n this.reportError(error);\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n let ownsThread = true;\n if (startRun) {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n // Before the message is linked: callers parent it on the in-flight\n // assistant, and settling that assistant reassigns its optimistic id,\n // which would evict it and reparent this message onto a branch.\n ownsThread = this.supersedeActiveRun();\n }\n const threadMessageId = this.appendEntry(message);\n if (!startRun || !ownsThread) return;\n await this.startRun(threadMessageId, message.runConfig);\n }\n\n appendVoiceTranscript(message: ThreadMessage): void {\n const parentId = this.session.headId;\n this.session.addOrUpdateMessage(parentId, message);\n this.session.switchToBranch(message.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, message);\n }\n\n private maybeAutoCancelPendingToolCalls(): void {\n if (this.autoCancelPendingToolCalls === false) return;\n const pending = this.getPendingToolCalls();\n if (!pending) return;\n this.cancelUnresolvedToolCalls(pending.messageId);\n this.maybeCompleteAfterToolResults(pending.messageId);\n }\n\n private appendEntry(message: AppendMessage): string {\n const threadMessage = this.toThreadMessage(message);\n const parentId =\n message.parentId === null\n ? null\n : message.parentId && this.session.hasMessage(message.parentId)\n ? message.parentId\n : this.session.headId;\n this.session.addOrUpdateMessage(parentId, threadMessage);\n this.session.switchToBranch(threadMessage.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, threadMessage);\n return threadMessage.id;\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n config: { runConfig?: RunConfig } = {},\n ): Promise<void> {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n await this.startRun(parentId, config.runConfig);\n }\n\n async cancel(): Promise<void> {\n this.abortActiveRun();\n }\n\n // abortRun is what stops an upstream agent: AbstractAgent.runAgent declares\n // two parameters and HttpAgent binds its request to a controller of its own,\n // so the run options object reaches only subclasses that read it. The local\n // abort comes last and is unconditional: its listener runs onCancel\n // synchronously, so a callback that starts another run must keep the\n // controller it installed, and a throw from a subclass's abortRun would\n // otherwise strand the thread as running.\n private abortActiveRun(): void {\n const controller = this.abortController;\n if (!controller) return;\n try {\n (this.activeRunAgent ?? this.agent).abortRun();\n } finally {\n controller.abort();\n }\n }\n\n // Starting a run supersedes the active one, and reports whether the caller\n // still owns the thread afterwards: the local abort runs onCancel\n // synchronously, so a callback that starts its own run keeps it. abortRun is a\n // subclass's code, and a throw there must not abandon the run being started,\n // unlike cancel(), where the failed operation is the caller's own. Calling\n // this twice for one run is harmless, because the second call finds no active\n // run to supersede.\n private supersedeActiveRun(): boolean {\n try {\n this.abortActiveRun();\n } catch (error) {\n this.logger.error?.(\"[agui] agent abortRun failed\", error);\n }\n if (this.abortController === null) return true;\n this.logger.debug?.(\n \"[agui] onCancel started a replacement run; dropping the superseding send\",\n );\n return false;\n }\n\n async resume(config: ResumeRunConfig): Promise<void> {\n this.assertNoPendingInterrupts();\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\n undefined,\n config.stream,\n );\n }\n\n async resumeInFlightRun(messages: readonly ThreadMessage[]): Promise<void> {\n // Without a resume stream startRun would re-run the agent from scratch.\n const resumeStream = this.history?.resume?.bind(this.history);\n if (!resumeStream) {\n const error = new Error(\n \"[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method; skipping resume after thread switch\",\n );\n this.logger.error?.(error.message);\n invokeRuntimeCallback(\"onError\", this.onError, error);\n return;\n }\n const parentId = messages.at(-1)?.id ?? null;\n try {\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n } catch {\n // startRun already reported via onError; don't reject the switch.\n }\n }\n\n private assertNoPendingInterrupts(): void {\n if (!this.getPendingInterrupts()) return;\n throw new Error(\n \"[agui] cannot start a new run while interrupts are pending; resolve them with submitInterruptResponses()\",\n );\n }\n\n private findRequiresActionAssistant(\n reason: \"interrupt\" | \"tool-calls\",\n ): ThreadAssistantMessage | null {\n const assistant = this.getMessages().findLast(\n (message) => message.role === \"assistant\",\n ) as ThreadAssistantMessage | undefined;\n if (\n !assistant ||\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== reason\n ) {\n return null;\n }\n return assistant;\n }\n\n getPendingInterrupts(): {\n messageId: string;\n interrupts: readonly AgUiInterrupt[];\n } | null {\n const assistant = this.findRequiresActionAssistant(\"interrupt\");\n if (!assistant) return null;\n const stored = (\n assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined\n )?.interrupts;\n if (!stored?.length) return null;\n return { messageId: assistant.id, interrupts: stored };\n }\n\n getPendingToolCalls(): {\n messageId: string;\n toolCallIds: string[];\n } | null {\n const assistant = this.findRequiresActionAssistant(\"tool-calls\");\n if (!assistant) return null;\n const toolCallIds: string[] = [];\n for (const part of iterateToolCallParts(assistant.content)) {\n if (isResolvedToolCall(part)) continue;\n toolCallIds.push(part.toolCallId);\n }\n if (toolCallIds.length === 0) return null;\n return { messageId: assistant.id, toolCallIds };\n }\n\n async submitInterruptResponses(\n responses: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] submitInterruptResponses: no pending interrupts on this thread\",\n );\n }\n\n const responsesById = this.collectInterruptResponses(\n \"submitInterruptResponses\",\n pending.interrupts,\n responses,\n );\n\n const openIds = pending.interrupts.map((i) => i.id);\n const missing = openIds.filter((id) => !responsesById.has(id));\n if (missing.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: missing responses for open interrupts: ${missing.join(\", \")}`,\n );\n }\n\n this.assertInterruptsAnswerable(\n \"submitInterruptResponses\",\n pending.interrupts,\n );\n\n await this.resumeWithResponses(\n pending.messageId,\n openIds.map((id) => responsesById.get(id)!),\n );\n }\n\n /**\n * Resumes with an already validated resume array. Answerability is checked\n * once per submission: re-checking here would let a clock crossing reject a\n * decision this runtime has already recorded, stranding the gate decided and\n * unretryable.\n */\n private async resumeWithResponses(\n messageId: string,\n resume: AgUiResumeEntry[],\n ): Promise<void> {\n this.clearPendingInterrupts(messageId, resume);\n await this.startRun(messageId, this.lastRunConfig, {\n entries: resume,\n interruptedMessageId: messageId,\n });\n }\n\n /**\n * A rejected decision reaches the caller through the approval seam, and\n * `onError` in addition, because a consumer watching only the runtime would\n * otherwise miss it. A failure raised by the resumed run itself was already\n * reported by `startRun` before it rethrew, so reporting it here again would\n * give the consumer two notifications for one failure.\n */\n reportError(error: unknown): void {\n if (this.reportedErrors.has(error as object)) {\n this.reportedErrors.delete(error as object);\n return;\n }\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n private assertInterruptsAnswerable(\n method: \"submitInterruptResponses\" | \"respondToToolApproval\",\n interrupts: readonly AgUiInterrupt[],\n ): void {\n const now = Date.now();\n for (const interrupt of interrupts) {\n if (!interrupt.expiresAt) continue;\n const expiry = new Date(interrupt.expiresAt).getTime();\n if (Number.isNaN(expiry)) {\n throw new Error(\n `[agui] ${method}: interrupt ${interrupt.id} has malformed expiresAt \"${interrupt.expiresAt}\"`,\n );\n }\n if (expiry <= now) {\n throw new Error(\n `[agui] ${method}: interrupt ${interrupt.id} expired at ${interrupt.expiresAt}`,\n );\n }\n }\n if (this.isRunningFlag) {\n throw new Error(`[agui] ${method}: a run is already in progress`);\n }\n }\n\n async respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] respondToToolApproval: no pending interrupts on this thread\",\n );\n }\n\n // Bound against the message the gates landed on, so this check claims a\n // batch only where the projection did.\n const gatedMessage = this.session.tryGetMessage(pending.messageId)\n ?.message as ThreadAssistantMessage | undefined;\n const gated = projectAgUiToolApprovals(\n pending.interrupts,\n new Set(\n Array.from(iterateToolCallParts(gatedMessage?.content ?? [])).map(\n (part) => part.toolCallId,\n ),\n ),\n );\n const isGated = [...gated.values()].some(\n (approval) => approval.id === options.approvalId,\n );\n if (!isGated) {\n throw new Error(\n `[agui] respondToToolApproval: no pending tool-call interrupt for approval id \"${options.approvalId}\"`,\n );\n }\n\n // The decision is recorded only once the batch is known to be answerable:\n // a rejected submission would otherwise leave the gate decided and\n // unretryable, because a second click reports it as already decided.\n this.assertInterruptsAnswerable(\n \"respondToToolApproval\",\n pending.interrupts,\n );\n\n const recorded = this.session.updateMessage(\n pending.messageId,\n (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const content = withToolApprovalDecision(assistant.content, options);\n if (content === assistant.content) return assistant;\n return { ...assistant, content };\n },\n );\n if (!recorded) {\n throw new Error(\n `[agui] respondToToolApproval: approval \"${options.approvalId}\" is already decided`,\n );\n }\n this.notifyUpdate();\n\n const assistant = this.session.tryGetMessage(pending.messageId)?.message as\n | ThreadAssistantMessage\n | undefined;\n if (!assistant) return;\n\n // AG-UI resumes a run with one response per open interrupt, so the run\n // stays paused until every gate in the batch has been answered.\n const resume = buildToolApprovalResume(\n assistant.content,\n pending.interrupts,\n );\n if (!resume) return;\n\n await this.resumeWithResponses(pending.messageId, resume);\n }\n\n async steerAway(\n message: CreateAppendMessage,\n responses?: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n const pendingTools = this.getPendingToolCalls();\n if (pendingTools) {\n if (responses?.length) {\n throw new Error(\n \"[agui] steerAway: responses are only valid for pending interrupts\",\n );\n }\n if (this.isRunningFlag) {\n throw new Error(\"[agui] steerAway: a run is already in progress\");\n }\n this.cancelUnresolvedToolCalls(pendingTools.messageId);\n this.maybeCompleteAfterToolResults(pendingTools.messageId);\n const normalized = this.toAppendMessage(message);\n const threadMessageId = this.appendEntry(normalized);\n await this.startRun(threadMessageId, normalized.runConfig);\n return;\n }\n if (responses?.length) {\n throw new Error(\n \"[agui] steerAway: no pending interrupts on this thread\",\n );\n }\n await this.append(this.toAppendMessage(message));\n return;\n }\n\n const resume = this.resolveSteerAwayResume(pending.interrupts, responses);\n\n if (this.isRunningFlag) {\n throw new Error(\"[agui] steerAway: a run is already in progress\");\n }\n\n const normalized = this.toAppendMessage(message);\n this.clearPendingInterrupts(pending.messageId, resume);\n const threadMessageId = this.appendEntry(normalized);\n await this.startRun(threadMessageId, normalized.runConfig, {\n entries: resume,\n interruptedMessageId: pending.messageId,\n });\n }\n\n private resolveSteerAwayResume(\n interrupts: readonly AgUiInterrupt[],\n responses: readonly AgUiResumeEntry[] | undefined,\n ): AgUiResumeEntry[] {\n const responsesById = this.collectInterruptResponses(\n \"steerAway\",\n interrupts,\n responses ?? [],\n );\n return interrupts.map(\n (interrupt) =>\n responsesById.get(interrupt.id) ?? {\n interruptId: interrupt.id,\n status: \"cancelled\",\n },\n );\n }\n\n private collectInterruptResponses(\n method: \"submitInterruptResponses\" | \"steerAway\",\n interrupts: readonly AgUiInterrupt[],\n responses: readonly AgUiResumeEntry[],\n ): Map<string, AgUiResumeEntry> {\n const known = new Set(interrupts.map((interrupt) => interrupt.id));\n const responsesById = new Map<string, AgUiResumeEntry>();\n for (const entry of responses) {\n if (!entry || typeof entry.interruptId !== \"string\") {\n throw new Error(\n `[agui] ${method}: every entry must have an interruptId`,\n );\n }\n if (entry.status !== \"resolved\" && entry.status !== \"cancelled\") {\n throw new Error(\n `[agui] ${method}: invalid status \"${entry.status}\" for interrupt ${entry.interruptId}`,\n );\n }\n if (!known.has(entry.interruptId)) {\n throw new Error(\n `[agui] ${method}: unknown interrupt id ${entry.interruptId}`,\n );\n }\n if (responsesById.has(entry.interruptId)) {\n throw new Error(\n `[agui] ${method}: duplicate response for interrupt ${entry.interruptId}`,\n );\n }\n responsesById.set(entry.interruptId, entry);\n }\n return responsesById;\n }\n\n private toAppendMessage(message: CreateAppendMessage): AppendMessage {\n if (typeof message === \"string\") {\n return {\n createdAt: new Date(),\n parentId: this.session.headId,\n sourceId: null,\n runConfig: {},\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n attachments: [],\n metadata: { custom: {} },\n };\n }\n return {\n createdAt: message.createdAt ?? new Date(),\n parentId:\n message.parentId === undefined ? this.session.headId : message.parentId,\n sourceId: message.sourceId ?? null,\n role: message.role ?? \"user\",\n content: message.content,\n attachments: message.attachments ?? [],\n metadata: message.metadata ?? { custom: {} },\n runConfig: message.runConfig ?? {},\n startRun: message.startRun,\n } as AppendMessage;\n }\n\n private clearPendingInterrupts(\n messageId: string,\n resume: readonly AgUiResumeEntry[],\n ): void {\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return assistant;\n }\n const aguiMeta = assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined;\n const { interrupts: _drop, ...restAgui } = aguiMeta ?? {};\n const newCustom = { ...assistant.metadata.custom };\n if (Object.keys(restAgui).length > 0) {\n newCustom[AG_UI_METADATA_NAMESPACE] = restAgui;\n } else {\n delete newCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n ...assistant,\n content: withSettledToolApprovals(assistant.content, resume),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n metadata: { ...assistant.metadata, custom: newCustom },\n };\n });\n if (touched) {\n this.notifyUpdate();\n }\n }\n\n findMessageIdForToolCall(toolCallId: string): string | undefined {\n let fallbackMessageId: string | undefined;\n const messages = this.getMessages();\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (!message || message.role !== \"assistant\") continue;\n for (const part of iterateToolCallParts(message.content)) {\n if (part.toolCallId !== toolCallId) continue;\n if (!isResolvedToolCall(part)) {\n return message.id;\n }\n fallbackMessageId ??= message.id;\n }\n }\n return fallbackMessageId;\n }\n\n private cancelUnresolvedToolCalls(messageId: string): void {\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (isResolvedToolCall(part)) return part;\n return {\n ...part,\n result: { error: \"Tool call cancelled by user\" },\n isError: true,\n };\n });\n return { ...assistant, content };\n });\n if (updated) this.notifyUpdate();\n }\n\n addToolResult(options: AddToolResultOptions): void {\n // Core's ToolInvocationTracker resolves a nested call to the nested\n // subagent message's id, which is not a session message; re-anchor on the\n // top-level message that owns the tree so the update can land.\n const sessionMessageId = this.session.tryGetMessage(options.messageId)\n ? options.messageId\n : this.findMessageIdForToolCall(options.toolCallId);\n if (sessionMessageId === undefined) return;\n const updated = this.session.updateMessage(sessionMessageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== options.toolCallId) return part;\n matchedToolCall = true;\n // artifact and modelContent are optional; only override when supplied\n // so a later result that omits them keeps a stored value, and\n // emitToolResult can forward the model-facing content to the agent.\n return {\n ...part,\n result: options.result,\n isError: options.isError,\n ...(options.artifact !== undefined && { artifact: options.artifact }),\n ...(options.modelContent !== undefined && {\n modelContent: options.modelContent,\n }),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeResumeAfterToolResults(sessionMessageId);\n }\n\n async recordToolInteraction(options: {\n messageId: string;\n toolCallId: string;\n interaction: Unstable_ToolInteraction;\n }): Promise<void> {\n const sessionMessageId = this.session.tryGetMessage(options.messageId)\n ? options.messageId\n : this.findMessageIdForToolCall(options.toolCallId);\n if (sessionMessageId === undefined) {\n throw new Error(\n `[agui] recordToolInteraction: message \"${options.messageId}\" was not found`,\n );\n }\n\n const item = this.session.tryGetMessage(sessionMessageId);\n if (!item) {\n throw new Error(\n `[agui] recordToolInteraction: message \"${sessionMessageId}\" was not found`,\n );\n }\n\n let recorded = false;\n const updated = this.session.updateMessage(sessionMessageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== options.toolCallId) return part;\n recorded = true;\n return {\n ...part,\n unstable_interactions: appendToolInteraction(\n part.unstable_interactions,\n options.interaction,\n ),\n };\n });\n return recorded ? { ...assistant, content } : assistant;\n });\n if (!recorded || !updated) {\n throw new Error(\n `[agui] recordToolInteraction: tool call \"${options.toolCallId}\" was not found on message \"${options.messageId}\"`,\n );\n }\n\n this.notifyUpdate();\n\n const message = this.session.tryGetMessage(sessionMessageId)?.message;\n const history = this.history;\n if (\n !message ||\n !history?.update ||\n !this.isPersistableStatus(message.status)\n ) {\n return;\n }\n\n await this.chainHistoryWrite(sessionMessageId, () =>\n history.update!({ parentId: item.parentId, message }),\n );\n }\n\n sendA2uiAction(action: Record<string, unknown>): void {\n this.assertNoPendingInterrupts();\n this.maybeAutoCancelPendingToolCalls();\n const parentId = this.session.headId;\n if (parentId === null) {\n this.logger.debug(\n \"[agui] sendA2uiAction: no messages to resume, dropping action\",\n );\n return;\n }\n\n const userAction = { ...action };\n delete userAction.type;\n if (!(\"timestamp\" in userAction)) {\n userAction.timestamp = new Date().toISOString();\n }\n this.pendingA2uiAction = userAction;\n\n const owner = this.abortController;\n if (owner) {\n this.pendingA2uiResumeOwner = owner;\n return;\n }\n this.startResumeRun(parentId);\n }\n\n // The continuation fires whether the frontend result lands before\n // RUN_FINISHED (the status flips to requires-action only later, while the\n // run is still draining) or after it.\n private maybeResumeAfterToolResults(messageId: string): void {\n if (!this.maybeCompleteAfterToolResults(messageId)) return;\n\n const owner = this.abortController;\n if (owner) {\n // A run is still draining (RUN_FINISHED arrived but the stream has not\n // closed). Defer until startRun's tail so we never start two runs.\n this.pendingResume = { owner, messageId };\n return;\n }\n this.startResumeRun(messageId);\n }\n\n private maybeCompleteAfterToolResults(messageId: string): boolean {\n const message = this.session.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return false;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"tool-calls\"\n ) {\n return false;\n }\n let allResolved = true;\n for (const part of iterateToolCallParts(assistant.content)) {\n if (!isResolvedToolCall(part)) {\n allResolved = false;\n break;\n }\n }\n if (!allResolved) return false;\n\n const updated = this.session.updateMessage(messageId, (current) =>\n current.role === \"assistant\"\n ? {\n ...(current as ThreadAssistantMessage),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n }\n : current,\n );\n if (!updated) return false;\n this.notifyUpdate();\n this.persistAssistantHistory(messageId);\n return true;\n }\n\n private startResumeRun(messageId: string): void {\n void this.startRun(messageId, this.lastRunConfig).catch((error) => {\n this.reportError(error);\n });\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n messages = messages.map((message) => {\n if (message.role === \"system\" || message.metadata.modality !== undefined)\n return message;\n const modality = this.session.tryGetMessage(message.id)?.message.metadata\n .modality;\n if (modality === undefined) return message;\n return {\n ...message,\n metadata: { ...message.metadata, modality },\n } as ThreadMessage;\n });\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n this.assistantHistoryParents.clear();\n\n if (messages.length === 0) {\n this.session.clear();\n } else {\n let expectedParentId: string | null = null;\n let lastAppliedId: string | null = null;\n let hardReplace = false;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n const existing = this.session.tryGetMessage(message.id);\n if (existing && existing.parentId !== expectedParentId) {\n hardReplace = true;\n break;\n }\n this.session.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n\n if (hardReplace) {\n this.session.clear();\n expectedParentId = null;\n lastAppliedId = null;\n seen.clear();\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n this.session.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n }\n\n this.session.resetHead(lastAppliedId);\n }\n\n this.snapshotHistoryIds.clear();\n for (const { message } of this.getMessageRepository().messages) {\n this.snapshotHistoryIds.add(message.id);\n }\n // MESSAGES_SNAPSHOT re-appends the active assistant, so a parked\n // continuation whose target survived the snapshot is still answerable.\n // Membership is the head branch, not the repository: a soft merge leaves\n // the messages it dropped behind as off-branch nodes.\n const resumeTarget = this.pendingResume?.messageId;\n if (\n resumeTarget !== undefined &&\n !this.session.getMessages().some((message) => message.id === resumeTarget)\n ) {\n this.pendingResume = null;\n }\n this.notifyUpdate();\n }\n\n loadExternalState(state: ReadonlyJSONValue): void {\n this.stateSnapshot = state;\n this.notifyUpdate();\n }\n\n setState(\n next:\n | ReadonlyJSONValue\n | ((prev: ReadonlyJSONValue | undefined) => ReadonlyJSONValue),\n ): void {\n this.stateSnapshot =\n typeof next === \"function\" ? next(this.stateSnapshot) : next;\n this.notifyUpdate();\n }\n\n resetState(): void {\n this.stateSnapshot = undefined;\n this.notifyUpdate();\n }\n\n resetThreadState(): void {\n const controller = this.abortController;\n const activeRunAgent = this.activeRunAgent;\n\n this.stateSnapshot = undefined;\n this.pendingResume = null;\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n\n if (controller) {\n this.abortController = null;\n this.activeRunAgent = null;\n this.setRunning(false);\n try {\n (activeRunAgent ?? this.agent).abortRun();\n } catch (error) {\n this.logger.error?.(\"[agui] agent abortRun failed\", error);\n } finally {\n controller.abort();\n }\n } else {\n this.notifyUpdate();\n }\n }\n\n private async startRun(\n parentId: string | null,\n runConfig?: RunConfig,\n resume?: ResumeDispatch,\n resumeStream?: ResumeStream,\n ): Promise<void> {\n // A default AG-UI run supersedes the active run; the hook's opt-in message\n // queue serializes sends instead. append supersedes earlier, before it links\n // its message; this covers the entry points that start a run without one.\n if (!this.supersedeActiveRun()) return;\n\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n const parent =\n parentId === null ? undefined : this.session.tryGetMessage(parentId);\n const shouldEagerlyInsertAssistant =\n parentId !== null &&\n parent !== undefined &&\n parentId !== this.session.headId;\n const historicalMessages = [\n ...(shouldEagerlyInsertAssistant\n ? (this.session.tryGetMessages(parentId) ?? this.session.getMessages())\n : this.session.getMessages()),\n ];\n const runStartMessageIds = new Set(\n this.getMessageRepository().messages.map(({ message }) => message.id),\n );\n\n let pendingError: Error | null = null;\n const assistantParentId = parent ? parentId : this.session.headId;\n let assistantMessageId: string | undefined;\n // A snapshot the preserve gate declines still evicts the in-flight\n // assistant; recreating under the cached id on the next content-bearing\n // emit keeps both the stream and the message identity. Status-only emits,\n // data-only content, and off-branch server-id collisions must not\n // recreate: the snapshot already carries this turn's assistant, so\n // resurrecting for custom-event data would leave a trailing data-only\n // duplicate.\n let assistantCollided = false;\n const ensureAssistant = (allowRecreate = false): string => {\n const cached = assistantMessageId;\n if (cached !== undefined && this.session.tryGetMessage(cached))\n return cached;\n if (cached !== undefined && (assistantCollided || !allowRecreate)) {\n return cached;\n }\n const repositoryHeadId = this.session.headId;\n const shouldUseSelectedParent =\n cached === undefined ||\n (shouldEagerlyInsertAssistant &&\n (repositoryHeadId === null ||\n runStartMessageIds.has(repositoryHeadId)));\n // Branch runs keep their selected parent unless the snapshot advanced to\n // a message introduced during this run.\n const parentId =\n shouldUseSelectedParent &&\n assistantParentId &&\n this.session.hasMessage(assistantParentId)\n ? assistantParentId\n : repositoryHeadId;\n const created = this.insertAssistantPlaceholder(parentId, cached);\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, parentId);\n return created;\n };\n\n if (shouldEagerlyInsertAssistant) ensureAssistant();\n\n const applyUpdate = (update: ChatModelRunResult) => {\n const hasStreamContent =\n Array.isArray(update.content) &&\n update.content.some((part) => part.type !== \"data\");\n const resolved = this.updateAssistantMessage(\n ensureAssistant(hasStreamContent),\n update,\n );\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n };\n\n const adoptServerMessageId = (\n serverId: string,\n startNewMessage: boolean,\n ) => {\n if (startNewMessage && assistantMessageId !== undefined) {\n applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n const previousId = assistantMessageId;\n assistantMessageId = undefined;\n if (this.session.tryGetMessage(previousId)) {\n const created = this.insertAssistantPlaceholder(previousId);\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, previousId);\n }\n }\n const placeholder = ensureAssistant(true);\n if (placeholder === serverId) return;\n const reassigned = this.reassignAssistantId(placeholder, serverId);\n // A collision drops the placeholder before revealing the existing\n // server message as the current head. Only messages introduced during\n // this run can replace the placeholder; regeneration must not rewrite\n // a previous branch when the server incorrectly reuses its id.\n const adoptsVisibleCollision =\n !reassigned &&\n !runStartMessageIds.has(serverId) &&\n this.session.headId === serverId;\n if (reassigned || adoptsVisibleCollision) {\n assistantMessageId = serverId;\n if (adoptsVisibleCollision) {\n const parentId =\n this.session.tryGetMessage(serverId)?.parentId ?? null;\n this.markPendingAssistantHistory(serverId, parentId);\n }\n } else {\n assistantCollided = true;\n }\n };\n\n const abortController = new AbortController();\n const abortSignal = abortController.signal;\n const aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: applyUpdate,\n onServerMessageId: (serverId) => {\n adoptServerMessageId(serverId, false);\n },\n onTextMessageStart: (serverId) => adoptServerMessageId(serverId, true),\n });\n let runFinished = false;\n const dispatch = (event: AgUiEvent) => {\n if (this.abortController !== abortController) return;\n if (event.type === \"RUN_FINISHED\") runFinished = true;\n const nextAssistantMessageId = this.handleEvent(\n aggregator,\n event,\n assistantMessageId,\n );\n if (event.type === \"MESSAGES_SNAPSHOT\") {\n assistantMessageId = nextAssistantMessageId;\n }\n };\n\n this.abortController = abortController;\n const runAgentInstance = this.agent;\n this.activeRunAgent = runAgentInstance;\n\n let cancelRun = () => dispatch({ type: \"RUN_CANCELLED\" });\n abortSignal.addEventListener(\n \"abort\",\n () => {\n cancelRun();\n this.finishRun(abortController);\n invokeRuntimeCallback(\"onCancel\", this.onCancel);\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n try {\n if (resumeStream) {\n // Cancel flips only the status; an aggregator RUN_CANCELLED would emit an empty snapshot and wipe the replayed content.\n cancelRun = () => {\n const current =\n assistantMessageId === undefined\n ? undefined\n : this.session.tryGetMessage(assistantMessageId)?.message;\n if (current?.status?.type === \"complete\") return;\n applyUpdate({ status: { type: \"incomplete\", reason: \"cancelled\" } });\n };\n pendingError =\n (await this.consumeResumeStream(resumeStream, {\n runConfig: normalizedRunConfig,\n threadId: this.agent.threadId || \"main\",\n parentId: assistantParentId,\n historicalMessages,\n abortSignal,\n ensureAssistant,\n applyUpdate,\n getAssistantMessageId: () => assistantMessageId,\n })) ?? null;\n } else {\n const runId = generateId();\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\n const subscriber = createAgUiSubscriber({\n dispatch,\n runId,\n logger: this.logger,\n onRunFailed: (error) => {\n if (abortSignal.aborted) return;\n pendingError = error;\n invokeRuntimeCallback(\"onError\", this.onError, error);\n },\n });\n try {\n (runAgentInstance as any).messages = input.messages;\n (runAgentInstance as any).threadId = input.threadId;\n (runAgentInstance as any).state = input.state ?? null;\n } catch {\n // ignore\n }\n const runAgent: RunAgentWithRunOptions =\n runAgentInstance.runAgent.bind(runAgentInstance);\n await runAgent(input, subscriber, { signal: abortSignal });\n }\n } catch (error) {\n // HttpAgent rethrows a failure it already passed to the subscriber's\n // onRunFailed, which reported it.\n if (!abortSignal.aborted && !pendingError) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (!runFinished) dispatch({ type: \"RUN_ERROR\", message: err.message });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n pendingError = err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (pendingError) {\n const err = pendingError;\n this.reportedErrors.add(err);\n this.clearDeferredContinuations(abortController);\n throw err;\n }\n\n // A tool result that landed before the run settled deferred its\n // continuation here so a second run never overlaps the first.\n if (this.pendingResume?.owner === abortController) {\n const { messageId } = this.pendingResume;\n this.pendingResume = null;\n if (!abortSignal.aborted) {\n this.startResumeRun(messageId);\n }\n }\n\n if (this.pendingA2uiResumeOwner === abortController) {\n this.pendingA2uiResumeOwner = null;\n if (!abortSignal.aborted && this.pendingA2uiAction !== undefined) {\n if (this.getPendingInterrupts()) {\n this.pendingA2uiAction = undefined;\n this.logger.debug(\n \"[agui] sendA2uiAction: pending interrupts, dropping action\",\n );\n return;\n }\n this.maybeAutoCancelPendingToolCalls();\n const parentId = this.session.headId;\n if (parentId !== null) {\n this.startResumeRun(parentId);\n } else {\n this.pendingA2uiAction = undefined;\n this.logger.debug(\n \"[agui] sendA2uiAction: no messages to resume, dropping action\",\n );\n }\n } else {\n this.pendingA2uiAction = undefined;\n }\n }\n }\n\n // Replays a persisted run's snapshots into the existing assistant message, bypassing agent.runAgent so it is not re-invoked.\n private async consumeResumeStream(\n stream: ResumeStream,\n ctx: {\n runConfig: RunConfig;\n threadId: string;\n parentId: string | null;\n historicalMessages: readonly ThreadMessage[];\n abortSignal: AbortSignal;\n ensureAssistant: () => string;\n applyUpdate: (update: ChatModelRunResult) => void;\n getAssistantMessageId: () => string | undefined;\n },\n ): Promise<Error | undefined> {\n this.pendingA2uiAction = undefined;\n this.pendingA2uiResumeOwner = null;\n const assistantId = ctx.ensureAssistant();\n const currentId = () => ctx.getAssistantMessageId() ?? assistantId;\n const options: ChatModelRunOptions = {\n messages: ctx.historicalMessages,\n runConfig: ctx.runConfig,\n abortSignal: ctx.abortSignal,\n context: this.runtime?.thread.getModelContext() ?? {},\n unstable_assistantMessageId: assistantId,\n unstable_threadId: ctx.threadId,\n unstable_parentId: ctx.parentId,\n unstable_getMessage: () => {\n const message = this.session.tryGetMessage(currentId())?.message;\n if (!message) {\n throw new Error(\n \"[agui] resume stream requested the assistant message before it existed\",\n );\n }\n return message;\n },\n };\n\n try {\n for await (const result of stream(options)) {\n if (ctx.abortSignal.aborted) return undefined;\n ctx.applyUpdate(result);\n }\n } catch (error) {\n if (ctx.abortSignal.aborted) return undefined;\n const err = error instanceof Error ? error : new Error(String(error));\n ctx.applyUpdate({\n status: { type: \"incomplete\", reason: \"error\", error: err.message },\n });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n return err;\n }\n\n if (ctx.abortSignal.aborted) return undefined;\n const current = this.session.tryGetMessage(currentId())?.message;\n if (!current || current.status?.type === \"running\") {\n ctx.applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n }\n return undefined;\n }\n\n private buildRunInput(\n runId: string,\n runConfig: RunConfig | undefined,\n historyMessages: readonly ThreadMessage[] | undefined,\n resume?: ResumeDispatch,\n ) {\n const threadId = this.agent.threadId || \"main\";\n const messages = toAgUiMessages(\n this.selectRunMessages(\n historyMessages ?? this.session.getMessages(),\n resume,\n ),\n );\n const context = this.runtime?.thread.getModelContext();\n const input = {\n threadId,\n runId,\n state: this.stateSnapshot ?? null,\n messages,\n tools: toAgUiTools(context?.tools),\n context: context?.system\n ? [{ description: \"system\", value: context.system }]\n : [],\n forwardedProps: {\n ...(context?.callSettings ?? {}),\n ...(context?.config ?? {}),\n ...(runConfig?.custom ? { runConfig: runConfig.custom } : {}),\n ...(this.pendingA2uiAction\n ? { a2uiAction: { userAction: this.pendingA2uiAction } }\n : {}),\n },\n ...(resume !== undefined ? { resume: resume.entries } : {}),\n };\n this.pendingA2uiAction = undefined;\n return input;\n }\n\n /**\n * An anchor the thread no longer carries falls back to the whole transcript.\n * The anchor is missing exactly when a snapshot import replaced the messages\n * this resume was raised against, and a host that expects a delta tolerates\n * being told more than it knows, while one rebuilding the run from the\n * transcript cannot recover from being told less.\n */\n private selectRunMessages(\n messages: readonly ThreadMessage[],\n resume: ResumeDispatch | undefined,\n ): readonly ThreadMessage[] {\n if (resume === undefined || this.resumeTranscript !== \"appended\")\n return messages;\n const anchor = messages.findIndex(\n (message) => message.id === resume.interruptedMessageId,\n );\n if (anchor === -1) return messages;\n return messages.slice(anchor + 1);\n }\n\n private clearDeferredContinuations(owner: AbortController): void {\n if (this.pendingResume?.owner === owner) {\n this.pendingResume = null;\n }\n if (this.pendingA2uiResumeOwner === owner) {\n this.pendingA2uiResumeOwner = null;\n this.pendingA2uiAction = undefined;\n }\n }\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController !== controller) return;\n this.abortController = null;\n this.activeRunAgent = null;\n this.setRunning(false);\n }\n\n private insertAssistantPlaceholder(\n parentId: string | null,\n id: string = generateOptimisticId(),\n ): string {\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.stateSnapshot ?? null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n isOptimistic: isOptimisticId(id),\n custom: {},\n },\n };\n this.session.addOrUpdateMessage(parentId ?? this.session.headId, assistant);\n this.session.switchToBranch(id);\n this.notifyUpdate();\n return id;\n }\n\n private reassignAssistantId(oldId: string, newId: string): boolean {\n if (oldId === newId) return true;\n const oldItem = this.session.tryGetMessage(oldId);\n if (!oldItem) return false;\n\n const collidesWithExisting = this.session.hasMessage(newId);\n\n if (collidesWithExisting) {\n this.logger.debug?.(\n \"[agui] reassignAssistantId: server id already present in messages or repository, dropping placeholder\",\n { oldId, newId },\n );\n this.session.deleteMessage(oldId, oldItem.parentId ?? null);\n } else {\n const { isOptimistic: _, ...metadata } = oldItem.message.metadata;\n this.session.addOrUpdateMessage(oldItem.parentId, {\n ...oldItem.message,\n id: newId,\n metadata,\n } as ThreadMessage);\n this.session.switchToBranch(newId);\n this.session.tryDeleteMessage(oldId);\n }\n\n const pendingParent = this.assistantHistoryParents.get(oldId);\n if (pendingParent !== undefined) {\n this.assistantHistoryParents.delete(oldId);\n if (!collidesWithExisting && !this.assistantHistoryParents.has(newId)) {\n this.assistantHistoryParents.set(newId, pendingParent);\n }\n }\n\n for (const ids of [this.snapshotHistoryIds, this.persistedHistoryIds]) {\n if (ids.has(oldId)) {\n ids.delete(oldId);\n if (!collidesWithExisting) {\n ids.add(newId);\n }\n }\n }\n\n // An in-flight write completes under the id it was started with, so the\n // rename moves the chain entry and transfers the completion mark; without\n // this the resolve records the dead id and the live one appends again.\n const pendingWrite = this.historyWrites.get(oldId);\n if (pendingWrite) {\n this.historyWrites.delete(oldId);\n if (!collidesWithExisting) {\n this.historyWrites.set(newId, pendingWrite);\n const settle = () => {\n if (this.historyWrites.get(newId) === pendingWrite) {\n this.historyWrites.delete(newId);\n }\n };\n void pendingWrite.then(() => {\n this.persistedHistoryIds.delete(oldId);\n this.persistedHistoryIds.add(newId);\n settle();\n }, settle);\n }\n }\n\n this.notifyUpdate();\n return !collidesWithExisting;\n }\n\n private updateAssistantMessage(\n messageId: string,\n update: ChatModelRunResult,\n ): string {\n let latestStatus: MessageStatus | undefined;\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const metadata = update.metadata\n ? this.mergeAssistantMetadata(assistant.metadata, update.metadata)\n : assistant.metadata;\n latestStatus = update.status ?? assistant.status;\n const content =\n update.content !== undefined\n ? this.preserveToolResults(\n assistant.content,\n update.content as ThreadAssistantMessage[\"content\"],\n )\n : assistant.content;\n return {\n ...assistant,\n content,\n status: latestStatus,\n metadata,\n };\n });\n if (!touched) return messageId;\n\n let resolvedMessageId = messageId;\n const isSettled =\n latestStatus !== undefined && latestStatus.type !== \"running\";\n if (isSettled && isOptimisticId(messageId)) {\n const stableId = generateId();\n this.reassignAssistantId(messageId, stableId);\n resolvedMessageId = stableId;\n } else {\n this.notifyUpdate();\n }\n if (this.isPersistableStatus(latestStatus)) {\n this.persistAssistantHistory(resolvedMessageId);\n }\n this.maybeResumeAfterToolResults(resolvedMessageId);\n return resolvedMessageId;\n }\n\n // The RunAggregator rebuilds the assistant content from stream events only,\n // so a fresh snapshot omits results injected via addToolResult (frontend tool\n // execution). Carry those results forward so the aggregator never clobbers\n // them. Results are only ever added in this flow, so preserving is safe.\n private preserveToolResults(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const preserved = new Map<string, ToolCallMessagePart>();\n for (const part of iterateToolCallParts(previous)) {\n if (isResolvedToolCall(part)) {\n preserved.set(part.toolCallId, part);\n }\n }\n if (preserved.size === 0) {\n return this.preserveToolInteractions(previous, next);\n }\n\n const { content: merged, changed } = mapToolCallPartsDeep(next, (part) => {\n const prior = preserved.get(part.toolCallId);\n if (!prior) return part;\n if (!isResolvedToolCall(part) && isResolvedToolCall(prior)) {\n return {\n ...part,\n result: prior.result,\n ...(prior.artifact !== undefined ? { artifact: prior.artifact } : {}),\n ...(prior.isError !== undefined ? { isError: prior.isError } : {}),\n ...(prior.modelContent !== undefined\n ? { modelContent: prior.modelContent }\n : {}),\n };\n }\n return part;\n });\n return this.preserveToolInteractions(previous, changed ? merged : next);\n }\n\n private preserveToolInteractions(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const interactions = new Map<\n string,\n NonNullable<ToolCallMessagePart[\"unstable_interactions\"]>\n >();\n for (const part of iterateToolCallParts(previous)) {\n if (part.unstable_interactions !== undefined) {\n interactions.set(part.toolCallId, part.unstable_interactions);\n }\n }\n if (interactions.size === 0) return next;\n\n const { content, changed } = mapToolCallPartsDeep(next, (part) => {\n const interaction = interactions.get(part.toolCallId);\n if (interaction === undefined || part.unstable_interactions !== undefined)\n return part;\n return { ...part, unstable_interactions: interaction };\n });\n return changed ? content : next;\n }\n\n private mergeAssistantMetadata(\n current: ThreadAssistantMessage[\"metadata\"],\n incoming: NonNullable<ChatModelRunResult[\"metadata\"]>,\n ): ThreadAssistantMessage[\"metadata\"] {\n const annotations = incoming.unstable_annotations\n ? [...current.unstable_annotations, ...incoming.unstable_annotations]\n : current.unstable_annotations;\n const data = incoming.unstable_data\n ? [...current.unstable_data, ...incoming.unstable_data]\n : current.unstable_data;\n const steps = incoming.steps\n ? [...current.steps, ...incoming.steps]\n : current.steps;\n return {\n unstable_state:\n incoming.unstable_state !== undefined\n ? incoming.unstable_state\n : current.unstable_state,\n unstable_annotations: annotations,\n unstable_data: data,\n steps,\n ...(current.isOptimistic ? { isOptimistic: true } : {}),\n ...(incoming.timing ? { timing: incoming.timing } : {}),\n custom: incoming.custom\n ? mergeAgUiNamespace(current.custom, incoming.custom)\n : current.custom,\n };\n }\n\n private handleEvent(\n aggregator: RunAggregator,\n event: AgUiEvent,\n activeAssistantId: string | undefined,\n ): string | undefined {\n switch (event.type) {\n case \"STATE_SNAPSHOT\": {\n this.stateSnapshot = event.snapshot as ReadonlyJSONValue;\n this.updateActiveAssistantState(activeAssistantId);\n break;\n }\n case \"STATE_DELTA\": {\n if (event.delta.length === 0) break;\n try {\n const state = this.stateSnapshot ?? {};\n const result = jsonpatch.applyPatch(\n state,\n event.delta as Operation[],\n /* validateOperation */ true,\n /* mutateDocument */ false,\n );\n this.stateSnapshot = result.newDocument as ReadonlyJSONValue;\n this.updateActiveAssistantState(activeAssistantId);\n } catch (error) {\n this.logger.error?.(\"[agui] failed to apply state delta\", error);\n }\n break;\n }\n case \"MESSAGES_SNAPSHOT\": {\n const previousHeadId = this.session.headId;\n const activeAssistant =\n activeAssistantId === undefined\n ? undefined\n : this.session.tryGetMessage(activeAssistantId)?.message;\n const hasActiveText =\n activeAssistant?.role === \"assistant\" &&\n activeAssistant.content.some((part) => part.type === \"text\");\n this.importMessagesSnapshot(event.messages, activeAssistantId);\n const headId = this.session.headId;\n if (hasActiveText && headId !== previousHeadId) {\n const head =\n headId === null\n ? undefined\n : this.session.tryGetMessage(headId)?.message;\n activeAssistantId =\n head?.role === \"assistant\" ? (headId ?? undefined) : undefined;\n }\n this.updateActiveAssistantState(activeAssistantId);\n break;\n }\n case \"TOOL_CALL_RESULT\": {\n if (!aggregator.hasToolCall(event.toolCallId)) {\n const messageId = this.findMessageIdForToolCall(event.toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunToolResult(messageId, event);\n break;\n }\n }\n aggregator.handle(event);\n break;\n }\n case \"ACTIVITY_SNAPSHOT\": {\n const toolCallId = event.content[\"toolCallId\"];\n if (\n event.activityType === MCP_APPS_ACTIVITY_TYPE &&\n typeof toolCallId === \"string\" &&\n !aggregator.hasToolCall(toolCallId)\n ) {\n const messageId = this.findMessageIdForToolCall(toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunActivitySnapshot(messageId, toolCallId, event);\n break;\n }\n }\n aggregator.handle(event);\n break;\n }\n default:\n aggregator.handle(event);\n }\n return activeAssistantId;\n }\n\n private updateActiveAssistantState(messageId: string | undefined): void {\n const current =\n messageId === undefined\n ? undefined\n : this.session.tryGetMessage(messageId)?.message;\n const activeAssistantId =\n current?.role === \"assistant\" && this.session.headId === messageId\n ? messageId\n : this.session.headId;\n if (activeAssistantId !== null && activeAssistantId !== undefined) {\n this.session.updateMessage(activeAssistantId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n return {\n ...assistant,\n metadata: {\n ...assistant.metadata,\n unstable_state: this.stateSnapshot ?? null,\n },\n };\n });\n }\n this.notifyUpdate();\n }\n\n private applyCrossRunToolResult(\n messageId: string,\n event: Extract<AgUiEvent, { type: \"TOOL_CALL_RESULT\" }>,\n ): void {\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n const mcpAppUri = readMcpAppResourceUri(event.mcpResult?._meta);\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== event.toolCallId) return part;\n matchedToolCall = true;\n // An applied activity snapshot owns part.result; a later result only\n // fills what is missing, mirroring the aggregator's finishToolCall.\n // The aggregator's flag is set only when the snapshot carried a\n // result, so app presence alone is not enough: the current result\n // must be CallToolResult-shaped (a required content array).\n const snapshotResultApplied =\n part.mcp?.app !== undefined &&\n isPlainObject(part.result) &&\n Array.isArray((part.result as Record<string, unknown>)[\"content\"]);\n if (snapshotResultApplied) {\n return {\n ...part,\n ...(part.modelContent === undefined && event.content\n ? {\n modelContent: [\n { type: \"text\" as const, text: event.content },\n ],\n }\n : {}),\n ...(part.isError === undefined\n ? typeof event.mcpResult?.isError === \"boolean\"\n ? { isError: event.mcpResult.isError }\n : event.role === \"tool\"\n ? { isError: false }\n : {}\n : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n }\n return {\n ...part,\n result: (event.mcpResult ??\n tryParseJSON(event.content ?? \"\")) as ReadonlyJSONValue,\n ...(event.mcpResult !== undefined\n ? { modelContent: [{ type: \"text\" as const, text: event.content }] }\n : {}),\n ...(typeof event.mcpResult?.isError === \"boolean\"\n ? { isError: event.mcpResult.isError }\n : event.role === \"tool\"\n ? { isError: false }\n : {}),\n ...(part.mcp === undefined && mcpAppUri !== undefined\n ? { mcp: { app: { resourceUri: mcpAppUri } } }\n : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n // Not maybeResumeAfterToolResults: the delivering run is already in\n // flight, and a resume from the owner would reset the head past it.\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private applyCrossRunActivitySnapshot(\n messageId: string,\n toolCallId: string,\n event: Extract<AgUiEvent, { type: \"ACTIVITY_SNAPSHOT\" }>,\n ): void {\n const resourceUri = event.content[\"resourceUri\"];\n if (typeof resourceUri !== \"string\" || !isMcpAppUri(resourceUri)) return;\n const serverId = event.content[\"serverId\"];\n const serverHash = event.content[\"serverHash\"];\n const appServerId =\n typeof serverId === \"string\" && serverId.length > 0\n ? serverId\n : typeof serverHash === \"string\" && serverHash.length > 0\n ? serverHash\n : undefined;\n const result = event.content[\"result\"];\n const updated = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const { content } = mapToolCallPartsDeep(assistant.content, (part) => {\n if (part.toolCallId !== toolCallId) return part;\n matchedToolCall = true;\n return {\n ...part,\n mcp: {\n app: {\n resourceUri,\n ...(appServerId ? { serverId: appServerId } : {}),\n },\n },\n ...(isPlainObject(result)\n ? {\n ...(part.result !== undefined && part.modelContent === undefined\n ? {\n modelContent: [\n {\n type: \"text\" as const,\n text:\n typeof part.result === \"string\"\n ? part.result\n : JSON.stringify(part.result),\n },\n ],\n }\n : {}),\n result: result as ReadonlyJSONValue,\n isError: result[\"isError\"] === true,\n }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private importMessagesSnapshot(\n rawMessages: readonly unknown[],\n activeAssistantId: string | undefined,\n ) {\n try {\n const activeMessage = activeAssistantId\n ? this.session.tryGetMessage(activeAssistantId)?.message\n : undefined;\n const activeAssistant =\n activeMessage?.role === \"assistant\" ? activeMessage : undefined;\n const normalized = fromAgUiMessages(rawMessages, {\n showThinking: this.showThinking,\n });\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n const convertedMessage = fromThreadMessageLike(\n message,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n const existing = this.session.tryGetMessage(\n convertedMessage.id,\n )?.message;\n if (\n convertedMessage.role === \"assistant\" &&\n existing?.role === \"assistant\"\n ) {\n converted.push({\n ...convertedMessage,\n content: this.preserveToolInteractions(\n existing.content,\n convertedMessage.content,\n ),\n });\n } else {\n converted.push(convertedMessage);\n }\n } catch (error) {\n this.logger.error?.(\n \"[agui] failed to import message from snapshot\",\n error,\n );\n }\n }\n const snapshotContainsActiveAssistant = converted.some(\n (message) => message.id === activeAssistant?.id,\n );\n const preservesActiveAssistant =\n activeAssistant !== undefined &&\n !snapshotContainsActiveAssistant &&\n (activeAssistant.metadata.isOptimistic !== true ||\n converted.at(-1)?.role !== \"assistant\");\n if (preservesActiveAssistant) {\n converted.push(activeAssistant);\n }\n this.applyExternalMessages(converted);\n if (activeAssistant !== undefined) {\n const activeItem = this.session.tryGetMessage(activeAssistant.id);\n if (activeItem) {\n if (preservesActiveAssistant) {\n this.snapshotHistoryIds.delete(activeAssistant.id);\n }\n this.markPendingAssistantHistory(\n activeAssistant.id,\n activeItem.parentId,\n );\n }\n }\n } catch (error) {\n this.logger.error?.(\"[agui] failed to import messages snapshot\", error);\n }\n }\n\n private toThreadMessage(message: AppendMessage): ThreadMessage {\n return fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n }\n\n private isTerminalStatus(status?: MessageStatus): boolean {\n return status?.type === \"complete\" || status?.type === \"incomplete\";\n }\n\n private isPersistableStatus(status?: MessageStatus): boolean {\n if (this.isTerminalStatus(status)) return true;\n return status?.type === \"requires-action\" && status.reason === \"interrupt\";\n }\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n void this.appendHistoryItem(parentId, message)?.catch((error) => {\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n });\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n const history = this.history;\n if (!history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.session.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return;\n if (!this.isPersistableStatus(message.status)) return;\n const wasPersisted = this.persistedHistoryIds.has(messageId);\n const update = history.update;\n const shouldUpdate =\n update !== undefined &&\n (wasPersisted || this.snapshotHistoryIds.has(messageId));\n\n if (shouldUpdate) {\n const write = this.chainHistoryWrite(messageId, () =>\n update.call(history, { parentId, message }),\n );\n this.assistantHistoryParents.delete(messageId);\n void write.then(\n () => {\n this.persistedHistoryIds.add(messageId);\n },\n (error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, parentId);\n }\n this.logger.error?.(\"[agui] failed to update history entry\", error);\n },\n );\n return;\n }\n\n if (wasPersisted) {\n this.assistantHistoryParents.delete(messageId);\n return;\n }\n\n const write = this.appendHistoryItem(parentId, message);\n if (!write) return;\n this.assistantHistoryParents.delete(messageId);\n void write.then(\n () => {},\n (error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, parentId);\n }\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n },\n );\n }\n\n private appendHistoryItem(\n parentId: string | null,\n message: ThreadMessage,\n ): Promise<void> | undefined {\n if (!this.history || this.persistedHistoryIds.has(message.id)) return;\n const pending = this.historyWrites.get(message.id);\n if (pending) return pending;\n\n const append = this.history.append.bind(this.history);\n const write = this.chainHistoryWrite(message.id, () =>\n append({ parentId, message }),\n );\n void write.then(\n () => {\n this.persistedHistoryIds.add(message.id);\n },\n () => {},\n );\n return write;\n }\n\n private chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const pending = this.historyWrites.get(id);\n let next: Promise<void>;\n if (pending) {\n next = pending.then(write, write);\n } else {\n try {\n next = Promise.resolve(write());\n } catch (error) {\n next = Promise.reject(error);\n }\n }\n this.historyWrites.set(id, next);\n void next.then(\n () => {\n if (this.historyWrites.get(id) === next) {\n this.historyWrites.delete(id);\n }\n },\n () => {\n if (this.historyWrites.get(id) === next) {\n this.historyWrites.delete(id);\n }\n },\n );\n return next;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/subscriber.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAiB;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,qBAAkB;AAExC,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE3C,KAAK,UAAU,GAAG;IAChB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChD,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,yBAAyB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAClE,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACxE,iCAAiC,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1E,6BAA6B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,4BAA4B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACrE,8BAA8B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,0BAA0B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnE,8BAA8B,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1D,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACtD,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnD,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/D,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACxD,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAC;CACnD,CAAC;AAgCF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,iBAAiB,KACzB,
|
|
1
|
+
{"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/subscriber.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscriber.js","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"sourcesContent":["\"use client\";\n\nimport type { AgUiEvent } from \"../types\";\nimport { parseAgUiEvent } from \"../event-parser\";\nimport type { Logger } from \"../logger\";\n\ntype Dispatch = (event: AgUiEvent) => void;\n\ntype Subscriber = {\n onEvent?: (payload: { event: unknown }) => void;\n onTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onTextMessageChunkEvent?: (payload: { event: unknown }) => void;\n onThinkingStartEvent?: (payload: { event: unknown }) => void;\n onThinkingEndEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningStartEvent?: (payload: { event: unknown }) => void;\n onReasoningEndEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageStartEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageContentEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningEncryptedValueEvent?: (payload: { event: unknown }) => void;\n onToolCallStartEvent?: (payload: { event: unknown }) => void;\n onToolCallArgsEvent?: (payload: { event: unknown }) => void;\n onToolCallEndEvent?: (payload: { event: unknown }) => void;\n onToolCallChunkEvent?: (payload: { event: unknown }) => void;\n onToolCallResultEvent?: (payload: { event: unknown }) => void;\n onActivitySnapshotEvent?: (payload: { event: unknown }) => void;\n onActivityDeltaEvent?: (payload: { event: unknown }) => void;\n onStateSnapshotEvent?: (payload: { event: unknown }) => void;\n onStateDeltaEvent?: (payload: { event: unknown }) => void;\n onMessagesSnapshotEvent?: (payload: { event: unknown }) => void;\n onCustomEvent?: (payload: { event: unknown }) => void;\n onRawEvent?: (payload: { event: unknown }) => void;\n onSubagentStartedEvent?: (payload: { event: unknown }) => void;\n onSubagentFinishedEvent?: (payload: { event: unknown }) => void;\n onSubagentErrorEvent?: (payload: { event: unknown }) => void;\n onRunFinishedEvent?: (payload: { event: unknown }) => void;\n onRunErrorEvent?: (payload: { event: unknown }) => void;\n onStepStartedEvent?: (payload: { event: unknown }) => void;\n onStepFinishedEvent?: (payload: { event: unknown }) => void;\n onRunFinalized?: () => void;\n onRunFailed?: (payload: { error: Error }) => void;\n};\n\nconst isAbortError = (error: Error): boolean => {\n if (error.name === \"AbortError\") return true;\n const message = typeof error.message === \"string\" ? error.message : \"\";\n return (\n message === \"Fetch is aborted\" ||\n message === \"signal is aborted without reason\" ||\n message === \"component unmounted\"\n );\n};\n\nconst ensureEvent = (\n raw: unknown,\n type: AgUiEvent[\"type\"],\n logger?: Logger,\n): AgUiEvent | null => {\n const parseOptions = logger ? { logger } : undefined;\n let parsed: AgUiEvent | null;\n if (raw && typeof raw === \"object\") {\n const payload = raw as Record<string, unknown>;\n if (typeof payload.type === \"string\") {\n parsed = parseAgUiEvent(payload, parseOptions);\n } else {\n parsed = parseAgUiEvent({ type, ...payload }, parseOptions);\n }\n } else {\n parsed = parseAgUiEvent({ type }, parseOptions);\n }\n return parsed && parsed.type === type ? parsed : null;\n};\n\ntype SubscriberOptions = {\n dispatch: Dispatch;\n runId: string;\n logger?: Logger;\n onRunFailed?: (error: Error) => void;\n};\n\nexport const createAgUiSubscriber = (\n options: SubscriberOptions,\n): Subscriber => {\n const { dispatch, runId, logger, onRunFailed } = options;\n let runFinishedDispatched = false;\n const dispatchIfValid = (raw: unknown, type: AgUiEvent[\"type\"]) => {\n const event = ensureEvent(raw, type, logger);\n if (!event) return;\n dispatch(event);\n };\n return {\n onEvent: ({ event }) => {\n const typeCandidate =\n event && typeof event === \"object\"\n ? (event as Record<string, unknown>).type\n : undefined;\n if (typeof typeCandidate === \"string\") {\n // Typed handlers will receive this via the discriminated callbacks; avoid duplicates.\n return;\n }\n const parsed = parseAgUiEvent(event, logger ? { logger } : undefined);\n if (parsed) dispatch(parsed);\n },\n onTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_START\"),\n onTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CONTENT\"),\n onTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_END\"),\n onTextMessageChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CHUNK\"),\n onThinkingStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_START\"),\n onThinkingEndEvent: ({ event }) => dispatchIfValid(event, \"THINKING_END\"),\n onThinkingTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_START\"),\n onThinkingTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_CONTENT\"),\n onThinkingTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_END\"),\n onReasoningStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_START\"),\n onReasoningEndEvent: ({ event }) => dispatchIfValid(event, \"REASONING_END\"),\n onReasoningMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_START\"),\n onReasoningMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_CONTENT\"),\n onReasoningMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_END\"),\n onReasoningEncryptedValueEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_ENCRYPTED_VALUE\"),\n onToolCallStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_START\"),\n onToolCallArgsEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_ARGS\"),\n onToolCallEndEvent: ({ event }) => dispatchIfValid(event, \"TOOL_CALL_END\"),\n onToolCallChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_CHUNK\"),\n onToolCallResultEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_RESULT\"),\n onActivitySnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_SNAPSHOT\"),\n onActivityDeltaEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_DELTA\"),\n onStateSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"STATE_SNAPSHOT\"),\n onStateDeltaEvent: ({ event }) => dispatchIfValid(event, \"STATE_DELTA\"),\n onMessagesSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"MESSAGES_SNAPSHOT\"),\n onCustomEvent: ({ event }) => dispatchIfValid(event, \"CUSTOM\"),\n onRawEvent: ({ event }) => dispatchIfValid(event, \"RAW\"),\n onSubagentStartedEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_STARTED\"),\n onSubagentFinishedEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_FINISHED\"),\n onSubagentErrorEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_ERROR\"),\n onRunFinishedEvent: ({ event }) => {\n if (runFinishedDispatched) return;\n const parsed = ensureEvent(event, \"RUN_FINISHED\", logger);\n if (!parsed) return;\n runFinishedDispatched = true;\n dispatch(parsed);\n },\n onRunErrorEvent: ({ event }) => {\n const parsed = ensureEvent(event, \"RUN_ERROR\", logger);\n if (!parsed || parsed.type !== \"RUN_ERROR\") return;\n runFinishedDispatched = true;\n dispatch(parsed);\n\n const error = Object.assign(\n new Error(parsed.message ?? \"Run failed\"),\n parsed.code === undefined ? {} : { code: parsed.code },\n );\n onRunFailed?.(error);\n },\n onStepStartedEvent: ({ event }) =>\n logger?.debug?.(\"[agui] step boundary ignored\", event),\n onStepFinishedEvent: ({ event }) =>\n logger?.debug?.(\"[agui] step boundary ignored\", event),\n onRunFinalized: () => {\n if (runFinishedDispatched) return;\n dispatch({ type: \"RUN_FINISHED\", runId });\n },\n onRunFailed: ({ error }) => {\n runFinishedDispatched = true;\n onRunFailed?.(error);\n if (isAbortError(error)) {\n dispatch({ type: \"RUN_CANCELLED\" } satisfies AgUiEvent);\n return;\n }\n const message =\n typeof error.message === \"string\" ? error.message : \"Run failed\";\n const code =\n typeof (error as any)?.code === \"string\"\n ? (error as any).code\n : undefined;\n dispatch({\n type: \"RUN_ERROR\" as const,\n ...(message !== undefined ? { message } : {}),\n ...(code !== undefined ? { code } : {}),\n } satisfies AgUiEvent);\n },\n };\n};\n\nexport type AgUiSubscriber = ReturnType<typeof createAgUiSubscriber>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subscriber.js","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"sourcesContent":["\"use client\";\n\nimport type { AgUiEvent } from \"../types\";\nimport { parseAgUiEvent } from \"../event-parser\";\nimport type { Logger } from \"../logger\";\n\ntype Dispatch = (event: AgUiEvent) => void;\n\ntype Subscriber = {\n onEvent?: (payload: { event: unknown }) => void;\n onTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onTextMessageChunkEvent?: (payload: { event: unknown }) => void;\n onThinkingStartEvent?: (payload: { event: unknown }) => void;\n onThinkingEndEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningStartEvent?: (payload: { event: unknown }) => void;\n onReasoningEndEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageStartEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageContentEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningEncryptedValueEvent?: (payload: { event: unknown }) => void;\n onToolCallStartEvent?: (payload: { event: unknown }) => void;\n onToolCallArgsEvent?: (payload: { event: unknown }) => void;\n onToolCallEndEvent?: (payload: { event: unknown }) => void;\n onToolCallChunkEvent?: (payload: { event: unknown }) => void;\n onToolCallResultEvent?: (payload: { event: unknown }) => void;\n onActivitySnapshotEvent?: (payload: { event: unknown }) => void;\n onActivityDeltaEvent?: (payload: { event: unknown }) => void;\n onStateSnapshotEvent?: (payload: { event: unknown }) => void;\n onStateDeltaEvent?: (payload: { event: unknown }) => void;\n onMessagesSnapshotEvent?: (payload: { event: unknown }) => void;\n onCustomEvent?: (payload: { event: unknown }) => void;\n onRawEvent?: (payload: { event: unknown }) => void;\n onSubagentStartedEvent?: (payload: { event: unknown }) => void;\n onSubagentFinishedEvent?: (payload: { event: unknown }) => void;\n onSubagentErrorEvent?: (payload: { event: unknown }) => void;\n onRunFinishedEvent?: (payload: { event: unknown }) => void;\n onRunErrorEvent?: (payload: { event: unknown }) => void;\n onStepStartedEvent?: (payload: { event: unknown }) => void;\n onStepFinishedEvent?: (payload: { event: unknown }) => void;\n onRunFinalized?: () => void;\n onRunFailed?: (payload: { error: Error }) => void;\n};\n\nconst isAbortError = (error: Error): boolean => {\n if (error.name === \"AbortError\") return true;\n const message = typeof error.message === \"string\" ? error.message : \"\";\n return (\n message === \"Fetch is aborted\" ||\n message === \"signal is aborted without reason\" ||\n message === \"component unmounted\"\n );\n};\n\nconst ensureEvent = (\n raw: unknown,\n type: AgUiEvent[\"type\"],\n logger?: Logger,\n): AgUiEvent | null => {\n const parseOptions = logger ? { logger } : undefined;\n let parsed: AgUiEvent | null;\n if (raw && typeof raw === \"object\") {\n const payload = raw as Record<string, unknown>;\n if (typeof payload.type === \"string\") {\n parsed = parseAgUiEvent(payload, parseOptions);\n } else {\n parsed = parseAgUiEvent({ type, ...payload }, parseOptions);\n }\n } else {\n parsed = parseAgUiEvent({ type }, parseOptions);\n }\n return parsed && parsed.type === type ? parsed : null;\n};\n\ntype SubscriberOptions = {\n dispatch: Dispatch;\n runId: string;\n logger?: Logger;\n onRunFailed?: (error: Error) => void;\n};\n\nexport const createAgUiSubscriber = (\n options: SubscriberOptions,\n): Subscriber => {\n const { dispatch, runId, logger, onRunFailed } = options;\n let runFinishedDispatched = false;\n const dispatchIfValid = (raw: unknown, type: AgUiEvent[\"type\"]) => {\n const event = ensureEvent(raw, type, logger);\n if (!event) return;\n dispatch(event);\n };\n return {\n onEvent: ({ event }) => {\n const typeCandidate =\n event && typeof event === \"object\"\n ? (event as Record<string, unknown>).type\n : undefined;\n if (typeof typeCandidate === \"string\") {\n // Typed handlers will receive this via the discriminated callbacks; avoid duplicates.\n return;\n }\n const parsed = parseAgUiEvent(event, logger ? { logger } : undefined);\n if (parsed) dispatch(parsed);\n },\n onTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_START\"),\n onTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CONTENT\"),\n onTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_END\"),\n onTextMessageChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CHUNK\"),\n onThinkingStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_START\"),\n onThinkingEndEvent: ({ event }) => dispatchIfValid(event, \"THINKING_END\"),\n onThinkingTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_START\"),\n onThinkingTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_CONTENT\"),\n onThinkingTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_END\"),\n onReasoningStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_START\"),\n onReasoningEndEvent: ({ event }) => dispatchIfValid(event, \"REASONING_END\"),\n onReasoningMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_START\"),\n onReasoningMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_CONTENT\"),\n onReasoningMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_END\"),\n onReasoningEncryptedValueEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_ENCRYPTED_VALUE\"),\n onToolCallStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_START\"),\n onToolCallArgsEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_ARGS\"),\n onToolCallEndEvent: ({ event }) => dispatchIfValid(event, \"TOOL_CALL_END\"),\n onToolCallChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_CHUNK\"),\n onToolCallResultEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_RESULT\"),\n onActivitySnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_SNAPSHOT\"),\n onActivityDeltaEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_DELTA\"),\n onStateSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"STATE_SNAPSHOT\"),\n onStateDeltaEvent: ({ event }) => dispatchIfValid(event, \"STATE_DELTA\"),\n onMessagesSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"MESSAGES_SNAPSHOT\"),\n onCustomEvent: ({ event }) => dispatchIfValid(event, \"CUSTOM\"),\n onRawEvent: ({ event }) => dispatchIfValid(event, \"RAW\"),\n onSubagentStartedEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_STARTED\"),\n onSubagentFinishedEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_FINISHED\"),\n onSubagentErrorEvent: ({ event }) =>\n dispatchIfValid(event, \"SUBAGENT_ERROR\"),\n onRunFinishedEvent: ({ event }) => {\n if (runFinishedDispatched) return;\n const parsed = ensureEvent(event, \"RUN_FINISHED\", logger);\n if (!parsed) return;\n runFinishedDispatched = true;\n dispatch(parsed);\n },\n onRunErrorEvent: ({ event }) => {\n const parsed = ensureEvent(event, \"RUN_ERROR\", logger);\n if (!parsed || parsed.type !== \"RUN_ERROR\") return;\n runFinishedDispatched = true;\n dispatch(parsed);\n\n const error = Object.assign(\n new Error(parsed.message ?? \"Run failed\"),\n parsed.code === undefined ? {} : { code: parsed.code },\n );\n onRunFailed?.(error);\n },\n onStepStartedEvent: ({ event }) =>\n logger?.debug?.(\"[agui] step boundary ignored\", event),\n onStepFinishedEvent: ({ event }) =>\n logger?.debug?.(\"[agui] step boundary ignored\", event),\n onRunFinalized: () => {\n if (runFinishedDispatched) return;\n dispatch({ type: \"RUN_FINISHED\", runId });\n },\n onRunFailed: ({ error }) => {\n if (runFinishedDispatched) return;\n runFinishedDispatched = true;\n onRunFailed?.(error);\n if (isAbortError(error)) {\n dispatch({ type: \"RUN_CANCELLED\" } satisfies AgUiEvent);\n return;\n }\n const message =\n typeof error.message === \"string\" ? error.message : \"Run failed\";\n const code =\n typeof (error as any)?.code === \"string\"\n ? (error as any).code\n : undefined;\n dispatch({\n type: \"RUN_ERROR\" as const,\n ...(message !== undefined ? { message } : {}),\n ...(code !== undefined ? { code } : {}),\n } satisfies AgUiEvent);\n },\n };\n};\n\nexport type AgUiSubscriber = ReturnType<typeof createAgUiSubscriber>;\n"],"mappings":"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"}
|
|
@@ -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,
|
|
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"}
|
package/dist/useAgUiRuntime.js
CHANGED
|
@@ -48,6 +48,7 @@ function useAgUiRuntime(options) {
|
|
|
48
48
|
const isRunning = core.isRunning() || hasExecutingTools;
|
|
49
49
|
const queueRef = useRef(null);
|
|
50
50
|
const busyEdgesRef = useRef(0);
|
|
51
|
+
const lastQueueEdgeRef = useRef(null);
|
|
51
52
|
if (options.unstable_enableMessageQueue && !queueRef.current) queueRef.current = createMessageQueue({ run: (message) => {
|
|
52
53
|
const controller = queueRef.current;
|
|
53
54
|
const edgesAtDispatch = busyEdgesRef.current;
|
|
@@ -71,10 +72,16 @@ function useAgUiRuntime(options) {
|
|
|
71
72
|
const steerQueueItems = useSyncExternalStore(queueController?.subscribe ?? subscribeNoop, () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS, () => EMPTY_QUEUE_ITEMS);
|
|
72
73
|
const queueBusy = isRunning || core.getPendingInterrupts() !== null;
|
|
73
74
|
useEffect(() => {
|
|
75
|
+
if (!queueController) return;
|
|
76
|
+
if (lastQueueEdgeRef.current?.controller === queueController && lastQueueEdgeRef.current.busy === queueBusy) return;
|
|
77
|
+
lastQueueEdgeRef.current = {
|
|
78
|
+
controller: queueController,
|
|
79
|
+
busy: queueBusy
|
|
80
|
+
};
|
|
74
81
|
if (queueBusy) {
|
|
75
82
|
busyEdgesRef.current++;
|
|
76
|
-
queueController
|
|
77
|
-
} else queueController
|
|
83
|
+
queueController.notifyBusy();
|
|
84
|
+
} else queueController.notifyIdle();
|
|
78
85
|
}, [queueBusy, queueController]);
|
|
79
86
|
const threadList = useMemo(() => {
|
|
80
87
|
if (!threadListAdapter) return void 0;
|
|
@@ -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 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 (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 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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ag-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.64",
|
|
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.
|
|
34
|
-
"@assistant-ui/react-generative-ui": "^0.0.
|
|
35
|
-
"@assistant-ui/store": "^0.3.
|
|
36
|
-
"assistant-stream": "^0.3.
|
|
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",
|
|
37
37
|
"fast-json-patch": "^3.1.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
49
|
+
"@assistant-ui/x-buildutils": "0.0.30",
|
|
50
50
|
"@assistant-ui/x-react18": "0.0.0",
|
|
51
51
|
"@testing-library/dom": "^10.4.2",
|
|
52
52
|
"@testing-library/react": "^16.3.3",
|
|
53
53
|
"@types/react": "^19.3.0",
|
|
54
54
|
"jsdom": "^30.0.1",
|
|
55
55
|
"react": "^19.3.0",
|
|
56
|
-
"vitest": "^5.0.
|
|
56
|
+
"vitest": "^5.0.3",
|
|
57
57
|
"zod": "^4.6.5"
|
|
58
58
|
},
|
|
59
59
|
"publishConfig": {
|
|
@@ -300,11 +300,7 @@ export class AgUiThreadRuntimeCore {
|
|
|
300
300
|
})
|
|
301
301
|
.catch((error) => {
|
|
302
302
|
this.logger.error?.("[agui] failed to load history", error);
|
|
303
|
-
|
|
304
|
-
"onError",
|
|
305
|
-
this.onError,
|
|
306
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
307
|
-
);
|
|
303
|
+
this.reportError(error);
|
|
308
304
|
})
|
|
309
305
|
.finally(() => {
|
|
310
306
|
this._isLoading = false;
|
|
@@ -1039,11 +1035,7 @@ export class AgUiThreadRuntimeCore {
|
|
|
1039
1035
|
|
|
1040
1036
|
private startResumeRun(messageId: string): void {
|
|
1041
1037
|
void this.startRun(messageId, this.lastRunConfig).catch((error) => {
|
|
1042
|
-
|
|
1043
|
-
"onError",
|
|
1044
|
-
this.onError,
|
|
1045
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
1046
|
-
);
|
|
1038
|
+
this.reportError(error);
|
|
1047
1039
|
});
|
|
1048
1040
|
}
|
|
1049
1041
|
|
|
@@ -1293,8 +1285,10 @@ export class AgUiThreadRuntimeCore {
|
|
|
1293
1285
|
},
|
|
1294
1286
|
onTextMessageStart: (serverId) => adoptServerMessageId(serverId, true),
|
|
1295
1287
|
});
|
|
1288
|
+
let runFinished = false;
|
|
1296
1289
|
const dispatch = (event: AgUiEvent) => {
|
|
1297
1290
|
if (this.abortController !== abortController) return;
|
|
1291
|
+
if (event.type === "RUN_FINISHED") runFinished = true;
|
|
1298
1292
|
const nextAssistantMessageId = this.handleEvent(
|
|
1299
1293
|
aggregator,
|
|
1300
1294
|
event,
|
|
@@ -1325,8 +1319,14 @@ export class AgUiThreadRuntimeCore {
|
|
|
1325
1319
|
try {
|
|
1326
1320
|
if (resumeStream) {
|
|
1327
1321
|
// Cancel flips only the status; an aggregator RUN_CANCELLED would emit an empty snapshot and wipe the replayed content.
|
|
1328
|
-
cancelRun = () =>
|
|
1322
|
+
cancelRun = () => {
|
|
1323
|
+
const current =
|
|
1324
|
+
assistantMessageId === undefined
|
|
1325
|
+
? undefined
|
|
1326
|
+
: this.session.tryGetMessage(assistantMessageId)?.message;
|
|
1327
|
+
if (current?.status?.type === "complete") return;
|
|
1329
1328
|
applyUpdate({ status: { type: "incomplete", reason: "cancelled" } });
|
|
1329
|
+
};
|
|
1330
1330
|
pendingError =
|
|
1331
1331
|
(await this.consumeResumeStream(resumeStream, {
|
|
1332
1332
|
runConfig: normalizedRunConfig,
|
|
@@ -1369,11 +1369,13 @@ export class AgUiThreadRuntimeCore {
|
|
|
1369
1369
|
await runAgent(input, subscriber, { signal: abortSignal });
|
|
1370
1370
|
}
|
|
1371
1371
|
} catch (error) {
|
|
1372
|
-
|
|
1372
|
+
// HttpAgent rethrows a failure it already passed to the subscriber's
|
|
1373
|
+
// onRunFailed, which reported it.
|
|
1374
|
+
if (!abortSignal.aborted && !pendingError) {
|
|
1373
1375
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
1374
|
-
dispatch({ type: "RUN_ERROR", message: err.message });
|
|
1376
|
+
if (!runFinished) dispatch({ type: "RUN_ERROR", message: err.message });
|
|
1375
1377
|
invokeRuntimeCallback("onError", this.onError, err);
|
|
1376
|
-
pendingError
|
|
1378
|
+
pendingError = err;
|
|
1377
1379
|
}
|
|
1378
1380
|
} finally {
|
|
1379
1381
|
this.finishRun(abortController);
|
|
@@ -188,6 +188,7 @@ export const createAgUiSubscriber = (
|
|
|
188
188
|
dispatch({ type: "RUN_FINISHED", runId });
|
|
189
189
|
},
|
|
190
190
|
onRunFailed: ({ error }) => {
|
|
191
|
+
if (runFinishedDispatched) return;
|
|
191
192
|
runFinishedDispatched = true;
|
|
192
193
|
onRunFailed?.(error);
|
|
193
194
|
if (isAbortError(error)) {
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
import { act, Activity, version, type ComponentType } from "react";
|
|
4
4
|
import { afterAll, afterEach, expect, it, vi } from "vitest";
|
|
5
5
|
import type { HttpAgent } from "@ag-ui/client";
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
AssistantRuntime,
|
|
8
|
+
MessageQueueController,
|
|
9
|
+
} from "@assistant-ui/core";
|
|
7
10
|
import { AgUiThreadRuntimeCore } from "./runtime/AgUiThreadRuntimeCore";
|
|
8
11
|
import type { UseAgUiRuntimeOptions } from "./runtime/types";
|
|
9
12
|
import { useAgUiRuntime, type AgUiAssistantRuntime } from "./useAgUiRuntime";
|
|
@@ -11,6 +14,34 @@ import { useAgUiRuntime, type AgUiAssistantRuntime } from "./useAgUiRuntime";
|
|
|
11
14
|
const onReact18 = version.startsWith("18.");
|
|
12
15
|
|
|
13
16
|
const base = vi.hoisted(() => ({ version: 0 }));
|
|
17
|
+
const queue = vi.hoisted(() => ({
|
|
18
|
+
controller: null as MessageQueueController | null,
|
|
19
|
+
busy: vi.fn(),
|
|
20
|
+
idle: vi.fn(),
|
|
21
|
+
}));
|
|
22
|
+
vi.mock("@assistant-ui/core", async (importOriginal) => {
|
|
23
|
+
const actual = await importOriginal<typeof import("@assistant-ui/core")>();
|
|
24
|
+
return {
|
|
25
|
+
...actual,
|
|
26
|
+
createMessageQueue: (
|
|
27
|
+
...args: Parameters<typeof actual.createMessageQueue>
|
|
28
|
+
) => {
|
|
29
|
+
const controller = actual.createMessageQueue(...args);
|
|
30
|
+
queue.controller = {
|
|
31
|
+
...controller,
|
|
32
|
+
notifyBusy: () => {
|
|
33
|
+
queue.busy();
|
|
34
|
+
controller.notifyBusy();
|
|
35
|
+
},
|
|
36
|
+
notifyIdle: () => {
|
|
37
|
+
queue.idle();
|
|
38
|
+
controller.notifyIdle();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
return queue.controller;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
});
|
|
14
45
|
vi.mock("@assistant-ui/core/react", async (importOriginal) => {
|
|
15
46
|
const actual =
|
|
16
47
|
await importOriginal<typeof import("@assistant-ui/core/react")>();
|
|
@@ -61,6 +92,7 @@ afterEach(() => {
|
|
|
61
92
|
fiberRoots.clear();
|
|
62
93
|
vi.restoreAllMocks();
|
|
63
94
|
base.version = 0;
|
|
95
|
+
queue.controller = null;
|
|
64
96
|
});
|
|
65
97
|
afterAll(() => vi.unstubAllGlobals());
|
|
66
98
|
|
|
@@ -112,6 +144,80 @@ it("keeps the wrapper across refresh and replaces it when the base runtime chang
|
|
|
112
144
|
expect(runtime).not.toBe(wrapper);
|
|
113
145
|
});
|
|
114
146
|
|
|
147
|
+
it("emits queue edges once across refresh and dispatches the queued message", async () => {
|
|
148
|
+
let finishFirst!: () => void;
|
|
149
|
+
const firstRun = new Promise<void>((resolve) => {
|
|
150
|
+
finishFirst = resolve;
|
|
151
|
+
});
|
|
152
|
+
const runAgent = vi.fn(
|
|
153
|
+
async (_input: unknown, subscriber: { onRunFinalized?: () => void }) => {
|
|
154
|
+
if (runAgent.mock.calls.length === 1) await firstRun;
|
|
155
|
+
subscriber.onRunFinalized?.();
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
options = {
|
|
159
|
+
agent: { runAgent, abortRun: vi.fn() } as unknown as HttpAgent,
|
|
160
|
+
unstable_enableMessageQueue: true,
|
|
161
|
+
};
|
|
162
|
+
const { Before, After } = createProbe();
|
|
163
|
+
const view = render(<Before />);
|
|
164
|
+
expect(queue.idle).toHaveBeenCalledTimes(1);
|
|
165
|
+
|
|
166
|
+
await act(async () => {
|
|
167
|
+
await runtime.thread.append({
|
|
168
|
+
role: "user",
|
|
169
|
+
content: [{ type: "text", text: "first" }],
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(1));
|
|
173
|
+
expect(queue.busy).toHaveBeenCalledTimes(1);
|
|
174
|
+
|
|
175
|
+
await act(async () => {
|
|
176
|
+
await runtime.thread.append({
|
|
177
|
+
role: "user",
|
|
178
|
+
content: [{ type: "text", text: "second" }],
|
|
179
|
+
parentId: runtime.thread.getState().messages.at(-1)?.id ?? null,
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
expect(runAgent).toHaveBeenCalledTimes(1);
|
|
183
|
+
expect(
|
|
184
|
+
[
|
|
185
|
+
...queue.controller!.adapter.items,
|
|
186
|
+
...queue.controller!.adapter.steerItems,
|
|
187
|
+
].map((item) => item.prompt),
|
|
188
|
+
).toEqual(["second"]);
|
|
189
|
+
|
|
190
|
+
await refresh(Before, After);
|
|
191
|
+
expect(queue.busy).toHaveBeenCalledTimes(1);
|
|
192
|
+
expect(queue.idle).toHaveBeenCalledTimes(1);
|
|
193
|
+
|
|
194
|
+
await act(async () => {
|
|
195
|
+
finishFirst();
|
|
196
|
+
await firstRun;
|
|
197
|
+
});
|
|
198
|
+
await waitFor(() => expect(runAgent).toHaveBeenCalledTimes(2));
|
|
199
|
+
await waitFor(() =>
|
|
200
|
+
expect([
|
|
201
|
+
...queue.controller!.adapter.items,
|
|
202
|
+
...queue.controller!.adapter.steerItems,
|
|
203
|
+
]).toHaveLength(0),
|
|
204
|
+
);
|
|
205
|
+
await waitFor(() => expect(queue.busy).toHaveBeenCalledTimes(2));
|
|
206
|
+
await waitFor(() => expect(queue.idle).toHaveBeenCalledTimes(3));
|
|
207
|
+
|
|
208
|
+
await refresh(Before, After);
|
|
209
|
+
expect(queue.busy).toHaveBeenCalledTimes(2);
|
|
210
|
+
expect(queue.idle).toHaveBeenCalledTimes(3);
|
|
211
|
+
|
|
212
|
+
const firstController = queue.controller;
|
|
213
|
+
options = { ...options, unstable_enableMessageQueue: false };
|
|
214
|
+
view.rerender(<After />);
|
|
215
|
+
options = { ...options, unstable_enableMessageQueue: true };
|
|
216
|
+
view.rerender(<After />);
|
|
217
|
+
expect(queue.controller).not.toBe(firstController);
|
|
218
|
+
expect(queue.idle).toHaveBeenCalledTimes(4);
|
|
219
|
+
});
|
|
220
|
+
|
|
115
221
|
const expectInFlightRunAcrossRefresh = async (
|
|
116
222
|
exit: "hidden" | "unmount",
|
|
117
223
|
inActivity: boolean,
|
package/src/useAgUiRuntime.ts
CHANGED
|
@@ -114,6 +114,10 @@ export function useAgUiRuntime(
|
|
|
114
114
|
// A dispatch whose count never moves was never observed as busy, so no
|
|
115
115
|
// falling edge is coming to release the queue.
|
|
116
116
|
const busyEdgesRef = useRef(0);
|
|
117
|
+
const lastQueueEdgeRef = useRef<{
|
|
118
|
+
controller: MessageQueueController;
|
|
119
|
+
busy: boolean;
|
|
120
|
+
} | null>(null);
|
|
117
121
|
if (options.unstable_enableMessageQueue && !queueRef.current) {
|
|
118
122
|
queueRef.current = createMessageQueue({
|
|
119
123
|
run: (message) => {
|
|
@@ -172,11 +176,18 @@ export function useAgUiRuntime(
|
|
|
172
176
|
// refusal would lose the message instead of keeping it visible.
|
|
173
177
|
const queueBusy = isRunning || core.getPendingInterrupts() !== null;
|
|
174
178
|
useEffect(() => {
|
|
179
|
+
if (!queueController) return;
|
|
180
|
+
if (
|
|
181
|
+
lastQueueEdgeRef.current?.controller === queueController &&
|
|
182
|
+
lastQueueEdgeRef.current.busy === queueBusy
|
|
183
|
+
)
|
|
184
|
+
return;
|
|
185
|
+
lastQueueEdgeRef.current = { controller: queueController, busy: queueBusy };
|
|
175
186
|
if (queueBusy) {
|
|
176
187
|
busyEdgesRef.current++;
|
|
177
|
-
queueController
|
|
188
|
+
queueController.notifyBusy();
|
|
178
189
|
} else {
|
|
179
|
-
queueController
|
|
190
|
+
queueController.notifyIdle();
|
|
180
191
|
}
|
|
181
192
|
}, [queueBusy, queueController]);
|
|
182
193
|
|