@sema-agent/core 5.12.0 → 5.14.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 (101) hide show
  1. package/CHANGELOG.md +320 -0
  2. package/dist/agents/send-message-tool.js +1 -0
  3. package/dist/agents/subagent.d.ts +4 -0
  4. package/dist/agents/subagent.js +137 -43
  5. package/dist/brain/anthropic.js +33 -10
  6. package/dist/brain/context-overflow.d.ts +20 -0
  7. package/dist/brain/context-overflow.js +58 -0
  8. package/dist/brain/open-responses.js +24 -10
  9. package/dist/brain/openai.js +29 -11
  10. package/dist/brain/request-params.d.ts +2 -0
  11. package/dist/brain/request-params.js +16 -0
  12. package/dist/brain/stream-engine.d.ts +9 -1
  13. package/dist/brain/stream-engine.js +256 -27
  14. package/dist/brain/timeout.d.ts +1 -0
  15. package/dist/brain/timeout.js +1 -0
  16. package/dist/core/a2a.d.ts +2 -2
  17. package/dist/core/a2a.js +3 -3
  18. package/dist/core/ask-question.d.ts +47 -2
  19. package/dist/core/ask-question.js +209 -28
  20. package/dist/core/background-agent-store.d.ts +2 -0
  21. package/dist/core/checkpoint-store.d.ts +49 -18
  22. package/dist/core/checkpoint-store.js +117 -4
  23. package/dist/core/compliance.d.ts +11 -0
  24. package/dist/core/compliance.js +34 -0
  25. package/dist/core/governance-codes.d.ts +12 -0
  26. package/dist/core/governance-codes.js +24 -0
  27. package/dist/core/hooks.d.ts +24 -2
  28. package/dist/core/hooks.js +97 -10
  29. package/dist/core/human-input-projection.d.ts +12 -0
  30. package/dist/core/human-input-projection.js +27 -0
  31. package/dist/core/locked-config.d.ts +27 -0
  32. package/dist/core/locked-config.js +42 -0
  33. package/dist/core/mcp.d.ts +7 -2
  34. package/dist/core/mcp.js +7 -7
  35. package/dist/core/memory-admission.d.ts +51 -0
  36. package/dist/core/memory-admission.js +159 -0
  37. package/dist/core/memory.d.ts +2 -0
  38. package/dist/core/memory.js +3 -2
  39. package/dist/core/retention.d.ts +36 -0
  40. package/dist/core/retention.js +31 -0
  41. package/dist/core/runner/assemble-result.d.ts +1 -0
  42. package/dist/core/runner/assemble-result.js +2 -2
  43. package/dist/core/runner/prepare-memory.d.ts +9 -0
  44. package/dist/core/runner/prepare-memory.js +28 -2
  45. package/dist/core/runner/prepare-task.d.ts +18 -6
  46. package/dist/core/runner/prepare-task.js +428 -38
  47. package/dist/core/runner/runtask.d.ts +3 -6
  48. package/dist/core/runner/runtask.js +258 -77
  49. package/dist/core/runner/tool-output-projection.js +1 -0
  50. package/dist/core/session-store.d.ts +4 -0
  51. package/dist/core/session-store.js +5 -0
  52. package/dist/core/session.d.ts +1 -0
  53. package/dist/core/store-contracts/background-agent-store-contract.js +19 -0
  54. package/dist/core/store-contracts/checkpoint-store-contract.js +62 -3
  55. package/dist/core/task-notification.d.ts +2 -0
  56. package/dist/core/task-notification.js +5 -3
  57. package/dist/core/task-registry-agent.d.ts +1 -0
  58. package/dist/core/task-registry-agent.js +6 -0
  59. package/dist/core/task-registry.d.ts +1 -0
  60. package/dist/core/task-registry.js +4 -1
  61. package/dist/core/tool-policy.d.ts +5 -0
  62. package/dist/core/tool-policy.js +2 -1
  63. package/dist/core/tool-result-store.d.ts +2 -0
  64. package/dist/core/tool-result-store.js +1 -0
  65. package/dist/core/types.d.ts +38 -2
  66. package/dist/core/wiring-manifest.d.ts +97 -0
  67. package/dist/core/wiring-manifest.js +186 -0
  68. package/dist/engine/compaction/compaction.js +2 -2
  69. package/dist/engine/harness/agent-harness.d.ts +2 -1
  70. package/dist/engine/harness/agent-harness.js +19 -2
  71. package/dist/engine/harness/types.d.ts +3 -1
  72. package/dist/engine/llm/types.d.ts +7 -0
  73. package/dist/engine/llm/types.js +8 -1
  74. package/dist/engine/llm/validation.js +11 -1
  75. package/dist/engine/session/import-validate.d.ts +6 -1
  76. package/dist/engine/session/import-validate.js +29 -6
  77. package/dist/engine/session/memory-repo.d.ts +3 -1
  78. package/dist/engine/session/memory-repo.js +2 -2
  79. package/dist/index.d.ts +12 -4
  80. package/dist/index.js +12 -4
  81. package/dist/internal/harness-types.d.ts +1 -1
  82. package/dist/internal/llm.d.ts +2 -2
  83. package/dist/internal/llm.js +1 -1
  84. package/dist/orchestration/run-workflow-tool.d.ts +4 -0
  85. package/dist/orchestration/run-workflow-tool.js +3 -0
  86. package/dist/orchestration/workflow-types.d.ts +8 -0
  87. package/dist/orchestration/workflow-types.js +14 -0
  88. package/dist/orchestration/workflow.d.ts +4 -0
  89. package/dist/orchestration/workflow.js +134 -5
  90. package/dist/prompts/default.js +1 -1
  91. package/dist/stores/file/checkpoint-store.d.ts +3 -5
  92. package/dist/stores/file/checkpoint-store.js +31 -2
  93. package/dist/stores/file/index.js +1 -1
  94. package/dist/stores/file/session-store.d.ts +3 -1
  95. package/dist/stores/file/session-store.js +2 -2
  96. package/dist/stores/file/shared-ledger.js +8 -1
  97. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -0
  98. package/dist/tools/fs/bash-readonly-classifier.js +94 -0
  99. package/dist/tools/fs/fs-bash.js +31 -12
  100. package/dist/tools/fs/safety.js +34 -10
  101. package/package.json +1 -1
