@sema-agent/core 3.0.0 → 4.0.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +2345 -0
  2. package/dist/agents/cascade.d.ts +2 -1
  3. package/dist/agents/cascade.js +31 -32
  4. package/dist/agents/cumulative-stats.d.ts +29 -0
  5. package/dist/agents/cumulative-stats.js +29 -0
  6. package/dist/agents/observer.d.ts +4 -0
  7. package/dist/agents/observer.js +11 -10
  8. package/dist/agents/repair-loop.js +27 -19
  9. package/dist/agents/retain-ledger.d.ts +2 -0
  10. package/dist/agents/retain-ledger.js +6 -5
  11. package/dist/agents/roster-store.js +3 -5
  12. package/dist/agents/subagent.js +66 -64
  13. package/dist/agents/teacher.d.ts +1 -9
  14. package/dist/agents/teacher.js +21 -24
  15. package/dist/agents/verify.js +15 -14
  16. package/dist/brain/anthropic.js +24 -21
  17. package/dist/brain/openai.js +24 -21
  18. package/dist/brain/stream-engine.js +5 -2
  19. package/dist/brain/stream-shared.d.ts +1 -0
  20. package/dist/brain/stream-shared.js +14 -0
  21. package/dist/brain/terminal-cause.d.ts +4 -0
  22. package/dist/brain/terminal-cause.js +12 -0
  23. package/dist/brain/tool-call-id.d.ts +1 -0
  24. package/dist/brain/tool-call-id.js +3 -0
  25. package/dist/brain/tool-call-repair.js +2 -1
  26. package/dist/core/auto-compaction.js +16 -25
  27. package/dist/core/background-agent-store.d.ts +22 -22
  28. package/dist/core/background-agent-store.js +19 -23
  29. package/dist/core/checkpoint-store.d.ts +6 -13
  30. package/dist/core/checkpoint-store.js +11 -5
  31. package/dist/core/file-snapshot-store.d.ts +8 -0
  32. package/dist/core/file-snapshot-store.js +4 -3
  33. package/dist/core/hooks.d.ts +3 -1
  34. package/dist/core/hooks.js +8 -18
  35. package/dist/core/lsp.js +4 -3
  36. package/dist/core/mailbox-store.d.ts +7 -10
  37. package/dist/core/mcp.d.ts +7 -10
  38. package/dist/core/mcp.js +7 -3
  39. package/dist/core/memory-engine/engine.d.ts +0 -1
  40. package/dist/core/memory-engine/engine.js +24 -34
  41. package/dist/core/memory-engine/file-backend.d.ts +1 -2
  42. package/dist/core/memory-engine/file-backend.js +25 -36
  43. package/dist/core/memory-engine/layout.d.ts +8 -0
  44. package/dist/core/memory-engine/layout.js +60 -4
  45. package/dist/core/memory-engine/scope-contract.js +9 -3
  46. package/dist/core/memory-engine/types.d.ts +1 -1
  47. package/dist/core/runner/active-skill-scope.d.ts +0 -1
  48. package/dist/core/runner/active-skill-scope.js +1 -15
  49. package/dist/core/runner/assemble-result.d.ts +2 -7
  50. package/dist/core/runner/assemble-result.js +3 -4
  51. package/dist/core/runner/compaction-call-options.d.ts +7 -0
  52. package/dist/core/runner/compaction-call-options.js +30 -0
  53. package/dist/core/runner/prepare-task.d.ts +6 -23
  54. package/dist/core/runner/prepare-task.js +20 -53
  55. package/dist/core/runner/runtask.d.ts +1 -0
  56. package/dist/core/runner/runtask.js +65 -156
  57. package/dist/core/runner/session-rule-policy.js +4 -1
  58. package/dist/core/runner/teardown-bounded.d.ts +7 -0
  59. package/dist/core/runner/teardown-bounded.js +36 -0
  60. package/dist/core/runner/tool-disclosure.d.ts +2 -5
  61. package/dist/core/runner/turn-attachments.d.ts +5 -15
  62. package/dist/core/runner/turn-attachments.js +1 -1
  63. package/dist/core/safe-notify.d.ts +17 -0
  64. package/dist/core/safe-notify.js +59 -0
  65. package/dist/core/sensitive-path-policy.js +2 -1
  66. package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
  67. package/dist/core/stub-env.d.ts +2 -6
  68. package/dist/core/surrogate-safe-slice.d.ts +4 -0
  69. package/dist/core/surrogate-safe-slice.js +18 -0
  70. package/dist/core/task-registry-monitor.js +8 -13
  71. package/dist/core/task-registry-shared.d.ts +22 -0
  72. package/dist/core/task-registry-shared.js +16 -0
  73. package/dist/core/task-registry.d.ts +1 -0
  74. package/dist/core/task-registry.js +40 -57
  75. package/dist/core/tool-errors.js +5 -4
  76. package/dist/core/tool-name-aliases.js +2 -1
  77. package/dist/core/tool-policy.js +10 -5
  78. package/dist/core/tool-result-store.d.ts +1 -0
  79. package/dist/core/tool-result-store.js +17 -1
  80. package/dist/core/trace.d.ts +2 -9
  81. package/dist/core/types.d.ts +15 -12
  82. package/dist/core/untrusted-egress.js +7 -5
  83. package/dist/core/workflow-journal-store.d.ts +9 -20
  84. package/dist/core/workflow-run-store.d.ts +11 -10
  85. package/dist/core/workflow-run-store.js +22 -16
  86. package/dist/engine/compaction/utils.js +4 -2
  87. package/dist/engine/execution-env/node-execution-env.d.ts +2 -24
  88. package/dist/engine/harness/agent-harness.d.ts +1 -0
  89. package/dist/engine/harness/agent-harness.js +13 -33
  90. package/dist/engine/harness/types.d.ts +29 -67
  91. package/dist/engine/llm/types.d.ts +1 -1
  92. package/dist/engine/loop/agent-loop.js +11 -4
  93. package/dist/engine/loop/types.d.ts +11 -9
  94. package/dist/engine/session/memory-repo.d.ts +2 -6
  95. package/dist/engine/session/session.d.ts +5 -30
  96. package/dist/index.d.ts +3 -1
  97. package/dist/index.js +2 -1
  98. package/dist/internal/harness-types.d.ts +3 -1
  99. package/dist/orchestration/run-spec.js +7 -4
  100. package/dist/orchestration/run-workflow-tool.js +3 -35
  101. package/dist/orchestration/workflow.d.ts +3 -11
  102. package/dist/orchestration/workflow.js +164 -204
  103. package/dist/prompt-assembly/tool-catalog.d.ts +10 -9
  104. package/dist/prompt-assembly/turn-snapshot.d.ts +2 -5
  105. package/dist/stores/file/background-agent-store.d.ts +3 -12
  106. package/dist/stores/file/background-agent-store.js +3 -41
  107. package/dist/stores/file/checkpoint-store.js +6 -6
  108. package/dist/stores/file/mailbox-store.d.ts +2 -6
  109. package/dist/stores/file/session-policy-store.js +15 -1
  110. package/dist/stores/file/session-store.d.ts +2 -6
  111. package/dist/stores/file/workflow-journal-store.d.ts +3 -11
  112. package/dist/stores/file/workflow-run-store.d.ts +3 -7
  113. package/dist/stores/file/workflow-run-store.js +4 -17
  114. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -0
  115. package/dist/tools/fs/bash-readonly-classifier.js +60 -25
  116. package/dist/tools/fs/fs-bash.js +324 -96
  117. package/dist/tools/fs/fs-pdf.d.ts +2 -12
  118. package/dist/tools/fs/fs-shared.js +2 -2
  119. package/dist/tools/fs/notebook.d.ts +2 -5
  120. package/dist/tools/fs/safety.d.ts +3 -0
  121. package/dist/tools/fs/safety.js +43 -14
  122. package/dist/tools/fs/search.js +5 -5
  123. package/dist/tools/monitor.d.ts +1 -0
  124. package/dist/tools/monitor.js +7 -5
  125. package/dist/tools/worktree.d.ts +2 -7
  126. package/dist/tools/worktree.js +3 -1
  127. package/package.json +6 -2
