@assistant-ui/react-a2a 0.2.47 → 0.2.48

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.
@@ -0,0 +1,244 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createA2AThreadState, reduceA2AThreadState } from "./a2aThreadState";
3
+ import type {
4
+ A2AAgentCard,
5
+ A2AArtifact,
6
+ A2AMessage,
7
+ A2ATask,
8
+ A2ATaskArtifactUpdateEvent,
9
+ A2ATaskStatusUpdateEvent,
10
+ } from "./types";
11
+
12
+ const statusEvent = (
13
+ state: A2ATask["status"]["state"],
14
+ ): A2ATaskStatusUpdateEvent => ({
15
+ taskId: "task-1",
16
+ contextId: "context-1",
17
+ status: { state },
18
+ });
19
+
20
+ const artifactEvent = (
21
+ artifact: A2AArtifact,
22
+ options: Partial<A2ATaskArtifactUpdateEvent> = {},
23
+ ): A2ATaskArtifactUpdateEvent => ({
24
+ taskId: "task-1",
25
+ contextId: "context-1",
26
+ artifact,
27
+ ...options,
28
+ });
29
+
30
+ const surfaceMessage: A2AMessage = {
31
+ messageId: "message-1",
32
+ role: "agent",
33
+ parts: [
34
+ {
35
+ data: {
36
+ version: "v0.9",
37
+ createSurface: { surfaceId: "summary" },
38
+ },
39
+ },
40
+ ],
41
+ };
42
+
43
+ describe("reduceA2AThreadState", () => {
44
+ it("creates and updates a task from status events without dropping its artifacts", () => {
45
+ const initial = createA2AThreadState();
46
+ const working = reduceA2AThreadState(initial, {
47
+ type: "statusUpdate",
48
+ event: statusEvent("working"),
49
+ });
50
+ expect(working.currentTask).toEqual({
51
+ id: "task-1",
52
+ contextId: "context-1",
53
+ status: { state: "working" },
54
+ });
55
+ expect(working.contextId).toBe("context-1");
56
+
57
+ const withArtifact = reduceA2AThreadState(working, {
58
+ type: "artifactUpdate",
59
+ event: artifactEvent({ artifactId: "file-1", parts: [{ text: "a" }] }),
60
+ });
61
+ const completed = reduceA2AThreadState(withArtifact, {
62
+ type: "statusUpdate",
63
+ event: statusEvent("completed"),
64
+ });
65
+ expect(completed.currentTask?.status.state).toBe("completed");
66
+ expect(completed.currentArtifacts[0]?.parts).toEqual([{ text: "a" }]);
67
+ expect(working.currentTask?.status.state).toBe("working");
68
+ });
69
+
70
+ it("appends or replaces artifact parts and retains the updated final chunk", () => {
71
+ const first = reduceA2AThreadState(createA2AThreadState(), {
72
+ type: "artifactUpdate",
73
+ event: artifactEvent({ artifactId: "file-1", parts: [{ text: "a" }] }),
74
+ });
75
+ const appended = reduceA2AThreadState(first, {
76
+ type: "artifactUpdate",
77
+ event: artifactEvent(
78
+ { artifactId: "file-1", parts: [{ text: "b" }] },
79
+ { append: true, lastChunk: true },
80
+ ),
81
+ });
82
+ expect(appended.currentArtifacts).toEqual([
83
+ { artifactId: "file-1", parts: [{ text: "a" }, { text: "b" }] },
84
+ ]);
85
+ expect(first.currentArtifacts[0]?.parts).toEqual([{ text: "a" }]);
86
+
87
+ const replaced = reduceA2AThreadState(appended, {
88
+ type: "artifactUpdate",
89
+ event: artifactEvent({ artifactId: "file-1", parts: [{ text: "c" }] }),
90
+ });
91
+ expect(replaced.currentArtifacts[0]?.parts).toEqual([{ text: "c" }]);
92
+ });
93
+
94
+ it("merges partial task artifacts and rebuilds from a complete snapshot", () => {
95
+ const first = reduceA2AThreadState(createA2AThreadState(), {
96
+ type: "artifactUpdate",
97
+ event: artifactEvent({ artifactId: "file-1", parts: [{ text: "live" }] }),
98
+ });
99
+ const partial = reduceA2AThreadState(first, {
100
+ type: "taskSnapshot",
101
+ task: {
102
+ id: "task-1",
103
+ status: { state: "working" },
104
+ artifacts: [
105
+ { artifactId: "file-1", parts: [{ text: "stale" }] },
106
+ { artifactId: "file-2", parts: [{ text: "new" }] },
107
+ ],
108
+ },
109
+ });
110
+ expect(partial.currentArtifacts).toEqual([
111
+ { artifactId: "file-1", parts: [{ text: "live" }] },
112
+ { artifactId: "file-2", parts: [{ text: "new" }] },
113
+ ]);
114
+
115
+ const complete = reduceA2AThreadState(partial, {
116
+ type: "taskSnapshot",
117
+ task: {
118
+ id: "task-1",
119
+ status: { state: "completed" },
120
+ history: [],
121
+ artifacts: [{ artifactId: "file-1", parts: [{ text: "final" }] }],
122
+ },
123
+ });
124
+ expect(complete.currentArtifacts).toEqual([
125
+ { artifactId: "file-1", parts: [{ text: "final" }] },
126
+ ]);
127
+ });
128
+
129
+ it("tracks A2UI message ids and skips replay without mutating prior state", () => {
130
+ const initial = createA2AThreadState();
131
+ const first = reduceA2AThreadState(initial, {
132
+ type: "a2uiMessage",
133
+ message: surfaceMessage,
134
+ });
135
+ expect(first.a2uiMessageIds.has("message-1")).toBe(true);
136
+ expect(initial.a2uiMessageIds.size).toBe(0);
137
+ expect(first.a2uiState.has("summary")).toBe(true);
138
+ expect(
139
+ reduceA2AThreadState(first, {
140
+ type: "a2uiMessage",
141
+ message: surfaceMessage,
142
+ replay: true,
143
+ }),
144
+ ).toBe(first);
145
+ });
146
+
147
+ it("replays A2UI history when a complete task snapshot replaces the surface map", () => {
148
+ const first = reduceA2AThreadState(createA2AThreadState(), {
149
+ type: "a2uiMessage",
150
+ message: surfaceMessage,
151
+ });
152
+ const complete = reduceA2AThreadState(first, {
153
+ type: "taskSnapshot",
154
+ task: {
155
+ id: "task-1",
156
+ status: { state: "completed" },
157
+ history: [surfaceMessage],
158
+ artifacts: [],
159
+ },
160
+ });
161
+ expect(complete.a2uiState.has("summary")).toBe(true);
162
+ expect(complete.a2uiState).not.toBe(first.a2uiState);
163
+ expect(complete.a2uiMessageIds.has("message-1")).toBe(true);
164
+ });
165
+
166
+ it.each(["completed", "failed", "canceled", "rejected"] as const)(
167
+ "clears a %s task before the next run",
168
+ (status) => {
169
+ const withTask = reduceA2AThreadState(createA2AThreadState(), {
170
+ type: "statusUpdate",
171
+ event: statusEvent(status),
172
+ });
173
+ expect(
174
+ reduceA2AThreadState(withTask, { type: "prepareRun" }).currentTask,
175
+ ).toBeUndefined();
176
+ },
177
+ );
178
+
179
+ it("prepares a new run, resets external state, and preserves the context seed", () => {
180
+ const withTask = reduceA2AThreadState(createA2AThreadState("seed"), {
181
+ type: "statusUpdate",
182
+ event: statusEvent("failed"),
183
+ });
184
+ const prepared = reduceA2AThreadState(withTask, { type: "prepareRun" });
185
+ expect(prepared.currentTask).toBeUndefined();
186
+ expect(prepared.contextId).toBe("context-1");
187
+
188
+ const running = reduceA2AThreadState(prepared, { type: "runStarted" });
189
+ const loading = reduceA2AThreadState(running, { type: "loadStarted" });
190
+ const reset = reduceA2AThreadState(loading, { type: "reset" });
191
+ expect(reset.isRunning).toBe(true);
192
+ expect(reset.isLoading).toBe(true);
193
+ expect(reset.currentArtifacts).toEqual([]);
194
+ expect(reset.a2uiMessageIds.size).toBe(0);
195
+ const contextReset = reduceA2AThreadState(reset, {
196
+ type: "resetContext",
197
+ contextId: "seed",
198
+ });
199
+ expect(contextReset.contextId).toBe("seed");
200
+ expect(contextReset.isLoading).toBe(false);
201
+ expect(
202
+ reduceA2AThreadState(contextReset, { type: "runFinished" }).isRunning,
203
+ ).toBe(false);
204
+ });
205
+
206
+ it("returns the same state when a flag or context already matches", () => {
207
+ const initial = createA2AThreadState("seed");
208
+ expect(reduceA2AThreadState(initial, { type: "runFinished" })).toBe(
209
+ initial,
210
+ );
211
+ expect(reduceA2AThreadState(initial, { type: "loadFinished" })).toBe(
212
+ initial,
213
+ );
214
+ expect(
215
+ reduceA2AThreadState(initial, {
216
+ type: "contextLearned",
217
+ contextId: "seed",
218
+ }),
219
+ ).toBe(initial);
220
+ });
221
+
222
+ it("records agent capabilities, requested loads, and explicit context changes", () => {
223
+ const initial = createA2AThreadState("seed");
224
+ const card = { capabilities: { streaming: false } } as A2AAgentCard;
225
+ const loaded = reduceA2AThreadState(initial, {
226
+ type: "agentCardLoaded",
227
+ agentCard: card,
228
+ });
229
+ expect(loaded.agentCard).toBe(card);
230
+ const requested = reduceA2AThreadState(loaded, {
231
+ type: "loadRequested",
232
+ });
233
+ expect(requested.loadRequested).toBe(true);
234
+ expect(reduceA2AThreadState(requested, { type: "loadRequested" })).toBe(
235
+ requested,
236
+ );
237
+ expect(
238
+ reduceA2AThreadState(requested, {
239
+ type: "contextLearned",
240
+ contextId: undefined,
241
+ }).contextId,
242
+ ).toBeUndefined();
243
+ });
244
+ });
@@ -0,0 +1,242 @@
1
+ import {
2
+ applyA2uiOperations,
3
+ type A2uiState,
4
+ } from "@assistant-ui/generative-ui/a2ui";
5
+ import { a2uiPartsToOperations, isTerminalTaskState } from "./conversions";
6
+ import type {
7
+ A2AAgentCard,
8
+ A2AArtifact,
9
+ A2AMessage,
10
+ A2APart,
11
+ A2ATask,
12
+ A2ATaskArtifactUpdateEvent,
13
+ A2ATaskStatusUpdateEvent,
14
+ } from "./types";
15
+
16
+ export type A2AThreadState = {
17
+ currentTask: A2ATask | undefined;
18
+ currentArtifacts: A2AArtifact[];
19
+ a2uiState: A2uiState;
20
+ a2uiMessageIds: ReadonlySet<string>;
21
+ agentCard: A2AAgentCard | undefined;
22
+ isRunning: boolean;
23
+ isLoading: boolean;
24
+ loadRequested: boolean;
25
+ contextId: string | undefined;
26
+ };
27
+
28
+ export type A2AThreadAction =
29
+ | { type: "statusUpdate"; event: A2ATaskStatusUpdateEvent }
30
+ | { type: "artifactUpdate"; event: A2ATaskArtifactUpdateEvent }
31
+ | { type: "taskSnapshot"; task: A2ATask }
32
+ | { type: "a2uiMessage"; message: A2AMessage; replay?: boolean }
33
+ | { type: "prepareRun" }
34
+ | { type: "runStarted" }
35
+ | { type: "runFinished" }
36
+ | { type: "agentCardLoaded"; agentCard: A2AAgentCard }
37
+ | { type: "loadRequested" }
38
+ | { type: "loadStarted" }
39
+ | { type: "loadFinished" }
40
+ | { type: "contextLearned"; contextId: string | undefined }
41
+ | { type: "resetContext"; contextId: string | undefined }
42
+ | { type: "taskReplaced"; task: A2ATask }
43
+ | { type: "reset" };
44
+
45
+ export const createA2AThreadState = (contextId?: string): A2AThreadState => ({
46
+ currentTask: undefined,
47
+ currentArtifacts: [],
48
+ a2uiState: new Map(),
49
+ a2uiMessageIds: new Set(),
50
+ agentCard: undefined,
51
+ isRunning: false,
52
+ isLoading: false,
53
+ loadRequested: false,
54
+ contextId,
55
+ });
56
+
57
+ const normalizeArtifact = (artifact: A2AArtifact): A2AArtifact => ({
58
+ ...artifact,
59
+ parts: Array.isArray(artifact.parts) ? artifact.parts : [],
60
+ });
61
+
62
+ const applyParts = (
63
+ state: A2AThreadState,
64
+ parts: readonly A2APart[],
65
+ ): A2AThreadState => {
66
+ const operations = a2uiPartsToOperations(parts);
67
+ if (operations.length === 0) return state;
68
+ return {
69
+ ...state,
70
+ a2uiState: applyA2uiOperations(state.a2uiState, operations).state,
71
+ };
72
+ };
73
+
74
+ const applyMessage = (
75
+ state: A2AThreadState,
76
+ message: A2AMessage,
77
+ replay: boolean,
78
+ ): A2AThreadState => {
79
+ if (
80
+ message.messageId &&
81
+ replay &&
82
+ state.a2uiMessageIds.has(message.messageId)
83
+ )
84
+ return state;
85
+ const next = message.messageId
86
+ ? {
87
+ ...state,
88
+ a2uiMessageIds: new Set([...state.a2uiMessageIds, message.messageId]),
89
+ }
90
+ : state;
91
+ return applyParts(next, message.parts);
92
+ };
93
+
94
+ export const reduceA2AThreadState = (
95
+ state: A2AThreadState,
96
+ action: A2AThreadAction,
97
+ ): A2AThreadState => {
98
+ switch (action.type) {
99
+ case "statusUpdate": {
100
+ const { event } = action;
101
+ const currentTask = state.currentTask
102
+ ? { ...state.currentTask, status: event.status }
103
+ : {
104
+ id: event.taskId,
105
+ contextId: event.contextId,
106
+ status: event.status,
107
+ };
108
+ const next = {
109
+ ...state,
110
+ currentTask,
111
+ contextId: event.contextId || state.contextId,
112
+ };
113
+ return event.status.message
114
+ ? applyMessage(next, event.status.message, false)
115
+ : next;
116
+ }
117
+ case "artifactUpdate": {
118
+ const { artifact: input, append } = action.event;
119
+ const artifact = normalizeArtifact(input);
120
+ const index = state.currentArtifacts.findIndex(
121
+ (current) => current.artifactId === artifact.artifactId,
122
+ );
123
+ const updated =
124
+ index >= 0 && append
125
+ ? {
126
+ ...state.currentArtifacts[index]!,
127
+ parts: [
128
+ ...state.currentArtifacts[index]!.parts,
129
+ ...artifact.parts,
130
+ ],
131
+ }
132
+ : artifact;
133
+ const currentArtifacts =
134
+ index >= 0
135
+ ? [
136
+ ...state.currentArtifacts.slice(0, index),
137
+ updated,
138
+ ...state.currentArtifacts.slice(index + 1),
139
+ ]
140
+ : [...state.currentArtifacts, updated];
141
+ return applyParts({ ...state, currentArtifacts }, artifact.parts);
142
+ }
143
+ case "taskSnapshot": {
144
+ const { task } = action;
145
+ const artifacts =
146
+ task.artifacts === undefined
147
+ ? undefined
148
+ : Array.isArray(task.artifacts)
149
+ ? task.artifacts.map(normalizeArtifact)
150
+ : [];
151
+ const history =
152
+ task.history === undefined
153
+ ? undefined
154
+ : Array.isArray(task.history)
155
+ ? task.history
156
+ : [];
157
+ const complete = history !== undefined && artifacts !== undefined;
158
+ const artifactsToApply = complete
159
+ ? artifacts
160
+ : artifacts?.filter(
161
+ (artifact) =>
162
+ !state.currentArtifacts.some(
163
+ ({ artifactId }) => artifactId === artifact.artifactId,
164
+ ),
165
+ );
166
+ let next: A2AThreadState = {
167
+ ...state,
168
+ currentTask: {
169
+ ...task,
170
+ ...(artifacts === undefined ? {} : { artifacts }),
171
+ ...(history === undefined ? {} : { history }),
172
+ },
173
+ contextId: task.contextId || state.contextId,
174
+ currentArtifacts: complete
175
+ ? artifacts!
176
+ : artifactsToApply
177
+ ? [...state.currentArtifacts, ...artifactsToApply]
178
+ : state.currentArtifacts,
179
+ a2uiState: complete ? new Map() : state.a2uiState,
180
+ a2uiMessageIds: complete ? new Set() : state.a2uiMessageIds,
181
+ };
182
+ for (const message of history ?? []) {
183
+ if (message.role === "agent") next = applyMessage(next, message, true);
184
+ }
185
+ for (const artifact of artifactsToApply ?? []) {
186
+ next = applyParts(next, artifact.parts);
187
+ }
188
+ if (task.status.message) {
189
+ next = applyMessage(next, task.status.message, true);
190
+ }
191
+ return next;
192
+ }
193
+ case "a2uiMessage":
194
+ return applyMessage(state, action.message, action.replay ?? false);
195
+ case "prepareRun":
196
+ return {
197
+ ...state,
198
+ currentTask:
199
+ state.currentTask &&
200
+ isTerminalTaskState(state.currentTask.status.state)
201
+ ? undefined
202
+ : state.currentTask,
203
+ currentArtifacts: [],
204
+ a2uiState: new Map(),
205
+ a2uiMessageIds: new Set(),
206
+ };
207
+ case "runStarted":
208
+ return state.isRunning ? state : { ...state, isRunning: true };
209
+ case "runFinished":
210
+ return !state.isRunning ? state : { ...state, isRunning: false };
211
+ case "agentCardLoaded":
212
+ return state.agentCard === action.agentCard
213
+ ? state
214
+ : { ...state, agentCard: action.agentCard };
215
+ case "loadRequested":
216
+ return state.loadRequested ? state : { ...state, loadRequested: true };
217
+ case "loadStarted":
218
+ return state.isLoading ? state : { ...state, isLoading: true };
219
+ case "loadFinished":
220
+ return !state.isLoading ? state : { ...state, isLoading: false };
221
+ case "contextLearned":
222
+ return state.contextId === action.contextId
223
+ ? state
224
+ : { ...state, contextId: action.contextId };
225
+ case "resetContext":
226
+ return !state.isLoading && state.contextId === action.contextId
227
+ ? state
228
+ : { ...state, isLoading: false, contextId: action.contextId };
229
+ case "taskReplaced":
230
+ return state.currentTask === action.task
231
+ ? state
232
+ : { ...state, currentTask: action.task };
233
+ case "reset":
234
+ return {
235
+ ...state,
236
+ currentTask: undefined,
237
+ currentArtifacts: [],
238
+ a2uiState: new Map(),
239
+ a2uiMessageIds: new Set(),
240
+ };
241
+ }
242
+ };
@@ -4,7 +4,7 @@ import { act, Activity, version } from "react";
4
4
  import { afterAll, afterEach, expect, it, vi } from "vitest";
