@sema-agent/server 7.146.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 +384 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +170 -66
- package/deploy/facts/lanes.json +7 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +22 -0
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -4
- package/deploy/sema-up/chart/templates/server.yaml +5 -4
- package/deploy/sema-up/chart/values.yaml +1 -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 +4 -3
- package/dist/approval-card.d.ts +4 -4
- 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/device-lane.js +5 -5
- package/dist/boot/engine-lease.d.ts +12 -11
- package/dist/boot/execution-env.d.ts +2 -1
- package/dist/boot/execution-env.js +45 -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 +1 -1
- package/dist/boot/exit-last.js +2 -1
- package/dist/boot/governance-seams.d.ts +2 -2
- 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 +13 -24
- package/dist/boot/memory-consolidation.js +0 -13
- 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.js +1 -1
- package/dist/boot/resolve-spec.js +91 -111
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +8 -2
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +6 -2
- 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 +1 -1
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +3 -3
- package/dist/boot/stage-06-runners.d.ts +3 -3
- package/dist/boot/stage-06-runners.js +1 -3
- package/dist/boot/stage-07-capability-layer.d.ts +3 -3
- package/dist/boot/stage-07-capability-layer.js +4 -9
- package/dist/boot/stage-08-reapers.d.ts +3 -3
- package/dist/boot/stage-09-leader.d.ts +4 -3
- package/dist/boot/stage-10-http-server.d.ts +4 -3
- package/dist/boot/stage-10-http-server.js +2 -1
- package/dist/boot/stores.d.ts +9 -0
- package/dist/boot/stores.js +18 -7
- package/dist/boot/web-admin.js +3 -3
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +1 -0
- package/dist/capabilities/composite-members.js +1 -0
- 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 +32 -18
- 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 +38 -0
- package/dist/capability-facts.js +34 -1
- package/dist/center-credential-renewer.js +3 -2
- package/dist/config-catalog.js +6 -5
- 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.js +2 -0
- package/dist/config-types.d.ts +190 -186
- package/dist/config.d.ts +68 -5
- package/dist/config.js +80 -54
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deploy-facts.js +3 -2
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- 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 +17 -10
- package/dist/fleet/drain-entry.js +1 -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/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +52 -8
- package/dist/hooks/hook-runner.js +160 -36
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +17 -0
- package/dist/http/checkpoint-ctx.js +6 -0
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +1 -1
- package/dist/http/durable-run-leg.js +2 -1
- package/dist/http/execution-context.d.ts +3 -1
- package/dist/http/execution-context.js +4 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.js +3 -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 +3 -14
- package/dist/http/principal-gate.js +0 -13
- package/dist/http/request-guards.d.ts +1 -1
- package/dist/http/resume-legs.d.ts +7 -10
- package/dist/http/resume-legs.js +79 -50
- 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 +32 -16
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/approvals-assistant.js +5 -25
- package/dist/http/routes/capabilities.js +8 -2
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -1
- 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 +8 -8
- package/dist/http/routes/session-sync.js +27 -10
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +104 -2
- package/dist/http/routes/tasks.js +9 -3
- package/dist/http/server.d.ts +24 -10
- package/dist/http/server.js +17 -6
- package/dist/http/stored-body-replay.d.ts +5 -3
- package/dist/http/stored-body-replay.js +10 -1
- package/dist/http/wire-types.d.ts +19 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- 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-scope.d.ts +2 -2
- package/dist/memory-scope.js +1 -1
- 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/observability/fail-open.d.ts +17 -9
- package/dist/observability/fail-open.js +17 -9
- 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/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/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 +9 -4
- 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 +1 -1
- 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 -12
- package/dist/plugins/file-run-store.js +63 -63
- package/dist/plugins/imported-layer-root-retirement.d.ts +17 -8
- 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 +5 -0
- package/dist/plugins/local-checkpoint-store.js +11 -7
- 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 +91 -25
- package/dist/plugins/local-session-store.js +124 -45
- 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 +4 -3
- package/dist/plugins/memory-engine-pg.js +4 -4
- package/dist/plugins/memory-engine-sql-apply.d.ts +13 -4
- package/dist/plugins/memory-engine-sql-apply.js +1 -1
- package/dist/plugins/memory-engine-tidb.d.ts +8 -5
- package/dist/plugins/memory-engine-tidb.js +7 -8
- package/dist/plugins/one-time-migrations.d.ts +145 -35
- package/dist/plugins/one-time-migrations.js +272 -120
- 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 +8 -8
- package/dist/plugins/permission-rule-store-file.js +14 -2
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +11 -4
- 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/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 +11 -1
- 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 +1 -1
- 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/store-backend.d.ts +35 -8
- package/dist/plugins/store-backend.js +184 -62
- package/dist/plugins/store-contracts.d.ts +9 -2
- package/dist/plugins/store-contracts.js +1 -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 +19 -31
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- 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 +41 -13
- package/dist/rules-consent.js +101 -53
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +26 -16
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sealed-key-layout.d.ts +2 -3
- package/dist/sealed-key-layout.js +0 -1
- package/dist/sealed-key.js +7 -5
- package/dist/security.d.ts +5 -3
- 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-resident-background.d.ts +85 -32
- package/dist/session-resident-background.js +75 -7
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +1 -1
- package/dist/session-workspace.d.ts +11 -2
- package/dist/session-workspace.js +5 -0
- package/dist/sighup-idle.d.ts +1 -1
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/stores-sql/checkpoint-store-sql.d.ts +1 -1
- package/dist/stores-sql/checkpoint-store-sql.js +11 -27
- 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}/pg-session-storage.d.ts +23 -76
- package/dist/{plugins → stores-sql}/pg-session-storage.js +80 -209
- 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}/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 +32 -122
- package/dist/{plugins → stores-sql}/tidb-session-store.js +71 -171
- package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
- package/dist/stores-sql/tool-result-store-sql.js +1 -1
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- 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 +9 -4
- package/dist/task-settings.js +17 -6
- package/dist/tool-approval.d.ts +21 -8
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +9 -3
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +23 -1
- package/dist/trace/exit-seat.js +3 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +12 -9
- package/dist/trace/redact.d.ts +1 -1
- package/dist/trace/redact.js +61 -73
- package/dist/trace/self-minted-wire.d.ts +263 -10
- package/dist/trace/self-minted-wire.js +90 -2
- 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 +38 -2
- package/dist/trace/wire-projection-faces.js +26 -1
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -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 +13 -12
- package/scripts/drain-check-local.mjs +2 -28
- package/scripts/drain-check.mysql.sql +2 -18
- package/scripts/drain-check.pg.sql +2 -18
- package/wire-changes/server@7.147.0.json +813 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [ref] A9 域模块 —— 单会话面。
|
|
3
3
|
*
|
|
4
|
-
* 路由:`/v1/sessions/:id` 的 init / settings / mcp / head / events(SSE)/ fork / PATCH(会话行可写位)/ DELETE / policy / workspace,
|
|
4
|
+
* 路由:`/v1/sessions/:id` 的 init / settings / mcp / head / events(SSE)/ fork / rewind-files(run 外只恢复代码)/ PATCH(会话行可写位)/ DELETE / policy / workspace,
|
|
5
5
|
* 外加同段的 `deps.sessionAudit` 只读审计面。
|
|
6
6
|
*
|
|
7
7
|
* 单域独占状态(lens1 §C2 的 12 条里的 5 条)全部收进 `SessionsLocal`,每个 server 实例一份:
|
|
@@ -121,6 +121,12 @@ export declare const SESSIONS_ROUTES: readonly [{
|
|
|
121
121
|
readonly pattern: RegExp;
|
|
122
122
|
readonly label: "/v1/sessions/:id";
|
|
123
123
|
readonly methods: readonly ["GET"];
|
|
124
|
+
}, {
|
|
125
|
+
readonly id: "session-rewind-files";
|
|
126
|
+
readonly pattern: RegExp;
|
|
127
|
+
readonly label: "/v1/sessions/:id/rewind-files";
|
|
128
|
+
readonly credentialGated: readonly ["POST"];
|
|
129
|
+
readonly methods: readonly ["POST"];
|
|
124
130
|
}, {
|
|
125
131
|
readonly id: "session-patch";
|
|
126
132
|
readonly pattern: RegExp;
|
|
@@ -14,18 +14,23 @@ import { readWritableSessionPermissionRules } from "../../session-policy-wire.js
|
|
|
14
14
|
import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
|
|
15
15
|
import { fleetViewOf, gatedPrincipal, explicitOperatorOk, sessionCallerOf, sessionOwnerReadable, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
|
|
16
16
|
import { headReadOf, leafOfAdmittedHead, sessionFaceOfHead } from "../../session-incarnation.js";
|
|
17
|
-
import { foldOwnerUnreadable, runRowReadableOnSessionFace } from "../owner-access.js";
|
|
17
|
+
import { foldOwnerUnreadable, readOwnedSessionHead, runRowReadableOnSessionFace } from "../owner-access.js";
|
|
18
18
|
import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
|
|
19
19
|
import * as facts from "../../capability-facts.js";
|
|
20
20
|
import { rosterAgentId } from "./agents-roster.js";
|
|
21
21
|
import { projectSessionListRow } from "./sessions-list.js";
|
|
22
22
|
import { readSessionRowPatch } from "../../session-row.js";
|
|
23
|
-
import { forkPathOf } from "../execution-context.js";
|
|
23
|
+
import { forkPathOf, resolveExecutionContext } from "../execution-context.js";
|
|
24
24
|
import { executionPlacementView } from "../../execution-placement.js";
|
|
25
|
+
import { resolveHistoryAnchor } from "../../history-anchor.js";
|
|
26
|
+
import { engineRefusalAnswerOf } from "../engine-refusal.js";
|
|
27
|
+
import { buildRewindFilesReply } from "../rewind-files-reply.js";
|
|
25
28
|
import { ForkTargetUnsettledError, forkKeyOf } from "../../plugins/session-fork.js";
|
|
26
29
|
import { fieldConflictFacts } from "../../field-conflict.js";
|
|
27
30
|
import { buildBoundedToolNames } from "../../panel-tool-names.js";
|
|
28
31
|
import { projectMcpAuthorization } from "../../mcp-authorization-face.js";
|
|
32
|
+
import { presentHostWorkspaceOf } from "../../task-cwd.js";
|
|
33
|
+
import { rewindFilesUnderPurpose } from "../../execution-env-purpose.js";
|
|
29
34
|
const MCP_STATUS_TTL_MS = 5_000;
|
|
30
35
|
const A2A_STATUS_TTL_MS = 5_000;
|
|
31
36
|
const A2A_MATERIALIZE_TIMEOUT_MS = 10_000;
|
|
@@ -743,6 +748,82 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
743
748
|
}
|
|
744
749
|
}
|
|
745
750
|
}
|
|
751
|
+
if (match.decl.id === "session-rewind-files") {
|
|
752
|
+
if (ctx.helpers.rateLimited(req, res))
|
|
753
|
+
return;
|
|
754
|
+
const rewind = facts.sessionRewindFiles(deps);
|
|
755
|
+
if (!rewind.available) {
|
|
756
|
+
switch (rewind.why) {
|
|
757
|
+
case "file_history_store_absent":
|
|
758
|
+
sendError(res, 501, "capability.snapshot_store_required", "rewinding a session's files is not available on this deployment: no file-history store is wired, so no file history was ever recorded");
|
|
759
|
+
return;
|
|
760
|
+
case "session_head_face_absent":
|
|
761
|
+
sendError(res, 501, "capability.session_store_required", "rewinding a session's files requires a durable session store (DB_BACKEND=mysql|pg|local)");
|
|
762
|
+
return;
|
|
763
|
+
case "resume_anchor_store_absent":
|
|
764
|
+
sendError(res, 501, "capability.session_store_required", "rewinding a session's files is not available on this deployment: no session-store backend holds the rewind anchor map");
|
|
765
|
+
return;
|
|
766
|
+
case "execution_lane_handless":
|
|
767
|
+
sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment: it mounts no execution environment (REMOTE_EXEC=none), so a session has no working tree to rewind");
|
|
768
|
+
return;
|
|
769
|
+
case "workspace_rebuilt_per_task":
|
|
770
|
+
sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment: each task's workspace is rebuilt when the task starts (fresh, or restored from a saved copy that a rewind cannot yet write into), so a rewind would not reach the files the next task works on");
|
|
771
|
+
return;
|
|
772
|
+
case "session_store_shared":
|
|
773
|
+
sendError(res, 501, "capability.unavailable", "rewinding a session's files is not available on this deployment yet: its session store is shared by several server instances (DB_BACKEND=mysql|pg), and a rewind cannot yet keep runs started on another instance off the session while it restores");
|
|
774
|
+
return;
|
|
775
|
+
default:
|
|
776
|
+
return assertNever(rewind.why);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
const { anchors, sessionStorage } = rewind;
|
|
780
|
+
const sessionId = safeDecode(match.params.sessionId);
|
|
781
|
+
if (sessionId === null || !isUuidShape(sessionId)) {
|
|
782
|
+
sendError(res, 400, "request.id_invalid", "invalid session id (must be a canonical uuid)");
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
const caller = sessionCallerOf(req, deps);
|
|
786
|
+
if (DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(deps.config) && caller.principal === undefined) {
|
|
787
|
+
sendPrincipalRefusal(res, req, deps.config);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
const owned = await readOwnedSessionHead(deps, sessionStorage, caller, sessionId, "owner_or_operator");
|
|
791
|
+
if (owned === undefined) {
|
|
792
|
+
sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
const sessionOwner = owned.head.owner;
|
|
796
|
+
leafOfAdmittedHead(owned.head);
|
|
797
|
+
const read = readRewindFilesBody(await readJson(req));
|
|
798
|
+
if (read.kind === "refused") {
|
|
799
|
+
sendError(res, 400, read.errorCode, read.message);
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
const execution = await resolveExecutionContext(deps, { kind: "continuation", root: sessionId, principal: sessionOwner ?? undefined });
|
|
803
|
+
if (execution.lane === "host" && (await presentHostWorkspaceOf(deps.perSessionCwd?.get(sessionId))) === undefined) {
|
|
804
|
+
sendError(res, 409, "conflict.session_workspace_unknown", "this server process does not know a working directory for this session that it can rewind into (no prompt carrying its cwd has been submitted since the server started, or the directory that prompt named no longer exists), so nothing was rewound; submit a prompt with its cwd first, then rewind");
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
const entryId = await resolveHistoryAnchor("rewindFilesTo", anchors, sessionId, read.to, sessionOwner, "to");
|
|
808
|
+
const activeTaskId = await deps.runStore?.getActiveTaskId(sessionId);
|
|
809
|
+
if (activeTaskId) {
|
|
810
|
+
sendError(res, 409, "conflict.session_active_run", `session has an active run (${activeTaskId}); its files cannot be rewound under it — wait for that run to end (or cancel it), then rewind`, { activeTaskId });
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
let result;
|
|
814
|
+
try {
|
|
815
|
+
result = await rewindFilesUnderPurpose(deps.runner, { sessionId, to: entryId, dryRun: read.dryRun });
|
|
816
|
+
}
|
|
817
|
+
catch (e) {
|
|
818
|
+
const answer = engineRefusalAnswerOf(e);
|
|
819
|
+
if (answer === undefined)
|
|
820
|
+
throw e;
|
|
821
|
+
sendError(res, answer.status, answer.refusal.errorCode, answer.refusal.message);
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
sendJson(res, 200, buildRewindFilesReply(result));
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
746
827
|
{
|
|
747
828
|
if (match.decl.id === "session-fork") {
|
|
748
829
|
const forkFact = facts.sessionFork(deps);
|
|
@@ -967,6 +1048,7 @@ export const SESSIONS_ROUTES = [
|
|
|
967
1048
|
{ id: "session-memory-status", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/memory-status$/, label: "/v1/sessions/:id/memory-status", methods: ["GET"] },
|
|
968
1049
|
{ id: "session-workspace", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/workspace(?:\/(?<key>[^/]+)(?:\/(?<sub>tree|file|archive))?)?$/, label: "/v1/sessions/:id/workspace", methods: ["GET"] },
|
|
969
1050
|
{ id: "session-detail", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["GET"] },
|
|
1051
|
+
{ id: "session-rewind-files", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)\/rewind-files$/, label: "/v1/sessions/:id/rewind-files", credentialGated: ["POST"], methods: ["POST"] },
|
|
970
1052
|
{ id: "session-patch", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["PATCH"] },
|
|
971
1053
|
{ id: "session-delete", pattern: /^\/v1\/sessions\/(?<sessionId>[^/]+)$/, label: "/v1/sessions/:id", methods: ["DELETE"] },
|
|
972
1054
|
];
|
|
@@ -989,4 +1071,24 @@ function readForkTarget(raw, sourceId) {
|
|
|
989
1071
|
return { kind: "keyed", forkId, forkNonce };
|
|
990
1072
|
}
|
|
991
1073
|
const FORK_NONCE_MAX_CHARS = 255;
|
|
1074
|
+
const REWIND_TO_MAX_CHARS = 255;
|
|
1075
|
+
function readRewindFilesBody(raw) {
|
|
1076
|
+
const shape = {
|
|
1077
|
+
kind: "refused",
|
|
1078
|
+
errorCode: "request.body_shape",
|
|
1079
|
+
message: 'the rewind-files body must be an object { to: string, dryRun?: boolean } — acceptPartialRestore is not accepted: the engine\'s out-of-run rewind has no partial-restore policy, so a partial restore answers 200 with restore.outcome "partial" and every refused or failed file on its ledger',
|
|
1080
|
+
};
|
|
1081
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
1082
|
+
return shape;
|
|
1083
|
+
const keys = Object.keys(raw);
|
|
1084
|
+
if (!keys.includes("to") || keys.some((k) => k !== "to" && k !== "dryRun"))
|
|
1085
|
+
return shape;
|
|
1086
|
+
const { to, dryRun } = raw;
|
|
1087
|
+
if (typeof to !== "string" || to.length === 0 || to.length > REWIND_TO_MAX_CHARS) {
|
|
1088
|
+
return { kind: "refused", errorCode: "request.field_invalid", message: `to must be a non-empty string of at most ${REWIND_TO_MAX_CHARS} characters: the handle of a prompt in this session (the handle rewindFilesTo takes)` };
|
|
1089
|
+
}
|
|
1090
|
+
if (dryRun !== undefined && typeof dryRun !== "boolean")
|
|
1091
|
+
return { kind: "refused", errorCode: "request.field_invalid", message: "dryRun must be a boolean when given" };
|
|
1092
|
+
return { kind: "read", to, dryRun: dryRun === true };
|
|
1093
|
+
}
|
|
992
1094
|
//# sourceMappingURL=sessions.js.map
|
|
@@ -16,7 +16,7 @@ import { buildCancelledLedgerRow, createRunAbort, mintCancelledResult } from "..
|
|
|
16
16
|
import { recordResourceWindow } from "../../resource-window.js";
|
|
17
17
|
import { redactSecrets } from "../../trace/redact.js";
|
|
18
18
|
import { writeLiveFrame, writeLiveHeartbeat } from "../live-frame.js";
|
|
19
|
-
import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, liveIdentityFields } from "../../trace/project.js";
|
|
19
|
+
import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat, liveIdentityFields } from "../../trace/project.js";
|
|
20
20
|
import { cascadeConfig, fillRunPreviewOnDelivery, runMeta } from "../run-meta.js";
|
|
21
21
|
import { idemCallerOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
|
|
22
22
|
import { replayOfExistingRun } from "../submit-replay.js";
|
|
@@ -27,6 +27,7 @@ import { approvalPreambleReplays, createApprovalCardEmitter, declaredApprovalFra
|
|
|
27
27
|
import { buildActiveRunConflict, isActiveRunConflictBody, toDoneFrameResult } from "../active-run-conflict.js";
|
|
28
28
|
import { commitExecutionContext } from "../execution-context.js";
|
|
29
29
|
import { rootSessionAbsentAnswer } from "../execution-context.js";
|
|
30
|
+
import { timeClaim } from "../claim-latency.js";
|
|
30
31
|
import { commitSessionInheritEnv } from "../session-inherit-env.js";
|
|
31
32
|
import { headerStr, gatedPrincipal, explicitOperatorOk, runIdentityOf } from "../principal-gate.js";
|
|
32
33
|
import { failOpenTagForDroppedFrame, recordFailOpen } from "../../observability/fail-open.js";
|
|
@@ -184,6 +185,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
184
185
|
}
|
|
185
186
|
reqState.streamTaskId = earlyDurableTid;
|
|
186
187
|
let usageKey;
|
|
188
|
+
let manifestSeat;
|
|
187
189
|
reqState.streamDetached = detachOnDisconnect;
|
|
188
190
|
sseHeaders(res, earlyDurableTid ? { "x-task-id": earlyDurableTid } : undefined);
|
|
189
191
|
if (earlyDurableTid)
|
|
@@ -302,7 +304,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
302
304
|
};
|
|
303
305
|
if (deps.runStore) {
|
|
304
306
|
const tid = earlyDurableTid ?? uuidv7();
|
|
305
|
-
const created = await deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null });
|
|
307
|
+
const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null }));
|
|
306
308
|
if (created.ok)
|
|
307
309
|
clearTurnActivity(tid);
|
|
308
310
|
if (created.ok)
|
|
@@ -348,6 +350,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
348
350
|
ledgerSink = createLedgerSink({ appendEvent: (seq, type, data) => rs.appendEvent(tid, seq, type, data), persistThinking: deps.config.traceThinking, onActivity: (kind, statusData) => recordTurnActivity(tid, kind, statusData), legSections: legWiringSections, usage: { modelUsage: deps.modelUsage, taskId: tid } });
|
|
349
351
|
usageKey = tid;
|
|
350
352
|
deps.modelUsage?.register(tid);
|
|
353
|
+
manifestSeat = createPromptManifestSeat(deps.promptManifests, tid);
|
|
351
354
|
const owner = principal ?? null;
|
|
352
355
|
const abortFromVerb = () => ac.abort("cancel_verb");
|
|
353
356
|
durableHeartbeat = setInterval(() => {
|
|
@@ -508,6 +511,8 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
508
511
|
await deps.userInputLedger?.observeLegEvent(liveStream, ev);
|
|
509
512
|
await prepared.acceptance.observe(ev);
|
|
510
513
|
await liveWorkspace.observe(ev);
|
|
514
|
+
if (ledgerSink)
|
|
515
|
+
await manifestSeat?.drain(ledgerSink.append);
|
|
511
516
|
if (ev.type === "done") {
|
|
512
517
|
finalResult = await mintSubmitExitResult(ev.result, deps.checkpointStore);
|
|
513
518
|
if (durableTaskId && finalResult)
|
|
@@ -869,6 +874,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
869
874
|
clearInterval(hb);
|
|
870
875
|
if (usageKey)
|
|
871
876
|
deps.modelUsage?.clear(usageKey);
|
|
877
|
+
manifestSeat?.release();
|
|
872
878
|
}
|
|
873
879
|
if (!ranLive && resp && !res.writableEnded) {
|
|
874
880
|
writeLiveFrame(res, { type: "done", result: doneResultOfOutcome(resp), replay: true });
|
|
@@ -889,7 +895,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
889
895
|
let durableHeartbeat;
|
|
890
896
|
if (deps.runStore) {
|
|
891
897
|
const tid = uuidv7();
|
|
892
|
-
const created = await deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null });
|
|
898
|
+
const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(tid, prepared.spec.sessionId, principal ?? null, deps.instanceId ?? "default", { ...runMeta(prepared, source), identity: runIdentityOf(req, deps.config, principal ?? null), idem: idem ?? null }));
|
|
893
899
|
if (created.ok)
|
|
894
900
|
clearTurnActivity(tid);
|
|
895
901
|
if (created.ok)
|
package/dist/http/server.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type { SubagentSteerRegistry } from "../orchestration/subagent-steer.js";
|
|
|
21
21
|
import { type WorkflowCompletionInbox } from "../orchestration/workflow-completion-inbox.js";
|
|
22
22
|
import type { FleetLeaseManager } from "../fleet-lease.js";
|
|
23
23
|
import { type FleetEventBus } from "../fleet/fleet-bus.js";
|
|
24
|
+
import type { SessionResidentCounts } from "../session-resident-background.js";
|
|
24
25
|
import type { ElicitationCoordinator } from "../elicitation.js";
|
|
25
26
|
import type { QuestionCoordinator } from "../question.js";
|
|
26
27
|
import { type ParkedAskRedeem, type ToolApprovalCoordinator } from "../tool-approval.js";
|
|
@@ -100,7 +101,9 @@ export interface ServiceCoreDeps {
|
|
|
100
101
|
/**
|
|
101
102
|
* Map an inbound request body + resolved auth to a TaskSpec. The SERVICE/deployment owns model
|
|
102
103
|
* + tools + mcp here (callers only supply content). `auth` carries the principal-derived memory scope —
|
|
103
|
-
* prefer it over anything in the body.
|
|
104
|
+
* prefer it over anything in the body. The root session is not read from `auth` either: the resolver's one reading of
|
|
105
|
+
* "which session is this leg on" is `opts.execution.root` (`auth.sessionId` is the authorizer's hand-off to the server's
|
|
106
|
+
* execution-context resolver, not a second reading for the resolver).
|
|
104
107
|
* The root session is NOT the resolver's to write: the return type carries no `sessionId`
|
|
105
108
|
* (`ResolvedTaskSpec`); the server stamps the root the authorizer resolved onto every spec it executes
|
|
106
109
|
* (`http/execution-context.ts` `stampSpecRoot`). A resolver that needs the root reads `opts.execution.root`.
|
|
@@ -155,7 +158,8 @@ export interface ServiceCoreDeps {
|
|
|
155
158
|
* `principalCaps`、同一份部署缺省):凡回答「此主体在此场景能看见哪些 MCP 服务器 / A2A 对端」的口 —— `GET /v1/capabilities/mcp` 的状态面、
|
|
156
159
|
* `GET /v1/sessions/:id/mcp` 与 `…/a2a` 两张会话面板 —— 的场景名都由它给,**点名与缺席都问**:点名 ⇒ 判在册 / allowlist,
|
|
157
160
|
* 拒体(400 `scenario_unknown` 附在册词表 / 400 `scenario_not_allowed` 附 allowlist)与任务提交腿逐字同;缺席 ⇒ 指派链(中心 ruling 胜者,
|
|
158
|
-
* 否则部署缺省),与这位主体 run 时同一读法(指派悬空 ⇒ 503 `state.scenario_assignment_unknown`,同提交腿)
|
|
161
|
+
* 否则部署缺省),与这位主体 run 时同一读法(指派悬空 ⇒ 503 `state.scenario_assignment_unknown`,同提交腿)。中心配了却答不出这位主体的裁定 ⇒
|
|
162
|
+
* 点名与缺席同答 503 `state.scenario_assignment_unavailable`(同提交腿)。
|
|
159
163
|
* 读面上这只门走**只读腿**(`createScenarioGate(…, "peek")`):问中心裁定时 center 抖动的那一拍,不替这个主体的真提交留下 fail-closed 降级项
|
|
160
164
|
* (提交腿自己是 `"enforce"`)。
|
|
161
165
|
* 🔴 **必填**:读口的场景名只有这一个来源,没有「缺接缝 ⇒ 读部署缺省 / 点名 404」这类第二种读法 —— 漏接是**编译错**(嵌入方自己装配时,工厂与它的型从包根导出:
|
|
@@ -717,16 +721,24 @@ export interface ServiceDeploymentDeps {
|
|
|
717
721
|
* composition root 装起来的夹具)⇒ 两键都缺席,两面与没有声明的部署逐字节同。
|
|
718
722
|
*/
|
|
719
723
|
deploymentModPackages?: number;
|
|
724
|
+
/**
|
|
725
|
+
* 会话 → 调用方登记的工作目录(提交体 `cwd` 的唯一写口 `setSessionCwd` 写的那一张进程内表,`boot/execution-env.ts` `createSessionScopedRegistries`)。
|
|
726
|
+
* **只读**,读者只有 run 外回退口(`POST /v1/sessions/:id/rewind-files`):host 工厂按 `effectiveHostWorkspace(本表.get(会话), ctx)` 定根(`execution-env.ts`
|
|
727
|
+
* host 臂),口在交引擎之前用**同一只函数、同一份入参**问「工厂这一次会不会落到一只用完即删的临时目录」—— 会 ⇒ 拒,不让台账说恢复了而项目没动。
|
|
728
|
+
* 缺席(夹具 / 嵌入方没接)⇒ 读作「没有登记」⇒ host 车道上口拒(fail-closed)。
|
|
729
|
+
*/
|
|
730
|
+
perSessionCwd?: ReadonlyMap<string, string>;
|
|
720
731
|
/**
|
|
721
732
|
* Graceful drain — shared mutable state between main.ts (flips `draining` on SIGTERM) and this server:
|
|
722
733
|
* • while `draining`, NEW model-running submissions (the billable submit paths) get 503 + Retry-After, so an
|
|
723
734
|
* orchestrator/shell retries against the replacement instance; read paths + in-flight verbs (steer/cancel/
|
|
724
735
|
* respond/subagent) stay open so the runs we are waiting on can still finish/interact.
|
|
725
736
|
* • `inflight` is ASSIGNED BY createServer (a live union of this replica's in-flight legs: durable bg/resume
|
|
726
|
-
* `inflightRuns` + live sync/resume streams `steerableRuns`, the leader leg,
|
|
727
|
-
* shells/monitors — `inflightBreakdown` is the same read split into its
|
|
728
|
-
*
|
|
729
|
-
*
|
|
737
|
+
* `inflightRuns` + live sync/resume streams `steerableRuns`, the leader leg, the background sub-agents that outlived the leg
|
|
738
|
+
* that spawned them, and the session-resident background shells/monitors — `inflightBreakdown` is the same read split into its
|
|
739
|
+
* four terms) — an observable fact (`/health.inflight`).
|
|
740
|
+
* `blockingInflight` (also ASSIGNED BY createServer) is the SAME breakdown function minus the session-resident shell term: "is there still
|
|
741
|
+
* work that must be waited out" — the drain wait main.ts polls after SIGTERM, the orphan/lease windows and the SIGHUP idle window read THAT.
|
|
730
742
|
* • /health carries `draining:true` + `version` (build self-description); draining is a readiness reason
|
|
731
743
|
* (`http/readiness.ts`) ⇒ `/readyz` 503 + `/health` `ready:false` (the k8s readiness 摘流信号).
|
|
732
744
|
* • [ref]:`attachedStreams` 同样 ASSIGNED BY createServer —— 本副本当前打开着的 SSE 流条数
|
|
@@ -738,11 +750,13 @@ export interface ServiceDeploymentDeps {
|
|
|
738
750
|
*/
|
|
739
751
|
drainState?: import("../fleet/drain-entry.js").DrainState;
|
|
740
752
|
/**
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
* `drainState.blockingInflight`(排空 / 孤儿窗与附着租约自退 / SIGHUP
|
|
753
|
+
* 会话驻留后台行的读口:本进程活过起它的腿、仍在跑的**后台子代理**与**后台 shell / monitor**,一次走查交出两项(`session-resident-background.ts` 的
|
|
754
|
+
* `countSessionResidentBackground` 在 composition root 绑上围栏表;法与边界见该文件头)。`createHttpServer` 把两项并进**唯一的分项函数** `inflightBreakdown`:
|
|
755
|
+
* `backgroundAgents` 进阻断集 `drainState.blockingInflight`(排空 / 孤儿窗与附着租约自退 / SIGHUP 空闲窗判停读它)与总数,`sessionResident` 只进总数 `drainState.inflight`。
|
|
756
|
+
* 读口**不许抛**:判停路径每拍读它,排空首读在期限计时器装上之前 —— 一抛就永不硬停(组合根那只按会话收住读失败、计 1 并报出)。
|
|
757
|
+
* 缺席(嵌入方 / 夹具)= 两项恒 0,两个读数逐字同 7.145.x。
|
|
744
758
|
*/
|
|
745
|
-
sessionResidentBackground?: () =>
|
|
759
|
+
sessionResidentBackground?: () => SessionResidentCounts;
|
|
746
760
|
/** 编排器片 2 件 3:服务租约此刻的读数(`fleet/serving-lease.ts` 的客户端交出;引擎信号铸点与计费准入判同读)。缺席 = 没装租约客户端
|
|
747
761
|
* (非 fleet 成员 / 没接中心 / 测试夹具)⇒ `none`(与没有租约的引擎逐字同)。 */
|
|
748
762
|
servingLease?: () => import("../fleet/engine-signal.js").ServingLeaseView;
|
package/dist/http/server.js
CHANGED
|
@@ -26,6 +26,7 @@ import { sqlEngineSeatIssue } from "../sql-engine-posture.js";
|
|
|
26
26
|
import { parkDecisionStoreRefusal } from "../orchestration/workflow-park-decision.js";
|
|
27
27
|
import { CHECKPOINT_CTX_SEALING_REQUIRED } from "./checkpoint-ctx.js";
|
|
28
28
|
import { PARKED_REVIVE_EXECUTION_SEAT_REQUIRED } from "../parked-decide.js";
|
|
29
|
+
import { operatorDeclarationRefusal } from "../config-invariants.js";
|
|
29
30
|
import { retiredServiceDepsRefusal } from "./retired-service-deps.js";
|
|
30
31
|
import { createAdmission, MAX_SKILL_CONTENT_CHARS, MAX_SYSTEM_PROMPT_CHARS, MAX_OUTPUT_SCHEMA_CHARS, validateUserSkills } from "./admission.js";
|
|
31
32
|
import { createResumeLegs } from "./resume-legs.js";
|
|
@@ -76,6 +77,12 @@ export function createHttpServer(rawDeps) {
|
|
|
76
77
|
if (retired !== undefined)
|
|
77
78
|
throw new Error(retired);
|
|
78
79
|
}
|
|
80
|
+
{
|
|
81
|
+
const operatorDeclarationFailure = operatorDeclarationRefusal(deps.config);
|
|
82
|
+
if (operatorDeclarationFailure !== undefined) {
|
|
83
|
+
throw new Error(operatorDeclarationFailure);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
79
86
|
{
|
|
80
87
|
const issue = sqlEngineSeatIssue(deps.backend, deps.sqlEngine);
|
|
81
88
|
if (issue !== undefined) {
|
|
@@ -106,15 +113,19 @@ export function createHttpServer(rawDeps) {
|
|
|
106
113
|
const steerableRuns = new Map();
|
|
107
114
|
const wakeParkMints = new Map();
|
|
108
115
|
const counters = { uncountedBillableInflight: 0, admittedInflight: 0 };
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
const inflightBreakdown = () => {
|
|
117
|
+
const resident = deps.sessionResidentBackground?.() ?? { backgroundAgents: 0, sessionResident: 0 };
|
|
118
|
+
return {
|
|
119
|
+
http: liveRunIdsOf(inflightRuns, steerableRuns).size + counters.uncountedBillableInflight + counters.admittedInflight,
|
|
120
|
+
leader: deps.leaderEndpoint?.inflight?.() ?? 0,
|
|
121
|
+
backgroundAgents: resident.backgroundAgents,
|
|
122
|
+
sessionResident: resident.sessionResident,
|
|
123
|
+
};
|
|
124
|
+
};
|
|
114
125
|
if (deps.drainState) {
|
|
115
126
|
deps.drainState.inflightBreakdown = inflightBreakdown;
|
|
116
127
|
deps.drainState.inflight = () => inflightTotal(inflightBreakdown());
|
|
117
|
-
deps.drainState.blockingInflight = () => blockingInflightOf(
|
|
128
|
+
deps.drainState.blockingInflight = () => blockingInflightOf(inflightBreakdown());
|
|
118
129
|
}
|
|
119
130
|
let lastBillableActivityAt = performance.now();
|
|
120
131
|
let firstBillableActivityAt = null;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { PermissionMode } from "@sema-agent/core";
|
|
11
11
|
import { type Autonomy } from "../runtime-governance.js";
|
|
12
12
|
import { type ExecutionConfigRootDeployment } from "../execution-config-root.js";
|
|
13
|
+
import { type UnreadMembersDeployment } from "../unread-request-members.js";
|
|
13
14
|
import { type ModelApiKeyEnvTable } from "../server-secret-env.js";
|
|
14
15
|
import { type StoredBodyReplayRefusal } from "./checkpoint-ctx.js";
|
|
15
16
|
import type { CheckpointCtx } from "./route-ctx.js";
|
|
@@ -23,15 +24,16 @@ export declare function permissionModeReadingUnstated(ctx: CheckpointCtx, floor:
|
|
|
23
24
|
floor: PermissionMode;
|
|
24
25
|
} | undefined;
|
|
25
26
|
/**
|
|
26
|
-
* 预判读的部署配置:`autonomy`(模式词问的模式词地板)、执行车道的 home 两位(`~/` 形规则那一问)
|
|
27
|
+
* 预判读的部署配置:`autonomy`(模式词问的模式词地板)、执行车道的 home 两位(`~/` 形规则那一问)、配置根的几位(user 设置层 `/` 规则那一问)与「请求成员读不出」那一问的
|
|
28
|
+
* 租户轴 / 两只注入闸的否决位。`ServiceConfig` 结构上满足,四个问点传 `deps.config` 整份。
|
|
27
29
|
*/
|
|
28
|
-
export type StoredReplayDeployment = ExecutionConfigRootDeployment & {
|
|
30
|
+
export type StoredReplayDeployment = ExecutionConfigRootDeployment & UnreadMembersDeployment & {
|
|
29
31
|
readonly autonomy?: Autonomy | undefined;
|
|
30
32
|
/** 生效配置模型条目 name → `apiKeyEnv`(`settings.env` 凭据判据的名单一臂;缺席 = 没有模型条目,与 `serverCredentialValueSources` 的缺省同读)。 */
|
|
31
33
|
readonly modelApiKeyEnv?: ModelApiKeyEnvTable | undefined;
|
|
32
34
|
};
|
|
33
35
|
/**
|
|
34
|
-
* 四问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法(体里带非空 `allow` 而写者版本证不出 ≥ 7.117.0;常设,按写者版本)→ 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ deny / ask 的名字层 + 规则文法)→ 模式词读法记号 → 体里的退役请求键(几问同中时答先中的那一问 ——
|
|
36
|
+
* 四问一只判据:不能重放 ⇒ 返回拒的那条规则;能 ⇒ `undefined`。顺序:allow 读法(体里带非空 `allow` 而写者版本证不出 ≥ 7.117.0;常设,按写者版本)→ 请求设置里的条目表(**与拒点同序**:桶门〔形 / 空串 / 超帽〕→ 工具名清单读成空〔**只问限制方向**:放行方向的存量条目读成空,续跑照旧、只留一行运维 warn〕→ 请求成员读不出〔hooks / env / MCP transport / A2A headers …,判据 `unread-request-members.ts`〕→ deny / ask 的名字层 + 规则文法)→ 模式词读法记号 → 体里的退役请求键(几问同中时答先中的那一问 ——
|
|
35
37
|
* 任一问中都不重放,句子只需一句)。`deployment` = 本部署**此刻**的 `config`(活 config:热改即生效):`autonomy` 的地板由它的唯一属主算,`~/` 形规则的 home 由 `executionLaneHomeDir` 算,问点都不自己算。
|
|
36
38
|
*/
|
|
37
39
|
export declare function storedBodyReplayRefusal(ctx: CheckpointCtx, deployment: StoredReplayDeployment): StoredBodyReplayRefusal | undefined;
|
|
@@ -7,6 +7,8 @@ import { executionLaneHomeDir } from "../execution-lane-caps.js";
|
|
|
7
7
|
import { executionConfigRootOf } from "../execution-config-root.js";
|
|
8
8
|
import { migrationWindowEnd } from "../plugins/one-time-migrations.js";
|
|
9
9
|
import { storedEnvCredentialsDropM38 } from "../stored-request-env-credentials-m38.js";
|
|
10
|
+
import { storedToolAxesRereadM19 } from "../stored-request-tool-axes-m19.js";
|
|
11
|
+
import { MAX_NAMED_MEMBERS, unreadRequestMembers, unreadRequestMembersRefusal } from "../unread-request-members.js";
|
|
10
12
|
import { serverCredentialValueSources } from "../server-secret-env.js";
|
|
11
13
|
import { allowListWriterUnproven, permissionModeReadingStated, retiredRequestKeyOf } from "./checkpoint-ctx.js";
|
|
12
14
|
export function permissionModeReadingUnstated(ctx, floor) {
|
|
@@ -75,7 +77,14 @@ export function storedBodyReplayRefusal(ctx, deployment) {
|
|
|
75
77
|
const envCredential = storedEnvCredentialRefusal(ctx.body, deployment);
|
|
76
78
|
if (envCredential !== undefined)
|
|
77
79
|
return { kind: "settings_env_credential", refusal: envCredential };
|
|
78
|
-
const
|
|
80
|
+
const inert = inertToolListEntryOf(ctx.body, ["deny"]);
|
|
81
|
+
if (inert !== undefined)
|
|
82
|
+
return { kind: "inert_tool_list", entry: inert };
|
|
83
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
84
|
+
const unread = unreadRequestMembers({ settings: ctx.body.settings, mcpServers: ctx.body.mcpServers, a2aPeers: ctx.body.a2aPeers }, deployment, { replay: true, today, storedToolAxes: storedToolAxesRereadM19(today) });
|
|
85
|
+
if (unread.length > 0)
|
|
86
|
+
return { kind: "unread_members", refusal: unreadRequestMembersRefusal(unread), members: unread.slice(0, MAX_NAMED_MEMBERS), memberCount: unread.length };
|
|
87
|
+
const entry = storedRulePolicyRefusal(ctx.body, deployment);
|
|
79
88
|
if (entry !== undefined)
|
|
80
89
|
return { kind: "inert_tool_list", entry };
|
|
81
90
|
const mode = permissionModeReadingUnstated(ctx, autonomyModeFloor(deployment.autonomy));
|
|
@@ -46,7 +46,8 @@ export interface TaskRequestBody {
|
|
|
46
46
|
* `scenario_unknown`, a known-but-not-allowed one a typed 400 `scenario_not_allowed`; absent ⇒ the ruling's
|
|
47
47
|
* assigned scenario, else `DEFAULT_SCENARIO` (consumed at `boot/resolve-spec.ts` via `gateScenarioRequest`). A name
|
|
48
48
|
* on that default chain this deployment does not have is NEVER folded to `default`: an assigned one is a typed 503
|
|
49
|
-
* `state.scenario_assignment_unknown`, a dangling `DEFAULT_SCENARIO` refuses to boot.
|
|
49
|
+
* `state.scenario_assignment_unknown`, a dangling `DEFAULT_SCENARIO` refuses to boot. On a center-wired deployment whose
|
|
50
|
+
* center cannot answer for this principal, named or absent alike is a typed 503 `state.scenario_assignment_unavailable`.
|
|
50
51
|
* ⚠️ scenario-SPECIFIC keys (`repo`/`lenses`/`rounds`, read through `ScenarioRequest`'s index signature) are
|
|
51
52
|
* deliberately NOT declared here — they belong to one scenario each, not to the shared submit surface. */
|
|
52
53
|
scenario?: string;
|
|
@@ -189,10 +190,12 @@ export interface TaskRequestBody {
|
|
|
189
190
|
* 400 (fail-loud, never silently dropped — the body.model silent-drop bug class). Absent ⇒ core uses the resolved
|
|
190
191
|
* role's default thinking. NEVER `budgetTokens`/`fast_mode` (provider-neutral by omission). */
|
|
191
192
|
reasoningEffort?: string;
|
|
192
|
-
/** Resume-at (shell-host contract E18): the
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
193
|
+
/** Resume-at (shell-host contract E18): the history-anchor handle of the prior message to rewind the conversation to
|
|
194
|
+
* (a message's E2 `eventId`, or a prompt's `taskId` — the anchor map holds both) — core branches the session at
|
|
195
|
+
* that message before running the new objective ("rewind to this message, ask differently"). The service resolves
|
|
196
|
+
* handle → the persisted SessionTreeEntry.id through the ONE anchor reader (`history-anchor.ts`) in resolveSpec; an
|
|
197
|
+
* unknown handle is a 404 `resume_at.unknown_event` (never silently dropped). Requires a session. Absent ⇒ continue
|
|
198
|
+
* from the current leaf. */
|
|
196
199
|
resumeAt?: string;
|
|
197
200
|
/** [ref] rewind exclusive mode (core 1.292 `TaskSpec.resumeAtMode`): qualifies the `resumeAt` target. `"at"`
|
|
198
201
|
* (default when absent — zero regression) keeps the target message in the branched context; `"before"` branches at
|
|
@@ -224,12 +227,18 @@ export interface TaskRequestBody {
|
|
|
224
227
|
* either way. Requires a FileHistoryStore. */
|
|
225
228
|
restoreFiles?: boolean;
|
|
226
229
|
/** DV-15: opt-in tolerance for a PARTIAL file restore (default = loud terminal failure carrying the per-file
|
|
227
|
-
* ledger; `true` = keep going and disclose the same ledger on the result's rewindNotes).
|
|
230
|
+
* ledger; `true` = keep going and disclose the same ledger on the result's rewindNotes). A RUN-seat policy only
|
|
231
|
+
* ("may the agent keep working on a mixed tree"): the out-of-run `POST /v1/sessions/:id/rewind-files` has no such
|
|
232
|
+
* key — the engine's out-of-run rewind has no partial policy and that route answers the ledger as it stands. */
|
|
228
233
|
acceptPartialRestore?: boolean;
|
|
229
234
|
/** R8 code-only rewind (CC "Restore code" mode): converge the TRACKED set to the history boundary at a prior
|
|
230
|
-
* USER message WITHOUT forking the conversation (the session leaf is untouched — only the files move). The
|
|
231
|
-
*
|
|
232
|
-
*
|
|
235
|
+
* USER message WITHOUT forking the conversation (the session leaf is untouched — only the files move). The value is
|
|
236
|
+
* a history-anchor handle, NOT a SessionTreeEntry.id: the prompt's `taskId` (`messages[].taskId` on the session view;
|
|
237
|
+
* the same handle space `resumeAt` reads) — the service resolves it → the entry id through the one anchor reader
|
|
238
|
+
* (unknown ⇒ 404 `rewind_files_to.unknown_event`). Honored ONLY when `resumeAt` is ABSENT (the two modes are mutually
|
|
239
|
+
* exclusive). Requires the anchor map + a FileHistoryStore + the session store's head read (capability
|
|
240
|
+
* `rewindFilesTo`). Its out-of-run twin — no run, no model call — is `POST /v1/sessions/:id/rewind-files` with the same
|
|
241
|
+
* handle in `to` (capability `sessionRewindFiles`). */
|
|
233
242
|
rewindFilesTo?: string;
|
|
234
243
|
/** [ref](core 7.31.0 [ref] `TaskSpec.fileHistory`)—— 请求级的**文件历史关断词**,唯一词 `"disabled"`(core 的拼法,
|
|
235
244
|
* 与 `checkpointStore` 同;没有 `"enabled"` —— 缺席就是「部署说了算」的唯一形,声明只能单向收紧)。`"disabled"` ⇒
|
|
@@ -457,7 +466,7 @@ export interface TaskRequestBody {
|
|
|
457
466
|
* · `"scrub"` —— 缺省清洗(剥凭据形变量),**任何车道、任何部署**都受理(它就是缺省;7.106.0 合并复审 X7)。
|
|
458
467
|
* **缺席 = 缺省清洗**:不带键的请求把本会话的绑定清掉(不继承上一条请求的声明 —— 这一位是「本条请求要什么」,
|
|
459
468
|
* 粘到下一条上就是替一个没说话的请求放宽)。名单形(`string[]`)**不上 wire**(那是嵌入方构造执行环境的选项)。
|
|
460
|
-
* 🔒 **只有 host 车道有消费点**:别的车道(e2b / k8s / local-docker / ssh / adb / device /
|
|
469
|
+
* 🔒 **只有 host 车道有消费点**:别的车道(e2b / k8s / local-docker / ssh / adb / device / none)带 `"all"` ⇒
|
|
461
470
|
* 400 `request.field_invalid`(`reason: lane_not_host`)「applies to the host lane only」,不静默忽略、不映射到别的车道的 env 名单;`"scrub"` 在那些车道上照受理(无消费点,无害)。
|
|
462
471
|
* Rides the persisted body onto resume legs:重放照射程与车道重判(部署由单用户改托管后 revive ⇒ 同一只拒,
|
|
463
472
|
* resume-legs 折成 `409 resume_blocked_by_policy`)。
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { loadConfig, type ServiceConfig } from "./config.js";
|
|
2
|
-
export { composeExecutionLane, assertExecutionLaneInvariants, type ExecutionLaneComposeCtx } from "./boot/execution-lane.js";
|
|
2
|
+
export { composeExecutionLane, assertExecutionLaneInvariants, HTTP_SERVICE_LANE_ENTRY, type ExecutionLaneComposeCtx, type ExecutionLaneEntry } from "./boot/execution-lane.js";
|
|
3
3
|
export { createBrain } from "./brain.js";
|
|
4
4
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
5
5
|
export { createStoreBackend, type StoreBackend, type SessionCaptureRecordSource } from "./plugins/store-backend.js";
|
|
6
6
|
export { RetiredSchemaPresentError } from "./plugins/schema-consistency.js";
|
|
7
|
-
export { LocalDataRootSchemaMismatchError, type
|
|
7
|
+
export { LocalDataRootSchemaMismatchError, type LocalDataRootMismatch } from "./plugins/local-session-store.js";
|
|
8
8
|
export { CachingSessionStore, type CachingOptions } from "./plugins/caching-session-store.js";
|
|
9
9
|
export type { RunRecord, RunEvent } from "./plugins/store-contracts.js";
|
|
10
10
|
export { runInBackground } from "./runs.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { loadConfig } from "./config.js";
|
|
2
|
-
export { composeExecutionLane, assertExecutionLaneInvariants } from "./boot/execution-lane.js";
|
|
2
|
+
export { composeExecutionLane, assertExecutionLaneInvariants, HTTP_SERVICE_LANE_ENTRY } from "./boot/execution-lane.js";
|
|
3
3
|
export { createBrain } from "./brain.js";
|
|
4
4
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
5
5
|
export { createStoreBackend } from "./plugins/store-backend.js";
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* ## 基线 = 会话的服务端元数据
|
|
12
12
|
* 基线是「同一 session 上一次 run 选中的链成员相对路径」(不是指纹:指纹密钥每进程随机,跨进程不可比)。它住在会话店的
|
|
13
|
-
* 服务端元数据面 —— SQL 两孪生是 `
|
|
13
|
+
* 服务端元数据面 —— SQL 两孪生是 `session_ext.instruction_source` 一列,local 文件店是一只 sidecar —— 所以重启 /
|
|
14
14
|
* 跨副本都读得到、随会话删除一起消失,且不进模型上下文、不进 wire 会话面。不接这张面的店(core 的内存 dev 店、
|
|
15
15
|
* `run-local` 的 core 文件店)⇒ 席缺席 ⇒ 一帧不发(诚实缺席:那两形的会话本来就活不过进程,或没有会话流可投)。
|
|
16
16
|
*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory-embedder-reembed.ts` —— 「清列重嵌」**确认口令**的单一属主:`MEMORY_EMBEDDER_REEMBED=<model>/<dimensions>`。
|
|
3
|
+
*
|
|
4
|
+
* ## 律(一句)
|
|
5
|
+
*
|
|
6
|
+
* embedder 指纹门(`plugins/memory-embedder-fingerprint.ts`)从不凭自己的判断清列:记下的身份与配置的身份对不上
|
|
7
|
+
* (changed / unattributed / unreadable 三态)⇒ 拒启;唯一出路是运维显式确认「把向量列清掉、按**这个**身份重嵌」——
|
|
8
|
+
* 口令的值就是**配置的那个身份**。口令绑定身份,所以它天然是一次性的:清完并记下这个身份之后,下一次起服判「相等」,
|
|
9
|
+
* 口令不再有东西可确认;之后再换一次模型,留着的旧口令对不上新配置 ⇒ 起服拒(不会替下一次换模型静默清列)。
|
|
10
|
+
*
|
|
11
|
+
* ## 为什么是一只顶层叶模块
|
|
12
|
+
*
|
|
13
|
+
* 两个消费方在不同层:`config.ts` 在 boot 期解析并判口令(拼错 / 对不上配置 ⇒ 拒启),指纹门在拒句里**写出**这条口令。
|
|
14
|
+
* config 层不得值引 plugins 层;口令的读写形只有一份,两层各按需引 —— 这是本文件存在的全部理由。零依赖。
|
|
15
|
+
*
|
|
16
|
+
* 句子里写给运维**照抄**的那条赋值只有一个写者 {@link formatReembedAssignment}:值按 POSIX 单引号包起(模型名可以含空格 / `$` / 引号,
|
|
17
|
+
* 不包就粘不进 shell);引号只是 shell 的写法,shell 读完赋给 env 的值仍是 `<model>/<dimensions>` 本身(config 读的就是它)。
|
|
18
|
+
*/
|
|
19
|
+
/** 口令那一键的名字(config 读它、门的拒句写它)。 */
|
|
20
|
+
export declare const MEMORY_EMBEDDER_REEMBED_ENV = "MEMORY_EMBEDDER_REEMBED";
|
|
21
|
+
/** 口令所确认的身份形(与指纹门的 `EmbedderIdentity` 同形;本叶不引 zod)。 */
|
|
22
|
+
export interface EmbedderIdentityToken {
|
|
23
|
+
readonly model: string;
|
|
24
|
+
readonly dimensions: number;
|
|
25
|
+
}
|
|
26
|
+
/** 身份 → 口令值:`<model>/<dimensions>`。模型名自身可以含 `/`(`BAAI/bge-m3`)—— 维度恒在**最后一个** `/` 之后。 */
|
|
27
|
+
export declare function formatEmbedderIdentityToken(identity: EmbedderIdentityToken): string;
|
|
28
|
+
/**
|
|
29
|
+
* 运维照抄的那条赋值:`MEMORY_EMBEDDER_REEMBED='<model>/<dimensions>'`。POSIX 单引号:值内唯一的元字符是 `'` 本身,写成 `'\''`
|
|
30
|
+
* (关引号、转义一个 `'`、再开引号)。拒句与 config 的出路句都经这里写,不各拼一份。
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatReembedAssignment(identity: EmbedderIdentityToken): string;
|
|
33
|
+
/**
|
|
34
|
+
* 口令值 → 身份;形不对 ⇒ `undefined`(调用方拒启并给出期望形,不猜)。判据:最后一个 `/` 之前非空(模型名),
|
|
35
|
+
* 之后是十进制正整数(无前导零、无符号、无空白)。`true` / `1` / `yes` 这类「开关形」一律不是口令。
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseEmbedderIdentityToken(raw: string): EmbedderIdentityToken | undefined;
|
|
38
|
+
//# sourceMappingURL=memory-embedder-reembed.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const MEMORY_EMBEDDER_REEMBED_ENV = "MEMORY_EMBEDDER_REEMBED";
|
|
2
|
+
export function formatEmbedderIdentityToken(identity) {
|
|
3
|
+
return `${identity.model}/${identity.dimensions}`;
|
|
4
|
+
}
|
|
5
|
+
export function formatReembedAssignment(identity) {
|
|
6
|
+
return `${MEMORY_EMBEDDER_REEMBED_ENV}='${formatEmbedderIdentityToken(identity).replace(/'/g, "'\\''")}'`;
|
|
7
|
+
}
|
|
8
|
+
export function parseEmbedderIdentityToken(raw) {
|
|
9
|
+
const cut = raw.lastIndexOf("/");
|
|
10
|
+
if (cut <= 0)
|
|
11
|
+
return undefined;
|
|
12
|
+
const digits = raw.slice(cut + 1);
|
|
13
|
+
if (!/^[1-9][0-9]*$/.test(digits))
|
|
14
|
+
return undefined;
|
|
15
|
+
const dimensions = Number(digits);
|
|
16
|
+
if (!Number.isSafeInteger(dimensions))
|
|
17
|
+
return undefined;
|
|
18
|
+
return { model: raw.slice(0, cut), dimensions };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=memory-embedder-reembed.js.map
|
|
@@ -1,31 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 记忆引擎 **incident 席**在本仓的唯一落点形。
|
|
3
|
-
*
|
|
4
|
-
* ## 为什么要一只共用工厂(而不是每个宿主各写一行 `logger.warn`)
|
|
5
|
-
* core 的记忆引擎有**两条**到宿主的披露路:
|
|
6
|
-
* · **mount 路**——`MemoryEngine` 自己的 `onIncident`,由 core 的 Runner 在 `prepare-memory` 里桥到
|
|
7
|
-
* `RunnerDeps.onError(err, { phase: "memory", sessionId })`(亲读 `dist/core/runner/prepare-memory.js`
|
|
8
|
-
* 的 `const onEngineIncident = (err) => deps.onError?.(err, { phase: "memory", sessionId })`);
|
|
9
|
-
* · **无锁公开面路**——`FileMemoryEngineBackend` 的**构造期** `onIncident`,是那条腿上唯一的披露口
|
|
10
|
-
* (`adoptLayoutLocked` 取 `onIncident ?? this.onIncident`)。
|
|
11
|
-
* 同一条事实(例如一次性的目录布局搬家)会按调用路径落到其中**一条**,而本仓有**两个宿主**
|
|
12
|
-
* (HTTP 服务的 `boot/runner-deps.ts` 与 `run-local.ts`)各自持有 `onError` 座。四个落点各写一行 =
|
|
13
|
-
* 四份会各自漂移的形;实际已经漂过一次:服务腿把整族印成 `memory_consolidation_failed`(只有一支是
|
|
14
|
-
* consolidation),run-local 腿把整族印成 `engine_error` 并用 `String(err)` 抹掉 `err.code`。
|
|
15
|
-
*
|
|
16
|
-
* ## 形(一处定义,四处引用)
|
|
17
|
-
* `memory_engine_incident` + `{ sessionId?, code?, detail }`,并计 `memory_engine_incident_total{code?}`。
|
|
18
|
-
* 🔴 `code` 是**结构化字段**而不是被折进散文:它是运维唯一能按名告警的那一位,而这一族里最要紧的几条
|
|
19
|
-
* (一次性布局搬家、无主根内容、控制面写失败)一辈子只发生一次 —— 折平就等于没说。
|
|
20
|
-
* 码的读法与 `boot/runner-deps.ts` 的 `onError` 汇点其余七条行**同一只**(`terminal.ts` 的 `codeFieldOf`:不抛的读口 + 码判官 `isCodeToken`):是码才带;
|
|
21
|
-
* 无码(core 里有大量不带 `.code` 的记忆相 Error)、不是串 / 空串、非 `Error` 抛出物、读取时抛、或带的不是码(超长 / 含空白 / 凭据形 —— 引擎错上的 `code` 是别人写的串)⇒ 行里**没有** `code` 键、
|
|
22
|
-
* 计数**没有** `code` 标签:不编码,也不写 `null` / `"none"` 之类的占位。
|
|
23
|
-
*
|
|
24
|
-
* ⚠️ 与三只 **operator 面**引擎座(`memory_compliance_incident` / `memory_origin_incident` /
|
|
25
|
-
* `memory_consolidation_incident`)**事件名刻意不合并**:那三条的事件名回答「哪一张操作面」,是三个产品面的
|
|
26
|
-
* 分辨位;本工厂回答「引擎事故席」,是同一件事的四个落点。合并会丢掉前者的分辨位。三座有自己的工厂
|
|
27
|
-
* {@link createOperatorFaceIncidentSink}(事件名由装配处点名),`code` 位与本工厂读同一只 `codeFieldOf`。
|
|
28
|
-
*/
|
|
29
1
|
import type { Logger } from "./observability/logger.js";
|
|
30
2
|
import type { Metrics } from "./observability/metrics.js";
|
|
31
3
|
/** 落点依赖。`metrics` 可缺席(run-local 的 backend 构造期座就没有计数面的消费者)。 */
|