@@ -12,12 +12,13 @@ import type { SessionPermissionRules } from "../session-policy-store.js";
12
12
  import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
13
13
  import { type OutputRef, type BlockedRef, type SkillListingEntry } from "./synthetic-tools.js";
14
14
  import type { MemoryEngine } from "../memory-engine/engine.js";
15
+ import { type ToolManifestRow } from "../../prompt-assembly/tool-catalog.js";
15
16
  import type { TaskNotificationPayload } from "../task-notification.js";
16
17
  import { type CwdRef } from "../../tools/fs/index.js";
17
18
  import type { Runner } from "./runtask.js";
18
19
  import { type CheckpointGate, type CheckpointState, type CheckpointToken, type ResourceLedger, type ResourceLimitReason } from "../checkpoint-store.js";
19
- import type { AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
20
- import type { RunnerDeps, TaskEvent, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
20
+ import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
21
+ import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
21
22
  import type { RepairBundle } from "../../agents/repair-loop.js";
22
23
  export declare const DEFAULT_IRREVERSIBLE_SCOPE = "irreversible";
23
24
  export declare function checkpointScopeOf(spec: {
@@ -42,21 +43,11 @@ export interface Prepared {
42
43
  hit: boolean;
43
44
  };
44
45
  blockedToolCalls: Set<string>;
45
- nestedStats: {
46
- tokens: number;
47
- turns: number;
48
- tasks: number;
49
- costMicroUsd: number;
50
- };
46
+ nestedStats: NestedUsageAccum;
51
47
  rewindNotes?: NonNullable<TaskResult["rewindNotes"]>;
52
48
  cwdRef?: CwdRef;
53
49
  worktreeSessionRef?: {
54
- current?: {
55
- worktreeDir: string;
56
- originalCwd: string;
57
- baseSha: string;
58
- entered?: boolean;
59
- };
50
+ current?: ActiveWorktreeSession;
60
51
  };
61
52
  workspaceStateSettle?: {
62
53
  rootCanonical: string;
@@ -89,15 +80,7 @@ export interface Prepared {
89
80
  hash: string;
90
81
  contentHash?: string;
91
82
  }>;
92
- tools?: Array<{
93
- wireName: string;
94
- aliases: string[];
95
- contractId: string;
96
- implementationRevision: string;
97
- cardId: string;
98
- shapeDigest: string;
99
- wireSchemaDigest: string;
100
- }>;
83
+ tools?: ToolManifestRow[];
101
84
  snapshot?: {
102
85
  cacheIdentity: string;
103
86
  elements: import("../../prompt-assembly/turn-snapshot.js").CacheIdentityElements;
@@ -31,7 +31,7 @@ import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
31
31
  import { defineTool, isDefineToolProduct } from "../tools.js";
32
32
  import { canonicalToolName } from "../tool-name-aliases.js";
33
33
  import { pathToUri } from "../lsp-protocol.js";
34
- import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, buildToolResultRef, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME, createReadToolResultTool, withToolResultOffload, } from "../tool-result-store.js";
34
+ import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, createOffloadPersist, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME, createReadToolResultTool, withToolResultOffload, } from "../tool-result-store.js";
35
35
  import { OUTPUT_TOOL_NAME, REPORT_FINDINGS_TOOL_NAME, SKILL_CONTENT_MAX_CHARS, SKILL_TOOL_NAME, createOutputTool, createReportBlockedTool, createReportFindingsTool, createSkillTool, normalizeSkills } from "./synthetic-tools.js";
36
36
  import { compileOutputSchema } from "./strict-output-schema.js";
37
37
  import { TOOL_SEARCH_NAME, buildDeferredRegistry, classifyDeferred, extractDiscoveredToolNames, createPlaceholderTool, createToolSearchTool, } from "./tool-disclosure.js";
@@ -51,6 +51,7 @@ import { dropOrphanToolResults, guardBudget, insertTrimNotice, trimToBudget } fr
51
51
  import { StubExecutionEnv } from "../stub-env.js";
52
52
  import { hasDestroy, isIsolated, isRemoteExecutionEnv, isRetryableRemoteErrorCode, isSuspendable, missingRestoreSurface, RETRYABLE_REMOTE_ERROR_CODES } from "../remote-env.js";
53
53
  import { withRetry } from "../with-retry.js";
54
+ import { settleTeardownLeg } from "./teardown-bounded.js";
54
55
  import { hasBackgroundShell, sweepBackgroundShells } from "../background-shell.js";
55
56
  import { createTaskOutputTool, createTaskStopTool, defaultTaskRegistry } from "../task-registry.js";
56
57
  import { createMonitorTool } from "../../tools/monitor.js";
@@ -62,7 +63,7 @@ import { createSchedulerTools } from "../../tools/scheduler-tools.js";
62
63
  import { createPresentPlanTool, createEnterPlanModeTool, PRESENT_PLAN_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME } from "../present-plan-tool.js";
63
64
  import { isSelfOrchestrationActive, selfOrchestrationFailClosedReason } from "../../orchestration/workflow-script-runner.js";
64
65
  import { createRunWorkflowTool, RUN_WORKFLOW_TOOL_NAME } from "../../orchestration/run-workflow-tool.js";
65
- import { createLspTool, gitCheckIgnoreFilter } from "../lsp.js";
66
+ import { createLspTool, gitCheckIgnoreFilter, resolveLspPath } from "../lsp.js";
66
67
  import { resolveKey } from "../../tools/fs/safety.js";
67
68
  import { BINDING_CHECKPOINT_VERSION, mintCheckpointToken, RESOURCE_CHECKPOINT_VERSION, WALLTIME_CHECKPOINT_VERSION, buildRiskDescriptor, debitLedger, remainingBudgetMicroUsd, } from "../checkpoint-store.js";
68
69
  import { boundInputHashOf } from "../canonical-json.js";
@@ -442,18 +443,21 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
442
443
  if (extraBodyCollisions.length > 0) {
443
444
  deps.onError?.(new Error(`model.extraBody contains reserved key(s) [${extraBodyCollisions.join(", ")}] that core owns and sets itself — they are ignored. Remove them from extraBody.`), { phase: "config", sessionId });
444
445
  }
445
- const nestedStats = { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0 };
446
+ const nestedStats = { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0, anyUnpriced: false };
446
447
  if (resume) {
447
448
  nestedStats.tokens = resume.seed.nestedStats.tokens;
448
449
  nestedStats.turns = resume.seed.nestedStats.turns;
449
450
  nestedStats.tasks = resume.seed.nestedStats.tasks;
450
451
  nestedStats.costMicroUsd = resume.seed.nestedStats.costMicroUsd;
452
+ nestedStats.anyUnpriced = resume.seed.nestedStats.anyUnpriced ?? true;
451
453
  }
452
454
  const reportUsage = (u) => {
453
455
  nestedStats.tokens += u.tokens;
454
456
  nestedStats.turns += u.turns;
455
457
  nestedStats.tasks += u.tasks;
456
458
  nestedStats.costMicroUsd += u.costMicroUsd ?? 0;
459
+ if (u.costMicroUsd === undefined)
460
+ nestedStats.anyUnpriced = true;
457
461
  };
458
462
  const explicitGlobalThreshold = spec.toolResultThresholdChars ?? deps.toolResultThresholdChars;
459
463
  const offloadThreshold = explicitGlobalThreshold ?? DEFAULT_TOOL_RESULT_THRESHOLD_CHARS;
@@ -482,13 +486,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
482
486
  if (offloadStore && (spec.tools ?? []).some((t) => t.name === OFFLOAD_TOOL_NAME)) {
483
487
  const e = new Error(`Tool name "${OFFLOAD_TOOL_NAME}" is reserved when large-result offload is enabled.`);
484
488
  e.code = "config.reserved_tool_name";
485
- await forgetOnThrow();
489
+ await settleTeardownLeg(() => forgetOnThrow(), "forgetOnThrow (reserved-name leg)", (err) => deps.onError?.(err, { phase: "config", sessionId }));
486
490
  throw e;
487
491
  }
488
492
  let ownedEnv;
489
493
  let mcp;
490
494
  if (internals?.requestedCwd !== undefined && deps.executionEnvFactory === undefined) {
491
- await forgetOnThrow();
495
+ await settleTeardownLeg(() => forgetOnThrow(), "forgetOnThrow (cwd-unsupported leg)", (err) => deps.onError?.(err, { phase: "config", sessionId }));
492
496
  const e = new Error(`Agent cwd "${internals.requestedCwd}" cannot take effect: this deployment has no executionEnvFactory (a static execution environment cannot be re-rooted per agent). Drop the cwd parameter or deploy a factory.`);
493
497
  e.code = "config.cwd_unsupported";
494
498
  throw e;
@@ -504,7 +508,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
504
508
  : undefined;
505
509
  }
506
510
  catch (factoryErr) {
507
- await forgetOnThrow();
511
+ await settleTeardownLeg(() => forgetOnThrow(), "forgetOnThrow (env-factory-throw leg)", (err) => deps.onError?.(err, { phase: "config", sessionId }));
508
512
  throw factoryErr;
509
513
  }
510
514
  const executionEnv = ownedEnv ?? deps.executionEnv ?? new StubExecutionEnv();
@@ -515,13 +519,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
515
519
  };
516
520
  const want = await canon(internals.requestedCwd);
517
521
  const rejectCwd = async (message, code) => {
518
- await forgetOnThrow();
519
- try {
520
- if (ownedEnv && hasDestroy(ownedEnv))
521
- await ownedEnv.destroy();
522
- }
523
- catch {
524
- }
522
+ await settleTeardownLeg(() => forgetOnThrow(), "forgetOnThrow (cwd-reject leg)", (err) => deps.onError?.(err, { phase: "config", sessionId }));
523
+ await settleTeardownLeg(() => (ownedEnv && hasDestroy(ownedEnv) ? ownedEnv.destroy() : undefined), "ownedEnv.destroy (cwd-reject leg)", (err) => deps.onError?.(err, { phase: "config", sessionId }));
525
524
  const e = new Error(message);
526
525
  e.code = code;
527
526
  throw e;
@@ -1403,6 +1402,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1403
1402
  ...(internals?.onTaskNotification !== undefined ? { onTaskNotification: internals.onTaskNotification } : {}),
1404
1403
  ...(handsCwdRef !== undefined ? { cwdRef: handsCwdRef } : {}),
1405
1404
  ...(offloadStore !== undefined ? { toolResultStore: offloadStore } : {}),
1405
+ ...(spec.retainBackgroundProcesses === true ? { retainBackgroundProcesses: true } : {}),
1406
1406
  })));