5
5
  import type { AssistantRuntime } from "@assistant-ui/core";
6
6
  import { A2AClient } from "./A2AClient";
7
- import { A2AThreadRuntimeCore } from "./A2AThreadRuntimeCore";
7
+ import { A2AThreadController } from "./A2AThreadController";
8
8
  import type { UseA2ARuntimeOptions } from "./types";
9
9
  import { useA2ARuntime } from "./useA2ARuntime";
10
10
 
@@ -75,12 +75,12 @@ it("keeps the managed client and core across refresh, then replaces both when op
75
75
  vi.spyOn(A2AClient.prototype, "getAgentCard").mockResolvedValue(
76
76
  {} as Awaited<ReturnType<A2AClient["getAgentCard"]>>,
77
77
  );
78
- const attach = vi.spyOn(A2AThreadRuntimeCore.prototype, "attachRuntime");
79
- const update = vi.spyOn(A2AThreadRuntimeCore.prototype, "updateOptions");
78
+ const attach = vi.spyOn(A2AThreadController.prototype, "attachRuntime");
79
+ const update = vi.spyOn(A2AThreadController.prototype, "updateOptions");
80
80
  options = { baseUrl: "https://first.example" };
81
81
  const { Before, After } = createProbe();
82
82
  const view = render(<Before />);
83
- const firstCore = attach.mock.instances[0]! as A2AThreadRuntimeCore;
83
+ const firstCore = attach.mock.instances[0]! as A2AThreadController;
84
84
  const firstClient = update.mock.lastCall![0].client;
85
85
 
86
86
  await refresh(Before, After);
@@ -115,8 +115,8 @@ const keepsStreamAcrossRefresh = async (
115
115
  };
116
116
  }),