@@ -0,0 +1,36 @@
1
+ export type RetentionDeclaration = "managed" | "none";
2
+ export interface RetentionDeclaring {
3
+ readonly retention?: RetentionDeclaration;
4
+ }
5
+ export interface RetentionPolicy {
6
+ maxAgeDays: number;
7
+ }
8
+ export interface ManagedRetentionCapability {
9
+ listRetentionDomains(): Promise<readonly string[]>;
10
+ expireCheckpoints(input: {
11
+ domain: string;
12
+ cutoffMs: number;
13
+ }): Promise<RetentionReceipt>;
14
+ deleteExpiredSessions(input: {
15
+ domain: string;
16
+ cutoffMs: number;
17
+ }): Promise<RetentionReceipt>;
18
+ deleteOrphanToolResults(input: {
19
+ domain: string;
20
+ cutoffMs: number;
21
+ }): Promise<RetentionReceipt>;
22
+ }
23
+ export interface RetentionReceipt {
24
+ domain: string;
25
+ deleted: number;
26
+ skipped: number;
27
+ tombstones: number;
28
+ }
29
+ export declare function assertRetentionCapability(input: {
30
+ policy: RetentionPolicy | undefined;
31
+ locked: boolean;
32
+ stores: ReadonlyArray<{
33
+ name: string;
34
+ store: object | undefined;
35
+ }>;
36
+ }): void;
@@ -0,0 +1,31 @@
1
+ function codedError(code, message) {
2
+ const e = new Error(message);
3
+ e.code = code;
4
+ return e;
5
+ }
6
+ export function assertRetentionCapability(input) {
7
+ const { policy, locked, stores } = input;
8
+ if (policy !== undefined && (!Number.isFinite(policy.maxAgeDays) || policy.maxAgeDays < 0)) {
9
+ throw codedError("config.retention_policy", `retentionPolicy.maxAgeDays must be a finite non-negative number of days (got ${String(policy.maxAgeDays)}).`);
10
+ }
11
+ const declaredRetention = (name, store) => {
12
+ const r = store.retention;
13
+ if (r === undefined || r === "none")
14
+ return "none";
15
+ if (r === "managed")
16
+ return "managed";
17
+ throw codedError("config.retention_capability", `store "${name}" declares an unparseable retention value ${JSON.stringify(r)} — expected "managed" or "none".`);
18
+ };
19
+ const declarations = stores
20
+ .filter((s) => s.store !== undefined)
21
+ .map(({ name, store }) => ({ name, retention: declaredRetention(name, store) }));
22
+ if (!locked || policy === undefined)
23
+ return;
24
+ const incapable = declarations.filter(({ retention }) => retention !== "managed");
25
+ if (incapable.length > 0) {
26
+ throw codedError("config.retention_capability", `retention policy is LOCKED but ${incapable.map((s) => s.name).join(", ")} ` +
27
+ `declare${incapable.length === 1 ? "s" : ""} retention "none" (or no declaration — read fail-closed as "none"): ` +
28
+ `a locked retention policy over stores that cannot delete would be "policy locked, data immortal". ` +
29
+ `Wire managed-retention stores, or unlock/remove the retention policy.`);
30
+ }
31
+ }
@@ -58,6 +58,7 @@ export interface ResultFlags {
58
58
  model?: string;
59
59
  unpricedSpend?: boolean;
60
60
  rewindNotes?: TaskResult["rewindNotes"];
61
+ strandedHumanAnswers?: TaskResult["strandedHumanAnswers"];
61
62
  remoteEnvFailures?: TaskResult["remoteEnvFailures"];
62
63
  retryAfterMs?: number;
63
64
  abortedForTimeout: boolean;
@@ -154,10 +154,10 @@ export function assembleResult(spec, sessionId, final, stats, flags) {
154
154
  if (errorCode !== undefined && SALVAGE_ELIGIBLE_TERMINALS.has(errorCode)) {
155
155
  salvagedOutput = text.trim() || undefined;
156
156
  }
157
- const retryAfterMs = errorCode === "usage.window_exhausted" ? flags.retryAfterMs : undefined;
157
+ const retryAfterMs = errorCode === "usage.window_exhausted" || errorCode === "memory.admission_required" ? flags.retryAfterMs : undefined;
158
158
  const { compactionMicroUsd: _internalCompaction, ...publicStats } = stats;
159
159
  void _internalCompaction;
160
160
  if (flags.unpricedSpend)
161
161
  delete publicStats.costMicroUsd;
162
- return { taskId, sessionId, status, ...(flags.model !== undefined ? { model: flags.model } : {}), result: result.trim(), salvagedOutput, blockedReason, errorMessage, errorCode, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), checkpointToken, checkpointGate, ...(workspaceRestoreMode !== undefined ? { workspaceRestoreMode } : {}), ...(flags.rewindNotes !== undefined && flags.rewindNotes.length > 0 ? { rewindNotes: flags.rewindNotes } : {}), ...(flags.remoteEnvFailures !== undefined && flags.remoteEnvFailures.length > 0 ? { remoteEnvFailures: flags.remoteEnvFailures } : {}), stats: publicStats };
162
+ return { taskId, sessionId, status, ...(flags.model !== undefined ? { model: flags.model } : {}), result: result.trim(), salvagedOutput, blockedReason, errorMessage, errorCode, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), checkpointToken, checkpointGate, ...(workspaceRestoreMode !== undefined ? { workspaceRestoreMode } : {}), ...(flags.rewindNotes !== undefined && flags.rewindNotes.length > 0 ? { rewindNotes: flags.rewindNotes } : {}), ...(flags.remoteEnvFailures !== undefined && flags.remoteEnvFailures.length > 0 ? { remoteEnvFailures: flags.remoteEnvFailures } : {}), ...(flags.strandedHumanAnswers !== undefined && flags.strandedHumanAnswers.length > 0 ? { strandedHumanAnswers: flags.strandedHumanAnswers } : {}), stats: publicStats };
163
163
  }
