@assistant-ui/react-a2a 0.2.46 → 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.
@@ -1,7 +1,7 @@
1
1
  import type { AppendMessage, AssistantRuntime, ExportedMessageRepository, ThreadHistoryAdapter, ThreadMessage, Unstable_RecordToolInteractionOptions } from "@assistant-ui/core";
2
2
  import type { A2AClient } from "./A2AClient.js";
3
3
  import type { A2AArtifact, A2AAgentCard, A2ASendMessageConfiguration, A2ATask } from "./types.js";
4
- export type A2AThreadRuntimeCoreOptions = {
4
+ export type A2AThreadControllerOptions = {
5
5
  client: A2AClient;
6
6
  contextId?: string | undefined;
7
7
  configuration?: A2ASendMessageConfiguration | undefined;
@@ -10,9 +10,9 @@ export type A2AThreadRuntimeCoreOptions = {
10
10
  onArtifactComplete?: ((artifact: A2AArtifact) => void) | undefined;
11
11
  history?: ThreadHistoryAdapter | undefined;
12
12
  };
13
- export declare class A2AThreadRuntimeCore {
13
+ export declare class A2AThreadController {
14
14
  private client;
15
- private contextId;
15
+ private state;
16
16
  private configuration;
17
17
  private onError;
18
18
  private onCancel;
@@ -22,28 +22,20 @@ export declare class A2AThreadRuntimeCore {
22
22
  private snapshot;
23
23
  private runtime;
24
24
  private readonly session;
25
- private isRunningFlag;
26
25
  private abortController;
27
26
  private readonly runLeases;
28
27
  private pendingError;
29
- private currentTask;
30
- private currentArtifacts;
31
- private a2uiState;
32
- private readonly a2uiMessageIds;
33
- private agentCardValue;
34
28
  private readonly assistantHistoryParents;
35
29
  private readonly recordedHistoryIds;
36
30
  private readonly historyWrites;
37
- private _isLoading;
38
31
  private _loadPromise;
39
32
  private _historyLoadGeneration;
40
- private _loadRequested;
41
33
  private _agentCardPromise;
42
34
  private _agentCardRetryAfter;
43
35
  private _agentCardRetryDelay;
44
36
  private _agentCardDiscoveryFailed;
45
37
  private lastOptionsContextId;
46
- constructor(options: A2AThreadRuntimeCoreOptions);
38
+ constructor(options: A2AThreadControllerOptions);
47
39
  subscribe: (listener: () => void) => (() => void);
48
40
  getSnapshot: () => {
49
41
  isLoading: boolean;
@@ -53,8 +45,9 @@ export declare class A2AThreadRuntimeCore {
53
45
  artifacts: readonly A2AArtifact[];
54
46
  agentCard: A2AAgentCard | undefined;
55
47
  };
48
+ private dispatch;
56
49
  private publishUpdate;
57
- updateOptions(options: A2AThreadRuntimeCoreOptions): void;
50
+ updateOptions(options: A2AThreadControllerOptions): void;
58
51
  /** Thread-boundary reset: applyExternalMessages alone also serves branch
59
52
  * switches, deletes, and cancel resyncs, which must keep the live context. */
60
53
  resetContext(): void;
@@ -92,8 +85,6 @@ export declare class A2AThreadRuntimeCore {
92
85
  private handleTaskSnapshot;
93
86
  private insertAssistantPlaceholder;
94
87
  private updateAssistantContent;
95
- private applyA2uiMessage;
96
- private applyA2uiParts;
97
88
  private a2uiSurfaceParts;
98
89
  private withA2uiSurfaces;
99
90
  private withPreservedToolInteractions;
@@ -108,6 +99,5 @@ export declare class A2AThreadRuntimeCore {
108
99
  private markPendingAssistantHistory;
109
100
  private persistAssistantHistory;
110
101
  private appendHistoryItem;
111
- private chainHistoryWrite;
112
102
  }
113
- //# sourceMappingURL=A2AThreadRuntimeCore.d.ts.map
103
+ //# sourceMappingURL=A2AThreadController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"A2AThreadController.d.ts","sourceRoot":"","sources":["../src/A2AThreadController.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  "use client";
2
- import { a2aMessageToContent, a2uiPartsToOperations, isTerminalTaskState, taskStateToMessageStatus, threadMessageToA2AMessage } from "./conversions.js";
3
- import { RunLeases, appendToolInteraction, createMessageRepositorySession, invokeUserCallback } from "@assistant-ui/core/internal";
2
+ import { a2aMessageToContent, isTerminalTaskState, taskStateToMessageStatus, threadMessageToA2AMessage } from "./conversions.js";
3
+ import { createA2AThreadState, reduceA2AThreadState } from "./a2aThreadState.js";
4
+ import { RunLeases, appendToolInteraction, createHistoryWriteChain, createMessageRepositorySession, invokeUserCallback } from "@assistant-ui/core/internal";
4
5
  import { fromThreadMessageLike, generateId } from "@assistant-ui/core";
5
- import { applyA2uiOperations, surfaceToPresentToolCall } from "@assistant-ui/generative-ui/a2ui";
6
- //#region src/A2AThreadRuntimeCore.ts
6
+ import { surfaceToPresentToolCall } from "@assistant-ui/generative-ui/a2ui";
7
+ //#region src/A2AThreadController.ts
7
8
  const INITIAL_AGENT_CARD_RETRY_DELAY_MS = 5e3;
8
9
  const MAX_AGENT_CARD_RETRY_DELAY_MS = 3e5;
9
10
  const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -18,15 +19,9 @@ const FALLBACK_USER_STATUS = {
18
19
  const invokeRuntimeCallback = (name, callback, ...args) => {
19
20
  invokeUserCallback("react-a2a", name, callback, ...args);
20
21
  };
21
- function normalizeArtifact(artifact) {
22
- return {
23
- ...artifact,
24
- parts: Array.isArray(artifact.parts) ? artifact.parts : []
25
- };
26
- }
27
- var A2AThreadRuntimeCore = class {
22
+ var A2AThreadController = class {
28
23
  client;
29
- contextId;
24
+ state;
30
25
  configuration;
31
26
  onError;
32
27
  onCancel;
@@ -36,22 +31,14 @@ var A2AThreadRuntimeCore = class {
36
31
  snapshot;
37
32
  runtime;
38
33
  session = createMessageRepositorySession();
39
- isRunningFlag = false;
40
34
  abortController = null;
41
35
  runLeases = new RunLeases();
42
36
  pendingError = null;
43
- currentTask;
44
- currentArtifacts = [];
45
- a2uiState = /* @__PURE__ */ new Map();
46
- a2uiMessageIds = /* @__PURE__ */ new Set();
47
- agentCardValue;
48
37
  assistantHistoryParents = /* @__PURE__ */ new Map();
49
38
  recordedHistoryIds = /* @__PURE__ */ new Set();
50
- historyWrites = /* @__PURE__ */ new Map();
51
- _isLoading = false;
39
+ historyWrites = createHistoryWriteChain();
52
40
  _loadPromise;
53
41
  _historyLoadGeneration = 0;
54
- _loadRequested = false;
55
42
  _agentCardPromise;
56
43
  _agentCardRetryAfter = 0;
57
44
  _agentCardRetryDelay = INITIAL_AGENT_CARD_RETRY_DELAY_MS;
@@ -59,7 +46,7 @@ var A2AThreadRuntimeCore = class {
59
46
  lastOptionsContextId;
60
47
  constructor(options) {
61
48
  this.client = options.client;
62
- this.contextId = options.contextId;
49
+ this.state = createA2AThreadState(options.contextId);
63
50
  this.lastOptionsContextId = options.contextId;
64
51
  this.configuration = options.configuration;
65
52
  this.onError = options.onError;
@@ -72,13 +59,16 @@ var A2AThreadRuntimeCore = class {
72
59
  return () => this.listeners.delete(listener);
73
60
  };
74
61
  getSnapshot = () => this.snapshot ??= {
75
- isLoading: this._isLoading,
76
- isRunning: this.isRunningFlag,
62
+ isLoading: this.state.isLoading,
63
+ isRunning: this.state.isRunning,
77
64
  messageRepository: this.session.export(),
78
- task: this.currentTask,
79
- artifacts: this.currentArtifacts,
80
- agentCard: this.agentCardValue
65
+ task: this.state.currentTask,
66
+ artifacts: this.state.currentArtifacts,
67
+ agentCard: this.state.agentCard
81
68
  };
69
+ dispatch(action) {
70
+ this.state = reduceA2AThreadState(this.state, action);
71
+ }
82
72
  publishUpdate() {
83
73
  this.snapshot = void 0;
84
74
  for (const listener of this.listeners) listener();
@@ -86,7 +76,10 @@ var A2AThreadRuntimeCore = class {
86
76
  updateOptions(options) {
87
77
  this.client = options.client;
88
78
  if (options.contextId !== this.lastOptionsContextId) {
89
- this.contextId = options.contextId;
79
+ this.dispatch({
80
+ type: "contextLearned",
81
+ contextId: options.contextId
82
+ });
90
83
  this.lastOptionsContextId = options.contextId;
91
84
  }
92
85
  this.configuration = options.configuration;
@@ -95,16 +88,18 @@ var A2AThreadRuntimeCore = class {
95
88
  this.onArtifactComplete = options.onArtifactComplete;
96
89
  const previousHistory = this.history;
97
90
  this.history = options.history;
98
- if (this._loadRequested && !this._loadPromise && !previousHistory && options.history && this.session.getMessages().length === 0) this.__internal_load();
91
+ if (this.state.loadRequested && !this._loadPromise && !previousHistory && options.history && this.session.getMessages().length === 0) this.__internal_load();
99
92
  }
100
93
  /** Thread-boundary reset: applyExternalMessages alone also serves branch
101
94
  * switches, deletes, and cancel resyncs, which must keep the live context. */
102
95
  resetContext() {
103
96
  this._historyLoadGeneration++;
104
- const wasLoading = this._isLoading;
105
- this._isLoading = false;
97
+ const wasLoading = this.state.isLoading;
106
98
  const controller = this.abortController;
107
- this.contextId = this.lastOptionsContextId;
99
+ this.dispatch({
100
+ type: "resetContext",
101
+ contextId: this.lastOptionsContextId
102
+ });
108
103
  if (controller) {
109
104
  controller.abort();
110
105
  if (this.abortController === controller) this.abortController = null;
@@ -152,24 +147,27 @@ var A2AThreadRuntimeCore = class {
152
147
  }
153
148
  }
154
149
  getTask() {
155
- return this.currentTask;
150
+ return this.state.currentTask;
156
151
  }
157
152
  getArtifacts() {
158
- return this.currentArtifacts;
153
+ return this.state.currentArtifacts;
159
154
  }
160
155
  getAgentCard() {
161
- return this.agentCardValue;
156
+ return this.state.agentCard;
162
157
  }
163
158
  isRunning() {
164
- return this.isRunningFlag;
159
+ return this.state.isRunning;
165
160
  }
166
161
  get isLoading() {
167
- return this._isLoading;
162
+ return this.state.isLoading;
168
163
  }
169
164
  loadAgentCard() {
170
165
  if (Date.now() < this._agentCardRetryAfter) return Promise.resolve();
171
166
  this._agentCardPromise ??= this.client.getAgentCard().then((agentCard) => {
172
- this.agentCardValue = agentCard;
167
+ this.dispatch({
168
+ type: "agentCardLoaded",
169
+ agentCard
170
+ });
173
171
  this._agentCardRetryAfter = 0;
174
172
  this._agentCardRetryDelay = INITIAL_AGENT_CARD_RETRY_DELAY_MS;
175
173
  this._agentCardDiscoveryFailed = false;
@@ -200,11 +198,11 @@ var A2AThreadRuntimeCore = class {
200
198
  return !signal.aborted;
201
199
  }
202
200
  __internal_load() {
203
- this._loadRequested = true;
201
+ this.dispatch({ type: "loadRequested" });
204
202
  const agentCardPromise = this.loadAgentCard();
205
203
  if (this._loadPromise) return this._loadPromise;
206
204
  if (!this.history) return agentCardPromise;
207
- this._isLoading = true;
205
+ this.dispatch({ type: "loadStarted" });
208
206
  const generation = this._historyLoadGeneration;
209
207
  const historyPromise = this.history.load();
210
208
  this._loadPromise = historyPromise.then((repo) => {
@@ -218,7 +216,7 @@ var A2AThreadRuntimeCore = class {
218
216
  invokeRuntimeCallback("onError", this.onError, error instanceof Error ? error : new Error(String(error)));
219
217
  }).finally(() => {
220
218
  if (generation !== this._historyLoadGeneration) return;
221
- this._isLoading = false;
219
+ this.dispatch({ type: "loadFinished" });
222
220
  this.publishUpdate();
223
221
  });
224
222
  this.publishUpdate();
@@ -254,13 +252,16 @@ var A2AThreadRuntimeCore = class {
254
252
  }
255
253
  async cancel() {
256
254
  if (!this.abortController) return;
257
- const task = this.currentTask;
255
+ const task = this.state.currentTask;
258
256
  const lease = this.runLeases.current();
259
257
  this.abortController.abort();
260
258
  if (task?.id) try {
261
259
  const updated = await this.client.cancelTask(task.id);
262
- if (this.currentTask === task && lease.isCurrent()) {
263
- this.currentTask = updated;
260
+ if (this.state.currentTask === task && lease.isCurrent()) {
261
+ this.dispatch({
262
+ type: "taskReplaced",
263
+ task: updated
264
+ });
264
265
  this.publishUpdate();
265
266
  }
266
267
  } catch {}
@@ -282,10 +283,7 @@ var A2AThreadRuntimeCore = class {
282
283
  this.assistantHistoryParents.clear();
283
284
  this.recordedHistoryIds.clear();
284
285
  for (const { message } of this.getMessageRepository().messages) this.recordedHistoryIds.add(message.id);
285
- this.currentTask = void 0;
286
- this.currentArtifacts = [];
287
- this.a2uiState = /* @__PURE__ */ new Map();
288
- this.a2uiMessageIds.clear();
286
+ this.dispatch({ type: "reset" });
289
287
  this.publishUpdate();
290
288
  }
291
289
  applyExternalMessages(messages) {
@@ -324,13 +322,10 @@ var A2AThreadRuntimeCore = class {
324
322
  this.abortController = null;
325
323
  }
326
324
  const a2aMessage = threadMessageToA2AMessage(userThreadMessage, {
327
- contextId: this.contextId,
328
- taskId: this.currentTask?.id && !isTerminalTaskState(this.currentTask.status.state) ? this.currentTask.id : void 0
325
+ contextId: this.state.contextId,
326
+ taskId: this.state.currentTask?.id && !isTerminalTaskState(this.state.currentTask.status.state) ? this.state.currentTask.id : void 0
329
327
  });
330
- if (this.currentTask && isTerminalTaskState(this.currentTask.status.state)) this.currentTask = void 0;
331
- this.currentArtifacts = [];
332
- this.a2uiState = /* @__PURE__ */ new Map();
333
- this.a2uiMessageIds.clear();
328
+ this.dispatch({ type: "prepareRun" });
334
329
  const assistantParentId = userThreadMessage.id;
335
330
  const assistantId = this.insertAssistantPlaceholder(assistantParentId);
336
331
  this.markPendingAssistantHistory(assistantId, assistantParentId);
@@ -347,7 +342,7 @@ var A2AThreadRuntimeCore = class {
347
342
  this.setRunning(true);
348
343
  try {
349
344
  if (!await this.waitForAgentCard(abortController.signal)) return;
350
- if (this.agentCardValue?.capabilities?.streaming !== false) await this.runStreaming(a2aMessage, assistantId, abortController);
345
+ if (this.state.agentCard?.capabilities?.streaming !== false) await this.runStreaming(a2aMessage, assistantId, abortController);
351
346
  else await this.runSync(a2aMessage, assistantId, abortController);
352
347
  } catch (error) {
353
348
  if (!abortController.signal.aborted) {
@@ -416,18 +411,11 @@ var A2AThreadRuntimeCore = class {
416
411
  }
417
412
  }
418
413
  handleStatusUpdate(assistantId, event) {
419
- if (!this.currentTask) this.currentTask = {
420
- id: event.taskId,
421
- contextId: event.contextId,
422
- status: event.status
423
- };
424
- else this.currentTask = {
425
- ...this.currentTask,
426
- status: event.status
427
- };
428
- if (event.contextId) this.contextId = event.contextId;
414
+ this.dispatch({
415
+ type: "statusUpdate",
416
+ event
417
+ });
429
418
  if (event.status.message) {
430
- this.applyA2uiMessage(event.status.message);
431
419
  const content = a2aMessageToContent(event.status.message);
432
420
  this.updateAssistantContent(assistantId, content);
433
421
  }
@@ -436,65 +424,33 @@ var A2AThreadRuntimeCore = class {
436
424
  this.publishUpdate();
437
425
  }
438
426
  handleArtifactUpdate(assistantId, event) {
439
- const { append, lastChunk } = event;
440
- const artifact = normalizeArtifact(event.artifact);
441
- const existingIdx = this.currentArtifacts.findIndex((a) => a.artifactId === artifact.artifactId);
442
- let updated;
443
- if (existingIdx >= 0 && append) {
444
- const existing = this.currentArtifacts[existingIdx];
445
- updated = {
446
- ...existing,
447
- parts: [...existing.parts, ...artifact.parts]
448
- };
449
- this.currentArtifacts = [
450
- ...this.currentArtifacts.slice(0, existingIdx),
451
- updated,
452
- ...this.currentArtifacts.slice(existingIdx + 1)
453
- ];
454
- } else if (existingIdx >= 0) {
455
- updated = artifact;
456
- this.currentArtifacts = [
457
- ...this.currentArtifacts.slice(0, existingIdx),
458
- updated,
459
- ...this.currentArtifacts.slice(existingIdx + 1)
460
- ];
461
- } else {
462
- updated = artifact;
463
- this.currentArtifacts = [...this.currentArtifacts, updated];
464
- }
465
- this.applyA2uiParts(artifact.parts);
427
+ this.dispatch({
428
+ type: "artifactUpdate",
429
+ event
430
+ });
431
+ const updated = this.state.currentArtifacts.find(({ artifactId }) => artifactId === event.artifact.artifactId);
466
432
  this.updateAssistantArtifacts(assistantId);
467
433
  this.rebuildAssistantA2uiSurfaces(assistantId);
468
- if (lastChunk) invokeRuntimeCallback("onArtifactComplete", this.onArtifactComplete, updated);
434
+ if (event.lastChunk) invokeRuntimeCallback("onArtifactComplete", this.onArtifactComplete, updated);
469
435
  this.publishUpdate();
470
436
  }
471
437
  handleMessage(assistantId, message) {
472
438
  if (message.role !== "agent") return;
473
- this.applyA2uiMessage(message);
439
+ this.dispatch({
440
+ type: "a2uiMessage",
441
+ message
442
+ });
474
443
  const content = a2aMessageToContent(message);
475
444
  this.updateAssistantContent(assistantId, content);
476
445
  this.publishUpdate();
477
446
  }
478
447
  handleTaskSnapshot(assistantId, task) {
479
- const artifacts = task.artifacts === void 0 ? void 0 : Array.isArray(task.artifacts) ? task.artifacts.map(normalizeArtifact) : [];
480
- const history = task.history === void 0 ? void 0 : Array.isArray(task.history) ? task.history : [];
481
- this.currentTask = {
482
- ...task,
483
- ...artifacts === void 0 ? {} : { artifacts },
484
- ...history === void 0 ? {} : { history }
485
- };
486
- if (task.contextId) this.contextId = task.contextId;
487
- const isCompleteSnapshot = history !== void 0 && artifacts !== void 0;
488
- const artifactsToApply = isCompleteSnapshot ? artifacts : artifacts?.filter((artifact) => !this.currentArtifacts.some(({ artifactId }) => artifactId === artifact.artifactId));
489
- if (isCompleteSnapshot) {
490
- this.currentArtifacts = artifacts;
491
- this.a2uiState = /* @__PURE__ */ new Map();
492
- this.a2uiMessageIds.clear();
493
- } else if (artifactsToApply) this.currentArtifacts = [...this.currentArtifacts, ...artifactsToApply];
494
- for (const message of history ?? []) if (message.role === "agent") this.applyA2uiMessage(message, true);
495
- for (const artifact of artifactsToApply ?? []) this.applyA2uiParts(artifact.parts);
496
- if (task.status.message) this.applyA2uiMessage(task.status.message, true);
497
- if (isCompleteSnapshot || artifactsToApply?.length) this.updateAssistantArtifacts(assistantId);
448
+ const previousArtifacts = this.state.currentArtifacts;
449
+ this.dispatch({
450
+ type: "taskSnapshot",
451
+ task
452
+ });
453
+ if (task.history !== void 0 && task.artifacts !== void 0 || this.state.currentArtifacts.length > previousArtifacts.length) this.updateAssistantArtifacts(assistantId);
498
454
  if (task.status.message) {
499
455
  const content = a2aMessageToContent(task.status.message);
500
456
  this.updateAssistantContent(assistantId, content);
@@ -533,21 +489,9 @@ var A2AThreadRuntimeCore = class {
533
489
  };
534
490
  });
535
491
  }
536
- applyA2uiMessage(message, replay = false) {
537
- if (message.messageId) {
538
- if (replay && this.a2uiMessageIds.has(message.messageId)) return;
539
- this.a2uiMessageIds.add(message.messageId);
540
- }
541
- this.applyA2uiParts(message.parts);
542
- }
543
- applyA2uiParts(parts) {
544
- const operations = a2uiPartsToOperations(parts);
545
- if (operations.length === 0) return;
546
- this.a2uiState = applyA2uiOperations(this.a2uiState, operations).state;
547
- }
548
492
  a2uiSurfaceParts() {
549
493
  const parts = [];
550
- for (const [surfaceId, surface] of this.a2uiState) {
494
+ for (const [surfaceId, surface] of this.state.a2uiState) {
551
495
  const { toolCall } = surfaceToPresentToolCall(surfaceId, surface);
552
496
  if (!toolCall) continue;
553
497
  parts.push({
@@ -597,7 +541,7 @@ var A2AThreadRuntimeCore = class {
597
541
  ...custom,
598
542
  a2a: {
599
543
  ...a2a,
600
- artifacts: this.currentArtifacts.map(storedArtifact)
544
+ artifacts: this.state.currentArtifacts.map(storedArtifact)
601
545
  }
602
546
  }
603
547
  }
@@ -625,7 +569,7 @@ var A2AThreadRuntimeCore = class {
625
569
  return status.type === "complete" || status.type === "incomplete" || status.type === "requires-action" && status.reason === "interrupt";
626
570
  }
627
571
  setRunning(running) {
628
- this.isRunningFlag = running;
572
+ this.dispatch({ type: running ? "runStarted" : "runFinished" });
629
573
  this.publishUpdate();
630
574
  }
631
575
  finishRun(controller) {
@@ -657,7 +601,7 @@ var A2AThreadRuntimeCore = class {
657
601
  if (this.recordedHistoryIds.has(messageId)) {
658
602
  if (this.history.update) {
659
603
  const update = this.history.update.bind(this.history);
660
- const write = this.chainHistoryWrite(messageId, () => update({
604
+ const write = this.historyWrites.chain(messageId, () => update({
661
605
  parentId: resolvedParentId,
662
606
  message
663
607
  }));
@@ -665,7 +609,7 @@ var A2AThreadRuntimeCore = class {
665
609
  write.then(() => {
666
610
  this.recordedHistoryIds.add(messageId);
667
611
  }, (error) => {
668
- const pending = this.historyWrites.get(messageId);
612
+ const pending = this.historyWrites.pending(messageId);
669
613
  if (pending === void 0 || pending === write) this.assistantHistoryParents.set(messageId, resolvedParentId);
670
614
  console.error("[react-a2a] failed to update history entry", error);
671
615
  });
@@ -678,7 +622,7 @@ var A2AThreadRuntimeCore = class {
678
622
  if (!write) return;
679
623
  if (!isPausing) this.assistantHistoryParents.delete(messageId);
680
624
  write.catch((error) => {
681
- const pending = this.historyWrites.get(messageId);
625
+ const pending = this.historyWrites.pending(messageId);
682
626
  if (pending === void 0 || pending === write) this.assistantHistoryParents.set(messageId, resolvedParentId);
683
627
  console.error("[react-a2a] failed to append history entry", error);
684
628
  });
@@ -687,7 +631,7 @@ var A2AThreadRuntimeCore = class {
687
631
  if (!this.history || this.recordedHistoryIds.has(message.id)) return;
688
632
  this.recordedHistoryIds.add(message.id);
689
633
  const append = this.history.append.bind(this.history);
690
- const write = this.chainHistoryWrite(message.id, () => append({
634
+ const write = this.historyWrites.chain(message.id, () => append({
691
635
  parentId,
692
636
  message
693
637
  }));
@@ -696,25 +640,8 @@ var A2AThreadRuntimeCore = class {
696
640
  });
697
641
  return write;
698
642
  }
699
- chainHistoryWrite(id, write) {
700
- const pending = this.historyWrites.get(id);
701
- let next;
702
- if (pending) next = pending.then(write, write);
703
- else try {
704
- next = Promise.resolve(write());
705
- } catch (error) {
706
- next = Promise.reject(error);
707
- }
708
- this.historyWrites.set(id, next);
709
- next.then(() => {
710
- if (this.historyWrites.get(id) === next) this.historyWrites.delete(id);
711
- }, () => {
712
- if (this.historyWrites.get(id) === next) this.historyWrites.delete(id);
713
- });
714
- return next;
715
- }
716
643
  };
717
644
  //#endregion
718
- export { A2AThreadRuntimeCore };
645
+ export { A2AThreadController };
719
646
 
720
- //# sourceMappingURL=A2AThreadRuntimeCore.js.map
647
+ //# sourceMappingURL=A2AThreadController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"A2AThreadController.js","names":["isRecord"],"sources":["../src/A2AThreadController.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 createHistoryWriteChain,\n createMessageRepositorySession,\n invokeUserCallback,\n RunLeases,\n} from \"@assistant-ui/core/internal\";\nimport { surfaceToPresentToolCall } 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 isTerminalTaskState,\n threadMessageToA2AMessage,\n taskStateToMessageStatus,\n} from \"./conversions\";\nimport {\n createA2AThreadState,\n reduceA2AThreadState,\n type A2AThreadAction,\n type A2AThreadState,\n} from \"./a2aThreadState\";\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 A2AThreadControllerOptions = {\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\nexport class A2AThreadController {\n private client: A2AClient;\n private state: A2AThreadState;\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 abortController: AbortController | null = null;\n private readonly runLeases = new RunLeases();\n private pendingError: Error | null = null;\n\n // History tracking\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private readonly historyWrites = createHistoryWriteChain();\n private _loadPromise: Promise<void> | undefined;\n private _historyLoadGeneration = 0;\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: A2AThreadControllerOptions) {\n this.client = options.client;\n this.state = createA2AThreadState(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.state.isLoading,\n isRunning: this.state.isRunning,\n messageRepository: this.session.export(),\n task: this.state.currentTask,\n artifacts: this.state.currentArtifacts,\n agentCard: this.state.agentCard,\n });\n\n private dispatch(action: A2AThreadAction): void {\n this.state = reduceA2AThreadState(this.state, action);\n }\n\n private publishUpdate(): void {\n this.snapshot = undefined;\n for (const listener of this.listeners) listener();\n }\n\n updateOptions(options: A2AThreadControllerOptions) {\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.dispatch({\n type: \"contextLearned\",\n contextId: options.contextId,\n });\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.state.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.state.isLoading;\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.dispatch({\n type: \"resetContext\",\n contextId: this.lastOptionsContextId,\n });\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.state.currentTask;\n }\n\n getArtifacts(): readonly A2AArtifact[] {\n return this.state.currentArtifacts;\n }\n\n getAgentCard(): A2AAgentCard | undefined {\n return this.state.agentCard;\n }\n\n isRunning(): boolean {\n return this.state.isRunning;\n }\n\n get isLoading(): boolean {\n return this.state.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.dispatch({\n type: \"agentCardLoaded\",\n agentCard,\n });\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.dispatch({ type: \"loadRequested\" });\n const agentCardPromise = this.loadAgentCard();\n\n if (this._loadPromise) return this._loadPromise;\n if (!this.history) return agentCardPromise;\n\n this.dispatch({ type: \"loadStarted\" });\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.dispatch({ type: \"loadFinished\" });\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.state.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.state.currentTask === task && lease.isCurrent()) {\n this.dispatch({\n type: \"taskReplaced\",\n task: updated,\n });\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.dispatch({ type: \"reset\" });\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.state.contextId,\n taskId:\n this.state.currentTask?.id &&\n !isTerminalTaskState(this.state.currentTask.status.state)\n ? this.state.currentTask.id\n : undefined,\n });\n\n this.dispatch({ type: \"prepareRun\" });\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.state.agentCard?.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 this.dispatch({\n type: \"statusUpdate\",\n event,\n });\n\n if (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 this.dispatch({\n type: \"artifactUpdate\",\n event,\n });\n const updated = this.state.currentArtifacts.find(\n ({ artifactId }) => artifactId === event.artifact.artifactId,\n )!;\n this.updateAssistantArtifacts(assistantId);\n this.rebuildAssistantA2uiSurfaces(assistantId);\n\n if (event.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.dispatch({\n type: \"a2uiMessage\",\n message,\n });\n const content = a2aMessageToContent(message);\n this.updateAssistantContent(assistantId, content);\n this.publishUpdate();\n }\n\n private handleTaskSnapshot(assistantId: string, task: A2ATask) {\n const previousArtifacts = this.state.currentArtifacts;\n this.dispatch({\n type: \"taskSnapshot\",\n task,\n });\n\n if (\n (task.history !== undefined && task.artifacts !== undefined) ||\n this.state.currentArtifacts.length > previousArtifacts.length\n ) {\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 a2uiSurfaceParts(): ThreadAssistantMessagePart[] {\n const parts: ThreadAssistantMessagePart[] = [];\n for (const [surfaceId, surface] of this.state.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.state.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.dispatch({\n type: running ? \"runStarted\" : \"runFinished\",\n });\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.historyWrites.chain(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.pending(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.pending(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.historyWrites.chain(message.id, () =>\n append({ parentId, message }),\n );\n void write.catch(() => {\n this.recordedHistoryIds.delete(message.id);\n });\n return write;\n }\n}\n"],"mappings":"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"}