@sema-agent/core 7.54.1 → 7.55.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/CHANGELOG.md +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.js +2 -1
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +43 -9
- package/dist/agents/peer-directory.js +66 -23
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +8 -1
- package/dist/core/parent-spec-seat.js +4 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +28 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +2 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +3 -1
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -101,8 +101,12 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
101
101
|
private readonly retainBackgroundProcesses;
|
|
102
102
|
private readonly onSecretEnvScrub?;
|
|
103
103
|
private readonly onNotice?;
|
|
104
|
-
/** design/128 T1-1:
|
|
104
|
+
/** design/128 T1-1: the env-owned spool dir (mkdtemp under os tmp — unpredictable, never the cwd). It exists only while
|
|
105
|
+
* {@link spoolPairs} is non-empty: the last pair's release removes it, the next mint makes a fresh one. */
|
|
105
106
|
private bgSpoolDir?;
|
|
107
|
+
/** The `outPath` of every spool pair this env minted and has not released — the one fact the dir's lifetime reads. A
|
|
108
|
+
* retain-lane bg pair is never released (its files outlive the run by design), so it keeps the dir. */
|
|
109
|
+
private readonly spoolPairs;
|
|
106
110
|
readonly backgroundCapabilities: BackgroundShellCapability["backgroundCapabilities"];
|
|
107
111
|
constructor(options: {
|
|
108
112
|
cwd: string;
|
|
@@ -127,7 +131,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
127
131
|
* env lane; `TaskSpec.retainBackgroundProcesses` is the task lane, without this spooling guarantee on
|
|
128
132
|
* every platform — docs/background-process-lifetime.md). The 2h bg-timeout reaper and `killBackground` still work
|
|
129
133
|
* while the host lives; after host exit, cleanup is the deployment's responsibility (e.g. the TB
|
|
130
|
-
* container teardown)
|
|
134
|
+
* container teardown) — the retained shells' spool files, and the dir holding them, are never released
|
|
135
|
+
* by the env (every other spool pair is, and the dir goes with the last one). v1 covers processes spawned via `execBackground` only (a detach-adopted
|
|
131
136
|
* foreground exec keeps pipe stdio — best-effort survival). Incompatible with durable-suspend
|
|
132
137
|
* deployments (their pre-suspend dispose becomes a no-op too — do not combine).
|
|
133
138
|
*/
|
|
@@ -157,8 +162,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
157
162
|
abortSignal?: AbortSignal;
|
|
158
163
|
}): Promise<Result<string[], FileError>>;
|
|
159
164
|
readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>>;
|
|
160
|
-
/** RB-221: whole-file replace via same-directory staging + fsync + rename
|
|
161
|
-
*
|
|
165
|
+
/** RB-221: whole-file replace via same-directory staging + fsync + rename.
|
|
166
|
+
* The former single-step `writeFile` was an in-place O_TRUNC: an abort mid-write
|
|
162
167
|
* (Esc during a large Write — ctx.signal reaches here directly), ENOSPC, or a crash left the target as
|
|
163
168
|
* a torn prefix of the NEW content with the original unrecoverable. Post-fix contract: the target is
|
|
164
169
|
* either fully old or fully new; `aborted` means it was never touched. Known semantic change (same as
|
|
@@ -251,10 +256,19 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
251
256
|
* the file), while poll slicing keeps using the logical stream totalBytes; the two advance in
|
|
252
257
|
* lockstep here but are NOT interchangeable after a rotation. */
|
|
253
258
|
private syncSpool;
|
|
259
|
+
/** The one seat that opens a spool pair (foreground exec and background spawn alike), inside the env's spool dir: made on
|
|
260
|
+
* the first mint after the dir was last removed, so a command never runs against a dir an idle reap or a temp cleaner took. */
|
|
261
|
+
private mintSpoolPair;
|
|
262
|
+
/** The one seat that gives a spool pair back: unlinks both files (a descendant still writing keeps its fd into the unlinked
|
|
263
|
+
* inode — no EPIPE), forgets the pair, and removes the dir once no pair is left in it. Idempotent. */
|
|
264
|
+
private releaseSpoolPair;
|
|
265
|
+
/** Removes the spool dir (and whatever a failed unlink stranded in it) when no pair of this env lives in it. A retain-lane
|
|
266
|
+
* bg pair is never released, so it keeps its dir; the rest is gone with its last pair. Best-effort, never throws. */
|
|
267
|
+
private reapSpoolDirIfIdle;
|
|
254
268
|
/** +: reclaim an EPHEMERAL spool (detach-adopted, or any non-retain bg
|
|
255
269
|
* spawn — the whole unix bg lane is spool-backed now) — fold the final residue into the tails,
|
|
256
270
|
* unlink both files, and drop the spool reference (later syncs become no-ops). Idempotent;
|
|
257
|
-
* never touches design/128 retain-lane
|
|
271
|
+
* never touches the spool of a design/128 retain-lane shell that has a process (no `ephemeral` flag). A still-writing detached
|
|
258
272
|
* descendant keeps its fd into the unlinked inode (RB-26 posture — no EPIPE, auto-reclaim at
|
|
259
273
|
* its exit). */
|
|
260
274
|
private reclaimEphemeralSpool;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, statSync, truncateSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, rmSync, statSync, truncateSync, unlinkSync } from "node:fs";
|
|
4
4
|
import { access, appendFile, lstat, mkdir, mkdtemp, open, readdir, readFile, readlink, rename, rm, stat, unlink, writeFile, } from "node:fs/promises";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { isAbsolute, join, resolve } from "node:path";
|
|
@@ -336,6 +336,7 @@ export class NodeExecutionEnv {
|
|
|
336
336
|
onSecretEnvScrub;
|
|
337
337
|
onNotice;
|
|
338
338
|
bgSpoolDir;
|
|
339
|
+
spoolPairs = new Set();
|
|
339
340
|
backgroundCapabilities;
|
|
340
341
|
constructor(options) {
|
|
341
342
|
this.cwd = options.cwd;
|
|
@@ -465,13 +466,7 @@ export class NodeExecutionEnv {
|
|
|
465
466
|
if (spoolPumpRef.current)
|
|
466
467
|
clearInterval(spoolPumpRef.current);
|
|
467
468
|
if (execSpoolRef.current && !(result.ok && result.value.detached !== undefined)) {
|
|
468
|
-
|
|
469
|
-
try {
|
|
470
|
-
unlinkSync(path);
|
|
471
|
-
}
|
|
472
|
-
catch {
|
|
473
|
-
}
|
|
474
|
-
}
|
|
469
|
+
this.releaseSpoolPair(execSpoolRef.current);
|
|
475
470
|
execSpoolRef.current = undefined;
|
|
476
471
|
}
|
|
477
472
|
resolvePromise(result);
|
|
@@ -479,9 +474,7 @@ export class NodeExecutionEnv {
|
|
|
479
474
|
let execSpoolFds;
|
|
480
475
|
if (process.platform !== "win32") {
|
|
481
476
|
try {
|
|
482
|
-
|
|
483
|
-
this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
484
|
-
const pair = openSpoolPair(join(this.bgSpoolDir, `fg_${randomUUID()}`));
|
|
477
|
+
const pair = this.mintSpoolPair(`fg_${randomUUID()}`);
|
|
485
478
|
execSpoolRef.current = { outPath: pair.outPath, errPath: pair.errPath };
|
|
486
479
|
execSpoolFds = pair.fds;
|
|
487
480
|
}
|
|
@@ -1309,9 +1302,7 @@ export class NodeExecutionEnv {
|
|
|
1309
1302
|
let spoolFds;
|
|
1310
1303
|
if (this.retainBackgroundProcesses || process.platform !== "win32") {
|
|
1311
1304
|
try {
|
|
1312
|
-
|
|
1313
|
-
this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
1314
|
-
const pair = openSpoolPair(join(this.bgSpoolDir, `bg_${this.bgCounter + 1}_${randomUUID()}`));
|
|
1305
|
+
const pair = this.mintSpoolPair(`bg_${this.bgCounter + 1}_${randomUUID()}`);
|
|
1315
1306
|
spool = {
|
|
1316
1307
|
outPath: pair.outPath,
|
|
1317
1308
|
errPath: pair.errPath,
|
|
@@ -1345,6 +1336,8 @@ export class NodeExecutionEnv {
|
|
|
1345
1336
|
}
|
|
1346
1337
|
}
|
|
1347
1338
|
}
|
|
1339
|
+
if (spool)
|
|
1340
|
+
this.releaseSpoolPair(spool);
|
|
1348
1341
|
const cause = toError(error);
|
|
1349
1342
|
return err(new BackgroundShellError("spawn_failed", cause.message, cause));
|
|
1350
1343
|
}
|
|
@@ -1533,23 +1526,51 @@ export class NodeExecutionEnv {
|
|
|
1533
1526
|
}
|
|
1534
1527
|
}
|
|
1535
1528
|
}
|
|
1529
|
+
mintSpoolPair(name) {
|
|
1530
|
+
this.bgSpoolDir ??= mkdtempSync(join(tmpdir(), "sema-bg-"));
|
|
1531
|
+
try {
|
|
1532
|
+
const pair = openSpoolPair(join(this.bgSpoolDir, name));
|
|
1533
|
+
this.spoolPairs.add(pair.outPath);
|
|
1534
|
+
return pair;
|
|
1535
|
+
}
|
|
1536
|
+
catch (error) {
|
|
1537
|
+
this.reapSpoolDirIfIdle();
|
|
1538
|
+
throw error;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
releaseSpoolPair(pair) {
|
|
1542
|
+
for (const path of [pair.outPath, pair.errPath]) {
|
|
1543
|
+
try {
|
|
1544
|
+
unlinkSync(path);
|
|
1545
|
+
}
|
|
1546
|
+
catch {
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
this.spoolPairs.delete(pair.outPath);
|
|
1550
|
+
this.reapSpoolDirIfIdle();
|
|
1551
|
+
}
|
|
1552
|
+
reapSpoolDirIfIdle() {
|
|
1553
|
+
const dir = this.bgSpoolDir;
|
|
1554
|
+
if (dir === undefined || this.spoolPairs.size > 0)
|
|
1555
|
+
return;
|
|
1556
|
+
this.bgSpoolDir = undefined;
|
|
1557
|
+
try {
|
|
1558
|
+
rmSync(dir, { recursive: true, force: true });
|
|
1559
|
+
}
|
|
1560
|
+
catch {
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1536
1563
|
reclaimEphemeralSpool(entry) {
|
|
1537
1564
|
if (entry.spoolPump !== undefined) {
|
|
1538
1565
|
clearInterval(entry.spoolPump);
|
|
1539
1566
|
entry.spoolPump = undefined;
|
|
1540
1567
|
}
|
|
1541
1568
|
const spool = entry.spool;
|
|
1542
|
-
if (!spool
|
|
1569
|
+
if (!spool || (!spool.ephemeral && entry.child.pid !== undefined))
|
|
1543
1570
|
return;
|
|
1544
1571
|
this.syncSpool(entry);
|
|
1545
1572
|
entry.spool = undefined;
|
|
1546
|
-
|
|
1547
|
-
try {
|
|
1548
|
-
unlinkSync(path);
|
|
1549
|
-
}
|
|
1550
|
-
catch {
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1573
|
+
this.releaseSpoolPair(spool);
|
|
1553
1574
|
}
|
|
1554
1575
|
async disposeBackgroundShells(opts) {
|
|
1555
1576
|
if (this.retainBackgroundProcesses)
|
|
@@ -347,6 +347,12 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
347
347
|
private createTurnState;
|
|
348
348
|
private createContext;
|
|
349
349
|
private createStreamFn;
|
|
350
|
+
/** May a drain take this frame now? The one predicate of the drain, the immediate re-check and {@link pendingInjectionCount}.
|
|
351
|
+
* A person's or caller's frame always may. An engine-authored frame is held — a drained steer makes a request — under
|
|
352
|
+
* the human-halt hold ({@link engineInjectionsHeld}), and an ADVISORY is held where the loop's own work owes no request
|
|
353
|
+
* (`continuing` false): it rides a request, never makes one; a notification's payload is an event and may continue a
|
|
354
|
+
* run. Held frames stay queued: later input drains past them, an owed drain takes them, else they end with the run. */
|
|
355
|
+
private isDrainable;
|
|
350
356
|
private drainQueuedMessages;
|
|
351
357
|
/** #389 — drop these frames from the in-flight account (they went back on a queue, or they landed). */
|
|
352
358
|
private unbookInFlight;
|
|
@@ -371,7 +377,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
371
377
|
private validateToolNames;
|
|
372
378
|
private flushPendingSessionWrites;
|
|
373
379
|
/**
|
|
374
|
-
* #506 ㋐ — write the transcript's record of a TERMINAL provider failure
|
|
380
|
+
* #506 ㋐ — write the transcript's record of a TERMINAL provider failure.
|
|
375
381
|
*
|
|
376
382
|
* A SEPARATE object, never the live frame: `failure` is the engine's terminal error shell and every
|
|
377
383
|
* other consumer of it (the run result, failover, telemetry, usage accounting) reads its real
|
|
@@ -466,7 +472,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
466
472
|
* no frame whose consumption could make the cut self-defeating, so the seat's own liveness is
|
|
467
473
|
* the only guard. The cut settles exactly as every S1 cut does: finished tool calls keep
|
|
468
474
|
* their REAL results, never-started ones settle as paired interrupted results, the
|
|
469
|
-
*
|
|
475
|
+
* the interruption marker lands.
|
|
470
476
|
*
|
|
471
477
|
* Returns `{ turnCut, accepted }` — `turnCut` `true` iff THIS call aborted a live turn seat (an
|
|
472
478
|
* in-flight provider stream / tool batch will settle as interrupted; the completion-race arm is
|
|
@@ -489,7 +495,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
489
495
|
* consults the latch at its own boundary, so the stop is provably in place when the forced
|
|
490
496
|
* boundary arrives (the enqueue-then-abort discipline, one lane over).
|
|
491
497
|
*
|
|
492
|
-
* Queued injection frames are deliberately NOT touched (
|
|
498
|
+
* Queued injection frames are deliberately NOT touched (the reference's `control_request:"interrupt"`
|
|
493
499
|
* keeps the queue and answers `still_queued` — see {@link abort}'s recorded ruling): whatever
|
|
494
500
|
* the queues hold settles by the run's ordinary terminal contract for accepted-but-undelivered
|
|
495
501
|
* input (durable park when a suspend seat exists, else the loud undrained accounts).
|
|
@@ -516,10 +522,10 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
516
522
|
private noteTurnCutConsumed;
|
|
517
523
|
/**
|
|
518
524
|
* design/373 §3.3 (the final-commit-point double check) — how many queued injection frames a
|
|
519
|
-
* boundary drain could deliver RIGHT NOW
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
525
|
+
* boundary drain could deliver RIGHT NOW where the loop's own work owes none ({@link isDrainable}, `continuing` false):
|
|
526
|
+
* what could continue the run (an unwinding run drains nothing — its frames belong to the terminal account).
|
|
527
|
+
* Synchronous and side-effect-free by contract: the loop reads it between its last drain and the terminal
|
|
528
|
+
* commit, with zero awaits.
|
|
523
529
|
*/
|
|
524
530
|
pendingInjectionCount(): number;
|
|
525
531
|
/** design/373 §3.4-3 — the pre-request re-check's drain half (see the loop-config seam): sweep
|
|
@@ -607,7 +613,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
607
613
|
followUp: number;
|
|
608
614
|
};
|
|
609
615
|
/**
|
|
610
|
-
* backlog #389 (
|
|
616
|
+
* backlog #389 (`control_request:"interrupt"`) — an interrupt does
|
|
611
617
|
* NOT destroy accepted user input. CC's default keeps the queue and answers `still_queued`; only an
|
|
612
618
|
* explicit `cancel_queued` cancels, with a per-uuid `cancelled` receipt. This harness had the opposite
|
|
613
619
|
* polarity: both queues were emptied unconditionally and the contents handed back on a result object
|
|
@@ -43,6 +43,9 @@ function createTrailingMessage(seed) {
|
|
|
43
43
|
}
|
|
44
44
|
const engineNotePayloads = new WeakMap();
|
|
45
45
|
const engineAuthoredInjections = new WeakSet();
|
|
46
|
+
function isEngineAdvisory(m) {
|
|
47
|
+
return engineAuthoredInjections.has(m) && !engineNotePayloads.has(m);
|
|
48
|
+
}
|
|
46
49
|
const userInputParkRecords = new WeakMap();
|
|
47
50
|
const drainedFromLane = new WeakMap();
|
|
48
51
|
const immediateClassInjections = new WeakSet();
|
|
@@ -548,28 +551,34 @@ export class AgentHarness {
|
|
|
548
551
|
});
|
|
549
552
|
};
|
|
550
553
|
}
|
|
551
|
-
|
|
552
|
-
|
|
554
|
+
isDrainable(m, continuing) {
|
|
555
|
+
if (!engineAuthoredInjections.has(m))
|
|
556
|
+
return true;
|
|
557
|
+
if (this.engineInjectionsHeld?.() === true)
|
|
558
|
+
return false;
|
|
559
|
+
return continuing || !isEngineAdvisory(m);
|
|
560
|
+
}
|
|
561
|
+
async drainQueuedMessages(queue, mode, continuing) {
|
|
553
562
|
if (this.aborting)
|
|
554
563
|
return [];
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
564
|
+
const messages = [];
|
|
565
|
+
let first;
|
|
566
|
+
let selecting = true;
|
|
567
|
+
for (let i = 0; i < queue.length; i++) {
|
|
568
|
+
const m = queue[i];
|
|
569
|
+
if (!this.isDrainable(m, continuing))
|
|
570
|
+
continue;
|
|
571
|
+
if (!isEngineAdvisory(m)) {
|
|
572
|
+
if (!selecting)
|
|
560
573
|
continue;
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
let count = mode === "all" ? queue.length : 1;
|
|
567
|
-
if (mode !== "all" && queue.length > 1 && engineNotePayloads.has(queue[0])) {
|
|
568
|
-
count = 1;
|
|
569
|
-
while (count < queue.length && engineNotePayloads.has(queue[count]))
|
|
570
|
-
count++;
|
|
574
|
+
if (mode !== "all" && first !== undefined && !(engineNotePayloads.has(first) && engineNotePayloads.has(m))) {
|
|
575
|
+
selecting = false;
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
first ??= m;
|
|
571
579
|
}
|
|
572
|
-
messages
|
|
580
|
+
messages.push(...queue.splice(i, 1));
|
|
581
|
+
i--;
|
|
573
582
|
}
|
|
574
583
|
if (messages.length === 0) {
|
|
575
584
|
return messages;
|
|
@@ -682,9 +691,9 @@ export class AgentHarness {
|
|
|
682
691
|
return result;
|
|
683
692
|
},
|
|
684
693
|
afterToolCall: ({ toolCall, args, result, isError }) => this.afterToolCallHook(toolCall, args, result, isError),
|
|
685
|
-
prepareNextTurn: async () => {
|
|
694
|
+
prepareNextTurn: async ({ continues }) => {
|
|
686
695
|
await this.flushPendingSessionWrites();
|
|
687
|
-
await this.emitHook({ type: "turn_boundary", model: this.model });
|
|
696
|
+
await this.emitHook({ type: "turn_boundary", model: this.model, continues });
|
|
688
697
|
const nextTurnState = await this.createTurnState();
|
|
689
698
|
setTurnState(nextTurnState);
|
|
690
699
|
return {
|
|
@@ -693,7 +702,7 @@ export class AgentHarness {
|
|
|
693
702
|
thinkingLevel: nextTurnState.thinkingLevel,
|
|
694
703
|
};
|
|
695
704
|
},
|
|
696
|
-
getSteeringMessages: async () => this.drainQueuedMessages(this.steerQueue, this.steeringQueueMode),
|
|
705
|
+
getSteeringMessages: async (continuing) => this.drainQueuedMessages(this.steerQueue, this.steeringQueueMode, continuing),
|
|
697
706
|
publishTurnInterruptSeat: (seat) => {
|
|
698
707
|
if (seat !== undefined) {
|
|
699
708
|
this.lastPublishedSeat = seat;
|
|
@@ -705,7 +714,7 @@ export class AgentHarness {
|
|
|
705
714
|
recheckImmediateInjections: async (pending) => this.absorbImmediateSteering(pending),
|
|
706
715
|
pendingInjectionCount: () => this.pendingInjectionCount(),
|
|
707
716
|
getFollowUpMessages: async () => {
|
|
708
|
-
const queued = await this.drainQueuedMessages(this.followUpQueue, this.followUpQueueMode);
|
|
717
|
+
const queued = await this.drainQueuedMessages(this.followUpQueue, this.followUpQueueMode, false);
|
|
709
718
|
if (queued.length > 0)
|
|
710
719
|
return queued;
|
|
711
720
|
return this.stopGate ? await this.stopGate() : queued;
|
|
@@ -1160,20 +1169,18 @@ export class AgentHarness {
|
|
|
1160
1169
|
pendingInjectionCount() {
|
|
1161
1170
|
if (this.aborting)
|
|
1162
1171
|
return 0;
|
|
1163
|
-
const
|
|
1164
|
-
const drainable = (q) => held ? q.filter((m) => !engineAuthoredInjections.has(m)).length : q.length;
|
|
1172
|
+
const drainable = (q) => q.filter((m) => this.isDrainable(m, false)).length;
|
|
1165
1173
|
return drainable(this.steerQueue) + drainable(this.followUpQueue);
|
|
1166
1174
|
}
|
|
1167
1175
|
async absorbImmediateSteering(pending) {
|
|
1168
1176
|
if (this.aborting)
|
|
1169
1177
|
return pending;
|
|
1170
|
-
const held = this.engineInjectionsHeld?.() === true;
|
|
1171
1178
|
const taken = [];
|
|
1172
1179
|
for (let i = 0; i < this.steerQueue.length; i++) {
|
|
1173
1180
|
const m = this.steerQueue[i];
|
|
1174
1181
|
if (!immediateClassInjections.has(m))
|
|
1175
1182
|
break;
|
|
1176
|
-
if (
|
|
1183
|
+
if (!this.isDrainable(m, true))
|
|
1177
1184
|
continue;
|
|
1178
1185
|
taken.push(...this.steerQueue.splice(i, 1));
|
|
1179
1186
|
i--;
|
|
@@ -194,7 +194,7 @@ export declare class ExecutionError extends Error {
|
|
|
194
194
|
* TB triple-fake-green report (2026-07-13) — output produced BEFORE the failure, for the
|
|
195
195
|
* ran-then-cut codes (`timeout` / `liveness_no_output` / `aborted` / `callback_error`; the last is a command that
|
|
196
196
|
* started and was then killed because a host-side output callback failed — its completion was
|
|
197
|
-
* never observed, but its captured output is real work).
|
|
197
|
+
* never observed, but its captured output is real work). Reference behavior (BashTask settle): a
|
|
198
198
|
* timed-out command keeps ALL captured stdout/stderr and only APPENDS a "Command timed out after
|
|
199
199
|
* X" line — discarding 600s of build logs forces the model to rerun blind. Optional: envs that
|
|
200
200
|
* cannot capture partial output simply omit these; never-started codes
|
|
@@ -325,7 +325,7 @@ export interface ExecutionEnvExecOptions {
|
|
|
325
325
|
*/
|
|
326
326
|
detachSignal?: AbortSignal;
|
|
327
327
|
/**
|
|
328
|
-
* RB-198 F1 (form-one audit
|
|
328
|
+
* RB-198 F1 (form-one audit) — when this command's OWN timeout
|
|
329
329
|
* fires, an env that supports detach ADOPTS the running child as a background process (the same
|
|
330
330
|
* mechanism `detachSignal` uses) instead of killing it, settling the exec with
|
|
331
331
|
* `detached: {shellId, cause:"timeout"}` — a non-idempotent long command survives its own timeout
|
|
@@ -665,6 +665,14 @@ export interface AnnouncedListingSnapshot {
|
|
|
665
665
|
models?: string[];
|
|
666
666
|
mcpFailed?: AnnouncedMcpFailure[];
|
|
667
667
|
advisories?: string[];
|
|
668
|
+
advisor?: AnnouncedAdvisorState;
|
|
669
|
+
}
|
|
670
|
+
/** What the model was told about the advisor tool, and in which SEGMENT of the conversation — the id of the branch's
|
|
671
|
+
* latest compaction entry when the telling was delivered, `null` before any. A record from another segment reads as
|
|
672
|
+
* nothing told: a compaction summarized the telling away. */
|
|
673
|
+
export interface AnnouncedAdvisorState {
|
|
674
|
+
state: "announced" | "withdrawn";
|
|
675
|
+
segment: string | null;
|
|
668
676
|
}
|
|
669
677
|
/** The same snapshot as an APPEND input (borrowed arrays; the store copies through the shape gate). */
|
|
670
678
|
export interface AnnouncedListingSnapshotInput {
|
|
@@ -673,6 +681,7 @@ export interface AnnouncedListingSnapshotInput {
|
|
|
673
681
|
models?: readonly string[];
|
|
674
682
|
mcpFailed?: ReadonlyArray<AnnouncedMcpFailure>;
|
|
675
683
|
advisories?: readonly string[];
|
|
684
|
+
advisor?: Readonly<AnnouncedAdvisorState>;
|
|
676
685
|
}
|
|
677
686
|
/**
|
|
678
687
|
* REF-D3/D4 merge target: the active EnterWorktree session (M22 live-CC anchor —
|
|
@@ -841,8 +850,8 @@ export declare function isValidModelChange(e: {
|
|
|
841
850
|
modelId?: unknown;
|
|
842
851
|
}): boolean;
|
|
843
852
|
/**
|
|
844
|
-
* #506 ㋐ — the reserved `model` value on a transcript entry NO MODEL PRODUCED.
|
|
845
|
-
* (`"<synthetic>"`,
|
|
853
|
+
* #506 ㋐ — the reserved `model` value on a transcript entry NO MODEL PRODUCED. Spelled as in the reference
|
|
854
|
+
* (`"<synthetic>"`, its own single-occurrence constant), and single-occurrence here for the
|
|
846
855
|
* same reason: the mint site and the recognition predicate must read the same literal or the entry
|
|
847
856
|
* becomes unrecognizable the first time one of them is retyped.
|
|
848
857
|
*
|
|
@@ -904,6 +913,14 @@ export interface SessionMetadata {
|
|
|
904
913
|
incarnation?: string;
|
|
905
914
|
/** Fork lineage's OCCUPANT half: the source row's `incarnation` at fork time (the occupant copied, not whoever holds `forkedFrom` later); absent = unknown. */
|
|
906
915
|
forkedFromIncarnation?: string;
|
|
916
|
+
/** WHO owns this row, recorded by the write that creates it and changed by no later write; `null` = anonymous; absent reads as `null`. */
|
|
917
|
+
owner?: string | null;
|
|
918
|
+
}
|
|
919
|
+
/** One row's owner, occupant (`undefined` = unknown) and active leaf (`null` = none), read in ONE read so the three answer for one row generation. */
|
|
920
|
+
export interface SessionHead {
|
|
921
|
+
readonly owner: string | null;
|
|
922
|
+
readonly incarnation: string | undefined;
|
|
923
|
+
readonly leafId: string | null;
|
|
907
924
|
}
|
|
908
925
|
export interface JsonlSessionMetadata extends SessionMetadata {
|
|
909
926
|
cwd: string;
|
|
@@ -1050,6 +1067,8 @@ export interface SessionCreateOptions {
|
|
|
1050
1067
|
placement?: Omit<SessionPlacementRecord, "placedAt"> & {
|
|
1051
1068
|
placedAt?: number;
|
|
1052
1069
|
};
|
|
1070
|
+
/** The owner the creating write records (absent ⇒ `null`; on a fork, absent or `null` ⇒ the copied source row's); a create over an existing id records nothing. */
|
|
1071
|
+
owner?: string | null;
|
|
1053
1072
|
}
|
|
1054
1073
|
export interface SessionForkOptions {
|
|
1055
1074
|
entryId?: string;
|
|
@@ -1070,10 +1089,11 @@ export interface SessionRepo<TMetadata extends SessionMetadata = SessionMetadata
|
|
|
1070
1089
|
* Optional — a backend that supports cross-backend session export/migration implements it.
|
|
1071
1090
|
*/
|
|
1072
1091
|
exportEntries?(sessionId: string): Promise<SessionTreeEntry[]>;
|
|
1092
|
+
/** The row's {@link SessionHead} in one read (`undefined` = no row); `TtlSessionStore` has a head read and an ownership pair only over a repo that has this. */
|
|
1093
|
+
headOf?(sessionId: string): Promise<SessionHead | undefined>;
|
|
1073
1094
|
/**
|
|
1074
|
-
* 2c session-sync: write a verbatim entry log (produced by {@link exportEntries} on another backend) into
|
|
1075
|
-
*
|
|
1076
|
-
* from the bundle). The log MUST be passed through `validateEntriesForImport` first (the single fail-closed
|
|
1095
|
+
* 2c session-sync: write a verbatim entry log (produced by {@link exportEntries} on another backend) into `sessionId` (the log is
|
|
1096
|
+
* replaced, never the row: an existing row keeps its metadata whole; an absent id is a new row recording `owner`, `undefined` ⇒ `null` — the caller's principal, never the bundle's). The log MUST be passed through `validateEntriesForImport` first (the single fail-closed
|
|
1077
1097
|
* invariant gate); a durable backend persists THAT function's output, it does not re-implement the checks.
|
|
1078
1098
|
* Optional.
|
|
1079
1099
|
*
|
|
@@ -1160,6 +1180,8 @@ export interface TurnBoundaryEvent {
|
|
|
1160
1180
|
type: "turn_boundary";
|
|
1161
1181
|
/** The model that will run the next turn (authoritative under a mid-task model switch). */
|
|
1162
1182
|
model: Model;
|
|
1183
|
+
/** The loop's continuation fact, as defined at {@link import("../loop/types.js").PrepareNextTurnContext.continues}. */
|
|
1184
|
+
continues: boolean;
|
|
1163
1185
|
}
|
|
1164
1186
|
export interface BeforeProviderRequestEvent {
|
|
1165
1187
|
type: "before_provider_request";
|
|
@@ -212,7 +212,17 @@ export function normalizeAnnouncedListing(v) {
|
|
|
212
212
|
const models = arm(src.models);
|
|
213
213
|
const mcpFailed = failureArm(src.mcpFailed);
|
|
214
214
|
const advisories = arm(src.advisories);
|
|
215
|
-
|
|
215
|
+
const advisorArm = (a) => {
|
|
216
|
+
if (a === undefined)
|
|
217
|
+
return undefined;
|
|
218
|
+
if (typeof a !== "object" || a === null)
|
|
219
|
+
return null;
|
|
220
|
+
const { state, segment } = a;
|
|
221
|
+
const segmentOk = segment === null || (typeof segment === "string" && segment.length <= ANNOUNCED_LISTING_MAX_NAME_CHARS);
|
|
222
|
+
return (state === "announced" || state === "withdrawn") && segmentOk ? { state, segment: segment } : null;
|
|
223
|
+
};
|
|
224
|
+
const advisor = advisorArm(src.advisor);
|
|
225
|
+
if (agents === null || skills === null || models === null || mcpFailed === null || advisories === null || advisor === null)
|
|
216
226
|
return undefined;
|
|
217
227
|
return {
|
|
218
228
|
...(agents !== undefined ? { agents } : {}),
|
|
@@ -220,5 +230,6 @@ export function normalizeAnnouncedListing(v) {
|
|
|
220
230
|
...(models !== undefined ? { models } : {}),
|
|
221
231
|
...(mcpFailed !== undefined ? { mcpFailed } : {}),
|
|
222
232
|
...(advisories !== undefined ? { advisories } : {}),
|
|
233
|
+
...(advisor !== undefined ? { advisor } : {}),
|
|
223
234
|
};
|
|
224
235
|
}
|
|
@@ -611,10 +611,10 @@ export interface AssistantMessage {
|
|
|
611
611
|
/**
|
|
612
612
|
* design/124 tier A: this final message was PARTIALLY FINALIZED after a mid-stream connection
|
|
613
613
|
* loss/stall — the substantive streamed prefix (text and/or completed tool calls) was promoted to
|
|
614
|
-
* final content instead of failing the turn (
|
|
614
|
+
* final content instead of failing the turn (avoid re-billing +
|
|
615
615
|
* keep the displayed content consistent with the result). `stopReason` is synthesized from the
|
|
616
616
|
* content ("toolUse" when a completed tool call streamed, else "stop"); `errorMessage` carries the
|
|
617
|
-
* warning in
|
|
617
|
+
* warning in the reference's former words ("Response stalled mid-stream." / "Connection closed mid-response."), visible
|
|
618
618
|
* to the model in the transcript. Downstream semantics (agent-loop): `partialFinalized &&
|
|
619
619
|
* stopReason==="stop"` gets a BOUNDED continue nudge (an unattended run must not book the cut as an
|
|
620
620
|
* incomplete success); `partialFinalized && stopReason==="toolUse"` executes normally (a truncated
|
|
@@ -877,7 +877,7 @@ export interface OpenAIResponsesCompat {
|
|
|
877
877
|
*/
|
|
878
878
|
export interface AnthropicMessagesCompat {
|
|
879
879
|
/**
|
|
880
|
-
* How this endpoint takes extended thinking (
|
|
880
|
+
* How this endpoint takes extended thinking (design/119).
|
|
881
881
|
* - `"budget"` (default, pre-Fable models): `thinking: { type: "enabled", budget_tokens }`.
|
|
882
882
|
* - `"adaptive"` (Fable 5 / Opus 4.8/4.7 class): `thinking: { type: "adaptive" }` — NO
|
|
883
883
|
* `budget_tokens` (these models 400 on a budget), no max_tokens bump; the intensity is carried
|
|
@@ -886,7 +886,7 @@ export interface AnthropicMessagesCompat {
|
|
|
886
886
|
*/
|
|
887
887
|
thinkingMode?: "budget" | "adaptive";
|
|
888
888
|
/**
|
|
889
|
-
* Effort tiers this endpoint accepts via `output_config.effort` (
|
|
889
|
+
* Effort tiers this endpoint accepts via `output_config.effort` (the reference's `effort` /
|
|
890
890
|
* `xhigh_effort` / `max_effort` capability bits collapsed into one declared set, matching the
|
|
891
891
|
* `reasoningEffortLevels` pattern on {@link OpenAICompletionsCompat}). Present ⇒ the brain sends
|
|
892
892
|
* `output_config: { effort }` plus the `effort-2025-11-24` beta header, clamping the requested
|
|
@@ -896,14 +896,14 @@ export interface AnthropicMessagesCompat {
|
|
|
896
896
|
*/
|
|
897
897
|
effortLevels?: ThinkingLevel[];
|
|
898
898
|
/**
|
|
899
|
-
* Whether the endpoint accepts `temperature` at all.
|
|
899
|
+
* Whether the endpoint accepts `temperature` at all. The reference sends temperature only to a
|
|
900
900
|
* legacy allowlist — Fable-5-class models NEVER receive it (400 risk), independent of thinking
|
|
901
901
|
* state. Default true (existing models unchanged); `false` drops a caller temperature
|
|
902
902
|
* unconditionally, not just under extended thinking.
|
|
903
903
|
*/
|
|
904
904
|
supportsTemperature?: boolean;
|
|
905
905
|
/**
|
|
906
|
-
* design/119 S4 (
|
|
906
|
+
* design/119 S4 (`context_management` capability): when thinking is enabled, send
|
|
907
907
|
* `context_management: { edits: [{ type: "clear_thinking_20251015", keep: "all" }] }` plus the
|
|
908
908
|
* `context-management-2025-06-27` beta — an explicit opt-OUT of the server's default
|
|
909
909
|
* thinking-clearing, preserving cross-turn reasoning continuity (what CC sends on first-party
|
|
@@ -912,7 +912,7 @@ export interface AnthropicMessagesCompat {
|
|
|
912
912
|
*/
|
|
913
913
|
contextManagement?: boolean;
|
|
914
914
|
/**
|
|
915
|
-
* design/119 S4
|
|
915
|
+
* design/119 S4: attach the `interleaved-thinking-2025-05-14` beta on tool-enabled
|
|
916
916
|
* requests with thinking on (thinking blocks may interleave with tool_use). Declare per endpoint;
|
|
917
917
|
* absent = no beta (pre-119 behavior; a deployment could already do this via static `headers`).
|
|
918
918
|
*/
|
|
@@ -957,7 +957,7 @@ export interface Model<TApi extends Api = Api> {
|
|
|
957
957
|
/**
|
|
958
958
|
* Optional AUTOCOMPACT window — the window the compaction trigger and the clearStale frontier
|
|
959
959
|
* are derived from when it differs from the physical request window (dual-window semantics).
|
|
960
|
-
*
|
|
960
|
+
* The reference's posture: its 1M sonnet keeps the PHYSICAL window at 1M while a per-model dynamic
|
|
961
961
|
* config lowers only the autocompact window to 967000, so the reactive trigger lands at 934000
|
|
962
962
|
* (= 967000 − 33000); a single window value cannot express both. Consumed by the trigger-side
|
|
963
963
|
* geometry only (`editBudget`/`sanitizeCompactionSettings`/`shouldCompact` window); the request
|
|
@@ -996,7 +996,7 @@ export interface Model<TApi extends Api = Api> {
|
|
|
996
996
|
/** Extra request HEADERS merged into the provider call. Cannot override auth / content-type / version. */
|
|
997
997
|
headers?: Record<string, string>;
|
|
998
998
|
/**
|
|
999
|
-
* design/119 S3
|
|
999
|
+
* design/119 S3: model-declared system-prompt guidance sections, appended to
|
|
1000
1000
|
* the assembled system prompt. This is the declarative home for per-model behavioral patches (CC
|
|
1001
1001
|
* ships Fable-5 "mitigations" baked behind model-name checks; sema keeps the MECHANISM generic —
|
|
1002
1002
|
* any Model can carry guidance — and the CONTENT as preset data, zero model-name matching in core).
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Tool, ToolCall } from "./types.js";
|
|
2
2
|
/** Finds the target tool and validates/coerces a model-emitted tool call. */
|
|
3
3
|
export declare function validateToolCall(tools: Tool[], toolCall: ToolCall): unknown;
|
|
4
|
-
/**
|
|
4
|
+
/** The dispatcher's name resolution over one tool list, indexed once (for a caller resolving many names over the same list):
|
|
5
|
+
* canonical names first, then aliases (design/115 P0 order) — the first tool carrying a name, or an alias, owns it. */
|
|
6
|
+
export declare function toolNameIndex<T extends Tool>(tools: readonly T[] | undefined): (name: string) => T | undefined;
|
|
7
|
+
/** VENDORED EDIT (design/115 P0): resolve canonical tool names first, then legacy aliases ({@link toolNameIndex} for one name). */
|
|
5
8
|
export declare function findToolByName<T extends Tool>(tools: readonly T[] | undefined, name: string): T | undefined;
|
|
6
9
|
/** Validates tool arguments against TypeBox or plain JSON-schema parameters. */
|
|
7
10
|
export declare function validateToolArguments(tool: Tool, toolCall: ToolCall): unknown;
|
|
@@ -378,8 +378,20 @@ export function validateToolCall(tools, toolCall) {
|
|
|
378
378
|
}
|
|
379
379
|
return validateToolArguments(tool, toolCall);
|
|
380
380
|
}
|
|
381
|
+
export function toolNameIndex(tools) {
|
|
382
|
+
const byName = new Map();
|
|
383
|
+
const byAlias = new Map();
|
|
384
|
+
for (const t of tools ?? []) {
|
|
385
|
+
if (!byName.has(t.name))
|
|
386
|
+
byName.set(t.name, t);
|
|
387
|
+
for (const a of t.aliases ?? [])
|
|
388
|
+
if (!byAlias.has(a))
|
|
389
|
+
byAlias.set(a, t);
|
|
390
|
+
}
|
|
391
|
+
return (name) => byName.get(name) ?? byAlias.get(name);
|
|
392
|
+
}
|
|
381
393
|
export function findToolByName(tools, name) {
|
|
382
|
-
return
|
|
394
|
+
return toolNameIndex(tools)(name);
|
|
383
395
|
}
|
|
384
396
|
export function validateToolArguments(tool, toolCall) {
|
|
385
397
|
const args = structuredClone(toolCall.arguments);
|
|
@@ -61,7 +61,7 @@ export type LoopTerminalReason =
|
|
|
61
61
|
* loop ended cleanly at a manufactured boundary, no reconcile owed), and which consult caught
|
|
62
62
|
* it is timing, not semantics. */
|
|
63
63
|
| "stop_requested"
|
|
64
|
-
/** RB-206 (
|
|
64
|
+
/** RB-206 (the reference buckets it
|
|
65
65
|
* with budget_exhausted/api_error/model_error/turn_setup_failed, explicitly NOT `"completed"`): every
|
|
66
66
|
* tool call in the turn was dropped as malformed AND the bounded `malformed_tool_use_retry` nudge
|
|
67
67
|
* budget is used up — the model believes it acted, nothing ran, and there is no more recovery budget
|