@@ -8,6 +8,13 @@ export interface PrepareMemoryInput {
8
8
  memoryWriteGateRef: {
9
9
  current?: BeforeWriteHook;
10
10
  };
11
+ admissionCtx: {
12
+ orgMemoryDenied: boolean;
13
+ complianceDegraded: boolean;
14
+ parentAdmittedOrgScopes: readonly string[] | undefined;
15
+ priorOwnVerdict: import("../memory-admission.js").OwnOrgAdmissionVerdict | undefined;
16
+ governedProvenance: boolean;
17
+ };
11
18
  }
12
19
  export interface PrepareMemoryResult {
13
20
  memoryEngineSession: Prepared["memoryEngineSession"];
@@ -16,5 +23,7 @@ export interface PrepareMemoryResult {
16
23
  path: string;
17
24
  content: string;
18
25
  }>;
26
+ admittedOrgScopes: readonly string[];
27
+ ownOrgVerdict: import("../memory-admission.js").OwnOrgAdmissionVerdict | undefined;
19
28
  }
20
29
  export declare function prepareMemory(input: PrepareMemoryInput): Promise<PrepareMemoryResult>;
@@ -1,3 +1,4 @@
1
+ import { admitMemoryScopes } from "../memory-admission.js";
1
2
  import { adoptLegacyRepoDirs, deriveRepoControlPlaneDir, deriveProjectControlDir, deriveProjectMemoryDir, deriveRepoMemoryDir, drainMemoryAnnouncements, enqueueMemoryAnnouncement, lookupProjectIdHint, recordProjectIdHint, resolveMemoryEngineRoot } from "../memory-engine/layout.js";
