@sema-agent/server 7.145.0 → 7.147.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/MIGRATION.md +876 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +374 -99
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +61 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
- package/deploy/sema-up/chart/templates/server.yaml +9 -4
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +2 -1
- package/deploy/sema-up/lib/flagshape.sh +4 -0
- package/deploy/sema-up/lib/lanes.json +2 -5
- package/deploy/sema-up/sema-up.sh +12 -9
- package/deploy/sema-up/stack/compose.yaml +5 -4
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +7 -16
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/approval.d.ts +3 -3
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -1
- package/dist/boot/crash-last.js +2 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +7 -5
- package/dist/boot/engine-lease.d.ts +195 -22
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +5 -0
- package/dist/boot/execution-env.js +57 -33
- package/dist/boot/execution-lane.d.ts +37 -9
- package/dist/boot/execution-lane.js +74 -20
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +23 -5
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/leader.js +1 -1
- package/dist/boot/memory-boundary.d.ts +11 -11
- package/dist/boot/memory-boundary.js +3 -3
- package/dist/boot/memory-consolidation.d.ts +42 -41
- package/dist/boot/memory-consolidation.js +26 -28
- package/dist/boot/org-memory.js +3 -2
- package/dist/boot/parked-revive-gate.d.ts +1 -1
- package/dist/boot/parked-revive-gate.js +1 -1
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +40 -16
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +126 -123
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +11 -3
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +7 -3
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
- package/dist/boot/stage-02-web-admin-pull.js +10 -8
- package/dist/boot/stage-03-store-backend.d.ts +2 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +2 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -1
- package/dist/boot/stage-05-execution-env.js +6 -6
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +12 -13
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +7 -7
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +6 -2
- package/dist/boot/stage-10-http-server.d.ts +6 -2
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.d.ts +10 -0
- package/dist/boot/stores.js +53 -26
- package/dist/boot/web-admin.js +3 -3
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +4 -1
- package/dist/capabilities/composite-members.js +4 -1
- package/dist/capabilities/execution-lane.d.ts +7 -7
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +1 -1
- package/dist/capabilities/scenarios.d.ts +34 -20
- package/dist/capabilities/scenarios.js +13 -9
- package/dist/capabilities/settings-contract.d.ts +29 -0
- package/dist/capabilities/settings-contract.js +14 -0
- package/dist/capabilities/skills.d.ts +5 -5
- package/dist/capability-facts.d.ts +56 -1
- package/dist/capability-facts.js +59 -8
- package/dist/center-credential-renewer.js +3 -2
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +19 -9
- package/dist/config-invariants.d.ts +18 -3
- package/dist/config-invariants.js +36 -19
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-lkg.js +5 -6
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-provider.js +2 -0
- package/dist/config-types.d.ts +228 -185
- package/dist/config.d.ts +74 -6
- package/dist/config.js +146 -64
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +95 -0
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/execution-config-root.d.ts +5 -5
- package/dist/execution-config-root.js +5 -5
- package/dist/execution-env-purpose.d.ts +14 -0
- package/dist/execution-env-purpose.js +29 -0
- package/dist/execution-lane-caps.d.ts +49 -86
- package/dist/execution-lane-caps.js +52 -62
- package/dist/execution-placement.d.ts +18 -2
- package/dist/execution-placement.js +19 -0
- package/dist/file-history-disclosure.d.ts +2 -2
- package/dist/fleet/drain-entry.d.ts +46 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/fleet/serving-lease.js +3 -4
- package/dist/history-anchor.d.ts +22 -0
- package/dist/history-anchor.js +14 -0
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +85 -24
- package/dist/hooks/hook-runner.js +326 -109
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +76 -71
- package/dist/http/checkpoint-ctx.js +40 -40
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +19 -3
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +3 -1
- package/dist/http/execution-context.d.ts +7 -1
- package/dist/http/execution-context.js +13 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
- package/dist/http/memory-compliance-failure-reply.js +5 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/memory-store-refusal-reply.d.ts +3 -3
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +7 -4
- package/dist/http/principal-gate.d.ts +28 -16
- package/dist/http/principal-gate.js +10 -19
- package/dist/http/request-guards.d.ts +2 -2
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +29 -10
- package/dist/http/resume-legs.js +94 -56
- package/dist/http/rewind-files-reply.d.ts +34 -0
- package/dist/http/rewind-files-reply.js +36 -0
- package/dist/http/route-ctx.d.ts +43 -26
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +7 -26
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +12 -3
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +2 -2
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/notify-wake.js +2 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/projects.d.ts +70 -0
- package/dist/http/routes/projects.js +86 -0
- package/dist/http/routes/rules.js +30 -2
- package/dist/http/routes/runs.js +15 -11
- package/dist/http/routes/session-sync.js +39 -35
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +108 -2
- package/dist/http/routes/tasks.js +32 -8
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +31 -14
- package/dist/http/server.js +29 -3
- package/dist/http/stored-body-replay.d.ts +12 -7
- package/dist/http/stored-body-replay.js +28 -5
- package/dist/http/wire-types.d.ts +27 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-embedder-reembed.d.ts +38 -0
- package/dist/memory-embedder-reembed.js +20 -0
- package/dist/memory-incident-sink.d.ts +0 -28
- package/dist/memory-incident-sink.js +5 -0
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +38 -2
- package/dist/memory-scope.js +33 -2
- package/dist/memory-store-refusal.d.ts +17 -4
- package/dist/memory-store-refusal.js +1 -1
- package/dist/memory-sync-client.d.ts +2 -0
- package/dist/memory-sync-client.js +13 -11
- package/dist/memory-sync.js +1 -1
- package/dist/model-compat.d.ts +35 -21
- package/dist/model-compat.js +49 -21
- package/dist/model-entry-refusal.d.ts +11 -1
- package/dist/model-entry-refusal.js +7 -0
- package/dist/namespaced-rule-name.d.ts +18 -1
- package/dist/namespaced-rule-name.js +12 -0
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +29 -17
- package/dist/observability/fail-open.js +29 -17
- package/dist/observability/metrics.d.ts +2 -0
- package/dist/observability/metrics.js +2 -0
- package/dist/observability/secret-env-scrub.d.ts +30 -4
- package/dist/observability/secret-env-scrub.js +15 -3
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
- package/dist/orchestration/workflow-agent-session-index.js +1 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
- package/dist/orchestration/workflow-completion-inbox.js +63 -45
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/org-memory-admission.d.ts +5 -2
- package/dist/org-memory-admission.js +25 -10
- package/dist/parked-decide.d.ts +33 -26
- package/dist/parked-decide.js +36 -44
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +37 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
- package/dist/plugins/approval-ask-store-memory.js +11 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
- package/dist/plugins/approval-ask-store-sql.js +3 -1
- package/dist/plugins/blob-backend.d.ts +38 -195
- package/dist/plugins/blob-backend.js +33 -229
- package/dist/plugins/caching-session-store.d.ts +12 -5
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
- package/dist/plugins/checkpoint-index-columns.js +3 -2
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/device-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.js +5 -10
- package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
- package/dist/plugins/execution-lane-rename-m40.js +10 -0
- package/dist/plugins/execution-placement-sql.d.ts +63 -88
- package/dist/plugins/execution-placement-sql.js +94 -54
- package/dist/plugins/file-run-store.d.ts +26 -18
- package/dist/plugins/file-run-store.js +64 -75
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
- package/dist/plugins/imported-layer-root-retirement.js +4 -8
- package/dist/plugins/inbox-payload-column.d.ts +14 -0
- package/dist/plugins/inbox-payload-column.js +13 -0
- package/dist/plugins/local-checkpoint-store.d.ts +7 -2
- package/dist/plugins/local-checkpoint-store.js +13 -8
- package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
- package/dist/plugins/local-data-dir-modes-m39.js +182 -0
- package/dist/plugins/local-engine-high-water.d.ts +11 -0
- package/dist/plugins/local-engine-high-water.js +59 -0
- package/dist/plugins/local-session-store.d.ts +119 -30
- package/dist/plugins/local-session-store.js +156 -53
- package/dist/plugins/local-task-attachment-store.d.ts +2 -0
- package/dist/plugins/local-task-attachment-store.js +10 -11
- package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
- package/dist/plugins/memory-embedder-fingerprint.js +52 -12
- package/dist/plugins/memory-embedder.d.ts +1 -1
- package/dist/plugins/memory-embedder.js +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +30 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +38 -9
- package/dist/plugins/memory-engine-tidb.js +99 -230
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +169 -83
- package/dist/plugins/one-time-migrations.js +295 -235
- package/dist/plugins/owner-only-file-mode.d.ts +29 -0
- package/dist/plugins/owner-only-file-mode.js +141 -0
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +20 -1
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +12 -5
- package/dist/plugins/release-version.d.ts +20 -0
- package/dist/plugins/release-version.js +28 -0
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +39 -11
- package/dist/plugins/remote-env-e2b.d.ts +12 -3
- package/dist/plugins/remote-env-e2b.js +6 -4
- package/dist/plugins/remote-env-host.d.ts +9 -1
- package/dist/plugins/remote-env-host.js +6 -5
- package/dist/plugins/remote-env-k8s.d.ts +5 -2
- package/dist/plugins/remote-env-k8s.js +15 -4
- package/dist/plugins/remote-env-local-docker.d.ts +4 -1
- package/dist/plugins/remote-env-local-docker.js +3 -3
- package/dist/plugins/remote-env-ssh.d.ts +8 -2
- package/dist/plugins/remote-env-ssh.js +26 -24
- package/dist/plugins/remote-shell.d.ts +59 -30
- package/dist/plugins/remote-shell.js +175 -62
- package/dist/plugins/retention-declaration.d.ts +37 -0
- package/dist/plugins/retention-declaration.js +9 -0
- package/dist/plugins/retention-deployment.d.ts +126 -0
- package/dist/plugins/retention-deployment.js +88 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
- package/dist/plugins/retention-lane-store-sql.js +103 -1
- package/dist/plugins/retention-sql.d.ts +29 -0
- package/dist/plugins/retention-sql.js +8 -0
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-consistency.d.ts +0 -6
- package/dist/plugins/schema-consistency.js +1 -2
- package/dist/plugins/schema-ensure-legs.d.ts +1 -1
- package/dist/plugins/schema-ensure-legs.js +13 -3
- package/dist/plugins/session-ext-table.d.ts +74 -0
- package/dist/plugins/session-ext-table.js +121 -0
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/session-row-sql.d.ts +8 -7
- package/dist/plugins/session-row-sql.js +15 -7
- package/dist/plugins/session-store-sql.d.ts +131 -0
- package/dist/plugins/session-store-sql.js +298 -0
- package/dist/plugins/session-workspace-cell.d.ts +2 -2
- package/dist/plugins/session-workspace-cell.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
- package/dist/plugins/shared-memory-store-sql.js +13 -13
- package/dist/plugins/snapshot-bucket-presence.js +1 -1
- package/dist/plugins/sql-driver.d.ts +23 -7
- package/dist/plugins/sql-driver.js +41 -8
- package/dist/plugins/sql-errors.d.ts +5 -2
- package/dist/plugins/sql-errors.js +4 -0
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +46 -16
- package/dist/plugins/store-backend.js +192 -69
- package/dist/plugins/store-contracts.d.ts +10 -13
- package/dist/plugins/store-contracts.js +1 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/task-attachment-store.d.ts +6 -8
- package/dist/plugins/task-attachment-store.js +15 -10
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/text-column-capacity.d.ts +21 -0
- package/dist/plugins/text-column-capacity.js +5 -0
- package/dist/plugins/tidb-pool.d.ts +3 -2
- package/dist/plugins/tidb-pool.js +20 -32
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/read-face-posture.d.ts +6 -6
- package/dist/read-face-posture.js +2 -2
- package/dist/request-value-closure.d.ts +5 -5
- package/dist/request-value-closure.js +1 -1
- package/dist/rules-consent.d.ts +48 -27
- package/dist/rules-consent.js +147 -23
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +27 -17
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +16 -0
- package/dist/sealed-key-layout.js +3 -0
- package/dist/sealed-key.js +8 -6
- package/dist/security.d.ts +43 -9
- package/dist/security.js +9 -2
- package/dist/sema-config-dir.js +2 -2
- package/dist/server-secret-env.d.ts +2 -0
- package/dist/service-version.d.ts +2 -1
- package/dist/service-version.js +2 -2
- package/dist/session-error-wire.d.ts +1 -1
- package/dist/session-incarnation.d.ts +8 -5
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +110 -0
- package/dist/session-resident-background.js +88 -0
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +12 -2
- package/dist/session-workspace.js +6 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
- package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
- package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
- package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
- package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
- package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
- package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
- package/dist/stores-sql/session-write-hooks.d.ts +59 -0
- package/dist/stores-sql/session-write-hooks.js +2 -0
- package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
- package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
- package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
- package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-a2a.d.ts +7 -1
- package/dist/task-a2a.js +15 -14
- package/dist/task-cwd.d.ts +11 -3
- package/dist/task-cwd.js +17 -1
- package/dist/task-mcp.d.ts +10 -2
- package/dist/task-mcp.js +13 -16
- package/dist/task-settings.d.ts +68 -8
- package/dist/task-settings.js +63 -6
- package/dist/tool-approval.d.ts +23 -10
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +17 -10
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -0
- package/dist/trace/exit-seat.d.ts +29 -1
- package/dist/trace/exit-seat.js +4 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +21 -9
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +347 -78
- package/dist/trace/self-minted-wire.d.ts +587 -16
- package/dist/trace/self-minted-wire.js +215 -9
- package/dist/trace/sema-provenance.d.ts +45 -41
- package/dist/trace/sema-provenance.js +81 -10
- package/dist/trace/task-notification-facets.d.ts +70 -2
- package/dist/trace/task-notification-facets.js +71 -1
- package/dist/trace/wire-projection-faces.d.ts +39 -3
- package/dist/trace/wire-projection-faces.js +27 -2
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -0
- package/dist/usage-analytics.d.ts +4 -0
- package/dist/user-input-ledger.d.ts +2 -2
- package/dist/web-admin-client/apply-effective.js +22 -26
- package/dist/web-admin-client/candidate-gate.d.ts +35 -3
- package/dist/web-admin-client/candidate-gate.js +53 -5
- package/dist/web-admin-client/center-request.d.ts +4 -1
- package/dist/web-admin-client/center-request.js +2 -1
- package/dist/web-admin-client/effective-keys.js +0 -1
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/http-client.d.ts +1 -0
- package/dist/web-admin-client/http-client.js +17 -9
- package/dist/web-admin-client/restart-signal.js +5 -2
- package/dist/web-admin-client/skills-mcp.d.ts +20 -6
- package/dist/web-admin-client/skills-mcp.js +26 -21
- package/dist/web-admin-client/types.d.ts +34 -49
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
- package/package.json +22 -13
- package/scripts/drain-check-local.mjs +8 -55
- package/scripts/drain-check.mysql.sql +3 -40
- package/scripts/drain-check.pg.sql +3 -40
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/wire-changes/server@7.147.0.json +813 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
* 店上,带 placement 的 acquire 必须回读到**已持久化**且同一元组身份的行,回读缺失/异组=响亮拒。
|
|
35
35
|
*/
|
|
36
36
|
import { type PlacedSessionRow, type SessionPlacement, type SessionPlacementRecord, type SessionStore } from "@sema-agent/core";
|
|
37
|
+
import type { ForkPlacement } from "./session-fork.js";
|
|
37
38
|
/**
|
|
38
39
|
* 三只持久会话店(SQL 两孪生 + local 后端)的**会话耐久声明**(core `SessionStore.durability`:未 placed 的会话活不活过进程重启)——
|
|
39
40
|
* **单源**:三处声明(两孪生类上的顶层 `durability`、`LocalBackend` 交给店的顶层 `durability`)与委派分区的 {@link SESSION_PLACEMENTS}
|
|
@@ -93,8 +94,9 @@ export declare function placementFromRow(row: PlacementColumns | undefined): Ses
|
|
|
93
94
|
* 消费方对它 fail-closed(永不按年龄收割)。一个「无行」与「另一个租户有行」分不清的 join 不许删东西。
|
|
94
95
|
*/
|
|
95
96
|
export declare function placedRowFromRow(sessionId: string, row: PlacementColumns, lastActivityMs?: number): PlacedSessionRow;
|
|
96
|
-
/** 创建时一次落行的六个绑定值(顺序 = {@link PLACEMENT_SELECT_COLUMNS});无 placement ⇒ 六个 NULL
|
|
97
|
-
|
|
97
|
+
/** 创建时一次落行的六个绑定值(顺序 = {@link PLACEMENT_SELECT_COLUMNS});无 placement ⇒ 六个 NULL。读的只是元组(属主不在元组里 —— 它是行的属主格,建行那一笔另记):
|
|
98
|
+
* 带 placement 的 acquire 与带元组的 fork 两个建行点同调。 */
|
|
99
|
+
export declare function placementInsertValues(placement: ForkPlacement | undefined, placedAt: Date): [string | null, string | null, string | null, string | null, string | null, Date | null];
|
|
98
100
|
/** `acquire` 的 opts 面(core `SessionStore.acquire` 的第二参,窄成本模块要判的两键)。 */
|
|
99
101
|
export interface PlacementAcquireOpts {
|
|
100
102
|
requireExisting?: boolean;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* **会话行格写原语的 SQL 半** ——
|
|
3
|
-
*
|
|
2
|
+
* **会话行格写原语的 SQL 半** —— 两方言同一只实现,方言只在语句文本里。规则在 `src/session-row.ts` 头注「写原语」;判序只在那里的判官
|
|
3
|
+
* `judgeSessionRowWrite`,本模块只说事务与语句。格住部署的旁表 `session_ext`(属主 `session-ext-table.ts`);住客住引擎座表 `session_meta`(只读)。
|
|
4
4
|
*
|
|
5
5
|
* ## 一只事务(经 `SqlDriver.connect()`)
|
|
6
|
-
* ① `SELECT … FROM session_meta WHERE session_id = ? FOR UPDATE` ——
|
|
7
|
-
* `sql-driver.ts` 的 `@contract txn.read-semantics`)
|
|
8
|
-
* `leaf_id` 同句 +1,导入 / 换装 / fork 写成条目数)
|
|
6
|
+
* ① `SELECT … FROM session_meta WHERE session_id = ? FOR UPDATE` —— 锁根行读住客(当前读;连接初始化钉住读语义:TiDB 悲观、设不上拒启,
|
|
7
|
+
* `sql-driver.ts` 的 `@contract txn.read-semantics`);行在 ⇒ 同锁下锁读它的旁表行(格:执行角色、标题、置顶;行不在 = 全缺省)。
|
|
8
|
+
* 行期望带 `log` 时,同锁下读日志的 mark:长度 = 锁住的行上的 `leaf_seq`(每次追加与 `leaf_id` 同句 +1,导入 / 换装 / fork 写成条目数),
|
|
9
|
+
* 末条 = `session_event` 按 `seq` 倒序第一行(锁读)。追加者先锁这一行再插事件,所以持锁期间 mark 不动。
|
|
9
10
|
* ② 判官(行期望 → 写者身份 → 标签);不是 `write` ⇒ 回滚、一个字节不写。
|
|
10
|
-
* ③ `write` ⇒
|
|
11
|
+
* ③ `write` ⇒ 补旁表行(行在不动)、按 `session_id` 写格(根行已被本事务锁住)→ 提交。`updated_at` 不动(改名不是活动 —— 列表的新近序不变)。
|
|
11
12
|
* 应答行在**提交 / 回滚之后**由调用方的列表行读另读(新语句、新快照 —— 不在事务内用普通 `SELECT` 读:TiDB 悲观事务的普通读钉 `start_ts`,
|
|
12
13
|
* 等锁之后会读回判定之前的旧值),再交 `settleSessionRowWrite` 复核住客。
|
|
13
|
-
*
|
|
14
|
+
* 全局锁序:根 `session_meta` 一行 → 它的旁表行(→ 读日志 mark 时它的末条事件),不碰 `task_*`(与旁表的每个写者同序:根行先)。
|
|
14
15
|
*/
|
|
15
16
|
import type { SqlDriver } from "./sql-driver.js";
|
|
16
17
|
import { type SessionRowAnswer, type SessionRowPatch, type SessionRowWrite, type SessionRowWriteOutcome } from "../session-row.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SESSION_EXT_TABLE, ensureSessionExtRowStatement } from "./session-ext-table.js";
|
|
1
2
|
import { incarnationFromCell } from "../session-incarnation.js";
|
|
2
3
|
import { judgeSessionRowWrite, settleSessionRowWrite, } from "../session-row.js";
|
|
3
4
|
function binder(dialect) {
|
|
@@ -10,15 +11,15 @@ function binder(dialect) {
|
|
|
10
11
|
},
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
|
-
function lockedRowFrom(dialect, sessionId, row) {
|
|
14
|
+
function lockedRowFrom(dialect, sessionId, row, ext) {
|
|
14
15
|
return {
|
|
15
16
|
owner: row.owner === null || row.owner === undefined ? null : String(row.owner),
|
|
16
17
|
incarnation: incarnationFromCell(sessionId, row.incarnation, "absent"),
|
|
17
18
|
placed: row.placement_kind !== null && row.placement_kind !== undefined,
|
|
18
|
-
mirror:
|
|
19
|
+
mirror: ext?.execution_role === "mirror",
|
|
19
20
|
cells: {
|
|
20
|
-
title:
|
|
21
|
-
pinned: dialect === "pg" ?
|
|
21
|
+
title: ext?.title === null || ext?.title === undefined ? null : String(ext.title),
|
|
22
|
+
pinned: ext === undefined ? false : dialect === "pg" ? ext.pinned === true : Number(ext.pinned) === 1,
|
|
22
23
|
},
|
|
23
24
|
};
|
|
24
25
|
}
|
|
@@ -35,9 +36,16 @@ export async function writeSessionRowCellsSql(db, sessionId, cells, how, readAns
|
|
|
35
36
|
try {
|
|
36
37
|
await conn.begin();
|
|
37
38
|
const read = binder(dialect);
|
|
38
|
-
const locked = (await conn.query(`SELECT owner, incarnation, placement_kind,
|
|
39
|
+
const locked = (await conn.query(`SELECT owner, incarnation, placement_kind, leaf_seq FROM session_meta WHERE session_id = ${read.p(sessionId)} FOR UPDATE`, read.values)).rows[0];
|
|
40
|
+
const extRead = binder(dialect);
|
|
41
|
+
let ext;
|
|
42
|
+
if (locked !== undefined) {
|
|
43
|
+
const ensure = ensureSessionExtRowStatement(dialect, sessionId);
|
|
44
|
+
await conn.query(ensure.text, [...ensure.values]);
|
|
45
|
+
ext = (await conn.query(`SELECT execution_role, title, pinned FROM ${SESSION_EXT_TABLE} WHERE session_id = ${extRead.p(sessionId)} FOR UPDATE`, extRead.values)).rows[0];
|
|
46
|
+
}
|
|
39
47
|
const mark = how.row.log === undefined || locked === undefined ? undefined : await lockedLogMark(conn, dialect, sessionId, locked.leaf_seq);
|
|
40
|
-
verdict = judgeSessionRowWrite(sessionId, how, locked === undefined ? undefined : lockedRowFrom(dialect, sessionId, locked), () => {
|
|
48
|
+
verdict = judgeSessionRowWrite(sessionId, how, locked === undefined ? undefined : lockedRowFrom(dialect, sessionId, locked, ext), () => {
|
|
41
49
|
if (mark === undefined)
|
|
42
50
|
throw new Error(`writeSessionRowCellsSql: the judge asked session ${sessionId}'s log mark, but the expectation carries none`);
|
|
43
51
|
return mark;
|
|
@@ -53,7 +61,7 @@ export async function writeSessionRowCellsSql(db, sessionId, cells, how, readAns
|
|
|
53
61
|
if (cells.pinned !== undefined)
|
|
54
62
|
sets.push(`pinned = ${w.p(cells.pinned)}`);
|
|
55
63
|
if (sets.length > 0)
|
|
56
|
-
await conn.query(`UPDATE
|
|
64
|
+
await conn.query(`UPDATE ${SESSION_EXT_TABLE} SET ${sets.join(", ")} WHERE session_id = ${w.p(sessionId)}`, w.values);
|
|
57
65
|
await conn.commit();
|
|
58
66
|
}
|
|
59
67
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **SQL 会话店 = 引擎座店 + 部署的会话格**(两方言同一只类;组合座 `store-backend.ts` 装配)。
|
|
3
|
+
*
|
|
4
|
+
* ## 两半,一只店
|
|
5
|
+
* · **座**(`src/stores-sql/` 的方言店):引擎座表 `session_meta` / `session_event` 的唯一写者 —— 唤醒、追加、fork、导入、暂存、删除。
|
|
6
|
+
* · **部署格**(本模块):本服务记在一只会话上的格,全部住旁表 `session_ext`(属主 `session-ext-table.ts`)—— 列表投影的标题 / 置顶 / 行标签、
|
|
7
|
+
* 换源通告的基线、位置与项目、执行放置那一格与 fork 键。读引擎座表只经它的公布列(身份、属主、化身、时刻、委派判别位);写只写旁表。
|
|
8
|
+
* 座在它的写事务里锁住根行之后调部署的**事务内钩**({@link createSqlSessionWriteHooks},契约在 `stores-sql/session-write-hooks.ts`)——
|
|
9
|
+
* 认领、本处写者、导入落 mirror、fork 键都在座的同一事务里由钩判 / 写(同事务两句:锁根行一句、钩的读写各一句)。
|
|
10
|
+
*
|
|
11
|
+
* ## 一条列表读口
|
|
12
|
+
* 列表面(`listSessions` / `listSessionRows` / `sessionSummaryOf`)是一条 SELECT、一只行映射({@link SqlSessionStore.selectListRows}):
|
|
13
|
+
* `session_meta` LEFT JOIN 旁表(标题 / 置顶;行不在 = 未命名、未置顶)LEFT JOIN run 账本的预览。两方言只差语句文本(窗函数 / `DISTINCT ON`、JSON 标量提取、
|
|
14
|
+
* LIKE 的转义字面量、布尔的读法)。
|
|
15
|
+
*
|
|
16
|
+
* ## 旁表的写序(一条,与执行放置的写序律同一条)
|
|
17
|
+
* 每个格写者在一只事务里:锁根 `session_meta` 行(行不在 ⇒ 不写)→ 补旁表行(行在不动)→ 要判格的再锁定读那一行 → 一句按 `session_id` 定址的格写。根行先 ⇒ 与座的删除 /
|
|
18
|
+
* 导入 / 换装同一锁序,外键的补行不会与删除的级联互等;补行先于锁定读 ⇒ 锁定读永远落在一行在的记录上(不拿 InnoDB 间隙锁)。
|
|
19
|
+
*/
|
|
20
|
+
import type { AcquiredSession, PlacedSessionRow, SessionHead, SessionPlacementRecord, SessionStore, SessionTreeEntry } from "@sema-agent/core";
|
|
21
|
+
import type { TiDBSessionStore } from "../stores-sql/tidb-session-store.js";
|
|
22
|
+
import type { SessionWriteHooks } from "../stores-sql/session-write-hooks.js";
|
|
23
|
+
import type { SqlDriver } from "./sql-driver.js";
|
|
24
|
+
import { type ExecutionPlacementSeat } from "../execution-placement.js";
|
|
25
|
+
import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
|
|
26
|
+
import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowAnswer, type SessionRowPatch, type SessionRowWriteOutcome } from "../session-row.js";
|
|
27
|
+
import type { SessionSummary } from "./store-contracts.js";
|
|
28
|
+
import type { SessionWorkspace } from "../session-workspace.js";
|
|
29
|
+
/** 座的面:座的公开成员(两方言同形 —— PG 孪生按结构赋给它,组合座里 tsc 判)。 */
|
|
30
|
+
export type SessionSeat = Pick<TiDBSessionStore, "retention" | "placements" | "durability" | "acquire" | "register" | "placementOf" | "listPlaced" | "headOf" | "touch" | "release" | "forget" | "fork" | "forkTo" | "exportEntries" | "listEntryIds" | "exportEntriesStream" | "importEntries" | "replaceEntries" | "beginImportStaging" | "readStagedEntries" | "sweepStagingSessions" | "deleteSession" | "size" | "dispose">;
|
|
31
|
+
/** 列表面的查询(`OwnerAwareSessionStore.listSessions` 的入参形)。 */
|
|
32
|
+
export interface SessionListOptions {
|
|
33
|
+
owner?: string;
|
|
34
|
+
includeUnowned?: boolean;
|
|
35
|
+
cursor?: {
|
|
36
|
+
lastActivityAt: string;
|
|
37
|
+
sessionId: string;
|
|
38
|
+
};
|
|
39
|
+
limit: number;
|
|
40
|
+
q?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 会话店的事务内钩(座锁住根行之后、写之前调;同一事务、同一连接):
|
|
44
|
+
* · `import` —— 判官 {@link judgeImportWrite}(local 店的写锁内同调这一只):认领在 ⇒ 拒 `SessionActiveRunError`;这一处是写者 ⇒ 拒 `SessionWriterPresentError`;放行 ⇒ 这一格落 mirror(写者在别处);
|
|
45
|
+
* · `delete` / `retention-delete` —— 认领在 ⇒ 拒 `SessionActiveRunError`(级联随根行带走旁表行,钩不另删);
|
|
46
|
+
* · 键控 fork(服务扩展)—— `record`:新行的 fork 键落旁表(新行是本事务刚插下的,本事务持着它的锁);`targetOf`:撞上已在的目标时的一次池读(属主 + fork 键)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function createSqlSessionWriteHooks(db: Pick<SqlDriver, "dialect" | "query">): SessionWriteHooks;
|
|
49
|
+
export declare class SqlSessionStore implements SessionStore {
|
|
50
|
+
private readonly db;
|
|
51
|
+
/** 座(引擎座表的唯一写者)。 */
|
|
52
|
+
private readonly seat;
|
|
53
|
+
/** 托管留存声明 / placement 声明 / 耐久声明:座的声明逐字转发。 */
|
|
54
|
+
readonly retention: SessionSeat["retention"];
|
|
55
|
+
readonly placements: SessionSeat["placements"];
|
|
56
|
+
readonly durability: SessionSeat["durability"];
|
|
57
|
+
/** 执行席(规则在 `src/execution-placement.ts`;实现与语句的唯一属主 = `execution-placement-sql.ts`)。 */
|
|
58
|
+
readonly executionPlacement: ExecutionPlacementSeat;
|
|
59
|
+
/** `db` = 座的池包成的 SqlDriver(同一只池);`seatOn` 拿部署的事务内钩建座。 */
|
|
60
|
+
constructor(db: SqlDriver, seatOn: (hooks: SessionWriteHooks) => SessionSeat);
|
|
61
|
+
acquire(...a: Parameters<SessionSeat["acquire"]>): Promise<AcquiredSession>;
|
|
62
|
+
register(sessionId: string, owner: string | null): Promise<void>;
|
|
63
|
+
placementOf(sessionId: string): Promise<SessionPlacementRecord | undefined>;
|
|
64
|
+
listPlaced(...a: Parameters<SessionSeat["listPlaced"]>): Promise<PlacedSessionRow[]>;
|
|
65
|
+
headOf(sessionId: string): Promise<SessionHead | undefined>;
|
|
66
|
+
touch(sessionId: string): Promise<void>;
|
|
67
|
+
release(sessionId: string): Promise<void>;
|
|
68
|
+
forget(sessionId: string): void;
|
|
69
|
+
fork(...a: Parameters<SessionSeat["fork"]>): ReturnType<SessionSeat["fork"]>;
|
|
70
|
+
forkTo(...a: Parameters<SessionSeat["forkTo"]>): ReturnType<SessionSeat["forkTo"]>;
|
|
71
|
+
exportEntries(sessionId: string): Promise<SessionTreeEntry[] | null>;
|
|
72
|
+
listEntryIds(sessionId: string): Promise<string[] | null>;
|
|
73
|
+
exportEntriesStream(...a: Parameters<SessionSeat["exportEntriesStream"]>): ReturnType<SessionSeat["exportEntriesStream"]>;
|
|
74
|
+
importEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
75
|
+
replaceEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
76
|
+
beginImportStaging(...a: Parameters<SessionSeat["beginImportStaging"]>): ReturnType<SessionSeat["beginImportStaging"]>;
|
|
77
|
+
readStagedEntries(stagingId: string): Promise<SessionTreeEntry[]>;
|
|
78
|
+
sweepStagingSessions(): Promise<number>;
|
|
79
|
+
deleteSession(sessionId: string, owner: string | null): Promise<boolean>;
|
|
80
|
+
get size(): number;
|
|
81
|
+
dispose(): void;
|
|
82
|
+
/**
|
|
83
|
+
* E16 — list the caller's sessions (CC /resume picker), keyset-paginated newest-first by last activity. Session IDENTITY/enumeration comes from
|
|
84
|
+
* `session_meta` (owner-filtered on its owner column); the side table supplies the title / pin; a LEFT JOIN onto the `task_run` runs ledger
|
|
85
|
+
* supplies run-level PREVIEW (latest run's objective/status, run count) but never gates which sessions exist. Keyset on `(updated_at, session_id)`.
|
|
86
|
+
*/
|
|
87
|
+
listSessions(opts: SessionListOptions): Promise<SessionSummary[]>;
|
|
88
|
+
/** {@link listSessions} with each row's occupant (owner + incarnation) from the same SELECT — `OwnerAwareSessionStore.listSessionRows`; the incarnation never enters the row. */
|
|
89
|
+
listSessionRows(opts: SessionListOptions): Promise<Array<SessionRowAnswer<SessionSummary>>>;
|
|
90
|
+
/** ONE session's list row — {@link listSessions}' projection (same SELECT, same mapper) scoped to one id; `undefined` = not a row of the list face
|
|
91
|
+
* (no such session / placed). The run-preview subqueries are scoped to the same id. */
|
|
92
|
+
sessionSummaryOf(sessionId: string): Promise<SessionSummary | undefined>;
|
|
93
|
+
/** {@link sessionSummaryOf} 那一读 + 读到它时行上的住客(写原语的应答行要复核住客,`settleSessionRowWrite`)。 */
|
|
94
|
+
private listRowOf;
|
|
95
|
+
/**
|
|
96
|
+
* The list projection's ONE SELECT + row mapper ({@link listSessions} and {@link sessionSummaryOf} both read through it). `runSessionId` scopes the
|
|
97
|
+
* two run-preview subqueries to one session (the single-row read); the list leaves them whole. Placeholders are minted in text order (run scope,
|
|
98
|
+
* then `where`, then the LIMIT), so one builder serves both dialects. `sm.incarnation` is read for the row tag and the answer row's occupant only.
|
|
99
|
+
* The run-preview JOIN: the LATEST run per session (ties broken by task_id so EXACTLY one row joins) + a count rollup; LEFT JOINs keep sessions with
|
|
100
|
+
* no runs (preview NULL, run_count 0) and sessions with no side-table row (title NULL, not pinned).
|
|
101
|
+
*/
|
|
102
|
+
private selectListRows;
|
|
103
|
+
/**
|
|
104
|
+
* 会话行格写原语 —— 用户标题 / 置顶的唯一写口(规则与判序:`src/session-row.ts` 头注「写原语」;事务与语句:`session-row-sql.ts`)。应答行在提交 / 回滚之后
|
|
105
|
+
* 由列表行读另读(含新 `rowTag`)、复核仍是判过的那一位住客。只写列表面上的行(委派分区行 ⇒ `absent`);`updated_at` 不动(改名不是活动)。
|
|
106
|
+
*/
|
|
107
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ClientSessionRowWrite): Promise<SessionRowWriteOutcome<SessionSummary>>;
|
|
108
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ReplaySessionRowWrite): Promise<ReplaySessionRowWriteOutcome<SessionSummary>>;
|
|
109
|
+
/** Cheap pre-LLM probe: "none" = session_meta row not yet REGISTERED (createRun fires before the Runner's session acquire — the titler retries),
|
|
110
|
+
* "untitled" / "titled" as read (no side-table row = untitled). */
|
|
111
|
+
probeTitle(sessionId: string): Promise<"none" | "untitled" | "titled">;
|
|
112
|
+
/** The auto-titler's write: lands ONLY when title IS NULL (a concurrent/prior title — the user's included — wins; writer order: `src/session-row.ts`).
|
|
113
|
+
* Returns whether this call set it. No session row ⇒ `false`. */
|
|
114
|
+
setTitleIfNull(sessionId: string, title: string): Promise<boolean>;
|
|
115
|
+
/** 换源通告的基线读(一行 PK 读;列的三态读法见 `instruction-source-notice.ts`)。旁表行不在 ⇒ 读作「没记过」。语句期限 {@link BASELINE_IO_DEADLINE_MS}(过期 ⇒ 查询自己拒、连接销毁)。 */
|
|
116
|
+
readInstructionSource(sessionId: string): Promise<InstructionSourceBaseline>;
|
|
117
|
+
/**
|
|
118
|
+
* CAS 覆写基线(期望值 = 调用方读到的那一份;不符 ⇒ 0 行、不抛 —— 契约见 `InstructionSourceStore`)。会话行不在 ⇒ 不写。**不**碰 `updated_at`。
|
|
119
|
+
* 期限:事务里每一句带语句期限 {@link BASELINE_IO_DEADLINE_MS} —— 被行锁卡住的写由查询自己在期限内拒、连接销毁(事务随连接关闭回滚,池里不留卡住的连接);
|
|
120
|
+
* 调用方的 `withinIoDeadline` 同一只数,是它那一侧的放手。
|
|
121
|
+
*/
|
|
122
|
+
recordInstructionSource(sessionId: string, expected: InstructionSourceBaseline, source: string | null): Promise<void>;
|
|
123
|
+
/** 会话行的位置与项目那一格(域律 `src/session-workspace.ts`,列属主 `session-workspace-cell.ts`)。一行 PK 读,按文本投影、恰好解一次;行不在 / 格为 NULL ⇒ `undefined`。 */
|
|
124
|
+
readSessionWorkspace(sessionId: string): Promise<SessionWorkspace | undefined>;
|
|
125
|
+
/**
|
|
126
|
+
* 整格覆写(最后一帧胜;唯一调用方 = 腿的记录座)。**住客围栏**:只写化身仍是 `incarnation` 的那一行(锁根行时按化身收窄)—— 行不在、或同 id 已换了住客 ⇒
|
|
127
|
+
* 不写、不抛。**不**碰 `updated_at`。
|
|
128
|
+
*/
|
|
129
|
+
recordSessionWorkspace(sessionId: string, incarnation: string, workspace: SessionWorkspace): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=session-store-sql.d.ts.map
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { escapeLike } from "./sql-escape.js";
|
|
2
|
+
import { jsonColumnText } from "./sql-json-column.js";
|
|
3
|
+
import { pgSafeJsonStringify } from "./pg-safe-json.js";
|
|
4
|
+
import { SESSION_EXT_TABLE, ensureSessionExtRowStatement } from "./session-ext-table.js";
|
|
5
|
+
import { decodeSessionWorkspaceCell, encodeSessionWorkspaceCell } from "./session-workspace-cell.js";
|
|
6
|
+
import { createSqlExecutionPlacementSeat, markMirrorStatement, readCellOn, readClaimOn, writeCellOn } from "./execution-placement-sql.js";
|
|
7
|
+
import { SessionActiveRunError, judgeImportWrite } from "../execution-placement.js";
|
|
8
|
+
import { BASELINE_IO_DEADLINE_MS, decodeInstructionSource, encodeInstructionSource } from "../instruction-source-notice.js";
|
|
9
|
+
import { incarnationFromCell } from "../session-incarnation.js";
|
|
10
|
+
import { sessionRowTagKey } from "../session-row.js";
|
|
11
|
+
import { writeSessionRowCellsSql } from "./session-row-sql.js";
|
|
12
|
+
function binder(dialect) {
|
|
13
|
+
const values = [];
|
|
14
|
+
return {
|
|
15
|
+
values,
|
|
16
|
+
p: (v) => {
|
|
17
|
+
values.push(v);
|
|
18
|
+
return dialect === "pg" ? `$${values.length}` : "?";
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const rowsOnTxn = (txn) => async (sql, values) => (await txn.query(sql, [...values])).rows;
|
|
23
|
+
export function createSqlSessionWriteHooks(db) {
|
|
24
|
+
const dialect = db.dialect;
|
|
25
|
+
return {
|
|
26
|
+
async beforeCommit(txn, write) {
|
|
27
|
+
const rows = rowsOnTxn(txn);
|
|
28
|
+
const root = write.rootSessionId;
|
|
29
|
+
switch (write.op) {
|
|
30
|
+
case "import": {
|
|
31
|
+
const verdict = await judgeImportWrite(root, { claim: () => readClaimOn(rows, dialect, root), cell: () => readCellOn(rows, dialect, root) });
|
|
32
|
+
if (verdict !== "proceed")
|
|
33
|
+
return verdict;
|
|
34
|
+
await writeCellOn(txn, dialect, root, markMirrorStatement(dialect, root));
|
|
35
|
+
return "proceed";
|
|
36
|
+
}
|
|
37
|
+
case "delete":
|
|
38
|
+
case "retention-delete": {
|
|
39
|
+
const claim = await readClaimOn(rows, dialect, root);
|
|
40
|
+
return claim === null ? "proceed" : { refuse: new SessionActiveRunError(root, claim) };
|
|
41
|
+
}
|
|
42
|
+
default: {
|
|
43
|
+
const unknownOp = write.op;
|
|
44
|
+
throw new Error(`session write hooks: no write ${JSON.stringify(unknownOp)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
keyedFork: {
|
|
49
|
+
async record(txn, fork) {
|
|
50
|
+
const ensure = ensureSessionExtRowStatement(dialect, fork.rootSessionId);
|
|
51
|
+
await txn.query(ensure.text, [...ensure.values]);
|
|
52
|
+
const b = binder(dialect);
|
|
53
|
+
const res = await txn.query(`UPDATE ${SESSION_EXT_TABLE} SET fork_key = ${b.p(fork.forkKey)} WHERE session_id = ${b.p(fork.rootSessionId)}`, b.values);
|
|
54
|
+
if (res.affected !== 1)
|
|
55
|
+
throw new Error(`fork of session ${fork.rootSessionId}: the fork key write matched no row of a row this transaction just created — engine/driver anomaly, refusing to guess`);
|
|
56
|
+
},
|
|
57
|
+
async targetOf(sessionId) {
|
|
58
|
+
const b = binder(dialect);
|
|
59
|
+
const row = (await db.query(`SELECT sm.owner, se.fork_key FROM session_meta sm LEFT JOIN ${SESSION_EXT_TABLE} se ON se.session_id = sm.session_id WHERE sm.session_id = ${b.p(sessionId)}`, b.values)).rows[0];
|
|
60
|
+
if (row === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
return { owner: row.owner === null || row.owner === undefined ? null : String(row.owner), forkKey: row.fork_key === null || row.fork_key === undefined ? null : String(row.fork_key) };
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const BASELINE_STATEMENT = { deadlineMs: BASELINE_IO_DEADLINE_MS };
|
|
68
|
+
async function withLockedSessionExt(db, sessionId, lock, write) {
|
|
69
|
+
const conn = await db.connect();
|
|
70
|
+
const query = (sql, params) => conn.query(sql, params, lock.statement);
|
|
71
|
+
try {
|
|
72
|
+
await conn.begin();
|
|
73
|
+
const b = binder(db.dialect);
|
|
74
|
+
const locked = await query(`SELECT session_id FROM session_meta WHERE session_id = ${b.p(sessionId)}${lock.where === undefined ? "" : ` AND ${lock.where(b.p)}`} FOR UPDATE`, b.values);
|
|
75
|
+
if (locked.rows.length === 0) {
|
|
76
|
+
await conn.rollback();
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const ensure = ensureSessionExtRowStatement(db.dialect, sessionId);
|
|
80
|
+
await query(ensure.text, [...ensure.values]);
|
|
81
|
+
const wrote = await write(query);
|
|
82
|
+
await conn.commit();
|
|
83
|
+
return wrote;
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
await conn.rollback().catch(() => undefined);
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
conn.release();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const pinnedOf = (dialect, v) => (dialect === "pg" ? v === true : Number(v) === 1);
|
|
94
|
+
export class SqlSessionStore {
|
|
95
|
+
db;
|
|
96
|
+
seat;
|
|
97
|
+
retention;
|
|
98
|
+
placements;
|
|
99
|
+
durability;
|
|
100
|
+
executionPlacement;
|
|
101
|
+
constructor(db, seatOn) {
|
|
102
|
+
this.db = db;
|
|
103
|
+
this.seat = seatOn(createSqlSessionWriteHooks(db));
|
|
104
|
+
this.retention = this.seat.retention;
|
|
105
|
+
this.placements = this.seat.placements;
|
|
106
|
+
this.durability = this.seat.durability;
|
|
107
|
+
this.executionPlacement = createSqlExecutionPlacementSeat(db);
|
|
108
|
+
}
|
|
109
|
+
acquire(...a) {
|
|
110
|
+
return this.seat.acquire(...a);
|
|
111
|
+
}
|
|
112
|
+
register(sessionId, owner) {
|
|
113
|
+
return this.seat.register(sessionId, owner);
|
|
114
|
+
}
|
|
115
|
+
placementOf(sessionId) {
|
|
116
|
+
return this.seat.placementOf(sessionId);
|
|
117
|
+
}
|
|
118
|
+
listPlaced(...a) {
|
|
119
|
+
return this.seat.listPlaced(...a);
|
|
120
|
+
}
|
|
121
|
+
headOf(sessionId) {
|
|
122
|
+
return this.seat.headOf(sessionId);
|
|
123
|
+
}
|
|
124
|
+
touch(sessionId) {
|
|
125
|
+
return this.seat.touch(sessionId);
|
|
126
|
+
}
|
|
127
|
+
release(sessionId) {
|
|
128
|
+
return this.seat.release(sessionId);
|
|
129
|
+
}
|
|
130
|
+
forget(sessionId) {
|
|
131
|
+
this.seat.forget(sessionId);
|
|
132
|
+
}
|
|
133
|
+
fork(...a) {
|
|
134
|
+
return this.seat.fork(...a);
|
|
135
|
+
}
|
|
136
|
+
forkTo(...a) {
|
|
137
|
+
return this.seat.forkTo(...a);
|
|
138
|
+
}
|
|
139
|
+
exportEntries(sessionId) {
|
|
140
|
+
return this.seat.exportEntries(sessionId);
|
|
141
|
+
}
|
|
142
|
+
listEntryIds(sessionId) {
|
|
143
|
+
return this.seat.listEntryIds(sessionId);
|
|
144
|
+
}
|
|
145
|
+
exportEntriesStream(...a) {
|
|
146
|
+
return this.seat.exportEntriesStream(...a);
|
|
147
|
+
}
|
|
148
|
+
importEntries(sessionId, owner, entries) {
|
|
149
|
+
return this.seat.importEntries(sessionId, owner, entries);
|
|
150
|
+
}
|
|
151
|
+
replaceEntries(sessionId, owner, entries) {
|
|
152
|
+
return this.seat.replaceEntries(sessionId, owner, entries);
|
|
153
|
+
}
|
|
154
|
+
beginImportStaging(...a) {
|
|
155
|
+
return this.seat.beginImportStaging(...a);
|
|
156
|
+
}
|
|
157
|
+
readStagedEntries(stagingId) {
|
|
158
|
+
return this.seat.readStagedEntries(stagingId);
|
|
159
|
+
}
|
|
160
|
+
sweepStagingSessions() {
|
|
161
|
+
return this.seat.sweepStagingSessions();
|
|
162
|
+
}
|
|
163
|
+
deleteSession(sessionId, owner) {
|
|
164
|
+
return this.seat.deleteSession(sessionId, owner);
|
|
165
|
+
}
|
|
166
|
+
get size() {
|
|
167
|
+
return this.seat.size;
|
|
168
|
+
}
|
|
169
|
+
dispose() {
|
|
170
|
+
this.seat.dispose();
|
|
171
|
+
}
|
|
172
|
+
async listSessions(opts) {
|
|
173
|
+
return (await this.listSessionRows(opts)).map((a) => a.row);
|
|
174
|
+
}
|
|
175
|
+
async listSessionRows(opts) {
|
|
176
|
+
const dialect = this.db.dialect;
|
|
177
|
+
return this.selectListRows({
|
|
178
|
+
limit: opts.limit,
|
|
179
|
+
where: (p) => {
|
|
180
|
+
const where = ["sm.placement_kind IS NULL"];
|
|
181
|
+
if (opts.owner !== undefined)
|
|
182
|
+
where.push(opts.includeUnowned ? `(sm.owner = ${p(opts.owner)} OR sm.owner IS NULL)` : `sm.owner = ${p(opts.owner)}`);
|
|
183
|
+
if (opts.q) {
|
|
184
|
+
const escape = dialect === "pg" ? "'\\'" : "'\\\\'";
|
|
185
|
+
where.push(`EXISTS (SELECT 1 FROM task_run tr WHERE tr.session_id = sm.session_id AND LOWER(tr.objective_preview) LIKE LOWER(${p(`%${escapeLike(opts.q)}%`)}) ESCAPE ${escape})`);
|
|
186
|
+
}
|
|
187
|
+
if (opts.cursor) {
|
|
188
|
+
const at = new Date(opts.cursor.lastActivityAt);
|
|
189
|
+
where.push(`(sm.updated_at < ${p(at)} OR (sm.updated_at = ${p(at)} AND sm.session_id < ${p(opts.cursor.sessionId)}))`);
|
|
190
|
+
}
|
|
191
|
+
return where;
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async sessionSummaryOf(sessionId) {
|
|
196
|
+
return (await this.listRowOf(sessionId))?.row;
|
|
197
|
+
}
|
|
198
|
+
async listRowOf(sessionId) {
|
|
199
|
+
return (await this.selectListRows({ limit: 1, runSessionId: sessionId, where: (p) => ["sm.placement_kind IS NULL", `sm.session_id = ${p(sessionId)}`] }))[0];
|
|
200
|
+
}
|
|
201
|
+
async selectListRows(q) {
|
|
202
|
+
const dialect = this.db.dialect;
|
|
203
|
+
const b = binder(dialect);
|
|
204
|
+
const runWhere = () => (q.runSessionId !== undefined ? ` WHERE session_id = ${b.p(q.runSessionId)}` : "");
|
|
205
|
+
const runCount = `LEFT JOIN (SELECT session_id, COUNT(*) AS run_count FROM task_run${runWhere()} GROUP BY session_id) r ON r.session_id = sm.session_id `;
|
|
206
|
+
const latest = dialect === "pg"
|
|
207
|
+
? "LEFT JOIN (SELECT DISTINCT ON (session_id) session_id, objective_preview, status, task_id, result ->> 'runId' AS last_task_run_id FROM task_run" +
|
|
208
|
+
runWhere() +
|
|
209
|
+
" ORDER BY session_id, created_at DESC, task_id DESC) latest ON latest.session_id = sm.session_id "
|
|
210
|
+
: "LEFT JOIN (SELECT session_id, objective_preview, status, task_id, last_task_run_id FROM (" +
|
|
211
|
+
" SELECT session_id, objective_preview, status, task_id, JSON_UNQUOTE(JSON_EXTRACT(result, '$.runId')) AS last_task_run_id, " +
|
|
212
|
+
" ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY created_at DESC, task_id DESC) AS rn FROM task_run" +
|
|
213
|
+
runWhere() +
|
|
214
|
+
" ) lr WHERE rn = 1) latest ON latest.session_id = sm.session_id ";
|
|
215
|
+
const where = q.where(b.p);
|
|
216
|
+
const sql = "SELECT sm.session_id, sm.owner, sm.incarnation, sm.updated_at AS last_activity, sm.created_at AS first_activity, se.title, se.pinned, " +
|
|
217
|
+
" COALESCE(r.run_count, 0) AS run_count, latest.objective_preview, latest.status, latest.task_id AS last_run_id, latest.last_task_run_id " +
|
|
218
|
+
"FROM session_meta sm " +
|
|
219
|
+
`LEFT JOIN ${SESSION_EXT_TABLE} se ON se.session_id = sm.session_id ` +
|
|
220
|
+
runCount +
|
|
221
|
+
latest +
|
|
222
|
+
(where.length ? "WHERE " + where.join(" AND ") + " " : "") +
|
|
223
|
+
`ORDER BY sm.updated_at DESC, sm.session_id DESC LIMIT ${b.p(q.limit)}`;
|
|
224
|
+
const rows = (await this.db.query(sql, b.values)).rows;
|
|
225
|
+
return rows.map((r) => {
|
|
226
|
+
const runId = r.last_task_run_id;
|
|
227
|
+
const sessionId = String(r.session_id);
|
|
228
|
+
const owner = r.owner ?? null;
|
|
229
|
+
const incarnation = incarnationFromCell(sessionId, r.incarnation, "absent");
|
|
230
|
+
const title = r.title ?? null;
|
|
231
|
+
const pinned = pinnedOf(dialect, r.pinned);
|
|
232
|
+
const row = {
|
|
233
|
+
sessionId,
|
|
234
|
+
owner,
|
|
235
|
+
lastActivityAt: r.last_activity instanceof Date ? r.last_activity.toISOString() : String(r.last_activity),
|
|
236
|
+
firstActivityAt: r.first_activity instanceof Date ? r.first_activity.toISOString() : String(r.first_activity),
|
|
237
|
+
runCount: Number(r.run_count),
|
|
238
|
+
objectivePreview: r.objective_preview ?? null,
|
|
239
|
+
lastStatus: r.status == null ? "" : String(r.status),
|
|
240
|
+
lastRunId: r.last_run_id ?? null,
|
|
241
|
+
...(typeof runId === "string" && runId !== "" ? { lastTaskRunId: runId } : {}),
|
|
242
|
+
title,
|
|
243
|
+
pinned,
|
|
244
|
+
...sessionRowTagKey({ sessionId, owner, incarnation, cells: { title, pinned } }),
|
|
245
|
+
};
|
|
246
|
+
return { row, occupant: { owner, incarnation } };
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async writeSessionRowCells(sessionId, cells, how) {
|
|
250
|
+
return writeSessionRowCellsSql(this.db, sessionId, cells, how, (id) => this.listRowOf(id));
|
|
251
|
+
}
|
|
252
|
+
async probeTitle(sessionId) {
|
|
253
|
+
const b = binder(this.db.dialect);
|
|
254
|
+
const row = (await this.db.query(`SELECT se.title FROM session_meta sm LEFT JOIN ${SESSION_EXT_TABLE} se ON se.session_id = sm.session_id WHERE sm.session_id = ${b.p(sessionId)}`, b.values)).rows[0];
|
|
255
|
+
if (row === undefined)
|
|
256
|
+
return "none";
|
|
257
|
+
return row.title === null || row.title === undefined ? "untitled" : "titled";
|
|
258
|
+
}
|
|
259
|
+
async setTitleIfNull(sessionId, title) {
|
|
260
|
+
return withLockedSessionExt(this.db, sessionId, {}, async (query) => {
|
|
261
|
+
const b = binder(this.db.dialect);
|
|
262
|
+
return (await query(`UPDATE ${SESSION_EXT_TABLE} SET title = ${b.p(title)} WHERE session_id = ${b.p(sessionId)} AND title IS NULL`, b.values)).affected > 0;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
async readInstructionSource(sessionId) {
|
|
266
|
+
const b = binder(this.db.dialect);
|
|
267
|
+
const conn = await this.db.connect();
|
|
268
|
+
try {
|
|
269
|
+
const row = (await conn.query(`SELECT instruction_source FROM ${SESSION_EXT_TABLE} WHERE session_id = ${b.p(sessionId)}`, b.values, BASELINE_STATEMENT)).rows[0];
|
|
270
|
+
return decodeInstructionSource(row?.instruction_source);
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
conn.release();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async recordInstructionSource(sessionId, expected, source) {
|
|
277
|
+
const next = encodeInstructionSource(source);
|
|
278
|
+
await withLockedSessionExt(this.db, sessionId, { statement: BASELINE_STATEMENT }, async (query) => {
|
|
279
|
+
const b = binder(this.db.dialect);
|
|
280
|
+
const text = `UPDATE ${SESSION_EXT_TABLE} SET instruction_source = ${b.p(next)} WHERE session_id = ${b.p(sessionId)} AND ${expected.recorded ? `instruction_source = ${b.p(encodeInstructionSource(expected.source))}` : "instruction_source IS NULL"}`;
|
|
281
|
+
return (await query(text, b.values)).affected > 0;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
async readSessionWorkspace(sessionId) {
|
|
285
|
+
const b = binder(this.db.dialect);
|
|
286
|
+
const row = (await this.db.query(`SELECT ${jsonColumnText(this.db.dialect, "workspace")} FROM ${SESSION_EXT_TABLE} WHERE session_id = ${b.p(sessionId)}`, b.values)).rows[0];
|
|
287
|
+
return row === undefined ? undefined : decodeSessionWorkspaceCell(row.workspace, sessionId);
|
|
288
|
+
}
|
|
289
|
+
async recordSessionWorkspace(sessionId, incarnation, workspace) {
|
|
290
|
+
const dialect = this.db.dialect;
|
|
291
|
+
const cell = encodeSessionWorkspaceCell(workspace, dialect === "pg" ? pgSafeJsonStringify : JSON.stringify, sessionId);
|
|
292
|
+
await withLockedSessionExt(this.db, sessionId, { where: (p) => `incarnation = ${p(incarnation)}` }, async (query) => {
|
|
293
|
+
const b = binder(dialect);
|
|
294
|
+
return (await query(`UPDATE ${SESSION_EXT_TABLE} SET workspace = ${b.p(cell)}${dialect === "pg" ? "::jsonb" : ""} WHERE session_id = ${b.p(sessionId)}`, b.values)).affected > 0;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=session-store-sql.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SessionWorkspace } from "../session-workspace.js";
|
|
2
2
|
import { type JsonColumnReader } from "./sql-json-column.js";
|
|
3
|
-
/** 列定义的唯一属主(
|
|
4
|
-
export declare const
|
|
3
|
+
/** 列定义的唯一属主(旁表建表句内插它,`session-ext-table.ts`)。 */
|
|
4
|
+
export declare const SESSION_WORKSPACE_COLUMN: {
|
|
5
5
|
readonly name: "workspace";
|
|
6
6
|
readonly mysql: "workspace JSON NULL";
|
|
7
7
|
readonly pg: "workspace JSONB";
|
|
@@ -2,7 +2,7 @@ import { PROJECT_ID_REGEX } from "@sema-agent/core";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
4
4
|
import { assertJsonColumnWritable, createZodColumnReader, decodeJsonColumn, isJsonColumnBodyProblem } from "./sql-json-column.js";
|
|
5
|
-
export const
|
|
5
|
+
export const SESSION_WORKSPACE_COLUMN = {
|
|
6
6
|
name: "workspace",
|
|
7
7
|
mysql: "workspace JSON NULL",
|
|
8
8
|
pg: "workspace JSONB",
|
|
@@ -16,7 +16,7 @@ const SESSION_WORKSPACE_SHAPE = z.object({
|
|
|
16
16
|
});
|
|
17
17
|
export const readSessionWorkspaceCell = createZodColumnReader(SESSION_WORKSPACE_SHAPE);
|
|
18
18
|
export const SESSION_WORKSPACE_DEGRADED = "server.session-workspace.record-degraded";
|
|
19
|
-
const where = (sessionId) => `
|
|
19
|
+
const where = (sessionId) => `session_ext.workspace for session ${sessionId}`;
|
|
20
20
|
export function encodeSessionWorkspaceCell(workspace, encode, sessionId) {
|
|
21
21
|
const text = encode(workspace);
|
|
22
22
|
assertJsonColumnWritable(text, readSessionWorkspaceCell, where(sessionId));
|
|
@@ -131,6 +131,16 @@ export interface SqlSharedMemoryStoreOptions {
|
|
|
131
131
|
* This module keeps no copy of the pattern (nor of the `__` ban): the protocol table's namespace separator is core's to spell.
|
|
132
132
|
*/
|
|
133
133
|
export declare function assertStoreId(storeId: string): void;
|
|
134
|
+
/**
|
|
135
|
+
* MINT-side org scope key admission. The rule is core's own judge ({@link isOrgScopeKey}): `org:` plus one segment spelled by core's
|
|
136
|
+
* `formatOrgScope`. This module keeps no copy of the grammar, and no width bound of its own — core's segment bound is far inside the
|
|
137
|
+
* `scope_key` column.
|
|
138
|
+
*
|
|
139
|
+
* Called only where a key ENTERS a durable row: {@link SqlSharedMemoryStore.putScopeState} and {@link SqlSharedMemoryStore.putStore}.
|
|
140
|
+
* The other write methods take the key as a FENCE against the owner already registered for the store id ({@link ownedExactly}: a byte-for-byte
|
|
141
|
+
* match, loud on a miss), so they never judge its shape: a row stored under a key this judge now refuses stays addressable — it can still be
|
|
142
|
+
* written to and deleted, which is the way out for an operator who must re-home it under a key core accepts.
|
|
143
|
+
*/
|
|
134
144
|
export declare function assertScopeKey(scopeKey: string): void;
|
|
135
145
|
/**
|
|
136
146
|
* WRITE-side document-path admission: core's own judge ({@link isSharedMemoryDocumentPath} — the SAME predicate core's listing
|