@sema-agent/server 1.322.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +2132 -96
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +59 -3
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EffectiveConfig application — mutate the boot `ServiceConfig` OVER with a pulled `EffectiveConfig`
|
|
3
|
+
* (models/roles/tiers/projects `applyEffective`, the 6 runtime gates `applyRuntimeGates`, the per-request-hot
|
|
4
|
+
* governance baton `applyRuntimeHot`) plus their shared helpers (`toModel`, `mutateInPlace`,
|
|
5
|
+
* `resolveDefaultModelName`, `logEffectiveDiff`, `runtimeHasActiveGate`). Split out of `sema-registry.ts`
|
|
6
|
+
* (design/158 A13, internal-lossless — the facade re-exports every symbol below unchanged).
|
|
7
|
+
*/
|
|
1
8
|
import { isThinkingLevel } from "@sema-agent/core";
|
|
2
9
|
import { resolveActiveTiers, SEALED_BOX_ALG } from "@sema-agent/registry-core";
|
|
3
10
|
import { sealedKeyPoison } from "../sealed-key.js";
|
|
@@ -6,8 +13,11 @@ import { validateCommandRules } from "../runtime-governance.js";
|
|
|
6
13
|
import { projectCollabToWorkflows, registerCollabWorkflows } from "../capabilities/collab-workflows.js";
|
|
7
14
|
import { registerTeams } from "../capabilities/team.js";
|
|
8
15
|
const asModelThinking = (v) => (v && isThinkingLevel(v) && v !== "off" ? v : undefined);
|
|
16
|
+
/** design/123: accept only a positive finite roster charsPerToken (fail-safe to env default / core 4). */
|
|
9
17
|
const charsPerTokenOf = (v) => (typeof v === "number" && Number.isFinite(v) && v > 0 ? v : undefined);
|
|
10
18
|
function toModel(m, envDefaults = {}) {
|
|
19
|
+
// design/111 L2②: a center model MAY declare defaultThinking/reasoningEffortLevels; absent → inherit the env-derived
|
|
20
|
+
// model's values (BL-8 — same class as reasoning/contextWindow/maxTokens, else a roster silently drops the env default).
|
|
11
21
|
const thinkingDefault = asModelThinking(m.defaultThinking) ?? envDefaults.defaultThinking;
|
|
12
22
|
const effortLevels = (m.reasoningEffortLevels ? m.reasoningEffortLevels.map(asModelThinking).filter((x) => x !== undefined) : undefined) ?? envDefaults.reasoningEffortLevels ?? [];
|
|
13
23
|
const model = {
|
|
@@ -15,46 +25,93 @@ function toModel(m, envDefaults = {}) {
|
|
|
15
25
|
name: m.name,
|
|
16
26
|
provider: m.provider,
|
|
17
27
|
api: m.api,
|
|
28
|
+
// 实机 /model 切 Kimi 404 定谳: a catalog model MAY carry its own gateway URL — the
|
|
29
|
+
// hardcoded "" made core's brain fall back to the boot-env endpoint, so cross-endpoint `body.model`
|
|
30
|
+
// selection hit the WRONG gateway (kimi id → Qwen vLLM → 404). Absent still = "" (brain env default;
|
|
31
|
+
// byte-compat for single-gateway rosters). core brain honors model.baseUrl; keys stay per-model via apiKeyEnv.
|
|
18
32
|
baseUrl: m.baseUrl ?? "",
|
|
33
|
+
// BL-8 extended (systematic-audit): fall back to the ENV-derived model's reasoning, not Boolean(undefined)=false —
|
|
34
|
+
// else a center roster that omits `reasoning` SILENTLY disables it even though the env lane defaults it ON
|
|
35
|
+
// (config.ts MODEL_REASONING="true"). A center model MAY set false to override. Same class as contextWindow/maxTokens.
|
|
19
36
|
reasoning: m.reasoning !== undefined ? Boolean(m.reasoning) : (envDefaults.reasoning ?? true),
|
|
20
37
|
input: m.vision ? ["text", "image"] : ["text"],
|
|
38
|
+
// BL-8: fall back to the ENV-derived model's value (MODEL_CONTEXT_WINDOW / MODEL_MAX_TOKENS), not a
|
|
39
|
+
// hardcoded literal — else a center roster that replaces the env model SILENTLY clamps maxTokens to 4096
|
|
40
|
+
// (the prod review-gw runs deepseek at 32000), shrinking every response. A center model MAY still set its
|
|
41
|
+
// own value to override. (ROBUSTNESS-BACKLOG:28 / BL-8.)
|
|
21
42
|
contextWindow: m.contextWindow ?? envDefaults.contextWindow ?? 262144,
|
|
22
43
|
maxTokens: m.maxTokens ?? envDefaults.maxTokens ?? 4096,
|
|
44
|
+
// design/123 D2 (BL-8 class): center override ?? env default (MODEL_CHARS_PER_TOKEN) ?? omit = core 4.
|
|
45
|
+
// Positive-finite guard mirrors the env lane — a bad roster value must not zero structural estimates.
|
|
23
46
|
...(charsPerTokenOf(m.charsPerToken) !== undefined || envDefaults.charsPerToken !== undefined
|
|
24
47
|
? { charsPerToken: charsPerTokenOf(m.charsPerToken) ?? envDefaults.charsPerToken }
|
|
25
48
|
: {}),
|
|
26
49
|
cost: m.cost
|
|
27
50
|
? { input: m.cost.input, output: m.cost.output, cacheRead: m.cost.cacheRead ?? 0, cacheWrite: m.cost.cacheWrite ?? 0 }
|
|
28
51
|
: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
52
|
+
// Explicit cache family by provider (core 1.23) — same as the env path in config.ts. Anthropic brain
|
|
53
|
+
// reports input EXCLUDING cached; the openai gateway INCLUDES it (design/18).
|
|
29
54
|
params: { ...(m.tier ? { tier: m.tier } : {}), promptCacheFamily: m.provider === "anthropic" ? "input-excludes-cached" : "input-includes-cached" },
|
|
55
|
+
// design/111 L2②: per-model default thinking + endpoint-accepted tiers (center override ?? env default, BL-8).
|
|
30
56
|
...(thinkingDefault ? { defaultThinking: thinkingDefault } : {}),
|
|
31
57
|
...(effortLevels.length > 0 && m.provider !== "anthropic" ? { compat: { reasoningEffortLevels: effortLevels } } : {}),
|
|
58
|
+
// Generation tuning (1.60) carried verbatim — without this a center roster that replaces the env model
|
|
59
|
+
// would silently drop the degenerate-looping prevention (freq/pres penalties). Absent → unchanged.
|
|
32
60
|
...(m.extraBody ? { extraBody: m.extraBody } : {}),
|
|
61
|
+
// Per-model behavior-slot sentences ([998]⑤c consumer half) — verbatim, same posture as extraBody.
|
|
33
62
|
...(Array.isArray(m.promptGuidance) && m.promptGuidance.length > 0 ? { promptGuidance: m.promptGuidance.map(String) } : {}),
|
|
34
63
|
};
|
|
64
|
+
// [818]① 1M dual-window: an explicit roster `autoCompactTokens` (structural, like tier passthroughs) wins;
|
|
65
|
+
// else a >=1M contextWindow derives the CC-aligned 967000; else absent. Same helper as the env lane.
|
|
35
66
|
const explicitAct = m.autoCompactTokens;
|
|
36
67
|
applyAutoCompactWindow(model, typeof explicitAct === "number" ? explicitAct : undefined);
|
|
37
68
|
return model;
|
|
38
69
|
}
|
|
70
|
+
/** Apply center config OVER the env-derived config (mutates `config`). Empty domains keep env defaults. */
|
|
71
|
+
/** Replace a record's contents IN PLACE (clear keys, copy source) so holders of the SAME reference see the
|
|
72
|
+
* change. This is what makes models/roles/pricing HOT-apply: core's Runner reads
|
|
73
|
+
* `this.deps.models/roles/pricing` LIVE per-task and `/v1/models` reads `config.models` — both share the
|
|
74
|
+
* reference captured at boot, so mutating it (vs reassigning) updates both with no split, no Runner rebuild. */
|
|
39
75
|
export function mutateInPlace(target, source) {
|
|
40
76
|
for (const k of Object.keys(target))
|
|
41
77
|
delete target[k];
|
|
42
78
|
Object.assign(target, source);
|
|
43
79
|
}
|
|
44
80
|
export function applyEffective(config, eff, logger, opts = {}) {
|
|
81
|
+
// version 0 / empty effective = the sema-registry has nothing for us yet — typically CONFIG_PUBLISH_MODE
|
|
82
|
+
// is ON but nothing has been published. We do NOT wipe: models/roles fall back to env (the enabled>0
|
|
83
|
+
// guard below), teams to BUILTIN_TEAMS (registerTeams resets to built-ins). Warn once at boot so the
|
|
84
|
+
// operator knows their config isn't live (publish a version, or disable the publish gate). See the
|
|
85
|
+
// sema-registry's ORCHESTRATOR-REVIEW §④ publish-gate contract.
|
|
45
86
|
if (!opts.teamsOnly && !eff.version) {
|
|
46
87
|
logger?.warn("sema_registry_unpublished", {
|
|
47
88
|
version: eff.version,
|
|
48
89
|
note: "empty/unpublished effective config — using env + built-in fallback; publish a config or unset CONFIG_PUBLISH_MODE",
|
|
49
90
|
});
|
|
50
91
|
}
|
|
92
|
+
// models/roles HOT-apply on BOTH boot and refresh (TOC "save = effective"). We MUTATE
|
|
93
|
+
// config.models/roles IN PLACE (mutateInPlace) — NOT reassign — so the live Runner (reads `this.deps.models/
|
|
94
|
+
// roles` per-task by reference) and `/v1/models` (reads config.models) share the one updated object with NO
|
|
95
|
+
// split, no Runner rebuild, no core change. Caller (main.ts refresh) additionally refreshes `pricing` (same
|
|
96
|
+
// ref) + rebuilds `keyResolver`. (Was startup-only when reassignment split the Runner's ref from config.)
|
|
51
97
|
const enabled = (eff.models?.models ?? []).filter((m) => m.enabled !== false);
|
|
98
|
+
// codex R10: `deferModelPlane` skips the WHOLE model plane (models/roles/tiers + per-model keys) — main.ts
|
|
99
|
+
// sets it when the Runner is tier-frozen (private expanded copy) and the plane changed: hot-applying would
|
|
100
|
+
// split admission (/v1/models, catalog gates) from the Runner's frozen generation, letting a same-key retarget
|
|
101
|
+
// silently route/bill the stale Model object through the restart window. Deferred = live plane stays on the
|
|
102
|
+
// Runner's generation; the models-tiers restart slice signals the orchestrator; the restarted process applies
|
|
103
|
+
// the new plane at boot BEFORE Runner construction. Caller logs the deferral (never silent).
|
|
52
104
|
if (enabled.length > 0 && opts.deferModelPlane !== true) {
|
|
53
105
|
const models = {};
|
|
54
106
|
const modelApiKeyEnv = {};
|
|
55
|
-
const modelApiKeys = {};
|
|
107
|
+
const modelApiKeys = {}; // sealed-box 解封明文(内存-only,绝不日志/落盘)或毒丸标记(解封失败,见下)
|
|
108
|
+
// Capture the env-derived model's generation bounds BEFORE the loop overwrites config.model (line below):
|
|
109
|
+
// a center model that omits maxTokens/contextWindow inherits the operator's env values, not a literal (BL-8).
|
|
56
110
|
const envDefaults = { maxTokens: config.model.maxTokens, contextWindow: config.model.contextWindow, reasoning: config.model.reasoning, charsPerToken: config.model.charsPerToken, defaultThinking: config.model.defaultThinking, reasoningEffortLevels: config.model.compat?.reasoningEffortLevels };
|
|
57
111
|
for (const m of enabled) {
|
|
112
|
+
// Guard (since 1.128.0): a registry baseUrl now DIRECTS model traffic (incl. that model's
|
|
113
|
+
// Authorization key) — a registry editor is a lower-trust writer than the env, so a non-http(s)/unparsable
|
|
114
|
+
// value is REJECTED back to "" (boot-env gateway) and every honored override is logged (observable routing).
|
|
58
115
|
const rawBaseUrl = m.baseUrl;
|
|
59
116
|
let safeUrl = rawBaseUrl;
|
|
60
117
|
if (rawBaseUrl) {
|
|
@@ -74,6 +131,22 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
74
131
|
}
|
|
75
132
|
}
|
|
76
133
|
models[m.name] = toModel(safeUrl === rawBaseUrl ? m : { ...m, baseUrl: safeUrl }, envDefaults);
|
|
134
|
+
// Sealed-box custody (registry-core 0.10.5): a model MAY carry `sealedApiKey` — the
|
|
135
|
+
// api key pasted in the web UI and sealed BROWSER-SIDE against this host's X25519 public key; the
|
|
136
|
+
// center stores only the ciphertext. We unseal with the private key registered under the EXACT
|
|
137
|
+
// `publicKeyId` (no try-every-key scanning — the contract selects precisely) and inject the
|
|
138
|
+
// plaintext into the in-memory per-model key pipeline (config.modelApiKeys → getApiKeyAndHeaders).
|
|
139
|
+
// Mutual exclusion (contract): sealed OUTRANKS apiKeyEnv when both are set — and STRICTLY so: a
|
|
140
|
+
// sealed key that fails to unseal (missing private key / bad base64 / MAC failure) does NOT fall
|
|
141
|
+
// back to the env-NAME reference. Falling back would turn "the key I pasted isn't live" into a
|
|
142
|
+
// silent misroute onto some stale env key; we fail LOUD (warn). And since a merely-ABSENT map
|
|
143
|
+
// entry is indistinguishable from "no per-model key configured" — which with a gateway
|
|
144
|
+
// MODEL_API_KEY deployed meant the model's tasks silently burned the shared account — a failed
|
|
145
|
+
// unseal plants a POISON PILL in the map instead of injecting nothing: the key resolver turns it
|
|
146
|
+
// into a task-level SealedKeyPoisonedError on every brain call (the gateway key is NEVER a silent
|
|
147
|
+
// fallback for a broken sealed key) until the operator fixes custody and a later apply delivers a
|
|
148
|
+
// decryptable ciphertext (the rebuild below makes recovery automatic). 🔴 Neither the plaintext
|
|
149
|
+
// NOR the ciphertext ever reaches a log line or the poison object (write-only discipline).
|
|
77
150
|
if (m.sealedApiKey) {
|
|
78
151
|
const s = m.sealedApiKey;
|
|
79
152
|
if (s.alg !== SEALED_BOX_ALG) {
|
|
@@ -98,18 +171,30 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
98
171
|
}
|
|
99
172
|
}
|
|
100
173
|
}
|
|
174
|
+
// Per-model key: center declares the env var NAME (never the secret) holding this model's upstream
|
|
175
|
+
// key. Drives the spec's getApiKeyAndHeaders so each model authenticates with its own account; the
|
|
176
|
+
// value is resolved from process.env in THIS service (secrets stay in env, design/15). A model
|
|
177
|
+
// without apiKeyEnv (or whose env var is unset) falls back to the gateway key — purely additive.
|
|
178
|
+
// (`else if` on sealedApiKey ABSENCE: a sealed model never consults the env reference — see above.)
|
|
101
179
|
else if (m.apiKeyEnv) {
|
|
102
180
|
if (process.env[m.apiKeyEnv])
|
|
103
181
|
modelApiKeyEnv[m.name] = m.apiKeyEnv;
|
|
104
182
|
else
|
|
105
183
|
logger?.warn("sema_registry_model_key_env_missing", { model: m.name, apiKeyEnv: m.apiKeyEnv, hint: "env var not set in this service — model falls back to the gateway key" });
|
|
106
184
|
}
|
|
185
|
+
// A center model whose provider has no matching brain in THIS service's env will mis-route:
|
|
186
|
+
// createRoutingBrain falls back to the gateway brain. The anthropic route needs ANTHROPIC_API_KEY.
|
|
107
187
|
if (m.provider === "anthropic" && !config.anthropic) {
|
|
108
188
|
logger?.warn("sema_registry_model_no_brain", { model: m.name, provider: m.provider, hint: "set ANTHROPIC_API_KEY in this service's env, else it mis-routes to the gateway brain" });
|
|
109
189
|
}
|
|
110
190
|
}
|
|
111
|
-
config.modelApiKeyEnv = modelApiKeyEnv;
|
|
112
|
-
|
|
191
|
+
config.modelApiKeyEnv = modelApiKeyEnv; // reassign ok — keyResolver is rebuilt from it on refresh (main.ts)
|
|
192
|
+
// same rebuild contract; plaintext values — memory-only, never logged. Poison markers ride the same
|
|
193
|
+
// map (they ARE per-model key state: "configured but broken"); the cast bridges config.ts's
|
|
194
|
+
// plaintext-only field type until it is widened to Record<string, string | SealedKeyPoison>.
|
|
195
|
+
config.modelApiKeys = modelApiKeys; // 类型已放真(string | SealedKeyPoison),桥接 cast 退役
|
|
196
|
+
// weight-at-burn 源:quotaWeight 按 name+id 双键索引(tracer 的 brain.call e.model=模型 id,
|
|
197
|
+
// 目录键=name——双键免猜);非法值(≤0/NaN)按缺省 1 丢弃。IN PLACE 与 models 同批 hot-apply。
|
|
113
198
|
const quotaWeights = {};
|
|
114
199
|
for (const m of enabled) {
|
|
115
200
|
const qw = typeof m.quotaWeight === "number" && Number.isFinite(m.quotaWeight) && m.quotaWeight > 0 ? m.quotaWeight : undefined;
|
|
@@ -127,27 +212,53 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
127
212
|
else if ("select" in tgt)
|
|
128
213
|
roles[role] = { select: tgt.select };
|
|
129
214
|
}
|
|
215
|
+
// registry-core 0.9.0: tier groups → the engine's single active tier table. `resolveActiveTiers`
|
|
216
|
+
// is registry-core's ONE resolution point (active group → its bound tiers; no active / dangling / all-unbound
|
|
217
|
+
// → undefined = INERT). Values are catalog NAME strings (open, not enum'd); dangling bindings were already
|
|
218
|
+
// culled center-side. mutateInPlace keeps the reference RunnerDeps.tiers holds — the expansion itself happens
|
|
219
|
+
// at Runner CONSTRUCTION (core 1.265 expandTiers), so a refresh-time change is restart-to-apply like models.
|
|
220
|
+
// NOTE: the wire face (this module's EffectiveConfig) carries the JSON body verbatim, so tierGroups ride
|
|
221
|
+
// eff.models even though CenterModel doesn't type them — resolveActiveTiers reads them structurally.
|
|
130
222
|
const activeTiers = resolveActiveTiers(eff.models) ?? {};
|
|
223
|
+
// [865]①(clay 生产实锤:onboard 选 kimi 实跑 Qwen)显式默认解析——enabled[0] 会被任何改变 pool 顺序的写
|
|
224
|
+
// 静默翻转,default 必须消费 wire 里已有的显式意图。解析单源 = resolveDefaultModelName(dry-run 的
|
|
225
|
+
// wouldDefaultModel 共用同一只,报数与真 apply 永不撕裂——codex M2)。
|
|
131
226
|
const picked = resolveDefaultModelName(eff, (n) => models[n] !== undefined, enabled[0].name, (source, name) => logger?.warn("sema_registry_default_dangling", { source, name, hint: "explicit default names a model that is not in the enabled catalog — falling to the next source" }));
|
|
132
227
|
const defaultName = picked.name;
|
|
133
228
|
const defaultSource = picked.source;
|
|
134
229
|
models.default = models[defaultName];
|
|
135
|
-
mutateInPlace(config.models, models);
|
|
230
|
+
mutateInPlace(config.models, models); // IN PLACE: keep the ref the Runner + /v1/models share (hot-apply)
|
|
136
231
|
config.model = config.models.default;
|
|
137
232
|
if (Object.keys(roles).length > 0)
|
|
138
|
-
mutateInPlace(config.roles, roles);
|
|
233
|
+
mutateInPlace(config.roles, roles); // IN PLACE: Runner reads this.deps.roles live
|
|
139
234
|
mutateInPlace(config.tiers, activeTiers);
|
|
140
235
|
logger?.info("sema_registry_models", { count: enabled.length, default: config.model.id, defaultSource, roles: Object.keys(roles), tiers: Object.keys(config.tiers), sealedKeys: Object.values(modelApiKeys).filter((v) => typeof v === "string").length, sealedPoisoned: Object.values(modelApiKeys).filter((v) => typeof v !== "string").length });
|
|
141
236
|
}
|
|
237
|
+
// Runtime governance/limit gates (phase-2): STARTUP only (restart-to-apply) — the live RateLimiter / CostQuota
|
|
238
|
+
// / approval gate are built from `config` AFTER this in main.ts, so mutating it here before they're constructed
|
|
239
|
+
// is what takes effect; a refresh (teamsOnly) must NOT touch them (the running gates hold their boot values).
|
|
240
|
+
// governance 切新位:治理三件优先读 governance 域(真值),runtime 旧位(双写镜像)fallback——
|
|
241
|
+
// 双写期两处逐键相等语义不变;center 撤双写后 governance 即唯一来源。限额残余(rateLimit/cost 五件)仍在 runtime。
|
|
142
242
|
const gatesView = eff.governance ? { ...eff.runtime, ...eff.governance } : eff.runtime;
|
|
143
243
|
if (!opts.teamsOnly)
|
|
144
244
|
applyRuntimeGates(config, gatesView, logger);
|
|
245
|
+
// Runtime governance "second baton" (center §10): autonomy + commandPolicy are per-request HOT (read live in
|
|
246
|
+
// resolveSpec), NOT baked into boot middleware → apply on BOTH boot and refresh (outside the teamsOnly guard) so
|
|
247
|
+
// they hot-reload. No restart-to-apply signal (they take effect on the next task without a restart).
|
|
145
248
|
applyRuntimeHot(config, gatesView, logger);
|
|
249
|
+
// Teams → registry (hot-reloadable; center overrides/extends the built-ins).
|
|
250
|
+
// codex R11: teams + collab workflows carry MODEL REFERENCES (member.model / workflow model args) — when the
|
|
251
|
+
// model plane is deferred (tier-frozen Runner, see the deferModelPlane guard above) these faces must defer
|
|
252
|
+
// WITH it, or a candidate that atomically adds/retargets a model AND updates a team/workflow to reference it
|
|
253
|
+
// publishes a mixed generation: the new template goes live while config.models/the Runner stay old (a new ref
|
|
254
|
+
// fails as unknown; a same-name retarget silently executes stale). One catalog generation = one visibility.
|
|
146
255
|
if (opts.deferModelPlane !== true) {
|
|
147
256
|
const teams = {};
|
|
148
257
|
for (const t of (eff.teams?.teams ?? []).filter((t) => t.enabled !== false)) {
|
|
149
258
|
teams[t.name] = {
|
|
150
259
|
name: t.name,
|
|
260
|
+
// F8: honor member.model (core TeamMember.model supports it) — was silently dropped, leaving the
|
|
261
|
+
// member to fall back to the "team" role instead of the operator's chosen model.
|
|
151
262
|
members: t.members.map((mm) => ({ role: mm.role, ...(mm.model ? { model: mm.model } : {}), modelRole: mm.modelRole, systemPrompt: mm.systemPrompt })),
|
|
152
263
|
rounds: t.rounds,
|
|
153
264
|
synthesizer: t.synthesizer ? { role: t.synthesizer.role, modelRole: t.synthesizer.modelRole, systemPrompt: t.synthesizer.systemPrompt } : undefined,
|
|
@@ -156,6 +267,11 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
156
267
|
registerTeams(teams);
|
|
157
268
|
if (Object.keys(teams).length > 0)
|
|
158
269
|
logger?.info("sema_registry_teams", { teams: Object.keys(teams) });
|
|
270
|
+
// collab → named-workflow projection(切片 1.5,design/140 统一解;切片① 的
|
|
271
|
+
// TeamTemplate 投影已整体替换——纪律「别留双路径降级」)。可投影子集翻译成命名 workflow 注册条目
|
|
272
|
+
// (执行体=core 内置 team-discussion 脚本,center 模板=defaultArgs 合并链第二级;键=collab id,shell
|
|
273
|
+
// `/team`/LLM 经 Workflow({name}) 调用);子集外整条跳过+结构化上报,绝不静默降级。HOT:boot+refresh
|
|
274
|
+
// 双腿整表替换(非粘——center 停发即空表,内置 workflow 不受影响)。
|
|
159
275
|
const projected = projectCollabToWorkflows(eff.collab?.templates);
|
|
160
276
|
registerCollabWorkflows(projected.workflows);
|
|
161
277
|
if (Object.keys(projected.workflows).length > 0)
|
|
@@ -165,6 +281,11 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
165
281
|
if (projected.notes.length > 0)
|
|
166
282
|
logger?.info("sema_registry_collab_notes", { notes: projected.notes });
|
|
167
283
|
}
|
|
284
|
+
// 142-S4 projects 域(registry-core 0.10.0):center 项目登记簿 → config.projects(键=
|
|
285
|
+
// projectId)。消费是 per-request 查表(memoryScope 派生 + defaultScopes 种子,security.ts/main.ts),
|
|
286
|
+
// 所以 boot+refresh 双腿都 mutateInPlace 热应用(整表替换,非粘——center 停发即清空);env lane 恒空。
|
|
287
|
+
// 宽读:域包裹 `{projects:{...}}`(registry-core ProjectsConfig 真形状)与裸 Record 都认(projectId=UUID,
|
|
288
|
+
// 永不撞 "projects" 字面键);防御:非 object 条目跳过,字段逐个验型(wire verbatim,不信任形状)。
|
|
168
289
|
const projDomain = eff.projects;
|
|
169
290
|
const rawProjects = (projDomain && typeof projDomain === "object" && !Array.isArray(projDomain)
|
|
170
291
|
? "projects" in projDomain && typeof projDomain.projects === "object"
|
|
@@ -174,7 +295,7 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
174
295
|
const projects = {};
|
|
175
296
|
for (const [pid, reg] of Object.entries(rawProjects)) {
|
|
176
297
|
if (!reg || typeof reg !== "object" || Array.isArray(reg))
|
|
177
|
-
continue;
|
|
298
|
+
continue; // defensive: non-object entry → skip
|
|
178
299
|
const r = reg;
|
|
179
300
|
projects[pid] = {
|
|
180
301
|
...(typeof r.displayName === "string" ? { displayName: r.displayName } : {}),
|
|
@@ -182,11 +303,36 @@ export function applyEffective(config, eff, logger, opts = {}) {
|
|
|
182
303
|
...(Array.isArray(r.defaultScopes) ? { defaultScopes: r.defaultScopes.filter((x) => typeof x === "string") } : {}),
|
|
183
304
|
};
|
|
184
305
|
}
|
|
185
|
-
mutateInPlace(config.projects, projects);
|
|
306
|
+
mutateInPlace(config.projects, projects); // IN PLACE: keep the ref per-request consumers captured at boot
|
|
186
307
|
if (Object.keys(projects).length > 0)
|
|
187
308
|
logger?.info("sema_registry_projects", { projects: Object.keys(projects) });
|
|
188
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Apply the center `runtime` governance/limit gates OVER the env-derived config (mutates `config`).
|
|
312
|
+
*
|
|
313
|
+
* UNIFORM presence semantics across all 6 gates (center `f95438a` adopted this from our sentinel flag —
|
|
314
|
+
* SERVICE-INTEGRATION「Runtime 治理/限额闸」): all six fields are center `.optional()`, so
|
|
315
|
+
* `undefined` = center isn't managing it → KEEP env;
|
|
316
|
+
* present (any value, INCLUDING an explicit 0 / [] = "publish the gate OFF") → OVERRIDE env.
|
|
317
|
+
* (Earlier center had `rateLimitPerMin`/`approvalRequire` as `.default(0/[])`, which would have let a default
|
|
318
|
+
* silently disable an env-set gate — we flagged it, center made all six optional, so a plain presence rule is
|
|
319
|
+
* now both correct and uniform. No sentinel special-casing.)
|
|
320
|
+
*
|
|
321
|
+
* Only guard: `costQuotaWindowSec` must be `> 0` (a 0 window is nonsensical — core divides by it). Center's
|
|
322
|
+
* schema is `.positive()` so it can't send 0; this is belt-and-suspenders.
|
|
323
|
+
*
|
|
324
|
+
* Per-worker overrides ride the per-worker `/effective?worker=` response (center merges WorkerSpec.runtime over
|
|
325
|
+
* the fleet default server-side), so this single "effective beats env" rule already honors per-worker > fleet.
|
|
326
|
+
*/
|
|
327
|
+
/** The 6 runtime governance/limit gates, in ONE place (council DRY): the consume loop, the restart-to-apply
|
|
328
|
+
* signal, and the dry-run diff all derive from this list, so adding a 7th gate is a single edit and can't
|
|
329
|
+
* silently miss `runtimeHasActiveGate` (which would break the restart-to-apply warning). All six share keys
|
|
330
|
+
* across `EffectiveConfig["runtime"]` and `ServiceConfig`. Exported (not in the original single-file form) so
|
|
331
|
+
* the sibling restart-signal module can share the identical key list + presence rule. */
|
|
189
332
|
export const RUNTIME_GATE_KEYS = ["rateLimitPerMin", "approvalRequire", "maxTaskCostUsd", "maxTaskTokens", "maxPrincipalCostUsd", "costQuotaWindowSec"];
|
|
333
|
+
/** Uniform presence rule (center f95438a): a gate is "managed" when the field is present — any number (incl. 0),
|
|
334
|
+
* or an array for approvalRequire. Sole guard: costQuotaWindowSec must be > 0 (a 0 window is nonsensical — core
|
|
335
|
+
* divides by it; center's `.positive()` already enforces, belt-and-suspenders here). */
|
|
190
336
|
export function runtimeGatePresent(rt, key) {
|
|
191
337
|
const v = rt[key];
|
|
192
338
|
if (key === "approvalRequire")
|
|
@@ -201,21 +347,42 @@ export function applyRuntimeGates(config, rt, logger) {
|
|
|
201
347
|
const applied = {};
|
|
202
348
|
for (const key of RUNTIME_GATE_KEYS) {
|
|
203
349
|
if (!runtimeGatePresent(rt, key))
|
|
204
|
-
continue;
|
|
205
|
-
config[key] = rt[key];
|
|
350
|
+
continue; // undefined / sentinel → keep env
|
|
351
|
+
config[key] = rt[key]; // present (incl. explicit 0/[]) → override
|
|
206
352
|
applied[key] = rt[key];
|
|
207
353
|
}
|
|
208
354
|
if (Object.keys(applied).length > 0)
|
|
209
355
|
logger?.info("sema_registry_runtime", applied);
|
|
210
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Apply the runtime governance "second baton" (center §10): `autonomy` + `commandPolicy`. UNLIKE the 6 gates in
|
|
359
|
+
* {@link applyRuntimeGates}, these are per-request HOT (read live in main.ts `resolveSpec` via
|
|
360
|
+
* `applyRuntimeGovernance`), so they apply on BOTH boot and refresh (NOT via RUNTIME_GATE_KEYS / restart-to-apply).
|
|
361
|
+
*
|
|
362
|
+
* 🔴 NON-STICKY (differs from the restart-to-apply gates on purpose — adversarial-review HIGH): a hot field that
|
|
363
|
+
* center STOPS publishing must REVERT to the env baseline, not keep the last center value. The restart-to-apply
|
|
364
|
+
* gates can be sticky because a refresh never touches them (the running middleware holds boot values until a
|
|
365
|
+
* restart re-reads env+center); a HOT field has no such reset, so "absent ⇒ keep" would silently freeze a stale
|
|
366
|
+
* center override (e.g. center published `auto`, then un-published it — the gate would stay OFF forever). So we
|
|
367
|
+
* recompute every call as `present ? center : envBaseline`. The env baseline = `AUTONOMY` (re-derived, env is
|
|
368
|
+
* immutable at runtime) for autonomy; `undefined` (no env scalar source) for commandPolicy.
|
|
369
|
+
*
|
|
370
|
+
* 🔴 commandPolicy is VALIDATED here (adversarial-review HIGH): an invalid command (glob/path/operator — which
|
|
371
|
+
* core's EXACT-name matcher would silently never match → a hole) is rejected FAIL-LOUD and the prior good policy
|
|
372
|
+
* is KEPT (a broken publish never half-applies a silently-weakened gate).
|
|
373
|
+
*/
|
|
211
374
|
export function applyRuntimeHot(config, rt, logger) {
|
|
212
375
|
const applied = {};
|
|
376
|
+
// autonomy: present ⇒ center value; absent ⇒ revert to the env baseline (never a stale center override).
|
|
213
377
|
const envAutonomy = parseAutonomy(process.env.AUTONOMY);
|
|
214
378
|
const nextAutonomy = rt?.autonomy !== undefined ? rt.autonomy : envAutonomy;
|
|
215
379
|
if (config.autonomy !== nextAutonomy) {
|
|
216
380
|
config.autonomy = nextAutonomy;
|
|
217
381
|
applied.autonomy = nextAutonomy ?? "(env-baseline)";
|
|
218
382
|
}
|
|
383
|
+
// commandPolicy: present+valid ⇒ apply; present+invalid ⇒ fail-loud + keep prior; absent ⇒ revert to baseline
|
|
384
|
+
// (undefined — no env scalar source for structured command rules). Only re-set + log on an ACTUAL change
|
|
385
|
+
// (deep-equal compare) — refresh runs every ~60s and the policy is usually unchanged; logging every tick = noise.
|
|
219
386
|
if (rt?.commandPolicy !== undefined) {
|
|
220
387
|
const errors = validateCommandRules(rt.commandPolicy);
|
|
221
388
|
if (errors.length > 0) {
|
|
@@ -223,17 +390,32 @@ export function applyRuntimeHot(config, rt, logger) {
|
|
|
223
390
|
}
|
|
224
391
|
else if (JSON.stringify(config.commandPolicy) !== JSON.stringify(rt.commandPolicy)) {
|
|
225
392
|
config.commandPolicy = rt.commandPolicy;
|
|
226
|
-
applied.commandPolicy = rt.commandPolicy.length;
|
|
393
|
+
applied.commandPolicy = rt.commandPolicy.length; // log the COUNT, not the rules (avoid leaking on every refresh)
|
|
227
394
|
}
|
|
228
395
|
}
|
|
229
396
|
else if (config.commandPolicy !== undefined) {
|
|
230
|
-
config.commandPolicy = undefined;
|
|
397
|
+
config.commandPolicy = undefined; // center stopped managing → revert to baseline (no env source)
|
|
231
398
|
applied.commandPolicy = "(env-baseline)";
|
|
232
399
|
}
|
|
233
400
|
if (Object.keys(applied).length > 0)
|
|
234
401
|
logger?.info("sema_registry_runtime_hot", applied);
|
|
235
402
|
}
|
|
403
|
+
/** [865]①/H3:activeTierGroup 档绑定当默认时的档梯,与 core 单一语义源逐字对齐(core roles.js:
|
|
404
|
+
* `ROLE_TIER_DEFAULTS.default = "pro"` + `resolveTier` 从本档位置**只向低档**扫 DEFAULT_TIER_ORDER
|
|
405
|
+
* [ultra,max,pro,flash,lite] ⇒ pro→flash→lite,绝不向上抓 max/ultra——引擎运行时对 "default" 角色就是
|
|
406
|
+
* 这么解析的,applyEffective 的 default 若用别的梯子会与真路由再度撕裂,codex H3)。 */
|
|
236
407
|
const DEFAULT_ROLE_TIER_LADDER = ["pro", "flash", "lite"];
|
|
408
|
+
/**
|
|
409
|
+
* [865]① 显式默认解析——applyEffective 与 dry-run(logEffectiveDiff.wouldDefaultModel)共用的单源。优先级
|
|
410
|
+
* (显式源指向不在目录/未启用的名 ⇒ onDangling 回调后落下一级,绝不静默指错模型):
|
|
411
|
+
* 1) eff.models.default 结构键 —— ✅ 既得路径([874] registry-core 0.10.11 落 `default?: string` schema
|
|
412
|
+
* 键+per-worker /effective 直通;本地 lane 由 config-provider mapToServiceEffective 直通)。写面悬空 ref
|
|
413
|
+
* 由 registry-core superRefine fail-loud;存量/未经 schema 路径仍走本函数的 warn 降级(双层姿势与
|
|
414
|
+
* activeTierGroup 同构)。(1.200-1.202 期间此级恒空=当时如实的前行 seam,codex H2 注记已兑现。)
|
|
415
|
+
* 2) roles.default 的显式 {model} 绑定(现有 wire 真源)。
|
|
416
|
+
* 3) activeTierGroup 档绑定,按 {@link DEFAULT_ROLE_TIER_LADDER}(= core 对 "default" 角色的档语义)。
|
|
417
|
+
* 4) fallback(enabled[0]——原兜底,唯一不触发 onDangling 的落点)。
|
|
418
|
+
*/
|
|
237
419
|
export function resolveDefaultModelName(eff, has, fallback, onDangling) {
|
|
238
420
|
const activeTiers = resolveActiveTiers(eff.models) ?? {};
|
|
239
421
|
const structural = eff.models?.default;
|
|
@@ -252,6 +434,11 @@ export function resolveDefaultModelName(eff, has, fallback, onDangling) {
|
|
|
252
434
|
}
|
|
253
435
|
return { name: fallback, source: "enabled[0]" };
|
|
254
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* Read-only comparison (SEMA_REGISTRY_DRY_RUN): log what the center config WOULD change vs the current
|
|
439
|
+
* (env-derived) config, WITHOUT applying it. The safe-rollout step the sema-registry recommends — verify
|
|
440
|
+
* the center's models/roles/teams match (or intentionally differ from) the env baseline before going live.
|
|
441
|
+
*/
|
|
255
442
|
export function logEffectiveDiff(config, eff, logger) {
|
|
256
443
|
const enabled = (eff.models?.models ?? []).filter((m) => m.enabled !== false);
|
|
257
444
|
const centerModels = enabled.map((m) => ({ name: m.name, id: m.id, provider: m.provider, apiKeyEnv: m.apiKeyEnv ?? null, tier: m.tier ?? null }));
|
|
@@ -261,7 +448,9 @@ export function logEffectiveDiff(config, eff, logger) {
|
|
|
261
448
|
logger?.warn("sema_registry_dry_run", {
|
|
262
449
|
note: "DRY RUN — registry config NOT applied; unset SEMA_REGISTRY_DRY_RUN to go live",
|
|
263
450
|
version: eff.version,
|
|
264
|
-
wouldOverrideModels: enabled.length > 0,
|
|
451
|
+
wouldOverrideModels: enabled.length > 0, // empty/unpublished center → env baseline kept (no override)
|
|
452
|
+
// [865]①/codex M2:与 applyEffective 同一只解析器——dry-run 的上线前核验必须报真 apply 会选的默认,
|
|
453
|
+
// 报 enabled[0] 会让核验对显式默认(roles.default/tier 档)配置给出错误结论。
|
|
265
454
|
wouldDefaultModel: enabled.length > 0 ? resolveDefaultModelName(eff, (n) => enabled.some((m) => m.name === n), enabled[0].name).name : null,
|
|
266
455
|
currentDefaultModel: config.model.id,
|
|
267
456
|
models: { center: centerModels, envDerived: envModels },
|
|
@@ -270,11 +459,14 @@ export function logEffectiveDiff(config, eff, logger) {
|
|
|
270
459
|
skills: { centerWouldLoad: (eff.skills?.skills ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
|
|
271
460
|
mcp: { centerWouldRegister: (eff.mcp?.servers ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
|
|
272
461
|
runtime: {
|
|
462
|
+
// What the gates would become if applied (present center value overrides; absent → kept env shown as current).
|
|
273
463
|
center: eff.runtime ?? null,
|
|
274
464
|
current: Object.fromEntries(RUNTIME_GATE_KEYS.map((k) => [k, config[k]])),
|
|
275
465
|
},
|
|
276
466
|
});
|
|
277
467
|
}
|
|
468
|
+
/** True if the center `runtime` carries any managed gate (a PRESENT field) — i.e. a refresh that changed it
|
|
469
|
+
* needs a restart to take effect (restart-to-apply). Same key list + presence rule as applyRuntimeGates. */
|
|
278
470
|
export function runtimeHasActiveGate(rt) {
|
|
279
471
|
if (!rt)
|
|
280
472
|
return false;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import type { EntitlementRuntimeCaps } from "@sema-agent/registry-core";
|
|
2
2
|
import type { ScenarioRuling } from "../capabilities/scenarios.js";
|
|
3
3
|
import type { EffectiveConfig, ExecutionRuling } from "./types.js";
|
|
4
|
+
/** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error. */
|
|
4
5
|
export declare function fetchEffective(baseUrl: string, token: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
|
|
5
6
|
effective: EffectiveConfig;
|
|
6
7
|
etag?: string;
|
|
7
8
|
} | null>;
|
|
9
|
+
/**
|
|
10
|
+
* design/99 §K (core 1.157 `RunnerDeps.runtimeCapsResolver`) — GET the PER-PRINCIPAL runtime
|
|
11
|
+
* ENTITLEMENTS the engine enforces server-side, from center's `GET /api/config/effective?principal=&worker=`.
|
|
12
|
+
* Center pre-resolves the tighten-only intersection (fleet defaults ∩ tier ⊕ roles + overrides) and returns a
|
|
13
|
+
* `runtimeCaps` block — the service passes it through verbatim (no further tightening, per center's ruling).
|
|
14
|
+
*
|
|
15
|
+
* 🔐 TOKEN/WORKER (center ruling, sema-registry `aeb4979`): two valid postures —
|
|
16
|
+
* • FULL `SERVICE_PULL_TOKEN` + `?principal=` → full per-user body (caps + per-user config).
|
|
17
|
+
* • worker-scoped `wpt_<self>` + `?principal=&worker=<self>` → **caps-only** body (`{principal, configured,
|
|
18
|
+
* runtimeCaps, budget}`; never other tenants' config) — a worker MAY resolve its OWN worker's principals.
|
|
19
|
+
* A `wpt_` with NO `?worker=` (or a mismatched worker) still 403s. So we ALWAYS pass `?worker=` when the
|
|
20
|
+
* deployment has one (`SEMA_REGISTRY_WORKER`): it authorizes the wpt_ path AND is harmless on the full token
|
|
21
|
+
* (the caps value is worker-independent — `resolveEntitlement` resolves from the principal alone; worker only
|
|
22
|
+
* scopes the config view we ignore). This re-adds the `worker` arg dropped in 1.14.0 (L2-3) — center's ruling
|
|
23
|
+
* makes it load-bearing for AUTHORIZATION, not for the caps value.
|
|
24
|
+
* `null` = 304 (caller keeps its cached value). THROWS on transport / non-304 HTTP error → the resolver
|
|
25
|
+
* fail-closes (core then DENIES the optional `allowWorkflows` cap — an outage must never silently GRANT). ETag is
|
|
26
|
+
* content-hashed (`p-<hash>`); an `if-none-match` poll is cheap. Mirrors `fetchEffective` (Bearer + 8s + scheme guard).
|
|
27
|
+
*/
|
|
8
28
|
export declare function fetchPrincipalCaps(baseUrl: string, token: string, principal: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
|
|
9
29
|
runtimeCaps: EntitlementRuntimeCaps | null;
|
|
10
30
|
configured: boolean;
|
|
@@ -13,11 +33,25 @@ export declare function fetchPrincipalCaps(baseUrl: string, token: string, princ
|
|
|
13
33
|
executionDrift?: string;
|
|
14
34
|
etag?: string;
|
|
15
35
|
} | null>;
|
|
36
|
+
/** An HTTP error from a sema-registry fetch that carries the response status so callers can branch on it
|
|
37
|
+
* (e.g. translate a 404 to "unknown hash → undefined") WITHOUT parsing the message string. */
|
|
16
38
|
export declare class ConfigCenterHttpError extends Error {
|
|
17
39
|
readonly status: number;
|
|
18
40
|
constructor(message: string, status: number);
|
|
19
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Fetch one skill's body by content hash (`GET /api/config/skills/content/<hash>`, Bearer) and VERIFY its
|
|
44
|
+
* sha256 matches the manifest hash (integrity + tamper check). The content is immutable per hash, so the
|
|
45
|
+
* caller caches by hash and never re-fetches an unchanged skill. Throws a {@link ConfigCenterHttpError}
|
|
46
|
+
* (carrying `.status`) on an HTTP error — INCLUDING 404 — or a plain Error on hash mismatch. Callers that
|
|
47
|
+
* want "unknown hash → undefined" parity with the local backend inspect `.status === 404` and swallow it;
|
|
48
|
+
* the legacy `applyCenterSkills` path keeps treating every throw as "skip this skill, keep baseline".
|
|
49
|
+
*/
|
|
20
50
|
export declare function fetchSkillContent(baseUrl: string, token: string, contentHash: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
51
|
+
/** [985]b / [1285]① — §9.4 by-digest 补拉二函(fetchSkillContent 同姿势:HTTP+Bearer+8s 超时+
|
|
52
|
+
* 消费侧自证)。artifact=envelope JSON(验真=调用方过 core verifyPromptArtifact,canonical 重算——
|
|
53
|
+
* 本函数只做传输与形读,不越权解释);blob=段文本 raw-byte(sha256 逐位自证,fetchSkillContent 同款)。
|
|
54
|
+
* digest 参数收带前缀/裸 hex 两形([1285] 参数口径)。 */
|
|
21
55
|
export declare function fetchPromptArtifact(baseUrl: string, token: string, artifactDigest: string, fetchImpl?: typeof fetch): Promise<unknown>;
|
|
22
56
|
export declare function fetchPromptBlob(baseUrl: string, token: string, contentDigest: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
23
57
|
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sema-registry HTTP client — the transport calls the service makes against the config-center
|
|
3
|
+
* (`fetchEffective`/`fetchPrincipalCaps`/`fetchSkillContent`/`fetchPromptArtifact`/`fetchPromptBlob`) plus
|
|
4
|
+
* the shared HTTP-error type. Split out of `sema-registry.ts` (design/158 A13, internal-lossless — the
|
|
5
|
+
* facade re-exports every symbol below unchanged).
|
|
6
|
+
*/
|
|
1
7
|
import { createHash } from "node:crypto";
|
|
8
|
+
/** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error. */
|
|
2
9
|
export async function fetchEffective(baseUrl, token, etag, fetchImpl = fetch, worker) {
|
|
10
|
+
// Defensive scheme guard: Node's fetch supports file:// — a mis-set
|
|
11
|
+
// SEMA_REGISTRY_URL must not turn into a local-file read. Reject anything but http(s).
|
|
3
12
|
const scheme = new URL(baseUrl).protocol;
|
|
4
13
|
if (scheme !== "http:" && scheme !== "https:")
|
|
5
14
|
throw new Error(`SEMA_REGISTRY_URL must be http(s), got "${scheme}"`);
|
|
15
|
+
// worker-scoped pull: `?worker=<name>` returns that worker's roster; omitted → the global roster
|
|
16
|
+
// (backward compatible — the center returns today's global config when no worker is given).
|
|
6
17
|
const url = `${baseUrl.replace(/\/+$/, "")}/api/config/effective${worker ? `?worker=${encodeURIComponent(worker)}` : ""}`;
|
|
7
18
|
const res = await fetchImpl(url, {
|
|
8
19
|
headers: { authorization: `Bearer ${token}`, ...(etag ? { "if-none-match": etag } : {}) },
|
|
@@ -14,10 +25,30 @@ export async function fetchEffective(baseUrl, token, etag, fetchImpl = fetch, wo
|
|
|
14
25
|
throw new Error(`sema-registry HTTP ${res.status}`);
|
|
15
26
|
return { effective: (await res.json()), etag: res.headers.get("etag") ?? undefined };
|
|
16
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* design/99 §K (core 1.157 `RunnerDeps.runtimeCapsResolver`) — GET the PER-PRINCIPAL runtime
|
|
30
|
+
* ENTITLEMENTS the engine enforces server-side, from center's `GET /api/config/effective?principal=&worker=`.
|
|
31
|
+
* Center pre-resolves the tighten-only intersection (fleet defaults ∩ tier ⊕ roles + overrides) and returns a
|
|
32
|
+
* `runtimeCaps` block — the service passes it through verbatim (no further tightening, per center's ruling).
|
|
33
|
+
*
|
|
34
|
+
* 🔐 TOKEN/WORKER (center ruling, sema-registry `aeb4979`): two valid postures —
|
|
35
|
+
* • FULL `SERVICE_PULL_TOKEN` + `?principal=` → full per-user body (caps + per-user config).
|
|
36
|
+
* • worker-scoped `wpt_<self>` + `?principal=&worker=<self>` → **caps-only** body (`{principal, configured,
|
|
37
|
+
* runtimeCaps, budget}`; never other tenants' config) — a worker MAY resolve its OWN worker's principals.
|
|
38
|
+
* A `wpt_` with NO `?worker=` (or a mismatched worker) still 403s. So we ALWAYS pass `?worker=` when the
|
|
39
|
+
* deployment has one (`SEMA_REGISTRY_WORKER`): it authorizes the wpt_ path AND is harmless on the full token
|
|
40
|
+
* (the caps value is worker-independent — `resolveEntitlement` resolves from the principal alone; worker only
|
|
41
|
+
* scopes the config view we ignore). This re-adds the `worker` arg dropped in 1.14.0 (L2-3) — center's ruling
|
|
42
|
+
* makes it load-bearing for AUTHORIZATION, not for the caps value.
|
|
43
|
+
* `null` = 304 (caller keeps its cached value). THROWS on transport / non-304 HTTP error → the resolver
|
|
44
|
+
* fail-closes (core then DENIES the optional `allowWorkflows` cap — an outage must never silently GRANT). ETag is
|
|
45
|
+
* content-hashed (`p-<hash>`); an `if-none-match` poll is cheap. Mirrors `fetchEffective` (Bearer + 8s + scheme guard).
|
|
46
|
+
*/
|
|
17
47
|
export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchImpl = fetch, worker) {
|
|
18
48
|
const scheme = new URL(baseUrl).protocol;
|
|
19
49
|
if (scheme !== "http:" && scheme !== "https:")
|
|
20
50
|
throw new Error(`SEMA_REGISTRY_URL must be http(s), got "${scheme}"`);
|
|
51
|
+
// `?principal=<id>[&worker=<self>]` — worker authorizes the wpt_<self> caps-only path; harmless on a full token.
|
|
21
52
|
const params = new URLSearchParams({ principal });
|
|
22
53
|
if (worker)
|
|
23
54
|
params.set("worker", worker);
|
|
@@ -27,6 +58,9 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
|
|
|
27
58
|
signal: AbortSignal.timeout(8000),
|
|
28
59
|
});
|
|
29
60
|
if (res.status === 304) {
|
|
61
|
+
// A 304 is only valid as a reply to OUR conditional. If we sent no etag and still got 304, center is
|
|
62
|
+
// misbehaving — DON'T treat it as "unchanged" (that surfaces undefined caps = no restriction = fail OPEN).
|
|
63
|
+
// Throw so the resolver fail-closes (review B). With an etag, 304 = genuine "unchanged" → null.
|
|
30
64
|
if (!etag)
|
|
31
65
|
throw new Error("sema-registry returned 304 to a non-conditional principal-caps request");
|
|
32
66
|
return null;
|
|
@@ -37,6 +71,10 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
|
|
|
37
71
|
return {
|
|
38
72
|
runtimeCaps: body.runtimeCaps ?? null,
|
|
39
73
|
configured: Boolean(body.configured),
|
|
74
|
+
// The caps view carries the RESOLVED per-principal scenario ruling (two keys, shape pinned
|
|
75
|
+
// by center tests). An older center has NO such keys → undefined (no governance, legacy passthrough) —
|
|
76
|
+
// distinct from the "assigned nothing" ruling {scenario:null, allowlist:[]} a newer center returns.
|
|
77
|
+
// Defensive on shape (scenario face is fail-open — see gateScenarioRequest): non-string entries dropped.
|
|
40
78
|
...("scenario" in body || "allowlist" in body
|
|
41
79
|
? {
|
|
42
80
|
scenario: {
|
|
@@ -45,6 +83,15 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
|
|
|
45
83
|
},
|
|
46
84
|
}
|
|
47
85
|
: {}),
|
|
86
|
+
// (stage7 P5, registry-core 0.8 execution 域): the caps view's per-principal execution
|
|
87
|
+
// ruling `{required, allowedLanes}` — same car, same no-cache semantics as the scenario ruling. An
|
|
88
|
+
// older center has no key → undefined (no enforcement). allowedLanes is an OPEN value domain
|
|
89
|
+
// (adding a lane is never BREAKING) — tolerate unknown names, drop non-string ELEMENTS defensively.
|
|
90
|
+
// shape DRIFT (required non-boolean / allowedLanes non-array) must NOT be
|
|
91
|
+
// coerced — the old coercion turned "allowedLanes came as a comma string" + required=true into
|
|
92
|
+
// allowedLanes=[] = fleet-wide deny-all (fail-CLOSED on a wire glitch, opposite of the fail-open posture)
|
|
93
|
+
// and a drifted `required` into silent non-enforcement. Now: drift ⇒ DROP the whole ruling (fail-open,
|
|
94
|
+
// gate passes) + `executionDrift` so the caller's audit line fires (the resolver routes it to onError).
|
|
48
95
|
...((() => {
|
|
49
96
|
const ex = body.execution;
|
|
50
97
|
if (ex === undefined || ex === null)
|
|
@@ -54,6 +101,10 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
|
|
|
54
101
|
if (!Array.isArray(ex.allowedLanes))
|
|
55
102
|
return { executionDrift: `execution.allowedLanes is ${typeof ex.allowedLanes}, expected string[] — ruling dropped (fail-open)` };
|
|
56
103
|
const execution = { required: ex.required, allowedLanes: ex.allowedLanes.filter((s) => typeof s === "string") };
|
|
104
|
+
// registry-core 0.10.1-0.10.2:execution.sessionMirror 宽读。observation-only 子面
|
|
105
|
+
// (server 非执法端,见 ExecutionRuling.sessionMirror 注),所以形状漂移只丢**本子面**并走 executionDrift
|
|
106
|
+
// 审计线(resolver 路由到 onError),**绝不**连带丢 lane ruling(那是真执法面,不能被观测子面拖垮)。
|
|
107
|
+
// required 缺省 false = registry-core zod 默认(便利态);engineUrl 必须非空 string。
|
|
57
108
|
if (ex.sessionMirror !== undefined && ex.sessionMirror !== null) {
|
|
58
109
|
const sm = ex.sessionMirror;
|
|
59
110
|
const smOk = typeof sm === "object" && typeof sm.engineUrl === "string" && sm.engineUrl.length > 0 && (sm.required === undefined || typeof sm.required === "boolean");
|
|
@@ -67,6 +118,8 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
|
|
|
67
118
|
etag: res.headers.get("etag") ?? undefined,
|
|
68
119
|
};
|
|
69
120
|
}
|
|
121
|
+
/** An HTTP error from a sema-registry fetch that carries the response status so callers can branch on it
|
|
122
|
+
* (e.g. translate a 404 to "unknown hash → undefined") WITHOUT parsing the message string. */
|
|
70
123
|
export class ConfigCenterHttpError extends Error {
|
|
71
124
|
status;
|
|
72
125
|
constructor(message, status) {
|
|
@@ -75,6 +128,14 @@ export class ConfigCenterHttpError extends Error {
|
|
|
75
128
|
this.name = "ConfigCenterHttpError";
|
|
76
129
|
}
|
|
77
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetch one skill's body by content hash (`GET /api/config/skills/content/<hash>`, Bearer) and VERIFY its
|
|
133
|
+
* sha256 matches the manifest hash (integrity + tamper check). The content is immutable per hash, so the
|
|
134
|
+
* caller caches by hash and never re-fetches an unchanged skill. Throws a {@link ConfigCenterHttpError}
|
|
135
|
+
* (carrying `.status`) on an HTTP error — INCLUDING 404 — or a plain Error on hash mismatch. Callers that
|
|
136
|
+
* want "unknown hash → undefined" parity with the local backend inspect `.status === 404` and swallow it;
|
|
137
|
+
* the legacy `applyCenterSkills` path keeps treating every throw as "skip this skill, keep baseline".
|
|
138
|
+
*/
|
|
78
139
|
export async function fetchSkillContent(baseUrl, token, contentHash, fetchImpl = fetch) {
|
|
79
140
|
const url = `${baseUrl.replace(/\/+$/, "")}/api/config/skills/content/${encodeURIComponent(contentHash)}`;
|
|
80
141
|
const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
|
|
@@ -87,6 +148,10 @@ export async function fetchSkillContent(baseUrl, token, contentHash, fetchImpl =
|
|
|
87
148
|
throw new Error(`skill content hash mismatch for ${contentHash}: computed sha256:${got}`);
|
|
88
149
|
return content;
|
|
89
150
|
}
|
|
151
|
+
/** [985]b / [1285]① — §9.4 by-digest 补拉二函(fetchSkillContent 同姿势:HTTP+Bearer+8s 超时+
|
|
152
|
+
* 消费侧自证)。artifact=envelope JSON(验真=调用方过 core verifyPromptArtifact,canonical 重算——
|
|
153
|
+
* 本函数只做传输与形读,不越权解释);blob=段文本 raw-byte(sha256 逐位自证,fetchSkillContent 同款)。
|
|
154
|
+
* digest 参数收带前缀/裸 hex 两形([1285] 参数口径)。 */
|
|
90
155
|
export async function fetchPromptArtifact(baseUrl, token, artifactDigest, fetchImpl = fetch) {
|
|
91
156
|
const url = `${baseUrl.replace(/\/+$/, "")}/api/config/prompts/epoch-artifacts/${encodeURIComponent(artifactDigest)}`;
|
|
92
157
|
const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
|
|
@@ -99,6 +164,9 @@ export async function fetchPromptBlob(baseUrl, token, contentDigest, fetchImpl =
|
|
|
99
164
|
const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
|
|
100
165
|
if (!res.ok)
|
|
101
166
|
throw new ConfigCenterHttpError(`prompt blob HTTP ${res.status} for ${contentDigest}`, res.status);
|
|
167
|
+
// codex F2(补拉批):哈希必须打在**响应原始字节**上(res.text() 的 UTF-8 宽容解码会剥 BOM/替换坏序列
|
|
168
|
+
// ——验的就不再是送来的字节,content-addressed 完整性破功);验过再严格解码(fatal:true,坏 UTF-8
|
|
169
|
+
// 掷错而非静默替换)。
|
|
102
170
|
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
103
171
|
const want = contentDigest.replace(/^sha256:/, "").toLowerCase();
|
|
104
172
|
const got = createHash("sha256").update(bytes).digest("hex");
|