@sema-agent/core 2.4.0 → 2.5.0
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/agents/subagent.js +17 -14
- package/dist/core/auto-compaction.d.ts +2 -0
- package/dist/core/auto-compaction.js +2 -1
- package/dist/core/mcp.js +4 -1
- package/dist/core/runner/prepare-task.d.ts +5 -0
- package/dist/core/runner/prepare-task.js +21 -1
- package/dist/core/runner/runtask.js +39 -9
- package/dist/core/runner/tool-disclosure.d.ts +1 -0
- package/dist/core/runner/tool-disclosure.js +16 -5
- package/dist/core/session-reconcile.d.ts +1 -0
- package/dist/core/session-reconcile.js +40 -20
- package/dist/core/task-registry-agent.d.ts +2 -0
- package/dist/core/task-registry-agent.js +11 -1
- package/dist/core/task-registry-shared.d.ts +1 -0
- package/dist/core/task-registry.d.ts +2 -0
- package/dist/core/task-registry.js +11 -0
- package/dist/core/types.d.ts +10 -3
- package/dist/engine/compaction/compaction.d.ts +5 -0
- package/dist/engine/compaction/compaction.js +68 -2
- package/dist/engine/compaction/utils.d.ts +6 -0
- package/dist/engine/compaction/utils.js +53 -3
- package/dist/engine/harness/messages.d.ts +1 -1
- package/dist/engine/harness/messages.js +11 -3
- package/dist/engine/loop/types.d.ts +2 -0
- package/dist/engine/session/import-validate.js +30 -1
- package/dist/engine/session/session.js +7 -5
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/orchestration/workflow-types.d.ts +1 -0
- package/dist/orchestration/workflow.js +10 -1
- package/dist/tools/fs/fs-bash.js +11 -5
- package/package.json +1 -1
package/dist/agents/subagent.js
CHANGED
|
@@ -221,6 +221,9 @@ export function classifySubagentError(child) {
|
|
|
221
221
|
: "logic";
|
|
222
222
|
return { errorKind, retryable: errorKind !== "logic" };
|
|
223
223
|
}
|
|
224
|
+
function errorKindClause(c) {
|
|
225
|
+
return c !== undefined ? ` (error_kind: ${c.errorKind}, retryable: ${c.retryable})` : "";
|
|
226
|
+
}
|
|
224
227
|
const FAILED_SESSION_RETAIN_TTL_MS = 15 * 60 * 1000;
|
|
225
228
|
const PARTIAL_FINDINGS_MAX_CHARS = 1200;
|
|
226
229
|
const BG_NOTIFY_DRAIN_WINDOW_MS = 2_000;
|
|
@@ -427,7 +430,7 @@ export function createSubagentResume(deps) {
|
|
|
427
430
|
...resultSettleFields(child.result),
|
|
428
431
|
...(status !== "completed" ? { error: (child.errorMessage ?? `resumed run ${status}`).slice(0, 500) } : {}),
|
|
429
432
|
...(errCodeRevive !== undefined ? { errorCode: errCodeRevive } : {}),
|
|
430
|
-
...(errClassRevive !== undefined ? { retryable: errClassRevive.retryable } : {}),
|
|
433
|
+
...(errClassRevive !== undefined ? { retryable: errClassRevive.retryable, errorKind: errClassRevive.errorKind } : {}),
|
|
431
434
|
});
|
|
432
435
|
if (winner !== undefined)
|
|
433
436
|
status = winner;
|
|
@@ -440,7 +443,7 @@ export function createSubagentResume(deps) {
|
|
|
440
443
|
const reviveName = deps.rowDescription ?? `sub-agent ${marker}`;
|
|
441
444
|
const failReasonRevive = status === "failed" ? child.errorMessage : undefined;
|
|
442
445
|
const reviveTerminalSummary = failReasonRevive !== undefined
|
|
443
|
-
? `Agent "${reviveName}" (resumed) failed: ${failReasonRevive}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300)
|
|
446
|
+
? `Agent "${reviveName}" (resumed) failed: ${failReasonRevive}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + errorKindClause(errClassRevive)
|
|
444
447
|
: `Agent "${reviveName}" (resumed) ${status === "killed" ? "stopped" : child.status === "completed" ? "finished" : String(child.status)}${ccElapsedTag(Date.now() - reviveStartedAt)}`;
|
|
445
448
|
const ownsTerminalFacesRevive = deps.registry !== undefined && deps.taskId !== undefined ? deps.registry.claimAgentTerminalNotify(deps.taskId) : true;
|
|
446
449
|
if (ownsTerminalFacesRevive)
|
|
@@ -509,7 +512,7 @@ export function createSubagentResume(deps) {
|
|
|
509
512
|
status: abort.signal.aborted ? "killed" : "failed",
|
|
510
513
|
error: msgRevive.slice(0, 500),
|
|
511
514
|
...(errCodeReviveReject !== undefined ? { errorCode: errCodeReviveReject } : {}),
|
|
512
|
-
...(errClassReviveReject !== undefined ? { retryable: errClassReviveReject.retryable } : {}),
|
|
515
|
+
...(errClassReviveReject !== undefined ? { retryable: errClassReviveReject.retryable, errorKind: errClassReviveReject.errorKind } : {}),
|
|
513
516
|
});
|
|
514
517
|
}
|
|
515
518
|
catch {
|
|
@@ -530,7 +533,7 @@ export function createSubagentResume(deps) {
|
|
|
530
533
|
status: abort.signal.aborted ? "killed" : "failed",
|
|
531
534
|
seq: entry.cycleSeq,
|
|
532
535
|
...(stoppedByReject !== undefined ? { stoppedBy: stoppedByReject } : {}),
|
|
533
|
-
summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : "failed"}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300),
|
|
536
|
+
summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : "failed"}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + (abort.signal.aborted ? "" : errorKindClause(errClassReviveReject)),
|
|
534
537
|
...(completionIdRejectRevive !== undefined ? { completionId: completionIdRejectRevive } : {}),
|
|
535
538
|
});
|
|
536
539
|
try {
|
|
@@ -543,7 +546,7 @@ export function createSubagentResume(deps) {
|
|
|
543
546
|
status: abort.signal.aborted ? "killed" : "failed",
|
|
544
547
|
seq: entry.cycleSeq,
|
|
545
548
|
...(stoppedByReject !== undefined ? { stoppedBy: stoppedByReject } : {}),
|
|
546
|
-
summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : `failed: ${msgRevive}`}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300),
|
|
549
|
+
summary: `Agent "${rejectName}" (resumed) ${abort.signal.aborted ? "stopped" : `failed: ${msgRevive}`}${ccElapsedTag(Date.now() - reviveStartedAt)}`.slice(0, 300) + (abort.signal.aborted ? "" : errorKindClause(errClassReviveReject)),
|
|
547
550
|
...(abort.signal.aborted ? {} : { error: msgRevive.slice(0, REPORT_FIELD_MAX) }),
|
|
548
551
|
...(!abort.signal.aborted && errCodeReviveReject !== undefined ? { errorCode: errCodeReviveReject } : {}),
|
|
549
552
|
...(completionIdRejectRevive !== undefined ? { completionId: completionIdRejectRevive } : {}),
|
|
@@ -1753,7 +1756,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
1753
1756
|
...resultSettleFields(child.result),
|
|
1754
1757
|
...(!okBg ? { error: reapedBg ? (collateralBg ? BG_AGENT_COLLATERAL_REAP_REASON : BG_AGENT_REAP_STOP_ERROR) : child.errorMessage ?? String(child.status) } : {}),
|
|
1755
1758
|
...(errCodeFork !== undefined ? { errorCode: errCodeFork } : {}),
|
|
1756
|
-
...(errClassFork !== undefined ? { retryable: errClassFork.retryable } : {}),
|
|
1759
|
+
...(errClassFork !== undefined ? { retryable: errClassFork.retryable, errorKind: errClassFork.errorKind } : {}),
|
|
1757
1760
|
}) ?? (abort.signal.aborted ? "killed" : okBg ? "completed" : "failed");
|
|
1758
1761
|
const stoppedByBg = settledBg === "killed" ? bg.registry.getStopAttribution(taskId) ?? "system" : undefined;
|
|
1759
1762
|
const completionIdFork = bg.registry.getCompletionId(taskId);
|
|
@@ -1770,7 +1773,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
1770
1773
|
const forkTranscriptId = child.sessionId ?? forkedId;
|
|
1771
1774
|
const failReasonFork = settledBg === "failed" ? child.errorMessage : undefined;
|
|
1772
1775
|
const forkTerminalSummary = failReasonFork !== undefined
|
|
1773
|
-
? `Agent "${shortDesc}" failed: ${failReasonFork}${ccElapsedTag(Date.now() - forkBgStartedAt)}`.slice(0, 300)
|
|
1776
|
+
? `Agent "${shortDesc}" failed: ${failReasonFork}${ccElapsedTag(Date.now() - forkBgStartedAt)}`.slice(0, 300) + errorKindClause(errClassFork)
|
|
1774
1777
|
: `${ccCompletionText(shortDesc, settledBg, String(child.status), Date.now() - forkBgStartedAt)}`;
|
|
1775
1778
|
const ownsTerminalFacesFork = bg.registry.claimAgentTerminalNotify(taskId);
|
|
1776
1779
|
if (ownsTerminalFacesFork)
|
|
@@ -1823,11 +1826,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
1823
1826
|
status: killed ? "killed" : "failed",
|
|
1824
1827
|
error: killed ? BG_AGENT_REAP_STOP_ERROR : msgFork,
|
|
1825
1828
|
...(errCodeForkReject !== undefined ? { errorCode: errCodeForkReject } : {}),
|
|
1826
|
-
...(errClassForkReject !== undefined ? { retryable: errClassForkReject.retryable } : {}),
|
|
1829
|
+
...(errClassForkReject !== undefined ? { retryable: errClassForkReject.retryable, errorKind: errClassForkReject.errorKind } : {}),
|
|
1827
1830
|
}) ?? (killed ? "killed" : "failed");
|
|
1828
1831
|
const stoppedByBg = settledBg === "killed" ? bg.registry.getStopAttribution(taskId) ?? "system" : undefined;
|
|
1829
1832
|
const completionIdForkReject = bg.registry.getCompletionId(taskId);
|
|
1830
|
-
const summaryBg = `${shortDesc} — ${settledBg === "failed" ? `failed: ${msgFork}` : settledBg}`.slice(0, 300);
|
|
1833
|
+
const summaryBg = `${shortDesc} — ${settledBg === "failed" ? `failed: ${msgFork}` : settledBg}`.slice(0, 300) + (settledBg === "failed" ? errorKindClause(errClassForkReject) : "");
|
|
1831
1834
|
const ownsTerminalFacesForkReject = bg.registry.claimAgentTerminalNotify(taskId);
|
|
1832
1835
|
if (ownsTerminalFacesForkReject)
|
|
1833
1836
|
sinkEmit({
|
|
@@ -2390,7 +2393,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
2390
2393
|
...resultSettleFields(child.result),
|
|
2391
2394
|
...(!ok ? { error: reaped ? (collateral ? BG_AGENT_COLLATERAL_REAP_REASON : BG_AGENT_REAP_STOP_ERROR) : child.errorMessage ?? String(child.status) } : {}),
|
|
2392
2395
|
...(errCodeBg !== undefined ? { errorCode: errCodeBg } : {}),
|
|
2393
|
-
...(errClassBg !== undefined ? { retryable: errClassBg.retryable } : {}),
|
|
2396
|
+
...(errClassBg !== undefined ? { retryable: errClassBg.retryable, errorKind: errClassBg.errorKind } : {}),
|
|
2394
2397
|
}) ??
|
|
2395
2398
|
(abort.signal.aborted ? "killed" : ok ? "completed" : "failed");
|
|
2396
2399
|
if (!bgRetain && reviveRow === undefined && !(await bgRowConfirmed())) {
|
|
@@ -2408,7 +2411,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
2408
2411
|
const resumableBg = bgRetain !== undefined && settled !== "killed";
|
|
2409
2412
|
const failReasonBg = settled === "failed" ? child.errorMessage : undefined;
|
|
2410
2413
|
const bgTerminalSummary = failReasonBg !== undefined
|
|
2411
|
-
? `Agent "${shortDesc}" failed: ${failReasonBg}${ccElapsedTag(Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300)
|
|
2414
|
+
? `Agent "${shortDesc}" failed: ${failReasonBg}${ccElapsedTag(Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + errorKindClause(errClassBg)
|
|
2412
2415
|
: `${ccCompletionText(shortDesc, settled, String(child.status), Date.now() - bgStartedAt)}${observerNote}`;
|
|
2413
2416
|
const ownsTerminalFaces = bg.registry.claimAgentTerminalNotify(taskId);
|
|
2414
2417
|
if (ownsTerminalFaces)
|
|
@@ -2485,7 +2488,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
2485
2488
|
error: msg,
|
|
2486
2489
|
seq: seqAtSettle ?? 1,
|
|
2487
2490
|
...(errCodeBgReject !== undefined ? { errorCode: errCodeBgReject } : {}),
|
|
2488
|
-
...(errClassBgReject !== undefined ? { retryable: errClassBgReject.retryable } : {}),
|
|
2491
|
+
...(errClassBgReject !== undefined ? { retryable: errClassBgReject.retryable, errorKind: errClassBgReject.errorKind } : {}),
|
|
2489
2492
|
}) ?? (killed ? "killed" : "failed");
|
|
2490
2493
|
if (!bgRetain && reviveRow === undefined && !(await bgRowConfirmed())) {
|
|
2491
2494
|
try {
|
|
@@ -2510,7 +2513,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
2510
2513
|
status: settled,
|
|
2511
2514
|
...(seqAtSettle !== undefined ? { seq: seqAtSettle } : {}),
|
|
2512
2515
|
...(stoppedBy !== undefined ? { stoppedBy } : {}),
|
|
2513
|
-
summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300),
|
|
2516
|
+
summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + (settled === "failed" ? errorKindClause(errClassBgReject) : ""),
|
|
2514
2517
|
...(completionIdBgReject !== undefined ? { completionId: completionIdBgReject } : {}),
|
|
2515
2518
|
});
|
|
2516
2519
|
try {
|
|
@@ -2523,7 +2526,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
2523
2526
|
sessionId: bgChildSessionId,
|
|
2524
2527
|
...(seqAtSettle !== undefined ? { seq: seqAtSettle } : {}),
|
|
2525
2528
|
...(stoppedBy !== undefined ? { stoppedBy } : {}),
|
|
2526
|
-
summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300),
|
|
2529
|
+
summary: `${settled === "failed" ? `Agent "${shortDesc}" failed: ${msg}${ccElapsedTag(Date.now() - bgStartedAt)}` : ccCompletionText(shortDesc, settled, settled, Date.now() - bgStartedAt)}${observerNote}`.slice(0, 300) + (settled === "failed" ? errorKindClause(errClassBgReject) : ""),
|
|
2527
2530
|
...(settled === "failed" ? { error: msg.slice(0, REPORT_FIELD_MAX) } : {}),
|
|
2528
2531
|
...(settled === "failed" && errCodeBgReject !== undefined ? { errorCode: errCodeBgReject } : {}),
|
|
2529
2532
|
...(completionIdBgReject !== undefined ? { completionId: completionIdBgReject } : {}),
|
|
@@ -96,11 +96,13 @@ export interface MaybeCompactOptions {
|
|
|
96
96
|
droppedChars: number;
|
|
97
97
|
keptChars: number;
|
|
98
98
|
}) => void;
|
|
99
|
+
activeTools?: ReadonlyArray<string>;
|
|
99
100
|
}
|
|
100
101
|
export declare function maybeCompact(opts: MaybeCompactOptions): Promise<{
|
|
101
102
|
compacted: boolean;
|
|
102
103
|
blocked?: boolean;
|
|
103
104
|
disabled?: boolean;
|
|
105
|
+
noop?: true;
|
|
104
106
|
tokensBefore?: number;
|
|
105
107
|
freedTokens?: number;
|
|
106
108
|
triggerTokens?: number;
|
|
@@ -86,7 +86,7 @@ export async function maybeCompact(opts) {
|
|
|
86
86
|
throw prep.error;
|
|
87
87
|
}
|
|
88
88
|
if (!prep.value) {
|
|
89
|
-
return { contextUsage, compacted: false };
|
|
89
|
+
return { contextUsage, compacted: false, noop: true };
|
|
90
90
|
}
|
|
91
91
|
const trigger = opts.trigger ?? "auto";
|
|
92
92
|
let hookInstructions;
|
|
@@ -454,6 +454,7 @@ export async function maybeCompact(opts) {
|
|
|
454
454
|
...(details ?? {}),
|
|
455
455
|
promptEpoch: restatedEpoch,
|
|
456
456
|
...(restatedListings !== undefined ? { announcedListings: restatedListings } : {}),
|
|
457
|
+
...(opts.activeTools !== undefined && opts.activeTools.length > 0 ? { activeTools: [...opts.activeTools] } : {}),
|
|
457
458
|
}, false);
|
|
458
459
|
try {
|
|
459
460
|
opts.onApplied?.(attachedComplete, excludedReadStatePreserveKeys);
|
package/dist/core/mcp.js
CHANGED
|
@@ -1039,13 +1039,16 @@ function intakeListedTools(listed, spec, client, health, imageResizer) {
|
|
|
1039
1039
|
if (axis)
|
|
1040
1040
|
serverAxes.push(axis);
|
|
1041
1041
|
const writeEffect = (axis?.effect ?? "write") === "write";
|
|
1042
|
-
const
|
|
1042
|
+
const mcpToolMeta = t._meta;
|
|
1043
|
+
const mcpMaxResultSizeChars = resolveMcpDeclaredResultSize(mcpToolMeta);
|
|
1044
|
+
const mcpAlwaysLoad = mcpToolMeta?.["anthropic/alwaysLoad"] === true;
|
|
1043
1045
|
serverTools.push({
|
|
1044
1046
|
name: namespacedName,
|
|
1045
1047
|
description: effectiveDescription ?? `MCP tool ${remoteName} from ${spec.name}`,
|
|
1046
1048
|
label: `${spec.name}:${remoteName}`,
|
|
1047
1049
|
parameters: (effectiveInputSchema ?? { type: "object" }),
|
|
1048
1050
|
...(mcpMaxResultSizeChars !== undefined ? { mcpMaxResultSizeChars } : {}),
|
|
1051
|
+
...(mcpAlwaysLoad ? { mcpAlwaysLoad: true } : {}),
|
|
1049
1052
|
execute: async (_toolCallId, params, signal) => {
|
|
1050
1053
|
const what = `The call to tool ${inlineUntrusted(remoteName)}`;
|
|
1051
1054
|
if (health.dead)
|
|
@@ -327,6 +327,11 @@ export interface RunInternals {
|
|
|
327
327
|
requestedCwd?: string;
|
|
328
328
|
onSubagentSpawn?: (handle: import("../../agents/subagent.js").SubagentSteerHandle) => void;
|
|
329
329
|
onActivity?: (activity: ToolActivity) => void;
|
|
330
|
+
onWorkspaceResolved?: (workspace: ResolvedWorkspace) => void;
|
|
331
|
+
}
|
|
332
|
+
export interface ResolvedWorkspace {
|
|
333
|
+
cwd: string;
|
|
334
|
+
isolated: boolean;
|
|
330
335
|
}
|
|
331
336
|
export declare function batchContextAt(messages: AgentMessage[], currentId: string): {
|
|
332
337
|
batchToolCallIds: string[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
3
|
import { resolve as resolveFsPath } from "node:path";
|
|
4
|
-
import { AgentHarness, DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, estimateContextTokens, summaryOutputBudgetTokens } from "../../internal/harness.js";
|
|
4
|
+
import { AgentHarness, DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, estimateContextTokens, readCompactionActiveTools, summaryOutputBudgetTokens } from "../../internal/harness.js";
|
|
5
5
|
const PROMPT_HASH_SALT = randomBytes(16);
|
|
6
6
|
import { sanitizeCompactionSettings } from "../auto-compaction.js";
|
|
7
7
|
import { createAutoModeDecider } from "../auto-mode.js";
|
|
@@ -177,6 +177,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
177
177
|
const toolFaceSnapshot = {
|
|
178
178
|
exclude: spec.excludeTools ? Object.freeze([...spec.excludeTools]) : undefined,
|
|
179
179
|
defer: spec.deferTools ? Object.freeze([...spec.deferTools]) : undefined,
|
|
180
|
+
alwaysLoad: spec.alwaysLoadTools ? Object.freeze([...spec.alwaysLoadTools]) : undefined,
|
|
180
181
|
};
|
|
181
182
|
const promptProfile = resolveModelPromptTraits({ id: "" }, spec, internals).promptProfile;
|
|
182
183
|
if (spec.resumeAt !== undefined) {
|
|
@@ -608,6 +609,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
608
609
|
}
|
|
609
610
|
}
|
|
610
611
|
}
|
|
612
|
+
if (internals?.onWorkspaceResolved !== undefined) {
|
|
613
|
+
try {
|
|
614
|
+
internals.onWorkspaceResolved({ cwd: taskRootPath, isolated: internals.isolation === "worktree" });
|
|
615
|
+
}
|
|
616
|
+
catch {
|
|
617
|
+
}
|
|
618
|
+
}
|
|
611
619
|
let rewindTarget = spec.resumeAt !== undefined ? (spec.rewindFiles ? spec.resumeAt : undefined) : spec.rewindFilesTo;
|
|
612
620
|
const rewindBefore = rewindTarget !== undefined && spec.resumeAt !== undefined && spec.resumeAtMode === "before";
|
|
613
621
|
if (rewindTarget !== undefined && deps.fileSnapshotStore && handsEnabled) {
|
|
@@ -1781,6 +1789,10 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1781
1789
|
deferMode: deps.deferMode,
|
|
1782
1790
|
model,
|
|
1783
1791
|
deferNames: (toolFaceSnapshot.defer ?? []).filter((n) => tools.some((t) => t.name === n)),
|
|
1792
|
+
alwaysLoadNames: [
|
|
1793
|
+
...(toolFaceSnapshot.alwaysLoad ?? []),
|
|
1794
|
+
...mcp.tools.filter((t) => t.mcpAlwaysLoad === true).map((t) => t.name),
|
|
1795
|
+
],
|
|
1784
1796
|
});
|
|
1785
1797
|
for (const n of [...deferred]) {
|
|
1786
1798
|
if (!tools.some((t) => t.name === n))
|
|
@@ -1820,6 +1832,14 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1820
1832
|
if (deferred.has(n))
|
|
1821
1833
|
activeTools.add(n);
|
|
1822
1834
|
}
|
|
1835
|
+
for (const entry of await session.getBranch()) {
|
|
1836
|
+
if (entry.type !== "compaction" || entry.fromHook === true)
|
|
1837
|
+
continue;
|
|
1838
|
+
for (const n of readCompactionActiveTools(entry.details)) {
|
|
1839
|
+
if (deferred.has(n))
|
|
1840
|
+
activeTools.add(n);
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1823
1843
|
if (resume) {
|
|
1824
1844
|
for (const n of resume.seed.activeTools)
|
|
1825
1845
|
if (deferred.has(n))
|
|
@@ -538,6 +538,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
538
538
|
prepared.reviewRef.token !== undefined) {
|
|
539
539
|
if (forceManual) {
|
|
540
540
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "task_ending", ts: Date.now() }));
|
|
541
|
+
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: "manual", reason: "task_ending", ...ident() });
|
|
541
542
|
drainManualCompact("mooted");
|
|
542
543
|
}
|
|
543
544
|
return undefined;
|
|
@@ -552,6 +553,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
552
553
|
reason: "compaction circuit breaker open (3 consecutive failures this task) — manual request drained without an attempt",
|
|
553
554
|
ts: Date.now(),
|
|
554
555
|
}));
|
|
556
|
+
queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "manual", reason: "compaction circuit breaker open (3 consecutive failures this task) — manual request drained without an attempt", ...ident() });
|
|
555
557
|
drainManualCompact("failed");
|
|
556
558
|
}
|
|
557
559
|
return undefined;
|
|
@@ -590,6 +592,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
590
592
|
if (trimPressureArmed)
|
|
591
593
|
prepared.trimPressureRef.droppedMessages = false;
|
|
592
594
|
const trimPressure = trimPressureArmed && !rs.counters.trimForceBackoff;
|
|
595
|
+
const passTrigger = trimPressure ? "forced" : forceManual ? "manual" : "auto";
|
|
593
596
|
let manualOutcome = "failed";
|
|
594
597
|
if (rs.counters.finalizeInjected && forceManual) {
|
|
595
598
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.manual_in_finalize", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
@@ -617,6 +620,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
617
620
|
onInputTruncated: (info) => emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId: rs.telemetry.taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
618
621
|
forceUnderThreshold: trimPressure,
|
|
619
622
|
overheadTokens: prepared.promptOverheadTokens,
|
|
623
|
+
...(prepared.activeTools.size > 0 ? { activeTools: [...prepared.activeTools] } : {}),
|
|
620
624
|
workingFileAttachments: spec.compaction?.attachWorkingFiles !== false && prepared.readTaskFile
|
|
621
625
|
? {
|
|
622
626
|
readFile: prepared.readTaskFile,
|
|
@@ -632,7 +636,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
632
636
|
...(prepared.onCompactionApplied ? { onApplied: prepared.onCompactionApplied } : {}),
|
|
633
637
|
...runnerHooks.seamCCompactionOptions(prepared),
|
|
634
638
|
...windowSafetyOptions(event.model),
|
|
635
|
-
...runnerHooks.compactionHookOptions(spec, prepared.sessionId,
|
|
639
|
+
...runnerHooks.compactionHookOptions(spec, prepared.sessionId, passTrigger),
|
|
636
640
|
});
|
|
637
641
|
if (comp.blocked) {
|
|
638
642
|
emitTrace(rs.telemetry.tracer, () => ({
|
|
@@ -670,17 +674,32 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
670
674
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.noop", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
671
675
|
}
|
|
672
676
|
}
|
|
677
|
+
if (!comp.compacted) {
|
|
678
|
+
const outcome = comp.blocked
|
|
679
|
+
? "blocked"
|
|
680
|
+
: comp.disabled
|
|
681
|
+
? (forceManual || trimPressure ? "disabled" : undefined)
|
|
682
|
+
: comp.suppressedByFloor
|
|
683
|
+
? "suppressed"
|
|
684
|
+
: comp.noop || forceManual
|
|
685
|
+
? "noop"
|
|
686
|
+
: undefined;
|
|
687
|
+
if (outcome !== undefined) {
|
|
688
|
+
queue.push({ type: "compaction_outcome", outcome, trigger: passTrigger, ...ident() });
|
|
689
|
+
}
|
|
690
|
+
}
|
|
673
691
|
if (comp.compacted && !forceManual) {
|
|
674
692
|
if (recordCompactionAndCheckRapidRefill(rapidRefill, stats.turns)) {
|
|
675
693
|
compactionBreaker.failures = MAX_CONSECUTIVE_COMPACTION_FAILURES;
|
|
676
694
|
runnerHooks.onError?.(new Error("compaction.rapid_refill: the context refilled within <3 turns of compaction 3 times in a row — compaction disabled for the rest of this task (thrash spiral; the transcript is dominated by incompressible content)"), { phase: "compaction", sessionId: prepared.sessionId });
|
|
695
|
+
queue.push({ type: "compaction_outcome", outcome: "disabled", trigger: passTrigger, reason: "rapid_refill: compaction disabled for the rest of this task", ...ident() });
|
|
677
696
|
}
|
|
678
697
|
}
|
|
679
698
|
runnerHooks.recordCompactionReuse(prepared, comp);
|
|
680
699
|
if (comp.compacted) {
|
|
681
700
|
queue.push({
|
|
682
701
|
type: "compacted",
|
|
683
|
-
trigger:
|
|
702
|
+
trigger: passTrigger,
|
|
684
703
|
tokensBefore: comp.tokensBefore ?? 0,
|
|
685
704
|
...(comp.postTriggerTokens !== undefined ? { tokensAfter: comp.postTriggerTokens } : {}),
|
|
686
705
|
...(comp.triggerTokens !== undefined ? { triggerTokensBefore: comp.triggerTokens } : {}),
|
|
@@ -692,6 +711,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
692
711
|
...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
|
|
693
712
|
...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
|
|
694
713
|
...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
|
|
714
|
+
...ident(),
|
|
695
715
|
});
|
|
696
716
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
697
717
|
const pd = comp.phaseDurations;
|
|
@@ -713,6 +733,7 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
713
733
|
const manualCancelAbort = !prepared.abortController.signal.aborted && isCompactionManualCancel(err);
|
|
714
734
|
if (manualCancelAbort) {
|
|
715
735
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "cancelled", ts: Date.now() }));
|
|
736
|
+
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: passTrigger, reason: "cancelled", ...ident() });
|
|
716
737
|
manualOutcome = "mooted";
|
|
717
738
|
}
|
|
718
739
|
else if (!prepared.abortController.signal.aborted) {
|
|
@@ -721,18 +742,20 @@ function makeTurnBoundary(prepared, stats, rs, deps) {
|
|
|
721
742
|
compactionBreaker.failures += 1;
|
|
722
743
|
runnerHooks.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
|
|
723
744
|
const msg = String(err instanceof Error ? err.message : err);
|
|
745
|
+
const failReason = walltimeAbort
|
|
746
|
+
? "walltime soft-deadline abort (engine-initiated write-out protection; not counted toward the breaker)"
|
|
747
|
+
: msg.length > 512
|
|
748
|
+
? `${msg.slice(0, 512)}…`
|
|
749
|
+
: msg;
|
|
724
750
|
emitTrace(rs.telemetry.tracer, () => ({
|
|
725
751
|
kind: "compaction.failed",
|
|
726
752
|
version: 1,
|
|
727
753
|
taskId: rs.telemetry.taskId,
|
|
728
|
-
trigger:
|
|
729
|
-
reason:
|
|
730
|
-
? "walltime soft-deadline abort (engine-initiated write-out protection; not counted toward the breaker)"
|
|
731
|
-
: msg.length > 512
|
|
732
|
-
? `${msg.slice(0, 512)}…`
|
|
733
|
-
: msg,
|
|
754
|
+
trigger: passTrigger,
|
|
755
|
+
reason: failReason,
|
|
734
756
|
ts: Date.now(),
|
|
735
757
|
}));
|
|
758
|
+
queue.push({ type: "compaction_outcome", outcome: "failed", trigger: passTrigger, reason: failReason, ...ident() });
|
|
736
759
|
manualOutcome = "failed";
|
|
737
760
|
}
|
|
738
761
|
else {
|
|
@@ -2319,6 +2342,7 @@ export class Runner {
|
|
|
2319
2342
|
minTokens: 0,
|
|
2320
2343
|
force: true,
|
|
2321
2344
|
overheadTokens: prepared.promptOverheadTokens,
|
|
2345
|
+
...(prepared.activeTools.size > 0 ? { activeTools: [...prepared.activeTools] } : {}),
|
|
2322
2346
|
onInputTruncated: (info) => emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId: rs.telemetry.taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
2323
2347
|
workingFileAttachments: spec.compaction?.attachWorkingFiles !== false && prepared.readTaskFile
|
|
2324
2348
|
? {
|
|
@@ -2346,7 +2370,7 @@ export class Runner {
|
|
|
2346
2370
|
}
|
|
2347
2371
|
queue.push({
|
|
2348
2372
|
type: "compacted",
|
|
2349
|
-
trigger: "
|
|
2373
|
+
trigger: "forced",
|
|
2350
2374
|
tokensBefore: comp.tokensBefore ?? 0,
|
|
2351
2375
|
...(comp.postTriggerTokens !== undefined ? { tokensAfter: comp.postTriggerTokens } : {}),
|
|
2352
2376
|
...(comp.triggerTokens !== undefined ? { triggerTokensBefore: comp.triggerTokens } : {}),
|
|
@@ -2358,6 +2382,7 @@ export class Runner {
|
|
|
2358
2382
|
...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
|
|
2359
2383
|
...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
|
|
2360
2384
|
...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
|
|
2385
|
+
...ident(),
|
|
2361
2386
|
});
|
|
2362
2387
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
2363
2388
|
const pd = comp.phaseDurations;
|
|
@@ -2372,12 +2397,15 @@ export class Runner {
|
|
|
2372
2397
|
}
|
|
2373
2398
|
else {
|
|
2374
2399
|
compactionBreaker.failures += 1;
|
|
2400
|
+
queue.push({ type: "compaction_outcome", outcome: comp.noop ? "noop" : "failed", trigger: "forced", reason: "prompt-too-long recovery pass did not land", ...ident() });
|
|
2375
2401
|
}
|
|
2376
2402
|
return comp.compacted === true;
|
|
2377
2403
|
}
|
|
2378
2404
|
catch (err) {
|
|
2379
2405
|
if (!isCompactionWalltimeAbort(err))
|
|
2380
2406
|
compactionBreaker.failures += 1;
|
|
2407
|
+
const msg = String(err instanceof Error ? err.message : err);
|
|
2408
|
+
queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "forced", reason: msg.length > 512 ? `${msg.slice(0, 512)}…` : msg, ...ident() });
|
|
2381
2409
|
return false;
|
|
2382
2410
|
}
|
|
2383
2411
|
},
|
|
@@ -2661,6 +2689,7 @@ export class Runner {
|
|
|
2661
2689
|
...(comp.fallbackReason !== undefined ? { fallbackReason: comp.fallbackReason } : {}),
|
|
2662
2690
|
...(comp.clampedRatio !== undefined ? { clampedRatio: comp.clampedRatio } : {}),
|
|
2663
2691
|
...(comp.clampReason !== undefined ? { clampReason: comp.clampReason } : {}),
|
|
2692
|
+
...ident(),
|
|
2664
2693
|
});
|
|
2665
2694
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
2666
2695
|
const pd = comp.phaseDurations;
|
|
@@ -3453,6 +3482,7 @@ export class Runner {
|
|
|
3453
3482
|
customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
|
|
3454
3483
|
minTokens: opts?.minTokens,
|
|
3455
3484
|
overheadTokens: prepared.promptOverheadTokens,
|
|
3485
|
+
...(prepared.activeTools.size > 0 ? { activeTools: [...prepared.activeTools] } : {}),
|
|
3456
3486
|
onInputTruncated: (info) => emitTrace(spec.tracer ?? this.deps.tracer, () => ({
|
|
3457
3487
|
kind: "compaction.input_truncated",
|
|
3458
3488
|
version: 1,
|
|
@@ -21,6 +21,7 @@ export declare function classifyDeferred(opts: {
|
|
|
21
21
|
deferMode?: "auto";
|
|
22
22
|
model: Model;
|
|
23
23
|
deferNames?: ReadonlyArray<string>;
|
|
24
|
+
alwaysLoadNames?: ReadonlyArray<string>;
|
|
24
25
|
}): Set<string>;
|
|
25
26
|
export declare function buildDeferredRegistry(deferred: ReadonlySet<string>, tools: ReadonlyArray<{
|
|
26
27
|
name: string;
|
|
@@ -24,17 +24,24 @@ function inlinedChars(t) {
|
|
|
24
24
|
return t.description.length + schema.length;
|
|
25
25
|
}
|
|
26
26
|
export function classifyDeferred(opts) {
|
|
27
|
+
const pinned = new Set(opts.alwaysLoadNames ?? []);
|
|
28
|
+
for (const s of opts.specs) {
|
|
29
|
+
if (s.alwaysLoad === true)
|
|
30
|
+
pinned.add(s.name);
|
|
31
|
+
}
|
|
27
32
|
const deferred = new Set();
|
|
28
33
|
for (const s of opts.specs) {
|
|
29
|
-
if (s.defer === true)
|
|
34
|
+
if (s.defer === true && !pinned.has(s.name))
|
|
30
35
|
deferred.add(s.name);
|
|
31
36
|
}
|
|
32
37
|
for (const name of opts.mcpToolNames)
|
|
33
|
-
|
|
38
|
+
if (!pinned.has(name))
|
|
39
|
+
deferred.add(name);
|
|
34
40
|
for (const name of opts.deferNames ?? [])
|
|
35
|
-
|
|
41
|
+
if (!pinned.has(name))
|
|
42
|
+
deferred.add(name);
|
|
36
43
|
if (opts.deferMode === "auto") {
|
|
37
|
-
const candidates = opts.fullTools.filter((t) => !deferred.has(t.name));
|
|
44
|
+
const candidates = opts.fullTools.filter((t) => !deferred.has(t.name) && !pinned.has(t.name));
|
|
38
45
|
const total = candidates.reduce((n, t) => n + inlinedChars(t), 0);
|
|
39
46
|
const window = (opts.model.contextTokens ?? opts.model.contextWindow ?? 0) * CHARS_PER_TOKEN;
|
|
40
47
|
if (window > 0 && total > DEFER_AUTO_FRACTION * window) {
|
|
@@ -159,10 +166,14 @@ export function createToolSearchTool(opts) {
|
|
|
159
166
|
name: TOOL_SEARCH_NAME,
|
|
160
167
|
contract: { contractId: "core.tool_search@1", implementationRevision: "1" },
|
|
161
168
|
description: "Discover and activate deferred tools. Most tools start as name-only placeholders to keep requests " +
|
|
162
|
-
"small; to USE one you must activate it here first.
|
|
169
|
+
"small; to USE one you must activate it here first. When any instruction, reminder, or another " +
|
|
170
|
+
'tool\'s description names a deferred tool, activate it with query "select:<name>" before calling it. ' +
|
|
171
|
+
"Query forms: " +
|
|
163
172
|
'"select:ToolA,ToolB" — activate these exact tools by name; ' +
|
|
164
173
|
'"notebook jupyter" — keyword search, up to max_results best matches; ' +
|
|
165
174
|
"a bare tool name — activates that tool directly. " +
|
|
175
|
+
"Activate every tool you expect to need in one call (select accepts a comma-separated list) " +
|
|
176
|
+
"rather than one at a time. " +
|
|
166
177
|
"Activated tools become callable with their full parameters on your next turn.",
|
|
167
178
|
parameters: Type.Object({
|
|
168
179
|
query: Type.Optional(Type.String({
|
|
@@ -13,6 +13,7 @@ const INTERRUPTED_NEVER_STARTED = "[INTERRUPTED] The run was aborted before this
|
|
|
13
13
|
"no side effects — it is safe to re-issue this call if you still need it.";
|
|
14
14
|
export function findOrphanToolCalls(messages, suspendedBatch) {
|
|
15
15
|
const resolvedAt = new Map();
|
|
16
|
+
const callSitesAt = new Map();
|
|
16
17
|
messages.forEach((m, i) => {
|
|
17
18
|
if (m.role === "toolResult") {
|
|
18
19
|
const at = resolvedAt.get(m.toolCallId);
|
|
@@ -21,35 +22,54 @@ export function findOrphanToolCalls(messages, suspendedBatch) {
|
|
|
21
22
|
else
|
|
22
23
|
at.push(i);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
else if (m.role === "assistant") {
|
|
26
|
+
for (const part of m.content) {
|
|
27
|
+
if (part.type !== "toolCall")
|
|
28
|
+
continue;
|
|
29
|
+
const at = callSitesAt.get(part.id);
|
|
30
|
+
if (at === undefined)
|
|
31
|
+
callSitesAt.set(part.id, [i]);
|
|
32
|
+
else
|
|
33
|
+
at.push(i);
|
|
34
|
+
}
|
|
32
35
|
}
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
});
|
|
37
|
+
const nextReuseAfter = (id, from) => callSitesAt.get(id)?.find((j) => j > from) ?? Number.POSITIVE_INFINITY;
|
|
35
38
|
const orphans = [];
|
|
36
39
|
messages.forEach((m, i) => {
|
|
37
|
-
if (m.role
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
if (m.role === "assistant") {
|
|
41
|
+
for (const part of m.content) {
|
|
42
|
+
if (part.type !== "toolCall" || suspendedBatch?.has(part.id))
|
|
43
|
+
continue;
|
|
44
|
+
const bound = nextReuseAfter(part.id, i);
|
|
45
|
+
const closed = (resolvedAt.get(part.id) ?? []).some((at) => at > i && at < bound);
|
|
46
|
+
if (!closed)
|
|
47
|
+
orphans.push({ toolCallId: part.id, toolName: part.name });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (m.role === "toolResult") {
|
|
51
|
+
if (suspendedBatch?.has(m.toolCallId))
|
|
52
|
+
return;
|
|
53
|
+
const sites = callSitesAt.get(m.toolCallId) ?? [];
|
|
54
|
+
const results = resolvedAt.get(m.toolCallId) ?? [];
|
|
55
|
+
let paired = false;
|
|
56
|
+
for (const j of sites) {
|
|
57
|
+
if (j >= i)
|
|
58
|
+
break;
|
|
59
|
+
if (!results.some((at) => at > j && at < i)) {
|
|
60
|
+
paired = true;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!paired)
|
|
65
|
+
orphans.push({ toolCallId: m.toolCallId, toolName: m.toolName, kind: "result" });
|
|
46
66
|
}
|
|
47
67
|
});
|
|
48
68
|
return orphans;
|
|
49
69
|
}
|
|
50
70
|
export async function reconcileInterruptedSession(session, toolEffects, suspendedBatch, startedToolCallIds) {
|
|
51
71
|
const { messages } = await session.buildContext();
|
|
52
|
-
const orphans = findOrphanToolCalls(messages, suspendedBatch);
|
|
72
|
+
const orphans = findOrphanToolCalls(messages, suspendedBatch).filter((o) => o.kind !== "result");
|
|
53
73
|
const recovered = [];
|
|
54
74
|
for (const orphan of orphans) {
|
|
55
75
|
const effect = toolEffects?.get(canonicalToolName(orphan.toolName)) ?? "write";
|
|
@@ -68,6 +68,7 @@ export declare function settleBackgroundAgentLane(core: DurableAgentCore, id: st
|
|
|
68
68
|
error?: string;
|
|
69
69
|
errorCode?: string;
|
|
70
70
|
retryable?: boolean;
|
|
71
|
+
errorKind?: string;
|
|
71
72
|
stoppedBy?: StopSource;
|
|
72
73
|
seq?: number;
|
|
73
74
|
}): "completed" | "failed" | "killed" | undefined;
|
|
@@ -102,6 +103,7 @@ export declare function settleRevivedAgentLane(core: DurableAgentCore, id: strin
|
|
|
102
103
|
error?: string;
|
|
103
104
|
errorCode?: string;
|
|
104
105
|
retryable?: boolean;
|
|
106
|
+
errorKind?: string;
|
|
105
107
|
}): "completed" | "failed" | "killed" | undefined;
|
|
106
108
|
export declare function unmarkRetainedContinuationLane(core: DurableAgentCore, id: string): void;
|
|
107
109
|
export declare function attachAgentNotifyLane(core: DurableAgentCore, id: string, notify: NonNullable<BackgroundAgentTaskHandle["notify"]>, cycle?: number): void;
|