1407
1407
  }
1408
1408
  if (handsCwdRef !== undefined) {
@@ -1466,30 +1466,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1466
1466
  const nudgeLspOnEdit = lspDiagnostics
1467
1467
  ? (rawPath) => {
1468
1468
  const baseDir = handsCwdRef?.current ?? taskRootPath;
1469
- const isAbsForm = rawPath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(rawPath);
1470
- const joinSep = baseDir.includes("\\") ? "\\" : "/";
1471
- const normalizeSegments = (pth) => {
1472
- const isUnc = pth.startsWith("\\\\");
1473
- const drive = /^[A-Za-z]:/.exec(pth)?.[0] ?? "";
1474
- const rest = pth.slice(drive.length + (isUnc ? 2 : 0));
1475
- const sep = pth.includes("\\") ? "\\" : "/";
1476
- const abs = rest.startsWith("/") || rest.startsWith("\\");
1477
- const outSegs = [];
1478
- for (const seg of rest.split(/[\\/]+/)) {
1479
- if (!seg || seg === ".")
1480
- continue;
1481
- if (seg === "..") {
1482
- if (outSegs.length > 0 && outSegs[outSegs.length - 1] !== "..")
1483
- outSegs.pop();
1484
- else if (!abs)
1485
- outSegs.push("..");
1486
- continue;
1487
- }
1488
- outSegs.push(seg);
1489
- }
1490
- return (isUnc ? sep + sep : "") + drive + (abs ? sep : "") + outSegs.join(sep);
1491
- };
1492
- const filePath = normalizeSegments(isAbsForm ? rawPath : baseDir.replace(/[\\/]+$/, "") + joinSep + rawPath);
1469
+ const filePath = resolveLspPath(rawPath, baseDir);
1493
1470
  lspDiagnostics.fileEdited(pathToUri(filePath));
1494
1471
  void lspManager
1495
1472
  .sessionFor(filePath, undefined, executionEnv)
@@ -3296,11 +3273,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3296
3273
  ...(offloadStore
3297
3274
  ? {
3298
3275
  offload: {
3299
- persist: (toolCallId, fullText) => {
3300
- const ref = buildToolResultRef(sessionId, toolCallId);
3301
- void offloadStore.put(ref, fullText);
3302
- return ref;
3303
- },
3276
+ persist: createOffloadPersist(offloadStore, sessionId),
3304
3277
  },
3305
3278
  }
3306
3279
  : {}),
@@ -3501,20 +3474,14 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3501
3474
  }
3502
3475
  catch (prepareErr) {
3503
3476
  if (mcp) {
3504
- try {
3505
- await mcp.dispose();
3506
- }
3507
- catch {
3508
- }
3477
+ const mcpHandle = mcp;
3478
+ await settleTeardownLeg(() => mcpHandle.dispose(), "mcp.dispose (prepare-throw leg)", (e) => deps.onError?.(e, { phase: "config", sessionId }));
3509
3479
  }
3510
3480
  if (ownedEnv && hasDestroy(ownedEnv)) {
3511
- try {
3512
- await ownedEnv.destroy();
3513
- }
3514
- catch {
3515
- }
3481
+ const env = ownedEnv;
3482
+ await settleTeardownLeg(() => env.destroy(), "ownedEnv.destroy (prepare-throw leg)", (e) => deps.onError?.(e, { phase: "config", sessionId }));
3516
3483
  }
3517
- await forgetOnThrow();
3484
+ await settleTeardownLeg(() => forgetOnThrow(), "forgetOnThrow (prepare-throw leg)", (e) => deps.onError?.(e, { phase: "config", sessionId }));
3518
3485
  throw prepareErr;
3519
3486
  }
3520
3487
  }
@@ -19,6 +19,7 @@ interface ResumeRun {
19
19
  trusted: boolean;
20
20
  };
21
21
  onEnvRestoreFailed?: (reason: ReopenReason) => Promise<void>;
22
+ decisionDelivered?: boolean;
22
23
  }
23
24
  export declare class Runner {
24
25
  private deps;