@assistant-ui/react-ag-ui 0.0.71 → 0.1.1
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/README.md +1 -1
- package/dist/agUiExtras.js +1 -2
- package/dist/hooks.js +1 -2
- package/dist/runtime/{AgUiThreadRuntimeCore.d.ts → AgUiThreadController.d.ts} +6 -12
- package/dist/runtime/AgUiThreadController.d.ts.map +1 -0
- package/dist/runtime/{AgUiThreadRuntimeCore.js → AgUiThreadController.js} +567 -194
- package/dist/runtime/AgUiThreadController.js.map +1 -0
- package/dist/runtime/adapter/conversions.d.ts +4 -4
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +120 -35
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/replay-content.d.ts +9 -0
- package/dist/runtime/adapter/replay-content.d.ts.map +1 -0
- package/dist/runtime/adapter/replay-content.js +185 -0
- package/dist/runtime/adapter/replay-content.js.map +1 -0
- package/dist/runtime/adapter/run-aggregator.d.ts +3 -5
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +48 -63
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts +0 -24
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/subscriber.js +2 -24
- package/dist/runtime/adapter/subscriber.js.map +1 -1
- package/dist/runtime/adapter/tool-approval.d.ts +2 -0
- package/dist/runtime/adapter/tool-approval.d.ts.map +1 -1
- package/dist/runtime/adapter/tool-approval.js +23 -6
- package/dist/runtime/adapter/tool-approval.js.map +1 -1
- package/dist/runtime/agUiThreadState.d.ts +60 -0
- package/dist/runtime/agUiThreadState.d.ts.map +1 -0
- package/dist/runtime/agUiThreadState.js +94 -0
- package/dist/runtime/agUiThreadState.js.map +1 -0
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/event-parser.js +46 -50
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/interrupt-internals.js +1 -2
- package/dist/runtime/logger.js +1 -2
- package/dist/runtime/mcp-tool-result.d.ts +3 -1
- package/dist/runtime/mcp-tool-result.d.ts.map +1 -1
- package/dist/runtime/mcp-tool-result.js +7 -5
- package/dist/runtime/mcp-tool-result.js.map +1 -1
- package/dist/runtime/types.d.ts +11 -35
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js +1 -2
- package/dist/runtime/types.js.map +1 -1
- package/dist/useAgUiRuntime.js +3 -4
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +12 -11
- package/src/runtime/AgUiThreadController.deferred-results.test.ts +548 -0
- package/src/runtime/{AgUiThreadRuntimeCore.interrupt-cancel.test.ts → AgUiThreadController.interrupt-cancel.test.ts} +4 -4
- package/src/runtime/AgUiThreadController.replay.test.ts +3932 -0
- package/src/runtime/{AgUiThreadRuntimeCore.test.ts → AgUiThreadController.test.ts} +114 -6
- package/src/runtime/{AgUiThreadRuntimeCore.ts → AgUiThreadController.ts} +1037 -236
- package/src/runtime/adapter/conversions.content.test.ts +149 -5
- package/src/runtime/adapter/conversions.tools.test.ts +2 -1
- package/src/runtime/adapter/conversions.ts +249 -62
- package/src/runtime/adapter/replay-content.test.ts +235 -0
- package/src/runtime/adapter/replay-content.ts +306 -0
- package/src/runtime/adapter/run-aggregator.ts +79 -114
- package/src/runtime/adapter/subscriber.ts +1 -44
- package/src/runtime/adapter/tool-approval.ts +41 -3
- package/src/runtime/agUiThreadState.test.ts +224 -0
- package/src/runtime/agUiThreadState.ts +139 -0
- package/src/runtime/event-parser.ts +40 -58
- package/src/runtime/mcp-tool-result.ts +16 -2
- package/src/runtime/types.ts +16 -28
- package/src/useAgUiRuntime.fast-refresh.test.tsx +3 -3
- package/src/useAgUiRuntime.thread-switch.test.tsx +4 -4
- package/src/useAgUiRuntime.ts +3 -3
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +0 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-content.js","names":[],"sources":["../../../src/runtime/adapter/replay-content.ts"],"sourcesContent":["import type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"@assistant-ui/core\";\nimport {\n iterateToolCallParts,\n mapToolCallPartsDeep,\n} from \"@assistant-ui/core/internal\";\n\nimport { preserveToolApprovalDecision } from \"./tool-approval\";\n\ntype Content = ThreadAssistantMessage[\"content\"];\ntype Part = Content[number];\n\nexport function indexReplayToolOwners(\n owners: readonly ThreadAssistantMessage[],\n): ReadonlyMap<string, string> {\n const ownerByToolCallId = new Map<string, string>();\n for (const owner of owners) {\n for (const part of iterateToolCallParts(owner.content)) {\n if (!ownerByToolCallId.has(part.toolCallId))\n ownerByToolCallId.set(part.toolCallId, owner.id);\n }\n }\n return ownerByToolCallId;\n}\n\nexport function groupReplayToolContent(\n owners: readonly ThreadAssistantMessage[],\n content: Content,\n fallbackMessageId: string,\n): Map<string, Part[]> {\n const ownerByToolCallId = indexReplayToolOwners(owners);\n const grouped = new Map<string, Part[]>([[fallbackMessageId, []]]);\n for (const part of content) {\n const ownerId =\n part.type === \"tool-call\"\n ? (ownerByToolCallId.get(part.toolCallId) ?? fallbackMessageId)\n : fallbackMessageId;\n const parts = grouped.get(ownerId) ?? [];\n parts.push(part);\n grouped.set(ownerId, parts);\n }\n return grouped;\n}\n\nexport function preserveToolResult(\n previous: ToolCallMessagePart,\n next: ToolCallMessagePart,\n): ToolCallMessagePart {\n if (previous.result === undefined || next.result !== undefined) return next;\n return {\n ...next,\n result: previous.result,\n ...(previous.artifact !== undefined ? { artifact: previous.artifact } : {}),\n ...(previous.isError !== undefined ? { isError: previous.isError } : {}),\n ...(previous.modelContent !== undefined\n ? { modelContent: previous.modelContent }\n : {}),\n };\n}\n\nfunction mergeOrdered<T>(\n previous: readonly (readonly [T, string])[],\n next: readonly (readonly [T, string])[],\n merge: (old: T, fresh: T) => T,\n): T[] {\n const old = new Map(previous.map(([value, key]) => [key, value] as const));\n const indexes = new Map(next.map(([, key], index) => [key, index] as const));\n const insertions: T[][] = Array.from({ length: next.length + 1 }, () => []);\n let predecessor = -1;\n for (const [value, key] of previous) {\n const index = indexes.get(key);\n if (index === undefined) insertions[predecessor + 1]!.push(value);\n else predecessor = index;\n }\n const result: T[] = [];\n for (const [index, [value, key]] of next.entries()) {\n const prior = old.get(key);\n result.push(\n ...insertions[index]!,\n prior === undefined ? value : merge(prior, value),\n );\n }\n result.push(...insertions[next.length]!);\n return result;\n}\n\nfunction mergeMessages(\n previous: readonly ThreadMessage[],\n next: readonly ThreadMessage[],\n): readonly ThreadMessage[] {\n return mergeOrdered(\n previous.map((message) => [message, message.id] as const),\n next.map((message) => [message, message.id] as const),\n (old, fresh) =>\n old.role === \"assistant\" && fresh.role === \"assistant\"\n ? { ...fresh, content: mergeReplayContent(old.content, fresh.content) }\n : fresh,\n );\n}\n\nfunction mergeTool(\n previous: ToolCallMessagePart,\n next: ToolCallMessagePart,\n): ToolCallMessagePart {\n const result = preserveToolResult(previous, next);\n const approval = preserveToolApprovalDecision(previous, next);\n return {\n ...result,\n ...(approval ? { approval } : {}),\n ...(result.unstable_interactions === undefined &&\n previous.unstable_interactions !== undefined\n ? { unstable_interactions: previous.unstable_interactions }\n : {}),\n ...(previous.messages !== undefined || next.messages !== undefined\n ? {\n messages: mergeMessages(previous.messages ?? [], next.messages ?? []),\n }\n : {}),\n };\n}\n\nfunction partKey(part: Part): string {\n if (part.type === \"tool-call\") return `tool:${part.toolCallId}`;\n if (part.type === \"text\" || part.type === \"reasoning\") return part.type;\n if (\"id\" in part && typeof part.id === \"string\" && part.id)\n return `${part.type}:${part.id}`;\n if (part.type === \"data\") return `data:${part.name}`;\n return part.type;\n}\n\nfunction keyed(content: Content): [Part, string][] {\n const ordinals = new Map<string, number>();\n return content.map((part) => {\n const base = partKey(part);\n const ordinal = ordinals.get(base) ?? 0;\n ordinals.set(base, ordinal + 1);\n return [part, `${base}:${ordinal}`] as [Part, string];\n });\n}\n\nfunction identity(part: Part, key: string, scope: readonly string[]): string {\n return JSON.stringify(\n part.type === \"tool-call\" ? [\"tool\", part.toolCallId] : [...scope, key],\n );\n}\n\nfunction visitMessages(\n messages: readonly ThreadMessage[],\n scope: readonly string[],\n visit: (key: string) => void,\n): void {\n for (const message of messages) {\n const path = [...scope, \"message\", message.id];\n visit(JSON.stringify(path));\n if (message.role === \"assistant\")\n visitContent(message.content, path, visit);\n }\n}\n\nfunction visitContent(\n content: Content,\n scope: readonly string[],\n visit: (key: string) => void,\n): void {\n for (const [part, key] of keyed(content)) {\n visit(identity(part, key, scope));\n if (part.type === \"tool-call\" && part.messages)\n visitMessages(part.messages, [\"tool\", part.toolCallId], visit);\n }\n}\n\nfunction pruneMessages(\n messages: readonly ThreadMessage[],\n scope: readonly string[],\n present: ReadonlySet<string>,\n owned: ReadonlySet<string>,\n): { messages: readonly ThreadMessage[]; hasCurrent: boolean } {\n let hasCurrent = false;\n const kept = messages.flatMap((message) => {\n const path = [...scope, \"message\", message.id];\n const key = JSON.stringify(path);\n const nested =\n message.role === \"assistant\"\n ? pruneContent(message.content, path, present, owned)\n : undefined;\n const current = present.has(key) || (nested?.hasCurrent ?? false);\n if (owned.has(key) && !current) return [];\n hasCurrent ||= current;\n return [\n nested && message.role === \"assistant\"\n ? { ...message, content: nested.content }\n : message,\n ];\n });\n return { messages: kept, hasCurrent };\n}\n\nfunction pruneContent(\n content: Content,\n scope: readonly string[],\n present: ReadonlySet<string>,\n owned: ReadonlySet<string>,\n): { content: Content; hasCurrent: boolean } {\n let hasCurrent = false;\n const kept = keyed(content).flatMap(([part, localKey]) => {\n const key = identity(part, localKey, scope);\n const nested =\n part.type === \"tool-call\" && part.messages\n ? pruneMessages(\n part.messages,\n [\"tool\", part.toolCallId],\n present,\n owned,\n )\n : undefined;\n const current = present.has(key) || (nested?.hasCurrent ?? false);\n if (owned.has(key) && !current) return [];\n hasCurrent ||= current;\n return [nested ? { ...part, messages: nested.messages } : part];\n });\n return { content: kept, hasCurrent };\n}\n\nexport function createReplayContentMerger(): (\n previous: Content,\n next: Content,\n) => Content {\n // Remember stream-owned identities, never a second copy of tool payloads.\n const owned = new Set<string>();\n return (previous, next) => {\n const present = new Set<string>();\n visitContent(next, [], (key) => present.add(key));\n for (const key of present) owned.add(key);\n return pruneContent(mergeReplayContent(previous, next), [], present, owned)\n .content;\n };\n}\n\nfunction nestedToolIds(content: Content): Set<string> {\n const nestedIds = new Set<string>();\n for (const part of content) {\n if (part.type !== \"tool-call\") continue;\n for (const message of part.messages ?? []) {\n if (message.role !== \"assistant\") continue;\n for (const child of iterateToolCallParts(message.content)) {\n nestedIds.add(child.toolCallId);\n }\n }\n }\n return nestedIds;\n}\n\nfunction mergeReplayContent(previous: Content, next: Content): Content {\n const nestedIds = nestedToolIds(previous);\n const incomingNestedIds = nestedToolIds(next);\n const movingRoots = new Map(\n previous.flatMap((part) =>\n part.type === \"tool-call\" && incomingNestedIds.has(part.toolCallId)\n ? [[part.toolCallId, part] as const]\n : [],\n ),\n );\n const flattened = new Map<string, ToolCallMessagePart>();\n for (const part of next) {\n if (part.type === \"tool-call\" && nestedIds.has(part.toolCallId)) {\n flattened.set(part.toolCallId, part);\n }\n }\n const prior = (\n flattened.size\n ? mapToolCallPartsDeep(previous, (part) => {\n const fresh = flattened.get(part.toolCallId);\n return fresh ? mergeTool(part, fresh) : part;\n }).content\n : previous\n ).filter(\n (part) => part.type !== \"tool-call\" || !movingRoots.has(part.toolCallId),\n );\n let incoming = next.filter(\n (part) => part.type !== \"tool-call\" || !flattened.has(part.toolCallId),\n );\n if (movingRoots.size) {\n incoming = [\n ...mapToolCallPartsDeep(incoming, (part) => {\n const prior = movingRoots.get(part.toolCallId);\n return prior ? mergeTool(prior, part) : part;\n }).content,\n ];\n }\n return mergeOrdered(keyed(prior), keyed(incoming), (old, fresh) => {\n if (old.type === \"tool-call\" && fresh.type === \"tool-call\")\n return mergeTool(old, fresh);\n if (\n (old.type === \"text\" || old.type === \"reasoning\") &&\n (fresh.type === \"text\" || fresh.type === \"reasoning\") &&\n old.text.startsWith(fresh.text) &&\n old.text.length > fresh.text.length\n ) {\n return { ...fresh, text: old.text };\n }\n return fresh;\n });\n}\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ export type RunAggregatorOptions = {
|
|
|
10
10
|
logger: Logger;
|
|
11
11
|
emit: Emit;
|
|
12
12
|
onServerMessageId?: (messageId: string) => void;
|
|
13
|
-
onTextMessageStart?: (messageId: string) => void;
|
|
13
|
+
onTextMessageStart?: (messageId: string, openToolCallIds: string[]) => void;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Collects AG-UI events into assistant-ui run snapshots that can be yielded from a ChatModelAdapter.
|
|
@@ -31,6 +31,7 @@ export declare class RunAggregator {
|
|
|
31
31
|
private readonly onTextMessageStart;
|
|
32
32
|
private status;
|
|
33
33
|
private interrupts;
|
|
34
|
+
private pendingToolCallIds;
|
|
34
35
|
private readonly textParts;
|
|
35
36
|
private readonly activeTextMessageIdByScope;
|
|
36
37
|
private readonly reasoningParts;
|
|
@@ -39,17 +40,14 @@ export declare class RunAggregator {
|
|
|
39
40
|
private readonly hiddenSignatures;
|
|
40
41
|
private readonly hiddenSignatureAnchors;
|
|
41
42
|
private readonly hiddenBlockAnchors;
|
|
42
|
-
private hiddenAnonymousAnchor;
|
|
43
43
|
private readonly hiddenReasoningIds;
|
|
44
|
-
private
|
|
44
|
+
private hiddenActiveReasoningId;
|
|
45
45
|
private hasEmittedOpaqueReasoning;
|
|
46
46
|
private readonly loggedDroppedOpaqueIds;
|
|
47
47
|
private readonly reasoningMessageIds;
|
|
48
|
-
private readonly anonymousReasoningKeys;
|
|
49
48
|
private readonly activeReasoningKeyByScope;
|
|
50
49
|
private readonly subagentRuns;
|
|
51
50
|
private nestingMemo;
|
|
52
|
-
private reasoningPartCounter;
|
|
53
51
|
private readonly toolCalls;
|
|
54
52
|
private readonly a2uiBuckets;
|
|
55
53
|
private readonly a2uiToolCallIds;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-aggregator.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/run-aggregator.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,kBAAkB,EAQxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"run-aggregator.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/run-aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { readMcpAppResourceUri } from "../mcp-tool-result.js";
|
|
2
|
+
import { readMcpAppResourceUri, toolContentText } from "../mcp-tool-result.js";
|
|
3
3
|
import { AG_UI_METADATA_NAMESPACE } from "../types.js";
|
|
4
4
|
import { projectAgUiToolApprovals } from "./tool-approval.js";
|
|
5
5
|
import { isMcpAppUri } from "@assistant-ui/core";
|
|
6
6
|
import jsonpatch from "fast-json-patch";
|
|
7
7
|
import { applyA2uiOperations, surfaceToPresentToolCall } from "@assistant-ui/generative-ui/a2ui";
|
|
8
|
-
|
|
8
|
+
// src/runtime/adapter/run-aggregator.ts
|
|
9
9
|
const ROOT_SCOPE = "";
|
|
10
10
|
const MAX_SUBAGENT_DEPTH = 16;
|
|
11
11
|
const createJSONContainerScanner = () => ({
|
|
@@ -82,6 +82,7 @@ var RunAggregator = class {
|
|
|
82
82
|
onTextMessageStart;
|
|
83
83
|
status;
|
|
84
84
|
interrupts;
|
|
85
|
+
pendingToolCallIds;
|
|
85
86
|
textParts = /* @__PURE__ */ new Map();
|
|
86
87
|
activeTextMessageIdByScope = /* @__PURE__ */ new Map();
|
|
87
88
|
reasoningParts = /* @__PURE__ */ new Map();
|
|
@@ -90,17 +91,14 @@ var RunAggregator = class {
|
|
|
90
91
|
hiddenSignatures = /* @__PURE__ */ new Map();
|
|
91
92
|
hiddenSignatureAnchors = /* @__PURE__ */ new Map();
|
|
92
93
|
hiddenBlockAnchors = /* @__PURE__ */ new Map();
|
|
93
|
-
hiddenAnonymousAnchor;
|
|
94
94
|
hiddenReasoningIds = /* @__PURE__ */ new Set();
|
|
95
|
-
|
|
95
|
+
hiddenActiveReasoningId;
|
|
96
96
|
hasEmittedOpaqueReasoning = false;
|
|
97
97
|
loggedDroppedOpaqueIds = /* @__PURE__ */ new Set();
|
|
98
98
|
reasoningMessageIds = /* @__PURE__ */ new Map();
|
|
99
|
-
anonymousReasoningKeys = /* @__PURE__ */ new Set();
|
|
100
99
|
activeReasoningKeyByScope = /* @__PURE__ */ new Map();
|
|
101
100
|
subagentRuns = /* @__PURE__ */ new Map();
|
|
102
101
|
nestingMemo;
|
|
103
|
-
reasoningPartCounter = 0;
|
|
104
102
|
toolCalls = /* @__PURE__ */ new Map();
|
|
105
103
|
a2uiBuckets = /* @__PURE__ */ new Map();
|
|
106
104
|
a2uiToolCallIds = /* @__PURE__ */ new Set();
|
|
@@ -141,6 +139,16 @@ var RunAggregator = class {
|
|
|
141
139
|
this.emit();
|
|
142
140
|
break;
|
|
143
141
|
case "RUN_FINISHED": {
|
|
142
|
+
if (event.outcome?.type === "cancelled") {
|
|
143
|
+
this.interrupts = void 0;
|
|
144
|
+
this.status = {
|
|
145
|
+
type: "incomplete",
|
|
146
|
+
reason: "cancelled"
|
|
147
|
+
};
|
|
148
|
+
this.closeOpenSubagentRuns(this.status);
|
|
149
|
+
this.emit();
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
144
152
|
if (event.outcome?.type === "interrupt") {
|
|
145
153
|
this.interrupts = event.outcome.interrupts;
|
|
146
154
|
this.status = {
|
|
@@ -151,7 +159,11 @@ var RunAggregator = class {
|
|
|
151
159
|
break;
|
|
152
160
|
}
|
|
153
161
|
this.interrupts = void 0;
|
|
154
|
-
const
|
|
162
|
+
const pendingToolCallIds = event.outcome?.type === "success" ? event.outcome.pendingToolCallIds : void 0;
|
|
163
|
+
const hasUnresolvedToolCalls = pendingToolCallIds && pendingToolCallIds.length > 0 ? pendingToolCallIds.some((id) => {
|
|
164
|
+
const call = this.toolCalls.get(id);
|
|
165
|
+
return call !== void 0 && call.result === void 0;
|
|
166
|
+
}) : Array.from(this.toolCalls.values()).some((tc) => tc.result === void 0);
|
|
155
167
|
this.status = hasUnresolvedToolCalls ? {
|
|
156
168
|
type: "requires-action",
|
|
157
169
|
reason: "tool-calls"
|
|
@@ -159,6 +171,7 @@ var RunAggregator = class {
|
|
|
159
171
|
type: "complete",
|
|
160
172
|
reason: "unknown"
|
|
161
173
|
};
|
|
174
|
+
this.pendingToolCallIds = hasUnresolvedToolCalls && pendingToolCallIds?.length ? pendingToolCallIds : void 0;
|
|
162
175
|
this.closeOpenSubagentRuns(this.status);
|
|
163
176
|
this.emit();
|
|
164
177
|
break;
|
|
@@ -192,9 +205,8 @@ var RunAggregator = class {
|
|
|
192
205
|
this.emit();
|
|
193
206
|
break;
|
|
194
207
|
}
|
|
195
|
-
case "TEXT_MESSAGE_CONTENT":
|
|
196
|
-
|
|
197
|
-
const incomingId = "messageId" in event ? event.messageId : void 0;
|
|
208
|
+
case "TEXT_MESSAGE_CONTENT": {
|
|
209
|
+
const incomingId = event.messageId;
|
|
198
210
|
const scope = this.scopeOf(event);
|
|
199
211
|
if (scope === ROOT_SCOPE) {
|
|
200
212
|
this.beginDistinctTextMessage(incomingId);
|
|
@@ -225,43 +237,31 @@ var RunAggregator = class {
|
|
|
225
237
|
});
|
|
226
238
|
this.emit();
|
|
227
239
|
break;
|
|
228
|
-
case "THINKING_START":
|
|
229
|
-
case "THINKING_TEXT_MESSAGE_START":
|
|
230
240
|
case "REASONING_START":
|
|
231
241
|
case "REASONING_MESSAGE_START":
|
|
232
|
-
this.handleReasoningStart(this.scopeOf(
|
|
242
|
+
this.handleReasoningStart(this.scopeOf(event), event.messageId, event.type === "REASONING_MESSAGE_START", event.timestamp);
|
|
233
243
|
break;
|
|
234
244
|
case "REASONING_ENCRYPTED_VALUE":
|
|
235
245
|
if (event.subtype === "message") {
|
|
236
246
|
const scope = this.scopeOf(event);
|
|
237
|
-
const active = this.activeReasoningKeyByScope.get(scope);
|
|
238
247
|
const entityKey = this.partKey(scope, event.entityId);
|
|
239
|
-
const key = this.showThinking
|
|
248
|
+
const key = this.showThinking && this.reasoningParts.has(entityKey) ? entityKey : void 0;
|
|
240
249
|
if (key !== void 0) {
|
|
241
250
|
this.reasoningSignatures.set(key, event.encryptedValue);
|
|
242
251
|
this.reasoningSignatureIds.set(key, event.entityId);
|
|
243
252
|
this.emit();
|
|
244
|
-
} else if (!this.showThinking && scope === ROOT_SCOPE && event.entityId.trim().length > 0 && event.encryptedValue.trim().length > 0 &&
|
|
253
|
+
} else if (!this.showThinking && scope === ROOT_SCOPE && event.entityId.trim().length > 0 && event.encryptedValue.trim().length > 0 && this.hiddenReasoningIds.has(event.entityId)) {
|
|
245
254
|
this.hiddenSignatures.set(event.entityId, event.encryptedValue);
|
|
246
|
-
this.hiddenSignatureAnchors.set(event.entityId, this.hiddenBlockAnchors.get(event.entityId) ?? this.
|
|
255
|
+
this.hiddenSignatureAnchors.set(event.entityId, this.hiddenBlockAnchors.get(event.entityId) ?? this.partOrder.length);
|
|
247
256
|
this.emit();
|
|
248
257
|
}
|
|
249
258
|
}
|
|
250
259
|
break;
|
|
251
|
-
case "THINKING_TEXT_MESSAGE_CONTENT":
|
|
252
|
-
this.handleReasoningContent(ROOT_SCOPE, event.delta);
|
|
253
|
-
this.totalChunks++;
|
|
254
|
-
this.recordFirstToken();
|
|
255
|
-
break;
|
|
256
260
|
case "REASONING_MESSAGE_CONTENT":
|
|
257
|
-
this.handleReasoningContent(this.scopeOf(event), event.delta,
|
|
261
|
+
this.handleReasoningContent(this.scopeOf(event), event.delta, event.messageId, true);
|
|
258
262
|
this.totalChunks++;
|
|
259
263
|
this.recordFirstToken();
|
|
260
264
|
break;
|
|
261
|
-
case "THINKING_TEXT_MESSAGE_END":
|
|
262
|
-
case "THINKING_END":
|
|
263
|
-
this.handleReasoningEnd(ROOT_SCOPE, event.timestamp);
|
|
264
|
-
break;
|
|
265
265
|
case "REASONING_MESSAGE_END":
|
|
266
266
|
case "REASONING_END":
|
|
267
267
|
this.handleReasoningEnd(this.scopeOf(event), event.timestamp);
|
|
@@ -274,8 +274,6 @@ var RunAggregator = class {
|
|
|
274
274
|
break;
|
|
275
275
|
}
|
|
276
276
|
case "TOOL_CALL_ARGS":
|
|
277
|
-
case "TOOL_CALL_CHUNK":
|
|
278
|
-
if (event.type === "TOOL_CALL_CHUNK" && this.scopeOf(event) === ROOT_SCOPE) this.reportServerMessageId(event.parentMessageId);
|
|
279
277
|
if (!event.delta) break;
|
|
280
278
|
this.appendToolArgs(event.toolCallId, event.delta);
|
|
281
279
|
this.emit();
|
|
@@ -494,15 +492,12 @@ var RunAggregator = class {
|
|
|
494
492
|
this.hiddenSignatures.clear();
|
|
495
493
|
this.hiddenSignatureAnchors.clear();
|
|
496
494
|
this.hiddenBlockAnchors.clear();
|
|
497
|
-
this.hiddenAnonymousAnchor = void 0;
|
|
498
495
|
this.hiddenReasoningIds.clear();
|
|
499
|
-
this.
|
|
496
|
+
this.hiddenActiveReasoningId = void 0;
|
|
500
497
|
this.loggedDroppedOpaqueIds.clear();
|
|
501
|
-
this.anonymousReasoningKeys.clear();
|
|
502
498
|
this.activeReasoningKeyByScope.clear();
|
|
503
499
|
this.nestingMemo = void 0;
|
|
504
500
|
this.subagentRuns.clear();
|
|
505
|
-
this.reasoningPartCounter = 0;
|
|
506
501
|
this.toolCalls.clear();
|
|
507
502
|
this.a2uiBuckets.clear();
|
|
508
503
|
this.a2uiToolCallIds.clear();
|
|
@@ -527,10 +522,9 @@ var RunAggregator = class {
|
|
|
527
522
|
if (this.joinStrategy === "concat-content" || !messageId || this.lastTextMessageId === void 0 || this.lastTextMessageId === messageId || !this.onTextMessageStart) return;
|
|
528
523
|
const carried = this.takeTrailingReasoning();
|
|
529
524
|
if (carried.parts.length > 0 || carried.hiddenSignatures.length > 0) this.emit();
|
|
530
|
-
const
|
|
525
|
+
const openToolCallIds = Array.from(this.toolCalls.values()).filter((call) => call.result === void 0).map((call) => call.toolCallId);
|
|
531
526
|
this.resetMessageParts();
|
|
532
|
-
this.onTextMessageStart(messageId);
|
|
533
|
-
this.reasoningPartCounter = reasoningPartCounter;
|
|
527
|
+
this.onTextMessageStart(messageId, openToolCallIds);
|
|
534
528
|
this.restoreReasoning(carried);
|
|
535
529
|
}
|
|
536
530
|
takeTrailingReasoning() {
|
|
@@ -543,8 +537,7 @@ var RunAggregator = class {
|
|
|
543
537
|
entry: this.reasoningParts.get(last.key) ?? { buffer: "" },
|
|
544
538
|
signature: this.reasoningSignatures.get(last.key),
|
|
545
539
|
signatureId: this.reasoningSignatureIds.get(last.key),
|
|
546
|
-
reasoningId: this.reasoningMessageIds.get(last.key)
|
|
547
|
-
anonymous: this.anonymousReasoningKeys.has(last.key)
|
|
540
|
+
reasoningId: this.reasoningMessageIds.get(last.key)
|
|
548
541
|
});
|
|
549
542
|
last = this.partOrder.at(-1);
|
|
550
543
|
}
|
|
@@ -555,15 +548,13 @@ var RunAggregator = class {
|
|
|
555
548
|
this.hiddenSignatureAnchors.delete(id);
|
|
556
549
|
}
|
|
557
550
|
const hiddenBlockIds = Array.from(this.hiddenBlockAnchors).filter(([, anchor]) => anchor >= cut).map(([id]) => id);
|
|
558
|
-
const
|
|
559
|
-
const activeCarried = this.hiddenActiveReasoning === "identified" && hiddenBlockIds.length > 0 || this.hiddenActiveReasoning === "anonymous" && hiddenAnonymous;
|
|
551
|
+
const hiddenActiveReasoningId = this.hiddenActiveReasoningId;
|
|
560
552
|
return {
|
|
561
553
|
parts,
|
|
562
554
|
activeKey: this.activeReasoningKeyByScope.get(ROOT_SCOPE),
|
|
563
555
|
hiddenSignatures,
|
|
564
556
|
hiddenBlockIds,
|
|
565
|
-
|
|
566
|
-
hiddenActiveReasoning: activeCarried ? this.hiddenActiveReasoning : "none"
|
|
557
|
+
hiddenActiveReasoningId: hiddenActiveReasoningId !== void 0 && hiddenBlockIds.includes(hiddenActiveReasoningId) ? hiddenActiveReasoningId : void 0
|
|
567
558
|
};
|
|
568
559
|
}
|
|
569
560
|
restoreReasoning(carried) {
|
|
@@ -576,7 +567,6 @@ var RunAggregator = class {
|
|
|
576
567
|
if (part.signature !== void 0) this.reasoningSignatures.set(part.key, part.signature);
|
|
577
568
|
if (part.signatureId !== void 0) this.reasoningSignatureIds.set(part.key, part.signatureId);
|
|
578
569
|
if (part.reasoningId !== void 0) this.reasoningMessageIds.set(part.key, part.reasoningId);
|
|
579
|
-
if (part.anonymous) this.anonymousReasoningKeys.add(part.key);
|
|
580
570
|
}
|
|
581
571
|
if (carried.activeKey !== void 0 && this.reasoningParts.has(carried.activeKey)) this.activeReasoningKeyByScope.set(ROOT_SCOPE, carried.activeKey);
|
|
582
572
|
for (const [id, encryptedValue] of carried.hiddenSignatures) {
|
|
@@ -587,8 +577,7 @@ var RunAggregator = class {
|
|
|
587
577
|
this.hiddenReasoningIds.add(id);
|
|
588
578
|
this.hiddenBlockAnchors.set(id, 0);
|
|
589
579
|
}
|
|
590
|
-
|
|
591
|
-
this.hiddenActiveReasoning = carried.hiddenActiveReasoning;
|
|
580
|
+
this.hiddenActiveReasoningId = carried.hiddenActiveReasoningId;
|
|
592
581
|
}
|
|
593
582
|
generateTextKey() {
|
|
594
583
|
this.textPartCounter += 1;
|
|
@@ -696,6 +685,7 @@ var RunAggregator = class {
|
|
|
696
685
|
}
|
|
697
686
|
finishToolCall(scope, id, content, isError, toolMessageId, mcpResult) {
|
|
698
687
|
if (!id) return;
|
|
688
|
+
const modelText = toolContentText(content);
|
|
699
689
|
let entry = this.toolCalls.get(id);
|
|
700
690
|
if (!entry) {
|
|
701
691
|
entry = {
|
|
@@ -719,7 +709,7 @@ var RunAggregator = class {
|
|
|
719
709
|
entry.result = mcpResult;
|
|
720
710
|
entry.modelContent = [{
|
|
721
711
|
type: "text",
|
|
722
|
-
text:
|
|
712
|
+
text: modelText
|
|
723
713
|
}];
|
|
724
714
|
entry.snapshotResultApplied = true;
|
|
725
715
|
entry.isError = isError;
|
|
@@ -730,11 +720,12 @@ var RunAggregator = class {
|
|
|
730
720
|
} else if (entry.snapshotResultApplied) {
|
|
731
721
|
if (entry.modelContent === void 0) entry.modelContent = [{
|
|
732
722
|
type: "text",
|
|
733
|
-
text:
|
|
723
|
+
text: modelText
|
|
734
724
|
}];
|
|
735
725
|
if (entry.isError === void 0) entry.isError = isError;
|
|
736
726
|
} else {
|
|
737
|
-
entry.result = tryParseJSON(content);
|
|
727
|
+
entry.result = Array.isArray(content) ? content : tryParseJSON(content);
|
|
728
|
+
if (Array.isArray(content)) delete entry.modelContent;
|
|
738
729
|
entry.isError = isError;
|
|
739
730
|
}
|
|
740
731
|
if (toolMessageId) entry.toolMessageId = toolMessageId;
|
|
@@ -944,8 +935,9 @@ var RunAggregator = class {
|
|
|
944
935
|
const timing = this.getTiming();
|
|
945
936
|
const metadata = {
|
|
946
937
|
...timing ? { timing } : {},
|
|
947
|
-
...this.interrupts || includeOpaque ? { custom: { [AG_UI_METADATA_NAMESPACE]: {
|
|
938
|
+
...this.interrupts || this.status?.type === "requires-action" && this.status.reason === "tool-calls" && this.pendingToolCallIds || includeOpaque ? { custom: { [AG_UI_METADATA_NAMESPACE]: {
|
|
948
939
|
...this.interrupts ? { interrupts: this.interrupts } : {},
|
|
940
|
+
...this.status?.type === "requires-action" && this.status.reason === "tool-calls" && this.pendingToolCallIds ? { pendingToolCallIds: this.pendingToolCallIds } : {},
|
|
949
941
|
...includeOpaque ? { opaqueReasoning: publishableOpaqueReasoning } : {}
|
|
950
942
|
} } } : {}
|
|
951
943
|
};
|
|
@@ -978,20 +970,14 @@ var RunAggregator = class {
|
|
|
978
970
|
if (!this.showThinking) {
|
|
979
971
|
if (scope !== ROOT_SCOPE) return;
|
|
980
972
|
const anchor = this.partOrder.length;
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
} else {
|
|
985
|
-
this.hiddenReasoningIds.add(messageId);
|
|
986
|
-
this.hiddenBlockAnchors.set(messageId, anchor);
|
|
987
|
-
this.hiddenActiveReasoning = "identified";
|
|
988
|
-
}
|
|
973
|
+
this.hiddenReasoningIds.add(messageId);
|
|
974
|
+
this.hiddenBlockAnchors.set(messageId, anchor);
|
|
975
|
+
this.hiddenActiveReasoningId = messageId;
|
|
989
976
|
return;
|
|
990
977
|
}
|
|
991
978
|
this.activeTextMessageIdByScope.delete(scope);
|
|
992
|
-
const key = this.partKey(scope, messageId
|
|
993
|
-
if (
|
|
994
|
-
else if (isMessageId) this.reasoningMessageIds.set(key, messageId);
|
|
979
|
+
const key = this.partKey(scope, messageId);
|
|
980
|
+
if (isMessageId) this.reasoningMessageIds.set(key, messageId);
|
|
995
981
|
if (!this.reasoningParts.has(key)) {
|
|
996
982
|
this.reasoningParts.set(key, { buffer: "" });
|
|
997
983
|
this.partOrder.push(scope === ROOT_SCOPE ? {
|
|
@@ -1013,7 +999,7 @@ var RunAggregator = class {
|
|
|
1013
999
|
if (!delta) return;
|
|
1014
1000
|
if (!this.showThinking) {
|
|
1015
1001
|
if (scope !== ROOT_SCOPE) return;
|
|
1016
|
-
if (this.
|
|
1002
|
+
if (this.hiddenActiveReasoningId === void 0) this.handleReasoningStart(scope, messageId, isMessageId);
|
|
1017
1003
|
return;
|
|
1018
1004
|
}
|
|
1019
1005
|
if (!this.activeReasoningKeyByScope.has(scope)) this.handleReasoningStart(scope, messageId, isMessageId);
|
|
@@ -1025,7 +1011,7 @@ var RunAggregator = class {
|
|
|
1025
1011
|
}
|
|
1026
1012
|
handleReasoningEnd(scope, timestamp) {
|
|
1027
1013
|
if (!this.showThinking) {
|
|
1028
|
-
if (scope === ROOT_SCOPE) this.
|
|
1014
|
+
if (scope === ROOT_SCOPE) this.hiddenActiveReasoningId = void 0;
|
|
1029
1015
|
return;
|
|
1030
1016
|
}
|
|
1031
1017
|
const key = this.activeReasoningKeyByScope.get(scope);
|
|
@@ -1046,7 +1032,6 @@ function tryParseJSON(value) {
|
|
|
1046
1032
|
return value;
|
|
1047
1033
|
}
|
|
1048
1034
|
}
|
|
1049
|
-
//#endregion
|
|
1050
1035
|
export { RunAggregator, isPlainObject, tryParseJSON };
|
|
1051
1036
|
|
|
1052
1037
|
//# sourceMappingURL=run-aggregator.js.map
|