2
3
  import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir, mergeHarvestReports, mergeInjections, needsDualRoots, parsedProjectPlane } from "../memory-engine/dual-root.js";
3
4
  import { normalizeMemorySpec } from "../memory.js";
@@ -5,8 +6,33 @@ import { MemoryEngine } from "../memory-engine/engine.js";
5
6
  import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
6
7
  import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
7
8
  export async function prepareMemory(input) {
8
- const { spec, deps, sessionId, taskRootPath, memoryWriteGateRef } = input;
9
+ const { spec, deps, sessionId, taskRootPath, memoryWriteGateRef, admissionCtx } = input;
9
10
  const memorySpec = normalizeMemorySpec(spec.memory);
11
+ let admittedOrgScopes = [];
12
+ let ownOrgVerdict;
13
+ if (memorySpec && memorySpec.enabled && deps.memoryBackend) {
14
+ const outcome = await admitMemoryScopes({
15
+ memorySpec,
16
+ principal: spec.principal,
17
+ admission: deps.memoryScopeAdmission,
18
+ deploymentScopes: new Set(deps.deploymentMemoryScopes ?? []),
19
+ orgMemoryDenied: admissionCtx.orgMemoryDenied,
20
+ complianceDegraded: admissionCtx.complianceDegraded,
21
+ parentAdmittedOrgScopes: admissionCtx.parentAdmittedOrgScopes,
22
+ priorOwnVerdict: admissionCtx.priorOwnVerdict,
23
+ governedProvenance: admissionCtx.governedProvenance,
24
+ });
25
+ admittedOrgScopes = outcome.admittedOrgScopes;
26
+ ownOrgVerdict = outcome.ownVerdict;
27
+ for (const droppedScope of outcome.droppedDeploymentScopes) {
28
+ deps.onError?.(new Error(`org memory scope "${droppedScope}" (deployment-declared) was narrowed away (admission resolver or the session's frozen verdict) — the layer is not mounted this session.`), { phase: "memory", sessionId });
29
+ }
30
+ if (outcome.writeScopeNarrowed) {
31
+ deps.onError?.(new Error(`org memory writeScope "${String(memorySpec.writeScope)}" was not explicitly granted by admission — the session's memory write face is read-only (org layers default read-only).`), { phase: "memory", sessionId });
32
+ }
33
+ memorySpec.scopes = outcome.scopes;
34
+ memorySpec.writeScope = outcome.writeScope;
35
+ }
10
36
  const useMemoryEngine = Boolean(memorySpec && memorySpec.enabled && deps.memoryBackend);
11
37
  let memoryEngineSession;
12
38
  if (useMemoryEngine && memorySpec) {
@@ -193,5 +219,5 @@ export async function prepareMemory(input) {
193
219
  if (memoryBlock !== undefined && injection.indexSeed !== undefined)
194
220
  seedFiles = [injection.indexSeed];
195
221
  }
196
- return { memoryEngineSession, memoryBlock, ...(seedFiles !== undefined ? { seedFiles } : {}) };
222
+ return { memoryEngineSession, memoryBlock, admittedOrgScopes, ownOrgVerdict, ...(seedFiles !== undefined ? { seedFiles } : {}) };
197
223
  }
@@ -20,7 +20,8 @@ import type { TaskNotificationPayload } from "../task-notification.js";
20
20
  import { type CwdRef } from "../../tools/fs/index.js";
21
21
  import { type WorkflowSizeGuideline } from "../../orchestration/workflow-size-guideline.js";
22
22
  import type { Runner } from "./runtask.js";
23
- import { type CheckpointGate, type CheckpointState, type CheckpointStore, type CheckpointToken, type ResourceLedger, type PlatformLimitReason, type ResourceLimitReason } from "../checkpoint-store.js";
23
+ import { type CheckpointGate, type CheckpointState, type CheckpointToken, type ResourceLedger, type PlatformLimitReason, type ResourceLimitReason } from "../checkpoint-store.js";
24
+ import { type WiringManifest } from "../wiring-manifest.js";
24
25
  import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
25
26
  import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskLimits, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
26
27
  import type { RepairBundle } from "../../agents/repair-loop.js";
@@ -44,11 +45,7 @@ export declare function checkpointScopeOf(spec: {
44
45
  };
45
46
  principal?: string;
46
47
  }): string;
