@sema-agent/server 1.323.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 +58 -2
- 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,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/158 A9 域模块 —— D-1 通用文件附件面(`/v1/attachments`:上传/取回/删除三动词)。
|
|
3
|
+
*
|
|
4
|
+
* owner 门无 oracle(未知与他人同答 404,与 notify 门同姿);上限=server 权威(reject-not-OOM);
|
|
5
|
+
* mime 白名单是部署策略旋钮不是安全开关。本域零可变状态。
|
|
6
|
+
*/
|
|
1
7
|
import { createHash } from "node:crypto";
|
|
2
8
|
import { uuidv7, sanitizePathComponent } from "@sema-agent/core";
|
|
3
9
|
import { HttpError } from "../../security.js";
|
|
@@ -8,11 +14,19 @@ export async function handleAttachments(req, res, url, ctx) {
|
|
|
8
14
|
await handleAttachmentsBody(req, res, url, ctx, miss);
|
|
9
15
|
return !miss.fell;
|
|
10
16
|
}
|
|
17
|
+
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
18
|
+
* 的语义原样 =「本域已应答」;走到函数尾才是「没匹配上」,置 `miss.fell` 交回装配器继续下一个域。
|
|
19
|
+
* 跨域的东西(deps / 助手 / 单域状态 / 每请求量)一律在首行解构出来,于是下面每一行都逐字不变。 */
|
|
11
20
|
async function handleAttachmentsBody(req, res, url, ctx, miss) {
|
|
12
21
|
const { deps } = ctx;
|
|
13
22
|
const { rateLimited, quotaExceeded, safeDecode, readRawBody } = ctx.helpers;
|
|
23
|
+
// D-1 通用文件上传(clay 拍 2026-07-27:独立附件 store)——上传/取回/删除三动词。
|
|
24
|
+
// 语义:上传先行拿句柄 → TaskRequest.attachments 引用绑定(main.ts resolveSpec 半场)→ env 建立
|
|
25
|
+
// 时物化到执行环境(远程 lane factory 包装 / host lane 提交时直写)。owner 门无 oracle(未知与
|
|
26
|
+
// 他人同答 404,notify 门同姿);上限=server 权威(reject-not-OOM,sync-blob 同姿);
|
|
27
|
+
// mime 白名单是部署策略旋钮非安全开关(声明 mime 不可验证;真防线=尺寸上限+沙箱内消费)。
|
|
14
28
|
{
|
|
15
|
-
const am = /^\/v1\/attachments(?:\/([^/?]+))?$/.exec(url);
|
|
29
|
+
const am = /^\/v1\/attachments(?:\/([^/?]+))?$/.exec(url); // NB: `url` 已剥 query(:1017),参数读 req.url
|
|
16
30
|
if (am) {
|
|
17
31
|
if (rateLimited(req, res) || quotaExceeded(req, res))
|
|
18
32
|
return;
|
|
@@ -29,14 +43,17 @@ async function handleAttachmentsBody(req, res, url, ctx, miss) {
|
|
|
29
43
|
const owner = principal ?? "default";
|
|
30
44
|
const attId = am[1] !== undefined ? safeDecode(am[1]) : undefined;
|
|
31
45
|
if (attId === undefined && req.method === "POST") {
|
|
32
|
-
|
|
46
|
+
// ── 上传:POST /v1/attachments?name=<urlencoded>,raw body,content-type=声明 mime ──
|
|
47
|
+
const q = new URL(req.url ?? "", "http://x").searchParams; // `url` 已剥 query
|
|
33
48
|
const rawName = q.get("name");
|
|
49
|
+
// 消毒:剥路径段(两种分隔符)取 basename,截长,再过 core 的组件验证器(throw 形——不合法
|
|
50
|
+
// 即拒;此处先自检同一规则把「用户给了个烂名」按 400 答而不是 500)。
|
|
34
51
|
const base = ((rawName ?? "").split(/[/\\]/).filter(Boolean).pop() ?? "").slice(0, 128);
|
|
35
52
|
if (!rawName || base === "" || base === "." || base === ".." || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(base)) {
|
|
36
53
|
sendError(res, 400, "request.query_invalid", "query param `name` is required and must reduce to a safe basename ([A-Za-z0-9._-], not starting with a dot)");
|
|
37
54
|
return;
|
|
38
55
|
}
|
|
39
|
-
const name = sanitizePathComponent(base);
|
|
56
|
+
const name = sanitizePathComponent(base); // 双保险:与 core 文件店同一验证器(不合法=上面已 400,这里恒过)
|
|
40
57
|
const mime = String(req.headers["content-type"] ?? "").split(";")[0].trim().toLowerCase();
|
|
41
58
|
if (!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(mime) || mime.length > 128) {
|
|
42
59
|
sendError(res, 400, "request.query_invalid", "content-type must be a well-formed mime type (type/subtype)");
|
|
@@ -50,7 +67,7 @@ async function handleAttachmentsBody(req, res, url, ctx, miss) {
|
|
|
50
67
|
const max = deps.config.attachmentMaxBytes ?? 32 * 1024 * 1024;
|
|
51
68
|
let body;
|
|
52
69
|
try {
|
|
53
|
-
body = await readRawBody(req, max);
|
|
70
|
+
body = await readRawBody(req, max); // 413s mid-stream(reject-not-OOM)
|
|
54
71
|
}
|
|
55
72
|
catch (err) {
|
|
56
73
|
if (err instanceof HttpError && err.status === 413) {
|
|
@@ -83,6 +100,7 @@ async function handleAttachmentsBody(req, res, url, ctx, miss) {
|
|
|
83
100
|
res.writeHead(200, {
|
|
84
101
|
"content-type": meta.mime,
|
|
85
102
|
"content-length": String(bytes.byteLength),
|
|
103
|
+
// RFC 5987 编码名(name 已消毒为安全 basename,URL 编码后恒 header-safe)
|
|
86
104
|
"content-disposition": `attachment; filename*=UTF-8''${encodeURIComponent(meta.name)}`,
|
|
87
105
|
});
|
|
88
106
|
res.end(Buffer.from(bytes));
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/158 A9 域模块 —— 能力/场景/模型目录只读面。
|
|
3
|
+
*
|
|
4
|
+
* 路由:`GET /v1/capabilities/scenarios/:name`、`GET /v1/capabilities`、`GET /v1/models`。
|
|
5
|
+
* 三条都在全局 service-credential 门**之后**(config 面非密只读),装配表里的位置必须保住这一点。
|
|
6
|
+
* 本域零可变状态;deps 面宽(能力布尔逐条对应各路由的 501 门,单源不许漂移)但全是存在性只读。
|
|
7
|
+
*/
|
|
1
8
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
9
|
import type { RouteCtx } from "../route-ctx.js";
|
|
3
10
|
export declare function handleCapabilities(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
|
|
@@ -7,29 +7,56 @@ export async function handleCapabilities(req, res, url, ctx) {
|
|
|
7
7
|
await handleCapabilitiesBody(req, res, url, ctx, miss);
|
|
8
8
|
return !miss.fell;
|
|
9
9
|
}
|
|
10
|
+
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
11
|
+
* 的语义原样 =「本域已应答」;走到函数尾才是「没匹配上」,置 `miss.fell` 交回装配器继续下一个域。
|
|
12
|
+
* 跨域的东西(deps / 助手 / 单域状态 / 每请求量)一律在首行解构出来,于是下面每一行都逐字不变。 */
|
|
10
13
|
async function handleCapabilitiesBody(req, res, url, ctx, miss) {
|
|
11
14
|
const { deps } = ctx;
|
|
15
|
+
// E5 定稿:场景详情只读端点——web 专家模式渲染工具面选项+提示词概览。source 语义=selectScenario
|
|
16
|
+
// 实际取用的定义(main.ts 组装时 center 条目与 overlay 同判定源盖同名,约定①)。鉴权=与 /v1/capabilities
|
|
17
|
+
// 同门(全局 service-credential 门后,config 面非密);未知名 404 typed code(人话归壳/web)。
|
|
12
18
|
if (req.method === "GET" && url.startsWith("/v1/capabilities/scenarios/")) {
|
|
13
19
|
const name = url.slice("/v1/capabilities/scenarios/".length).split("?")[0];
|
|
14
20
|
const detail = deps.scenarioDetails?.[name];
|
|
15
21
|
if (!detail) {
|
|
22
|
+
// [939] 信封统一:本路曾是全站唯一对象形 error(`{error:{code}}`)——SDK toApiError 对它特判过一轮
|
|
23
|
+
// TypeError 加固。统一为「字符串 error + 顶层 errorCode」邻位形(cancel/decide 同款),机器判据保留。
|
|
16
24
|
sendError(res, 404, "scenario_not_found", "scenario not found");
|
|
17
25
|
return;
|
|
18
26
|
}
|
|
19
27
|
sendJson(res, 200, detail);
|
|
20
28
|
return;
|
|
21
29
|
}
|
|
30
|
+
// Capability discovery: one call tells a consumer which surfaces this worker has,
|
|
31
|
+
// instead of probing each verb for a 501. Open set — unknown keys must be ignored by consumers.
|
|
32
|
+
// Auth'd like /v1/models (config surface, non-secret). Booleans derive from the SAME deps that gate
|
|
33
|
+
// the routes, so this can never drift from actual 501 behavior.
|
|
22
34
|
if (req.method === "GET" && url === "/v1/capabilities") {
|
|
35
|
+
// Deployment bag first, derived booleans LAST: the bag extends the set but can never shadow the
|
|
36
|
+
// route-gating truths (a config typo must not make capabilities lie about what 501s).
|
|
23
37
|
sendJson(res, 200, {
|
|
24
38
|
...deps.capabilities,
|
|
25
39
|
asyncRuns: Boolean(deps.runStore),
|
|
26
40
|
artifacts: Boolean(deps.runStore),
|
|
41
|
+
// TRUE when durable HITL can FIRE = checkpointStore present (DURABLE_APPROVAL=true): it mounts
|
|
42
|
+
// AskUserQuestion-suspend + the approval center + resumable checkpoints, independent of whether any
|
|
43
|
+
// TOOL is gated (APPROVAL_REQUIRE = the additive F4 layer). Legacy poll-gate approvalStore does NOT
|
|
44
|
+
// count: alone it can't suspend (the P2-preflight lie).
|
|
27
45
|
approvals: Boolean(deps.checkpointStore),
|
|
28
46
|
sessions: Boolean(deps.sessionAudit),
|
|
47
|
+
// [1196] session 级 SSE 订阅面:与 /v1/sessions/:id/events 的 501 谓词同源(sessionWatch 只在
|
|
48
|
+
// sessionStorage 具备 getLeafId/ownerOf 时由 main.ts 构建)——web 据此换轨,false=回落 /head 轮询。
|
|
29
49
|
sessionEvents: Boolean(deps.sessionWatch && deps.sessionStorage?.getLeafId && deps.sessionStorage?.ownerOf),
|
|
50
|
+
// #13([1871] web asks,clay 排批 2026-07-27):fleet 面能力族——一个诚实对象或 false(无 fleetBus=
|
|
51
|
+
// 无 /v1/fleet/stream,路由 501 同谓词)。`resume:"snapshot"` 是刻意的语义广告而非搪塞:总线是
|
|
52
|
+
// latest-state 不是事件日志,**每次连接开头就是全量 snapshot 帧** ⇒ 重连=重快照,行状态不存在
|
|
53
|
+
// 「丢帧」;通知帧(bg_notification)另有 durable inbox 兜底重投。做 last-event-id 重放缓冲=与
|
|
54
|
+
// snapshot 机制重复建设,收益为零(SDK streamFleet 的「NOT RESUMABLE」旧自述按此口径改写)。
|
|
55
|
+
// `steerPriority:"advisory"` 诚实:steer body.priority 收下+枚举校验但 no-op(E15,候 core 队列 seam)。
|
|
30
56
|
fleet: deps.fleetBus
|
|
31
57
|
? { stream: true, sessionScope: true, observe: true, resume: "snapshot", bgNotifyFailClosed: true, steerPriority: "advisory" }
|
|
32
58
|
: false,
|
|
59
|
+
// #3 workspace 浏览面([1894]④:与 fleet 同姿势——对象=面在场,false=501 同谓词)。
|
|
33
60
|
workspace: (() => {
|
|
34
61
|
const wfs = deps.fileSnapshotStore;
|
|
35
62
|
return wfs && typeof wfs.listKeys === "function" && typeof wfs.exportManifest === "function" && typeof wfs.getBlob === "function" && Boolean(deps.sessionStorage?.ownerOf)
|
|
@@ -37,57 +64,216 @@ async function handleCapabilitiesBody(req, res, url, ctx, miss) {
|
|
|
37
64
|
: false;
|
|
38
65
|
})(),
|
|
39
66
|
leader: Boolean(deps.leaderEndpoint),
|
|
67
|
+
// design/138 S1 (clay 2026-07-08): the legacy MemoryStore surface (GET/DELETE /v1/memory + the MF-30
|
|
68
|
+
// session write verbs) was DEPRECATED with the store itself — the new memory engine is model file skills
|
|
69
|
+
// over the injected memory dir, with NO service HTTP verbs. Hard-coded false so a shell that still knows
|
|
70
|
+
// the old caps honestly hides the affordances (the adaptation was pre-announced).
|
|
40
71
|
memory: false,
|
|
41
72
|
memoryWrite: false,
|
|
73
|
+
// CLI surfaces: /v1/policy is always served (config surface); /v1/usage returns real
|
|
74
|
+
// cumulative spend only when a per-principal quota is configured (else enabled:false).
|
|
42
75
|
policy: true,
|
|
43
76
|
usage: Boolean(deps.costQuota),
|
|
77
|
+
// E5 (shell-host contract): permission-mode WRITE is not a cloud-worker capability. Autonomy is
|
|
78
|
+
// compile-time tighten-only + worker-global config (a cloud supervisor shell CANNOT change server-side
|
|
79
|
+
// gating, ~L2075; "autonomy is CONFIG, not steer", core checkpoint-store.ts:513). The READ side is served
|
|
80
|
+
// honestly via GET /v1/policy (PolicyInfo.autonomy). A runtime per-session mutation verb + mode_changed push
|
|
81
|
+
// need a core seam (SERVICE-GAP-DOSSIER §2 row 5) — advertise false so the shell keeps a read-only mode
|
|
82
|
+
// banner instead of a 501-able write affordance ("says yes but 501s" must be impossible).
|
|
44
83
|
permissionModeWrite: false,
|
|
84
|
+
// E7 (shell-host contract): model selection (body.model) + reasoning-effort selection
|
|
85
|
+
// (body.reasoningEffort→TaskSpec.thinking) are accepted on every task request → both true.
|
|
86
|
+
// 🔴 CORRECTION (2026-07-25, blackboard [1664]→[1668]): this used to say "the RESOLVED effectiveModel ECHO
|
|
87
|
+
// is a separate, still-core-blocked cap (SERVICE-GAP-DOSSIER §2 row 7)". THAT WAS WRONG, and it was wrong in
|
|
88
|
+
// an instructive way — the capability exists, it just isn't SPELLED `effectiveModel`. core's `TaskResult.model`
|
|
89
|
+
// (core `src/core/types.ts:1871`, design/99 MF-25) is documented verbatim as "the EFFECTIVE model id that
|
|
90
|
+
// served this task — the RESOLVED `Model.id`, not the requested `TaskSpec.model` ref … Lets a UI echo
|
|
91
|
+
// 'served by X'". A grep for the identifier `effectiveModel` returns zero hits in core and that was mistaken
|
|
92
|
+
// for "core doesn't have it" (search by SEMANTICS, not by identifier name). It already reaches the wire:
|
|
93
|
+
// `POST /v1/tasks` returns the TaskResult verbatim (~L1852), the SDK declares `TaskResult.model`, and this
|
|
94
|
+
// server already consumes it internally for cache-family accounting (~L1843). Pinned by
|
|
95
|
+
// `test/effective-model-echo-wire.test.ts` (real HTTP: resolved id echoed, absent key stays absent) so a
|
|
96
|
+
// future projection/whitelist on this leg can't silently drop it — the `toolEndEventData`-label bug class.
|
|
97
|
+
// Nothing is advertised as a capability BIT here because an additive result field needs no gate
|
|
98
|
+
// (gate-don't-trial-by-501 governs endpoints/verbs, not additive response fields).
|
|
45
99
|
modelSelection: true,
|
|
46
100
|
effortSelection: true,
|
|
101
|
+
// E1 (shell-host contract): tool_end now carries the model-facing `output` (core 1.121.0) — wired onto the durable +
|
|
102
|
+
// live + replay streams (redacted at every boundary). E2: content events carry `eventId` (+ `parentToolCallId`
|
|
103
|
+
// for sub-agent tasks). Both true now that the pinned core emits them and the service threads them through.
|
|
47
104
|
toolOutput: true,
|
|
48
105
|
messageIdentity: true,
|
|
106
|
+
// C1/C2 (core 1.219): `forwardSubagentEvents` = body flag accepted (a delegated child's live
|
|
107
|
+
// content events ride the run stream, parentToolCallId-attributed); `subagentSteer` = the
|
|
108
|
+
// POST /v1/runs/:id/subagents/:target/steer verb routes (requires the run store the route 501s without —
|
|
109
|
+
// same derive-from-deps discipline as the rest of this block; the registry itself is always constructed).
|
|
49
110
|
forwardSubagentEvents: true,
|
|
111
|
+
// G3([820]③):TaskRequest.scratchpadDir 壳供半场已接(env-facts.acceptShellScratchpadDir 验收门;
|
|
112
|
+
// 单用户 + host lane 生效,拒收形回落自算)。TRUE=键会被消费(而非静默丢),不是「必然生效」。
|
|
50
113
|
scratchpadDir: true,
|
|
51
114
|
subagentSteer: Boolean(deps.subagentSteerRegistry) && Boolean(deps.runStore),
|
|
115
|
+
// design/122 (core 1.225): body.retainSubagentSessions accepted + POST /v1/runs/:id/subagents/:target/resume
|
|
116
|
+
// routes (same gate as steer — the verbs share the registry + run store; retain-off runs 409 resume.retain_off).
|
|
52
117
|
subagentResume: Boolean(deps.subagentSteerRegistry) && Boolean(deps.runStore),
|
|
118
|
+
// TaskRequest.settings (client per-request SemaSettings stamp) → projected into the engine TIGHTEN-ONLY
|
|
119
|
+
// (deny-wins, after the deployment + operator baseline). v1 wires permissions + permissionMode (default/
|
|
120
|
+
// acceptEdits/plan — `bypassPermissions` is NEVER honored from settings) + model + outputStyle. `env` is
|
|
121
|
+
// DEFERRED (TaskSpec deliberately has no per-task env injection) — advertised here so the client never
|
|
122
|
+
// silently loses a setting (it can warn the user / withhold those fields).
|
|
123
|
+
// `hooks`(hook-runner 阶段一):TRUE 当本部署会真跑 hook 命令 = 单用户闸(hook 命令跑在
|
|
124
|
+
// worker host,class ② 能力授予;resolveSpec 的 taskHooks 装配同一谓词)。多租户 = false(收到警告忽略)。
|
|
53
125
|
taskSettings: { permissions: true, permissionMode: true, model: true, outputStyle: true, env: false, hooks: deps.config.requirePrincipal !== true },
|
|
126
|
+
// [1476] R1 / [1478] R2: TaskRequest.appendSystemPrompt is accepted top-level → TaskSpec.appendSystemPrompt
|
|
127
|
+
// (first-class lane for the shell's product-knowledge block). A shell probes THIS flag: false/absent ⇒ fall
|
|
128
|
+
// back to the settings.outputStyle ride-along (older servers fold that into the same spec field).
|
|
54
129
|
appendSystemPrompt: true,
|
|
130
|
+
// [1479]① TaskRequest.compactionModel → TaskSpec.compactionModel (design/145 cheap compaction gear;
|
|
131
|
+
// catalog-gated like body.model). Probe this before offering the picker — older servers drop the field.
|
|
55
132
|
compactionModel: true,
|
|
133
|
+
// [1488]③(b): GET /v1/runs/:id/subagents/:handle/output — a BACKGROUND child's (a… agent handle) final
|
|
134
|
+
// report body + status via the core TaskRegistry (the TaskOutput-tool face over HTTP; bg children are
|
|
135
|
+
// never in the run store and bg_notification only carries a summary). background_agent ONLY (codex R1
|
|
136
|
+
// type gate — wa… workflow rows read via the workflow journal). Replica-local like steer.
|
|
56
137
|
subagentOutput: Boolean(deps.subagentTaskOutput) && Boolean(deps.runStore),
|
|
138
|
+
// S2([1520]{core},server 1.251): GET /v1/runs/:id/subagents/:handle/stream — per-agent live tail
|
|
139
|
+
// (SSE;core 1.370 bgAgentId 路由键)。「replay+tail」的 tail 半场(replay=subagentOutput 面);
|
|
140
|
+
// live 帧 replica-local(帧只在宿主 run 所在副本产生),meta 帧如实声明。同门同寻址同 404 形。
|
|
57
141
|
subagentStream: Boolean(deps.subagentTaskOutput) && Boolean(deps.runStore),
|
|
142
|
+
// [1499] CC TaskOutput/TaskStop 人侧对位: GET/POST /v1/runs/:id/tasks/:handle/{output,stop} — the
|
|
143
|
+
// GENERIC background task-handle verbs (b* bash stdout consuming the cursor, m* monitor batches, a*
|
|
144
|
+
// agent final report; workflow handles refused — journal face owns them). SESSION-enforced from birth
|
|
145
|
+
// (?session= required on a session-bound run). Replica-local like subagentOutput.
|
|
58
146
|
taskHandles: Boolean(deps.taskHandleOutput) && Boolean(deps.taskHandleStop) && Boolean(deps.runStore),
|
|
147
|
+
// [876] per-task subagents (core 1.295 body.agents → TaskSpec.agents): honored on SINGLE-USER deployments
|
|
148
|
+
// only — multi-tenant has no per-tenant caps face yet, so it's fail-closed there (resolveSpec warns +
|
|
149
|
+
// ignores; same predicate as mcpInjection/hooks so the shell never pretends its agent bundle took effect).
|
|
150
|
+
// ⚠️ Semantics = "the HTTP face accepts + forwards the field", NOT "every scenario honors it": scenarios
|
|
151
|
+
// without a delegation tool (scan/oa/…) fail-loud in core prepare (`config.agents.no_delegation_tool`) —
|
|
152
|
+
// a per-scenario projection needs the capability face to know the requested scenario (it doesn't; next batch).
|
|
59
153
|
taskAgents: deps.config.requirePrincipal !== true,
|
|
154
|
+
// [854]② body.retainBackgroundProcesses → TaskSpec.retainBackgroundProcesses: a resource-residency grant
|
|
155
|
+
// (task-end keeps session bg processes alive), single-user gate like backgroundShell/hooks — multi-tenant
|
|
156
|
+
// warns + ignores, advertised false here so the shell greys the affordance.
|
|
157
|
+
// ⚠️ Best-effort per env lifecycle: on an isolated env destroyed at task end (e2b/k8s/local-docker/ephemeral
|
|
158
|
+
// host) core skips retention (`ownedEnvDying`, dist-read) — the grant only means anything where the env outlives the task.
|
|
60
159
|
retainBackgroundProcesses: deps.config.requirePrincipal !== true,
|
|
160
|
+
// [922]①/[915]② core 1.296 interactiveTools 三态旋钮经 body 透传(per-run 工具面选择,无租户门)——
|
|
161
|
+
// 壳 capability 探测门用(旧 server 剥字段,壳 fail-soft 白发;此旗=真转发)。
|
|
61
162
|
interactiveTools: true,
|
|
163
|
+
// [#40 / TOC cwd seam] TRUE when this deployment HONORS a caller-supplied `cwd` (the agent's host workspace =
|
|
164
|
+
// the TOC launch dir) — only the single-user `host` lane (task-cwd.ts cwdHonored). FALSE on cloud/container
|
|
165
|
+
// lanes + multi-tenant (cwd ignored there) so the shell never pretends `sema` operates on the project dir.
|
|
166
|
+
// Also gates `body.additionalDirectories` (CC --add-dir, design/119) — SAME host-lane trust boundary (extra
|
|
167
|
+
// host paths the file tools may read), so one flag covers both project-context host seams (no fragmentation).
|
|
62
168
|
projectContext: cwdHonored(deps.config),
|
|
169
|
+
// [R3 / TOC MCP seam] TRUE when this deployment HONORS a caller-supplied `mcpServers` (the TOC local
|
|
170
|
+
// `.mcp.json`) — any SINGLE-USER deployment (task-mcp.ts mcpInjectionHonored = `requirePrincipal!==true`), on
|
|
171
|
+
// ANY execution lane. FALSE on multi-tenant (per-request MCP ignored) so the shell never pretends its `.mcp.json` took effect.
|
|
63
172
|
mcpInjection: mcpInjectionHonored(deps.config),
|
|
173
|
+
// E8 (shell-host contract): per-model usage echo on TaskStats.modelUsage — sourced from durable model_usage events,
|
|
174
|
+
// so it requires BOTH the durable run store AND the tracker that feeds them (a store-without-
|
|
175
|
+
// tracker deploy would otherwise lie). Absent either → the shell shows aggregate cost only.
|
|
64
176
|
modelUsage: Boolean(deps.runStore && deps.modelUsage),
|
|
177
|
+
// E11 (shell-host contract): GET /v1/sessions/:id/init startup bundle. Pure config assembly (model+mode), always
|
|
178
|
+
// served (no 501 path) — safe unconditionally, like policy:true.
|
|
65
179
|
sessionInit: true,
|
|
180
|
+
// E9 (shell-host contract): GET /v1/sessions/:id/mcp materializes MCP server status on demand. The route is always
|
|
181
|
+
// served (returns an empty panel when no MCP is configured), so the query capability is unconditional.
|
|
66
182
|
mcp: true,
|
|
183
|
+
// E23 (shell-host contract): inbound MCP elicitation HITL — true ONLY when the onElicit producing path is wired
|
|
184
|
+
// (MCP_ELICITATION_ENABLED), so "says yes but no-ops" is impossible. Per-server opt-in (McpServerSpec.
|
|
185
|
+
// elicitation, default OFF) is the second, orthogonal gate; this flag advertises the deployment capability.
|
|
186
|
+
// SCOPE: elicitation fires only on the streaming + durable run legs (POST /v1/tasks/stream, POST /v1/runs,
|
|
187
|
+
// and a durable resume) — a synchronous POST /v1/tasks, a verify/cascade attempt, and leader sub-tasks have
|
|
188
|
+
// no live stream to surface a prompt on, so an elicitation there fail-closed DECLINES (honest, not a hang).
|
|
67
189
|
mcpElicitation: Boolean(deps.elicitation),
|
|
190
|
+
// §4④: AskUserQuestion LIVE HITL — true ONLY when the onQuestion producing path is wired
|
|
191
|
+
// (ASK_QUESTION_ENABLED). Same SCOPE as mcpElicitation (streaming + durable legs; a synchronous /v1/tasks or a
|
|
192
|
+
// sub-task with no live stream headless-defaults — honest, not a hang). The durable-disconnected-human leg is
|
|
193
|
+
// always available (createDurableQuestionPolicy on the durable path), independent of this live capability.
|
|
68
194
|
askUserQuestion: Boolean(deps.question),
|
|
195
|
+
// [816]/[820]②: live tool-approval HITL — true ONLY when the onAsk producing path is wired
|
|
196
|
+
// (TOOL_APPROVAL_ENABLED). LIVE sync-stream leg only; since [879] G1 (OnAsk 三值化) every other leg
|
|
197
|
+
// (no ALS context / undeliverable card) returns "unavailable" → core durable-parks where a checkpoint
|
|
198
|
+
// exists, and only fail-closed denies without one ([819]⑤). The durable-approval leg (checkpoint park +
|
|
199
|
+
// /decide) is independent of this.
|
|
69
200
|
toolApproval: Boolean(deps.toolApproval),
|
|
201
|
+
// [1469] POST /v1/side-query(core 1.361 Runner.sideQuery 包装):一次性 brain 路由问答,无 session
|
|
202
|
+
// 副作用。恒可用(runner 自带)——探测位供壳判「引擎腿在」而非 trial-by-404。
|
|
70
203
|
sideQuery: true,
|
|
204
|
+
// E16/E17/E21 (§0.5 session-ownership): list/fork/delete are homed on the durable SESSION abstraction.
|
|
205
|
+
// Each flag is true ONLY when its PRODUCING path exists (never a bare const) — list needs an enumerator
|
|
206
|
+
// (session store OR legacy run-store aggregate), fork needs sessionStorage.fork, delete needs the
|
|
207
|
+
// purgeSession coordinator. Absent backend (in-memory dev) ⇒ false, so "says yes but 501s" can't happen.
|
|
71
208
|
sessionList: Boolean(deps.sessionStorage?.listSessions ?? deps.runStore?.listSessions),
|
|
72
|
-
sessionSearch: Boolean(deps.sessionStorage?.listSessions ?? deps.runStore?.listSessions),
|
|
209
|
+
sessionSearch: Boolean(deps.sessionStorage?.listSessions ?? deps.runStore?.listSessions), // GET /v1/sessions?q= (all lister backends carry it)
|
|
73
210
|
sessionFork: Boolean(deps.sessionStorage?.fork),
|
|
74
211
|
sessionDelete: Boolean(deps.purgeSession),
|
|
212
|
+
// E18 (shell-host contract): resume-at (rewind to a prior message). True ONLY when BOTH the eventId→entryId anchor map
|
|
213
|
+
// (resumeAnchorStore) AND the leaf-read path (sessionStorage.getLeafId, the §0.5 durable session abstraction)
|
|
214
|
+
// exist — so a `resumeAt` submit can be resolved + captured. "Says yes but 4xx/no-ops" is impossible. Works
|
|
215
|
+
// local + cloud (the anchor store is present on all backends); false only on the env-only/no-backend worker.
|
|
75
216
|
resumeAt: Boolean(deps.resumeAnchorStore && deps.sessionStorage?.getLeafId),
|
|
217
|
+
// E12 (shell-host contract): opt-in post-completion prompt suggestions (body.suggestNextPrompts → a `suggestions` event
|
|
218
|
+
// on the run's events tail). A core 1.128 runner feature, no store dependency → always available on a worker.
|
|
76
219
|
promptSuggestions: true,
|
|
220
|
+
// E6 (shell-host contract): operator-tightened per-session tool rules (PUT/GET /v1/sessions/:id/policy + core reads them
|
|
221
|
+
// at prepare-time, subtract-only). True when the durable/local SessionPolicyStore is wired.
|
|
77
222
|
sessionPolicy: Boolean(deps.sessionPolicyStore),
|
|
223
|
+
// E19 (shell-host contract): rewind-files (body.rewindFiles → snapshot per turn + restore on a resumeAt branch). core's
|
|
224
|
+
// gate-split (1.134.0) snapshots for ANY ExecutionEnv when fileSnapshotStore is wired (host/local-mode +
|
|
225
|
+
// e2b/k8s/ssh/adb/local-docker all active) → advertise whenever the store is wired.
|
|
78
226
|
rewindFiles: Boolean(deps.fileSnapshotStore),
|
|
227
|
+
// R8 code-only rewind (CC "Restore code", core 1.166 body.rewindFilesTo → restore files to a prior user message
|
|
228
|
+
// WITHOUT forking). Needs BOTH the snapshot store (to restore) AND the anchor map (to resolve the target handle),
|
|
229
|
+
// so it's the conjunction of `rewindFiles` and `resumeAt` — "says yes ⟺ the code-only submit resolves + restores".
|
|
79
230
|
rewindFilesTo: Boolean(deps.fileSnapshotStore && deps.resumeAnchorStore && deps.sessionStorage?.getLeafId),
|
|
231
|
+
// R7 自唤醒 (CC parity): the self-wake scheduler is LIVE — the host env exposes core's SchedulerCapability
|
|
232
|
+
// (CronCreate/CronDelete/CronList mount——L8 订正旧名) and the TOC shell daemon should run to fire due intents. True
|
|
233
|
+
// only on the single-user host lane with SCHEDULER_ENABLED (multi-tenant routes scheduling to center).
|
|
80
234
|
scheduler: Boolean(deps.config.schedulerEnabled && deps.config.requirePrincipal !== true && deps.config.remoteExec?.provider === "host"),
|
|
235
|
+
// 2c session-sync (P1d): the /v1/sessions/:id/sync/* peer routes (manifest/blobs/import/plan). True only when
|
|
236
|
+
// the whole backend + the entry export seam + a snapshot store are all wired (so export/import + blob transfer
|
|
237
|
+
// all resolve) — absent backend ⇒ false (the routes 501); "says yes ⟺ route works".
|
|
81
238
|
sessionSync: Boolean(deps.backend && deps.sessionStorage?.exportEntries && deps.fileSnapshotStore),
|
|
239
|
+
// SendUserFile(S3 双轨公网直链,契约 settled 2026-07-14):flag=READY 语义(F7 codex 审)——
|
|
240
|
+
// emitter 存在(=工具真挂载,lane/租户/签发面三门在 main.ts 已判)∧ 公网端点在场(publicEndpoint
|
|
241
|
+
// 缺席时 issue()/prepareDirectUpload() 一律 fail-loud,工具挂着也必失败)。"says yes ⟺ 调用真能
|
|
242
|
+
// 成功":只看 config.sendUserFile(签发面已配)会在工具缺席的形态(adb/local-docker lane、多租户
|
|
243
|
+
// host/ssh)假 yes(配置自查 agent 抓获 2026-07-14);只看 emitter 会在无公网端点时假 yes。
|
|
244
|
+
// s3PublicEndpoint=web 渲染/拼接要的公网 base(bootstrap 单一真源判决——server 透出,web 不猜、
|
|
245
|
+
// 不走 registry env 双源;工具挂不挂载它都照透——纯感知面,web 可提前接线)。
|
|
82
246
|
sendUserFile: Boolean(deps.sendUserFile && deps.config.sendUserFile?.publicEndpoint),
|
|
83
247
|
s3PublicEndpoint: deps.config.sendUserFile?.publicEndpoint ?? null,
|
|
248
|
+
// SendUserFile 账本(多租户治理面):true ⇔ 签发面已配 + store backend 在(记账写点活 + GET
|
|
249
|
+
// /v1/sendfile-links 可列)。false = env-only worker(不记账,读面 501)——诚实缺席。
|
|
84
250
|
sendUserFileLedger: Boolean(deps.sendFileLedger),
|
|
251
|
+
// K-2 (shell §K) — core ruling = SPLIT into two ORTHOGONAL axes so the shell gates each honestly:
|
|
252
|
+
// • `workflows` = ENGINE-CAN (can the engine self-orchestrate / run ultracode) = core's single-source
|
|
253
|
+
// `workflowsCapability(deps)` (hardened script runner ∧ governance), boot-computed in main.ts. Falls back
|
|
254
|
+
// to the `Boolean(workflowRunStore)` proxy when the boot flag isn't wired (older callers / tests).
|
|
255
|
+
// • `workflowsList` = can durably LIST workflow runs = `Boolean(workflowRunStore)` (GET /v1/workflows* 501s
|
|
256
|
+
// without it — list AND detail/stream, see the store gate ~L731).
|
|
257
|
+
// ⚠️ In the CURRENT service wiring these two COINCIDE: `workflowRunStore` is built IFF self-orchestration is on
|
|
258
|
+
// (InMemoryWorkflowRunStore when WORKFLOW_RUN_STORE=memory, else File — main.ts ~L527), the SAME gate that
|
|
259
|
+
// wires the safe script runner `workflowsCapability` checks → `Boolean(workflowRunStore)` ≡ `workflowsCapability`
|
|
260
|
+
// always today. So this split is core's FORWARD-LOOKING orthogonal-axes CONTRACT, NOT a fix for a live
|
|
261
|
+
// divergence (the earlier "memory backend → no store → divergence" framing was WRONG — InMemory IS a store;
|
|
262
|
+
// double-review caught it). It becomes load-bearing only if a future wiring decouples them (e.g. a run store
|
|
263
|
+
// present without a safe runner → engine-not-capable but listable). Both values are correct today.
|
|
85
264
|
workflows: deps.workflowsCapable ?? Boolean(deps.workflowRunStore),
|
|
86
265
|
workflowsList: Boolean(deps.workflowRunStore),
|
|
266
|
+
// K-1c (shell §K): manual /compact verb (POST /v1/runs/:id/compact → core 1.156 TaskStream.compact()). Needs
|
|
267
|
+
// the runs ledger (live-run lookup); advertise on runStore presence so the shell un-greys /compact only where
|
|
268
|
+
// the endpoint exists (it 409s for a non-live run, 501s without the store). core ≥1.156 guaranteed by the pin.
|
|
87
269
|
manualCompact: Boolean(deps.runStore),
|
|
88
270
|
});
|
|
89
271
|
return;
|
|
90
272
|
}
|
|
273
|
+
// Model catalog for consumers (e.g. OA's @-model autocomplete). NON-secret: names/capabilities
|
|
274
|
+
// only — never baseUrl/apiKey. `name` is the `@handle`; any of these may be @-mentioned. Source
|
|
275
|
+
// today = env-derived config.models; later the sema registry (sema-registry). The internal
|
|
276
|
+
// `default` alias is hidden (it's a fallback ref, not a user-pickable model).
|
|
91
277
|
if (req.method === "GET" && url === "/v1/models") {
|
|
92
278
|
const models = Object.entries(deps.config.models)
|
|
93
279
|
.filter(([name]) => name !== "default")
|
|
@@ -97,10 +283,25 @@ async function handleCapabilitiesBody(req, res, url, ctx, miss) {
|
|
|
97
283
|
provider: m.provider,
|
|
98
284
|
reasoning: m.reasoning,
|
|
99
285
|
vision: Array.isArray(m.input) ? m.input.includes("image") : false,
|
|
286
|
+
// E4 (shell-host contract): the context-window DENOMINATOR for the "% context used / N tokens until
|
|
287
|
+
// compact / low-context warning" gauge. Pure passthrough of the Model the service already holds
|
|
288
|
+
// (config.ts:603-604). Soft-degrade — omit when unknown (0) so the shell renders a raw token count
|
|
289
|
+
// without a %. The NUMERATOR (turn_end.usage.contextTokens) is core-blocked (SERVICE-GAP-DOSSIER §2 row 4);
|
|
290
|
+
// the denominator ships now with zero core dependency.
|
|
100
291
|
...(m.contextWindow ? { contextWindow: m.contextWindow } : {}),
|
|
101
292
|
...(m.maxTokens ? { maxOutputTokens: m.maxTokens } : {}),
|
|
293
|
+
// E7 (shell-host contract): the `/effort` picker's options. core's authoritative default tier set
|
|
294
|
+
// (DEFAULT_EFFORT_LEVELS = minimal/low/medium/high) for a reasoning model; omitted for a non-reasoning
|
|
295
|
+
// model (effort doesn't apply). The accept-set on a request is broader (any core ThinkingLevel) — this is
|
|
296
|
+
// the advertised picker default, not a hard allow-list.
|
|
102
297
|
...(m.reasoning ? { supportedEffortLevels: [...DEFAULT_EFFORT_LEVELS] } : {}),
|
|
103
298
|
}));
|
|
299
|
+
// [865]③ id/name 撕裂消解:`default` 历史上是 **id 形**(壳面板行 value 却是 name 形,壳侧只能打补丁
|
|
300
|
+
// 拼回)。additive 双给:`default` 保持 id 形字节不动(既有消费者),新 `defaultModel = { id, name }`
|
|
301
|
+
// 一次给全。name = 目录里与 config.model 同一实例的键("default" 别名除外;registry 未生效的 env 单模型
|
|
302
|
+
// 目录也可能无命中 → 退 id 匹配,再退 undefined 时省略 name)。
|
|
303
|
+
// 双程匹配(codex M1):先引用相等(applyEffective 后 config.model 与目录真身同实例——重复 id 目录下
|
|
304
|
+
// 唯一无歧义的判据),仅 env 单模型 lane 等无引用命中时才退 id 匹配(目录序第一,确定性)。
|
|
104
305
|
const nonAlias = Object.entries(deps.config.models).filter(([n]) => n !== "default");
|
|
105
306
|
const defaultName = (nonAlias.find(([, m]) => m === deps.config.model) ?? nonAlias.find(([, m]) => m.id === deps.config.model.id))?.[0];
|
|
106
307
|
sendJson(res, 200, { models, default: deps.config.model.id, defaultModel: { id: deps.config.model.id, ...(defaultName ? { name: defaultName } : {}) } });
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/158 A9 域模块 —— MF-Fleet 实时舰队流。
|
|
3
|
+
*
|
|
4
|
+
* 路由:`GET /v1/fleet/stream`(SSE PUSH:连上先快照,之后每条 per-row delta)。跑在服务凭据门**之前**
|
|
5
|
+
* (按 principal 自门,与 workflow 只读路由同列)。本域零可变状态。
|
|
6
|
+
*/
|
|
1
7
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
8
|
import type { RouteCtx } from "../route-ctx.js";
|
|
3
9
|
export declare function handleFleet(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
|
|
@@ -6,38 +6,79 @@ export async function handleFleet(req, res, url, ctx) {
|
|
|
6
6
|
await handleFleetBody(req, res, url, ctx, miss);
|
|
7
7
|
return !miss.fell;
|
|
8
8
|
}
|
|
9
|
+
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
10
|
+
* = 「本域已应答」;走到函数尾才是「没匹配上」。跨域的东西一律在首行解构出来。 */
|
|
9
11
|
async function handleFleetBody(req, res, url, ctx, miss) {
|
|
10
12
|
const { deps } = ctx;
|
|
11
13
|
const { sessionOwnerScope } = ctx.helpers;
|
|
12
|
-
void url;
|
|
14
|
+
void url; // 本域按 `req.url` 的完整 pathname 判路(带 query),`url` 只为域入口签名一致
|
|
15
|
+
// MF-Fleet (shell-host data contract): GET /v1/fleet/stream — the LIVE multi-row task/workflow fleet view as
|
|
16
|
+
// an SSE PUSH stream (status/elapsed/tokens/doneCount transitions over time). Owner-gated by scope (the
|
|
17
|
+
// caller's own active runs) UNLESS fleet-wide (a deployment trace/auth token sees every tenant's rows, like
|
|
18
|
+
// the trace API). Before the service-credential gate (self-gates by principal), parity with the workflow routes.
|
|
13
19
|
if (req.method === "GET" && new URL(req.url ?? "", "http://x").pathname === "/v1/fleet/stream") {
|
|
14
20
|
if (!deps.fleetBus) {
|
|
15
21
|
sendError(res, 501, "capability.self_orchestration_required", "fleet stream requires self-orchestration / fleet wiring");
|
|
16
22
|
return;
|
|
17
23
|
}
|
|
18
|
-
const { fleetWide } = sessionOwnerScope(req);
|
|
19
|
-
const principal = gatedPrincipal(req, deps.config);
|
|
24
|
+
const { fleetWide } = sessionOwnerScope(req); // trace-token / system authToken ⇒ fleet-wide (all tenants)
|
|
25
|
+
const principal = gatedPrincipal(req, deps.config); // direct-door-safe identity (NOT the spoofable header)
|
|
20
26
|
if (deps.config.requirePrincipal && !principal && !fleetWide) {
|
|
21
27
|
sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
|
|
22
28
|
return;
|
|
23
29
|
}
|
|
30
|
+
// #3 fleet per-session scope (clay 2026-06-30): the shell sends its current sessionId as `?session=` to see ONLY
|
|
31
|
+
// this session's rows (not other sessions of the same principal — the "他会话 token" leak). Absent ⇒
|
|
32
|
+
// unscoped (all of the principal's rows — back-compat).
|
|
33
|
+
// 🔴 cli[1524] HIGH-1(V5c 回归锁首跑抓获):此前 fleetWide 把 callerSession 也强制 null——无 auth
|
|
34
|
+
// 部署(isFleetWide 第一臂:无 token/无 traceToken/无 requirePrincipal=恒 fleetWide,TOC loopback
|
|
35
|
+
// 默认形全中)下会话过滤/通知 fail-closed 门整体旁路成全量广播,而 meta 的 bgNotifyFailClosed 照报
|
|
36
|
+
// true=标说谎;1.245 的注入 fail-closed 与 1.247 的代际标在默认部署从未真正生效(一直是壳侧台账
|
|
37
|
+
// 在兜)。修:fleetWide 是**能力上限**(可看全量=豁免 scope 授权轴),不是「强制 unscoped」——
|
|
38
|
+
// 显式带 `?session=` 的请求无论 fleetWide 与否都按会话过滤(观察者要全量=不带 session;要跟单
|
|
39
|
+
// 会话且不烧 durable 副本=带 session+observe=1,既有防烧口)。meta 的 sessionScoped 由此自动如实,
|
|
40
|
+
// bgNotifyFailClosed 对 session-bound 连接从此真实。
|
|
24
41
|
const fleetParams = new URL(req.url ?? "", "http://x").searchParams;
|
|
25
42
|
const callerSession = fleetParams.get("session");
|
|
43
|
+
// `?observe=1` = a session-bound lane that must NOT serve-fence the durable copy
|
|
44
|
+
// (a non-shell observer following one session). Default (absent) keeps the frame-即-投递 semantics —
|
|
45
|
+
// today's only session-bound consumer IS the model-injecting shell.
|
|
26
46
|
const observeOnly = fleetParams.get("observe") === "1";
|
|
27
47
|
await streamFleet(req, res, deps.fleetBus, fleetWide ? null : (principal ?? "default"), callerSession || null, observeOnly ? undefined : deps.workflowCompletionInbox);
|
|
28
48
|
return;
|
|
29
49
|
}
|
|
30
50
|
miss.fell = true;
|
|
31
51
|
}
|
|
52
|
+
/** MF-Fleet: SSE the live fleet (active task + workflow rows) — a SNAPSHOT on connect, then every per-row delta
|
|
53
|
+
* the {@link FleetEventBus} fans out. `callerScope === null` ⇒ fleet-wide (a trace/auth token sees all tenants);
|
|
54
|
+
* else owner-scoped (only rows whose `scope` matches). The tenant-internal `scope` field is STRIPPED from every
|
|
55
|
+
* emitted row (it's a gate input, never rendered). A removal is forwarded ONLY for a row this connection actually
|
|
56
|
+
* saw (no id-existence oracle for an unseen tenant's run). Heartbeat + dual-close cleanup unsubscribe the bus. */
|
|
32
57
|
function streamFleet(req, res, bus, callerScope, callerSession = null, completionInbox) {
|
|
33
58
|
return new Promise((resolve) => {
|
|
34
59
|
sseHeaders(res);
|
|
60
|
+
// [1508] 1.247 `bgNotifyFailClosed` — the GENERATION marker cli asked for ([1500]📌/[1502] F2): declares
|
|
61
|
+
// this server's bg_notification injection path fails CLOSED for scoped subscribers (1.245+ [1493] fix), so
|
|
62
|
+
// a new-generation shell can drop its frame-level own/foreign checks entirely (incl. the cross-shell
|
|
63
|
+
// restart edge) while keeping them against older servers whose meta lacks the field. Additive (version
|
|
64
|
+
// stays 1): older shells ignore unknown fields.
|
|
35
65
|
res.write(`event: meta\ndata: ${JSON.stringify({ version: 1, scoped: callerScope !== null, sessionScoped: callerSession !== null, bgNotifyFailClosed: true })}\n\n`);
|
|
36
66
|
const seenTasks = new Set();
|
|
37
67
|
const seenWf = new Set();
|
|
68
|
+
// #3 fleet per-session scope (clay 2026-06-30): a row is visible iff it matches the caller's principal scope AND
|
|
69
|
+
// — when the caller sent `?session=` — its `sessionId`. A row WITHOUT a sessionId stays visible (back-compat for
|
|
70
|
+
// unscoped rows); the leak this closes is a row whose sessionId is ANOTHER session of the same principal.
|
|
38
71
|
const sessionOk = (rowSession) => callerSession === null || rowSession === undefined || rowSession === callerSession;
|
|
39
72
|
const visT = (r) => (callerScope === null || r.scope === callerScope) && sessionOk(r.sessionId);
|
|
40
73
|
const visW = (r) => (callerScope === null || r.scope === callerScope) && sessionOk(r.sessionId);
|
|
74
|
+
// [1493] fable5 R1 (display plane): an UNATTRIBUTED row (no sessionId — restart lazy-mint / core version
|
|
75
|
+
// skew edges; post-Part-A every normal spawn is tagged) stays fail-open VISIBLE to a scoped subscriber
|
|
76
|
+
// (liveness back-compat: your own row after a restart still shows as running), but its content fields are
|
|
77
|
+
// conversation-derived text — `name` is the objective preview, `description`/`agentType`/`agentName` label
|
|
78
|
+
// the ask, `currentAction` is a live tool line. None of that may cross the session boundary, so a SCOPED
|
|
79
|
+
// subscriber gets a content-scrubbed projection (ids/status/progress/timing kept); a fleet-wide observer
|
|
80
|
+
// (trace/dashboard, callerSession === null) keeps the full row. Rows tagged with the caller's own session
|
|
81
|
+
// pass sessionOk and are never scrubbed (r.sessionId present ⇒ it equals callerSession here).
|
|
41
82
|
const stripT = (r) => {
|
|
42
83
|
const { scope: _s, sessionId: _sid, ...rest } = r;
|
|
43
84
|
if (callerSession !== null && r.sessionId === undefined) {
|
|
@@ -56,6 +97,7 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
|
|
|
56
97
|
};
|
|
57
98
|
const send = (event, data) => { if (!res.writableEnded)
|
|
58
99
|
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`); };
|
|
100
|
+
// connect-time snapshot (filtered + scope-stripped) — the visible rows become this connection's "seen" set.
|
|
59
101
|
const snap = bus.snapshot();
|
|
60
102
|
const tasks = snap.tasks.filter(visT);
|
|
61
103
|
const workflows = snap.workflows.filter(visW);
|
|
@@ -85,35 +127,81 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
|
|
|
85
127
|
send("workflow_remove", { id: frame.id, ts: frame.ts });
|
|
86
128
|
break;
|
|
87
129
|
case "hook_notice": {
|
|
130
|
+
// cli [1786]:一次 hook 判定**未能完成**的观测帧。可见性与 bg_notification **同为 fail-CLOSED** ——
|
|
131
|
+
// 一条关于**别人会话**的「这轮没看住」落到这个壳上,会让用户以为是自己这轮出了问题
|
|
132
|
+
// (而且 `/goal enforced` 面板会据此说一句不属于这个会话的话)。
|
|
133
|
+
// ⇒ scoped 订阅方只收能证明是自己的:`ownerSessionId === callerSession`;`undefined` ⇒ **丢弃**。
|
|
134
|
+
// fleet-wide 观察者(callerSession === null:trace/dashboard)照收。
|
|
88
135
|
const hn = frame.notice;
|
|
89
136
|
const hScopeOk = callerScope === null || hn.ownerScope === callerScope;
|
|
90
137
|
const hSessionOk = callerSession === null || hn.ownerSessionId === callerSession;
|
|
91
138
|
if (hScopeOk && hSessionOk) {
|
|
92
139
|
const { ownerScope: _hs, ownerSessionId: _hsid, ...wire } = hn;
|
|
140
|
+
// 与 bg_notification 同一帧契约:`type` 也放进 payload(壳的帧桥按 data.type 分派)。
|
|
93
141
|
send("hook_notice", { type: "hook_notice", ...wire, ts: frame.ts });
|
|
94
142
|
}
|
|
95
143
|
break;
|
|
96
144
|
}
|
|
97
145
|
case "bg_notification": {
|
|
146
|
+
// design/129-B 缺口②(帧契约): a bg child's completion pushed on THIS always-open lane — the
|
|
147
|
+
// idle shell renders the receipt immediately (no more one-input-cycle durable-drain lag). Visibility:
|
|
148
|
+
// tenant filter on ownerScope (same rule as rows; a notification without one is operator/fleet-wide
|
|
149
|
+
// visible only — fail-closed for scoped callers) + `?session=` on ownerSessionId (the HOST session;
|
|
150
|
+
// the payload sessionId is the CHILD's uuid — the contract's stable anchor — and never matches the caller's).
|
|
98
151
|
const n = frame.notification;
|
|
99
152
|
const scopeOk = callerScope === null || n.ownerScope === callerScope;
|
|
153
|
+
// [1493] fail-CLOSED on the MODEL-INJECTION path. bg_notification is auto-injected into the idle
|
|
154
|
+
// shell's model (the receipt drives the LLM's next turn). Unlike the display rows — whose absent-
|
|
155
|
+
// session `sessionOk` stays fail-OPEN for back-compat (an untagged row is at worst visible, never
|
|
156
|
+
// actionable) — an untagged completion delivered to a SCOPED subscriber would inject a DIFFERENT
|
|
157
|
+
// session's result into this shell's model (clay's dual-shell repro: two shells sharing one engine +
|
|
158
|
+
// principal). So a scoped caller (callerSession !== null) receives a completion ONLY when it is
|
|
159
|
+
// provably its own: ownerSessionId === callerSession. undefined ⇒ NOT proven ⇒ dropped. A fleet-wide
|
|
160
|
+
// observer (callerSession === null: trace/dashboard) still sees everything. Part A (fleet-bus) is what
|
|
161
|
+
// populates ownerSessionId for the legit owner so this gate delivers to it and drops only strangers.
|
|
100
162
|
const sessionInjectOk = callerSession === null || n.ownerSessionId === callerSession;
|
|
101
163
|
if (scopeOk && sessionInjectOk) {
|
|
102
164
|
const { ownerScope: _os, ownerSessionId: _osid, ...wire } = n;
|
|
165
|
+
// The frame contract puts `type:'bg_notification'` INSIDE the object (the shell's frame
|
|
166
|
+
// bridge dispatches on data.type, not only the SSE event name) — carry it in the payload too.
|
|
103
167
|
send("bg_notification", { type: "bg_notification", ...wire, ts: frame.ts });
|
|
168
|
+
// The frame IS the delivery when it reaches the OWNING shell's session-bound lane —
|
|
169
|
+
// serve-fence the durable park (both orders hold: an already-parked entry is acked; a park landing
|
|
170
|
+
// AFTER this is refused by the serve fence) so the next stream-open drain can't re-inject the same
|
|
171
|
+
// completion into the model (the engine-side steer-inject double the shell cannot dedup — the
|
|
172
|
+
// 129-bg variant of that double-injection class, proven from real session logs). ONLY a `?session=`-bound subscriber counts: a fleet-wide
|
|
173
|
+
// dashboard consuming the frame must NOT burn the owning shell's durable copy — the park keeps its
|
|
174
|
+
// offline/no-active-lane semantics. Keys line up by contract: frame taskId = BackgroundChildEvent
|
|
175
|
+
// .taskId = the a*-domain registry handle (stable across kinds) = the parked entry's
|
|
176
|
+
// runId (leg onTaskNotification's n.task_id, same domain); ownerSessionId = HOST session = entry key.
|
|
177
|
+
// design/144 键升级:park 键=域:taskId:status[#seq],fleet 帧不带 seq → 传家族前缀
|
|
178
|
+
// (taskNotificationFoldKey 无 seq 形),markTerminalServed 家族 ack 清同族 seq 键成员。
|
|
179
|
+
// PAIR-REVIEW F-2:mark 延至 **write flush 回调** + socket 存活双检——「res.write 已调用」≠投递
|
|
180
|
+
// (对端已断本端未感知的窗口里,帧写进死 socket 而 durable 副本被烧=通知永丢,1.334 教训)。
|
|
181
|
+
// flush 回调=数据出到内核缓冲(尽力而为的最强本端信号;真端到端 ack 需协议位,另议),回调时
|
|
182
|
+
// 再验 socket.destroyed——断连时 Node 会先触发 destroy,此时不 ack,park 副本留给下次开流 drain。
|
|
183
|
+
// fence 的防双注入语义不变(已 ack 的重复帧仍被拒),只推迟 ack 时点。
|
|
104
184
|
if (completionInbox && n.ownerSessionId && callerSession !== null && callerSession === n.ownerSessionId && !res.writableEnded) {
|
|
105
185
|
const ownerSid = n.ownerSessionId;
|
|
186
|
+
// codex R1-H1(修车批):帧带 seq(1.239/core 1.352)→ **精确键** ack(servedAt 只 fence 该
|
|
187
|
+
// 周期;revive 周期 N+1 的 park/enqueue 不被连坐)。legacy 无 seq 帧保持家族键 ack(原语义)。
|
|
106
188
|
const family = taskNotificationFoldKey({ task_id: n.taskId, status: n.status, ...(n.seq !== undefined ? { seq: n.seq } : {}) });
|
|
189
|
+
// codex R2-H1(server belt):revive 周期的 park 键在 **uuid 域**(core ≤1.353 的 revive 通知
|
|
190
|
+
// task_id=childSessionId,subagent.js:598/655——identity 对齐转 core 在单),帧键在 a\* 域——
|
|
191
|
+
// 单键 ack 必 miss=开流二次注入。帧带 sessionId(uuid 别名)时**双域各 ack 一次**,两种 core
|
|
192
|
+
// 版本的 park 键都被 fence 住;core 修齐后 uuid 臂自然空转(无同键 park,无害)。
|
|
107
193
|
const familyUuid = n.sessionId !== undefined && n.sessionId !== n.taskId
|
|
108
194
|
? taskNotificationFoldKey({ task_id: n.sessionId, status: n.status, ...(n.seq !== undefined ? { seq: n.seq } : {}) })
|
|
109
195
|
: undefined;
|
|
110
196
|
const ackIfAlive = () => {
|
|
111
197
|
if (res.writableEnded || res.socket?.destroyed)
|
|
112
|
-
return;
|
|
198
|
+
return; // 死连接:不烧 durable 副本
|
|
113
199
|
void completionInbox.markTerminalServed(ownerSid, family).catch(() => undefined);
|
|
114
200
|
if (familyUuid !== undefined)
|
|
115
201
|
void completionInbox.markTerminalServed(ownerSid, familyUuid).catch(() => undefined);
|
|
116
202
|
};
|
|
203
|
+
// res.write 的 flush 回调在上面 send() 内不可达(send 不透传 cb)——补一个零字节注释帧承载回调:
|
|
204
|
+
// SSE 注释行(`: ack\n\n`)对消费者不可见(SDK 吞注释),flush 语义等同。
|
|
117
205
|
res.write(`: ack
|
|
118
206
|
|
|
119
207
|
`, ackIfAlive);
|
|
@@ -122,9 +210,10 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
|
|
|
122
210
|
break;
|
|
123
211
|
}
|
|
124
212
|
default:
|
|
125
|
-
break;
|
|
213
|
+
break; // snapshot frames are connect-time only, never fanned out
|
|
126
214
|
}
|
|
127
215
|
});
|
|
216
|
+
// Real frame (not an SSE comment) — a per-frame-parsing BFF drops comments (zero-frame window downstream)
|
|
128
217
|
const hb = setInterval(() => { if (!res.writableEnded)
|
|
129
218
|
res.write(`event: heartbeat\ndata: {}\n\n`); }, 15_000);
|
|
130
219
|
if (typeof hb.unref === "function")
|