@sema-agent/server 1.322.0 → 2.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.
- package/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +2132 -96
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +59 -3
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Degenerate-repetition instrument (a/b classifier).
|
|
3
|
+
*
|
|
4
|
+
* When a task fails with `errorCode === "output.degenerate"` (core 1.59), core hands back
|
|
5
|
+
* `salvagedOutput` = the degenerate turn's **whole** text (the good head + the looped garbage tail).
|
|
6
|
+
* Core's *salvage ②* — recovering the "last substantive turn" instead of the current one — is being
|
|
7
|
+
* gated on REAL data: how often is the useful answer actually in an EARLIER turn vs. in the degenerate
|
|
8
|
+
* turn itself? This instrument answers that, per event, without changing any behaviour.
|
|
9
|
+
*
|
|
10
|
+
* Classification (since the last user message = this task's own turns):
|
|
11
|
+
* - **a** good+garbage SAME turn — the degenerate turn carries a substantive unique head before the
|
|
12
|
+
* loop. Whole-turn salvage ① + a tail-trim is enough; ② would add nothing.
|
|
13
|
+
* - **b** good EARLIER / degenerate LATER — a substantive assistant turn already exists before the
|
|
14
|
+
* degenerate one. ② ("last-substantive-turn") would recover it; ① (current turn) throws it away.
|
|
15
|
+
* - **unknown** — degenerate from the start, nothing substantive anywhere (neither ① nor ② helps).
|
|
16
|
+
*
|
|
17
|
+
* Output is measurement only: a `degenerate_total{class}` counter (→ `/metrics/summary`) plus one
|
|
18
|
+
* structured log line carrying the raw signals. The aggregate a/b/unknown frequencies are what gets
|
|
19
|
+
* reported back to the core AI to decide whether ② is worth building. The repetition-boundary estimate
|
|
20
|
+
* here is for *measuring* the unique head — it is NOT the production tail-trim (that lives in core).
|
|
21
|
+
*/
|
|
1
22
|
import { type TaskResult } from "@sema-agent/core";
|
|
2
23
|
import type { Pool } from "mysql2/promise";
|
|
3
24
|
import type { Metrics } from "./observability/metrics.js";
|
|
@@ -5,13 +26,30 @@ import type { Logger } from "./observability/logger.js";
|
|
|
5
26
|
export type DegenerateClass = "a" | "b" | "unknown";
|
|
6
27
|
export interface DegenerateSignals {
|
|
7
28
|
class: DegenerateClass;
|
|
29
|
+
/** Assistant turns since the last user message, INCLUDING the degenerate one. */
|
|
8
30
|
turnsSinceUser: number;
|
|
31
|
+
/** Substantive (non-looping) assistant text before the degenerate turn, since the last user message. */
|
|
9
32
|
priorChars: number;
|
|
10
33
|
salvagedLen: number;
|
|
34
|
+
/** `salvagedLen` minus the estimated looped tail = how much real answer the degenerate turn carries. */
|
|
11
35
|
uniquePrefixLen: number;
|
|
12
36
|
repeatedTailLen: number;
|
|
13
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Length of the longest periodic suffix of `text` (≥ {@link MIN_REPEATS} contiguous copies of some
|
|
40
|
+
* unit ≤ {@link MAX_UNIT}). 0 when no qualifying loop is found. Bounded to the last {@link REP_WINDOW}
|
|
41
|
+
* chars. This estimates where the degenerate repetition begins — a measurement aid, not a trimmer.
|
|
42
|
+
*/
|
|
14
43
|
export declare function repetitionTail(text: string): number;
|
|
44
|
+
/**
|
|
45
|
+
* Classify a degenerate failure from its salvaged text + the substantive content of the assistant
|
|
46
|
+
* turns that preceded it (since the last user message). Pure — unit-tested directly.
|
|
47
|
+
*/
|
|
15
48
|
export declare function classifyDegenerate(salvaged: string, priorChars: number, turnsSinceUser: number): DegenerateSignals;
|
|
49
|
+
/**
|
|
50
|
+
* Build the fire-and-forget instrument. Returns a sync `(result) => void` so the hot result paths
|
|
51
|
+
* (`recordTaskResult` / `recordDone`) stay unblocked; the session read + classification run in the
|
|
52
|
+
* background and never throw into the response. No-op for non-degenerate results.
|
|
53
|
+
*/
|
|
16
54
|
export declare function makeDegenerateInstrument(pool: Pool, metrics?: Metrics, logger?: Logger): (result: TaskResult) => void;
|
|
17
55
|
//# sourceMappingURL=degenerate-instrument.d.ts.map
|
|
@@ -1,10 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Degenerate-repetition instrument (a/b classifier).
|
|
3
|
+
*
|
|
4
|
+
* When a task fails with `errorCode === "output.degenerate"` (core 1.59), core hands back
|
|
5
|
+
* `salvagedOutput` = the degenerate turn's **whole** text (the good head + the looped garbage tail).
|
|
6
|
+
* Core's *salvage ②* — recovering the "last substantive turn" instead of the current one — is being
|
|
7
|
+
* gated on REAL data: how often is the useful answer actually in an EARLIER turn vs. in the degenerate
|
|
8
|
+
* turn itself? This instrument answers that, per event, without changing any behaviour.
|
|
9
|
+
*
|
|
10
|
+
* Classification (since the last user message = this task's own turns):
|
|
11
|
+
* - **a** good+garbage SAME turn — the degenerate turn carries a substantive unique head before the
|
|
12
|
+
* loop. Whole-turn salvage ① + a tail-trim is enough; ② would add nothing.
|
|
13
|
+
* - **b** good EARLIER / degenerate LATER — a substantive assistant turn already exists before the
|
|
14
|
+
* degenerate one. ② ("last-substantive-turn") would recover it; ① (current turn) throws it away.
|
|
15
|
+
* - **unknown** — degenerate from the start, nothing substantive anywhere (neither ① nor ② helps).
|
|
16
|
+
*
|
|
17
|
+
* Output is measurement only: a `degenerate_total{class}` counter (→ `/metrics/summary`) plus one
|
|
18
|
+
* structured log line carrying the raw signals. The aggregate a/b/unknown frequencies are what gets
|
|
19
|
+
* reported back to the core AI to decide whether ② is worth building. The repetition-boundary estimate
|
|
20
|
+
* here is for *measuring* the unique head — it is NOT the production tail-trim (that lives in core).
|
|
21
|
+
*/
|
|
22
|
+
// 🔴 core 1.403 迁移(2026-07-25):runtime 构造用法,`Session` → `StoredSession`(见 audit.ts 同款注释)。
|
|
1
23
|
import { StoredSession } from "@sema-agent/core";
|
|
2
24
|
import { TiDBSessionStorage } from "./plugins/tidb-session-storage.js";
|
|
25
|
+
/** A "real" answer is at least this many non-looping chars (after the degenerate tail is stripped). */
|
|
3
26
|
const SUBSTANTIVE_CHARS = 200;
|
|
27
|
+
/** Loops live at the end — only inspect this much of the tail when hunting the repeating unit. */
|
|
4
28
|
const REP_WINDOW = 8192;
|
|
29
|
+
/** Need at least this many contiguous copies to call a periodic suffix a degenerate loop. */
|
|
5
30
|
const MIN_REPEATS = 3;
|
|
31
|
+
/** Longest repeating unit we look for (a sentence-ish block); bounds the scan. */
|
|
6
32
|
const MAX_UNIT = 256;
|
|
33
|
+
/** Two assistant turns are "the same turn" if their heads match (a degenerate head is distinctive). */
|
|
7
34
|
const TURN_MATCH_HEAD = 120;
|
|
35
|
+
/**
|
|
36
|
+
* Length of the longest periodic suffix of `text` (≥ {@link MIN_REPEATS} contiguous copies of some
|
|
37
|
+
* unit ≤ {@link MAX_UNIT}). 0 when no qualifying loop is found. Bounded to the last {@link REP_WINDOW}
|
|
38
|
+
* chars. This estimates where the degenerate repetition begins — a measurement aid, not a trimmer.
|
|
39
|
+
*/
|
|
8
40
|
export function repetitionTail(text) {
|
|
9
41
|
const n = text.length;
|
|
10
42
|
if (n < 2)
|
|
@@ -13,6 +45,7 @@ export function repetitionTail(text) {
|
|
|
13
45
|
const maxUnit = Math.min(MAX_UNIT, Math.floor((n - start) / MIN_REPEATS));
|
|
14
46
|
let best = 0;
|
|
15
47
|
for (let p = 1; p <= maxUnit; p++) {
|
|
48
|
+
// How many times does the final p-char block repeat contiguously, walking backwards?
|
|
16
49
|
let reps = 1;
|
|
17
50
|
for (;;) {
|
|
18
51
|
const blockStart = n - p * (reps + 1);
|
|
@@ -34,20 +67,26 @@ export function repetitionTail(text) {
|
|
|
34
67
|
}
|
|
35
68
|
return best;
|
|
36
69
|
}
|
|
70
|
+
/** Substantive (non-looping) length of one assistant turn's text. */
|
|
37
71
|
function substantiveLen(text) {
|
|
38
72
|
return Math.max(0, text.length - repetitionTail(text));
|
|
39
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Classify a degenerate failure from its salvaged text + the substantive content of the assistant
|
|
76
|
+
* turns that preceded it (since the last user message). Pure — unit-tested directly.
|
|
77
|
+
*/
|
|
40
78
|
export function classifyDegenerate(salvaged, priorChars, turnsSinceUser) {
|
|
41
79
|
const salvagedLen = salvaged.length;
|
|
42
80
|
const repeatedTailLen = repetitionTail(salvaged);
|
|
43
81
|
const uniquePrefixLen = Math.max(0, salvagedLen - repeatedTailLen);
|
|
44
82
|
const cls = priorChars >= SUBSTANTIVE_CHARS
|
|
45
|
-
? "b"
|
|
83
|
+
? "b" // a substantive answer already existed in an earlier turn → ② would recover it
|
|
46
84
|
: uniquePrefixLen >= SUBSTANTIVE_CHARS
|
|
47
|
-
? "a"
|
|
48
|
-
: "unknown";
|
|
85
|
+
? "a" // the degenerate turn itself carries the answer before looping → ① + tail-trim suffices
|
|
86
|
+
: "unknown"; // degenerate from the start, nothing substantive anywhere
|
|
49
87
|
return { class: cls, turnsSinceUser, priorChars, salvagedLen, uniquePrefixLen, repeatedTailLen };
|
|
50
88
|
}
|
|
89
|
+
/** Concatenated text-block content of one (assistant) message; "" for a tool-call-only turn. */
|
|
51
90
|
function turnText(msg) {
|
|
52
91
|
if (msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
53
92
|
return "";
|
|
@@ -56,6 +95,7 @@ function turnText(msg) {
|
|
|
56
95
|
.map((b) => b.text)
|
|
57
96
|
.join("");
|
|
58
97
|
}
|
|
98
|
+
/** Heads match → treat as the same turn (core may or may not persist the failed degenerate turn). */
|
|
59
99
|
function sameTurn(a, b) {
|
|
60
100
|
if (!a || !b)
|
|
61
101
|
return false;
|
|
@@ -64,6 +104,12 @@ function sameTurn(a, b) {
|
|
|
64
104
|
const k = Math.min(TURN_MATCH_HEAD, a.length, b.length);
|
|
65
105
|
return k > 0 && a.slice(0, k) === b.slice(0, k);
|
|
66
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Read this task's assistant turns (since the last user message) and total the substantive text that
|
|
109
|
+
* preceded the degenerate turn. The degenerate turn is located by head-matching `salvaged`; if it was
|
|
110
|
+
* not persisted, every persisted assistant turn in the window counts as prior (and the degenerate turn
|
|
111
|
+
* is added to the count). Best-effort — returns zeros if the session can't be read.
|
|
112
|
+
*/
|
|
67
113
|
async function readPriorTurns(pool, sessionId, salvaged) {
|
|
68
114
|
const storage = await TiDBSessionStorage.wake(pool, sessionId);
|
|
69
115
|
if (!storage)
|
|
@@ -90,9 +136,15 @@ async function readPriorTurns(pool, sessionId, salvaged) {
|
|
|
90
136
|
}
|
|
91
137
|
const priorTexts = degenIdx >= 0 ? assistantTexts.slice(0, degenIdx) : assistantTexts;
|
|
92
138
|
const priorChars = priorTexts.reduce((a, t) => a + substantiveLen(t), 0);
|
|
139
|
+
// turnsSinceUser counts the degenerate turn too; add 1 when it wasn't found among persisted turns.
|
|
93
140
|
const turnsSinceUser = degenIdx >= 0 ? assistantTexts.length : assistantTexts.length + 1;
|
|
94
141
|
return { priorChars, turnsSinceUser };
|
|
95
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Build the fire-and-forget instrument. Returns a sync `(result) => void` so the hot result paths
|
|
145
|
+
* (`recordTaskResult` / `recordDone`) stay unblocked; the session read + classification run in the
|
|
146
|
+
* background and never throw into the response. No-op for non-degenerate results.
|
|
147
|
+
*/
|
|
96
148
|
export function makeDegenerateInstrument(pool, metrics, logger) {
|
|
97
149
|
return (result) => {
|
|
98
150
|
if (result.errorCode !== "output.degenerate")
|
package/dist/elicitation.d.ts
CHANGED
|
@@ -1,27 +1,47 @@
|
|
|
1
1
|
import { type McpElicitRequest, type McpElicitResponse } from "@sema-agent/core";
|
|
2
|
+
/** A live elicitation frame delivered to whoever is tailing this run's stream. `type` IS the SSE event name
|
|
3
|
+
* (mirrors the named-event convention: the payload also carries `type` so a proxy that strips event names still
|
|
4
|
+
* works). The shell renders the `elicitation` frame as a dialog and dismisses on `elicitation_complete`. */
|
|
2
5
|
export interface ElicitationFrame {
|
|
3
6
|
type: "elicitation" | "elicitation_complete";
|
|
4
7
|
elicitationId: string;
|
|
5
8
|
mcpServerName: string;
|
|
9
|
+
/** "elicitation" only: the FENCED + secret-redacted human-facing prompt. UNTRUSTED — never re-feed to a model. */
|
|
6
10
|
message?: string;
|
|
11
|
+
/** "elicitation" only: the server's requested input schema. OPAQUE passthrough — never interpreted/validated;
|
|
12
|
+
* still server-controlled UNTRUSTED, so the shell must fence it on display. */
|
|
7
13
|
requestedSchema?: unknown;
|
|
14
|
+
/** "elicitation" only: always "form" in v1 (url-mode is rejected upstream). */
|
|
8
15
|
mode?: "form";
|
|
16
|
+
/** "elicitation_complete" only: how it resolved. */
|
|
9
17
|
action?: McpElicitResponse["action"];
|
|
10
18
|
}
|
|
19
|
+
/** The per-run context `onElicit` recovers via ALS. `emit` delivers a frame to the run's live stream;
|
|
20
|
+
* `abortSignal` (the run's own cancel signal) lets a run-abort promptly cancel an elicitation parked awaiting a
|
|
21
|
+
* human, since the MCP per-request signal may not be chained to the run abort. */
|
|
11
22
|
export interface ElicitationRunContext {
|
|
12
23
|
taskId: string;
|
|
13
24
|
owner: string | null;
|
|
14
25
|
emit: (frame: ElicitationFrame) => void | Promise<void>;
|
|
15
26
|
abortSignal?: AbortSignal;
|
|
16
27
|
}
|
|
28
|
+
/** @deprecated design/158 N22: the root word got truncated at naming time — `ElicitationFrame` / `ElicitationThrottle` /
|
|
29
|
+
* `ElicitationCoordinator` all spell it out; this alias was the odd one. Use {@link ElicitationRunContext}. */
|
|
17
30
|
export type ElicitRunContext = ElicitationRunContext;
|
|
18
31
|
export interface ElicitationThrottle {
|
|
32
|
+
/** Max concurrent in-flight elicitations per run leg (parallel tool calls can each elicit). Breach ⇒ decline. */
|
|
19
33
|
maxConcurrentPerRun: number;
|
|
34
|
+
/** Max total elicitations one run leg will surface to the human. Breach ⇒ decline (flood defense). */
|
|
20
35
|
maxTotalPerRun: number;
|
|
36
|
+
/** Min gap (ms) between two elicitations from the SAME server within a run. Within ⇒ decline (burst guard). */
|
|
21
37
|
minIntervalMsPerServer: number;
|
|
38
|
+
/** An unanswered elicitation auto-declines after this (ms) — the human walked away; don't hold core forever. */
|
|
22
39
|
ttlMs: number;
|
|
23
40
|
}
|
|
24
41
|
export declare const DEFAULT_ELICITATION_THROTTLE: ElicitationThrottle;
|
|
42
|
+
/** Validate the respond body = core's `McpElicitResponse`. `content` is accept-only OPAQUE passthrough (core never
|
|
43
|
+
* validates it against `requestedSchema`); we validate only the outer shape (a flat record of scalars / string[]),
|
|
44
|
+
* never the schema. A non-accept drops content (MCP convention). */
|
|
25
45
|
export declare function parseElicitationResponse(body: unknown): {
|
|
26
46
|
ok: true;
|
|
27
47
|
value: McpElicitResponse;
|
|
@@ -29,7 +49,16 @@ export declare function parseElicitationResponse(body: unknown): {
|
|
|
29
49
|
ok: false;
|
|
30
50
|
error: string;
|
|
31
51
|
};
|
|
52
|
+
/** @deprecated design/158 N22: renamed to {@link parseElicitationResponse} — unifies the HITL trio's parse-fn
|
|
53
|
+
* vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
|
|
54
|
+
* human's reply body"). Kept as a compat alias. */
|
|
32
55
|
export declare const parseElicitResponse: typeof parseElicitationResponse;
|
|
56
|
+
/**
|
|
57
|
+
* Coordinates inbound MCP elicitations for one server instance. Process-local + same-replica (the pending map is in
|
|
58
|
+
* memory, like `steerableRuns`): a respond that lands on another replica finds nothing → 404. Present (passed into
|
|
59
|
+
* `RunnerDeps.onElicit` + the respond route) ONLY when `MCP_ELICITATION_ENABLED` — absent ⇒ core advertises no
|
|
60
|
+
* elicitation capability to any server (doubly fail-closed with the per-server `McpServerSpec.elicitation` default OFF).
|
|
61
|
+
*/
|
|
33
62
|
export declare class ElicitationCoordinator {
|
|
34
63
|
private readonly als;
|
|
35
64
|
private readonly pending;
|
|
@@ -37,12 +66,22 @@ export declare class ElicitationCoordinator {
|
|
|
37
66
|
private readonly throttle;
|
|
38
67
|
private readonly now;
|
|
39
68
|
constructor(throttle?: ElicitationThrottle, now?: () => number);
|
|
69
|
+
/** Run `fn` with the per-run elicitation context ambient. On exit, cancel any still-pending elicitation for this
|
|
70
|
+
* run (a live-only elicitation cannot outlive its leg) and drop the run's counters (no leak). The cancel covers
|
|
71
|
+
* the case where the leg ends/throws while an elicitation is parked but the leg's own loop has already drained. */
|
|
40
72
|
runWithContext<T>(ctx: ElicitationRunContext, fn: () => Promise<T>): Promise<T>;
|
|
73
|
+
/** `RunnerDeps.onElicit`. Core calls this when an opted-in server elicits the END USER mid-tool-call; the resolved
|
|
74
|
+
* value is sent back to the server on the still-open connection. Fail-closed (`decline`/`cancel`) in every
|
|
75
|
+
* uncertain case. Arrow property so it can be passed as `onElicit: coordinator.elicit` with `this` bound. */
|
|
41
76
|
elicit: (req: McpElicitRequest, signal?: AbortSignal) => Promise<McpElicitResponse>;
|
|
77
|
+
/** `POST /v1/elicitations/:id/respond` — resolve a parked elicitation with the shell's answer. Owner-gated with a
|
|
78
|
+
* 404 (no existence oracle): a non-owner AND an unknown id (answered / expired / wrong replica) both get 404.
|
|
79
|
+
* Returns the HTTP {status, body}; the HTTP layer owns auth (gatedPrincipal + REQUIRE_PRINCIPAL) before calling. */
|
|
42
80
|
respond(id: string, principal: string | undefined, body: unknown): {
|
|
43
81
|
status: number;
|
|
44
82
|
body: unknown;
|
|
45
83
|
};
|
|
84
|
+
/** Test/observability hook: number of currently-parked elicitations. */
|
|
46
85
|
pendingCount(): number;
|
|
47
86
|
private countersFor;
|
|
48
87
|
}
|
package/dist/elicitation.js
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E23 (shell-host contract) — inbound-MCP-elicitation HITL flow, the SERVICE side of core 1.124.0's live-only
|
|
3
|
+
* `RunnerDeps.onElicit` seam (design/99 §E23).
|
|
4
|
+
*
|
|
5
|
+
* An opted-in MCP server (`McpServerSpec.elicitation === true`) may, MID-tool-call, ask the END USER for input.
|
|
6
|
+
* core hands that request to `onElicit` and awaits the answer SYNCHRONOUSLY on the still-open task-scoped
|
|
7
|
+
* connection (it replies to the server with whatever the promise resolves to). There is NO durable suspend —
|
|
8
|
+
* a crash/replica-change loses an in-flight elicitation (acceptable for an interactive shell; a durable variant
|
|
9
|
+
* waits on the deferred E22 longer-lived connection). So this whole flow is LIVE-ONLY + same-replica, the
|
|
10
|
+
* `steer()`-class of HITL, NOT the durable approval/checkpoint class.
|
|
11
|
+
*
|
|
12
|
+
* The service is pure WIRE glue (the abstraction is core's, §0.1): forward the request to whoever is tailing the
|
|
13
|
+
* run's stream (an `elicitation` SSE frame), park a promise, and resolve it from `POST /v1/elicitations/:id/respond`.
|
|
14
|
+
* Three responsibilities are explicitly the deployment's (core delegates them):
|
|
15
|
+
* 1. THROTTLE — core imposes no rate/count cap; an over-eager or hostile server could flood the human. We bound
|
|
16
|
+
* concurrency + total + per-server burst per run; a breach fail-closes to `decline`.
|
|
17
|
+
* 2. FENCING — `message`/`requestedSchema` are server-controlled UNTRUSTED text; `message` is `delimitUntrusted`-
|
|
18
|
+
* fenced + secret-redacted before it reaches a human (the shell must also fence `requestedSchema` on display).
|
|
19
|
+
* 3. FORM-MODE ONLY — v1 advertises form mode; url-mode (a phishing surface) is defensively rejected.
|
|
20
|
+
*
|
|
21
|
+
* ROUTING: `onElicit` lives on the SINGLETON runner's `RunnerDeps` and the request carries no taskId, so the run's
|
|
22
|
+
* executor establishes a per-run context (AsyncLocalStorage, like `withPrincipal`) carrying the taskId (throttle
|
|
23
|
+
* key), the owner (respond owner-gate), and an `emit` closure (durable append for background/resume legs; `res.write`
|
|
24
|
+
* for the synchronous stream leg). `node:async_hooks` propagates it through every await, so `onElicit` — invoked deep
|
|
25
|
+
* inside core's `callTool` — recovers it. No context ⇒ fail-closed `decline`.
|
|
26
|
+
*/
|
|
1
27
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
28
|
import { uuidv7, delimitUntrusted } from "@sema-agent/core";
|
|
3
29
|
import { redactSecrets, redactDeep } from "./trace/redact.js";
|
|
30
|
+
/** Size bounds on the UNTRUSTED server-controlled payload (the throttle bounds COUNT, these bound SIZE — an
|
|
31
|
+
* opted-in-but-hostile server otherwise amplifies a multi-MB prompt/schema into the durable log + SSE socket).
|
|
32
|
+
* The message is a human-facing prompt (a few KB is ample); a requestedSchema over the cap is dropped (the form
|
|
33
|
+
* can't render an abusive schema — fail-safe to no-schema). */
|
|
4
34
|
const MAX_ELICIT_MESSAGE_CHARS = 4096;
|
|
5
35
|
const MAX_ELICIT_SCHEMA_BYTES = 8192;
|
|
6
36
|
export const DEFAULT_ELICITATION_THROTTLE = {
|
|
@@ -9,6 +39,9 @@ export const DEFAULT_ELICITATION_THROTTLE = {
|
|
|
9
39
|
minIntervalMsPerServer: 1_000,
|
|
10
40
|
ttlMs: 5 * 60_000,
|
|
11
41
|
};
|
|
42
|
+
/** Validate the respond body = core's `McpElicitResponse`. `content` is accept-only OPAQUE passthrough (core never
|
|
43
|
+
* validates it against `requestedSchema`); we validate only the outer shape (a flat record of scalars / string[]),
|
|
44
|
+
* never the schema. A non-accept drops content (MCP convention). */
|
|
12
45
|
export function parseElicitationResponse(body) {
|
|
13
46
|
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
14
47
|
return { ok: false, error: "body must be an object" };
|
|
@@ -32,7 +65,14 @@ export function parseElicitationResponse(body) {
|
|
|
32
65
|
}
|
|
33
66
|
return { ok: true, value: { action: b.action } };
|
|
34
67
|
}
|
|
68
|
+
/** @deprecated design/158 N22: renamed to {@link parseElicitationResponse} — unifies the HITL trio's parse-fn
|
|
69
|
+
* vocabulary (`parseQuestionResponse` / `parseElicitationResponse` / `parseToolApprovalResponse`, all "the
|
|
70
|
+
* human's reply body"). Kept as a compat alias. */
|
|
35
71
|
export const parseElicitResponse = parseElicitationResponse;
|
|
72
|
+
/** redactDeep + size-bound an UNTRUSTED `requestedSchema` before it is persisted to the durable log / streamed
|
|
73
|
+
* (the same redact-at-write contract every other untrusted structured field honors, e.g. tool_end.output). A JSON
|
|
74
|
+
* Schema's free-text carriers (description/title/default/enum) can smuggle a secret. Over the byte cap ⇒ undefined
|
|
75
|
+
* (drop — an abusive schema can't render a form); unserializable (circular) ⇒ undefined. */
|
|
36
76
|
function boundSchema(schema) {
|
|
37
77
|
if (schema === undefined)
|
|
38
78
|
return undefined;
|
|
@@ -46,6 +86,12 @@ function boundSchema(schema) {
|
|
|
46
86
|
}
|
|
47
87
|
return redacted;
|
|
48
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Coordinates inbound MCP elicitations for one server instance. Process-local + same-replica (the pending map is in
|
|
91
|
+
* memory, like `steerableRuns`): a respond that lands on another replica finds nothing → 404. Present (passed into
|
|
92
|
+
* `RunnerDeps.onElicit` + the respond route) ONLY when `MCP_ELICITATION_ENABLED` — absent ⇒ core advertises no
|
|
93
|
+
* elicitation capability to any server (doubly fail-closed with the per-server `McpServerSpec.elicitation` default OFF).
|
|
94
|
+
*/
|
|
49
95
|
export class ElicitationCoordinator {
|
|
50
96
|
als = new AsyncLocalStorage();
|
|
51
97
|
pending = new Map();
|
|
@@ -56,12 +102,16 @@ export class ElicitationCoordinator {
|
|
|
56
102
|
this.throttle = throttle;
|
|
57
103
|
this.now = now;
|
|
58
104
|
}
|
|
105
|
+
/** Run `fn` with the per-run elicitation context ambient. On exit, cancel any still-pending elicitation for this
|
|
106
|
+
* run (a live-only elicitation cannot outlive its leg) and drop the run's counters (no leak). The cancel covers
|
|
107
|
+
* the case where the leg ends/throws while an elicitation is parked but the leg's own loop has already drained. */
|
|
59
108
|
runWithContext(ctx, fn) {
|
|
60
109
|
return this.als.run(ctx, async () => {
|
|
61
110
|
try {
|
|
62
111
|
return await fn();
|
|
63
112
|
}
|
|
64
113
|
finally {
|
|
114
|
+
// Snapshot first — settle() mutates this.pending.
|
|
65
115
|
for (const [, p] of [...this.pending]) {
|
|
66
116
|
if (p.taskId === ctx.taskId)
|
|
67
117
|
p.settle({ action: "cancel" });
|
|
@@ -70,26 +120,42 @@ export class ElicitationCoordinator {
|
|
|
70
120
|
}
|
|
71
121
|
});
|
|
72
122
|
}
|
|
123
|
+
/** `RunnerDeps.onElicit`. Core calls this when an opted-in server elicits the END USER mid-tool-call; the resolved
|
|
124
|
+
* value is sent back to the server on the still-open connection. Fail-closed (`decline`/`cancel`) in every
|
|
125
|
+
* uncertain case. Arrow property so it can be passed as `onElicit: coordinator.elicit` with `this` bound. */
|
|
73
126
|
elicit = async (req, signal) => {
|
|
74
127
|
const ctx = this.als.getStore();
|
|
128
|
+
// No run context to route to a human (a leg not wrapped by runWithContext — synchronous /v1/tasks, verify/cascade,
|
|
129
|
+
// or a leader sub-task) ⇒ fail-closed decline. NB on SUB-TASKS: subagent/team run on the SAME runner inside the
|
|
130
|
+
// parent's ALS frame, so a sub-task's elicitation INHERITS the top-level run's ctx — by design it routes to the
|
|
131
|
+
// top-level stream + owner and shares the per-run-tree throttle budget (one human, one budget); the frame's
|
|
132
|
+
// `mcpServerName` attributes which server asked. (Same tenant: a sub-task inherits the parent principal.)
|
|
75
133
|
if (!ctx)
|
|
76
134
|
return { action: "decline" };
|
|
135
|
+
// v1 FORM-MODE ONLY: defensively reject url-mode. core advertises form-only so `url` is never populated today;
|
|
136
|
+
// this is defense-in-depth so a future/hostile url can never reach a human as a phishing link.
|
|
77
137
|
if (typeof req.url === "string" && req.url.length > 0)
|
|
78
138
|
return { action: "decline" };
|
|
79
139
|
if (signal?.aborted || ctx.abortSignal?.aborted)
|
|
80
140
|
return { action: "cancel" };
|
|
141
|
+
// THROTTLE (service's job — core imposes none): bound concurrency + total + per-server burst. Breach ⇒ decline.
|
|
81
142
|
const rc = this.countersFor(ctx.taskId);
|
|
82
143
|
const t = this.now();
|
|
83
|
-
const last = rc.lastByServer.get(req.server);
|
|
144
|
+
const last = rc.lastByServer.get(req.server); // undefined ⇒ first elicitation from this server (no interval gate)
|
|
84
145
|
if (rc.inflight >= this.throttle.maxConcurrentPerRun ||
|
|
85
146
|
rc.total >= this.throttle.maxTotalPerRun ||
|
|
86
147
|
(last !== undefined && t - last < this.throttle.minIntervalMsPerServer)) {
|
|
87
148
|
return { action: "decline" };
|
|
88
149
|
}
|
|
89
150
|
const id = uuidv7();
|
|
90
|
-
rc.inflight += 1;
|
|
151
|
+
rc.inflight += 1; // reserve a concurrency slot for the await; total/interval are charged only on a successful emit
|
|
152
|
+
// FENCE + secret-redact + SIZE-bound the untrusted human-facing prompt: delimitUntrusted neutralizes
|
|
153
|
+
// <system-reminder>/fence break-out on BOTH the body and the server-name label; redactSecrets strips a secret the
|
|
154
|
+
// server echoed; the slice bounds storage/CPU. requestedSchema is redactDeep'd + size-bounded (it is persisted to
|
|
155
|
+
// the durable log + streamed, served to trace readers — fencing-on-display alone does not contain secrets).
|
|
91
156
|
const message = delimitUntrusted(req.server, redactSecrets((typeof req.message === "string" ? req.message : "").slice(0, MAX_ELICIT_MESSAGE_CHARS)));
|
|
92
157
|
const requestedSchema = boundSchema(req.requestedSchema);
|
|
158
|
+
// Deferred answer promise + idempotent settle (resolved by respond, the TTL timer, or an abort).
|
|
93
159
|
let done = false;
|
|
94
160
|
let timer;
|
|
95
161
|
let resolveAnswer;
|
|
@@ -106,37 +172,55 @@ export class ElicitationCoordinator {
|
|
|
106
172
|
rc.inflight = Math.max(0, rc.inflight - 1);
|
|
107
173
|
resolveAnswer(r);
|
|
108
174
|
};
|
|
175
|
+
// Both signals: the MCP per-request signal AND the run's own cancel signal (the former may not be chained to a
|
|
176
|
+
// run abort, which would otherwise leave a cancelled run parked here for the full TTL).
|
|
109
177
|
const onAbort = () => settle({ action: "cancel" });
|
|
110
178
|
timer = setTimeout(() => settle({ action: "decline" }), this.throttle.ttlMs);
|
|
111
179
|
timer.unref?.();
|
|
112
180
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
113
181
|
ctx.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
182
|
+
// Register BEFORE emitting so a (fast) respond can never miss the entry.
|
|
114
183
|
this.pending.set(id, { settle, owner: ctx.owner, taskId: ctx.taskId });
|
|
184
|
+
// Emit the OPEN frame AWAITED so its durable append is ORDERED ahead of the answer/completion/terminal appends —
|
|
185
|
+
// a fire-and-forget append can commit out of seq order and be permanently skipped by the monotonic events-tail
|
|
186
|
+
// cursor (an invisible prompt that then TTL-declines). On a successful emit, charge the per-run-tree budget; a
|
|
187
|
+
// FAILED emit declines (nobody can answer) and must NOT burn maxTotal / the per-server interval.
|
|
115
188
|
try {
|
|
116
189
|
await ctx.emit({ type: "elicitation", elicitationId: id, mcpServerName: req.server, message, ...(requestedSchema !== undefined ? { requestedSchema } : {}), mode: "form" });
|
|
117
190
|
rc.total += 1;
|
|
118
191
|
rc.lastByServer.set(req.server, t);
|
|
119
192
|
}
|
|
120
193
|
catch {
|
|
121
|
-
settle({ action: "decline" });
|
|
194
|
+
settle({ action: "decline" }); // inflight rolled back in settle
|
|
122
195
|
}
|
|
123
196
|
const answer = await answerP;
|
|
197
|
+
// Completion breadcrumb (dialog dismiss) — FIRE-AND-FORGET so a slow/hung durable append can NEVER delay
|
|
198
|
+
// returning the answer to core (which replies to the MCP server on the still-open connection). Best-effort +
|
|
199
|
+
// ordering-uncritical: the shell already has the answer via respond; a late/lost dismiss is cosmetic.
|
|
124
200
|
void Promise.resolve()
|
|
125
201
|
.then(() => ctx.emit({ type: "elicitation_complete", elicitationId: id, mcpServerName: req.server, action: answer.action }))
|
|
126
202
|
.catch(() => undefined);
|
|
127
203
|
return answer;
|
|
128
204
|
};
|
|
205
|
+
/** `POST /v1/elicitations/:id/respond` — resolve a parked elicitation with the shell's answer. Owner-gated with a
|
|
206
|
+
* 404 (no existence oracle): a non-owner AND an unknown id (answered / expired / wrong replica) both get 404.
|
|
207
|
+
* Returns the HTTP {status, body}; the HTTP layer owns auth (gatedPrincipal + REQUIRE_PRINCIPAL) before calling. */
|
|
129
208
|
respond(id, principal, body) {
|
|
209
|
+
// Validate the body BEFORE the lookup (steer parity): a bad body is the caller's error regardless of run state,
|
|
210
|
+
// so 400 is existence-independent (a malformed respond to ANY id → 400, never an existence oracle via 400-vs-404).
|
|
130
211
|
const parsed = parseElicitationResponse(body);
|
|
131
212
|
if (!parsed.ok)
|
|
132
213
|
return { status: 400, body: { error: parsed.error, errorCode: "request.body_shape" } };
|
|
133
214
|
const entry = this.pending.get(id);
|
|
215
|
+
// Owner-gate with 404 (no existence oracle): a non-owner AND an unknown id (answered / expired / wrong replica)
|
|
216
|
+
// both get 404, so a good-body caller can't tell another tenant's id from a nonexistent one.
|
|
134
217
|
if (!entry || (entry.owner !== null && entry.owner !== principal)) {
|
|
135
218
|
return { status: 404, body: { error: "no pending elicitation for this id (answered, expired, or not on this replica)", errorCode: "elicitation.not_pending" } };
|
|
136
219
|
}
|
|
137
220
|
entry.settle(parsed.value);
|
|
138
221
|
return { status: 200, body: { elicitationId: id, delivery: "applied", action: parsed.value.action } };
|
|
139
222
|
}
|
|
223
|
+
/** Test/observability hook: number of currently-parked elicitations. */
|
|
140
224
|
pendingCount() {
|
|
141
225
|
return this.pending.size;
|
|
142
226
|
}
|
package/dist/env-facts.d.ts
CHANGED
|
@@ -4,13 +4,31 @@ export interface SandboxEnvFacts {
|
|
|
4
4
|
capabilities?: string[];
|
|
5
5
|
pkgSource?: string;
|
|
6
6
|
egress?: "none" | "allowlist" | "full";
|
|
7
|
+
/** [820]③ scratchpad first wave: core `TaskSpec.envFacts.scratchpadDir` (field + prompt chain —
|
|
8
|
+
* buildScratchpadSection — shipped in core 1.257.3; only this server half was missing). Core renders the
|
|
9
|
+
* "# Scratchpad Directory" block steering temp files away from /tmp AND the user's project. Core's prompt
|
|
10
|
+
* wording promises: session-specific, isolated from the user's project, "can generally be used without
|
|
11
|
+
* permission prompts" — that last clause is exactly the exemption domain createFsWriteGatePolicy.exemptDirs
|
|
12
|
+
* will honor ([819]③/[820]①), so the path is produced by the single-source {@link scratchpadDirFor} and the
|
|
13
|
+
* 1.290 wiring must reference the SAME function for exemptDirs. */
|
|
7
14
|
scratchpadDir?: string;
|
|
15
|
+
/** [1467]②(core 1.360 B 半场)durable resume 铸句真值——server 按**车道能力面**填(部署静态事实,
|
|
16
|
+
* 非车道名判——[1452]③ 诚实裁:缺席字段=core 零句,绝不写死车道行为):
|
|
17
|
+
* - e2b:VM snapshot suspend/resume ⇒ processes+scratch 双 preserved。
|
|
18
|
+
* - k8s(s3Snapshot):resume=fresh pod+workspace untar ⇒ processes+scratch 双 lost(note 讲清
|
|
19
|
+
* workspace 文件已从快照恢复——「scratch lost」≠「工作丢了」)。
|
|
20
|
+
* - ssh/adb:park-only,远端 host/device 持续存在 ⇒ scratch preserved;processes 不声明(前台随
|
|
21
|
+
* 连接断,daemon 存活——不知道的不说)。
|
|
22
|
+
* - host:同机 ⇒ scratch preserved;processes 不声明(worker 进程可能换代)。
|
|
23
|
+
* - local-docker:容器跨 leg 存续不保证(reconnect 或有或无)⇒ 整域不声明。 */
|
|
8
24
|
resumeFacts?: {
|
|
9
25
|
processes?: "preserved" | "lost";
|
|
10
26
|
scratch?: "preserved" | "lost";
|
|
11
27
|
note?: string;
|
|
12
28
|
};
|
|
13
29
|
}
|
|
30
|
+
/** Compose envFacts from what the deployment knows at spec-prep. Returns undefined when nothing is known
|
|
31
|
+
* (no fact beats a vacuous one — an empty block would still spend prompt tokens). */
|
|
14
32
|
export declare function buildEnvFacts(opts: {
|
|
15
33
|
profile?: string | undefined;
|
|
16
34
|
capabilities?: ImageCapabilities | undefined;
|
|
@@ -19,22 +37,65 @@ export declare function buildEnvFacts(opts: {
|
|
|
19
37
|
scratchpadDir?: string | undefined;
|
|
20
38
|
resumeFacts?: SandboxEnvFacts["resumeFacts"] | undefined;
|
|
21
39
|
}): SandboxEnvFacts | undefined;
|
|
40
|
+
/** resumeFacts 按车道能力面的单真源(部署静态;undefined=整域不声明)。取值依据见
|
|
41
|
+
* {@link SandboxEnvFacts.resumeFacts} 的逐车道注。
|
|
42
|
+
* codex 复审 medium:k8s 必须按**有效快照能力**分叉,不能只看车道名——s3Snapshot 未配=park-only,
|
|
43
|
+
* resume 是全新 pod 且**工作区不恢复**,「文件已从快照恢复」那句会让模型信赖不存在的文件(比缺席
|
|
44
|
+
* 更糟的谎)。 */
|
|
22
45
|
export declare function resumeFactsForLane(provider: "e2b" | "k8s" | "ssh" | "adb" | "local-docker" | "host" | undefined, caps?: {
|
|
23
46
|
k8sSnapshot?: boolean;
|
|
24
47
|
}): SandboxEnvFacts["resumeFacts"] | undefined;
|
|
48
|
+
/** Path-safe session segment: the session id can be CALLER-SUPPLIED (body.sessionId), so it must not be able to
|
|
49
|
+
* walk the tree ("../", separators, control bytes). Allowlist [A-Za-z0-9_-] (dots excluded so ".." cannot
|
|
50
|
+
* survive), everything else becomes "_". Empty after sanitize → "_".
|
|
51
|
+
*
|
|
52
|
+
* INJECTIVITY (codex F3): allowlist sanitization alone is NOT injective — "team/a" and "team?a" both map to
|
|
53
|
+
* "team_a", so two DIFFERENT sessions (possibly different principals) would collide onto ONE scratchpad dir.
|
|
54
|
+
* The segment is therefore `<readable prefix (sanitized, ≤24)>-<sha256(FULL ORIGINAL sessionId) hex ≤16>`:
|
|
55
|
+
* the hash is over the raw pre-sanitize id, so distinct ids always produce distinct segments (the prefix stays
|
|
56
|
+
* purely for human readability). Max length 24+1+16=41 (uuidv7 = 36 raw). */
|
|
25
57
|
export declare function scratchpadSessionSegment(sessionId: string): string;
|
|
58
|
+
/** THE scratchpad path convention: `<localDataRoot>/scratchpad/<sessionSegment>`. Session-scoped (core's
|
|
59
|
+
* prompt says "session-specific" — every task on the session shares one dir, which is the useful semantics:
|
|
60
|
+
* intermediate artifacts survive across turns/resume legs). Exported as the single source both the envFacts
|
|
61
|
+
* composer (below) and the future createFsWriteGatePolicy `exemptDirs` wiring ([820]①, 1.290) must use. */
|
|
26
62
|
export declare function scratchpadDirFor(localDataRoot: string, sessionId: string): string;
|
|
63
|
+
/** Resolve + CREATE the session scratchpad dir (mkdir -p, idempotent). Returns the path, or undefined when
|
|
64
|
+
* creation fails (honest-facts posture: never advertise a directory that does not exist — same class as
|
|
65
|
+
* egress/pkgSource "don't declare what you don't know"). Lifecycle: the reaper primitives live below —
|
|
66
|
+
* {@link purgeScratchpadDir}(session delete)+ {@link sweepStaleScratchpads}(mtime 周期扫),keyed by the
|
|
67
|
+
* same scratchpadDirFor convention;接线(E21 DELETE purge + 周期 sweep)在 main.ts 侧(D 组)。 */
|
|
27
68
|
export declare function ensureScratchpadDir(localDataRoot: string, sessionId: string): Promise<string | undefined>;
|
|
69
|
+
/** G3([816] 壳侧承诺③/[820]③,[1840]§四接单):**壳供** scratchpad 路径的验收门。
|
|
70
|
+
*
|
|
71
|
+
* 壳(cli)vendored getScratchpadDir 算出 per-session scratchpad 路径随 `TaskRequest.scratchpadDir` 发来;
|
|
72
|
+
* 接受后它**优先于** server 自算(ensureScratchpadDir),喂 main.ts 的同一单点(envFacts 事实 +
|
|
73
|
+
* fs-write gate exemptDirs + additionalDirectories 根围栏)。「没到货引擎忽略 = 无害 additive」。
|
|
74
|
+
*
|
|
75
|
+
* 信任边界:这是 exemptDirs **放宽**输入,验收 fail-closed(任何拒收形回落自算,不 fault 任务):
|
|
76
|
+
* - 多租户(requirePrincipal)一律拒——共享 worker 盘上租户自选豁免目录=越权面;
|
|
77
|
+
* - 仅 host-semantics lane——远程沙箱 lane 的 worker 本机路径对 hands 是谎言(honest-facts 同轴);
|
|
78
|
+
* - 绝对路径 + ≤{@link MAX_PATH}(core 渲染上限同源,超限=core 只能给模型假路径)+ canonical
|
|
79
|
+
* 深度 ≥3(裸 /、/tmp、/home 一整块系统目录不能当豁免域;穿越形按 resolve 归一后判);
|
|
80
|
+
* - mkdir -p 确保存在(gate 的 canonicalize 与 core 根围栏都要真目录)。
|
|
81
|
+
* 敏感路径的最后一道在 core gate 折叠里(sensitivePatterns deny 恒赢,exemptDirs 越不过)。 */
|
|
28
82
|
export declare function acceptShellScratchpadDir(raw: unknown, opts: {
|
|
29
83
|
requirePrincipal: boolean;
|
|
30
84
|
hostSemanticsLane: boolean;
|
|
31
85
|
warn: (msg: string, meta?: object) => void;
|
|
32
86
|
}): Promise<string | undefined>;
|
|
87
|
+
/** 删除一个 session 的 scratchpad 目录(rm -rf,幂等:目录不存在=no-op)。失败吞 warn 不抛——
|
|
88
|
+
* 清理绝不 fault 调用它的 session-delete 路径;下一轮 {@link sweepStaleScratchpads} 仍会兜到它。 */
|
|
33
89
|
export declare function purgeScratchpadDir(localDataRoot: string, sessionId: string): Promise<void>;
|
|
90
|
+
/** 周期 sweep:扫 `<localDataRoot>/scratchpad/` 下 mtime 早于 `olderThanMs` 且不属于 `activeSessionIds`
|
|
91
|
+
* (先经 {@link scratchpadSessionSegment} 映射到目录名域)的目录并删除,返回删除数。逐目录失败跳过
|
|
92
|
+
* (下一轮再兜);scratchpad 根不存在=0。mtime 取目录自身(子文件写入会碰父目录 mtime 的语义因平台而异
|
|
93
|
+
* ——诚实边界:一个只被读的活跃 session 目录可能被判过期,activeSessionIds 排除面才是活会话的真保险)。 */
|
|
34
94
|
export declare function sweepStaleScratchpads(localDataRoot: string, opts: {
|
|
35
95
|
olderThanMs: number;
|
|
36
96
|
activeSessionIds?: Set<string>;
|
|
37
97
|
}): Promise<number>;
|
|
98
|
+
/** Map the exec-lane posture to the egress fact (the model must know when downloads can't work). */
|
|
38
99
|
export declare function egressForRemoteExec(remoteExec: {
|
|
39
100
|
provider?: string;
|
|
40
101
|
allowInternetAccess?: boolean;
|