117
117
  } as unknown as A2AClient;
118
- const attach = vi.spyOn(A2AThreadRuntimeCore.prototype, "attachRuntime");
119
- const detach = vi.spyOn(A2AThreadRuntimeCore.prototype, "detachRuntime");
118
+ const attach = vi.spyOn(A2AThreadController.prototype, "attachRuntime");
119
+ const detach = vi.spyOn(A2AThreadController.prototype, "detachRuntime");
120
120
  options = { client };
121
121
  const { Before, After } = createProbe();
122
122
  const Shell = ({ mode }: { mode: "visible" | "hidden" }) => (
@@ -22,7 +22,7 @@ import type {
22
22
  ThreadMessage,
23
23
  } from "@assistant-ui/core";
24
24
  import { A2AClient, type A2AClientOptions } from "./A2AClient";
25
- import { A2AThreadRuntimeCore } from "./A2AThreadRuntimeCore";
25
+ import { A2AThreadController } from "./A2AThreadController";
26
26
  import { a2aExtras } from "./a2aExtras";
27
27
  import type { UseA2ARuntimeOptions } from "./types";
28
28
 
@@ -114,7 +114,7 @@ export function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime {
114
114
  coreOptionsRef.current = coreOptions;
115
115
 
116
116
  const createCore = () =>
117
- new A2AThreadRuntimeCore({
117
+ new A2AThreadController({
118
118
  ...coreOptionsRef.current,
119
119
  client,
120
120
  });
@@ -1 +0,0 @@
1
- {"version":3,"file":"A2AThreadRuntimeCore.d.ts","sourceRoot":"","sources":["../src/A2AThreadRuntimeCore.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"A2AThreadRuntimeCore.js","names":["isRecord"],"sources":["../src/A2AThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport { generateId, fromThreadMessageLike } from \"@assistant-ui/core\";\nimport type {\n AppendMessage,\n AssistantRuntime,\n ExportedMessageRepository,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadAssistantMessagePart,\n ThreadHistoryAdapter,\n ThreadMessage,\n ToolCallMessagePart,\n Unstable_RecordToolInteractionOptions,\n} from \"@assistant-ui/core\";\nimport {\n appendToolInteraction,\n createMessageRepositorySession,\n invokeUserCallback,\n RunLeases,\n} from \"@assistant-ui/core/internal\";\nimport {\n applyA2uiOperations,\n surfaceToPresentToolCall,\n type A2uiState,\n} from \"@assistant-ui/generative-ui/a2ui\";\nimport type { A2AClient } from \"./A2AClient\";\nimport type {\n A2AArtifact,\n A2AAgentCard,\n A2AMessage,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskArtifactUpdateEvent,\n A2ATaskStatusUpdateEvent,\n} from \"./types\";\n\nimport {\n a2aMessageToContent,\n a2uiPartsToOperations,\n isTerminalTaskState,\n threadMessageToA2AMessage,\n taskStateToMessageStatus,\n} from \"./conversions\";\n\nconst INITIAL_AGENT_CARD_RETRY_DELAY_MS = 5_000;\nconst MAX_AGENT_CARD_RETRY_DELAY_MS = 5 * 60_000;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst storedArtifact = (artifact: A2AArtifact): A2AArtifact => ({\n ...artifact,\n parts: artifact.parts.map(({ raw: _raw, ...part }) => part),\n});\n\nexport type A2AThreadRuntimeCoreOptions = {\n client: A2AClient;\n contextId?: string | undefined;\n configuration?: A2ASendMessageConfiguration | undefined;\n onError?: ((error: Error) => void) | undefined;\n onCancel?: (() => void) | undefined;\n onArtifactComplete?: ((artifact: A2AArtifact) => void) | undefined;\n history?: ThreadHistoryAdapter | undefined;\n};\n\nconst FALLBACK_USER_STATUS = {\n type: \"complete\",\n reason: \"unknown\",\n} as const;\n\ntype A2ARuntimeCallbackName = \"onError\" | \"onCancel\" | \"onArtifactComplete\";\n\nconst invokeRuntimeCallback = <TArgs extends readonly unknown[]>(\n name: A2ARuntimeCallbackName,\n callback: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n): void => {\n void invokeUserCallback(\"react-a2a\", name, callback, ...args);\n};\n\nfunction normalizeArtifact(artifact: A2AArtifact): A2AArtifact {\n return {\n ...artifact,\n parts: Array.isArray(artifact.parts) ? artifact.parts : [],\n };\n}\n\nexport class A2AThreadRuntimeCore {\n private client: A2AClient;\n private contextId: string | undefined;\n private configuration: A2ASendMessageConfiguration | undefined;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private onArtifactComplete: ((artifact: A2AArtifact) => void) | undefined;\n private history: ThreadHistoryAdapter | undefined;\n private readonly listeners = new Set<() => void>();\n private snapshot:\n | {\n isLoading: boolean;\n isRunning: boolean;\n messageRepository: ExportedMessageRepository;\n task: A2ATask | undefined;\n artifacts: readonly A2AArtifact[];\n agentCard: A2AAgentCard | undefined;\n }\n | undefined;\n\n private runtime: AssistantRuntime | undefined;\n private readonly session = createMessageRepositorySession();\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n private readonly runLeases = new RunLeases();\n private pendingError: Error | null = null;\n\n // A2A-specific state\n private currentTask: A2ATask | undefined;\n private currentArtifacts: A2AArtifact[] = [];\n private a2uiState: A2uiState = new Map();\n private readonly a2uiMessageIds = new Set<string>();\n private agentCardValue: A2AAgentCard | undefined;\n\n // History tracking\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private readonly historyWrites = new Map<string, Promise<void>>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n private _historyLoadGeneration = 0;\n private _loadRequested = false;\n private _agentCardPromise: Promise<void> | undefined;\n private _agentCardRetryAfter = 0;\n private _agentCardRetryDelay = INITIAL_AGENT_CARD_RETRY_DELAY_MS;\n private _agentCardDiscoveryFailed = false;\n\n private lastOptionsContextId: string | undefined;\n\n constructor(options: A2AThreadRuntimeCoreOptions) {\n this.client = options.client;\n this.contextId = options.contextId;\n this.lastOptionsContextId = options.contextId;\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n this.history = options.history;\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = () =>\n (this.snapshot ??= {\n isLoading: this._isLoading,\n isRunning: this.isRunningFlag,\n messageRepository: this.session.export(),\n task: this.currentTask,\n artifacts: this.currentArtifacts,\n agentCard: this.agentCardValue,\n });\n\n private publishUpdate(): void {\n this.snapshot = undefined;\n for (const listener of this.listeners) listener();\n }\n\n updateOptions(options: A2AThreadRuntimeCoreOptions) {\n this.client = options.client;\n // The option only seeds the context; a re-render with the same value must\n // not clobber a server-assigned contextId learned from the stream.\n if (options.contextId !== this.lastOptionsContextId) {\n this.contextId = options.contextId;\n this.lastOptionsContextId = options.contextId;\n }\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n const previousHistory = this.history;\n this.history = options.history;\n\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 /** Thread-boundary reset: applyExternalMessages alone also serves branch\n * switches, deletes, and cancel resyncs, which must keep the live context. */\n resetContext(): void {\n this._historyLoadGeneration++;\n const wasLoading = this._isLoading;\n this._isLoading = false;\n // Restore the seed before aborting: an onCancel callback that starts a\n // new run must not pick up the old thread's context, and its controller\n // must not be discarded.\n const controller = this.abortController;\n this.contextId = this.lastOptionsContextId;\n if (controller) {\n controller.abort();\n if (this.abortController === controller) {\n this.abortController = null;\n }\n }\n if (wasLoading) this.publishUpdate();\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n // Abort in-flight requests on unmount\n const controller = this.abortController;\n if (controller) {\n controller.abort();\n if (this.abortController === controller) {\n this.abortController = null;\n }\n }\n }\n\n getRuntime(): AssistantRuntime | undefined {\n return this.runtime;\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.session.getMessages();\n }\n\n getMessageRepository(): ExportedMessageRepository {\n return this.session.export();\n }\n\n public async recordToolInteraction({\n messageId,\n toolCallId,\n interaction,\n }: Unstable_RecordToolInteractionOptions): Promise<void> {\n const message = this.session.tryGetMessage(messageId)?.message;\n if (!message) {\n throw new Error(\n \"Tried to record a tool interaction on a non-existing message\",\n );\n }\n if (message.role !== \"assistant\") {\n throw new Error(\n \"Tried to record a tool interaction on a non-assistant message\",\n );\n }\n const target = message.content.find(\n (part) => part.type === \"tool-call\" && part.toolCallId === toolCallId,\n );\n if (!target || target.type !== \"tool-call\") {\n throw new Error(\n \"Tried to record a tool interaction on a non-existing tool call\",\n );\n }\n\n const touched = this.session.updateMessage(messageId, (current) => {\n if (current.role !== \"assistant\") return current;\n return {\n ...current,\n content: current.content.map((part) =>\n part.type === \"tool-call\" && part.toolCallId === toolCallId\n ? {\n ...part,\n unstable_interactions: appendToolInteraction(\n part.unstable_interactions,\n interaction,\n ),\n }\n : part,\n ),\n };\n });\n if (touched) {\n this.publishUpdate();\n this.persistAssistantHistory(messageId);\n }\n }\n\n getTask(): A2ATask | undefined {\n return this.currentTask;\n }\n\n getArtifacts(): readonly A2AArtifact[] {\n return this.currentArtifacts;\n }\n\n getAgentCard(): A2AAgentCard | undefined {\n return this.agentCardValue;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n private loadAgentCard(): Promise<void> {\n if (Date.now() < this._agentCardRetryAfter) return Promise.resolve();\n\n this._agentCardPromise ??= this.client.getAgentCard().then(\n (agentCard) => {\n this.agentCardValue = agentCard;\n this._agentCardRetryAfter = 0;\n this._agentCardRetryDelay = INITIAL_AGENT_CARD_RETRY_DELAY_MS;\n this._agentCardDiscoveryFailed = false;\n this.publishUpdate();\n },\n () => {\n this._agentCardDiscoveryFailed = true;\n this._agentCardRetryAfter = Date.now() + this._agentCardRetryDelay;\n this._agentCardRetryDelay = Math.min(\n this._agentCardRetryDelay * 2,\n MAX_AGENT_CARD_RETRY_DELAY_MS,\n );\n this._agentCardPromise = undefined;\n },\n );\n return this._agentCardPromise;\n }\n\n private async waitForAgentCard(signal: AbortSignal): Promise<boolean> {\n const shouldWait = !this._agentCardDiscoveryFailed;\n const load = this.loadAgentCard();\n if (signal.aborted) return false;\n if (!shouldWait) return true;\n\n let onAbort!: () => void;\n const abort = new Promise<void>((resolve) => {\n onAbort = resolve;\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n try {\n await Promise.race([load, abort]);\n } finally {\n signal.removeEventListener(\"abort\", onAbort);\n }\n return !signal.aborted;\n }\n\n __internal_load(): Promise<void> {\n this._loadRequested = true;\n const agentCardPromise = this.loadAgentCard();\n\n if (this._loadPromise) return this._loadPromise;\n if (!this.history) return agentCardPromise;\n\n this._isLoading = true;\n\n const generation = this._historyLoadGeneration;\n const historyPromise = this.history.load();\n\n this._loadPromise = historyPromise\n .then((repo) => {\n if (generation !== this._historyLoadGeneration) return;\n if (repo) {\n this.session.applyExternalMessageRepository(repo);\n this.finalizeExternalApply();\n }\n })\n .catch((error) => {\n if (generation !== this._historyLoadGeneration) return;\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n if (generation !== this._historyLoadGeneration) return;\n this._isLoading = false;\n this.publishUpdate();\n });\n\n this.publishUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n\n const threadMessage = fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\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.publishUpdate();\n this.recordHistoryEntry(parentId, threadMessage);\n\n if (!startRun) return;\n await this.startRun(threadMessage);\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.publishUpdate();\n this.recordHistoryEntry(parentId, message);\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?: Record<string, unknown> } = {},\n ): Promise<void> {\n const messages =\n parentId === null\n ? []\n : (this.session.tryGetMessages(parentId) ?? this.getMessages());\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]!.role === \"user\") {\n await this.startRun(messages[i]!);\n return;\n }\n }\n }\n\n async cancel(): Promise<void> {\n if (!this.abortController) return;\n\n // Read the server target before aborting: the abort listener runs the\n // onCancel callback synchronously, which may clear the thread and with it\n // the task this cancellation is for, or start a new run.\n const task = this.currentTask;\n const lease = this.runLeases.current();\n\n // Abort locally first so the stream stops immediately\n this.abortController.abort();\n\n // Then try to cancel the task on the server\n if (task?.id) {\n try {\n const updated = await this.client.cancelTask(task.id);\n // Only apply the response while nothing newer exists. A newer snapshot\n // or a cleared thread replaces the task object; a follow-up run that\n // has not emitted yet keeps it, so the run lease is what rules\n // that case out.\n if (this.currentTask === task && lease.isCurrent()) {\n this.currentTask = updated;\n this.publishUpdate();\n }\n } catch {\n // Server cancel failed; local abort already handled\n }\n }\n }\n\n private appendLinearChain(messages: readonly ThreadMessage[]): string | null {\n let parentId: string | null = null;\n let lastId: string | null = null;\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 this.session.addOrUpdateMessage(parentId, message);\n parentId = message.id;\n lastId = message.id;\n }\n\n return lastId;\n }\n\n private finalizeExternalApply(): void {\n this.assistantHistoryParents.clear();\n this.recordedHistoryIds.clear();\n for (const { message } of this.getMessageRepository().messages) {\n this.recordedHistoryIds.add(message.id);\n }\n this.currentTask = undefined;\n this.currentArtifacts = [];\n this.a2uiState = new Map();\n this.a2uiMessageIds.clear();\n this.publishUpdate();\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\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 lastAppliedId = this.appendLinearChain(messages);\n }\n\n this.session.resetHead(lastAppliedId);\n }\n\n this.finalizeExternalApply();\n }\n\n // --- Run logic ---\n\n private async startRun(userThreadMessage: ThreadMessage): Promise<void> {\n this.runLeases.begin();\n\n // Cancel any in-progress run before starting a new one. Its abort runs\n // onCancel synchronously, and a run that callback starts keeps the thread.\n // A listener that throws before finishRun leaves `previous` installed, so\n // only a different, non-null controller counts as a replacement run.\n const previous = this.abortController;\n if (previous) {\n previous.abort();\n if (this.abortController !== previous && this.abortController !== null)\n return;\n this.abortController = null;\n }\n\n const a2aMessage = threadMessageToA2AMessage(userThreadMessage, {\n contextId: this.contextId,\n taskId:\n this.currentTask?.id &&\n !isTerminalTaskState(this.currentTask.status.state)\n ? this.currentTask.id\n : undefined,\n });\n\n // Clear task if previous task reached terminal state\n if (\n this.currentTask &&\n isTerminalTaskState(this.currentTask.status.state)\n ) {\n this.currentTask = undefined;\n }\n\n this.currentArtifacts = [];\n this.a2uiState = new Map();\n this.a2uiMessageIds.clear();\n\n const assistantParentId = userThreadMessage.id;\n const assistantId = this.insertAssistantPlaceholder(assistantParentId);\n this.markPendingAssistantHistory(assistantId, assistantParentId);\n\n const abortController = new AbortController();\n this.abortController = abortController;\n\n abortController.signal.addEventListener(\n \"abort\",\n () => {\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"cancelled\",\n });\n this.finishRun(abortController);\n invokeRuntimeCallback(\"onCancel\", this.onCancel);\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n try {\n if (!(await this.waitForAgentCard(abortController.signal))) return;\n\n const supportsStreaming =\n this.agentCardValue?.capabilities?.streaming !== false;\n if (supportsStreaming) {\n await this.runStreaming(a2aMessage, assistantId, abortController);\n } else {\n await this.runSync(a2aMessage, assistantId, abortController);\n }\n } catch (error) {\n if (!abortController.signal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"error\",\n });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n this.pendingError = this.pendingError ?? err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (this.pendingError) {\n const err = this.pendingError;\n this.pendingError = null;\n throw err;\n }\n }\n\n private async runStreaming(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const stream = this.client.streamMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n let receivedEvent = false;\n let skipReason: string | undefined;\n const diagnosedStream = (async function* () {\n const reason = yield* stream;\n if (typeof reason === \"string\") skipReason = reason;\n })();\n\n for await (const event of diagnosedStream) {\n if (abortController.signal.aborted) break;\n receivedEvent = true;\n this.handleStreamEvent(assistantId, event);\n }\n\n if (!abortController.signal.aborted) {\n if (!receivedEvent) {\n throw new Error(\n skipReason\n ? `A2A message stream ended without any events. First skipped frame: ${skipReason}`\n : \"A2A message stream ended without any events.\",\n );\n }\n\n const lastStatus = this.getAssistantStatus(assistantId);\n if (lastStatus?.type === \"running\") {\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n }\n\n private async runSync(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const result = await this.client.sendMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n if (abortController.signal.aborted) return;\n\n // Result is either A2ATask or A2AMessage\n if (\"id\" in result && \"status\" in result) {\n // It's a Task\n this.handleTaskSnapshot(assistantId, result as A2ATask);\n } else if (\"messageId\" in result && \"parts\" in result) {\n // It's a Message\n this.handleMessage(assistantId, result as A2AMessage);\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n\n private handleStreamEvent(assistantId: string, event: A2AStreamEvent) {\n switch (event.type) {\n case \"statusUpdate\":\n this.handleStatusUpdate(assistantId, event.event);\n break;\n case \"artifactUpdate\":\n this.handleArtifactUpdate(assistantId, event.event);\n break;\n case \"message\":\n this.handleMessage(assistantId, event.message);\n break;\n case \"task\":\n this.handleTaskSnapshot(assistantId, event.task);\n break;\n }\n }\n\n private handleStatusUpdate(\n assistantId: string,\n event: A2ATaskStatusUpdateEvent,\n ) {\n if (!this.currentTask) {\n this.currentTask = {\n id: event.taskId,\n contextId: event.contextId,\n status: event.status,\n };\n } else {\n this.currentTask = { ...this.currentTask, status: event.status };\n }\n\n if (event.contextId) {\n this.contextId = event.contextId;\n }\n\n if (event.status.message) {\n this.applyA2uiMessage(event.status.message);\n const content = a2aMessageToContent(event.status.message);\n this.updateAssistantContent(assistantId, content);\n }\n\n const status = taskStateToMessageStatus(event.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.publishUpdate();\n }\n\n private handleArtifactUpdate(\n assistantId: string,\n event: A2ATaskArtifactUpdateEvent,\n ) {\n const { append, lastChunk } = event;\n const artifact = normalizeArtifact(event.artifact);\n const existingIdx = this.currentArtifacts.findIndex(\n (a) => a.artifactId === artifact.artifactId,\n );\n\n let updated: A2AArtifact;\n if (existingIdx >= 0 && append) {\n const existing = this.currentArtifacts[existingIdx]!;\n updated = {\n ...existing,\n parts: [...existing.parts, ...artifact.parts],\n };\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else if (existingIdx >= 0) {\n updated = artifact;\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else {\n updated = artifact;\n this.currentArtifacts = [...this.currentArtifacts, updated];\n }\n\n this.applyA2uiParts(artifact.parts);\n this.updateAssistantArtifacts(assistantId);\n this.rebuildAssistantA2uiSurfaces(assistantId);\n\n if (lastChunk) {\n invokeRuntimeCallback(\n \"onArtifactComplete\",\n this.onArtifactComplete,\n updated,\n );\n }\n\n this.publishUpdate();\n }\n\n private handleMessage(assistantId: string, message: A2AMessage) {\n if (message.role !== \"agent\") return;\n\n this.applyA2uiMessage(message);\n const content = a2aMessageToContent(message);\n this.updateAssistantContent(assistantId, content);\n this.publishUpdate();\n }\n\n private handleTaskSnapshot(assistantId: string, task: A2ATask) {\n const artifacts =\n task.artifacts === undefined\n ? undefined\n : Array.isArray(task.artifacts)\n ? task.artifacts.map(normalizeArtifact)\n : [];\n const history =\n task.history === undefined\n ? undefined\n : Array.isArray(task.history)\n ? task.history\n : [];\n this.currentTask = {\n ...task,\n ...(artifacts === undefined ? {} : { artifacts }),\n ...(history === undefined ? {} : { history }),\n };\n\n if (task.contextId) {\n this.contextId = task.contextId;\n }\n const isCompleteSnapshot = history !== undefined && artifacts !== undefined;\n const artifactsToApply = isCompleteSnapshot\n ? artifacts\n : artifacts?.filter(\n (artifact) =>\n !this.currentArtifacts.some(\n ({ artifactId }) => artifactId === artifact.artifactId,\n ),\n );\n\n if (isCompleteSnapshot) {\n this.currentArtifacts = artifacts;\n this.a2uiState = new Map();\n this.a2uiMessageIds.clear();\n } else if (artifactsToApply) {\n this.currentArtifacts = [...this.currentArtifacts, ...artifactsToApply];\n }\n\n for (const message of history ?? []) {\n if (message.role === \"agent\") this.applyA2uiMessage(message, true);\n }\n for (const artifact of artifactsToApply ?? []) {\n this.applyA2uiParts(artifact.parts);\n }\n if (task.status.message) {\n this.applyA2uiMessage(task.status.message, true);\n }\n\n if (isCompleteSnapshot || artifactsToApply?.length) {\n this.updateAssistantArtifacts(assistantId);\n }\n\n if (task.status.message) {\n const content = a2aMessageToContent(task.status.message);\n this.updateAssistantContent(assistantId, content);\n } else {\n this.rebuildAssistantA2uiSurfaces(assistantId);\n }\n\n const status = taskStateToMessageStatus(task.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.publishUpdate();\n }\n\n // --- Message helpers ---\n\n private insertAssistantPlaceholder(parentId: string): string {\n const id = generateId();\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n };\n this.session.addOrUpdateMessage(parentId, assistant);\n this.session.switchToBranch(id);\n this.publishUpdate();\n return id;\n }\n\n private updateAssistantContent(\n messageId: string,\n content: ThreadAssistantMessage[\"content\"],\n ) {\n this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return {\n ...message,\n content: this.withA2uiSurfaces(content, message.content),\n };\n });\n }\n\n private applyA2uiMessage(message: A2AMessage, replay = false) {\n if (message.messageId) {\n if (replay && this.a2uiMessageIds.has(message.messageId)) return;\n this.a2uiMessageIds.add(message.messageId);\n }\n this.applyA2uiParts(message.parts);\n }\n\n private applyA2uiParts(parts: readonly A2AMessage[\"parts\"][number][]) {\n const operations = a2uiPartsToOperations(parts);\n if (operations.length === 0) return;\n this.a2uiState = applyA2uiOperations(this.a2uiState, operations).state;\n }\n\n private a2uiSurfaceParts(): ThreadAssistantMessagePart[] {\n const parts: ThreadAssistantMessagePart[] = [];\n for (const [surfaceId, surface] of this.a2uiState) {\n const { toolCall } = surfaceToPresentToolCall(surfaceId, surface);\n if (!toolCall) continue;\n parts.push({\n type: \"tool-call\",\n ...toolCall,\n });\n }\n return parts;\n }\n\n private withA2uiSurfaces(\n content: ThreadAssistantMessage[\"content\"],\n previousContent: ThreadAssistantMessage[\"content\"] = content,\n ): ThreadAssistantMessage[\"content\"] {\n const preserved = content.filter(\n (part) =>\n !(part.type === \"tool-call\" && part.toolCallId.startsWith(\"a2ui:\")),\n );\n const interactionSource = [...previousContent, ...content];\n return this.withPreservedToolInteractions(interactionSource, [\n ...preserved,\n ...this.a2uiSurfaceParts(),\n ]);\n }\n\n private withPreservedToolInteractions(\n previousContent: ThreadAssistantMessage[\"content\"],\n content: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const interactions = new Map<\n string,\n ToolCallMessagePart[\"unstable_interactions\"]\n >();\n for (const part of previousContent) {\n if (\n part.type === \"tool-call\" &&\n part.unstable_interactions !== undefined\n ) {\n interactions.set(part.toolCallId, part.unstable_interactions);\n }\n }\n if (interactions.size === 0) return content;\n return content.map((part) => {\n if (\n part.type !== \"tool-call\" ||\n part.unstable_interactions !== undefined\n ) {\n return part;\n }\n const unstable_interactions = interactions.get(part.toolCallId);\n return unstable_interactions === undefined\n ? part\n : { ...part, unstable_interactions };\n });\n }\n\n private rebuildAssistantA2uiSurfaces(messageId: string) {\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return {\n ...message,\n content: this.withA2uiSurfaces(message.content),\n };\n });\n if (touched) this.publishUpdate();\n }\n\n private updateAssistantArtifacts(messageId: string) {\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n const custom = message.metadata.custom;\n const a2a = isRecord(custom.a2a) ? custom.a2a : {};\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: {\n ...custom,\n a2a: {\n ...a2a,\n artifacts: this.currentArtifacts.map(storedArtifact),\n },\n },\n },\n };\n });\n if (touched) this.publishUpdate();\n }\n\n private updateAssistantStatus(messageId: string, status: MessageStatus) {\n const touched = this.session.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return { ...message, status };\n });\n if (touched) {\n this.publishUpdate();\n if (this.isPersistableAssistantStatus(status)) {\n this.persistAssistantHistory(messageId);\n }\n }\n }\n\n private getAssistantStatus(messageId: string): MessageStatus | undefined {\n const msg = this.session.tryGetMessage(messageId)?.message;\n if (msg?.role !== \"assistant\") return undefined;\n return msg.status;\n }\n\n private isPersistableAssistantStatus(status: MessageStatus): boolean {\n return (\n status.type === \"complete\" ||\n status.type === \"incomplete\" ||\n (status.type === \"requires-action\" && status.reason === \"interrupt\")\n );\n }\n\n // --- Lifecycle helpers ---\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.publishUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController !== controller) return;\n this.abortController = null;\n this.setRunning(false);\n }\n\n // --- History persistence ---\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n void this.appendHistoryItem(parentId, message)?.catch((error) => {\n console.error(\"[react-a2a] 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 if (!this.history) return;\n const messageData = this.session.tryGetMessage(messageId);\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined && !this.recordedHistoryIds.has(messageId)) {\n return;\n }\n const resolvedParentId =\n parentId === undefined ? messageData?.parentId : parentId;\n if (resolvedParentId === undefined) return;\n const message = messageData?.message;\n if (!message || message.role !== \"assistant\") return;\n if (!this.isPersistableAssistantStatus(message.status)) return;\n const isPausing = message.status.type === \"requires-action\";\n\n if (isPausing && !this.history.update) return;\n\n if (this.recordedHistoryIds.has(messageId)) {\n if (this.history.update) {\n const update = this.history.update.bind(this.history);\n const write = this.chainHistoryWrite(messageId, () =>\n update({ parentId: resolvedParentId, message }),\n );\n if (!isPausing) {\n this.assistantHistoryParents.delete(messageId);\n }\n void write.then(\n () => {\n this.recordedHistoryIds.add(messageId);\n },\n (error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, resolvedParentId);\n }\n console.error(\"[react-a2a] failed to update history entry\", error);\n },\n );\n return;\n }\n if (!isPausing) {\n this.assistantHistoryParents.delete(messageId);\n }\n return;\n }\n const write = this.appendHistoryItem(resolvedParentId, message);\n if (!write) return;\n if (!isPausing) {\n this.assistantHistoryParents.delete(messageId);\n }\n void write.catch((error) => {\n const pending = this.historyWrites.get(messageId);\n if (pending === undefined || pending === write) {\n this.assistantHistoryParents.set(messageId, resolvedParentId);\n }\n console.error(\"[react-a2a] failed to append history entry\", error);\n });\n }\n\n private appendHistoryItem(\n parentId: string | null,\n message: ThreadMessage,\n ): Promise<void> | undefined {\n if (!this.history || this.recordedHistoryIds.has(message.id)) return;\n this.recordedHistoryIds.add(message.id);\n const append = this.history.append.bind(this.history);\n const write = this.chainHistoryWrite(message.id, () =>\n append({ parentId, message }),\n );\n void write.catch(() => {\n this.recordedHistoryIds.delete(message.id);\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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"}