47
- export declare function resolveCheckpointStore(spec: {
48
- checkpointStore?: CheckpointStore | null;
49
- }, deps: {
50
- checkpointStore?: CheckpointStore;
51
- }): CheckpointStore | undefined;
48
+ export { resolveCheckpointStore } from "../checkpoint-store.js";
52
49
  export interface Prepared {
53
50
  harness: AgentHarness;
54
51
  session: StoredSession;
@@ -81,11 +78,16 @@ export interface Prepared {
81
78
  denyNarrowingPolicy?: ToolPolicy;
82
79
  basePolicyForResumeEdit?: ToolPolicy;
83
80
  releaseSignal: () => void;
81
+ settleContentAskBindings: () => ReadonlyArray<{
82
+ deliveryId: string;
83
+ toolCallId: string;
84
+ }>;
84
85
  cacheBreakDetector?: CacheBreakDetector;
85
86
  cacheFingerprint?: {
86
87
  systemPrompt: string;
87
88
  tools: ToolFingerprintInput[];
88
89
  };
90
+ wiringManifest: WiringManifest;
89
91
  promptManifest: {
90
92
  constitution: "core" | "replaced" | "provider-assembled";
91
93
  blocks: Array<{
@@ -294,6 +296,8 @@ export interface PrepareResume {
294
296
  }>;
295
297
  };
296
298
  workspaceHandle?: import("../remote-env.js").WorkspaceHandle;
299
+ redeemedContentAskCallId?: string;
300
+ redeemedContentAskQuestionsHash?: string;
297
301
  executesApprovedAction?: boolean;
298
302
  }
299
303
  export interface InheritedGate {
@@ -304,6 +308,8 @@ export interface InheritedGate {
304
308
  rules: SessionPermissionRules;
305
309
  }>;
306
310
  shellGate?: "off" | "always" | "classify";
311
+ admittedOrgScopes?: readonly string[];
312
+ orgAdmissionGoverned?: true;
307
313
  parentConstraints?: ReadonlyArray<{
308
314
  policy: ToolPolicy;
309
315
  onAsk?: OnAsk;
@@ -323,8 +329,13 @@ export declare function resolveModelPromptTraits(model: {
323
329
  };
324
330
  export interface RunInternals {
325
331
  repairBundle?: RepairBundle;
332
+ questionFaceStripped?: true;
333
+ parentInteractionPosture?: "interactive" | "headless";
326
334
  afterCheckpointResolve?: () => Promise<void>;
327
335
  inheritedGate?: InheritedGate;
336
+ ownOrgAdmissionRef?: {
337
+ current: import("../memory-admission.js").OwnOrgAdmissionVerdict | undefined;
338
+ };
328
339
  workflowDepth?: number;
329
340
  insideFork?: boolean;
330
341
  isDelegatedChild?: boolean;
@@ -336,6 +347,7 @@ export interface RunInternals {
336
347
  explicitAgentName?: string;
337
348
  parentTaskId?: string;
338
349
  parentSessionId?: string;
350
+ delegationTaskType?: import("../types.js").DelegationTaskType;
339
351
  rootSessionId?: string;
340
352
  registryScope?: string;
341
353
  parentCenterArtifactDigest?: string;