agents 0.14.1 → 0.14.3
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/LICENSE +21 -0
- package/dist/{agent-tool-types-BAJWu8s4.d.ts → agent-tool-types-V25Z_HcX.d.ts} +258 -115
- package/dist/agent-tool-types.d.ts +13 -11
- package/dist/{agent-tools-DYrkT-Kx.js → agent-tools-3zLG7MgA.js} +4 -2
- package/dist/{agent-tools-DYrkT-Kx.js.map → agent-tools-3zLG7MgA.js.map} +1 -1
- package/dist/{agent-tools-0R6KEert.d.ts → agent-tools-C-9s151X.d.ts} +2 -2
- package/dist/agent-tools.d.ts +13 -11
- package/dist/agent-tools.js +8 -3
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.js +1 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tanstack-ai.js +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/chat/index.d.ts +133 -11
- package/dist/chat/index.js +118 -29
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +4 -4
- package/dist/chat-sdk/index.js.map +1 -1
- package/dist/{classPrivateFieldGet2-D_obpP6O.js → classPrivateFieldGet2-Beqsfu2Z.js} +5 -5
- package/dist/{classPrivateMethodInitSpec-10iTYB7F.js → classPrivateMethodInitSpec-B5ko1s2R.js} +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/client-FUizKzj2.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/compaction-helpers-iiKMr2TQ.js.map +1 -1
- package/dist/email.js.map +1 -1
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/experimental/webmcp.js.map +1 -1
- package/dist/{index-RJ4OxMOe.d.ts → index-CPe1OtI0.d.ts} +17 -1
- package/dist/index.d.ts +66 -64
- package/dist/index.js +263 -76
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +14 -14
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +30 -30
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.js.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js.map +1 -1
- package/dist/react.d.ts +3 -3
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/schedule.js.map +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{shared-BIpUk4G5.js → shared-wyII629d.js} +3 -3
- package/dist/{shared-BIpUk4G5.js.map → shared-wyII629d.js.map} +1 -1
- package/dist/skills/index.js +4 -4
- package/dist/skills/index.js.map +1 -1
- package/dist/sub-routing.d.ts +6 -6
- package/dist/sub-routing.js.map +1 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/vite.d.ts +15 -4
- package/dist/vite.js +37 -7
- package/dist/vite.js.map +1 -1
- package/dist/workflows.d.ts +10 -2
- package/dist/workflows.js +48 -22
- package/dist/workflows.js.map +1 -1
- package/package.json +9 -17
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { __DO_NOT_USE_WILL_BREAK__agentContext } from "./internal_context.js";
|
|
|
2
2
|
import { MessageType } from "./types.js";
|
|
3
3
|
import { camelCaseToKebabCase, isInternalJsStubProp } from "./utils.js";
|
|
4
4
|
import { createHeaderBasedEmailResolver, signAgentHeaders } from "./email.js";
|
|
5
|
-
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-
|
|
5
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-Beqsfu2Z.js";
|
|
6
6
|
import { SUB_PREFIX, getSubAgentByName, parseSubAgentPath, routeSubAgentRequest } from "./sub-routing.js";
|
|
7
7
|
import { isErrorRetryable, tryN, validateRetryOptions } from "./retries.js";
|
|
8
8
|
import { a as MCPConnectionState, c as RPC_DO_PREFIX, i as normalizeServerId, l as DisposableStore, n as MCP_SERVER_ID_MAX_LENGTH, t as MCPClientManager } from "./client-FUizKzj2.js";
|
|
@@ -116,7 +116,8 @@ function getNextCronTime(cron) {
|
|
|
116
116
|
const DEFAULT_KEEP_ALIVE_INTERVAL_MS = 3e4;
|
|
117
117
|
const DEFAULT_AGENT_TOOL_RECOVERY_TIMEOUT_MS = 2e3;
|
|
118
118
|
const DEFAULT_AGENT_TOOL_RECOVERY_TOTAL_TIMEOUT_MS = 5e3;
|
|
119
|
-
const
|
|
119
|
+
const DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS = 12e4;
|
|
120
|
+
const DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS = Number.POSITIVE_INFINITY;
|
|
120
121
|
const SUB_AGENT_IDENTITY_VERSION_LEGACY = "legacy";
|
|
121
122
|
const SUB_AGENT_IDENTITY_VERSION_PATH_V2 = "path-v2";
|
|
122
123
|
const SUB_AGENT_IDENTITY_PATH_V2_PREFIX = "cf-agents:v2:";
|
|
@@ -126,7 +127,7 @@ const SUB_AGENT_IDENTITY_PATH_V2_PREFIX = "cf-agents:v2:";
|
|
|
126
127
|
* The constructor stores this as a row in cf_agents_state and checks it
|
|
127
128
|
* on wake to skip DDL on established DOs.
|
|
128
129
|
*/
|
|
129
|
-
const CURRENT_SCHEMA_VERSION =
|
|
130
|
+
const CURRENT_SCHEMA_VERSION = 9;
|
|
130
131
|
const SCHEMA_VERSION_ROW_ID = "cf_schema_version";
|
|
131
132
|
const STATE_ROW_ID = "cf_state_row_id";
|
|
132
133
|
const STATE_WAS_CHANGED = "cf_state_was_changed";
|
|
@@ -275,7 +276,27 @@ const DEFAULT_AGENT_STATIC_OPTIONS = {
|
|
|
275
276
|
* up. Bounds repeated retries of a `onFiberRecovered()` hook that keeps
|
|
276
277
|
* throwing so a poison row cannot re-trigger forever across boots.
|
|
277
278
|
*/
|
|
278
|
-
fiberRecoveryMaxAgeMs: 1440 * 60 * 1e3
|
|
279
|
+
fiberRecoveryMaxAgeMs: 1440 * 60 * 1e3,
|
|
280
|
+
/**
|
|
281
|
+
* No-progress budget (ms) for re-attaching to a still-running agent-tool
|
|
282
|
+
* child after a deploy / parent recovery (#1630). Bounds how long the parent
|
|
283
|
+
* waits with NO forward progress from the child; it resets on every forwarded
|
|
284
|
+
* chunk, so a child that keeps streaming is never abandoned mid-flight. Only a
|
|
285
|
+
* genuinely silent/hung child seals `interrupted` after a full window. Raise
|
|
286
|
+
* for children with long quiet stretches between outputs.
|
|
287
|
+
*/
|
|
288
|
+
agentToolReattachNoProgressTimeoutMs: DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS,
|
|
289
|
+
/**
|
|
290
|
+
* Optional hard wall-clock ceiling (ms) on a single agent-tool re-attach
|
|
291
|
+
* (#1630). Caps the total wait even as the no-progress budget re-arms across
|
|
292
|
+
* stream-closes. Defaults to `Infinity` (no implicit cap), mirroring
|
|
293
|
+
* chat-recovery's `maxRecoveryWork` (#1672): a healthy, still-advancing child
|
|
294
|
+
* is followed for as long as it makes progress — a hung child is bounded by
|
|
295
|
+
* the no-progress budget, and a content-runaway by the child's own
|
|
296
|
+
* `maxRecoveryWork` / `shouldKeepRecovering`. Set a finite value to impose a
|
|
297
|
+
* wall-clock cap (which also tears the child down on `window-exceeded`).
|
|
298
|
+
*/
|
|
299
|
+
agentToolReattachMaxWindowMs: DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS
|
|
279
300
|
};
|
|
280
301
|
/**
|
|
281
302
|
* Parse the raw `retry_options` TEXT column from a SQLite row into a
|
|
@@ -428,7 +449,9 @@ var Agent = class Agent extends Server {
|
|
|
428
449
|
},
|
|
429
450
|
fiberRecoveryHookTimeoutMs: ctor.options?.fiberRecoveryHookTimeoutMs ?? DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryHookTimeoutMs,
|
|
430
451
|
fiberRecoveryScanDeadlineMs: ctor.options?.fiberRecoveryScanDeadlineMs ?? DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryScanDeadlineMs,
|
|
431
|
-
fiberRecoveryMaxAgeMs: ctor.options?.fiberRecoveryMaxAgeMs ?? DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryMaxAgeMs
|
|
452
|
+
fiberRecoveryMaxAgeMs: ctor.options?.fiberRecoveryMaxAgeMs ?? DEFAULT_AGENT_STATIC_OPTIONS.fiberRecoveryMaxAgeMs,
|
|
453
|
+
agentToolReattachNoProgressTimeoutMs: ctor.options?.agentToolReattachNoProgressTimeoutMs ?? DEFAULT_AGENT_STATIC_OPTIONS.agentToolReattachNoProgressTimeoutMs,
|
|
454
|
+
agentToolReattachMaxWindowMs: ctor.options?.agentToolReattachMaxWindowMs ?? DEFAULT_AGENT_STATIC_OPTIONS.agentToolReattachMaxWindowMs
|
|
432
455
|
};
|
|
433
456
|
return this._cachedOptions;
|
|
434
457
|
}
|
|
@@ -655,6 +678,8 @@ var Agent = class Agent extends Server {
|
|
|
655
678
|
summary TEXT,
|
|
656
679
|
output_json TEXT,
|
|
657
680
|
error_message TEXT,
|
|
681
|
+
interrupted_reason TEXT,
|
|
682
|
+
child_still_running INTEGER,
|
|
658
683
|
display_metadata TEXT,
|
|
659
684
|
display_order INTEGER NOT NULL DEFAULT 0,
|
|
660
685
|
started_at INTEGER NOT NULL,
|
|
@@ -666,6 +691,8 @@ var Agent = class Agent extends Server {
|
|
|
666
691
|
ON cf_agent_tool_runs(parent_tool_call_id, display_order)
|
|
667
692
|
`;
|
|
668
693
|
addColumnIfNotExists("ALTER TABLE cf_agent_tool_runs ADD COLUMN output_json TEXT");
|
|
694
|
+
addColumnIfNotExists("ALTER TABLE cf_agent_tool_runs ADD COLUMN interrupted_reason TEXT");
|
|
695
|
+
addColumnIfNotExists("ALTER TABLE cf_agent_tool_runs ADD COLUMN child_still_running INTEGER");
|
|
669
696
|
this.sql`
|
|
670
697
|
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
671
698
|
VALUES (${SCHEMA_VERSION_ROW_ID}, ${String(CURRENT_SCHEMA_VERSION)})
|
|
@@ -680,12 +707,12 @@ var Agent = class Agent extends Server {
|
|
|
680
707
|
this._rawStateAccessors = /* @__PURE__ */ new WeakMap();
|
|
681
708
|
this._persistenceHookMode = "none";
|
|
682
709
|
this._isFacet = false;
|
|
683
|
-
this._suppressProtocolBroadcasts = false;
|
|
684
710
|
this._protocolBroadcastExcludeIds = /* @__PURE__ */ new Set();
|
|
685
711
|
this._cf_virtualSubAgentConnections = /* @__PURE__ */ new Map();
|
|
686
712
|
this._parentPath = [];
|
|
687
713
|
this._insideOnStart = false;
|
|
688
714
|
this._warnedScheduleInOnStart = /* @__PURE__ */ new Set();
|
|
715
|
+
this._warnedChatRecoveryInOnStart = false;
|
|
689
716
|
this._keepAliveRefs = 0;
|
|
690
717
|
this._facetKeepAliveTokens = /* @__PURE__ */ new Set();
|
|
691
718
|
this._runFiberActiveFibers = /* @__PURE__ */ new Set();
|
|
@@ -932,6 +959,7 @@ var Agent = class Agent extends Server {
|
|
|
932
959
|
this._checkOrphanedWorkflows();
|
|
933
960
|
await this._checkRunFibers();
|
|
934
961
|
const startupAgentToolRunIds = this._agentToolRunRecoveryRunIds();
|
|
962
|
+
const chatRecoveryBefore = this.chatRecovery;
|
|
935
963
|
this._insideOnStart = true;
|
|
936
964
|
this._warnedScheduleInOnStart.clear();
|
|
937
965
|
let result;
|
|
@@ -940,6 +968,12 @@ var Agent = class Agent extends Server {
|
|
|
940
968
|
} finally {
|
|
941
969
|
this._insideOnStart = false;
|
|
942
970
|
}
|
|
971
|
+
const chatRecoveryAfter = this.chatRecovery;
|
|
972
|
+
const chatRecoveryAfterMatters = typeof chatRecoveryAfter === "object" && chatRecoveryAfter !== null || chatRecoveryAfter === true;
|
|
973
|
+
if (!this._warnedChatRecoveryInOnStart && chatRecoveryBefore !== chatRecoveryAfter && chatRecoveryAfterMatters) {
|
|
974
|
+
this._warnedChatRecoveryInOnStart = true;
|
|
975
|
+
console.warn("[Agent] `chatRecovery` was assigned during onStart(). Chat recovery evaluates its budgets (and may seal an interrupted turn, firing onExhausted) on wake BEFORE onStart() runs, so a config set here is applied too late and the built-in defaults are used for the recovery that matters. Assign `chatRecovery` as a class field or in the constructor instead.");
|
|
976
|
+
}
|
|
943
977
|
this._scheduleAgentToolRunRecovery({ runIds: startupAgentToolRunIds });
|
|
944
978
|
return result;
|
|
945
979
|
});
|
|
@@ -976,7 +1010,6 @@ var Agent = class Agent extends Server {
|
|
|
976
1010
|
* @param excludeIds Additional connection IDs to exclude (e.g. the source)
|
|
977
1011
|
*/
|
|
978
1012
|
_broadcastProtocol(msg, excludeIds = []) {
|
|
979
|
-
if (this._suppressProtocolBroadcasts) return;
|
|
980
1013
|
const exclude = [...excludeIds, ...this._protocolBroadcastExcludeIds];
|
|
981
1014
|
for (const conn of this.getConnections()) if (!this.isConnectionProtocolEnabled(conn)) exclude.push(conn.id);
|
|
982
1015
|
this.broadcast(msg, exclude);
|
|
@@ -3387,6 +3420,7 @@ var Agent = class Agent extends Server {
|
|
|
3387
3420
|
if (this._isFacet) {
|
|
3388
3421
|
const stored = this._cf_virtualSubAgentConnections.get(id);
|
|
3389
3422
|
if (stored) return this._cf_createSubAgentBridgeConnection(stored.bridge, stored.meta);
|
|
3423
|
+
return;
|
|
3390
3424
|
}
|
|
3391
3425
|
const connection = super.getConnection(id);
|
|
3392
3426
|
if (!connection || this._cf_connectionHasSubAgentTarget(connection)) return;
|
|
@@ -3395,6 +3429,7 @@ var Agent = class Agent extends Server {
|
|
|
3395
3429
|
*getConnections(tag) {
|
|
3396
3430
|
if (this._isFacet) {
|
|
3397
3431
|
for (const stored of this._cf_virtualSubAgentConnections.values()) if (!tag || stored.meta.tags.includes(tag)) yield this._cf_createSubAgentBridgeConnection(stored.bridge, stored.meta);
|
|
3432
|
+
return;
|
|
3398
3433
|
}
|
|
3399
3434
|
for (const connection of super.getConnections(tag)) {
|
|
3400
3435
|
if (this._cf_connectionHasSubAgentTarget(connection)) continue;
|
|
@@ -3847,12 +3882,7 @@ var Agent = class Agent extends Server {
|
|
|
3847
3882
|
this.ctx.storage.put("cf_agents_facet_name", name),
|
|
3848
3883
|
this.ctx.storage.put("cf_agents_parent_path", parentPath)
|
|
3849
3884
|
]);
|
|
3850
|
-
this.
|
|
3851
|
-
try {
|
|
3852
|
-
await this.__unsafe_ensureInitialized();
|
|
3853
|
-
} finally {
|
|
3854
|
-
this._suppressProtocolBroadcasts = false;
|
|
3855
|
-
}
|
|
3885
|
+
await this.__unsafe_ensureInitialized();
|
|
3856
3886
|
}
|
|
3857
3887
|
get name() {
|
|
3858
3888
|
return this._facetName ?? logicalNameFromPathV2Identity(super.name) ?? super.name;
|
|
@@ -4022,10 +4052,12 @@ var Agent = class Agent extends Server {
|
|
|
4022
4052
|
} catch {}
|
|
4023
4053
|
return this._resultFromAgentToolRow(existing);
|
|
4024
4054
|
}
|
|
4055
|
+
let reattachReason;
|
|
4056
|
+
let childTornDown = false;
|
|
4025
4057
|
try {
|
|
4026
4058
|
const child = await this.subAgent(cls, runId);
|
|
4027
4059
|
const adapter = this._asAgentToolChildAdapter(child);
|
|
4028
|
-
const reattach = await this._reattachAgentToolRunToTerminal(adapter, existing, 1);
|
|
4060
|
+
const reattach = await this._reattachAgentToolRunToTerminal(adapter, existing, 1, this._resolvedOptions.agentToolReattachNoProgressTimeoutMs, this._resolvedOptions.agentToolReattachMaxWindowMs);
|
|
4029
4061
|
if (reattach.result) {
|
|
4030
4062
|
await this._finishAgentToolRun(this._agentToolRunInfoFromRow(existing), reattach.result, {
|
|
4031
4063
|
sequence: reattach.sequence,
|
|
@@ -4033,8 +4065,13 @@ var Agent = class Agent extends Server {
|
|
|
4033
4065
|
});
|
|
4034
4066
|
return reattach.result;
|
|
4035
4067
|
}
|
|
4068
|
+
reattachReason = reattach.reason;
|
|
4069
|
+
childTornDown = await this._teardownGivenUpAgentToolChild(adapter, runId, reattach.reason);
|
|
4036
4070
|
} catch {}
|
|
4037
|
-
return await this._replayAndInterruptAgentToolRun(existing,
|
|
4071
|
+
return await this._replayAndInterruptAgentToolRun(existing, this._interruptedMessageForReason(reattachReason), {
|
|
4072
|
+
reason: reattachReason,
|
|
4073
|
+
childStillRunning: !childTornDown
|
|
4074
|
+
});
|
|
4038
4075
|
}
|
|
4039
4076
|
const displayOrder = options.displayOrder ?? 0;
|
|
4040
4077
|
const inputPreview = options.inputPreview ?? this._defaultAgentToolPreview(options.input);
|
|
@@ -4128,7 +4165,7 @@ var Agent = class Agent extends Server {
|
|
|
4128
4165
|
try {
|
|
4129
4166
|
if (adapter.tailAgentToolRun) {
|
|
4130
4167
|
const stream = await adapter.tailAgentToolRun(runId, { afterSequence: -1 });
|
|
4131
|
-
sequence = await this._forwardAgentToolStream(stream, options.parentToolCallId, runId, sequence, options.signal);
|
|
4168
|
+
sequence = (await this._forwardAgentToolStream(stream, options.parentToolCallId, runId, sequence, options.signal)).next;
|
|
4132
4169
|
} else {
|
|
4133
4170
|
const chunks = await adapter.getAgentToolChunks(runId);
|
|
4134
4171
|
sequence = this._broadcastAgentToolChunks(options.parentToolCallId, runId, chunks, sequence);
|
|
@@ -4232,13 +4269,28 @@ var Agent = class Agent extends Server {
|
|
|
4232
4269
|
_readAgentToolRun(runId) {
|
|
4233
4270
|
return this.sql`
|
|
4234
4271
|
SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,
|
|
4235
|
-
summary, output_json, error_message,
|
|
4272
|
+
summary, output_json, error_message, interrupted_reason,
|
|
4273
|
+
child_still_running, display_metadata, display_order,
|
|
4236
4274
|
started_at, completed_at
|
|
4237
4275
|
FROM cf_agent_tool_runs
|
|
4238
4276
|
WHERE run_id = ${runId}
|
|
4239
4277
|
LIMIT 1
|
|
4240
4278
|
`[0] ?? null;
|
|
4241
4279
|
}
|
|
4280
|
+
/**
|
|
4281
|
+
* Reconstruct the typed interrupted cause (`reason` / `childStillRunning`,
|
|
4282
|
+
* #1630 follow-up) from a stored row so a row→result/event rebuild — e.g. a
|
|
4283
|
+
* reconnect replay — carries the same fields a live client saw. Only
|
|
4284
|
+
* `interrupted` rows store a cause; everything else yields `{}` (the columns
|
|
4285
|
+
* are cleared whenever a row settles to a hard terminal).
|
|
4286
|
+
*/
|
|
4287
|
+
_agentToolInterruptedExtrasFromRow(row) {
|
|
4288
|
+
if (row.status !== "interrupted") return {};
|
|
4289
|
+
return {
|
|
4290
|
+
...row.interrupted_reason !== null ? { reason: row.interrupted_reason } : {},
|
|
4291
|
+
...row.child_still_running !== null ? { childStillRunning: row.child_still_running !== 0 } : {}
|
|
4292
|
+
};
|
|
4293
|
+
}
|
|
4242
4294
|
_resultFromAgentToolRow(row) {
|
|
4243
4295
|
const output = this._parseAgentToolJson(row.output_json);
|
|
4244
4296
|
return {
|
|
@@ -4247,7 +4299,8 @@ var Agent = class Agent extends Server {
|
|
|
4247
4299
|
status: row.status,
|
|
4248
4300
|
...output !== void 0 ? { output } : {},
|
|
4249
4301
|
...row.summary !== null ? { summary: row.summary } : {},
|
|
4250
|
-
...row.error_message !== null ? { error: row.error_message } : {}
|
|
4302
|
+
...row.error_message !== null ? { error: row.error_message } : {},
|
|
4303
|
+
...this._agentToolInterruptedExtrasFromRow(row)
|
|
4251
4304
|
};
|
|
4252
4305
|
}
|
|
4253
4306
|
_agentToolRunInfoFromRow(row, status = row.status, completedAt = row.completed_at ?? void 0) {
|
|
@@ -4306,12 +4359,15 @@ var Agent = class Agent extends Server {
|
|
|
4306
4359
|
}
|
|
4307
4360
|
}
|
|
4308
4361
|
_updateAgentToolTerminal(runId, result, completedAt = Date.now()) {
|
|
4362
|
+
const childStillRunning = result.childStillRunning === void 0 ? null : result.childStillRunning ? 1 : 0;
|
|
4309
4363
|
this.sql`
|
|
4310
4364
|
UPDATE cf_agent_tool_runs
|
|
4311
4365
|
SET status = ${result.status},
|
|
4312
4366
|
summary = ${result.summary ?? null},
|
|
4313
4367
|
output_json = ${this._stringifyAgentToolOutput(result.output)},
|
|
4314
4368
|
error_message = ${result.error ?? null},
|
|
4369
|
+
interrupted_reason = ${result.reason ?? null},
|
|
4370
|
+
child_still_running = ${childStillRunning},
|
|
4315
4371
|
completed_at = ${completedAt}
|
|
4316
4372
|
WHERE run_id = ${runId}
|
|
4317
4373
|
AND status NOT IN ('completed', 'error', 'aborted')
|
|
@@ -4374,9 +4430,13 @@ var Agent = class Agent extends Server {
|
|
|
4374
4430
|
if (!chunks) return sequence;
|
|
4375
4431
|
return this._broadcastAgentToolChunks(row.parent_tool_call_id ?? void 0, row.run_id, chunks, sequence, replay, connection);
|
|
4376
4432
|
}
|
|
4377
|
-
async _forwardAgentToolStream(stream, parentToolCallId, runId, sequence, signal) {
|
|
4433
|
+
async _forwardAgentToolStream(stream, parentToolCallId, runId, sequence, signal, idleTimeoutMs) {
|
|
4378
4434
|
let next = sequence;
|
|
4379
|
-
if (signal?.aborted) return
|
|
4435
|
+
if (signal?.aborted) return {
|
|
4436
|
+
next,
|
|
4437
|
+
ended: "aborted"
|
|
4438
|
+
};
|
|
4439
|
+
let ended = "done";
|
|
4380
4440
|
const reader = stream.getReader();
|
|
4381
4441
|
const decoder = new TextDecoder();
|
|
4382
4442
|
let bufferedBytes = "";
|
|
@@ -4390,6 +4450,17 @@ var Agent = class Agent extends Server {
|
|
|
4390
4450
|
abortListener = () => resolveAbort?.();
|
|
4391
4451
|
signal.addEventListener("abort", abortListener, { once: true });
|
|
4392
4452
|
}
|
|
4453
|
+
const idleEnabled = typeof idleTimeoutMs === "number" && idleTimeoutMs > 0 && Number.isFinite(idleTimeoutMs);
|
|
4454
|
+
let resolveIdle;
|
|
4455
|
+
let idleTimer;
|
|
4456
|
+
const idlePromise = new Promise((resolve) => {
|
|
4457
|
+
resolveIdle = resolve;
|
|
4458
|
+
});
|
|
4459
|
+
const armIdle = () => {
|
|
4460
|
+
if (!idleEnabled) return;
|
|
4461
|
+
if (idleTimer !== void 0) clearTimeout(idleTimer);
|
|
4462
|
+
idleTimer = setTimeout(() => resolveIdle?.(), idleTimeoutMs);
|
|
4463
|
+
};
|
|
4393
4464
|
let forwardedSinceProgress = false;
|
|
4394
4465
|
try {
|
|
4395
4466
|
const forwardChunk = (chunk) => {
|
|
@@ -4399,6 +4470,7 @@ var Agent = class Agent extends Server {
|
|
|
4399
4470
|
body: chunk.body
|
|
4400
4471
|
});
|
|
4401
4472
|
forwardedSinceProgress = true;
|
|
4473
|
+
armIdle();
|
|
4402
4474
|
};
|
|
4403
4475
|
const forwardLine = (line) => {
|
|
4404
4476
|
try {
|
|
@@ -4419,15 +4491,21 @@ var Agent = class Agent extends Server {
|
|
|
4419
4491
|
bufferedBytes = "";
|
|
4420
4492
|
}
|
|
4421
4493
|
};
|
|
4494
|
+
armIdle();
|
|
4422
4495
|
while (true) {
|
|
4423
4496
|
const readPromise = reader.read();
|
|
4424
4497
|
readPromise.catch(() => {});
|
|
4425
|
-
const raced = await Promise.race([
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4498
|
+
const raced = await Promise.race([
|
|
4499
|
+
readPromise.then((result) => ({
|
|
4500
|
+
kind: "read",
|
|
4501
|
+
result
|
|
4502
|
+
})),
|
|
4503
|
+
abortPromise.then(() => ({ kind: "abort" })),
|
|
4504
|
+
idlePromise.then(() => ({ kind: "idle" }))
|
|
4505
|
+
]);
|
|
4506
|
+
if (raced.kind === "abort" || raced.kind === "idle") {
|
|
4430
4507
|
aborted = true;
|
|
4508
|
+
ended = raced.kind === "idle" ? "idle" : "aborted";
|
|
4431
4509
|
break;
|
|
4432
4510
|
}
|
|
4433
4511
|
const { done, value } = raced.result;
|
|
@@ -4448,12 +4526,16 @@ var Agent = class Agent extends Server {
|
|
|
4448
4526
|
}
|
|
4449
4527
|
}
|
|
4450
4528
|
} finally {
|
|
4529
|
+
if (idleTimer !== void 0) clearTimeout(idleTimer);
|
|
4451
4530
|
if (abortListener && signal) signal.removeEventListener("abort", abortListener);
|
|
4452
4531
|
if (!aborted) try {
|
|
4453
4532
|
reader.releaseLock();
|
|
4454
4533
|
} catch {}
|
|
4455
4534
|
}
|
|
4456
|
-
return
|
|
4535
|
+
return {
|
|
4536
|
+
next,
|
|
4537
|
+
ended
|
|
4538
|
+
};
|
|
4457
4539
|
}
|
|
4458
4540
|
/**
|
|
4459
4541
|
* Hook invoked by `_forwardAgentToolStream` after a child produces output that
|
|
@@ -4490,7 +4572,9 @@ var Agent = class Agent extends Server {
|
|
|
4490
4572
|
else if (result.status === "interrupted") this._broadcastAgentToolEvent(parentToolCallId, sequence, {
|
|
4491
4573
|
kind: "interrupted",
|
|
4492
4574
|
runId: result.runId,
|
|
4493
|
-
error: result.error ?? "Agent tool run was interrupted"
|
|
4575
|
+
error: result.error ?? "Agent tool run was interrupted",
|
|
4576
|
+
...result.reason !== void 0 ? { reason: result.reason } : {},
|
|
4577
|
+
...result.childStillRunning !== void 0 ? { childStillRunning: result.childStillRunning } : {}
|
|
4494
4578
|
}, replay, connection);
|
|
4495
4579
|
else this._broadcastAgentToolEvent(parentToolCallId, sequence, {
|
|
4496
4580
|
kind: "error",
|
|
@@ -4508,7 +4592,7 @@ var Agent = class Agent extends Server {
|
|
|
4508
4592
|
if (!cls) throw new Error(`Agent tool class "${className}" is not exported.`);
|
|
4509
4593
|
return cls;
|
|
4510
4594
|
}
|
|
4511
|
-
async _replayAndInterruptAgentToolRun(row, message) {
|
|
4595
|
+
async _replayAndInterruptAgentToolRun(row, message, extra) {
|
|
4512
4596
|
let sequence = 1;
|
|
4513
4597
|
try {
|
|
4514
4598
|
sequence = await this._broadcastAgentToolStoredChunks(row, sequence);
|
|
@@ -4517,12 +4601,53 @@ var Agent = class Agent extends Server {
|
|
|
4517
4601
|
runId: row.run_id,
|
|
4518
4602
|
agentType: row.agent_type,
|
|
4519
4603
|
status: "interrupted",
|
|
4520
|
-
error: message
|
|
4604
|
+
error: message,
|
|
4605
|
+
...extra?.reason !== void 0 ? { reason: extra.reason } : {},
|
|
4606
|
+
...extra?.childStillRunning !== void 0 ? { childStillRunning: extra.childStillRunning } : {}
|
|
4521
4607
|
};
|
|
4522
4608
|
await this._finishAgentToolRun(this._agentToolRunInfoFromRow(row), result, { sequence });
|
|
4523
4609
|
return result;
|
|
4524
4610
|
}
|
|
4525
4611
|
/**
|
|
4612
|
+
* Human-readable prose for an `interrupted` seal. Kept in sync with
|
|
4613
|
+
* {@link AgentToolInterruptedReason}; callers branch on the typed `reason`
|
|
4614
|
+
* field, not this string.
|
|
4615
|
+
*/
|
|
4616
|
+
_interruptedMessageForReason(reason) {
|
|
4617
|
+
switch (reason) {
|
|
4618
|
+
case "no-progress": return "Agent tool run was still running but made no forward progress within the re-attach no-progress budget; the parent gave up.";
|
|
4619
|
+
case "window-exceeded": return "Agent tool run did not reach a terminal result within the maximum re-attach window; the parent gave up.";
|
|
4620
|
+
case "not-tailable": return "Agent tool run was still running, but live-tail reattachment is not supported in this runtime.";
|
|
4621
|
+
case "inspect-timeout": return "Agent tool run inspection timed out during parent recovery.";
|
|
4622
|
+
case "inspect-failed": return "Agent tool run could not be inspected during parent recovery.";
|
|
4623
|
+
case "recovery-deadline": return "Agent tool run recovery deadline exceeded.";
|
|
4624
|
+
default: return "Agent tool run was still running and did not reach a terminal result.";
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
/**
|
|
4628
|
+
* Tear down a child agent-tool run the parent has genuinely given up on
|
|
4629
|
+
* (#1630 follow-up). Teardown is scoped to `window-exceeded` ONLY — the hard
|
|
4630
|
+
* ceiling, where the child has had its full recovery window and is therefore
|
|
4631
|
+
* truly exhausted, so cancelling it reclaims its fiber / keep-alive. Every
|
|
4632
|
+
* other give-up is deliberately left repairable: `no-progress` seals stay
|
|
4633
|
+
* SOFT (`interrupted`, `childStillRunning: true`) so a re-issue can still
|
|
4634
|
+
* re-attach and collect the child if it self-heals — tearing those down would
|
|
4635
|
+
* defeat the repair-on-re-issue path and convert a retryable interrupt into a
|
|
4636
|
+
* non-retryable `aborted`. Reasons where the child's state is unknown
|
|
4637
|
+
* (`inspect-*`, `recovery-deadline`, `not-tailable`) are also left alone.
|
|
4638
|
+
* Returns whether the child was torn down (so the caller reports
|
|
4639
|
+
* `childStillRunning: false`).
|
|
4640
|
+
*/
|
|
4641
|
+
async _teardownGivenUpAgentToolChild(adapter, runId, reason) {
|
|
4642
|
+
if (reason !== "window-exceeded") return false;
|
|
4643
|
+
try {
|
|
4644
|
+
await adapter.cancelAgentToolRun(runId, `agent tool run given up by parent recovery: ${reason}`);
|
|
4645
|
+
return true;
|
|
4646
|
+
} catch {
|
|
4647
|
+
return false;
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
/**
|
|
4526
4651
|
* Re-attach to a still-running child agent-tool run and tail it to its real
|
|
4527
4652
|
* terminal result, instead of abandoning it as `interrupted` (#1630). The
|
|
4528
4653
|
* child is a separate facet with its own `chatRecovery`, so resolving it via
|
|
@@ -4530,54 +4655,98 @@ var Agent = class Agent extends Server {
|
|
|
4530
4655
|
* its live stream (forwarding chunks to the parent's connections) until it
|
|
4531
4656
|
* reaches terminal, then inspect for the collected result.
|
|
4532
4657
|
*
|
|
4533
|
-
*
|
|
4534
|
-
* advancing
|
|
4535
|
-
*
|
|
4536
|
-
*
|
|
4658
|
+
* The wait is PROGRESS-KEYED, not a flat wall clock (which previously abandoned
|
|
4659
|
+
* healthy, still-advancing children whose recovery simply outran a fixed
|
|
4660
|
+
* budget). `noProgressTimeoutMs` bounds how long the parent waits with NO
|
|
4661
|
+
* forward progress; it is reset on every forwarded chunk. As long as the child
|
|
4662
|
+
* keeps streaming it is followed through to terminal. The loop also RE-ARMS
|
|
4663
|
+
* across stream-closes (a child re-evicted mid-recovery, or a tail that ends
|
|
4664
|
+
* before terminal) as long as the prior attempt made progress, so a child that
|
|
4665
|
+
* dies and recovers again during deploy churn is still collected. A genuinely
|
|
4666
|
+
* silent/hung child can never block recovery forever: it seals `interrupted`
|
|
4667
|
+
* after one `noProgressTimeoutMs` window. `maxWindowMs` is an OPTIONAL hard
|
|
4668
|
+
* wall-clock ceiling (default `Infinity` — uncapped, mirroring #1672's
|
|
4669
|
+
* `maxRecoveryWork`); set it finite to also bound a child that keeps
|
|
4670
|
+
* progressing, which seals `window-exceeded` and tears the child down.
|
|
4537
4671
|
*
|
|
4538
4672
|
* Returns the terminal `result` (and `completedAt`) when the child reaches a
|
|
4539
|
-
* terminal status
|
|
4540
|
-
*
|
|
4541
|
-
*
|
|
4673
|
+
* terminal status, plus the advanced broadcast `sequence`. Returns
|
|
4674
|
+
* `{ result: undefined }` when there is no `tailAgentToolRun` adapter, the
|
|
4675
|
+
* child makes no progress within a full no-progress window, or the ceiling is
|
|
4676
|
+
* reached while the child is still non-terminal — the caller then seals
|
|
4677
|
+
* `interrupted`.
|
|
4542
4678
|
*/
|
|
4543
|
-
async _reattachAgentToolRunToTerminal(adapter, row, sequence,
|
|
4544
|
-
if (typeof adapter.tailAgentToolRun !== "function") return {
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
else if (budgetMs <= 0) controller.abort();
|
|
4679
|
+
async _reattachAgentToolRunToTerminal(adapter, row, sequence, noProgressTimeoutMs = DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS, maxWindowMs = DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS) {
|
|
4680
|
+
if (typeof adapter.tailAgentToolRun !== "function") return {
|
|
4681
|
+
sequence,
|
|
4682
|
+
reason: "not-tailable"
|
|
4683
|
+
};
|
|
4549
4684
|
this._emit("agent_tool:recovery:reattach", {
|
|
4550
4685
|
runId: row.run_id,
|
|
4551
4686
|
agentType: row.agent_type,
|
|
4552
|
-
budgetMs
|
|
4687
|
+
budgetMs: noProgressTimeoutMs
|
|
4553
4688
|
});
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
let afterSequence = -1;
|
|
4689
|
+
const collectTerminal = async (seq) => {
|
|
4690
|
+
let inspection = null;
|
|
4557
4691
|
try {
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
}
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4692
|
+
inspection = await adapter.inspectAgentToolRun(row.run_id);
|
|
4693
|
+
} catch {
|
|
4694
|
+
return null;
|
|
4695
|
+
}
|
|
4696
|
+
if (inspection && inspection.status !== "running" && inspection.status !== "starting") return {
|
|
4697
|
+
sequence: seq,
|
|
4698
|
+
result: this._terminalResultFromInspection(row.agent_type, inspection),
|
|
4699
|
+
completedAt: inspection.completedAt
|
|
4700
|
+
};
|
|
4701
|
+
return null;
|
|
4702
|
+
};
|
|
4703
|
+
let nextSequence = sequence;
|
|
4704
|
+
if (!(noProgressTimeoutMs > 0)) return await collectTerminal(nextSequence) ?? {
|
|
4705
|
+
sequence: nextSequence,
|
|
4706
|
+
reason: "no-progress"
|
|
4707
|
+
};
|
|
4708
|
+
const ceilingController = new AbortController();
|
|
4709
|
+
let ceilingTimer;
|
|
4710
|
+
if (maxWindowMs > 0 && Number.isFinite(maxWindowMs)) ceilingTimer = setTimeout(() => ceilingController.abort(), maxWindowMs);
|
|
4711
|
+
let reason = "no-progress";
|
|
4567
4712
|
try {
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4713
|
+
while (!ceilingController.signal.aborted) {
|
|
4714
|
+
let afterSequence = -1;
|
|
4715
|
+
try {
|
|
4716
|
+
const existing = await adapter.getAgentToolChunks(row.run_id);
|
|
4717
|
+
const last = existing[existing.length - 1];
|
|
4718
|
+
if (last) afterSequence = last.sequence;
|
|
4719
|
+
} catch {}
|
|
4720
|
+
const beforeSequence = nextSequence;
|
|
4721
|
+
let streamEnded = "idle";
|
|
4722
|
+
try {
|
|
4723
|
+
const stream = await adapter.tailAgentToolRun(row.run_id, { afterSequence });
|
|
4724
|
+
const forwarded = await this._forwardAgentToolStream(stream, row.parent_tool_call_id ?? void 0, row.run_id, nextSequence, ceilingController.signal, noProgressTimeoutMs);
|
|
4725
|
+
nextSequence = forwarded.next;
|
|
4726
|
+
streamEnded = forwarded.ended;
|
|
4727
|
+
} catch {}
|
|
4728
|
+
const terminal = await collectTerminal(nextSequence);
|
|
4729
|
+
if (terminal) return terminal;
|
|
4730
|
+
if (ceilingController.signal.aborted) {
|
|
4731
|
+
reason = "window-exceeded";
|
|
4732
|
+
break;
|
|
4733
|
+
}
|
|
4734
|
+
if (streamEnded !== "done") break;
|
|
4735
|
+
if (nextSequence <= beforeSequence) break;
|
|
4736
|
+
}
|
|
4737
|
+
} finally {
|
|
4738
|
+
if (ceilingTimer !== void 0) clearTimeout(ceilingTimer);
|
|
4739
|
+
}
|
|
4740
|
+
return {
|
|
4571
4741
|
sequence: nextSequence,
|
|
4572
|
-
|
|
4573
|
-
completedAt: inspection.completedAt
|
|
4742
|
+
reason
|
|
4574
4743
|
};
|
|
4575
|
-
return { sequence: nextSequence };
|
|
4576
4744
|
}
|
|
4577
4745
|
async _replayAgentToolRuns(connection) {
|
|
4578
4746
|
const rows = this.sql`
|
|
4579
4747
|
SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,
|
|
4580
|
-
summary, output_json, error_message,
|
|
4748
|
+
summary, output_json, error_message, interrupted_reason,
|
|
4749
|
+
child_still_running, display_metadata, display_order
|
|
4581
4750
|
FROM cf_agent_tool_runs
|
|
4582
4751
|
ORDER BY started_at ASC
|
|
4583
4752
|
`;
|
|
@@ -4601,19 +4770,22 @@ var Agent = class Agent extends Server {
|
|
|
4601
4770
|
status: row.status,
|
|
4602
4771
|
output: this._parseAgentToolJson(row.output_json),
|
|
4603
4772
|
summary: row.summary ?? void 0,
|
|
4604
|
-
error: row.error_message ?? void 0
|
|
4773
|
+
error: row.error_message ?? void 0,
|
|
4774
|
+
...this._agentToolInterruptedExtrasFromRow(row)
|
|
4605
4775
|
}, true, connection);
|
|
4606
4776
|
}
|
|
4607
4777
|
}
|
|
4608
4778
|
async _reconcileAgentToolRuns(options) {
|
|
4609
|
-
const reattachTimeoutMs = options?.reattachTimeoutMs ??
|
|
4779
|
+
const reattachTimeoutMs = options?.reattachTimeoutMs ?? this._resolvedOptions.agentToolReattachNoProgressTimeoutMs;
|
|
4780
|
+
const reattachMaxWindowMs = options?.reattachMaxWindowMs ?? this._resolvedOptions.agentToolReattachMaxWindowMs;
|
|
4610
4781
|
const startedAt = Date.now();
|
|
4611
4782
|
const totalTimeoutMs = options?.totalRecoveryTimeoutMs ?? DEFAULT_AGENT_TOOL_RECOVERY_TOTAL_TIMEOUT_MS;
|
|
4612
4783
|
const deadlineAt = totalTimeoutMs > 0 ? startedAt + totalTimeoutMs : Number.POSITIVE_INFINITY;
|
|
4613
4784
|
const deferredFinishes = [];
|
|
4614
4785
|
const rows = this.sql`
|
|
4615
4786
|
SELECT run_id, parent_tool_call_id, agent_type, input_preview, status,
|
|
4616
|
-
summary, output_json, error_message,
|
|
4787
|
+
summary, output_json, error_message, interrupted_reason,
|
|
4788
|
+
child_still_running, display_metadata, display_order,
|
|
4617
4789
|
started_at, completed_at
|
|
4618
4790
|
FROM cf_agent_tool_runs
|
|
4619
4791
|
WHERE status IN ('starting', 'running')
|
|
@@ -4654,7 +4826,8 @@ var Agent = class Agent extends Server {
|
|
|
4654
4826
|
runId: row.run_id,
|
|
4655
4827
|
agentType: row.agent_type,
|
|
4656
4828
|
status: "interrupted",
|
|
4657
|
-
|
|
4829
|
+
reason: "recovery-deadline",
|
|
4830
|
+
error: this._interruptedMessageForReason("recovery-deadline")
|
|
4658
4831
|
}, sequence, void 0);
|
|
4659
4832
|
continue;
|
|
4660
4833
|
}
|
|
@@ -4662,12 +4835,16 @@ var Agent = class Agent extends Server {
|
|
|
4662
4835
|
const boundedChildTimeout = childTimeout > 0 ? Math.min(childTimeout, remainingMs) : remainingMs;
|
|
4663
4836
|
const recovery = await this._inspectAgentToolRunForRecovery(row, sequence, boundedChildTimeout);
|
|
4664
4837
|
if (recovery.status !== "inspected") {
|
|
4665
|
-
await finalizeRow(row, {
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4838
|
+
await finalizeRow(row, (() => {
|
|
4839
|
+
const reason = recovery.status === "timed-out" ? "inspect-timeout" : "inspect-failed";
|
|
4840
|
+
return {
|
|
4841
|
+
runId: row.run_id,
|
|
4842
|
+
agentType: row.agent_type,
|
|
4843
|
+
status: "interrupted",
|
|
4844
|
+
reason,
|
|
4845
|
+
error: this._interruptedMessageForReason(reason)
|
|
4846
|
+
};
|
|
4847
|
+
})(), sequence, void 0);
|
|
4671
4848
|
continue;
|
|
4672
4849
|
}
|
|
4673
4850
|
const inspection = recovery.inspection;
|
|
@@ -4687,17 +4864,26 @@ var Agent = class Agent extends Server {
|
|
|
4687
4864
|
runId: row.run_id,
|
|
4688
4865
|
agentType: row.agent_type,
|
|
4689
4866
|
status: "interrupted",
|
|
4690
|
-
|
|
4867
|
+
reason: "not-tailable",
|
|
4868
|
+
childStillRunning: true,
|
|
4869
|
+
error: this._interruptedMessageForReason("not-tailable")
|
|
4691
4870
|
}, sequenceAfterReplay, void 0);
|
|
4692
4871
|
else await finalizeRow(row, this._terminalResultFromInspection(row.agent_type, inspection), sequenceAfterReplay, inspection.completedAt);
|
|
4693
4872
|
}
|
|
4694
4873
|
await Promise.all(reattachQueue.map(async ({ row, adapter }) => {
|
|
4695
|
-
const reattach = await this._reattachAgentToolRunToTerminal(adapter, row, 1, reattachTimeoutMs);
|
|
4696
|
-
|
|
4874
|
+
const reattach = await this._reattachAgentToolRunToTerminal(adapter, row, 1, reattachTimeoutMs, reattachMaxWindowMs);
|
|
4875
|
+
if (reattach.result) {
|
|
4876
|
+
await finalizeRow(row, reattach.result, reattach.sequence, reattach.completedAt);
|
|
4877
|
+
return;
|
|
4878
|
+
}
|
|
4879
|
+
const tornDown = await this._teardownGivenUpAgentToolChild(adapter, row.run_id, reattach.reason);
|
|
4880
|
+
await finalizeRow(row, {
|
|
4697
4881
|
runId: row.run_id,
|
|
4698
4882
|
agentType: row.agent_type,
|
|
4699
4883
|
status: "interrupted",
|
|
4700
|
-
|
|
4884
|
+
reason: reattach.reason,
|
|
4885
|
+
childStillRunning: !tornDown,
|
|
4886
|
+
error: this._interruptedMessageForReason(reattach.reason)
|
|
4701
4887
|
}, reattach.sequence, reattach.completedAt);
|
|
4702
4888
|
}));
|
|
4703
4889
|
this._emit("agent_tool:recovery:complete", {
|
|
@@ -4737,6 +4923,7 @@ var Agent = class Agent extends Server {
|
|
|
4737
4923
|
childInspectionTimeoutMs: options?.childInspectionTimeoutMs,
|
|
4738
4924
|
totalRecoveryTimeoutMs: options?.totalRecoveryTimeoutMs,
|
|
4739
4925
|
reattachTimeoutMs: options?.reattachTimeoutMs,
|
|
4926
|
+
reattachMaxWindowMs: options?.reattachMaxWindowMs,
|
|
4740
4927
|
runIds: options?.runIds
|
|
4741
4928
|
});
|
|
4742
4929
|
await this._runDeferredAgentToolFinishHooks(recoveredAgentToolFinishes);
|