@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
|
@@ -4,21 +4,35 @@ import { redactSecrets } from "../../trace/redact.js";
|
|
|
4
4
|
import { HEARTBEAT_MS } from "../../runs.js";
|
|
5
5
|
import { sendJson, sendError, sseHeaders } from "../send.js";
|
|
6
6
|
import { gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
|
|
7
|
-
const WORKFLOWS_RE = /^\/v1\/workflows(?:\/([^/]+)(\/stream|\/journal)?)?$/;
|
|
7
|
+
const WORKFLOWS_RE = /^\/v1\/workflows(?:\/([^/]+)(\/stream|\/journal)?)?$/; // S8 self-orchestration runs: list / detail / live SSE
|
|
8
|
+
// SVC-5 (design/97 CORE-5 #6): steer a STILL-RUNNING workflow agent (ctx.agentStream) by runId + label. POST-only,
|
|
9
|
+
// so it never collides with the GET WORKFLOWS_RE above. The label is a non-slash segment (core mints `agent-N`
|
|
10
|
+
// for an unlabelled agent, else the caller's opts.label) — URL-decoded by the handler.
|
|
8
11
|
const WORKFLOW_AGENT_STEER_RE = /^\/v1\/workflows\/([^/]+)\/agents\/([^/]+)\/steer$/;
|
|
9
12
|
export async function handleWorkflows(req, res, url, ctx) {
|
|
10
13
|
const miss = { fell: false };
|
|
11
14
|
await handleWorkflowsReadBody(req, res, url, ctx, miss);
|
|
12
15
|
return !miss.fell;
|
|
13
16
|
}
|
|
17
|
+
/** SVC-5 的 steer 路——`handle()` 里位置在 tasks/runs 之后(鉴权门之后),故是**独立**的域入口。 */
|
|
14
18
|
export async function handleWorkflowAgentSteer(req, res, url, ctx) {
|
|
15
19
|
const miss = { fell: false };
|
|
16
20
|
await handleWorkflowAgentSteerBody(req, res, url, ctx, miss);
|
|
17
21
|
return !miss.fell;
|
|
18
22
|
}
|
|
23
|
+
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
24
|
+
* = 「本域已应答」;走到函数尾才是「没匹配上」。跨域的东西一律在首行解构出来。 */
|
|
19
25
|
async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
20
26
|
const { deps } = ctx;
|
|
21
27
|
const { runSessionAcceptOk } = ctx.helpers;
|
|
28
|
+
// S8 self-orchestration runs (design/97/98): GET /v1/workflows (list) · /v1/workflows/:id (detail) ·
|
|
29
|
+
// /v1/workflows/:id/stream (live SSE). OWNER-GATED by scope (= the creating principal, prepare-task.js
|
|
30
|
+
// scope: spec.principal). list/detail need the run store; live stream is in-process (subscribeWorkflow).
|
|
31
|
+
// 🔐 Identity from gatedPrincipal (direct-door-secure single point — crypto-verified principal JWT when
|
|
32
|
+
// directDoorActive, transparently `principalFrom` otherwise), NEVER the spoofable x-agent-principal header:
|
|
33
|
+
// a direct-door worker MUST NOT trust the raw header for a per-tenant owner gate (same bypass class —
|
|
34
|
+
// parity with the trace owner-gate, the workflow steer POST, and the elicit route). This block returns BEFORE
|
|
35
|
+
// the service-credential gate below, so the per-tenant gate here is the sole tenant boundary for these reads.
|
|
22
36
|
const wfMatch = req.method === "GET" ? WORKFLOWS_RE.exec(url) : null;
|
|
23
37
|
if (wfMatch) {
|
|
24
38
|
const principal = gatedPrincipal(req, deps.config);
|
|
@@ -30,19 +44,29 @@ async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
|
30
44
|
sendError(res, 501, "capability.self_orchestration_required", "workflow runs require self-orchestration (SELF_ORCHESTRATION_ENABLED)");
|
|
31
45
|
return;
|
|
32
46
|
}
|
|
33
|
-
const scope = principal ?? "default";
|
|
47
|
+
const scope = principal ?? "default"; // matches core's run_workflow scope = spec.principal ?? "default"
|
|
34
48
|
const wfId = wfMatch[1];
|
|
35
49
|
const isStream = wfMatch[2] === "/stream";
|
|
36
50
|
if (!wfId) {
|
|
37
51
|
const q = new URL(req.url ?? "", "http://x").searchParams;
|
|
38
52
|
const statusFilter = q.get("status");
|
|
39
53
|
const limit = Math.min(100, Math.max(1, Number(q.get("limit") ?? 50) || 50));
|
|
54
|
+
// [1512]§二 交付件接线(1.247 留的 list 缺口):`?session=` 过滤臂 —— present 即按
|
|
55
|
+
// `originatingSessionId` 严格等值筛。语义是**筛选**非 per-id 的接受拍:无字段行(pre-core-1.210)
|
|
56
|
+
// 不属于任何会话,筛选下剔除(per-id 面的 absent 放行是访问控制防误伤,两面语义刻意不同);
|
|
57
|
+
// 空串=无行可匹配=空列表;absent = 全量,字节不变。1.250:筛下推 store 侧(core 1.368 [1516]②
|
|
58
|
+
// `listByScope.opts.session`,limit **前**应用)——1.249 的「页内筛」升「全量筛」,忙 scope 下
|
|
59
|
+
// 比 newest-limit 窗口更老的会话行不再漏。直调 store(listWorkflowRuns 是纯透传,其 opts 类型
|
|
60
|
+
// 未收录 session)。
|
|
40
61
|
const sessionFilter = q.get("session");
|
|
41
62
|
const sessionRuns = await deps.workflowRunStore.listByScope(scope, {
|
|
42
63
|
...(statusFilter ? { status: statusFilter } : {}),
|
|
43
64
|
limit,
|
|
44
65
|
...(sessionFilter !== null ? { session: sessionFilter } : {}),
|
|
45
66
|
});
|
|
67
|
+
// K-2c LIST side (core 1.155 `WorkflowRunSummary` now carries name?/description?/currentPhase? from the
|
|
68
|
+
// script `meta` — flows via the pin bump): redact the LLM-authored label surfaces for parity with the DETAIL
|
|
69
|
+
// route (summarizeWorkflowDetail) + the fleet rows. The rest of the summary (status/counts/stats) rides as-is.
|
|
46
70
|
const redacted = sessionRuns.map((r) => ({
|
|
47
71
|
...r,
|
|
48
72
|
...(r.name !== undefined ? { name: redactSecrets(r.name) } : {}),
|
|
@@ -52,18 +76,33 @@ async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
|
52
76
|
sendJson(res, 200, { workflows: redacted });
|
|
53
77
|
return;
|
|
54
78
|
}
|
|
79
|
+
// per-id: owner-gate via the persisted run's scope (no existence oracle for non-owners → 404). 1.146:
|
|
80
|
+
// getWorkflowRun is scope-filtered IN CORE (returns null unless run.scope === scope) — defense-in-depth on
|
|
81
|
+
// top of our route gate; the `run.scope !== scope` below is now redundant but kept (belt-and-suspenders).
|
|
82
|
+
// The SSE branch streams ONLY after this gate, so the live stream is owner-gated too (core's subscribeWorkflow
|
|
83
|
+
// does not self-filter — this gate is its tenant boundary).
|
|
55
84
|
const run = await getWorkflowRun(deps.workflowRunStore, wfId, scope);
|
|
56
85
|
if (!run || run.scope !== scope) {
|
|
57
86
|
sendError(res, 404, "not_found.workflow", "workflow not found");
|
|
58
87
|
return;
|
|
59
88
|
}
|
|
89
|
+
// [1508] 1.247 — session ACCEPT phase on the workflow per-id faces ([1493]-class sibling: these deliver
|
|
90
|
+
// conversation-derived content — step prompts/outputs/live events — but were principal-gated only, while
|
|
91
|
+
// the durable WorkflowRun carries `originatingSessionId` since core 1.210). Same soft phase + helper as
|
|
92
|
+
// the run faces (present-mismatch → 404; absent → warn-once). The LIST face is NOT gated this拍:
|
|
93
|
+
// WorkflowRunSummary lacks the field (core ask, γ-batch alignment) — its rows stay redacted summaries.
|
|
60
94
|
if (!runSessionAcceptOk(req, res, { sessionId: run.originatingSessionId ?? null }, wfMatch[2] === "/journal" ? "workflow.journal" : isStream ? "workflow.stream" : "workflow.detail", "workflow not found"))
|
|
61
95
|
return;
|
|
62
96
|
if (wfMatch[2] === "/journal") {
|
|
97
|
+
// [1402]/[1400]④:per-agent journal 读面(云本地同构——三后端店同契约)。owner 门已过(上方 run
|
|
98
|
+
// scope 校验);投影=bounded+redact(result 是 LLM 产物,注入面纪律同 fleet 行),ordinal 序稳定。
|
|
63
99
|
if (!deps.workflowJournalStore) {
|
|
64
100
|
sendError(res, 501, "capability.workflow_store_required", "workflow journal requires the journal store (SELF_ORCHESTRATION_ENABLED + a store backend)");
|
|
65
101
|
return;
|
|
66
102
|
}
|
|
103
|
+
// codex R1-H2:hard bounds——limit 默认 20 cap 50(?limit=)、?offset= 游标;SQL 店走 loadPage
|
|
104
|
+
// (行数 LIMIT/OFFSET + 单行 64KiB LENGTH 门在库端,峰值 ≤50×64KiB);file/in-memory 店(单机形)
|
|
105
|
+
// 回落全量 load 后同界投影(内存峰值=店内容,记档取舍)。
|
|
67
106
|
const jq = new URL(req.url ?? "", "http://x").searchParams;
|
|
68
107
|
const jLimit = Math.min(50, Math.max(1, Number(jq.get("limit") ?? 20) || 20));
|
|
69
108
|
const jOffset = Math.max(0, Number(jq.get("offset") ?? 0) || 0);
|
|
@@ -83,6 +122,7 @@ async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
|
83
122
|
const page = await js.loadPage(wfId, scope, { offset: jOffset, limit: jLimit, maxResultBytes: MAX_ROW_BYTES });
|
|
84
123
|
projected = page.map((row) => {
|
|
85
124
|
if (row.resultJson === null) {
|
|
125
|
+
// 超单行门的条目:诚实标 truncated,不把 64KiB+ 的 TaskResult 拉进进程
|
|
86
126
|
return { callKey: row.callKey, ordinal: callKeyOrdinal(row.callKey), truncated: true, resultBytes: row.resultBytes };
|
|
87
127
|
}
|
|
88
128
|
try {
|
|
@@ -94,6 +134,9 @@ async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
|
94
134
|
});
|
|
95
135
|
}
|
|
96
136
|
else {
|
|
137
|
+
// fallback(file/in-memory,单机 TOC 形——多租户 durable 恒 SQL 店=loadPage 覆盖):load 全量的
|
|
138
|
+
// 内存/事件环成本=用户读自己盘的单机取舍(ARCHITECTURE.md 记档);投影侧与 SQL 店**同一诚实
|
|
139
|
+
// 语义**——超 64KiB 的行标 truncated/resultBytes,不做静默 2000 字投影(跨后端 API 形一致)。
|
|
97
140
|
const entries = await deps.workflowJournalStore.load(wfId, scope);
|
|
98
141
|
projected = entries
|
|
99
142
|
.sort((a, b) => callKeyOrdinal(a.callKey) - callKeyOrdinal(b.callKey))
|
|
@@ -109,35 +152,57 @@ async function handleWorkflowsReadBody(req, res, url, ctx, miss) {
|
|
|
109
152
|
return;
|
|
110
153
|
}
|
|
111
154
|
if (isStream)
|
|
112
|
-
await streamWorkflowRun(req, res, wfId, scope);
|
|
155
|
+
await streamWorkflowRun(req, res, wfId, scope); // core 1.366 B-3: scope-doored live stream(异 scope=空流,与不存在同形)
|
|
113
156
|
else
|
|
114
|
-
sendJson(res, 200, summarizeWorkflowDetail(run));
|
|
157
|
+
sendJson(res, 200, summarizeWorkflowDetail(run)); // SVC-4: structured drill-down (Phases panel + agent list + groups tree)
|
|
115
158
|
return;
|
|
116
159
|
}
|
|
117
160
|
miss.fell = true;
|
|
118
161
|
}
|
|
162
|
+
/** 同上纪律(SVC-5 steer 段)。 */
|
|
119
163
|
async function handleWorkflowAgentSteerBody(req, res, url, ctx, miss) {
|
|
120
164
|
const { deps } = ctx;
|
|
121
165
|
const { readJson, rateLimited, quotaExceeded, leaseDenied, safeDecode, runSessionAcceptOk } = ctx.helpers;
|
|
166
|
+
// SVC-5 (design/97 CORE-5 #6): POST /v1/workflows/:id/agents/:label/steer — STEER a still-running workflow
|
|
167
|
+
// agent (`ctx.agentStream`) mid-flight. Unlike RUN steer (a whole task run), this targets ONE running agent
|
|
168
|
+
// inside a workflow, addressed by runId + label. Delivery is replica-local (the steerable handle is an
|
|
169
|
+
// in-memory bridge to the running TaskStream, like `steerableRuns`):
|
|
170
|
+
// • the handle is live on THIS replica → `handle.steer(redacted)` injects + returns the marker → 200.
|
|
171
|
+
// • not here but the workflow run is `running` (another replica) → 409 steering.not_running (cross-replica
|
|
172
|
+
// live-steer is the same fast-follow seam as RUN steer — single-replica-per-worker today; honest, never
|
|
173
|
+
// a silent drop). • terminal / no handle → 409 steering.not_running.
|
|
174
|
+
// 🔴 HANDLE-VISIBILITY SEAM: core returns a WorkflowAgentHandle ONLY from `WorkflowRunContext.agentStream`,
|
|
175
|
+
// and that host ctx structurally never enters the script runner (the LLM workflow sees the sterile
|
|
176
|
+
// `WorkflowPrimitives`, which has `agent` but not `agentStream`). The service runs workflows ONLY via core's
|
|
177
|
+
// `run_workflow` tool → primitives, so it never holds a handle to register. The registry/redaction/auth here
|
|
178
|
+
// are production-real (the populated path uses them unchanged); until core hands the deployment the handle
|
|
179
|
+
// (e.g. an onAgentStream lifecycle sink on run_workflow), the registry is genuinely empty and the route
|
|
180
|
+
// returns steering.not_running. See workflow-agent-steer.ts. Raised to core (SVC-5).
|
|
122
181
|
const wfSteerMatch = req.method === "POST" ? WORKFLOW_AGENT_STEER_RE.exec(url) : null;
|
|
123
182
|
if (wfSteerMatch) {
|
|
124
183
|
if (rateLimited(req, res) || quotaExceeded(req, res) || (await leaseDenied(req, res)))
|
|
125
|
-
return;
|
|
184
|
+
return; // mutating + steers a running model agent
|
|
126
185
|
if (!deps.workflowRunStore) {
|
|
127
186
|
sendError(res, 501, "capability.self_orchestration_required", "workflow runs require self-orchestration (SELF_ORCHESTRATION_ENABLED)");
|
|
128
187
|
return;
|
|
129
188
|
}
|
|
189
|
+
// Identity from gatedPrincipal (direct-door-secure single point), NEVER the spoofable header — `trusted`
|
|
190
|
+
// carries operator authority (a supervisor steering any tenant's agent), so deriving it from a header would
|
|
191
|
+
// be a privilege escalation (parity with RUN steer / preempt; HANDOFF 铁律 + core §3 inv #1).
|
|
130
192
|
const principal = gatedPrincipal(req, deps.config);
|
|
131
193
|
if (deps.config.requirePrincipal && principal === undefined) {
|
|
132
194
|
sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
|
|
133
195
|
return;
|
|
134
196
|
}
|
|
197
|
+
// safeDecode (not bare decodeURIComponent): a malformed %-sequence is the CALLER's error → 400, not a 500
|
|
198
|
+
// (parity with the approvals + session-sync routes' established handling).
|
|
135
199
|
const wfRunId = safeDecode(wfSteerMatch[1]);
|
|
136
200
|
const label = safeDecode(wfSteerMatch[2]);
|
|
137
201
|
if (wfRunId === null || label === null) {
|
|
138
202
|
sendError(res, 400, "request.path_malformed", "malformed workflow path (invalid percent-encoding)");
|
|
139
203
|
return;
|
|
140
204
|
}
|
|
205
|
+
// Parse + validate the body BEFORE the run lookup (a bad body is the caller's error regardless of state).
|
|
141
206
|
let body;
|
|
142
207
|
try {
|
|
143
208
|
body = (await readJson(req));
|
|
@@ -150,21 +215,43 @@ async function handleWorkflowAgentSteerBody(req, res, url, ctx, miss) {
|
|
|
150
215
|
sendError(res, 400, "request.body_shape", "body must be { content: string (non-empty) }");
|
|
151
216
|
return;
|
|
152
217
|
}
|
|
218
|
+
// 入参上限(见 `STEER_IN_MAX_REQUEST_CHARS` 旁注):脱敏门是**同步**的,烧的是事件循环 ⇒
|
|
219
|
+
// 一次超大 steer 卡住的是**整个副本**。**拒**而不是服务端先截 —— 先截会让引擎的
|
|
220
|
+
// `[+N chars]` 披露低报,而"诚实标记不得低报"是本仓另一条钉守着的性质。
|
|
153
221
|
if (body.content.length > STEER_IN_MAX_REQUEST_CHARS) {
|
|
154
222
|
sendError(res, 413, "steer.content_too_large", `content exceeds ${STEER_IN_MAX_REQUEST_CHARS} characters (got ${body.content.length}); note only the first ${STEER_IN_MAX_CHARS} are delivered anyway`);
|
|
155
223
|
return;
|
|
156
224
|
}
|
|
225
|
+
// trusted = explicit operator (NOT bare isOperator — its empty-list "true-for-all" would let any caller
|
|
226
|
+
// steer any tenant's agent). A normal owner steers only their own workflow.
|
|
157
227
|
const trusted = explicitOperatorOk(principal, deps.config.operatorPrincipals);
|
|
158
|
-
const ownerScope = principal ?? "default";
|
|
228
|
+
const ownerScope = principal ?? "default"; // matches run_workflow scope = spec.principal ?? "default"
|
|
229
|
+
// Owner-gate via the persisted run, now scope-filtered IN CORE (1.146 getWorkflowRun(store, id, scope) →
|
|
230
|
+
// null unless run.scope === scope). For a NON-operator: a missing/other-tenant run is null → 404 (no
|
|
231
|
+
// existence oracle). An explicit OPERATOR (supervisor) may steer ANY tenant's workflow — but core's
|
|
232
|
+
// scope-filtered read can't fetch another tenant's run by the operator's own scope (→ null), so the operator
|
|
233
|
+
// is NOT gated on `wfRun` existence: its authority is the operator allowlist, and the steer target's
|
|
234
|
+
// existence+liveness is proven by the registry handle below (no handle → 409, never a wrong-tenant steer).
|
|
159
235
|
const wfRun = await getWorkflowRun(deps.workflowRunStore, wfRunId, ownerScope);
|
|
160
236
|
if (!trusted && !wfRun) {
|
|
161
237
|
sendError(res, 404, "not_found.workflow", "workflow not found");
|
|
162
238
|
return;
|
|
163
239
|
}
|
|
240
|
+
// [1508] 1.247 — same session accept-phase as the read faces (a steer ACTS on the conversation's
|
|
241
|
+
// workflow). Gated on the fetched run only: the operator leg (wfRun null by scope-filtered read) keeps
|
|
242
|
+
// its registry-handle-proven authority below, and runSessionAcceptOk's operator branch covers a
|
|
243
|
+
// same-scope operator anyway.
|
|
164
244
|
if (wfRun && !runSessionAcceptOk(req, res, { sessionId: wfRun.originatingSessionId ?? null }, "workflow.agent-steer", "workflow not found"))
|
|
165
245
|
return;
|
|
166
246
|
const sendNotRunningWf = (error) => sendError(res, 409, "steering.not_running", error);
|
|
247
|
+
// STEER-IN REDACTION GATE (SVC-5 信任门): treat the human/leader content as UNTRUSTED — redact host leaks +
|
|
248
|
+
// size-bound + fence — BEFORE it reaches the worker. core's `handle.steer` fences AGAIN inside its trusted
|
|
249
|
+
// marker framing (defense in depth). Applied regardless of `trusted`: an operator's copy-pasted steer can
|
|
250
|
+
// still leak a host path/token, and an authoritative-looking steer must not pose as system instructions.
|
|
167
251
|
const redacted = redactSteerIn(body.content, label);
|
|
252
|
+
// Same-replica live path: the steerable handle is registered here → inject now, return the marker.
|
|
253
|
+
// core does not enforce label uniqueness within a run, so resolve() reports the count: >1 = two live agents
|
|
254
|
+
// share this label → the target is ambiguous, refuse (409) rather than steer an arbitrary one.
|
|
168
255
|
const resolution = deps.workflowAgentRegistry?.resolve(wfRunId, label);
|
|
169
256
|
if (resolution && resolution.count > 1) {
|
|
170
257
|
sendError(res, 409, "steering.ambiguous_label", `${resolution.count} live agents share label '${label}' in this run — steer target is ambiguous`);
|
|
@@ -179,13 +266,18 @@ async function handleWorkflowAgentSteerBody(req, res, url, ctx, miss) {
|
|
|
179
266
|
}
|
|
180
267
|
catch (e) {
|
|
181
268
|
const code = e.code;
|
|
269
|
+
// The agent settled between the registry lookup and steer() → core rejects steering.not_running.
|
|
182
270
|
if (code === "steering.not_running") {
|
|
183
271
|
sendNotRunningWf("agent just finished — no longer accepting steers");
|
|
184
272
|
return;
|
|
185
273
|
}
|
|
186
|
-
throw e;
|
|
274
|
+
throw e; // unexpected → outer handler 500
|
|
187
275
|
}
|
|
188
276
|
}
|
|
277
|
+
// No live handle here. The workflow run is either terminal, or `running` on another replica (cross-replica
|
|
278
|
+
// live-steer = the same fast-follow seam as RUN steer; a workflow agent is in-memory steerable only on its
|
|
279
|
+
// running replica). Either way: honest 409, never a silent drop. `wfRun` may be null for an OPERATOR steering
|
|
280
|
+
// a cross-tenant run (core's scope-filtered read returned null) → a generic message (status unknowable here).
|
|
189
281
|
sendNotRunningWf(!wfRun
|
|
190
282
|
? "workflow agent is not running on this replica (no live handle)"
|
|
191
283
|
: wfRun.status === "running"
|
|
@@ -195,14 +287,37 @@ async function handleWorkflowAgentSteerBody(req, res, url, ctx, miss) {
|
|
|
195
287
|
}
|
|
196
288
|
miss.fell = true;
|
|
197
289
|
}
|
|
290
|
+
/** SVC-4 v1 — the STRUCTURED drill-down view of one persisted {@link WorkflowRun} (the historical detail the
|
|
291
|
+
* Phases panel + agent list + groups tree render, parity with CC's Workflow tool). Pure projection over the
|
|
292
|
+
* persisted run — no new source of truth, no gate input (the route already owner-gated by scope before this).
|
|
293
|
+
* Three derived shapes:
|
|
294
|
+
* - `phases`: each `run.phases` entry + a done/total of the agents that ran under that `phase` title (done =
|
|
295
|
+
* terminal status). Plus an `unphased` bucket counting agents with no phase.
|
|
296
|
+
* - `agents`: each agent flattened to `{ label, status, callKey, groupId, phase, tokens, turns, durationMs,
|
|
297
|
+
* replayed, prompt, output }`. `prompt`/`output` are core-redacted + size-bounded; this is a HUMAN view so
|
|
298
|
+
* they are surfaced AT REST WITHOUT a fence (a consumer that re-feeds them to an LLM must fence itself —
|
|
299
|
+
* core's `WorkflowAgentRun` doc). `tokens`/`turns`/`costMicroUsd` come from the agent's own `stats`.
|
|
300
|
+
* - `groups`: the nested tree rebuilt from `run.groups` (parentGroupId) — each node carries its direct agent
|
|
301
|
+
* callKeys so a UI can hang the agent list off the tree. Empty when the script used no `ctx.workflow` nesting.
|
|
302
|
+
* `stats` (own + nested, kept separate per core R-5) and the run-level fields pass through unchanged. */
|
|
198
303
|
function summarizeWorkflowDetail(run) {
|
|
199
304
|
const isDone = (s) => s === "completed" || s === "failed";
|
|
305
|
+
// MF-W queued (core 1.150): a WorkflowAgentRun's `startedAt` is now OPTIONAL — ABSENT while an agent is QUEUED
|
|
306
|
+
// (waiting on a concurrency slot) or if it was aborted/finalized before it ran. So duration is undefined unless
|
|
307
|
+
// BOTH ends are present (a queued agent has no running duration — the DoR fix). Phases still always carry startedAt.
|
|
200
308
|
const durationOf = (a) => a.startedAt === undefined || a.endedAt === undefined ? undefined : a.endedAt - a.startedAt;
|
|
309
|
+
// A real persisted run always carries these arrays; default defensively so a malformed/partial stored row
|
|
310
|
+
// projects cleanly instead of 500-ing the detail route (the view is read-only — never a gate input).
|
|
201
311
|
const runPhases = run.phases ?? [];
|
|
202
312
|
const runAgents = run.agents ?? [];
|
|
203
313
|
const runGroups = run.groups ?? [];
|
|
314
|
+
// [review] label-parity: an LLM-authored run_workflow script controls phase titles + agent labels + the per-agent
|
|
315
|
+
// phase tag (core stores them raw, unbounded), so redact them on EMISSION for the same reason as name/description
|
|
316
|
+
// (a secret the agent read could land in a label). Filter/bucket on the RAW values (below) so grouping is unchanged;
|
|
317
|
+
// redactSecrets is deterministic → a secret-bearing title and the matching agent.phase scrub to the SAME string,
|
|
318
|
+
// so the shell's phase grouping still lines up. (prompt/output are already core-redacted; model is catalog-sourced.)
|
|
204
319
|
const phases = runPhases.map((p) => {
|
|
205
|
-
const inPhase = runAgents.filter((a) => a.phase === p.title);
|
|
320
|
+
const inPhase = runAgents.filter((a) => a.phase === p.title); // RAW compare — bucketing key, not emitted
|
|
206
321
|
return {
|
|
207
322
|
title: redactSecrets(p.title),
|
|
208
323
|
status: p.status,
|
|
@@ -213,31 +328,50 @@ function summarizeWorkflowDetail(run) {
|
|
|
213
328
|
total: inPhase.length,
|
|
214
329
|
};
|
|
215
330
|
});
|
|
331
|
+
// Agents with no phase title, OR a phase title that matches no registered `run.phases` entry (a stray
|
|
332
|
+
// `opts.phase` with no enclosing `phase()` block) — surfaced so the panel's counts are EXHAUSTIVE (an agent is
|
|
333
|
+
// in exactly one bucket: its registered phase, or `unphased`). Without the `titleSet` guard a stray-phase agent
|
|
334
|
+
// would fall into NO bucket (under-count). Empty-string phase is also unphased.
|
|
216
335
|
const phaseTitleSet = new Set(runPhases.map((p) => p.title));
|
|
217
336
|
const unphased = runAgents.filter((a) => a.phase === undefined || a.phase === "" || !phaseTitleSet.has(a.phase));
|
|
218
337
|
const unphasedView = unphased.length > 0
|
|
219
338
|
? { done: unphased.filter((a) => isDone(a.status)).length, total: unphased.length }
|
|
220
339
|
: undefined;
|
|
221
340
|
const agents = runAgents.map((a) => ({
|
|
222
|
-
label: redactSecrets(a.label),
|
|
341
|
+
label: redactSecrets(a.label), // [review] label-parity (LLM-authored, see phases comment)
|
|
223
342
|
status: a.status,
|
|
343
|
+
// MF-W (1.149 CORE-shared): the canonical display status (running|queued|done|failed|interrupted) via core's
|
|
344
|
+
// deriveAgentDisplayStatus — the SAME pure fn the shell renders, so the agent-state glyph can't drift between
|
|
345
|
+
// shells (one source of truth in core). `interrupted` = a non-terminal agent under a terminal run. The live
|
|
346
|
+
// `idle` overlay (a running agent with no recent activity) stays a SHELL wall-clock concern — since core 1.295
|
|
347
|
+
// ToolActivity carries `at`, this view exposes the raw timestamps (activity[].at + lastActivityAt below) and
|
|
348
|
+
// the shell derives idleness against its own clock (a served idleMs would drift on a historical view).
|
|
224
349
|
displayStatus: deriveAgentDisplayStatus(a, run.status),
|
|
225
350
|
taskStatus: a.taskStatus,
|
|
226
351
|
callKey: a.callKey,
|
|
227
352
|
groupId: a.groupId,
|
|
228
|
-
phase: a.phase !== undefined ? redactSecrets(a.phase) : undefined,
|
|
229
|
-
model: a.model,
|
|
353
|
+
phase: a.phase !== undefined ? redactSecrets(a.phase) : undefined, // [review] label-parity; undefined = unphased (kept)
|
|
354
|
+
model: a.model, // SVC-4 v2 / CORE-8 ①: per-agent model display label ("Opus 4.8 (1M context)" row)
|
|
230
355
|
tokens: a.stats?.tokens,
|
|
231
356
|
turns: a.stats?.turns,
|
|
232
|
-
toolCalls: a.toolCalls,
|
|
357
|
+
toolCalls: a.toolCalls, // SVC-4 v2 / CORE-8 ②: total tool calls ("M" in "last N of M tool calls")
|
|
358
|
+
// SVC-4 v2 / CORE-8 ③: the LAST-N tool-call beats (structural — phase/toolName/ids, no args/output). The live
|
|
359
|
+
// detail SSE (subscribeWorkflow → streamWorkflowRun) already forwards the per-callKey `agent_activity` events
|
|
360
|
+
// verbatim for a running drill-down; this is the persisted tail a historical view renders.
|
|
361
|
+
// [843]④a (core 1.295): each beat now carries `at` (epoch ms, stamped on BOTH start and end) — verbatim
|
|
362
|
+
// passthrough here, so idle derives shell-side as the FRAME GAP (end.at → next start.at), the [879] ruling.
|
|
233
363
|
activity: a.activity,
|
|
364
|
+
// [843]④a convenience: the tail beat's timestamp, so a shell can grey a stale agent without walking the
|
|
365
|
+
// array. TIMESTAMP not a duration on purpose — this detail is a HISTORICAL view, so a served `idleMs`
|
|
366
|
+
// (Date.now()-derived) would drift on every re-read; the shell owns the clock. Absent for pre-1.295 runs
|
|
367
|
+
// whose beats carry no `at` (undefined → key omitted by JSON, same back-compat shape as agentFailures).
|
|
234
368
|
lastActivityAt: a.activity && a.activity.length > 0 ? a.activity[a.activity.length - 1].at : undefined,
|
|
235
369
|
durationMs: durationOf(a),
|
|
236
|
-
queuedAt: a.queuedAt,
|
|
237
|
-
startedAt: a.startedAt,
|
|
370
|
+
queuedAt: a.queuedAt, // MF-W queued (1.150): when the agent was ENQUEUED (always set) — a queued agent has queuedAt but no startedAt
|
|
371
|
+
startedAt: a.startedAt, // now optional (absent while queued / aborted-before-run) — displayStatus already reflects "queued"
|
|
238
372
|
endedAt: a.endedAt,
|
|
239
373
|
replayed: a.replayed,
|
|
240
|
-
prompt: a.prompt,
|
|
374
|
+
prompt: a.prompt, // core-redacted + bounded; human view → no fence at rest
|
|
241
375
|
output: a.output,
|
|
242
376
|
}));
|
|
243
377
|
const byId = new Map();
|
|
@@ -253,6 +387,9 @@ function summarizeWorkflowDetail(run) {
|
|
|
253
387
|
children: [],
|
|
254
388
|
});
|
|
255
389
|
}
|
|
390
|
+
// Walk up `parentGroupId` from `node`; true if the chain LOOPS (self-parent, or a multi-node cycle A→B→A)
|
|
391
|
+
// rather than terminating at a top-level (`undefined`) or dangling (absent) parent. Bounded by the seen-set, so
|
|
392
|
+
// a malformed run can neither hang nor build a circular object that `JSON.stringify` would throw 500 on.
|
|
256
393
|
const inCycle = (start) => {
|
|
257
394
|
const seen = new Set();
|
|
258
395
|
let cur = start;
|
|
@@ -267,18 +404,27 @@ function summarizeWorkflowDetail(run) {
|
|
|
267
404
|
const roots = [];
|
|
268
405
|
for (const node of byId.values()) {
|
|
269
406
|
const parent = node.parentGroupId !== undefined ? byId.get(node.parentGroupId) : undefined;
|
|
407
|
+
// Link to parent ONLY when that can't form a cycle — a self/multi-node cycle member grafts onto root, so the
|
|
408
|
+
// tree is always acyclic (JSON-safe) and no node is ever dropped.
|
|
270
409
|
if (parent && parent !== node && !inCycle(node))
|
|
271
410
|
parent.children.push(node);
|
|
272
411
|
else
|
|
273
|
-
roots.push(node);
|
|
412
|
+
roots.push(node); // top-level, dangling parent, or cycle member → graft onto root (never dropped)
|
|
274
413
|
}
|
|
275
414
|
return {
|
|
276
415
|
id: run.id,
|
|
277
416
|
scope: run.scope,
|
|
278
417
|
status: run.status,
|
|
418
|
+
// K-2c (shell §K): the workflow header label + subtitle the MF-W detail view needs — from the script's
|
|
419
|
+
// `export const meta = {name, description}` (core WorkflowRun.name/description). REDACTED for label parity with
|
|
420
|
+
// the fleet run/subagent names (an LLM-authored meta is task-controlled → could carry a secret shape). Per-phase
|
|
421
|
+
// title is already on each `phases[].title`. Omitted when absent (back-compat: older runs have neither).
|
|
279
422
|
...(run.name !== undefined ? { name: redactSecrets(run.name) } : {}),
|
|
280
423
|
...(run.description !== undefined ? { description: redactSecrets(run.description) } : {}),
|
|
281
424
|
stats: run.stats,
|
|
425
|
+
// core 1.293: run-level failed-agent count (agents whose status ended "failed"), stamped at run end only
|
|
426
|
+
// when > 0. A plain number (not task-controlled text) → no redaction. Omitted when absent (back-compat:
|
|
427
|
+
// pre-1.293 runs / zero failures) — [843]④a: the detail view had no failure count to render.
|
|
282
428
|
...(run.agentFailures !== undefined ? { agentFailures: run.agentFailures } : {}),
|
|
283
429
|
startedAt: run.startedAt,
|
|
284
430
|
endedAt: run.endedAt,
|
|
@@ -286,6 +432,10 @@ function summarizeWorkflowDetail(run) {
|
|
|
286
432
|
durationMs: durationOf(run),
|
|
287
433
|
rev: run.rev,
|
|
288
434
|
error: run.error,
|
|
435
|
+
// core 1.234: the script's RETURN VALUE — bounded + redacted AT THE SOURCE (completion-time,
|
|
436
|
+
// same egress discipline as the notifier), but re-redacted here for defence-in-depth parity with
|
|
437
|
+
// name/description (this projection's whitelist predates the field — live-dig T8 caught the omission:
|
|
438
|
+
// TaskOutput carried the result while this detail view silently dropped it). Absent on failed/pre-1.234 runs.
|
|
289
439
|
...(run.result !== undefined ? { result: redactSecrets(run.result) } : {}),
|
|
290
440
|
phases,
|
|
291
441
|
...(unphasedView ? { unphased: unphasedView } : {}),
|
|
@@ -293,14 +443,25 @@ function summarizeWorkflowDetail(run) {
|
|
|
293
443
|
groups: roots,
|
|
294
444
|
};
|
|
295
445
|
}
|
|
446
|
+
/** SSE the live progress of a RUNNING workflow (S8). subscribeWorkflow is IN-PROCESS (replica-local): the
|
|
447
|
+
* iterable ends when the run's channel closes at run_end, or when the client disconnects. A run with no live
|
|
448
|
+
* channel (already finished, or on another replica) yields nothing → the stream ends immediately (the
|
|
449
|
+
* historical view is GET /v1/workflows/:id). Owner-gating (run.scope === principal) is done by the caller;
|
|
450
|
+
* core 1.366 (B-3) additionally doors the subscription itself on scope — a mismatched scope yields an empty
|
|
451
|
+
* stream (same shape as not-found), so the caller passes the SAME scope it owner-gated with. */
|
|
296
452
|
async function streamWorkflowRun(req, res, runId, scope) {
|
|
297
453
|
sseHeaders(res);
|
|
298
454
|
res.write(`event: meta\ndata: ${JSON.stringify({ version: 1, runId })}\n\n`);
|
|
299
455
|
let closed = false;
|
|
456
|
+
// subscribeWorkflow is a PUSH iterator: a parked `next()` on an idle-but-alive workflow does NOT observe a
|
|
457
|
+
// `closed` flag, so a disconnected client would leave the subscriber queue registered in core's channels and
|
|
458
|
+
// publishWorkflowEvent would buffer events for the dead peer forever (a leak). Drive the iterator explicitly so
|
|
459
|
+
// disconnect can call `it.return()` — which unwinds the parked next() AND runs core's finally to prune the queue.
|
|
300
460
|
const it = subscribeWorkflow(runId, scope)[Symbol.asyncIterator]();
|
|
461
|
+
// Heartbeat so an idle proxy/mesh doesn't drop the connection (and a dead TCP peer is detected → "close").
|
|
301
462
|
const hb = setInterval(() => {
|
|
302
463
|
if (!res.writableEnded)
|
|
303
|
-
res.write(`event: heartbeat\ndata: {}\n\n`);
|
|
464
|
+
res.write(`event: heartbeat\ndata: {}\n\n`); // real frame (not an SSE comment) — a per-frame-parsing BFF drops comments, so downstream saw a zero-frame window; EventSource clients without a heartbeat listener ignore it (zero break)
|
|
304
465
|
}, 15_000);
|
|
305
466
|
if (typeof hb.unref === "function")
|
|
306
467
|
hb.unref();
|
|
@@ -309,12 +470,12 @@ async function streamWorkflowRun(req, res, runId, scope) {
|
|
|
309
470
|
return;
|
|
310
471
|
closed = true;
|
|
311
472
|
clearInterval(hb);
|
|
312
|
-
void it.return?.(undefined);
|
|
473
|
+
void it.return?.(undefined); // prune core's subscriber queue (workflow-observe finally) — stop buffering for a dead peer
|
|
313
474
|
if (!res.writableEnded)
|
|
314
475
|
res.end();
|
|
315
476
|
};
|
|
316
477
|
req.on("close", shutdown);
|
|
317
|
-
res.on("close", shutdown);
|
|
478
|
+
res.on("close", shutdown); // res close (peer gone) too, not just req — either side ending must prune the queue
|
|
318
479
|
try {
|
|
319
480
|
for (let next = await it.next(); !next.done; next = await it.next()) {
|
|
320
481
|
if (closed || res.writableEnded)
|
package/dist/http/run-meta.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/158 A9 装配缝的一片小叶子 —— 提交路径共用的两个纯函数(run 行元数据 + cascade 配置)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么单独成文件:`runMeta` 被 tasks 与 runs **两个**域模块调用,`cascadeConfig` 同理(还被测试直接引)。
|
|
5
|
+
* 挂在任一域模块上都会造出 routes/* 互相值 import 的第二条边;它们又是纯函数(只依赖入参 + redact 叶子),
|
|
6
|
+
* 所以正确归处是叶子。server.ts 转出口 `cascadeConfig` 以保住既有 import 点。
|
|
7
|
+
*/
|
|
1
8
|
import type { TaskSpec, CascadeConfig } from "@sema-agent/core";
|
|
9
|
+
/** The denormalized run-row metadata captured at submit: correlation (jobId), credential-derived source,
|
|
10
|
+
* and a redacted objective glance for lists. One place so the three submit paths can't drift. */
|
|
2
11
|
export declare function runMeta(prepared: {
|
|
3
12
|
jobId?: string;
|
|
4
13
|
spec: TaskSpec;
|
|
@@ -7,5 +16,7 @@ export declare function runMeta(prepared: {
|
|
|
7
16
|
source: string | null;
|
|
8
17
|
objectivePreview: string | null;
|
|
9
18
|
};
|
|
19
|
+
/** Build the cascade config from the operator ladder. Default gate = `status==="completed"` (escalate
|
|
20
|
+
* on a cheap-rung failure); cost-ceiling from the task's budget bounds the cold-rerun tax. */
|
|
10
21
|
export declare function cascadeConfig(ladder: readonly string[], maxCostUsd?: number): CascadeConfig;
|
|
11
22
|
//# sourceMappingURL=run-meta.d.ts.map
|
package/dist/http/run-meta.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { redactSecrets } from "../trace/redact.js";
|
|
2
|
+
/** The denormalized run-row metadata captured at submit: correlation (jobId), credential-derived source,
|
|
3
|
+
* and a redacted objective glance for lists. One place so the three submit paths can't drift. */
|
|
2
4
|
export function runMeta(prepared, source) {
|
|
3
5
|
const obj = prepared.spec.objective ?? "";
|
|
4
6
|
return {
|
|
5
7
|
jobId: prepared.jobId ?? null,
|
|
6
8
|
source,
|
|
9
|
+
// redactSecrets is best-effort (known key/token shapes only — NOT exhaustive; see redact.ts). Acceptable
|
|
10
|
+
// here: the preview rides the fleet-token-gated trace surface, not an end-user-readable channel (council #1).
|
|
7
11
|
objectivePreview: obj ? redactSecrets(obj).slice(0, 120) : null,
|
|
8
12
|
};
|
|
9
13
|
}
|
|
14
|
+
/** Build the cascade config from the operator ladder. Default gate = `status==="completed"` (escalate
|
|
15
|
+
* on a cheap-rung failure); cost-ceiling from the task's budget bounds the cold-rerun tax. */
|
|
10
16
|
export function cascadeConfig(ladder, maxCostUsd) {
|
|
11
17
|
return {
|
|
12
18
|
ladder: ladder.map((model) => ({ model })),
|
package/dist/http/send.d.ts
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/158 A9 seam — response senders, extracted VERBATIM out of `http/server.ts` so the per-domain route
|
|
3
|
+
* modules under `http/routes/` can call them without a value edge back into `server.ts` (that edge would close
|
|
4
|
+
* a runtime import cycle — see `test/module-cycle-gate.test.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Pure move: bodies are byte-identical to the ones that lived at `server.ts:9720/9822/9834/9843`. `server.ts`
|
|
7
|
+
* now imports them from here, so all ~500 existing `sendJson(...)` call sites are unchanged text.
|
|
8
|
+
*/
|
|
1
9
|
import type { ServerResponse } from "node:http";
|
|
2
10
|
export declare function sseHeaders(res: ServerResponse, extra?: Record<string, string>): void;
|
|
3
11
|
export declare function sendJson(res: ServerResponse, status: number, body: unknown): void;
|
|
12
|
+
/** A6(design/158 lens1 §C3/lens3 §C3a): canonical error-response sender for sites that already carry a
|
|
13
|
+
* machine `errorCode` — `errorCode` is a required positional arg (not optional-bag) so a call site
|
|
14
|
+
* cannot regress to the "code but no errorCode" shape the error-code-key-gate forbids. Body shape is
|
|
15
|
+
* `{ error: message, errorCode, ...extra }`; a site that used to ALSO emit a legacy `code` key keeps it
|
|
16
|
+
* by passing `{ code: ... }` inside `extra` — this is a pure call-site migration (zero wire-contract
|
|
17
|
+
* change), not a new response shape. Sites where the two machine-code channels genuinely disagree, or
|
|
18
|
+
* where `error`/`errorCode` aren't cleanly separable from the rest of the body, are left on raw
|
|
19
|
+
* `sendJson` (see the A6 migration notes for the callers still doing that on purpose). */
|
|
4
20
|
export declare function sendError(res: ServerResponse, status: number, errorCode: string, message: string, extra?: Record<string, unknown>): void;
|
|
21
|
+
/** B7(design/158 lens1 §C3):`HttpError` 的兜底 catch-all 站点没有自己的语义分支——`err.code` 在 42 个
|
|
22
|
+
* throw 点里只有 3 个带。为了让「errorCode 恒在」在这些站点也成立(而不是靠豁免表放行),按**状态码**
|
|
23
|
+
* 给一个诚实的粗码:它只声明「这类拒绝」,不冒充比 throw 点更细的语义。带 `code` 的 throw 点原样优先。 */
|
|
5
24
|
export declare function httpErrorCode(status: number, code?: string): string;
|
|
6
25
|
export declare function msg(e: unknown): string;
|
|
7
26
|
//# sourceMappingURL=send.d.ts.map
|
package/dist/http/send.js
CHANGED
|
@@ -10,9 +10,20 @@ export function sendJson(res, status, body) {
|
|
|
10
10
|
res.writeHead(status, { "content-type": "application/json" });
|
|
11
11
|
res.end(JSON.stringify(body));
|
|
12
12
|
}
|
|
13
|
+
/** A6(design/158 lens1 §C3/lens3 §C3a): canonical error-response sender for sites that already carry a
|
|
14
|
+
* machine `errorCode` — `errorCode` is a required positional arg (not optional-bag) so a call site
|
|
15
|
+
* cannot regress to the "code but no errorCode" shape the error-code-key-gate forbids. Body shape is
|
|
16
|
+
* `{ error: message, errorCode, ...extra }`; a site that used to ALSO emit a legacy `code` key keeps it
|
|
17
|
+
* by passing `{ code: ... }` inside `extra` — this is a pure call-site migration (zero wire-contract
|
|
18
|
+
* change), not a new response shape. Sites where the two machine-code channels genuinely disagree, or
|
|
19
|
+
* where `error`/`errorCode` aren't cleanly separable from the rest of the body, are left on raw
|
|
20
|
+
* `sendJson` (see the A6 migration notes for the callers still doing that on purpose). */
|
|
13
21
|
export function sendError(res, status, errorCode, message, extra) {
|
|
14
22
|
sendJson(res, status, { error: message, errorCode, ...extra });
|
|
15
23
|
}
|
|
24
|
+
/** B7(design/158 lens1 §C3):`HttpError` 的兜底 catch-all 站点没有自己的语义分支——`err.code` 在 42 个
|
|
25
|
+
* throw 点里只有 3 个带。为了让「errorCode 恒在」在这些站点也成立(而不是靠豁免表放行),按**状态码**
|
|
26
|
+
* 给一个诚实的粗码:它只声明「这类拒绝」,不冒充比 throw 点更细的语义。带 `code` 的 throw 点原样优先。 */
|
|
16
27
|
export function httpErrorCode(status, code) {
|
|
17
28
|
if (code)
|
|
18
29
|
return code;
|