@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,8 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shell/path helpers for the SSH + ADB `RemoteExecutionEnv` adapters. Kept in ONE place so the
|
|
3
|
+
* security-sensitive quoting can't drift between adapters (council design/#4, #5).
|
|
4
|
+
*/
|
|
1
5
|
import type { FileInfo } from "@sema-agent/core";
|
|
2
6
|
import type { ChildProcess } from "node:child_process";
|
|
7
|
+
/**
|
|
8
|
+
* D5 pipe-destroy grace (parity with core's vendored `EXEC_FORCE_SETTLE_GRACE_MS`, harness/env/nodejs.js):
|
|
9
|
+
* after a `kill()` on an abort/timeout, the child's `close` may NEVER fire — a re-parented grandchild that
|
|
10
|
+
* inherited the stdout/stderr pipe (or a D-state process) can hold those FDs open indefinitely. Our buffered
|
|
11
|
+
* exec already SETTLES the promise synchronously on abort/timeout (no hang), but the dangling pipe FDs leak.
|
|
12
|
+
* So after a kill we arm a short grace timer; if `close` hasn't fired by then we `destroy()` the pipes to
|
|
13
|
+
* force the FDs released. Core does NOT export this const (it's a vendor-local value), so service defines its
|
|
14
|
+
* own — a plain number, not a security/behavioural boundary.
|
|
15
|
+
*/
|
|
3
16
|
export declare const EXEC_FORCE_SETTLE_GRACE_MS = 3000;
|
|
17
|
+
/**
|
|
18
|
+
* D5 helper: arm a one-shot grace timer that `destroy()`s {@link ChildProcess.stdout}/`stderr` if the child's
|
|
19
|
+
* `close` never lands after a kill (a re-parented grandchild holding the pipe → dangling FD). Returns the
|
|
20
|
+
* timer so the caller can {@link clearTimeout} it the moment a real `close` (or any settle) arrives — the timer
|
|
21
|
+
* is `unref`'d so it can never keep the process alive on its own. This ONLY frees pipe FDs; it does NOT settle
|
|
22
|
+
* any promise (the buffered exec already settled synchronously on abort/timeout — that path is unchanged).
|
|
23
|
+
*/
|
|
4
24
|
export declare function armPipeDestroyGrace(child: ChildProcess): ReturnType<typeof setTimeout>;
|
|
25
|
+
/** POSIX single-quote a string for safe interpolation into a remote shell command. */
|
|
5
26
|
export declare function shellQuote(s: string): string;
|
|
27
|
+
/** Derive FileInfo kind from POSIX st_mode bits (raw stat/readdir attrs carry no isDirectory() helper). */
|
|
6
28
|
export declare function kindFromMode(mode?: number): FileInfo["kind"];
|
|
7
29
|
export declare function drainNumEnvWarnings(): Array<{
|
|
8
30
|
env: string;
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D5 pipe-destroy grace (parity with core's vendored `EXEC_FORCE_SETTLE_GRACE_MS`, harness/env/nodejs.js):
|
|
3
|
+
* after a `kill()` on an abort/timeout, the child's `close` may NEVER fire — a re-parented grandchild that
|
|
4
|
+
* inherited the stdout/stderr pipe (or a D-state process) can hold those FDs open indefinitely. Our buffered
|
|
5
|
+
* exec already SETTLES the promise synchronously on abort/timeout (no hang), but the dangling pipe FDs leak.
|
|
6
|
+
* So after a kill we arm a short grace timer; if `close` hasn't fired by then we `destroy()` the pipes to
|
|
7
|
+
* force the FDs released. Core does NOT export this const (it's a vendor-local value), so service defines its
|
|
8
|
+
* own — a plain number, not a security/behavioural boundary.
|
|
9
|
+
*/
|
|
1
10
|
export const EXEC_FORCE_SETTLE_GRACE_MS = 3000;
|
|
11
|
+
/**
|
|
12
|
+
* D5 helper: arm a one-shot grace timer that `destroy()`s {@link ChildProcess.stdout}/`stderr` if the child's
|
|
13
|
+
* `close` never lands after a kill (a re-parented grandchild holding the pipe → dangling FD). Returns the
|
|
14
|
+
* timer so the caller can {@link clearTimeout} it the moment a real `close` (or any settle) arrives — the timer
|
|
15
|
+
* is `unref`'d so it can never keep the process alive on its own. This ONLY frees pipe FDs; it does NOT settle
|
|
16
|
+
* any promise (the buffered exec already settled synchronously on abort/timeout — that path is unchanged).
|
|
17
|
+
*/
|
|
2
18
|
export function armPipeDestroyGrace(child) {
|
|
3
19
|
const t = setTimeout(() => {
|
|
4
20
|
try {
|
|
@@ -6,14 +22,17 @@ export function armPipeDestroyGrace(child) {
|
|
|
6
22
|
child.stderr?.destroy();
|
|
7
23
|
}
|
|
8
24
|
catch {
|
|
25
|
+
/* best-effort pipe teardown — never throw from a timer */
|
|
9
26
|
}
|
|
10
27
|
}, EXEC_FORCE_SETTLE_GRACE_MS);
|
|
11
28
|
t.unref?.();
|
|
12
29
|
return t;
|
|
13
30
|
}
|
|
31
|
+
/** POSIX single-quote a string for safe interpolation into a remote shell command. */
|
|
14
32
|
export function shellQuote(s) {
|
|
15
33
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
16
34
|
}
|
|
35
|
+
/** Derive FileInfo kind from POSIX st_mode bits (raw stat/readdir attrs carry no isDirectory() helper). */
|
|
17
36
|
export function kindFromMode(mode) {
|
|
18
37
|
const t = (mode ?? 0) & 0o170000;
|
|
19
38
|
if (t === 0o040000)
|
|
@@ -22,6 +41,13 @@ export function kindFromMode(mode) {
|
|
|
22
41
|
return "symlink";
|
|
23
42
|
return "file";
|
|
24
43
|
}
|
|
44
|
+
// ── design/158 B4 交接小件:plugins 数值旋钮的 fail-loud ─────────────────────────────────────────────
|
|
45
|
+
// HOST_BG_*/K8S_BG_*/E2B_* 是模块级、import 时读的常量,不走 ServiceConfig;此前手搓
|
|
46
|
+
// `Math.max(min, Math.floor(Number(env ?? "")) || def)` 让非法字面量(`1mb`)静默落默认——与 config.ts
|
|
47
|
+
// boolEnv 修掉的同族病。告警收本模块自带通道(不造 plugins→config 依赖边),main.ts 在 boot 诊断点
|
|
48
|
+
// (logConfigDiagnostics 旁)排空——ESM import 先于 main 体执行,时序成立。
|
|
49
|
+
// 语义逐字承原形:unset/"" 静默默认;显式 0 仍落默认(0 在这族旋钮上无合法语义,关功能走 *_ENABLED);
|
|
50
|
+
// 合法值 floor+min 夹紧。唯一新增行为=非法字面量推一条警告。
|
|
25
51
|
const NUM_ENV_WARNINGS = [];
|
|
26
52
|
const NUM_ENV_SEEN = new Set();
|
|
27
53
|
export function drainNumEnvWarnings() {
|
|
@@ -31,7 +57,7 @@ export function numEnvOr(name, def, min) {
|
|
|
31
57
|
const raw = process.env[name] ?? "";
|
|
32
58
|
const n = Math.floor(Number(raw));
|
|
33
59
|
if (raw !== "" && Number.isNaN(n) && !NUM_ENV_SEEN.has(name)) {
|
|
34
|
-
NUM_ENV_SEEN.add(name);
|
|
60
|
+
NUM_ENV_SEEN.add(name); // 首登记守卫(boolEnv 同款):懒/重复读不无界增长
|
|
35
61
|
NUM_ENV_WARNINGS.push({ env: name, raw });
|
|
36
62
|
}
|
|
37
63
|
return Math.max(min, n || def);
|
|
@@ -1,22 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable resume-at anchor map (E18) — SINGLE-FILE DUAL-DIALECT (design/158 A12 收编). The service-owned
|
|
3
|
+
* eventId→entryId translation: the shell holds the live E2 `eventId` (core never persists it); core's
|
|
4
|
+
* `TaskSpec.resumeAt` takes a persisted `SessionTreeEntry.id`. Keyed (session_id, event_id) so `resolve`
|
|
5
|
+
* is a PK point-lookup. `owner` is the single-DB-fleet null-safe defense-in-depth guard, the data-layer
|
|
6
|
+
* twin of the route's session-owner gate. GC'd with the session (E21 delete). The historical
|
|
7
|
+
* `TiDBResumeAnchorStore` / `PgResumeAnchorStore` class names survive as thin ctor subclasses so every
|
|
8
|
+
* consumer (store-backend.ts, the resume-anchor integration suite) is untouched.
|
|
9
|
+
*
|
|
10
|
+
* ── Dialect deltas, kept EXPLICIT (no genuinely-divergent algorithm in this pair — every method is
|
|
11
|
+
* SQL-text-only) ──────────────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* - `?` placeholders vs `$n`
|
|
13
|
+
* - `ON DUPLICATE KEY UPDATE … VALUES(col)` vs `ON CONFLICT (session_id, event_id) DO UPDATE SET …
|
|
14
|
+
* EXCLUDED.col`
|
|
15
|
+
* - null-safe owner compare: `<=>` vs `IS NOT DISTINCT FROM`
|
|
16
|
+
* - affectedRows vs rowCount (via SqlDriver)
|
|
17
|
+
*/
|
|
1
18
|
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
2
19
|
import type { Pool as PgPool } from "pg";
|
|
3
20
|
import { type SqlDriver } from "./sql-driver.js";
|
|
21
|
+
/** Dual-dialect durable resume-at anchor map. See the file header for the dialect-delta ledger. */
|
|
4
22
|
export declare class SqlResumeAnchorStore {
|
|
5
23
|
protected readonly db: SqlDriver;
|
|
6
24
|
constructor(db: SqlDriver);
|
|
25
|
+
/** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
|
|
7
26
|
private q;
|
|
27
|
+
/** Record/overwrite the anchor for one settled message boundary (idempotent upsert on the (session_id,event_id) PK). */
|
|
8
28
|
put(sessionId: string, eventId: string, entryId: string, owner: string | null): Promise<void>;
|
|
29
|
+
/** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id; undefined = unknown anchor. */
|
|
9
30
|
resolve(sessionId: string, eventId: string, owner: string | null): Promise<string | undefined>;
|
|
31
|
+
/** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
|
|
32
|
+
* session EXPORT bundles the whole anchor map so the importer can RE-KEY owner to the target principal (§9). The
|
|
33
|
+
* route already proved session ownership (the export gate), so no per-row owner filter here. owner carried verbatim. */
|
|
10
34
|
listBySession(sessionId: string): Promise<Array<{
|
|
11
35
|
eventId: string;
|
|
12
36
|
entryId: string;
|
|
13
37
|
owner: string | null;
|
|
14
38
|
}>>;
|
|
39
|
+
/** E21 — purge ALL anchors for a session, scoped by session_id ALONE (the route proved ownership; a per-row owner
|
|
40
|
+
* guard would orphan rows whose per-run principal diverged from the session owner). Idempotent (affected count). */
|
|
15
41
|
deleteBySession(sessionId: string): Promise<number>;
|
|
16
42
|
}
|
|
43
|
+
/** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
|
|
17
44
|
export declare class TiDBResumeAnchorStore extends SqlResumeAnchorStore {
|
|
18
45
|
constructor(pool: MySqlPool);
|
|
19
46
|
}
|
|
47
|
+
/** PostgreSQL binding — historical class name + ctor shape preserved. */
|
|
20
48
|
export declare class PgResumeAnchorStore extends SqlResumeAnchorStore {
|
|
21
49
|
constructor(pool: PgPool);
|
|
22
50
|
}
|
|
@@ -1,35 +1,46 @@
|
|
|
1
1
|
import { mysqlDriver, pgDriver } from "./sql-driver.js";
|
|
2
|
+
/** Dual-dialect durable resume-at anchor map. See the file header for the dialect-delta ledger. */
|
|
2
3
|
export class SqlResumeAnchorStore {
|
|
3
4
|
db;
|
|
4
5
|
constructor(db) {
|
|
5
6
|
this.db = db;
|
|
6
7
|
}
|
|
8
|
+
/** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
|
|
7
9
|
q(tidb, pg) {
|
|
8
10
|
return this.db.dialect === "tidb" ? tidb : pg;
|
|
9
11
|
}
|
|
12
|
+
/** Record/overwrite the anchor for one settled message boundary (idempotent upsert on the (session_id,event_id) PK). */
|
|
10
13
|
async put(sessionId, eventId, entryId, owner) {
|
|
11
14
|
await this.db.query(this.q("INSERT INTO resume_anchor (session_id, event_id, entry_id, owner, created_at) VALUES (?,?,?,?,?) " +
|
|
12
15
|
"ON DUPLICATE KEY UPDATE entry_id = VALUES(entry_id), owner = VALUES(owner)", "INSERT INTO resume_anchor (session_id, event_id, entry_id, owner, created_at) VALUES ($1,$2,$3,$4,$5) " +
|
|
13
16
|
"ON CONFLICT (session_id, event_id) DO UPDATE SET entry_id = EXCLUDED.entry_id, owner = EXCLUDED.owner"), [sessionId, eventId, entryId, owner, new Date()]);
|
|
14
17
|
}
|
|
18
|
+
/** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id; undefined = unknown anchor. */
|
|
15
19
|
async resolve(sessionId, eventId, owner) {
|
|
16
20
|
const { rows } = await this.db.query(this.q("SELECT entry_id FROM resume_anchor WHERE session_id = ? AND event_id = ? AND owner <=> ?", "SELECT entry_id FROM resume_anchor WHERE session_id = $1 AND event_id = $2 AND owner IS NOT DISTINCT FROM $3"), [sessionId, eventId, owner]);
|
|
17
21
|
return rows[0] ? String(rows[0].entry_id) : undefined;
|
|
18
22
|
}
|
|
23
|
+
/** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
|
|
24
|
+
* session EXPORT bundles the whole anchor map so the importer can RE-KEY owner to the target principal (§9). The
|
|
25
|
+
* route already proved session ownership (the export gate), so no per-row owner filter here. owner carried verbatim. */
|
|
19
26
|
async listBySession(sessionId) {
|
|
20
27
|
const { rows } = await this.db.query(this.q("SELECT event_id, entry_id, owner FROM resume_anchor WHERE session_id = ?", "SELECT event_id, entry_id, owner FROM resume_anchor WHERE session_id = $1"), [sessionId]);
|
|
21
28
|
return rows.map((r) => ({ eventId: String(r.event_id), entryId: String(r.entry_id), owner: r.owner == null ? null : String(r.owner) }));
|
|
22
29
|
}
|
|
30
|
+
/** E21 — purge ALL anchors for a session, scoped by session_id ALONE (the route proved ownership; a per-row owner
|
|
31
|
+
* guard would orphan rows whose per-run principal diverged from the session owner). Idempotent (affected count). */
|
|
23
32
|
async deleteBySession(sessionId) {
|
|
24
33
|
const res = await this.db.query(this.q("DELETE FROM resume_anchor WHERE session_id = ?", "DELETE FROM resume_anchor WHERE session_id = $1"), [sessionId]);
|
|
25
34
|
return res.affected;
|
|
26
35
|
}
|
|
27
36
|
}
|
|
37
|
+
/** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
|
|
28
38
|
export class TiDBResumeAnchorStore extends SqlResumeAnchorStore {
|
|
29
39
|
constructor(pool) {
|
|
30
40
|
super(mysqlDriver(pool));
|
|
31
41
|
}
|
|
32
42
|
}
|
|
43
|
+
/** PostgreSQL binding — historical class name + ctor shape preserved. */
|
|
33
44
|
export class PgResumeAnchorStore extends SqlResumeAnchorStore {
|
|
34
45
|
constructor(pool) {
|
|
35
46
|
super(pgDriver(pool));
|
|
@@ -1,7 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RosterStore SQL twins(agent-team S1 server 半场,[1070]① 提货单)——core `RunnerDeps.rosterStore`
|
|
3
|
+
* 的 TiDB/PG 双方言实现:具名子 agent 的持久名册(具名 spawn advisory 写入;SendMessage 活注册表
|
|
4
|
+
* miss 后咨询;v1=诚实指针 roster_only,非跨 run resume)。
|
|
5
|
+
*
|
|
6
|
+
* 语义三条([1070]① 必守,与 core roster-store.js 参考实现字节对齐):
|
|
7
|
+
* 1. resolve **查询内** filter-before-reduce:access 轴在 SQL WHERE 完成(scope 先拒 → owner 匹配 →
|
|
8
|
+
* sessionScoped 显式位才认 session 匹配),绝不先取全集再内存过滤(跨租户行连查询结果都不进);
|
|
9
|
+
* 2. 同 `(normalizedName, owner, scope)` 域 upsert(core upsertKey 同键);
|
|
10
|
+
* 3. 写失败降级 miss 不出错答案 —— 已核 core 调用侧兜底(subagent.js record=`void …catch(()=>{})`,
|
|
11
|
+
* resolve=try/catch),store 侧诚实 THROW 即可(绝不吞成假成功)。
|
|
12
|
+
*
|
|
13
|
+
* latest 语义:core `latestOf` 用 `>=`(同 createdAt 后遍历者赢=写入序)。SQL 无插入序 ⇒ 次序键三连
|
|
14
|
+
* `created_at_ms DESC, recorded_at_ms DESC, agent_id DESC`——第三键保**确定性**(发版复审 F3:并发
|
|
15
|
+
* spawn 可共享毫秒、多副本时钟可偏斜,无第三键的 LIMIT 1 非确定)。诚实记账:同毫秒并写时选择=
|
|
16
|
+
* agent_id 字典序最大,与 core 单进程的「后遍历者赢」可能不同——多副本本就无全序,确定性优先。
|
|
17
|
+
*
|
|
18
|
+
* normalize 私拷已回收(2026-07-19):core 公共出口落地(黑板 [1070]① 所请的 additive 导出),按
|
|
19
|
+
* 头注预案换回单行 import。⚠️ 语义仍是**存储键**:DB 行按 normalize 后的键写入——core 若改语义,
|
|
20
|
+
* 存量行查不回;test/roster-store-db-integration.test.ts 的 golden corpus 钉守这条(非私拷漂移钉,
|
|
21
|
+
* 是「core 变语义必须先过迁移裁量」的告警钉)。
|
|
22
|
+
*/
|
|
1
23
|
import type { Pool } from "mysql2/promise";
|
|
2
24
|
import { normalizeAgentName, type RosterStore, type RosterEntry } from "@sema-agent/core";
|
|
3
25
|
type RosterAccess = Parameters<RosterStore["resolve"]>[1];
|
|
4
26
|
import type { PgQueryFn } from "./pg-query.js";
|
|
27
|
+
/** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
|
|
5
28
|
export declare const normalizeAgentNameLocal: typeof normalizeAgentName;
|
|
6
29
|
export declare const ROSTER_TABLE = "agent_roster";
|
|
7
30
|
export declare function ensureTiDBRosterSchema(pool: Pool): Promise<void>;
|
|
@@ -14,6 +37,9 @@ export declare class TiDBRosterStore implements RosterStore {
|
|
|
14
37
|
resolve(name: string, access: RosterAccess): Promise<RosterEntry | undefined>;
|
|
15
38
|
list(): Promise<RosterEntry[]>;
|
|
16
39
|
releaseAgent(agentId: string): Promise<void>;
|
|
40
|
+
/** [1522] MED2(server 扩展,非 core 接口;core RB-23②③ 派给部署的清理半场):TTL 清理——
|
|
41
|
+
* task-scoped 具名 spawn 的 owner=宿主 taskId=每 run 一新行,无清理=线性无界。按 recorded_at_ms
|
|
42
|
+
* (最后一次 upsert 触碰)删,latest 语义不受影响(活跃名恒被新 spawn 刷新)。 */
|
|
17
43
|
reapOlderThan(cutoffMs: number): Promise<number>;
|
|
18
44
|
}
|
|
19
45
|
export declare class PgRosterStore implements RosterStore {
|
|
@@ -24,6 +50,7 @@ export declare class PgRosterStore implements RosterStore {
|
|
|
24
50
|
resolve(name: string, access: RosterAccess): Promise<RosterEntry | undefined>;
|
|
25
51
|
list(): Promise<RosterEntry[]>;
|
|
26
52
|
releaseAgent(agentId: string): Promise<void>;
|
|
53
|
+
/** [1522] MED2(TiDB twin 同案注)。 */
|
|
27
54
|
reapOlderThan(cutoffMs: number): Promise<number>;
|
|
28
55
|
}
|
|
29
56
|
export {};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { normalizeAgentName } from "@sema-agent/core";
|
|
2
|
+
/** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
|
|
2
3
|
export const normalizeAgentNameLocal = normalizeAgentName;
|
|
3
4
|
export const ROSTER_TABLE = "agent_roster";
|
|
5
|
+
/** 行 → RosterEntry(缺席键省略,core 形逐字;session_scoped 数值/布尔双方言归一)。
|
|
6
|
+
* core 1.365 BREAKING:owner/scope 升类型必填——两方言 CREATE 直接建成 NOT NULL(当年的「清死行 +
|
|
7
|
+
* MODIFY/SET NOT NULL」运行期迁移腿已折进建表,由来见两 ensure 上方顶注 ①),故此处直取不条件展开。 */
|
|
4
8
|
function rowToEntry(r) {
|
|
5
9
|
return {
|
|
6
10
|
name: String(r.name),
|
|
@@ -15,10 +19,51 @@ function rowToEntry(r) {
|
|
|
15
19
|
createdAt: Number(r.created_at_ms),
|
|
16
20
|
};
|
|
17
21
|
}
|
|
22
|
+
// F2(发版复审):TiDB 表级 COLLATE utf8mb4_bin / PG 授权列 COLLATE "C"——'=' 恢复字节等价(JS 严格
|
|
23
|
+
// 相等同义),大小写/重音/PAD 近撞值不再穿过谓词;真库混合大小写+尾空格案钉住。
|
|
24
|
+
/** resolve 的 access 谓词(两方言同形,占位符各自)——core 1.365 A-2 终态:**default-deny 双轴**
|
|
25
|
+
* (entryAccessible 新极性,旧「缺轴=放行」两支已删)。scope 轴:`scope = :accessScope` 硬等——行值
|
|
26
|
+
* NULL(前代残行)或 access.scope 缺席(参数 NULL,`= NULL` 恒假)都拒 ✓。owner 轴:相等,或
|
|
27
|
+
* sessionScoped 显式真且 owner=access.sessionId;owner NULL 行两支 `= NULL` 恒假=拒 ✓。
|
|
28
|
+
* 全部在查询内完成(语义条 1)。
|
|
29
|
+
* ⚠️ 上面两处「行值 NULL」现在只是**推理留档**:两列自建表起 NOT NULL,行值侧 NULL 结构上不可能
|
|
30
|
+
* (顶注 ③);仍然可达的是**参数侧** NULL —— access 缺 scope/owner 时 `= NULL` 恒假 = default-deny。 */
|
|
31
|
+
// 数据列(owner/scope)仍是 VARCHAR——谓词一侧 CAST 为 BINARY 即整个比较按字节(残余过滤行数极小,
|
|
32
|
+
// 无索引损耗;主过滤=VARBINARY name_key PK 前缀)。
|
|
18
33
|
const RESOLVE_WHERE_TIDB = `name_key = ? AND BINARY scope = ? AND (BINARY owner = ? OR (session_scoped = 1 AND ? IS NOT NULL AND BINARY owner = ?))`;
|
|
19
34
|
const RESOLVE_WHERE_PG = `name_key = $1 AND scope = $2 AND (owner = $3 OR (session_scoped = 1 AND $4::varchar IS NOT NULL AND owner = $5))`;
|
|
35
|
+
// core 1.373 additive:RosterEntry.model(spawn 记录的解析后模型 id)——列投影型 store 必须显式接
|
|
36
|
+
// (File/Memory 后端整对象持久化天然保住;列白名单剥键=SDK 0.0.72 中继剥键同族教训,发车复审抓获)。
|
|
20
37
|
const COLS = "name, agent_id, session_id, tool_use_id, owner, scope, session_scoped, root_session_id, model, created_at_ms";
|
|
38
|
+
/* ┌─ 历史:曾经的运行期迁移腿(已折进 CREATE,2026-07-26 clay 裁「删库重建」)────────────────────┐
|
|
39
|
+
* 本文件的两个 ensure 曾在每次 boot 跑三族迁移语句,现已全部折叠为 CREATE TABLE 里的列定义。
|
|
40
|
+
* 保留由来,因为它解释了这些列**为什么长这样**,以及当年为什么不能只写一条 CREATE:
|
|
41
|
+
*
|
|
42
|
+
* ① owner / scope 曾是 nullable(1.247 及更早的 `agent_roster`)。core 1.365 BREAKING(本仓
|
|
43
|
+
* commit `1172f31`,[1509] 对表)把注册面改成 **default-deny 双轴**:缺轴行在新谓词下永不可达
|
|
44
|
+
* (resolve 恒拒)= 死行。于是当年的 ensure 必须先 `DELETE … WHERE owner IS NULL OR scope IS NULL`
|
|
45
|
+
* 再 `MODIFY/SET … NOT NULL`——带数据的收紧遇 NULL 会**砖 boot**,清完才幂等。
|
|
46
|
+
* ⚠️ 该迁移腿有一个真实的**滚动升级窗**(当年复审 #1 如实记):共库上仍在跑的 1.247 旧副本此后写
|
|
47
|
+
* 缺轴条目会撞 NOT NULL 约束错——core 调用侧 record 有 catch 兜底,窗内退化为该条 roster-miss、
|
|
48
|
+
* 不崩;而 DELETE→ALTER 之间旧副本恰好插入一行 NULL,会砖**当次** ALTER(boot 失败),下次 boot
|
|
49
|
+
* 再清即自愈。BREAKING 当年在 CHANGELOG 声明整队同拍升级。
|
|
50
|
+
* → 删库重建口径下这个窗**消失**:两列自建表起即 NOT NULL,不存在「先有 NULL 行再收紧」的时刻;
|
|
51
|
+
* 那条 DELETE 也结构上删不到任何行(NOT NULL 列不可能有 NULL 值),删之无损。
|
|
52
|
+
*
|
|
53
|
+
* ② root_session_id(core 1.367 δ)/ model(core 1.373)曾靠**探针式 ADD COLUMN** 补进存量表:
|
|
54
|
+
* 先查 information_schema.COLUMNS、缺了才 ALTER。之所以不用 `ADD COLUMN IF NOT EXISTS`,是因为
|
|
55
|
+
* MySQL 8 没有该语法(TiDB/MariaDB 才有),而本仓 MySQL-protocol 口径要求可移植
|
|
56
|
+
* (tidb-pool.ts COLUMN_MIGRATIONS 同姿势;PG 腿则直接用 IF NOT EXISTS)。
|
|
57
|
+
* → 新库 CREATE 已带列,探针恒 no-op,连同 ALTER 一并删。
|
|
58
|
+
*
|
|
59
|
+
* ③ 语义位:当年 `model IS NULL` 兼有「pre-1.373 行」一义。删库重建后**不再产生**这类行——NULL 只
|
|
60
|
+
* 剩「该 spawn 没记录模型」一义(RosterEntry.model 本就可选)。读侧的条件展开分支({@link rowToEntry}
|
|
61
|
+
* 里 root_session_id / model 两支)因此仍然可达,**不动**;同理 RESOLVE_WHERE_* 谓词里
|
|
62
|
+
* 「行值 NULL ⇒ `= NULL` 恒假」那一层推理只对 **参数侧** NULL(access 缺轴)仍成立,行值侧已结构不可能。
|
|
63
|
+
* └────────────────────────────────────────────────────────────────────────────────────────────┘ */
|
|
21
64
|
export async function ensureTiDBRosterSchema(pool) {
|
|
65
|
+
// VARBINARY 键列(F2 终形):`utf8mb4_bin` 仍是 PAD SPACE collation——VARCHAR '=' 尾空格填充,
|
|
66
|
+
// 'x' 与 'x ' 同键/同谓词命中(真库红实测)。VARBINARY 比较=纯字节,upsert 域键与授权谓词双正。
|
|
22
67
|
await pool.query(`CREATE TABLE IF NOT EXISTS ${ROSTER_TABLE} (
|
|
23
68
|
name_key VARBINARY(190) NOT NULL,
|
|
24
69
|
owner_key VARBINARY(190) NOT NULL,
|
|
@@ -42,6 +87,8 @@ export async function ensureTiDBRosterSchema(pool) {
|
|
|
42
87
|
) COLLATE utf8mb4_bin`);
|
|
43
88
|
}
|
|
44
89
|
export async function ensurePgRosterSchema(q) {
|
|
90
|
+
// COLLATE "C"(F2 双方言对齐):授权谓词列的 '=' 必须是字节等价——数据库缺省 collation 若非确定性/
|
|
91
|
+
// 大小写不敏感,近撞 scope/owner 会穿过 in-query access 过滤(信任边界弱化)。
|
|
45
92
|
await q(`CREATE TABLE IF NOT EXISTS ${ROSTER_TABLE} (
|
|
46
93
|
name_key VARCHAR(190) COLLATE "C" NOT NULL,
|
|
47
94
|
owner_key VARCHAR(190) COLLATE "C" NOT NULL,
|
|
@@ -64,6 +111,7 @@ export async function ensurePgRosterSchema(q) {
|
|
|
64
111
|
)`);
|
|
65
112
|
await q(`CREATE INDEX IF NOT EXISTS idx_roster_agent ON ${ROSTER_TABLE} (agent_id)`);
|
|
66
113
|
}
|
|
114
|
+
/** upsert 参数序(两方言共用;core 1.365 起 owner/scope 类型必填——键列直取,与 core upsertKey 同键)。 */
|
|
67
115
|
function upsertParams(entry, now) {
|
|
68
116
|
return [
|
|
69
117
|
normalizeAgentNameLocal(entry.name),
|
|
@@ -75,6 +123,8 @@ function upsertParams(entry, now) {
|
|
|
75
123
|
entry.toolUseId ?? null,
|
|
76
124
|
entry.owner,
|
|
77
125
|
entry.scope,
|
|
126
|
+
// TINYINT(1) 归一(clay 批 2026-07-26):写入参双方言统一 0/1(PG 列已 SMALLINT,裸 boolean 参数
|
|
127
|
+
// 会在 'true'::smallint 上炸;MySQL TINYINT 本就收 0/1)。三态保留:undefined → NULL。
|
|
78
128
|
entry.sessionScoped === undefined ? null : entry.sessionScoped ? 1 : 0,
|
|
79
129
|
entry.rootSessionId ?? null,
|
|
80
130
|
entry.model ?? null,
|
|
@@ -111,6 +161,9 @@ export class TiDBRosterStore {
|
|
|
111
161
|
async releaseAgent(agentId) {
|
|
112
162
|
await this.pool.query(`DELETE FROM ${ROSTER_TABLE} WHERE agent_id = ?`, [agentId]);
|
|
113
163
|
}
|
|
164
|
+
/** [1522] MED2(server 扩展,非 core 接口;core RB-23②③ 派给部署的清理半场):TTL 清理——
|
|
165
|
+
* task-scoped 具名 spawn 的 owner=宿主 taskId=每 run 一新行,无清理=线性无界。按 recorded_at_ms
|
|
166
|
+
* (最后一次 upsert 触碰)删,latest 语义不受影响(活跃名恒被新 spawn 刷新)。 */
|
|
114
167
|
async reapOlderThan(cutoffMs) {
|
|
115
168
|
const [res] = (await this.pool.query(`DELETE FROM ${ROSTER_TABLE} WHERE recorded_at_ms < ?`, [cutoffMs]));
|
|
116
169
|
return res.affectedRows;
|
|
@@ -145,6 +198,7 @@ export class PgRosterStore {
|
|
|
145
198
|
async releaseAgent(agentId) {
|
|
146
199
|
await this.q(`DELETE FROM ${ROSTER_TABLE} WHERE agent_id = $1`, [agentId]);
|
|
147
200
|
}
|
|
201
|
+
/** [1522] MED2(TiDB twin 同案注)。 */
|
|
148
202
|
async reapOlderThan(cutoffMs) {
|
|
149
203
|
const { rows } = await this.q(`DELETE FROM ${ROSTER_TABLE} WHERE recorded_at_ms < $1 RETURNING agent_id`, [cutoffMs]);
|
|
150
204
|
return rows.length;
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async run registry (S1) + replayable event log (S2) — SINGLE-FILE DUAL-DIALECT (design/158 A12 定型半场).
|
|
3
|
+
* ONE implementation, TWO dialects; the historical `TiDBRunStore` / `PgRunStore` class names survive as thin
|
|
4
|
+
* ctor subclasses so every consumer (store-backend.ts, the run/reaper/session/usage suites) is untouched.
|
|
5
|
+
*
|
|
6
|
+
* A run is the background execution of one task. `POST /v1/runs` records it `running` and returns
|
|
7
|
+
* immediately; the background driver (`src/runs.ts`) appends events here as they happen and marks the
|
|
8
|
+
* run terminal when done. Because runs + events are durable and shared, any stateless instance can
|
|
9
|
+
* report status or replay the event stream — a client can reconnect (even to a different instance)
|
|
10
|
+
* with `Last-Event-ID` and resume. The two dialects are kept in lock-step by ONE shared integration suite
|
|
11
|
+
* (test/run-store-reaper-integration.test.ts) that runs the SAME park→resume→claim scenario against BOTH
|
|
12
|
+
* real engines — the anti-drift guard.
|
|
13
|
+
*
|
|
14
|
+
* ── Dialect deltas, kept EXPLICIT (never hidden behind an abstraction) ────────────────────────────────
|
|
15
|
+
* - `?` placeholders vs `$n` (transaction control itself is normalized by `SqlDriver`/`SqlTxConn` —
|
|
16
|
+
* mysql2's native begin/commit/rollback vs PG's statement form; see sql-driver.ts)
|
|
17
|
+
* - dup-key `ER_DUP_ENTRY` vs SQLSTATE `23505` (createRun's task_active claim race)
|
|
18
|
+
* - null-safe owner compare: `<=>` (TiDB) vs `IS NOT DISTINCT FROM` (PG) — a null-owner run still matches
|
|
19
|
+
* `owner=null` on both, single-DB-fleet defense-in-depth (see {@link requestCancel})
|
|
20
|
+
* - multi-table DELETE: `DELETE t FROM t JOIN j …` (TiDB) vs `DELETE FROM t USING j …` (PG)
|
|
21
|
+
* - `UPDATE t AS a SET col=…` — PG's SET columns are NOT alias-qualified (PG rejects `SET a.col`), while
|
|
22
|
+
* TiDB's SET clause DOES qualify (`SET tr.col = …`) — see reapSuspended / failSuspendedWithExpiredCheckpoint
|
|
23
|
+
* - JSON binding: TiDB `JSON.stringify` verbatim vs PG `pgSafeJsonStringify` + `$n::jsonb` casts
|
|
24
|
+
* - PG-only protocol-byte defenses on plain-TEXT columns: `pgSanitizeText` on objective_preview (createRun)
|
|
25
|
+
* and error/error_code (setTerminal) — a raw NUL would throw 22P05 and roll back the whole terminal write,
|
|
26
|
+
* stranding the run in a live status forever (codex R12); TiDB stores these verbatim
|
|
27
|
+
* - dynamic multi-clause builders (listRuns/listSessions): TiDB's `?` is position-agnostic so the WHERE
|
|
28
|
+
* array is built with plain string pushes; PG's `$n` needs numbered placeholders, so those two methods
|
|
29
|
+
* keep an EXPLICIT per-dialect branch (a shared positional-counter abstraction would hide the very
|
|
30
|
+
* placeholder-numbering divergence this file exists to keep visible)
|
|
31
|
+
* - schema ownership: TiDB DDL in tidb-pool.ts, PG DDL centrally in pg-pool.ts (neither store creates tables).
|
|
32
|
+
*/
|
|
1
33
|
import type { TaskResult, TaskStatus } from "@sema-agent/core";
|
|
2
34
|
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
3
35
|
import type { Pool as PgPool } from "pg";
|
|
@@ -5,13 +37,27 @@ import { type UsageRow } from "../usage-analytics.js";
|
|
|
5
37
|
import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
|
|
6
38
|
import { type SqlDriver } from "./sql-driver.js";
|
|
7
39
|
export type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
|
|
40
|
+
/** Dual-dialect async run registry + event log. See the file header for the dialect-delta ledger. */
|
|
8
41
|
export declare class SqlRunStore {
|
|
9
42
|
protected readonly db: SqlDriver;
|
|
10
43
|
constructor(db: SqlDriver);
|
|
44
|
+
/** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
|
|
11
45
|
private q;
|
|
46
|
+
/** mysql2 names the dup-key `ER_DUP_ENTRY`; PG raises SQLSTATE `23505`. */
|
|
12
47
|
private isDupKey;
|
|
48
|
+
/** JSON column binding: TiDB stores the string verbatim; PG goes through the protocol-safe envelope
|
|
49
|
+
* (a raw NUL byte in an event payload would otherwise throw 22P05 mid-write). */
|
|
13
50
|
private json;
|
|
51
|
+
/** Run statements atomically; rolls back on failure. */
|
|
14
52
|
private tx;
|
|
53
|
+
/**
|
|
54
|
+
* Create a run, but only if the session has no other active run (double-text guard).
|
|
55
|
+
*
|
|
56
|
+
* Mutual exclusion is a unique-key claim on `task_active(session_id)` — NOT a SELECT…FOR UPDATE,
|
|
57
|
+
* which on TiDB (no gap locks) would fail to serialize two concurrent createRuns when the session
|
|
58
|
+
* has no prior row. A plain INSERT either claims the session or throws a duplicate-key error (TiDB
|
|
59
|
+
* does NOT report a reliable affectedRows for `ON DUPLICATE KEY UPDATE …=…`, so we catch dup-key).
|
|
60
|
+
*/
|
|
15
61
|
createRun(taskId: string, sessionId: string, owner: string | null, instanceId: string, meta?: {
|
|
16
62
|
jobId?: string | null;
|
|
17
63
|
source?: string | null;
|
|
@@ -22,20 +68,92 @@ export declare class SqlRunStore {
|
|
|
22
68
|
ok: false;
|
|
23
69
|
activeTaskId: string;
|
|
24
70
|
}>;
|
|
71
|
+
/** Request cancel of a RUNNING run (durable, cross-replica). Sets the flag the owning instance's heartbeat
|
|
72
|
+
* tick polls; a same-replica caller additionally aborts the in-flight controller for instant effect. Only
|
|
73
|
+
* flags a `running` row (terminal/suspended → 0 affected = no-op). Returns whether a running row was flagged.
|
|
74
|
+
*
|
|
75
|
+
* `owner` is a single-DB-fleet defense-in-depth guard: the WHERE pins the row to the authenticated owner
|
|
76
|
+
* (null-safe compare so a legacy null-owner run matches owner=null), so even if the HTTP owner-gate has a bug
|
|
77
|
+
* a caller can never flip another tenant's run. Pass the run's owner (from the looked-up RunRecord). */
|
|
25
78
|
requestCancel(taskId: string, owner: string | null): Promise<boolean>;
|
|
79
|
+
/** Whether a cancel has been requested for this run (polled by the owning instance's heartbeat tick).
|
|
80
|
+
* `owner` is the single-DB-fleet null-safe owner guard (see {@link requestCancel}). */
|
|
26
81
|
isCancelRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
82
|
+
/** design/80 seam #2: request PREEMPT (graceful durable yield, ≠ cancel's kill) of a RUNNING run — durable +
|
|
83
|
+
* cross-replica. Sets the flag the owning instance's heartbeat tick polls (it then aborts its preemptSignal →
|
|
84
|
+
* the task suspends at the next clean turn boundary, gate resource_limit/reason preempt); a same-replica caller
|
|
85
|
+
* additionally aborts the in-flight preempt controller for instant effect. Only flags a `running` row
|
|
86
|
+
* (terminal/suspended → 0 affected = no-op). Returns whether a running row was flagged.
|
|
87
|
+
* `owner` is the single-DB-fleet null-safe owner guard (see {@link requestCancel}). */
|
|
27
88
|
requestPreempt(taskId: string, owner: string | null): Promise<boolean>;
|
|
89
|
+
/** Whether a preempt has been requested for this run (polled by the owning instance's heartbeat tick).
|
|
90
|
+
* `owner` is the single-DB-fleet null-safe owner guard (see {@link requestCancel}). */
|
|
28
91
|
isPreemptRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
92
|
+
/** Liveness heartbeat: refresh updated_at for a still-running run, independent of events. The
|
|
93
|
+
* running instance calls this on a timer so a long-but-alive turn (e.g. a subagent that emits no
|
|
94
|
+
* parent events for minutes) is not mistaken for a dead instance.
|
|
95
|
+
* `owner` is the single-DB-fleet null-safe owner guard (see {@link requestCancel}); the heartbeat is
|
|
96
|
+
* always issued by the owning instance with the run's own owner, so this only narrows, never blocks. */
|
|
29
97
|
heartbeat(taskId: string, owner: string | null): Promise<void>;
|
|
98
|
+
/** Append one event. A single INSERT — `updated_at` (liveness) is owned by `heartbeat`, so there
|
|
99
|
+
* is no second statement to keep atomic here. */
|
|
30
100
|
appendEvent(taskId: string, seq: number, type: string, data: unknown): Promise<void>;
|
|
101
|
+
/** Highest event seq for a task (0 if none). Lets a resumed leg CONTINUE the durable event log past the
|
|
102
|
+
* suspend (core 1.70 `resumeStream`) — the suspend wrote events 1..K, the resume appends from K+1 without
|
|
103
|
+
* colliding on the (task_id, seq) PK. */
|
|
31
104
|
maxSeq(taskId: string): Promise<number>;
|
|
105
|
+
/** Mark terminal AND release the single-active-run claim atomically — if the DELETE were a separate
|
|
106
|
+
* statement that failed, the session would stay permanently locked. [888] FIRST terminal writer wins:
|
|
107
|
+
* the UPDATE is CAS'd POSITIVELY on the live statuses (running/suspended/needs_review) — every call site
|
|
108
|
+
* is a settle-once flow whose backstops may double-fire (cancel × leg-throw × reaper), and an
|
|
109
|
+
* unconditional write let the LAST racer overwrite errorCode (a `cancelled` row flipping to a generic
|
|
110
|
+
* abort text, or vice versa). Positive form ([1.207 codex M1]): the negative NOT IN missed the
|
|
111
|
+
* blocked/timeout terminals — a first write of those could still be overwritten. The claim DELETE stays
|
|
112
|
+
* unconditional (idempotent; the first writer already released it). */
|
|
32
113
|
setTerminal(taskId: string, status: TaskStatus, result: TaskResult | null, error: string | null): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Durable F4 (design/45): a task suspended on a policy `ask`. Sets the run NON-terminal `suspended` and
|
|
116
|
+
* KEEPS the `task_active` claim — the session stays locked (no new run) until an operator resumes it to a
|
|
117
|
+
* terminal state or the reaper expires it. The token-bearing result is NOT stored (the submitter polling
|
|
118
|
+
* this row must never receive the capability token); only the status flips.
|
|
119
|
+
*/
|
|
33
120
|
setSuspended(taskId: string): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* design/80 D-B: PARK a run that paused on a REVIEW gate — a `needs_review` result (a dry-run diff review OR a
|
|
123
|
+
* pre-action `plan_review`; core assemble-result slot 8.6). Like {@link setSuspended} this is a NON-terminal park
|
|
124
|
+
* that KEEPS the `task_active` session claim (it does NOT delete it — only {@link setTerminal} does), so the
|
|
125
|
+
* resume path (`getActiveTaskId` → `markResuming`) can find + claim the row. core treats a review pause "like a
|
|
126
|
+
* suspend, an INTENTIONAL durable pause" (design/76 §2.5) — the service MUST park it the same way, else the run is
|
|
127
|
+
* terminalized + its lock released and the plan_review/dry_run_review resume can never run (it gets
|
|
128
|
+
* taskId=undefined and drives the model unprotected on an unlocked session). CAS on `running`/`needs_review`
|
|
129
|
+
* (reaper-revert guard, mirrors setSuspended). 🔴 The store SQL here is exercised by mocked unit tests only — a
|
|
130
|
+
* real-TiDB integration test of the park→resume→claim invariant is a required-before-GA TODO (the lesson from the
|
|
131
|
+
* P2 lease-SQL + this needs_review-park bug: mocked tests hide store-SQL defects).
|
|
132
|
+
*/
|
|
34
133
|
setNeedsReview(taskId: string): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Durable F4 resume: a suspended run is being actively resumed. Flip it back to `running` (CAS — only if
|
|
136
|
+
* still suspended) and refresh liveness, so the in-flight resume is protected by the running-run heartbeat
|
|
137
|
+
* and is NOT killed by `reapSuspended` (which targets `status='suspended'` past the approval TTL). Without
|
|
138
|
+
* this the row sits at `suspended`/updated_at=suspend-time for the WHOLE resume execution, so a resume that
|
|
139
|
+
* crosses the TTL is marked `failed` mid-run and its session lock (`task_active`) is released. Returns true
|
|
140
|
+
* if it claimed the flip (false ⇒ the reaper already expired it, or it isn't suspended).
|
|
141
|
+
*/
|
|
35
142
|
markResuming(taskId: string): Promise<boolean>;
|
|
143
|
+
/** The active run's taskId for a session (the `task_active` claim) — lets resume find the suspended run row. */
|
|
36
144
|
getActiveTaskId(sessionId: string): Promise<string | undefined>;
|
|
145
|
+
/** Shared row→record mapper — byte-identical between dialects (both drivers hand back the same column
|
|
146
|
+
* names + comparable JS types after SqlDriver's result normalization). */
|
|
37
147
|
private rowToRun;
|
|
38
148
|
getRun(taskId: string): Promise<RunRecord | undefined>;
|
|
149
|
+
/** Task Trace list (S1): runs newest-first, keyset-paginated on (created_at, task_id). Optional status +
|
|
150
|
+
* jobId filters (jobId = the work-view group, served by idx_job). Caller passes `limit+1` to detect a next
|
|
151
|
+
* page. Cursor fields are bound as params (no SQL injection).
|
|
152
|
+
*
|
|
153
|
+
* 🔴 Genuinely-divergent BUILDER (not just SQL text): TiDB's `?` is position-agnostic, so the WHERE array is
|
|
154
|
+
* built with plain string pushes in call order. PG's `$n` needs a NUMBERED placeholder per param, so that arm
|
|
155
|
+
* keeps its own positional-counter closure (`p()`) — collapsing the two into one shared counter would hide
|
|
156
|
+
* the very placeholder-numbering divergence this file exists to keep visible. */
|
|
39
157
|
listRuns(opts: {
|
|
40
158
|
status?: string;
|
|
41
159
|
jobId?: string;
|
|
@@ -47,6 +165,12 @@ export declare class SqlRunStore {
|
|
|
47
165
|
};
|
|
48
166
|
limit: number;
|
|
49
167
|
}): Promise<RunRecord[]>;
|
|
168
|
+
/** GET /v1/sessions (CC /resume picker): DISTINCT sessions newest-first by last activity, keyset-paginated on
|
|
169
|
+
* (last_activity, session_id). Aggregates task_run by session_id — one window pass picks the latest run per
|
|
170
|
+
* session (rn=1) for the preview/status and rolls up first/last/count. Owner-scoped when set (the per-user view).
|
|
171
|
+
* Bounded by per-tenant data today; a denormalized session table is the optimization if it ever goes hot.
|
|
172
|
+
*
|
|
173
|
+
* 🔴 Same builder divergence as {@link listRuns} — see its header note. */
|
|
50
174
|
listSessions(opts: {
|
|
51
175
|
owner?: string;
|
|
52
176
|
cursor?: {
|
|
@@ -56,17 +180,44 @@ export declare class SqlRunStore {
|
|
|
56
180
|
limit: number;
|
|
57
181
|
q?: string;
|
|
58
182
|
}): Promise<SessionSummary[]>;
|
|
183
|
+
/** Shared row→summary mapper for listSessions (byte-identical between dialects). */
|
|
59
184
|
private rowToSession;
|
|
185
|
+
/**
|
|
186
|
+
* E21 (§0.5 session delete) — purge the service-owned RUNS LEDGER for one session: task_event (the replayable
|
|
187
|
+
* event log), task_active (the single-active-run claim), and task_run (the run rows). Owner-guarded (null-safe
|
|
188
|
+
* compare, single-DB defense-in-depth, mirrors {@link requestCancel}) so even a buggy HTTP gate can't purge
|
|
189
|
+
* another tenant's runs. Idempotent — returns `{ removed }` (the count of task_run rows removed; 0 = nothing to
|
|
190
|
+
* purge). The conversation HISTORY (session_meta/session_event) is purged separately by the session store; the
|
|
191
|
+
* checkpoint/tool-result rows by their stores — this method owns only the runs-ledger tables. Done in one TX so a
|
|
192
|
+
* partial purge can't leak a task_active claim with no run row (a permanent session lock).
|
|
193
|
+
*
|
|
194
|
+
* 🔴 Active-run re-assert INSIDE the TX (adversarial-review LOW — TOCTOU): the route's pre-purge `getActiveTaskId`
|
|
195
|
+
* 409 check is a non-transactional SELECT — a concurrent createRun can claim `task_active(session_id)` in the
|
|
196
|
+
* window between that check and this purge, then have its LIVE rows deleted here. So we re-take the no-active-run
|
|
197
|
+
* invariant transactionally: `SELECT task_id FROM task_active WHERE session_id=? FOR UPDATE` at the TOP of the TX.
|
|
198
|
+
* `FOR UPDATE` serializes against createRun's unique-key INSERT on the SAME session_id (createRun either already
|
|
199
|
+
* holds the row — we see it and abort — or blocks on our lock until commit, then fails its own unique-key claim
|
|
200
|
+
* against the now-absent row). If a claim exists we return `{ active }` (the route maps it to 409) and delete
|
|
201
|
+
* NOTHING. Returns `{ removed }` on a clean purge.
|
|
202
|
+
*
|
|
203
|
+
* 🔴 The multi-table DELETEs are dialect-divergent SQL FORMS (not just placeholders): TiDB's
|
|
204
|
+
* `DELETE te FROM te JOIN tr ON …` vs PG's `DELETE FROM te USING tr WHERE …`.
|
|
205
|
+
*/
|
|
60
206
|
deleteBySession(sessionId: string, owner: string | null): Promise<{
|
|
61
207
|
removed: number;
|
|
62
208
|
} | {
|
|
63
209
|
active: string;
|
|
64
210
|
}>;
|
|
211
|
+
/** Per-door usage rollup (center systems-UI input): COUNT by (source,status) since a cutoff. Reads the
|
|
212
|
+
* denormalized columns only — no JSON parsing; served by full scan bounded by created_at (small windows). */
|
|
65
213
|
sourceSummary(sinceMs: number): Promise<Array<{
|
|
66
214
|
source: string | null;
|
|
67
215
|
status: string;
|
|
68
216
|
count: number;
|
|
69
217
|
}>>;
|
|
218
|
+
/** 用量扫窗(usage-analytics):按时间窗取 {owner,created_at,status,result} 四列,行内投影
|
|
219
|
+
* stats(JSON 提取在 JS,免 SQL JSON 方言分叉);LIMIT+1 探测截断(触顶=truncated:true 诚实上抛)。
|
|
220
|
+
* 聚合在 src/usage-analytics.ts 纯函数(三后端同代码)。可选 owner 过滤=JWT 主体只看自己。 */
|
|
70
221
|
usageScan(fromMs: number, toMs: number, opts?: {
|
|
71
222
|
owner?: string;
|
|
72
223
|
limit?: number;
|
|
@@ -74,15 +225,58 @@ export declare class SqlRunStore {
|
|
|
74
225
|
rows: UsageRow[];
|
|
75
226
|
truncated: boolean;
|
|
76
227
|
}>;
|
|
228
|
+
/** Earliest retained event seq for a task (0 if none) → `retainedFrom` for /turns and the 416 boundary for
|
|
229
|
+
* /stream (a resume point below this has been evicted past retention). */
|
|
77
230
|
retainedFrom(taskId: string): Promise<number>;
|
|
231
|
+
/** Events with seq strictly greater than `afterSeq` (use 0 for the whole stream). */
|
|
78
232
|
getEvents(taskId: string, afterSeq: number): Promise<RunEvent[]>;
|
|
233
|
+
/**
|
|
234
|
+
* Mark stale `running` rows as failed (best-effort recovery for runs whose instance died), then
|
|
235
|
+
* free any active-run claim whose run is no longer running (reaped here, or a terminal whose
|
|
236
|
+
* DELETE was lost). `olderThanMs` must exceed the longest expected gap between a run's events
|
|
237
|
+
* (each event refreshes `updated_at`), else a healthy slow run is wrongly reaped.
|
|
238
|
+
*/
|
|
79
239
|
reapStale(olderThanMs: number): Promise<number>;
|
|
240
|
+
/**
|
|
241
|
+
* Durable F4 expiry: an approval parked beyond `olderThanMs` (the approval TTL) was never answered → fail
|
|
242
|
+
* the run + RELEASE its task_active (unlock the session). Mirrors the checkpoint reaper's CAS-expire (≈ deny);
|
|
243
|
+
* idempotent across replicas. Returns count.
|
|
244
|
+
*
|
|
245
|
+
* 🔴 design/80 D-D (adversarial blocker fix): SKIPS any row whose checkpoint is STILL pending — that row is
|
|
246
|
+
* owned by a checkpoint-state-driven sweep (the SLA deny-sweep for human/irreversible_ask, or
|
|
247
|
+
* failSuspendedWithExpiredCheckpoint once the checkpoint is expired). Without this guard, this time-based
|
|
248
|
+
* UPDATE fired at the SAME instant as the deny-sweep (deadline == createdAt + ttl, both keyed on the TTL),
|
|
249
|
+
* almost always committed FIRST (it is a single UPDATE), and deleted task_active + failed the run BEFORE the
|
|
250
|
+
* deny-sweep's resumeCheckpoint ran — so resumeCheckpoint saw no task row (markResuming skipped) yet STILL ran
|
|
251
|
+
* the model on a now-unlocked session (the pending checkpoint's resolve-CAS wins), orphaning a model leg and
|
|
252
|
+
* opening a two-runs-one-session window. The NOT-EXISTS-pending guard (same shape as
|
|
253
|
+
* failSuspendedWithExpiredCheckpoint) means this only ever reaps a row whose checkpoint is already gone/expired.
|
|
254
|
+
*
|
|
255
|
+
* 🔴 Alias-qualification divergence (kept EXPLICIT, never "fixed" to match): TiDB's SET clause QUALIFIES with
|
|
256
|
+
* `tr.` (`SET tr.status = …`); PG's SET clause must NOT be alias-qualified (`SET status = …` — PG rejects
|
|
257
|
+
* `SET a.col`). Both WHERE clauses use the `tr.` alias.
|
|
258
|
+
*/
|
|
80
259
|
reapSuspended(olderThanMs: number): Promise<number>;
|
|
260
|
+
/**
|
|
261
|
+
* design/80 §3 inv#3 (crash-safe backstop — the run-row half of the checkpoint `terminal_at` sweep): fail a
|
|
262
|
+
* suspended run whose durable checkpoint was ALREADY EXPIRED by `reapExpired` (past its `deadline` or its
|
|
263
|
+
* absolute `terminal_at`), and release its task_active (unlock the session). Runs UNCONDITIONALLY (no
|
|
264
|
+
* approval-TTL gate), CHECKPOINT-STATE-driven not time-driven, so it aligns EXACTLY with the per-row
|
|
265
|
+
* `terminal_at` (which never falls before an operator's >30d deadline) — unlike a uniform timer, which would
|
|
266
|
+
* either be inert (gated off at APPROVAL_TIMEOUT_SEC=0) or prematurely kill a long gate. Safe against the two
|
|
267
|
+
* windows a naive predicate mis-fires on: (a) the transient suspend-write window — a run suspended before its
|
|
268
|
+
* checkpoint row exists has NO expired checkpoint, so it is not matched; (b) a re-suspended session that minted
|
|
269
|
+
* a NEW pending checkpoint — the `NOT EXISTS pending` clause excludes it. Idempotent across replicas. Returns count.
|
|
270
|
+
*
|
|
271
|
+
* Same alias-qualification divergence as {@link reapSuspended} — see its header note.
|
|
272
|
+
*/
|
|
81
273
|
failSuspendedWithExpiredCheckpoint(): Promise<number>;
|
|
82
274
|
}
|
|
275
|
+
/** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
|
|
83
276
|
export declare class TiDBRunStore extends SqlRunStore {
|
|
84
277
|
constructor(pool: MySqlPool);
|
|
85
278
|
}
|
|
279
|
+
/** PostgreSQL binding — historical class name + ctor shape preserved. */
|
|
86
280
|
export declare class PgRunStore extends SqlRunStore {
|
|
87
281
|
constructor(pool: PgPool);
|
|
88
282
|
}
|