@sema-agent/server 1.323.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +2132 -96
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +58 -2
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,9 +1,37 @@
|
|
|
1
|
+
// TiDB (MySQL wire) dialect twin of `memory-engine-pg.ts` — the THIRD MemoryBackend implementation
|
|
2
|
+
// (边界重切:core 养 File backend+seam+memoryBackendContract,SQL 方言归 service;先例=
|
|
3
|
+
// TiDBRunStore/PgRunStore 方言孪生对)。Same tables, same contract, mysql2 posture throughout.
|
|
4
|
+
//
|
|
5
|
+
// 方言改造点(core 指引,与 Pg 版逐条对照):
|
|
6
|
+
// - `$n` 占位符 → `?`;`jsonb` → `JSON`(mysql2 对 JSON 列返回已解析对象,fromJson 防御 string 形);
|
|
7
|
+
// - `UPDATE/DELETE … WHERE rev = ? RETURNING` → MySQL 无 RETURNING:条件写后看 affectedRows;零行=
|
|
8
|
+
// conflict,且 currentRev 必须 SELECT 现值(freshRev 语义——绝不把 pre-race SELECT 的旧值当 currentRev)。
|
|
9
|
+
// ⚠️ affectedRows 语义(归因修正:mysql2 默认 flags 含 FOUND_ROWS ⇒ affectedRows=
|
|
10
|
+
// MATCHED 行数;此前注释写反)。真库契约在真默认语义下全绿;下述 fresh-rev 比对分支让两种语义都正确:matched-but-
|
|
11
|
+
// identical 也是 0——零行后用 freshRev 消歧(现 rev==新 rev ⇒ 内容已是目标态=幂等成功,非 conflict);
|
|
12
|
+
// - add 路径 Pg 用 `INSERT … ON CONFLICT (id) DO UPDATE`(冲突靶=仅 PK)。MySQL 的 ON DUPLICATE KEY
|
|
13
|
+
// UPDATE 会被 **任意** 唯一键触发——(scope,slug) 撞键时它会把竞争对手的行改写成本 entry 的 id(数据毁),
|
|
14
|
+
// 不能用;拆成「不存在→INSERT / 已存在→UPDATE by id」,两条腿的 ER_DUP_ENTRY 都按键名分诊(PRIMARY=
|
|
15
|
+
// 并发同 id add → 转 UPDATE 腿;uk_scope_slug=并发 slug 竞争 → 下一个 -n 后缀重试);
|
|
16
|
+
// - unique violation 判定:ER_DUP_ENTRY(errno 1062),不是 Pg 的 23505;
|
|
17
|
+
// - pg-mem 伪影 workaround(索引列 ANY 零行/重复占位符重复行)不抄——MySQL 本就走 IN-list,dedupe 保留
|
|
18
|
+
// 是因为它同时是诚实语义(重复 key 问的是同一个 entry,契约锁死 once-per-entry);
|
|
19
|
+
// - (scope, slug) UNIQUE 约束照立(竞态正确性:两实例各自探得 free 同时 INSERT,DB 约束是唯一仲裁);
|
|
20
|
+
// - 表名与 Pg 版同名(两方言不会同库;与退役 MemoryStore 的 `agent_memory*` 面刻意不相交);
|
|
21
|
+
// - v1 lexical only:embedder/vector 面无 TiDB 对应(Pg 的 pgvector rung 是 Pg 专属);构造签名保留
|
|
22
|
+
// opts 但传入 embedder=fail-loud 拒绝,search 恒走 jaccard 词面,haystack 与 Pg/File 逐字节同构
|
|
23
|
+
// (`${name ?? slug} ${description} ${body}`——memoryBackendContract 的 search 等价断言依赖)。
|
|
1
24
|
import { jaccardDistance, termSet } from "./memory-engine-vector-util.js";
|
|
2
25
|
import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
|
|
26
|
+
/** Table names (single source) — SAME names as PG_MEMORY_ENGINE_TABLES (the two dialects never share
|
|
27
|
+
* one database), deliberately DISJOINT from the legacy `agent_memory*` MemoryStore plane. */
|
|
3
28
|
export const TIDB_MEMORY_ENGINE_TABLES = {
|
|
4
29
|
entries: "agent_memory_engine_entries",
|
|
5
30
|
cursors: "agent_memory_engine_cursors",
|
|
6
31
|
};
|
|
32
|
+
/** Idempotent DDL for the entry plane (TiDB dialect). Call once at startup.
|
|
33
|
+
* Key lengths: utf8mb4 = 4 bytes/char and the default index-key cap is 3072 bytes, so the
|
|
34
|
+
* (scope, slug) unique key budget is scope 190 + slug 512 = 702 chars ⇒ 2808 bytes ≤ 3072. */
|
|
7
35
|
export async function ensureTiDBMemoryEngineSchema(pool) {
|
|
8
36
|
await pool.query(`CREATE TABLE IF NOT EXISTS ${TIDB_MEMORY_ENGINE_TABLES.entries} (
|
|
9
37
|
id VARCHAR(64) NOT NULL,
|
|
@@ -19,6 +47,9 @@ export async function ensureTiDBMemoryEngineSchema(pool) {
|
|
|
19
47
|
KEY idx_scope (scope),
|
|
20
48
|
UNIQUE KEY uk_scope_slug (scope, slug)
|
|
21
49
|
)`);
|
|
50
|
+
// The (scope, slug) UNIQUE key above is CORRECTNESS, not perf (Pg 版同注):two
|
|
51
|
+
// instances racing an add of one scope+slug (different ids) can both probe "free" and both insert;
|
|
52
|
+
// the DB constraint is the only true arbiter and the add path retries the next suffix on violation.
|
|
22
53
|
await pool.query(`CREATE TABLE IF NOT EXISTS ${TIDB_MEMORY_ENGINE_TABLES.cursors} (
|
|
23
54
|
scope VARCHAR(190) NOT NULL,
|
|
24
55
|
\`cursor\` TEXT NOT NULL,
|
|
@@ -30,9 +61,12 @@ function isDupEntry(err) {
|
|
|
30
61
|
return false;
|
|
31
62
|
return err.code === "ER_DUP_ENTRY" || err.errno === 1062;
|
|
32
63
|
}
|
|
64
|
+
/** ER_DUP_ENTRY messages name the violated key (`… for key 'tbl.PRIMARY'` / `… for key 'tbl.uk_scope_slug'`)
|
|
65
|
+
* — the add path uses this to tell "id already exists (→ overwrite leg)" from "slug race (→ -n retry)". */
|
|
33
66
|
function isPrimaryKeyDup(err) {
|
|
34
67
|
return isDupEntry(err) && /for key '[^']*PRIMARY'/i.test(String(err.message ?? ""));
|
|
35
68
|
}
|
|
69
|
+
/** `?, ?, …` for a dynamic IN list (MySQL has no ANY(param); plain IN-list on both engines). */
|
|
36
70
|
function inPlaceholders(count) {
|
|
37
71
|
return Array.from({ length: count }, () => "?").join(", ");
|
|
38
72
|
}
|
|
@@ -43,7 +77,9 @@ export class TiDBMemoryEngineBackend {
|
|
|
43
77
|
pool;
|
|
44
78
|
clock;
|
|
45
79
|
history;
|
|
80
|
+
/** Cumulative lost-row count — audit-line breakage must itself be auditable. */
|
|
46
81
|
historyRowsLost = 0;
|
|
82
|
+
/** design/81 rung indicator — TiDB v1 sits on the lexical floor (Pg twin parity surface). */
|
|
47
83
|
get vectorMode() {
|
|
48
84
|
return "lexical";
|
|
49
85
|
}
|
|
@@ -63,6 +99,7 @@ export class TiDBMemoryEngineBackend {
|
|
|
63
99
|
const [res] = await this.pool.query(sql, params);
|
|
64
100
|
return res;
|
|
65
101
|
}
|
|
102
|
+
/** The search haystack — BYTE-EQUAL to the File/Pg backends' lexical haystack (contract equivalence). */
|
|
66
103
|
haystackOf(slug, fm, body) {
|
|
67
104
|
return `${fm.name ?? slug} ${fm.description ?? ""} ${body}`;
|
|
68
105
|
}
|
|
@@ -91,6 +128,8 @@ export class TiDBMemoryEngineBackend {
|
|
|
91
128
|
};
|
|
92
129
|
}
|
|
93
130
|
async listHeaders(scopes) {
|
|
131
|
+
// Dedupe (all three read paths): honest semantic — a caller repeating a key asks about ONE entry
|
|
132
|
+
// (contract-locked once-per-entry; real IN-lists don't duplicate anyway).
|
|
94
133
|
const uniq = [...new Set(scopes)];
|
|
95
134
|
if (uniq.length === 0)
|
|
96
135
|
return [];
|
|
@@ -102,13 +141,15 @@ export class TiDBMemoryEngineBackend {
|
|
|
102
141
|
if (uniq.length === 0)
|
|
103
142
|
return [];
|
|
104
143
|
const rows = await this.selectRows(`SELECT id, scope, slug, frontmatter, body, rev, mtime_ms, size_bytes FROM ${TIDB_MEMORY_ENGINE_TABLES.entries} WHERE id IN (${inPlaceholders(uniq.length)}) ORDER BY id`, uniq);
|
|
105
|
-
return rows.map((r) => this.entryFromRow(r));
|
|
144
|
+
return rows.map((r) => this.entryFromRow(r)); // unknown ids: silently absent
|
|
106
145
|
}
|
|
107
146
|
async search(query, scopes, opts) {
|
|
147
|
+
// Limit normalization mirrors the Pg twin verbatim (floor semantics; NaN rejected; Infinity = no cap).
|
|
108
148
|
const rawLimit = opts?.limit ?? 20;
|
|
109
149
|
const limit = Number.isFinite(rawLimit) ? Math.floor(rawLimit) : rawLimit;
|
|
110
150
|
if (scopes.length === 0 || !(limit > 0))
|
|
111
151
|
return [];
|
|
152
|
+
// EMPTY-QUERY contract is backend-uniform: no terms → [] (File/Pg parity).
|
|
112
153
|
const q = termSet(query);
|
|
113
154
|
if (q.size === 0)
|
|
114
155
|
return [];
|
|
@@ -120,16 +161,22 @@ export class TiDBMemoryEngineBackend {
|
|
|
120
161
|
const fm = fromJson(r.frontmatter);
|
|
121
162
|
const d = jaccardDistance(q, this.haystackOf(r.slug, fm, r.body));
|
|
122
163
|
if (d === null)
|
|
123
|
-
continue;
|
|
164
|
+
continue; // zero-overlap: not a candidate
|
|
124
165
|
scored.push({ ...this.headerFromRow(r), score: d });
|
|
125
166
|
}
|
|
167
|
+
// Deterministic id tie-break (opus 审 C4,Pg 版同注): tied scores must not order by row-arrival
|
|
168
|
+
// accident — the cross-backend equivalence assertion compares ordered projections.
|
|
126
169
|
scored.sort((a, b) => a.score - b.score || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
127
170
|
return scored.slice(0, limit);
|
|
128
171
|
}
|
|
129
172
|
async applyPatches(patches) {
|
|
130
173
|
const report = { applied: [], conflicts: [] };
|
|
174
|
+
// At most ONE non-delete op per id per batch (file-backend parity — a COPY keeping its frontmatter
|
|
175
|
+
// id would leave the projection↔applied binding ambiguous; refuse the later one).
|
|
131
176
|
const nonDeleteIds = new Set();
|
|
177
|
+
// In-batch (scope, slug) claims so two adds of one slug in one batch suffix deterministically.
|
|
132
178
|
const plannedSlugs = new Set();
|
|
179
|
+
// 142-S5.1: one history row per APPLIED patch, flushed as one batch below (append-only audit face).
|
|
133
180
|
const historyRows = [];
|
|
134
181
|
for (const patch of patches) {
|
|
135
182
|
try {
|
|
@@ -146,11 +193,17 @@ export class TiDBMemoryEngineBackend {
|
|
|
146
193
|
report.conflicts.push({ op: patch.op, id: patch.id, reason: `io error: ${err instanceof Error ? err.message : String(err)}` });
|
|
147
194
|
}
|
|
148
195
|
}
|
|
196
|
+
// BEST-EFFORT history append (see TiDBMemoryEngineBackendOptions.history for the honest trade-off:
|
|
197
|
+
// the entry writes above are already committed; a failed audit append must not fail the report —
|
|
198
|
+
// swallow + warn, never throw. appendHistory is (id,rev)-idempotent, so a caller retry is safe.
|
|
149
199
|
if (this.history && historyRows.length > 0) {
|
|
150
200
|
try {
|
|
151
201
|
await this.history.appendHistory(historyRows);
|
|
152
202
|
}
|
|
153
203
|
catch (err) {
|
|
204
|
+
// Every warn carries the CUMULATIVE lost count — a persistent silent failure
|
|
205
|
+
// (history table dropped, grant flipped) shows as a growing number, not a one-off line.
|
|
206
|
+
// The metrics counter leg lives in the main.ts sink wrapper (memory_history_append_failed_total).
|
|
154
207
|
this.historyRowsLost += historyRows.length;
|
|
155
208
|
console.warn(`TiDBMemoryEngineBackend: best-effort history append failed (${historyRows.length} row(s) lost, ${this.historyRowsLost} cumulative — audit face only, entries committed): ${err instanceof Error ? err.message : String(err)}`);
|
|
156
209
|
}
|
|
@@ -159,6 +212,8 @@ export class TiDBMemoryEngineBackend {
|
|
|
159
212
|
}
|
|
160
213
|
async applyOne(patch, report, plannedSlugs, historyRows) {
|
|
161
214
|
const T = TIDB_MEMORY_ENGINE_TABLES.entries;
|
|
215
|
+
// A patch whose entry carries a DIFFERENT id than the patch addresses is malformed — refused up
|
|
216
|
+
// front, all backends alike (Pg 版同注).
|
|
162
217
|
if (patch.op !== "delete" && patch.entry !== undefined && patch.entry.id !== patch.id) {
|
|
163
218
|
report.conflicts.push({ op: patch.op, id: patch.id, reason: `patch id ${JSON.stringify(patch.id)} != entry id ${JSON.stringify(patch.entry.id)} (malformed patch refused)` });
|
|
164
219
|
return;
|
|
@@ -169,9 +224,15 @@ export class TiDBMemoryEngineBackend {
|
|
|
169
224
|
report.conflicts.push({ op: "add", id: patch.id, reason: "add patch without an entry" });
|
|
170
225
|
return;
|
|
171
226
|
}
|
|
227
|
+
// Cross-scope add refusal (opus 审 C3,Pg 版同注): an add whose id already lives in a DIFFERENT
|
|
228
|
+
// scope must not silently MOVE the row; same-scope re-add stays the idempotent overwrite.
|
|
229
|
+
// One probe serves BOTH the E-02 guard and the cross-scope refusal (File/Pg parity).
|
|
172
230
|
const prior = await this.selectRows(`SELECT scope, slug, rev FROM ${T} WHERE id = ?`, [entry.id]);
|
|
173
231
|
const priorRow = prior.length > 0 ? prior[0] : undefined;
|
|
174
232
|
let existsById = priorRow !== undefined;
|
|
233
|
+
// E-02 add-if-absent guard (core 1.275.1/1.276.0 contract clause; caught live by the contract
|
|
234
|
+
// suite on real TiDB 2026-07-13): same rev AND same (scope, slug) projection = idempotent
|
|
235
|
+
// fall-through; different rev OR projection = REPORTED add_guard_absent_conflict + currentRev.
|
|
175
236
|
if (patch.guard === "absent" && priorRow) {
|
|
176
237
|
const currentRev = String(priorRow.rev);
|
|
177
238
|
if (currentRev !== computeEntryRev(entry)) {
|
|
@@ -182,6 +243,7 @@ export class TiDBMemoryEngineBackend {
|
|
|
182
243
|
report.conflicts.push({ op: "add", id: entry.id, reason: `add_guard_absent_conflict (id already exists at the same rev but a different projection ${JSON.stringify(`${String(priorRow.scope)}/${String(priorRow.slug)}`)}; add-if-absent refuses to duplicate)`, currentRev });
|
|
183
244
|
return;
|
|
184
245
|
}
|
|
246
|
+
// same rev AND same projection ⇒ idempotent; fall through to the normal add (no-op re-write).
|
|
185
247
|
}
|
|
186
248
|
if (priorRow) {
|
|
187
249
|
const held = String(priorRow.scope);
|
|
@@ -190,6 +252,9 @@ export class TiDBMemoryEngineBackend {
|
|
|
190
252
|
return;
|
|
191
253
|
}
|
|
192
254
|
}
|
|
255
|
+
// Slug collision with a DIFFERENT entry → deterministic `-n` suffix (file-backend parity); the
|
|
256
|
+
// probe is only an optimization — the write INSIDE the loop is arbitrated by uk_scope_slug, and
|
|
257
|
+
// a concurrent loser retries the next suffix (Pg 版同注).
|
|
193
258
|
let slug = entry.slug;
|
|
194
259
|
for (let n = 2;; n++) {
|
|
195
260
|
const key = `${entry.scope}|${slug}`;
|
|
@@ -202,12 +267,18 @@ export class TiDBMemoryEngineBackend {
|
|
|
202
267
|
const sizeBytes = Buffer.byteLength(serializeEntryFile(stored), "utf8");
|
|
203
268
|
try {
|
|
204
269
|
if (existsById) {
|
|
270
|
+
// Idempotent overwrite leg (Pg 的 ON CONFLICT(id) DO UPDATE 对应面;见文件头:MySQL 的
|
|
271
|
+
// ON DUPLICATE KEY UPDATE 会被 (scope,slug) 键劫持改写他人行,禁用)。
|
|
205
272
|
const res = await this.write(`UPDATE ${T} SET scope = ?, slug = ?, frontmatter = ?, body = ?, rev = ?, mtime_ms = ?, size_bytes = ?, embedding = NULL WHERE id = ?`, [stored.scope, stored.slug, JSON.stringify(stored.frontmatter), stored.body, rev, this.clock(), sizeBytes, stored.id]);
|
|
206
273
|
if (res.affectedRows === 0) {
|
|
274
|
+
// affectedRows: under mysql2 default (FOUND_ROWS ⇒ matched count) 0 = row gone;
|
|
275
|
+
// under changed-only semantics 0 could also mean already-at-target — the fresh-rev branch below covers BOTH: 0 = either the row already
|
|
276
|
+
// holds exactly this content (idempotent no-op = success) or it vanished under a
|
|
277
|
+
// concurrent delete (→ fall back to the INSERT leg, same slug).
|
|
207
278
|
const still = await this.selectRows(`SELECT id FROM ${T} WHERE id = ?`, [stored.id]);
|
|
208
279
|
if (still.length === 0) {
|
|
209
280
|
existsById = false;
|
|
210
|
-
continue;
|
|
281
|
+
continue; // row deleted concurrently — retry this slug via the INSERT leg
|
|
211
282
|
}
|
|
212
283
|
}
|
|
213
284
|
}
|
|
@@ -218,16 +289,18 @@ export class TiDBMemoryEngineBackend {
|
|
|
218
289
|
catch (err) {
|
|
219
290
|
if (isDupEntry(err)) {
|
|
220
291
|
if (isPrimaryKeyDup(err)) {
|
|
221
|
-
existsById = true;
|
|
292
|
+
existsById = true; // concurrent same-id add won the PK — retry this slug via the overwrite leg
|
|
222
293
|
continue;
|
|
223
294
|
}
|
|
224
|
-
slug = `${entry.slug}-${n}`;
|
|
295
|
+
slug = `${entry.slug}-${n}`; // concurrent winner took this (scope,slug) — next suffix
|
|
225
296
|
continue;
|
|
226
297
|
}
|
|
227
298
|
throw err;
|
|
228
299
|
}
|
|
229
300
|
plannedSlugs.add(key);
|
|
230
301
|
report.applied.push({ op: "add", id: stored.id, slug: stored.slug });
|
|
302
|
+
// History: chain head — prevRev absent by contract (a same-scope idempotent re-add of
|
|
303
|
+
// identical content dedupes on the (id, rev) PK; changed content starts a fresh head).
|
|
231
304
|
if (this.history)
|
|
232
305
|
historyRows.push({ id: stored.id, rev, op: "add", scope: stored.scope, snapshot: { ...stored, rev }, writtenAtMs: this.clock() });
|
|
233
306
|
return;
|
|
@@ -236,6 +309,8 @@ export class TiDBMemoryEngineBackend {
|
|
|
236
309
|
slug = `${entry.slug}-${n}`;
|
|
237
310
|
}
|
|
238
311
|
}
|
|
312
|
+
// update/delete address an EXISTING entry by immutable id. (scope in the projection = the
|
|
313
|
+
// history row's scope for delete — a tombstone can't be joined back to the deleted row.)
|
|
239
314
|
const cur = await this.selectRows(`SELECT slug, rev, scope, frontmatter FROM ${T} WHERE id = ?`, [patch.id]);
|
|
240
315
|
if (cur.length === 0) {
|
|
241
316
|
report.conflicts.push({ op: patch.op, id: patch.id, reason: "unknown id (entry not found in backend)" });
|
|
@@ -244,6 +319,10 @@ export class TiDBMemoryEngineBackend {
|
|
|
244
319
|
const currentRev = String(cur[0].rev);
|
|
245
320
|
const currentSlug = String(cur[0].slug);
|
|
246
321
|
const currentScope = String(cur[0].scope);
|
|
322
|
+
// Read-side whitewash refusal (core 1.302 contract I-2, File-backend parity incl. ordering: judged
|
|
323
|
+
// BEFORE the rev CAS): an update may not strip provenance/trust off a repo-ingested entry. Judged on
|
|
324
|
+
// the committed frontmatter of THIS SELECT — a write racing past it flips rev and the conditional
|
|
325
|
+
// write below re-reports as a CAS conflict, so the window stays closed.
|
|
247
326
|
if (patch.op === "update" && patch.entry !== undefined) {
|
|
248
327
|
const committedFm = fromJson(cur[0].frontmatter);
|
|
249
328
|
if (committedFm.provenance?.kind === "repo_file") {
|
|
@@ -261,16 +340,26 @@ export class TiDBMemoryEngineBackend {
|
|
|
261
340
|
}
|
|
262
341
|
}
|
|
263
342
|
if (patch.baseRev !== undefined && patch.baseRev !== currentRev) {
|
|
343
|
+
// Per-id CAS (§2.4 并发): NEVER blind-write over a concurrent change. ABA note shared with the
|
|
344
|
+
// File/Pg backends (rev is a content hash — an A→B→A round-trip re-arms a stale baseRev; benign
|
|
345
|
+
// by construction, same canonical content).
|
|
264
346
|
report.conflicts.push({ op: patch.op, id: patch.id, reason: "rev mismatch (concurrent change)", baseRev: patch.baseRev, currentRev });
|
|
265
347
|
return;
|
|
266
348
|
}
|
|
267
349
|
if (patch.op === "delete") {
|
|
350
|
+
// Conditional on the rev we just judged — a write landing between the SELECT and this DELETE
|
|
351
|
+
// re-reports as the same CAS conflict instead of silently deleting the newer committed state.
|
|
352
|
+
// DELETE's affectedRows counts deleted rows (FOUND_ROWS only affects UPDATE): 0 = the row changed/vanished.
|
|
268
353
|
const res = await this.write(`DELETE FROM ${T} WHERE id = ? AND rev = ?`, [patch.id, currentRev]);
|
|
269
354
|
if (res.affectedRows === 0) {
|
|
270
355
|
report.conflicts.push({ op: "delete", id: patch.id, reason: "rev mismatch (concurrent change)", baseRev: patch.baseRev, currentRev: await this.freshRev(patch.id, currentRev) });
|
|
271
356
|
return;
|
|
272
357
|
}
|
|
273
358
|
report.applied.push({ op: "delete", id: patch.id, slug: currentSlug });
|
|
359
|
+
// History tombstone. rev must be DISTINCT from the deleted version's rev — the (id, rev) PK
|
|
360
|
+
// already holds a row for currentRev (the add/update that committed it), and the idempotent
|
|
361
|
+
// no-op ODKU would silently drop a colliding tombstone. Deterministic derived key: revs are
|
|
362
|
+
// 16-hex content hashes (computeEntryRev), so the prefixed form stays well under VARCHAR(128).
|
|
274
363
|
if (this.history)
|
|
275
364
|
historyRows.push({ id: patch.id, rev: `tombstone:${currentRev}`, prevRev: currentRev, op: "delete", scope: currentScope, writtenAtMs: this.clock() });
|
|
276
365
|
return;
|
|
@@ -283,9 +372,22 @@ export class TiDBMemoryEngineBackend {
|
|
|
283
372
|
const rev = computeEntryRev(entry);
|
|
284
373
|
const res = await this.write(`UPDATE ${T} SET scope = ?, slug = ?, frontmatter = ?, body = ?, rev = ?, mtime_ms = ?, size_bytes = ?, embedding = NULL WHERE id = ? AND rev = ?`, [entry.scope, entry.slug, JSON.stringify(entry.frontmatter), entry.body, rev, this.clock(), Buffer.byteLength(serializeEntryFile(entry), "utf8"), entry.id, currentRev]);
|
|
285
374
|
if (res.affectedRows === 0) {
|
|
375
|
+
// Zero AFFECTED rows is ambiguous under the default protocol (changed-rows counting): the row may
|
|
376
|
+
// hold rev==currentRev with byte-identical values (matched but unchanged). Disambiguate on the
|
|
377
|
+
// fresh rev: the row must STILL EXIST and already be at the NEW rev ⇒ the content is exactly the
|
|
378
|
+
// target state (idempotent success — also covers a concurrent writer landing the same hash);
|
|
379
|
+
// anything else ⇒ CAS conflict with the rev NOW.
|
|
380
|
+
// 🔴 codex lens-3: the row-EXISTENCE check is load-bearing. When the row was concurrently DELETED
|
|
381
|
+
// between the SELECT and this UPDATE, affectedRows is also 0; a fallback that returned the pre-race
|
|
382
|
+
// rev would make `fresh === rev` true for a byte-identical update and FALSELY report `applied` on a
|
|
383
|
+
// row that no longer exists — while the Pg twin (UPDATE … RETURNING → zero rows) correctly reports a
|
|
384
|
+
// conflict. `freshRevOrMissing` returns undefined for a gone row, so it falls through to conflict,
|
|
385
|
+
// restoring dialect parity (never accept a lost write as applied).
|
|
286
386
|
const fresh = await this.freshRevOrMissing(entry.id);
|
|
287
387
|
if (fresh === rev) {
|
|
288
388
|
report.applied.push({ op: "update", id: entry.id, slug: entry.slug });
|
|
389
|
+
// History: the idempotent already-at-target success is a committed version too — the
|
|
390
|
+
// (id, rev) idempotent append dedupes if this exact version was already recorded.
|
|
289
391
|
if (this.history)
|
|
290
392
|
historyRows.push({ id: entry.id, rev, prevRev: currentRev, op: "update", scope: entry.scope, snapshot: { ...entry, rev }, writtenAtMs: this.clock() });
|
|
291
393
|
return;
|
|
@@ -294,13 +396,19 @@ export class TiDBMemoryEngineBackend {
|
|
|
294
396
|
return;
|
|
295
397
|
}
|
|
296
398
|
report.applied.push({ op: "update", id: entry.id, slug: entry.slug });
|
|
399
|
+
// History: rev-chain link — snapshot carries the committed entry (rev = the NEW content hash).
|
|
297
400
|
if (this.history)
|
|
298
401
|
historyRows.push({ id: entry.id, rev, prevRev: currentRev, op: "update", scope: entry.scope, snapshot: { ...entry, rev }, writtenAtMs: this.clock() });
|
|
299
402
|
}
|
|
403
|
+
/** The row's rev NOW, or undefined if the row is gone. The existence distinction is the whole point
|
|
404
|
+
* (codex lens-3): a concurrent delete must not be mistaken for an idempotent already-at-target write. */
|
|
300
405
|
async freshRevOrMissing(id) {
|
|
301
406
|
const rows = await this.selectRows(`SELECT rev FROM ${TIDB_MEMORY_ENGINE_TABLES.entries} WHERE id = ?`, [id]);
|
|
302
407
|
return rows.length > 0 ? String(rows[0].rev) : undefined;
|
|
303
408
|
}
|
|
409
|
+
/** When the conditional write reports zero rows (a write landed inside the SELECT→write window), the
|
|
410
|
+
* report's `currentRev` must be the rev NOW — re-reporting the pre-race SELECT value could claim
|
|
411
|
+
* `baseRev === currentRev` alongside a "rev mismatch" reason. Row gone ⇒ fallback (Pg parity). */
|
|
304
412
|
async freshRev(id, fallback) {
|
|
305
413
|
return (await this.freshRevOrMissing(id)) ?? fallback;
|
|
306
414
|
}
|
|
@@ -309,6 +417,8 @@ export class TiDBMemoryEngineBackend {
|
|
|
309
417
|
return rows.length > 0 ? String(rows[0].cursor) : undefined;
|
|
310
418
|
}
|
|
311
419
|
async setConsolidationCursor(scope, cursor) {
|
|
420
|
+
// Single unique key (the PK) on this table — ON DUPLICATE KEY UPDATE is unambiguous here,
|
|
421
|
+
// unlike the two-unique-key entries table (see the file-head dialect note).
|
|
312
422
|
await this.write(`INSERT INTO ${TIDB_MEMORY_ENGINE_TABLES.cursors} (scope, \`cursor\`) VALUES (?, ?) ON DUPLICATE KEY UPDATE \`cursor\` = VALUES(\`cursor\`)`, [scope, cursor]);
|
|
313
423
|
}
|
|
314
424
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
|
|
2
|
+
* 单一语义源;memoryBackendContract 的 search 等价断言依赖同源 haystack 距离)。
|
|
3
|
+
* `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
|
|
4
|
+
* 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
|
|
5
|
+
* `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
|
|
1
6
|
export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
|
|
2
7
|
export declare function isUniqueViolation(err: unknown): boolean;
|
|
3
8
|
//# sourceMappingURL=memory-engine-vector-util.d.ts.map
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
|
|
2
|
+
* 单一语义源;memoryBackendContract 的 search 等价断言依赖同源 haystack 距离)。
|
|
3
|
+
* `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
|
|
4
|
+
* 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
|
|
5
|
+
* `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
|
|
1
6
|
export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
|
|
2
7
|
export function isUniqueViolation(err) {
|
|
3
8
|
if (typeof err !== "object" || err === null)
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
export declare class MemoryResumeAnchorStore {
|
|
2
2
|
private readonly bySession;
|
|
3
|
+
/** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL ON DUPLICATE/CONFLICT). */
|
|
3
4
|
put(sessionId: string, eventId: string, entryId: string, owner: string | null): Promise<void>;
|
|
5
|
+
/** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
|
|
6
|
+
* anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
|
|
4
7
|
resolve(sessionId: string, eventId: string, owner: string | null): Promise<string | undefined>;
|
|
8
|
+
/** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
|
|
9
|
+
* session EXPORT bundles the whole anchor map so the importer can re-key owner to the target principal (§9). Twin of
|
|
10
|
+
* the SQL/file stores; kept on all three backends so the ResumeAnchorStore union shares a single contract. */
|
|
5
11
|
listBySession(sessionId: string): Promise<Array<{
|
|
6
12
|
eventId: string;
|
|
7
13
|
entryId: string;
|
|
8
14
|
owner: string | null;
|
|
9
15
|
}>>;
|
|
16
|
+
/** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
|
|
17
|
+
* ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count). */
|
|
10
18
|
deleteBySession(sessionId: string): Promise<number>;
|
|
11
19
|
}
|
|
12
20
|
//# sourceMappingURL=memory-resume-anchor-store.d.ts.map
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory resume-at anchor map — the LOCAL (DB-less) twin of {@link TiDBResumeAnchorStore}/{@link PgResumeAnchorStore}
|
|
3
|
+
* (E18 resume-at; clay seamless local↔cloud). The shell holds the live E2 `eventId` (core never persists it);
|
|
4
|
+
* core's `TaskSpec.resumeAt` takes a persisted `SessionTreeEntry.id`. This store is the service-owned translation
|
|
5
|
+
* ("a deployment that holds eventIds owns the eventId→entryId map", core types). resume-at works LOCALLY (it needs
|
|
6
|
+
* only the session tree + this map, no cloud-only checkpoint), so this is PRESENT on the local backend (a singleton,
|
|
7
|
+
* like MemoryRunStore) — not omitted like the cloud-only stores. Process-local + ephemeral (lost on restart, same
|
|
8
|
+
* blast radius as MemoryRunStore; the file-backed follow-on persists it alongside run history).
|
|
9
|
+
*/
|
|
1
10
|
const ownerEq = (a, b) => (a ?? null) === (b ?? null);
|
|
2
11
|
export class MemoryResumeAnchorStore {
|
|
3
12
|
bySession = new Map();
|
|
13
|
+
/** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL ON DUPLICATE/CONFLICT). */
|
|
4
14
|
async put(sessionId, eventId, entryId, owner) {
|
|
5
15
|
let m = this.bySession.get(sessionId);
|
|
6
16
|
if (!m) {
|
|
@@ -9,10 +19,15 @@ export class MemoryResumeAnchorStore {
|
|
|
9
19
|
}
|
|
10
20
|
m.set(eventId, { entryId, owner });
|
|
11
21
|
}
|
|
22
|
+
/** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
|
|
23
|
+
* anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
|
|
12
24
|
async resolve(sessionId, eventId, owner) {
|
|
13
25
|
const e = this.bySession.get(sessionId)?.get(eventId);
|
|
14
26
|
return e && ownerEq(e.owner, owner) ? e.entryId : undefined;
|
|
15
27
|
}
|
|
28
|
+
/** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
|
|
29
|
+
* session EXPORT bundles the whole anchor map so the importer can re-key owner to the target principal (§9). Twin of
|
|
30
|
+
* the SQL/file stores; kept on all three backends so the ResumeAnchorStore union shares a single contract. */
|
|
16
31
|
async listBySession(sessionId) {
|
|
17
32
|
const m = this.bySession.get(sessionId);
|
|
18
33
|
if (!m)
|
|
@@ -22,6 +37,8 @@ export class MemoryResumeAnchorStore {
|
|
|
22
37
|
out.push({ eventId, entryId: e.entryId, owner: e.owner });
|
|
23
38
|
return out;
|
|
24
39
|
}
|
|
40
|
+
/** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
|
|
41
|
+
* ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count). */
|
|
25
42
|
async deleteBySession(sessionId) {
|
|
26
43
|
const removed = this.bySession.get(sessionId)?.size ?? 0;
|
|
27
44
|
this.bySession.delete(sessionId);
|
|
@@ -1,17 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory async run registry + replayable event log — the LOCAL (DB-less) twin of {@link TiDBRunStore}/
|
|
3
|
+
* {@link PgRunStore} (clay 2026-06-25: the seamless local↔cloud switch — a locally-run HTTP service must serve the
|
|
4
|
+
* SAME contract a cloud worker does, incl. `/v1/runs` async runs + the trace event log). Behaviourally identical to
|
|
5
|
+
* the SQL twins (the shared `storeBehaviorSuite` keeps them in lock-step), but process-local + ephemeral: a restart
|
|
6
|
+
* loses run history (file-backed durability is the immediate follow-on; the conversation HISTORY + checkpoints DO
|
|
7
|
+
* persist via core's FileStorageBackend). Single-process, so the cross-replica/durable reapers degrade — see below.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the SQL semantics exactly: the `task_active` single-active-run claim (a Map keyed by sessionId), the
|
|
10
|
+
* NON-terminal suspend/needs_review parks that KEEP the claim, the markResuming CAS that resets cancel/preempt, the
|
|
11
|
+
* owner null-safe guard on the flag/heartbeat paths (`<=>` → JS `(a??null)===(b??null)`), and the keyset list order.
|
|
12
|
+
*/
|
|
1
13
|
import { type UsageRow } from "../usage-analytics.js";
|
|
2
14
|
import type { TaskResult, TaskStatus } from "@sema-agent/core";
|
|
3
15
|
import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
|
|
16
|
+
/**
|
|
17
|
+
* [868] P0 — the local lane's stand-in for the SQL twins' checkpoint-table JOIN. The file/memory run stores
|
|
18
|
+
* cannot JOIN `checkpoint` (separate store, separate files), so the suspended-run reapers were NO-OPs — which
|
|
19
|
+
* left a durable HITL park whose approval was never answered holding the task_active claim FOREVER (the
|
|
20
|
+
* "suspended run locks the session" incident: every later submit 409s and no reaper path releases it).
|
|
21
|
+
* The backend assembly (store-backend.ts local lane, where checkpoint + run store are built side by side)
|
|
22
|
+
* injects this probe so the reapers get the SAME two predicates the SQL twins express as EXISTS subqueries:
|
|
23
|
+
* - hasPending = EXISTS (checkpoint c WHERE c.session_id = ? AND c.status = 'pending') — the design/80 D-D
|
|
24
|
+
* NOT-EXISTS-pending guard: a row whose checkpoint is STILL pending is owned by the checkpoint-state-driven
|
|
25
|
+
* sweeps and must NEVER be time-reaped (else two-runs-one-session, see tidb-run-store.ts reapSuspended doc).
|
|
26
|
+
* - hasExpired = EXISTS (checkpoint ce WHERE ce.session_id = ? AND ce.status = 'expired') — the
|
|
27
|
+
* failSuspendedWithExpiredCheckpoint driver (checkpoint-STATE-driven, not time-driven).
|
|
28
|
+
* Probe ABSENT (old assembly / no checkpoint store wired) ⇒ the reapers stay honest NO-OPs — without the
|
|
29
|
+
* pending-guard there is no safe way to distinguish "abandoned park" from "operator still deciding".
|
|
30
|
+
*/
|
|
4
31
|
export interface RunStoreCheckpointProbe {
|
|
5
32
|
hasPending(sessionId: string): Promise<boolean>;
|
|
6
33
|
hasExpired(sessionId: string): Promise<boolean>;
|
|
7
34
|
}
|
|
8
35
|
export declare class MemoryRunStore {
|
|
9
36
|
private readonly runs;
|
|
37
|
+
/** sessionId → taskId — the single-active-run claim (the `task_active` table). */
|
|
10
38
|
private readonly active;
|
|
39
|
+
/** taskId → events (kept seq-sorted on read). */
|
|
11
40
|
private readonly events;
|
|
41
|
+
/** [868] the checkpoint-table stand-in (see {@link RunStoreCheckpointProbe}); absent ⇒ reapers NO-OP. */
|
|
12
42
|
private checkpointProbe?;
|
|
43
|
+
/** [868] wire the checkpoint probe (backend assembly, where checkpoint + run store are built together). */
|
|
13
44
|
setCheckpointProbe(probe: RunStoreCheckpointProbe): void;
|
|
14
45
|
private toRecord;
|
|
46
|
+
/** Create a run iff the session has no active run (the task_active unique-key claim). */
|
|
15
47
|
createRun(taskId: string, sessionId: string, owner: string | null, instanceId: string, meta?: {
|
|
16
48
|
jobId?: string | null;
|
|
17
49
|
source?: string | null;
|
|
@@ -31,12 +63,18 @@ export declare class MemoryRunStore {
|
|
|
31
63
|
maxSeq(taskId: string): Promise<number>;
|
|
32
64
|
retainedFrom(taskId: string): Promise<number>;
|
|
33
65
|
getEvents(taskId: string, afterSeq: number): Promise<RunEvent[]>;
|
|
66
|
+
/** [888] FIRST terminal writer wins(SQL 孪生同款正向 CAS on running/suspended/needs_review,
|
|
67
|
+
* [1.207 codex M1] 负向形漏 blocked/timeout);claim 释放保持无条件(幂等)。 */
|
|
34
68
|
setTerminal(taskId: string, status: TaskStatus, result: TaskResult | null, error: string | null): Promise<void>;
|
|
69
|
+
/** Durable F4: park NON-terminal `suspended`, KEEP the task_active claim. CAS on running/suspended (reaper-revert guard). */
|
|
35
70
|
setSuspended(taskId: string): Promise<void>;
|
|
71
|
+
/** design/80 D-B: park NON-terminal `needs_review`, KEEP the claim. CAS on running/needs_review. */
|
|
36
72
|
setNeedsReview(taskId: string): Promise<void>;
|
|
73
|
+
/** Durable F4 resume: flip suspended/needs_review → running (CAS) + reset cancel/preempt flags. */
|
|
37
74
|
markResuming(taskId: string): Promise<boolean>;
|
|
38
75
|
getActiveTaskId(sessionId: string): Promise<string | undefined>;
|
|
39
76
|
getRun(taskId: string): Promise<RunRecord | undefined>;
|
|
77
|
+
/** Runs newest-first, keyset on (createdAt, taskId) DESC; optional exact-match filters (owner is exact, like the SQL). */
|
|
40
78
|
listRuns(opts: {
|
|
41
79
|
status?: string;
|
|
42
80
|
jobId?: string;
|
|
@@ -48,6 +86,7 @@ export declare class MemoryRunStore {
|
|
|
48
86
|
};
|
|
49
87
|
limit: number;
|
|
50
88
|
}): Promise<RunRecord[]>;
|
|
89
|
+
/** DISTINCT sessions newest-first by last activity (the CC /resume picker): latest run's preview/status + first/last/count. */
|
|
51
90
|
listSessions(opts: {
|
|
52
91
|
owner?: string;
|
|
53
92
|
cursor?: {
|
|
@@ -57,11 +96,13 @@ export declare class MemoryRunStore {
|
|
|
57
96
|
limit: number;
|
|
58
97
|
q?: string;
|
|
59
98
|
}): Promise<SessionSummary[]>;
|
|
99
|
+
/** E21 (§0.5 delete) — purge the runs ledger for one session, owner-guarded; aborts (returns {active}) if a run is live. */
|
|
60
100
|
deleteBySession(sessionId: string, owner: string | null): Promise<{
|
|
61
101
|
removed: number;
|
|
62
102
|
} | {
|
|
63
103
|
active: string;
|
|
64
104
|
}>;
|
|
105
|
+
/** 用量扫窗——in-memory 腿:遍历窗内行,投影同 usage-analytics 纯函数(SQL 孪生 parity)。 */
|
|
65
106
|
usageScan(fromMs: number, toMs: number, opts?: {
|
|
66
107
|
owner?: string;
|
|
67
108
|
limit?: number;
|
|
@@ -74,10 +115,32 @@ export declare class MemoryRunStore {
|
|
|
74
115
|
status: string;
|
|
75
116
|
count: number;
|
|
76
117
|
}>>;
|
|
118
|
+
/** Fail stale `running` rows (crashed-run backstop) + release task_active for any now-terminal row. */
|
|
77
119
|
reapStale(olderThanMs: number): Promise<number>;
|
|
120
|
+
/** [868] shared tail of both suspended-run reapers: flip one parked row → failed('approval.expired'), the
|
|
121
|
+
* in-memory twin of the SQL UPDATE (`error`/`error_code` set directly — no result blob to derive from). */
|
|
78
122
|
private failExpiredPark;
|
|
123
|
+
/** Release the claim for TERMINAL rows only — suspended/needs_review keep it (the `DELETE ta … WHERE tr.status
|
|
124
|
+
* NOT IN ('running','suspended','needs_review')` twin, shared by reapStale + the [868] suspended reapers). */
|
|
79
125
|
private releaseTerminalClaims;
|
|
126
|
+
/**
|
|
127
|
+
* [868] Durable F4 expiry — the local twin of TiDBRunStore.reapSuspended, driven by the injected checkpoint
|
|
128
|
+
* probe instead of a SQL JOIN (formerly a NO-OP, which was one of the five closed doors in the "suspended run
|
|
129
|
+
* locks the session forever" incident). Semantics verbatim from the SQL twin: suspended ∧ updatedAt < cutoff
|
|
130
|
+
* ∧ NOT probe.hasPending(session) → failed 'approval expired before decision' / error_code 'approval.expired'
|
|
131
|
+
* + release the task_active claim. The NOT-pending clause is the design/80 D-D adversarial-blocker guard
|
|
132
|
+
* (see tidb-run-store.ts:577-583): a row whose checkpoint is STILL pending belongs to the checkpoint-state
|
|
133
|
+
* sweeps (SLA deny-sweep / failSuspendedWithExpiredCheckpoint) — time-reaping it here would orphan a model
|
|
134
|
+
* leg on a now-unlocked session. Probe absent ⇒ honest NO-OP (never kill a park without the guard).
|
|
135
|
+
*/
|
|
80
136
|
reapSuspended(olderThanMs: number): Promise<number>;
|
|
137
|
+
/**
|
|
138
|
+
* [868] design/80 §3 inv#3 crash-safe backstop — the local twin of TiDBRunStore.failSuspendedWithExpiredCheckpoint
|
|
139
|
+
* (checkpoint-STATE-driven, not time-driven; runs UNCONDITIONALLY every reaper tick, no APPROVAL_TIMEOUT_SEC gate).
|
|
140
|
+
* Semantics verbatim from the SQL twin: (suspended ∨ needs_review) ∧ probe.hasExpired(session) ∧ NOT
|
|
141
|
+
* probe.hasPending(session) → same fail + claim release. The NOT-pending clause covers a re-suspended session
|
|
142
|
+
* that minted a NEW pending gate (wq64gmm5e: an abandoned needs_review park leaks exactly like a suspended one).
|
|
143
|
+
*/
|
|
81
144
|
failSuspendedWithExpiredCheckpoint(): Promise<number>;
|
|
82
145
|
}
|
|
83
146
|
//# sourceMappingURL=memory-run-store.d.ts.map
|