@assistant-ui/react-ag-ui 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/AgUiThreadController.d.ts +10 -0
- package/dist/runtime/AgUiThreadController.d.ts.map +1 -1
- package/dist/runtime/AgUiThreadController.js +86 -32
- package/dist/runtime/AgUiThreadController.js.map +1 -1
- package/dist/runtime/adapter/conversions.d.ts +10 -0
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +9 -4
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/types.d.ts +6 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/useAgUiRuntime.d.ts.map +1 -1
- package/dist/useAgUiRuntime.js +6 -2
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +1 -1
- package/src/runtime/AgUiThreadController.connect.test.ts +372 -0
- package/src/runtime/AgUiThreadController.notifications.test.ts +126 -0
- package/src/runtime/AgUiThreadController.ts +158 -36
- package/src/runtime/adapter/conversions.subagent-messages.test.ts +117 -0
- package/src/runtime/adapter/conversions.ts +40 -5
- package/src/runtime/types.ts +6 -0
- package/src/useAgUiRuntime.connect.test.tsx +169 -0
- package/src/useAgUiRuntime.external-store.test.tsx +46 -1
- package/src/useAgUiRuntime.ts +8 -2
|
@@ -15,6 +15,7 @@ type CoreOptions = {
|
|
|
15
15
|
logger: Logger;
|
|
16
16
|
showThinking: boolean;
|
|
17
17
|
joinStrategy?: UseAgUiRuntimeOptions["joinStrategy"];
|
|
18
|
+
joinAdjacentAssistantMessages?: boolean | undefined;
|
|
18
19
|
getRunContext?: UseAgUiRuntimeOptions["getRunContext"];
|
|
19
20
|
resumeTranscript?: AgUiResumeTranscript | undefined;
|
|
20
21
|
autoCancelPendingToolCalls?: boolean | undefined;
|
|
@@ -27,6 +28,7 @@ export declare class AgUiThreadController {
|
|
|
27
28
|
private agent;
|
|
28
29
|
private logger;
|
|
29
30
|
private showThinking;
|
|
31
|
+
private joinAdjacentAssistantMessages;
|
|
30
32
|
private joinStrategy;
|
|
31
33
|
private getRunContext;
|
|
32
34
|
private resumeTranscript;
|
|
@@ -34,6 +36,7 @@ export declare class AgUiThreadController {
|
|
|
34
36
|
private onError;
|
|
35
37
|
private onCancel;
|
|
36
38
|
private readonly listeners;
|
|
39
|
+
private pendingUpdateNotification;
|
|
37
40
|
private snapshot;
|
|
38
41
|
private readonly isThreadSwitching;
|
|
39
42
|
private readonly reportedErrors;
|
|
@@ -65,6 +68,11 @@ export declare class AgUiThreadController {
|
|
|
65
68
|
updateOptions(options: CoreOptions): void;
|
|
66
69
|
attachRuntime(runtime: AssistantRuntime): void;
|
|
67
70
|
detachRuntime(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Stops following the active run because the thread is being left (a thread
|
|
73
|
+
* switch or teardown), as opposed to cancel(), which the user asked for.
|
|
74
|
+
*/
|
|
75
|
+
leave(): void;
|
|
68
76
|
getMessages(): readonly ThreadMessage[];
|
|
69
77
|
getMessageRepository(): ExportedMessageRepository;
|
|
70
78
|
getState(): ReadonlyJSONValue | undefined;
|
|
@@ -85,9 +93,11 @@ export declare class AgUiThreadController {
|
|
|
85
93
|
deleteMessage(messageId: string): Promise<void>;
|
|
86
94
|
cancel(): Promise<void>;
|
|
87
95
|
private abortActiveRun;
|
|
96
|
+
private stopAgent;
|
|
88
97
|
private supersedeActiveRun;
|
|
89
98
|
resume(config: ResumeRunConfig): Promise<void>;
|
|
90
99
|
resumeInFlightRun(messages: readonly ThreadMessage[]): Promise<void>;
|
|
100
|
+
private getResumeSource;
|
|
91
101
|
private assertNoPendingInterrupts;
|
|
92
102
|
private findRequiresActionAssistant;
|
|
93
103
|
private getTrailingAssistantTurn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgUiThreadController.d.ts","sourceRoot":"","sources":["../../src/runtime/AgUiThreadController.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EAEzB,4BAA4B,EAC5B,SAAS,EAET,oBAAoB,EACpB,aAAa,EAEb,wBAAwB,EACzB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAiB;AAEvC,OAAO,KAAK,EAGV,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACtB,mBAAgB;AAEjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAgKhE,KAAK,YAAY,GAAG,CAClB,OAAO,EAAE,mBAAmB,KACzB,cAAc,CAAC,kBAAkB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"AgUiThreadController.d.ts","sourceRoot":"","sources":["../../src/runtime/AgUiThreadController.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,12 @@ const actionableToolCallIds = (message) => {
|
|
|
61
61
|
return new Set(Array.from(iterateToolCallParts(message.content)).filter((part) => !isResolvedToolCall(part) && (!permitted || permitted.has(part.toolCallId))).map((part) => part.toolCallId));
|
|
62
62
|
};
|
|
63
63
|
const isActivityPart = (part) => part.type === "data" && part.name.startsWith("agui-activity/");
|
|
64
|
+
const implementsConnect = (agent) => {
|
|
65
|
+
if (typeof agent.connectAgent !== "function") return false;
|
|
66
|
+
if (Object.prototype.hasOwnProperty.call(agent, "connect")) return true;
|
|
67
|
+
for (let proto = Object.getPrototypeOf(agent); proto !== null; proto = Object.getPrototypeOf(proto)) if (Object.prototype.hasOwnProperty.call(proto, "connect")) return Object.getPrototypeOf(proto) !== Object.prototype;
|
|
68
|
+
return false;
|
|
69
|
+
};
|
|
64
70
|
const FALLBACK_USER_STATUS = {
|
|
65
71
|
type: "complete",
|
|
66
72
|
reason: "unknown"
|
|
@@ -141,6 +147,7 @@ var AgUiThreadController = class {
|
|
|
141
147
|
agent;
|
|
142
148
|
logger;
|
|
143
149
|
showThinking;
|
|
150
|
+
joinAdjacentAssistantMessages;
|
|
144
151
|
joinStrategy;
|
|
145
152
|
getRunContext;
|
|
146
153
|
resumeTranscript;
|
|
@@ -148,6 +155,7 @@ var AgUiThreadController = class {
|
|
|
148
155
|
onError;
|
|
149
156
|
onCancel;
|
|
150
157
|
listeners = /* @__PURE__ */ new Set();
|
|
158
|
+
pendingUpdateNotification;
|
|
151
159
|
snapshot;
|
|
152
160
|
isThreadSwitching;
|
|
153
161
|
reportedErrors = /* @__PURE__ */ new WeakSet();
|
|
@@ -188,6 +196,7 @@ var AgUiThreadController = class {
|
|
|
188
196
|
});
|
|
189
197
|
this.logger = options.logger;
|
|
190
198
|
this.showThinking = options.showThinking;
|
|
199
|
+
this.joinAdjacentAssistantMessages = options.joinAdjacentAssistantMessages ?? false;
|
|
191
200
|
this.joinStrategy = options.joinStrategy;
|
|
192
201
|
this.getRunContext = options.getRunContext;
|
|
193
202
|
this.resumeTranscript = options.resumeTranscript ?? "full";
|
|
@@ -210,8 +219,20 @@ var AgUiThreadController = class {
|
|
|
210
219
|
dispatch(action) {
|
|
211
220
|
this.state = reduceAgUiThreadState(this.state, action);
|
|
212
221
|
}
|
|
213
|
-
publishUpdate() {
|
|
222
|
+
publishUpdate(deferNotification = false) {
|
|
214
223
|
this.snapshot = void 0;
|
|
224
|
+
if (deferNotification) {
|
|
225
|
+
if (this.pendingUpdateNotification !== void 0) return;
|
|
226
|
+
this.pendingUpdateNotification = setTimeout(() => {
|
|
227
|
+
this.pendingUpdateNotification = void 0;
|
|
228
|
+
for (const listener of this.listeners) listener();
|
|
229
|
+
}, 0);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (this.pendingUpdateNotification !== void 0) {
|
|
233
|
+
clearTimeout(this.pendingUpdateNotification);
|
|
234
|
+
this.pendingUpdateNotification = void 0;
|
|
235
|
+
}
|
|
215
236
|
for (const listener of this.listeners) listener();
|
|
216
237
|
}
|
|
217
238
|
updateOptions(options) {
|
|
@@ -229,6 +250,7 @@ var AgUiThreadController = class {
|
|
|
229
250
|
}
|
|
230
251
|
this.logger = options.logger;
|
|
231
252
|
this.showThinking = options.showThinking;
|
|
253
|
+
this.joinAdjacentAssistantMessages = options.joinAdjacentAssistantMessages ?? false;
|
|
232
254
|
this.joinStrategy = options.joinStrategy;
|
|
233
255
|
this.getRunContext = options.getRunContext;
|
|
234
256
|
this.resumeTranscript = options.resumeTranscript ?? "full";
|
|
@@ -244,9 +266,19 @@ var AgUiThreadController = class {
|
|
|
244
266
|
}
|
|
245
267
|
detachRuntime() {
|
|
246
268
|
this.runtime = void 0;
|
|
247
|
-
|
|
269
|
+
try {
|
|
270
|
+
this.leave();
|
|
271
|
+
} catch (error) {
|
|
248
272
|
this.logger.error("[agui] failed to cancel run during teardown", error);
|
|
249
|
-
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Stops following the active run because the thread is being left (a thread
|
|
277
|
+
* switch or teardown), as opposed to cancel(), which the user asked for.
|
|
278
|
+
*/
|
|
279
|
+
leave() {
|
|
280
|
+
this.dispatch({ type: "historyMutationAdvanced" });
|
|
281
|
+
this.abortActiveRun(true);
|
|
250
282
|
}
|
|
251
283
|
getMessages() {
|
|
252
284
|
return this.session.getMessages();
|
|
@@ -289,8 +321,7 @@ var AgUiThreadController = class {
|
|
|
289
321
|
this._loadPromise = promise.then(async (repo) => {
|
|
290
322
|
if (repo?.unstable_resume) {
|
|
291
323
|
const parentId = repo.headId ?? this.session.headId;
|
|
292
|
-
|
|
293
|
-
await this.startRun(parentId, this.state.lastRunConfig, void 0, resumeStream);
|
|
324
|
+
await this.startRun(parentId, this.state.lastRunConfig, void 0, this.getResumeSource());
|
|
294
325
|
}
|
|
295
326
|
}).catch((error) => {
|
|
296
327
|
this.logger.error?.("[agui] failed to load history", error);
|
|
@@ -395,15 +426,24 @@ var AgUiThreadController = class {
|
|
|
395
426
|
this.dispatch({ type: "historyMutationAdvanced" });
|
|
396
427
|
this.abortActiveRun();
|
|
397
428
|
}
|
|
398
|
-
abortActiveRun() {
|
|
429
|
+
abortActiveRun(leaveRunning = false) {
|
|
399
430
|
const controller = this.abortController;
|
|
400
431
|
if (!controller) return;
|
|
401
432
|
try {
|
|
402
|
-
(this.activeRunAgent ?? this.agent)
|
|
433
|
+
this.stopAgent(this.activeRunAgent ?? this.agent, leaveRunning);
|
|
403
434
|
} finally {
|
|
404
435
|
controller.abort();
|
|
405
436
|
}
|
|
406
437
|
}
|
|
438
|
+
stopAgent(agent, leaveRunning) {
|
|
439
|
+
if (leaveRunning && implementsConnect(agent)) {
|
|
440
|
+
agent.detachActiveRun().catch((error) => {
|
|
441
|
+
this.logger.error?.("[agui] agent detachActiveRun failed", error);
|
|
442
|
+
});
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
agent.abortRun();
|
|
446
|
+
}
|
|
407
447
|
supersedeActiveRun() {
|
|
408
448
|
try {
|
|
409
449
|
this.abortActiveRun();
|
|
@@ -423,18 +463,23 @@ var AgUiThreadController = class {
|
|
|
423
463
|
async resumeInFlightRun(messages) {
|
|
424
464
|
const historyImport = this.waitForHistoryImport();
|
|
425
465
|
if (historyImport && !await historyImport) return;
|
|
426
|
-
const
|
|
427
|
-
if (!
|
|
428
|
-
const error = /* @__PURE__ */ new Error("[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method; skipping resume after thread switch");
|
|
466
|
+
const resumeSource = this.getResumeSource();
|
|
467
|
+
if (!resumeSource) {
|
|
468
|
+
const error = /* @__PURE__ */ new Error("[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method or an agent that implements connect(); skipping resume after thread switch");
|
|
429
469
|
this.logger.error?.(error.message);
|
|
430
470
|
invokeRuntimeCallback("onError", this.onError, error);
|
|
431
471
|
return;
|
|
432
472
|
}
|
|
433
473
|
const parentId = messages.at(-1)?.id ?? null;
|
|
434
474
|
try {
|
|
435
|
-
await this.startRun(parentId, this.state.lastRunConfig, void 0,
|
|
475
|
+
await this.startRun(parentId, this.state.lastRunConfig, void 0, resumeSource);
|
|
436
476
|
} catch {}
|
|
437
477
|
}
|
|
478
|
+
getResumeSource() {
|
|
479
|
+
const resumeStream = this.history?.resume?.bind(this.history);
|
|
480
|
+
if (resumeStream) return resumeStream;
|
|
481
|
+
return implementsConnect(this.agent) ? "connect" : void 0;
|
|
482
|
+
}
|
|
438
483
|
assertNoPendingInterrupts() {
|
|
439
484
|
if (!this.getPendingInterrupts()) return;
|
|
440
485
|
throw new Error("[agui] cannot start a new run while interrupts are pending; resolve them with submitInterruptResponses()");
|
|
@@ -957,7 +1002,7 @@ var AgUiThreadController = class {
|
|
|
957
1002
|
this.activeRunAgent = null;
|
|
958
1003
|
this.setRunning(false);
|
|
959
1004
|
try {
|
|
960
|
-
(activeRunAgent ?? this.agent)
|
|
1005
|
+
this.stopAgent(activeRunAgent ?? this.agent, true);
|
|
961
1006
|
} catch (error) {
|
|
962
1007
|
this.logger.error?.("[agui] agent abortRun failed", error);
|
|
963
1008
|
} finally {
|
|
@@ -965,8 +1010,9 @@ var AgUiThreadController = class {
|
|
|
965
1010
|
}
|
|
966
1011
|
} else this.publishUpdate();
|
|
967
1012
|
}
|
|
968
|
-
async startRun(parentId, runConfig, resume,
|
|
1013
|
+
async startRun(parentId, runConfig, resume, resumeSource, replayExistingMessages = false) {
|
|
969
1014
|
if (this.isThreadSwitching?.()) return;
|
|
1015
|
+
const resumeStream = typeof resumeSource === "function" ? resumeSource : void 0;
|
|
970
1016
|
if (!this.supersedeActiveRun()) return;
|
|
971
1017
|
const generation = this.state.historyMutationGeneration;
|
|
972
1018
|
const normalizedRunConfig = runConfig ?? {};
|
|
@@ -1019,6 +1065,7 @@ var AgUiThreadController = class {
|
|
|
1019
1065
|
let frameOwnerIds = /* @__PURE__ */ new Set();
|
|
1020
1066
|
let restrictedPendingToolCallIds;
|
|
1021
1067
|
let settlingRun = false;
|
|
1068
|
+
let deferUpdateNotifications = false;
|
|
1022
1069
|
let latestSnapshot;
|
|
1023
1070
|
let snapshotToolCallIds = /* @__PURE__ */ new Set();
|
|
1024
1071
|
const snapshotResultIds = /* @__PURE__ */ new Set();
|
|
@@ -1030,7 +1077,7 @@ var AgUiThreadController = class {
|
|
|
1030
1077
|
if (cached !== void 0 && (assistantCollided || !allowRecreate)) return cached;
|
|
1031
1078
|
const repositoryHeadId = this.session.headId;
|
|
1032
1079
|
const parentId = replayContexts.size === 0 && (cached === void 0 || shouldEagerlyInsertAssistant && (repositoryHeadId === null || runStartMessageIds.has(repositoryHeadId))) && (replayMessageIds.length === 0 || repositoryHeadId === null || runStartMessageIds.has(repositoryHeadId)) && assistantParentId && this.session.hasMessage(assistantParentId) ? assistantParentId : repositoryHeadId;
|
|
1033
|
-
const created = this.insertAssistantPlaceholder(parentId, cached);
|
|
1080
|
+
const created = this.insertAssistantPlaceholder(parentId, cached, deferUpdateNotifications);
|
|
1034
1081
|
assistantMessageId = created;
|
|
1035
1082
|
this.markPendingAssistantHistory(created, parentId);
|
|
1036
1083
|
return created;
|
|
@@ -1153,7 +1200,7 @@ var AgUiThreadController = class {
|
|
|
1153
1200
|
this.updateAssistantMessage(ownerId, {
|
|
1154
1201
|
...contentOwnerIds?.has(ownerId) ? { content } : {},
|
|
1155
1202
|
...ownerStatus ? { status: ownerStatus } : {}
|
|
1156
|
-
}, replayContexts.get(ownerId), interrupt ? /* @__PURE__ */ new Set() : restrictedPendingToolCallIds);
|
|
1203
|
+
}, replayContexts.get(ownerId), interrupt ? /* @__PURE__ */ new Set() : restrictedPendingToolCallIds, deferUpdateNotifications);
|
|
1157
1204
|
}
|
|
1158
1205
|
const { content: _content, ...controlUpdate } = update;
|
|
1159
1206
|
const content = ownerParts.get(messageId) ?? [];
|
|
@@ -1163,7 +1210,7 @@ var AgUiThreadController = class {
|
|
|
1163
1210
|
...ownerStatus && !interrupt && replayContexts.has(messageId) ? { status: ownerStatus } : {}
|
|
1164
1211
|
};
|
|
1165
1212
|
}
|
|
1166
|
-
const resolved = this.updateAssistantMessage(messageId, primaryUpdate, replayContexts.get(messageId), restrictedPendingToolCallIds);
|
|
1213
|
+
const resolved = this.updateAssistantMessage(messageId, primaryUpdate, replayContexts.get(messageId), restrictedPendingToolCallIds, deferUpdateNotifications);
|
|
1167
1214
|
if (messageId === frameMessageId && resolved !== assistantMessageId) assistantMessageId = resolved;
|
|
1168
1215
|
for (const messageId of pendingMessages) this.maybeResumeAfterToolResults(messageId, replayMessageIds.includes(messageId) ? accountedResultIds : void 0);
|
|
1169
1216
|
};
|
|
@@ -1200,7 +1247,7 @@ var AgUiThreadController = class {
|
|
|
1200
1247
|
const previousId = assistantMessageId;
|
|
1201
1248
|
assistantMessageId = void 0;
|
|
1202
1249
|
if (!adoptsReplay && this.session.tryGetMessage(previousId)) {
|
|
1203
|
-
const created = this.insertAssistantPlaceholder(previousId);
|
|
1250
|
+
const created = this.insertAssistantPlaceholder(previousId, void 0, deferUpdateNotifications);
|
|
1204
1251
|
assistantMessageId = created;
|
|
1205
1252
|
this.markPendingAssistantHistory(created, previousId);
|
|
1206
1253
|
}
|
|
@@ -1214,7 +1261,7 @@ var AgUiThreadController = class {
|
|
|
1214
1261
|
replayEnded = true;
|
|
1215
1262
|
const placeholder = ensureAssistant(true);
|
|
1216
1263
|
if (placeholder === serverId) return;
|
|
1217
|
-
const reassigned = this.reassignAssistantId(placeholder, serverId);
|
|
1264
|
+
const reassigned = this.reassignAssistantId(placeholder, serverId, deferUpdateNotifications);
|
|
1218
1265
|
const adoptsVisibleCollision = !reassigned && !runStartMessageIds.has(serverId) && this.session.headId === serverId;
|
|
1219
1266
|
if (reassigned || adoptsVisibleCollision) {
|
|
1220
1267
|
assistantMessageId = serverId;
|
|
@@ -1248,14 +1295,14 @@ var AgUiThreadController = class {
|
|
|
1248
1295
|
type: "complete",
|
|
1249
1296
|
reason: "unknown"
|
|
1250
1297
|
}
|
|
1251
|
-
});
|
|
1298
|
+
}, void 0, void 0, deferUpdateNotifications);
|
|
1252
1299
|
const current = this.session.tryGetMessage(messageId)?.message;
|
|
1253
1300
|
if (current?.role === "assistant") retainedSnapshots.set(messageId, {
|
|
1254
1301
|
...snapshot,
|
|
1255
1302
|
message: current
|
|
1256
1303
|
});
|
|
1257
1304
|
const head = assistantMessageId === void 0 ? void 0 : this.session.tryGetMessage(assistantMessageId)?.message;
|
|
1258
|
-
if (!settlingRun && !announcingMove && head?.role === "assistant" && head.status?.type !== "running" && !runStartMessageIds.has(head.id) && !aggregator.isRetained(head.id)) this.updateAssistantMessage(head.id, { status: { type: "running" } });
|
|
1305
|
+
if (!settlingRun && !announcingMove && head?.role === "assistant" && head.status?.type !== "running" && !runStartMessageIds.has(head.id) && !aggregator.isRetained(head.id)) this.updateAssistantMessage(head.id, { status: { type: "running" } }, void 0, void 0, deferUpdateNotifications);
|
|
1259
1306
|
};
|
|
1260
1307
|
const abortController = new AbortController();
|
|
1261
1308
|
const abortSignal = abortController.signal;
|
|
@@ -1369,6 +1416,8 @@ var AgUiThreadController = class {
|
|
|
1369
1416
|
settlingRun = event.type === "RUN_FINISHED" || event.type === "RUN_ERROR" || event.type === "RUN_CANCELLED";
|
|
1370
1417
|
if (settlingRun) persistRunAssistants(true);
|
|
1371
1418
|
const beforeSnapshot = event.type === "MESSAGES_SNAPSHOT" ? this.session.getMessages() : [];
|
|
1419
|
+
const previousDeferredNotifications = deferUpdateNotifications;
|
|
1420
|
+
deferUpdateNotifications = event.type === "TEXT_MESSAGE_CONTENT" || event.type === "REASONING_MESSAGE_CONTENT" || event.type === "TOOL_CALL_ARGS" || event.type === "ACTIVITY_DELTA" || event.type === "STATE_DELTA";
|
|
1372
1421
|
try {
|
|
1373
1422
|
const nextAssistantMessageId = this.handleEvent(aggregator, event, assistantMessageId, joinStrategy, runStartMessageIds, hasRunUserBoundary, heldMessages, candidateContexts.size ? reconcileReplaySnapshot : void 0);
|
|
1374
1423
|
if (event.type === "MESSAGES_SNAPSHOT") {
|
|
@@ -1426,6 +1475,7 @@ var AgUiThreadController = class {
|
|
|
1426
1475
|
});
|
|
1427
1476
|
if (settlingRun) persistRunAssistants(false);
|
|
1428
1477
|
} finally {
|
|
1478
|
+
deferUpdateNotifications = previousDeferredNotifications;
|
|
1429
1479
|
settlingRun = false;
|
|
1430
1480
|
}
|
|
1431
1481
|
};
|
|
@@ -1480,7 +1530,8 @@ var AgUiThreadController = class {
|
|
|
1480
1530
|
runAgentInstance.threadId = input.threadId;
|
|
1481
1531
|
runAgentInstance.state = input.state;
|
|
1482
1532
|
} catch {}
|
|
1483
|
-
await runAgentInstance.
|
|
1533
|
+
if (resumeSource === "connect") await runAgentInstance.connectAgent(input, subscriber);
|
|
1534
|
+
else await runAgentInstance.runAgent.bind(runAgentInstance)(input, subscriber, { signal: abortSignal });
|
|
1484
1535
|
}
|
|
1485
1536
|
} catch (error) {
|
|
1486
1537
|
if (!abortSignal.aborted && !pendingError) {
|
|
@@ -1682,7 +1733,7 @@ var AgUiThreadController = class {
|
|
|
1682
1733
|
this.activeRunAgent = null;
|
|
1683
1734
|
this.setRunning(false);
|
|
1684
1735
|
}
|
|
1685
|
-
insertAssistantPlaceholder(parentId, id = generateOptimisticId()) {
|
|
1736
|
+
insertAssistantPlaceholder(parentId, id = generateOptimisticId(), deferNotification = false) {
|
|
1686
1737
|
const assistant = {
|
|
1687
1738
|
id,
|
|
1688
1739
|
role: "assistant",
|
|
@@ -1700,10 +1751,10 @@ var AgUiThreadController = class {
|
|
|
1700
1751
|
};
|
|
1701
1752
|
this.session.addOrUpdateMessage(parentId ?? this.session.headId, assistant);
|
|
1702
1753
|
this.session.switchToBranch(id);
|
|
1703
|
-
this.publishUpdate();
|
|
1754
|
+
this.publishUpdate(deferNotification);
|
|
1704
1755
|
return id;
|
|
1705
1756
|
}
|
|
1706
|
-
reassignAssistantId(oldId, newId) {
|
|
1757
|
+
reassignAssistantId(oldId, newId, deferNotification = false) {
|
|
1707
1758
|
if (oldId === newId) return true;
|
|
1708
1759
|
const oldItem = this.session.tryGetMessage(oldId);
|
|
1709
1760
|
if (!oldItem) return false;
|
|
@@ -1740,10 +1791,10 @@ var AgUiThreadController = class {
|
|
|
1740
1791
|
this.persistedHistoryIds.add(newId);
|
|
1741
1792
|
this.unappendedHistoryIds.delete(newId);
|
|
1742
1793
|
}, () => {});
|
|
1743
|
-
this.publishUpdate();
|
|
1794
|
+
this.publishUpdate(deferNotification);
|
|
1744
1795
|
return !collidesWithExisting;
|
|
1745
1796
|
}
|
|
1746
|
-
updateAssistantMessage(messageId, update, replay, pendingToolCallIds) {
|
|
1797
|
+
updateAssistantMessage(messageId, update, replay, pendingToolCallIds, deferNotification = false) {
|
|
1747
1798
|
let latestStatus;
|
|
1748
1799
|
if (!this.session.updateMessage(messageId, (message) => {
|
|
1749
1800
|
if (message.role !== "assistant") return message;
|
|
@@ -1794,9 +1845,9 @@ var AgUiThreadController = class {
|
|
|
1794
1845
|
let resolvedMessageId = messageId;
|
|
1795
1846
|
if (latestStatus !== void 0 && latestStatus.type !== "running" && isOptimisticId(messageId)) {
|
|
1796
1847
|
const stableId = generateId();
|
|
1797
|
-
this.reassignAssistantId(messageId, stableId);
|
|
1848
|
+
this.reassignAssistantId(messageId, stableId, deferNotification);
|
|
1798
1849
|
resolvedMessageId = stableId;
|
|
1799
|
-
} else this.publishUpdate();
|
|
1850
|
+
} else this.publishUpdate(deferNotification);
|
|
1800
1851
|
if (this.isPersistableStatus(latestStatus)) this.persistAssistantHistory(resolvedMessageId);
|
|
1801
1852
|
this.maybeResumeAfterToolResults(resolvedMessageId, replay?.accountedResultIds);
|
|
1802
1853
|
return resolvedMessageId;
|
|
@@ -1975,7 +2026,7 @@ var AgUiThreadController = class {
|
|
|
1975
2026
|
type: "stateSnapshot",
|
|
1976
2027
|
snapshot: result.newDocument
|
|
1977
2028
|
});
|
|
1978
|
-
this.updateActiveAssistantState(activeAssistantId);
|
|
2029
|
+
this.updateActiveAssistantState(activeAssistantId, true);
|
|
1979
2030
|
} catch (error) {
|
|
1980
2031
|
this.logger.error?.("[agui] failed to apply state delta", error);
|
|
1981
2032
|
}
|
|
@@ -2032,7 +2083,7 @@ var AgUiThreadController = class {
|
|
|
2032
2083
|
}
|
|
2033
2084
|
return activeAssistantId;
|
|
2034
2085
|
}
|
|
2035
|
-
updateActiveAssistantState(messageId) {
|
|
2086
|
+
updateActiveAssistantState(messageId, deferNotification = false) {
|
|
2036
2087
|
const activeAssistantId = (messageId === void 0 ? void 0 : this.session.tryGetMessage(messageId)?.message)?.role === "assistant" && this.session.headId === messageId ? messageId : this.session.headId;
|
|
2037
2088
|
if (activeAssistantId !== null && activeAssistantId !== void 0) this.session.updateMessage(activeAssistantId, (message) => {
|
|
2038
2089
|
if (message.role !== "assistant") return message;
|
|
@@ -2045,7 +2096,7 @@ var AgUiThreadController = class {
|
|
|
2045
2096
|
}
|
|
2046
2097
|
};
|
|
2047
2098
|
});
|
|
2048
|
-
this.publishUpdate();
|
|
2099
|
+
this.publishUpdate(deferNotification);
|
|
2049
2100
|
}
|
|
2050
2101
|
applyCrossRunToolResult(messageId, event) {
|
|
2051
2102
|
if (!this.session.updateMessage(messageId, (message) => {
|
|
@@ -2137,7 +2188,10 @@ var AgUiThreadController = class {
|
|
|
2137
2188
|
const activeMessage = activeAssistantItem?.message;
|
|
2138
2189
|
const activeAssistantParentId = activeAssistantItem?.parentId;
|
|
2139
2190
|
const activeAssistant = activeMessage?.role === "assistant" ? activeMessage : void 0;
|
|
2140
|
-
const normalized = fromAgUiSnapshotMessages(rawMessages, {
|
|
2191
|
+
const normalized = fromAgUiSnapshotMessages(rawMessages, {
|
|
2192
|
+
showThinking: this.showThinking,
|
|
2193
|
+
joinAdjacentAssistantMessages: this.joinAdjacentAssistantMessages
|
|
2194
|
+
}, this.subagentParentToolCallIds);
|
|
2141
2195
|
const converted = [];
|
|
2142
2196
|
for (const message of normalized) try {
|
|
2143
2197
|
const previous = message.id ? this.session.tryGetMessage(message.id)?.message : void 0;
|