@sema-agent/server 7.149.0 → 7.151.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 +307 -9
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +92 -40
- package/deploy/sema-up/README.md +7 -1
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
- package/deploy/sema-up/chart/templates/server.yaml +5 -3
- package/deploy/sema-up/chart/values-full-single.yaml +3 -1
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +1 -0
- package/deploy/sema-up/kube-up.sh +1 -1
- package/deploy/sema-up/lib/flagshape.sh +1 -1
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-machine.d.ts +1 -1
- package/dist/approval-card.d.ts +3 -3
- package/dist/approval-gate-currency.d.ts +2 -2
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +2 -2
- package/dist/auth-bridge.d.ts +20 -0
- package/dist/auth-bridge.js +9 -0
- package/dist/background-session-reap.d.ts +2 -2
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +2 -3
- package/dist/bind-host.js +2 -4
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -2
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +8 -14
- package/dist/boot/execution-env.js +54 -17
- package/dist/boot/execution-lane.js +32 -5
- package/dist/boot/late-binds.d.ts +8 -4
- package/dist/boot/late-binds.js +7 -1
- package/dist/boot/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/parked-revive-gate.d.ts +5 -5
- package/dist/boot/parked-revive-gate.js +2 -3
- package/dist/boot/reapers.d.ts +5 -0
- package/dist/boot/reapers.js +12 -1
- package/dist/boot/resolve-spec.d.ts +7 -8
- package/dist/boot/resolve-spec.js +80 -35
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.d.ts +9 -2
- package/dist/boot/runner-deps.js +3 -3
- package/dist/boot/session-age-out.d.ts +36 -0
- package/dist/boot/session-age-out.js +101 -0
- package/dist/boot/session-faces.d.ts +5 -14
- package/dist/boot/session-faces.js +28 -24
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +7 -4
- package/dist/boot/stage-06-runners.js +16 -8
- package/dist/boot/stage-07-capability-layer.d.ts +7 -4
- package/dist/boot/stage-07-capability-layer.js +3 -2
- package/dist/boot/stage-08-reapers.d.ts +7 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +11 -5
- package/dist/boot/stage-09-leader.js +12 -3
- package/dist/boot/stage-10-http-server.d.ts +44 -6
- package/dist/boot/stage-10-http-server.js +12 -10
- package/dist/boot/web-admin.d.ts +1 -1
- package/dist/boot/web-admin.js +3 -1
- package/dist/boot/workflow-orchestration.d.ts +7 -2
- package/dist/boot/workflow-orchestration.js +24 -7
- package/dist/bounded-rotation.d.ts +29 -0
- package/dist/bounded-rotation.js +24 -0
- package/dist/capability-facts.d.ts +84 -66
- package/dist/capability-facts.js +58 -41
- package/dist/center-credential.d.ts +25 -6
- package/dist/center-credential.js +25 -5
- package/dist/config-catalog.d.ts +26 -7
- package/dist/config-catalog.js +15 -12
- package/dist/config-invariants.d.ts +2 -1
- package/dist/config-invariants.js +4 -4
- package/dist/config-types.d.ts +22 -15
- package/dist/config.d.ts +51 -2
- package/dist/config.js +35 -24
- package/dist/deployment-governance.d.ts +7 -28
- package/dist/deployment-governance.js +1 -14
- package/dist/deployment-shape.d.ts +9 -1
- package/dist/deployment-shape.js +2 -1
- package/dist/device-protocol.d.ts +5 -4
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.d.ts +1 -0
- package/dist/device-ws-hub.js +66 -29
- package/dist/device-ws-protocol.d.ts +79 -12
- package/dist/device-ws-protocol.js +64 -26
- package/dist/engine-identity.d.ts +23 -5
- package/dist/engine-identity.js +13 -0
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/execution-env-refusal.d.ts +23 -0
- package/dist/execution-env-refusal.js +5 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +3 -3
- package/dist/file-history-capture.d.ts +11 -4
- package/dist/file-history-capture.js +9 -6
- package/dist/file-history-disclosure.d.ts +7 -5
- package/dist/file-history-disclosure.js +7 -5
- package/dist/fleet/drain-entry.d.ts +4 -0
- package/dist/fleet/engine-signal.d.ts +14 -1
- package/dist/fleet/engine-signal.js +5 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/serving-lease.d.ts +18 -3
- package/dist/fleet/serving-lease.js +81 -35
- package/dist/fleet-client.d.ts +13 -11
- package/dist/fleet-client.js +53 -33
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +1 -3
- package/dist/hitl-delivery.js +1 -1
- package/dist/hooks/hook-runner.js +2 -2
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/active-run-conflict.d.ts +3 -7
- package/dist/http/active-run-conflict.js +2 -2
- package/dist/http/admission.js +19 -4
- package/dist/http/approval-sweeps.js +7 -6
- package/dist/http/caller-trust.d.ts +2 -2
- package/dist/http/caller-trust.js +3 -3
- package/dist/http/checkpoint-ctx.d.ts +20 -63
- package/dist/http/checkpoint-ctx.js +2 -24
- package/dist/http/claim-heartbeat.d.ts +4 -4
- package/dist/http/claim-heartbeat.js +3 -3
- package/dist/http/dispatch.d.ts +2 -1
- package/dist/http/dispatch.js +36 -29
- package/dist/http/durable-run-leg.js +17 -17
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +2 -0
- package/dist/http/owner-access.d.ts +264 -20
- package/dist/http/owner-access.js +215 -5
- package/dist/http/readiness.d.ts +4 -2
- package/dist/http/resume-ctx-read.js +38 -1
- package/dist/http/resume-legs.d.ts +2 -1
- package/dist/http/resume-legs.js +273 -89
- package/dist/http/route-ctx.d.ts +41 -19
- package/dist/http/route-table.d.ts +1 -1
- package/dist/http/routes/a2a-serve.js +15 -14
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +3 -2
- package/dist/http/routes/approvals-assistant.js +12 -12
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.js +10 -6
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/mcp-reconnect.js +2 -2
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -3
- package/dist/http/routes/projects.d.ts +4 -2
- package/dist/http/routes/projects.js +7 -6
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +1 -1
- package/dist/http/routes/runs.js +125 -66
- package/dist/http/routes/session-memory-sync.js +4 -5
- package/dist/http/routes/session-sync.d.ts +4 -3
- package/dist/http/routes/session-sync.js +174 -83
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +26 -48
- package/dist/http/routes/tasks.js +38 -23
- package/dist/http/routes/trace-usage.js +14 -14
- package/dist/http/routes/workflows.d.ts +1 -0
- package/dist/http/routes/workflows.js +20 -38
- package/dist/http/server.d.ts +28 -30
- package/dist/http/server.js +7 -3
- package/dist/http/stored-body-replay.d.ts +3 -24
- package/dist/http/stored-body-replay.js +2 -12
- package/dist/http/submit-ctx.d.ts +1 -2
- package/dist/http/submit-ctx.js +8 -6
- package/dist/http/submit-replay.d.ts +15 -2
- package/dist/http/submit-replay.js +10 -4
- package/dist/http/wire-types.d.ts +19 -6
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +0 -1
- package/dist/leader/endpoint.js +9 -8
- package/dist/leader/leader.d.ts +2 -1
- package/dist/leg-facts.d.ts +19 -5
- package/dist/leg-facts.js +3 -1
- package/dist/mcp-authorization-face.d.ts +18 -14
- package/dist/mcp-authorization-face.js +3 -2
- package/dist/memory-scope.d.ts +5 -4
- package/dist/memory-scope.js +4 -4
- package/dist/memory-store-refusal.d.ts +1 -1
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/observability/corrupt-read-seat.d.ts +1 -1
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +12 -8
- package/dist/observability/fail-open.js +12 -8
- package/dist/observability/logger.d.ts +7 -0
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
- package/dist/orchestration/workflow-notify-journal.js +12 -1
- package/dist/orchestration/workflow-park-decision.d.ts +70 -18
- package/dist/orchestration/workflow-park-decision.js +49 -10
- package/dist/orchestration/workflow-park-holder.d.ts +65 -0
- package/dist/orchestration/workflow-park-holder.js +98 -0
- package/dist/orchestration/workflow-record-fence.d.ts +36 -0
- package/dist/orchestration/workflow-record-fence.js +42 -0
- package/dist/owner-faces.d.ts +28 -4
- package/dist/owner-faces.js +2 -0
- package/dist/parked-decide.d.ts +104 -53
- package/dist/parked-decide.js +153 -117
- package/dist/peer-directory.d.ts +2 -2
- package/dist/peer-inbound-face.d.ts +2 -6
- package/dist/peer-inbound-face.js +0 -3
- package/dist/peer-seat.d.ts +1 -1
- package/dist/peer-seat.js +52 -59
- package/dist/permission-mode-admission.d.ts +41 -5
- package/dist/permission-mode-admission.js +29 -3
- package/dist/plugins/adoption-log-sql.d.ts +3 -1
- package/dist/plugins/adoption-log-sql.js +7 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +8 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
- package/dist/plugins/approval-ask-store-memory.js +28 -9
- package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
- package/dist/plugins/approval-ask-store-sql.js +34 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- package/dist/plugins/breaker-state-sql.js +2 -0
- package/dist/plugins/caching-session-store.d.ts +9 -15
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/device-store-sql.js +6 -0
- package/dist/plugins/error-origin.d.ts +18 -0
- package/dist/plugins/error-origin.js +10 -0
- package/dist/plugins/exec-path-law.d.ts +34 -0
- package/dist/plugins/exec-path-law.js +13 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/image-bake-store-sql.js +6 -0
- package/dist/plugins/image-index-sql.js +4 -0
- package/dist/plugins/landed-attendants.d.ts +212 -0
- package/dist/plugins/landed-attendants.js +161 -0
- package/dist/plugins/leader-run-store-sql.js +4 -0
- package/dist/plugins/local-checkpoint-store.d.ts +4 -1
- package/dist/plugins/local-checkpoint-store.js +3 -0
- package/dist/plugins/local-session-live-reference.d.ts +40 -0
- package/dist/plugins/local-session-live-reference.js +39 -0
- package/dist/plugins/local-session-store.d.ts +71 -33
- package/dist/plugins/local-session-store.js +129 -27
- package/dist/plugins/memory-engine-pg.js +4 -0
- package/dist/plugins/memory-engine-sql-apply.js +5 -2
- package/dist/plugins/memory-engine-tidb.js +4 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/memory-sync-store-pg.js +5 -0
- package/dist/plugins/memory-sync-store-tidb.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +80 -61
- package/dist/plugins/one-time-migrations.js +241 -104
- package/dist/plugins/org-delivery-quota-store.js +4 -1
- package/dist/plugins/outcome-ledger-sql.js +2 -0
- package/dist/plugins/permission-rule-store-sql.js +11 -4
- package/dist/plugins/pg-cost-quota.js +4 -0
- package/dist/plugins/pg-pool.js +28 -1
- package/dist/plugins/pg-rate-limiter.js +2 -0
- package/dist/plugins/posix-shell-fs.d.ts +6 -1
- package/dist/plugins/posix-shell-fs.js +8 -3
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +44 -17
- package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
- package/dist/plugins/remote-env-connect-seat.js +72 -0
- package/dist/plugins/remote-env-device.d.ts +22 -5
- package/dist/plugins/remote-env-device.js +114 -14
- package/dist/plugins/remote-env-e2b.d.ts +18 -7
- package/dist/plugins/remote-env-e2b.js +53 -40
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +18 -1
- package/dist/plugins/remote-env-host.js +48 -47
- package/dist/plugins/remote-env-k8s.d.ts +41 -39
- package/dist/plugins/remote-env-k8s.js +56 -32
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +37 -43
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +64 -62
- package/dist/plugins/remote-shell.d.ts +101 -2
- package/dist/plugins/remote-shell.js +221 -3
- package/dist/plugins/replica-registration.d.ts +35 -0
- package/dist/plugins/replica-registration.js +48 -0
- package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
- package/dist/plugins/resume-anchor-store-sql.js +12 -5
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +4 -0
- package/dist/plugins/retention-sql.d.ts +20 -2
- package/dist/plugins/retention-sql.js +11 -0
- package/dist/plugins/run-store-sql.d.ts +22 -3
- package/dist/plugins/run-store-sql.js +33 -9
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
- package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
- package/dist/plugins/schema-consistency.d.ts +9 -5
- package/dist/plugins/schema-consistency.js +48 -18
- package/dist/plugins/schema-drift-sentence.js +1 -1
- package/dist/plugins/send-file-ledger.js +3 -0
- package/dist/plugins/serving-requirement.d.ts +68 -0
- package/dist/plugins/serving-requirement.js +60 -0
- package/dist/plugins/session-birth.d.ts +6 -2
- package/dist/plugins/session-capture-record-store-sql.js +2 -0
- package/dist/plugins/session-ext-table.d.ts +14 -1
- package/dist/plugins/session-ext-table.js +5 -1
- package/dist/plugins/session-row-sql.d.ts +49 -2
- package/dist/plugins/session-row-sql.js +56 -13
- package/dist/plugins/session-store-sql.d.ts +34 -18
- package/dist/plugins/session-store-sql.js +98 -17
- package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
- package/dist/plugins/shared-memory-store-sql.js +6 -2
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/sql-driver.js +18 -3
- package/dist/plugins/sql-errors.d.ts +11 -6
- package/dist/plugins/sql-errors.js +5 -6
- package/dist/plugins/stop-then-start-sentence.d.ts +48 -3
- package/dist/plugins/stop-then-start-sentence.js +48 -0
- package/dist/plugins/stop-then-start.d.ts +109 -0
- package/dist/plugins/stop-then-start.js +104 -0
- package/dist/plugins/store-backend.d.ts +40 -13
- package/dist/plugins/store-backend.js +169 -27
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +29 -2
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
- package/dist/plugins/store-fault-sentence-m53.js +25 -0
- package/dist/plugins/store-fault.d.ts +26 -7
- package/dist/plugins/store-fault.js +18 -2
- package/dist/plugins/task-attachment-store.js +9 -0
- package/dist/plugins/task-list-store-sql.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.js +10 -8
- package/dist/plugins/tidb-cost-quota.js +4 -0
- package/dist/plugins/tidb-pool.js +6 -1
- package/dist/plugins/tidb-rate-limiter.js +4 -0
- package/dist/plugins/user-input-ledger-sql.js +4 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
- package/dist/plugins/workflow-run-store-sql.js +64 -4
- package/dist/plugins/workspace-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/process-instance.d.ts +3 -0
- package/dist/process-instance.js +7 -0
- package/dist/project-context.d.ts +64 -0
- package/dist/project-context.js +66 -0
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/question.d.ts +9 -21
- package/dist/question.js +28 -19
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +4 -0
- package/dist/request-value-closure.js +10 -0
- package/dist/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-cancel-card.d.ts +1 -1
- package/dist/run-cancel-card.js +2 -1
- package/dist/run-local.js +1 -0
- package/dist/runs.d.ts +37 -8
- package/dist/runs.js +53 -12
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +31 -33
- package/dist/security.js +41 -7
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-agent.d.ts +1 -10
- package/dist/session-agent.js +0 -6
- package/dist/session-bindings.d.ts +82 -0
- package/dist/session-bindings.js +18 -0
- package/dist/session-children-retire.d.ts +2 -2
- package/dist/session-children-retire.js +2 -6
- package/dist/session-deletion.d.ts +16 -1
- package/dist/session-error-wire.d.ts +3 -3
- package/dist/session-error-wire.js +3 -3
- package/dist/session-incarnation.d.ts +28 -4
- package/dist/session-incarnation.js +14 -2
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-notify-door.d.ts +4 -4
- package/dist/session-notify-door.js +5 -6
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-rules-seat.d.ts +4 -3
- package/dist/session-rules-seat.js +3 -11
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +4 -98
- package/dist/session-sync.js +4 -74
- package/dist/session-titler.d.ts +10 -3
- package/dist/session-titler.js +19 -6
- package/dist/ssh-host-key.d.ts +5 -0
- package/dist/ssh-host-key.js +3 -0
- package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
- package/dist/stores-sql/checkpoint-store-sql.js +106 -18
- package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
- package/dist/stores-sql/file-history-store-sql.js +108 -70
- package/dist/stores-sql/pg-session-storage.d.ts +34 -7
- package/dist/stores-sql/pg-session-storage.js +37 -13
- package/dist/stores-sql/retention-store-sql.d.ts +2 -10
- package/dist/stores-sql/retention-store-sql.js +2 -10
- package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
- package/dist/stores-sql/session-policy-store-sql.js +61 -44
- package/dist/stores-sql/session-write-hooks.d.ts +11 -0
- package/dist/stores-sql/tidb-session-store.d.ts +58 -7
- package/dist/stores-sql/tidb-session-store.js +37 -13
- package/dist/submission-exit.d.ts +3 -2
- package/dist/submission-exit.js +9 -1
- package/dist/task-cwd.d.ts +6 -5
- package/dist/task-settings.d.ts +19 -5
- package/dist/task-settings.js +13 -7
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +147 -12
- package/dist/tool-approval.js +206 -109
- package/dist/trace/engine-notice-wire.d.ts +14 -0
- package/dist/trace/engine-notice-wire.js +18 -1
- package/dist/trace/project.d.ts +4 -3
- package/dist/trace/project.js +3 -2
- package/dist/trace/projection-table.d.ts +33 -2
- package/dist/trace/self-minted-wire.d.ts +422 -26
- package/dist/trace/self-minted-wire.js +149 -23
- package/dist/trace/tool-card.d.ts +3 -0
- package/dist/trace/tool-card.js +24 -0
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/unattended-permission-mode.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
- package/package.json +3 -3
- package/wire-changes/server@7.150.0.json +335 -0
- package/wire-changes/server@7.151.0.json +762 -0
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
|
@@ -14,8 +14,8 @@ import { readWritableSessionPermissionRules } from "../../session-policy-wire.js
|
|
|
14
14
|
import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
|
|
15
15
|
import { gatedPerson, gatedSubject, sendPrincipalRefusal } from "../principal-gate.js";
|
|
16
16
|
import { personOf } from "../../owner-brands.js";
|
|
17
|
-
import {
|
|
18
|
-
import { admitSessionById, admitSessionRow, admittedAsFleet, callerEntry, callerOf, deliverVerdict, enter,
|
|
17
|
+
import { leafOfAdmittedHead, sessionFaceOfHead } from "../../session-incarnation.js";
|
|
18
|
+
import { admitSessionById, admitSessionForDeletion, admitSessionRow, admitSessionView, admittedAsFleet, callerEntry, callerOf, deliverVerdict, enter, judgeSessionById, protocolEntry, readOwnerCell, readVisibleLatestRun, refuse, sessionOccupantUnchanged } from "../owner-access.js";
|
|
19
19
|
import { assertNever } from "../route-ctx.js";
|
|
20
20
|
import * as facts from "../../capability-facts.js";
|
|
21
21
|
import { rosterAgentId } from "./agents-roster.js";
|
|
@@ -67,11 +67,9 @@ async function readLastLegMcp(deps, sessionId, entry) {
|
|
|
67
67
|
const runStore = deps.runStore;
|
|
68
68
|
if (!runStore || sessionId === null)
|
|
69
69
|
return undefined;
|
|
70
|
-
const latest = await runStore
|
|
70
|
+
const latest = await readVisibleLatestRun(entry, runStore, sessionId);
|
|
71
71
|
if (latest === undefined)
|
|
72
72
|
return undefined;
|
|
73
|
-
if (!seesRun(entry, latest.owner))
|
|
74
|
-
return undefined;
|
|
75
73
|
const events = await runStore.getEvents(latest.taskId, 0);
|
|
76
74
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
77
75
|
const ev = events[i];
|
|
@@ -87,26 +85,7 @@ async function readLastLegMcp(deps, sessionId, entry) {
|
|
|
87
85
|
export async function handleSessions(req, res, match, ctx) {
|
|
88
86
|
const { deps } = ctx;
|
|
89
87
|
const { readJson, safeDecode } = ctx.helpers;
|
|
90
|
-
const readOwnedSessionView =
|
|
91
|
-
const headOf = headReadOf(deps.sessionStorage);
|
|
92
|
-
if (headOf !== undefined) {
|
|
93
|
-
const head = await readOwnerCell(entry, sessionId, () => headOf(sessionId));
|
|
94
|
-
if ((await admitSessionRow(entry, res, deps.sessionStorage, sessionId, head)) === undefined)
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
let audit;
|
|
98
|
-
try {
|
|
99
|
-
audit = await sessionAudit(sessionId, readOpts);
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
if (headOf !== undefined)
|
|
103
|
-
throw e;
|
|
104
|
-
throw new Error(`session view read failed before ownership could be established: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
105
|
-
}
|
|
106
|
-
if ((await admitSessionRow(entry, res, deps.sessionStorage, sessionId, audit)) === undefined)
|
|
107
|
-
return undefined;
|
|
108
|
-
return audit;
|
|
109
|
-
};
|
|
88
|
+
const readOwnedSessionView = (entry, sessionAudit, sessionId, readOpts) => admitSessionView(entry, res, deps.sessionStorage, sessionAudit, sessionId, readOpts);
|
|
110
89
|
const sse = ctx.local.sessions;
|
|
111
90
|
const { mcpStatusCache, a2aStatusCache } = ctx.local.sessions;
|
|
112
91
|
{
|
|
@@ -262,8 +241,8 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
262
241
|
}
|
|
263
242
|
{
|
|
264
243
|
if (match.decl.id === "session-head") {
|
|
265
|
-
const
|
|
266
|
-
if (!
|
|
244
|
+
const headFact = facts.sessionOwnership(deps);
|
|
245
|
+
if (!headFact.available) {
|
|
267
246
|
sendError(res, 501, "capability.session_store_required", "session head probe requires a durable session store (DB_BACKEND=mysql|pg|local)");
|
|
268
247
|
return;
|
|
269
248
|
}
|
|
@@ -273,8 +252,7 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
273
252
|
return;
|
|
274
253
|
}
|
|
275
254
|
const headEntry = callerEntry(req, deps, match.decl.id);
|
|
276
|
-
const
|
|
277
|
-
const admittedHead = await admitSessionRow(headEntry, res, deps.sessionStorage, headSession, headRead);
|
|
255
|
+
const admittedHead = await admitSessionById(headEntry, res, headFact.sessionStorage, headSession);
|
|
278
256
|
if (admittedHead === undefined)
|
|
279
257
|
return;
|
|
280
258
|
const leafId = leafOfAdmittedHead(admittedHead.row);
|
|
@@ -317,8 +295,6 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
317
295
|
return;
|
|
318
296
|
}
|
|
319
297
|
const evEntry = callerEntry(req, deps, match.decl.id);
|
|
320
|
-
const readHead = (id) => readOwnerCell(evEntry, id, () => evFact.sessionStorage.headOf(id));
|
|
321
|
-
const readOwner = async (id) => (await readHead(id))?.owner;
|
|
322
298
|
const watch = evFact.watch;
|
|
323
299
|
const evSession = safeDecode(match.params.sessionId);
|
|
324
300
|
if (evSession === null) {
|
|
@@ -354,7 +330,7 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
354
330
|
return;
|
|
355
331
|
}
|
|
356
332
|
sse.sseOwnerLookups++;
|
|
357
|
-
const admissionP =
|
|
333
|
+
const admissionP = judgeSessionById(evEntry, evFact.sessionStorage, evSession);
|
|
358
334
|
void admissionP.catch(() => undefined).then(() => { sse.sseOwnerLookups--; });
|
|
359
335
|
let stallTimer;
|
|
360
336
|
let admission;
|
|
@@ -381,12 +357,13 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
381
357
|
refuse(evEntry, res, "missing");
|
|
382
358
|
return;
|
|
383
359
|
}
|
|
384
|
-
|
|
360
|
+
const evAdmitted = deliverVerdict(evEntry, res, admission);
|
|
361
|
+
if (evAdmitted === undefined) {
|
|
385
362
|
cleanup();
|
|
386
363
|
return;
|
|
387
364
|
}
|
|
388
|
-
leafOfAdmittedHead(
|
|
389
|
-
const owner =
|
|
365
|
+
leafOfAdmittedHead(evAdmitted.row);
|
|
366
|
+
const owner = evAdmitted.row.owner;
|
|
390
367
|
const q = new URLSearchParams(match.search);
|
|
391
368
|
const lastLeafId = q.get("lastLeafId");
|
|
392
369
|
let first = true;
|
|
@@ -485,9 +462,9 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
485
462
|
}
|
|
486
463
|
ownerCheckPending = true;
|
|
487
464
|
ownerCheckStartedAt = Date.now();
|
|
488
|
-
void
|
|
465
|
+
void sessionOccupantUnchanged(evEntry, evFact.sessionStorage, evSession, evAdmitted.row).then((same) => {
|
|
489
466
|
ownerCheckPending = false;
|
|
490
|
-
if (!closed &&
|
|
467
|
+
if (!closed && !same)
|
|
491
468
|
onEnd();
|
|
492
469
|
}).catch(() => { ownerCheckPending = false; });
|
|
493
470
|
}, hbMs);
|
|
@@ -615,7 +592,7 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
615
592
|
sendJson(res, 200, {
|
|
616
593
|
sessionId,
|
|
617
594
|
autoConsolidationArmed: deps.memoryAutoConsolidationArmed,
|
|
618
|
-
...(deps.memorySyncLeg !== undefined ? { memorySync: { parked: deps.memorySyncLeg.parked()
|
|
595
|
+
...(deps.memorySyncLeg !== undefined ? { memorySync: { parked: deps.memorySyncLeg.parked() } } : {}),
|
|
619
596
|
...(s.captureOptedOut !== undefined ? { captureOptedOut: s.captureOptedOut } : {}),
|
|
620
597
|
...(s.committedCount !== undefined ? { committedCount: s.committedCount } : {}),
|
|
621
598
|
...(s.foldedCount !== undefined ? { foldedCount: s.foldedCount } : {}),
|
|
@@ -706,14 +683,11 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
706
683
|
const store = rowFact.sessionStorage;
|
|
707
684
|
const sessionId = match.params.sessionId;
|
|
708
685
|
const patchEntry = callerEntry(req, deps, match.decl.id);
|
|
709
|
-
const
|
|
710
|
-
if (
|
|
711
|
-
refuse(patchEntry, res, "missing");
|
|
686
|
+
const patchAdmitted = await admitSessionById(patchEntry, res, store, sessionId);
|
|
687
|
+
if (patchAdmitted === undefined)
|
|
712
688
|
return;
|
|
713
|
-
|
|
689
|
+
const head = patchAdmitted.row;
|
|
714
690
|
const face = sessionFaceOfHead(sessionId, head);
|
|
715
|
-
if ((await admitSessionRow(patchEntry, res, store, sessionId, face)) === undefined)
|
|
716
|
-
return;
|
|
717
691
|
leafOfAdmittedHead(head);
|
|
718
692
|
const read = readSessionRowPatch(await readJson(req));
|
|
719
693
|
if ("problem" in read) {
|
|
@@ -903,7 +877,7 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
903
877
|
sendError(res, 400, "request.id_invalid", "invalid session id (must be a canonical uuid)");
|
|
904
878
|
return;
|
|
905
879
|
}
|
|
906
|
-
const deleteAdmitted = await
|
|
880
|
+
const deleteAdmitted = await admitSessionForDeletion(deleteEntry, res, deleteFact.sessionStorage, sessionId);
|
|
907
881
|
if (deleteAdmitted === undefined)
|
|
908
882
|
return;
|
|
909
883
|
const owner = deleteAdmitted.row.owner;
|
|
@@ -931,7 +905,7 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
931
905
|
sendError(res, 501, "capability.session_store_required", "session policy requires a session-store backend");
|
|
932
906
|
return;
|
|
933
907
|
}
|
|
934
|
-
const store = policyFact.
|
|
908
|
+
const store = policyFact.backend.sessionPolicy();
|
|
935
909
|
const policyEntry = enter(req, res, deps, match.decl.id);
|
|
936
910
|
if (policyEntry === undefined)
|
|
937
911
|
return;
|
|
@@ -973,8 +947,12 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
973
947
|
}
|
|
974
948
|
const rules = read.rules;
|
|
975
949
|
try {
|
|
976
|
-
const stored = await
|
|
977
|
-
|
|
950
|
+
const stored = await policyFact.backend.landedAttendants().putPolicy(sessionId, sessionFaceOfHead(sessionId, policyAdmitted.row), target, rules, { ...(typeof body.expectedRev === "number" ? { expectedRev: body.expectedRev } : {}), operator });
|
|
951
|
+
if (!stored.landed) {
|
|
952
|
+
refuse(policyEntry, res, "missing");
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
sendJson(res, 200, { rules: stored.value });
|
|
978
956
|
}
|
|
979
957
|
catch (e) {
|
|
980
958
|
if (sendSessionPolicyError(res, e))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { redactErrorMessage, redactHead, redactTerminalResult } from "../../observability/run-terminal.js";
|
|
2
2
|
import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
|
|
3
3
|
import { heldFor } from "../../peer-seat.js";
|
|
4
|
-
import { beatRunHeartbeat, graftParkToolCallId, heldParkOf, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, settleResumeAnchor, TurnAnchorCapture, HEARTBEAT_MS } from "../../runs.js";
|
|
4
|
+
import { beatRunHeartbeat, createRunAnchorWriter, graftParkToolCallId, heldParkOf, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, settleResumeAnchor, TurnAnchorCapture, HEARTBEAT_MS } from "../../runs.js";
|
|
5
5
|
import { commitParkRow } from "../../park-row-commit.js";
|
|
6
6
|
import { atHostBoundary, failureCodeOf, sealResultForExit, outwardPlane } from "../../terminal.js";
|
|
7
7
|
import { voidVerifierPauseCard } from "../../verifier-pause-card.js";
|
|
@@ -21,7 +21,8 @@ import { writeLiveFrame, writeLiveHeartbeat } from "../live-frame.js";
|
|
|
21
21
|
import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat, identityFields } from "../../trace/project.js";
|
|
22
22
|
import { cascadeConfig, fillRunPreviewOnDelivery, runMeta } from "../run-meta.js";
|
|
23
23
|
import { idemCallerOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
|
|
24
|
-
import { isReplayedOutcome, replayedOutcome, replayOfExistingRun } from "../submit-replay.js";
|
|
24
|
+
import { answerReplay, isReplayedOutcome, replayedOutcome, replayOfExistingRun } from "../submit-replay.js";
|
|
25
|
+
import { readReplayHit, runFactsOf, sessionOccupantReadOf } from "../owner-access.js";
|
|
25
26
|
import { httpErrorCode, sendJson, sseHeaders } from "../send.js";
|
|
26
27
|
import { collectSsePreamble } from "../sse-log.js";
|
|
27
28
|
import { buildApprovalPreamble } from "../../approval-card.js";
|
|
@@ -32,7 +33,7 @@ import { SUBMISSION_CLAIM_FACE, commitExecutionContext, faultedAnswerOf } from "
|
|
|
32
33
|
import { rootSessionAbsentAnswer } from "../execution-context.js";
|
|
33
34
|
import { recheckClaimBeforeLaunch, startClaimHeartbeat } from "../claim-heartbeat.js";
|
|
34
35
|
import { timeClaim } from "../claim-latency.js";
|
|
35
|
-
import {
|
|
36
|
+
import { commitLegBindings } from "../../session-bindings.js";
|
|
36
37
|
import { headerStr, gatedPerson, gatedSubject, explicitOperatorOk, runIdentityOf } from "../principal-gate.js";
|
|
37
38
|
import { recoveredSubject } from "../../owner-faces.js";
|
|
38
39
|
import { recordFailOpen } from "../../observability/fail-open.js";
|
|
@@ -109,12 +110,12 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
109
110
|
const idem = rawIdem ? submissionIdemOf(rawIdem, idemCallerOf(req, ctx), keyedBody) : undefined;
|
|
110
111
|
const inflightKey = idem ? inflightKeyOf(idem, "sync") : undefined;
|
|
111
112
|
const cached = inflightKey ? idemCache.peek(inflightKey) : undefined;
|
|
112
|
-
const
|
|
113
|
-
if (
|
|
114
|
-
const replay = await
|
|
115
|
-
if (liveStream && replay.status === 200) {
|
|
116
|
-
sseHeaders(res, { "x-task-id":
|
|
117
|
-
writeMetaFrame(res,
|
|
113
|
+
const keyedHit = idem && !cached && deps.runStore ? await readReplayHit(submitter, deps.config, deps.runStore, { idemKey: idem.key }, undefined) : undefined;
|
|
114
|
+
if (keyedHit && deps.runStore) {
|
|
115
|
+
const replay = await answerReplay(keyedHit, { subject: submitter, idem }, "sync", deps.runStore);
|
|
116
|
+
if (liveStream && replay.status === 200 && keyedHit.kind === "visible") {
|
|
117
|
+
sseHeaders(res, { "x-task-id": keyedHit.row.taskId });
|
|
118
|
+
writeMetaFrame(res, keyedHit.row.taskId, keyedHit.row.sessionId);
|
|
118
119
|
writeLiveFrame(res, doneFrameOfOutcome(replay));
|
|
119
120
|
res.end();
|
|
120
121
|
}
|
|
@@ -294,13 +295,20 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
294
295
|
const promptCommit = createPromptCommitReader();
|
|
295
296
|
let anchorPut = false;
|
|
296
297
|
const putRewindAnchor = async () => {
|
|
297
|
-
const store = deps.resumeAnchorStore;
|
|
298
|
-
const key = durableTaskId;
|
|
299
298
|
const entryId = userMsgEntryId;
|
|
300
|
-
|
|
299
|
+
const write = createRunAnchorWriter({
|
|
300
|
+
seat: deps.backend?.landedAttendants(),
|
|
301
|
+
sessionId: prepared.spec.sessionId,
|
|
302
|
+
owner: principal ?? null,
|
|
303
|
+
promptKey: durableTaskId,
|
|
304
|
+
witness: prepared.legFacts?.sessionWitness,
|
|
305
|
+
occupantOf: sessionOccupantReadOf(deps.sessionStorage),
|
|
306
|
+
leafOf: undefined,
|
|
307
|
+
}).prompt;
|
|
308
|
+
if (anchorPut || !entryId || write === undefined)
|
|
301
309
|
return;
|
|
302
310
|
anchorPut = true;
|
|
303
|
-
await settleResumeAnchor(() =>
|
|
311
|
+
await settleResumeAnchor((held) => write(entryId, held), { leg: "stream", kind: "prompt" });
|
|
304
312
|
};
|
|
305
313
|
try {
|
|
306
314
|
if (deps.runStore) {
|
|
@@ -357,7 +365,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
357
365
|
writeTerminalFrame(doneFrameOfOutcome(claimFault));
|
|
358
366
|
return claimFault;
|
|
359
367
|
}
|
|
360
|
-
|
|
368
|
+
commitLegBindings(deps, prepared.seat, prepared.spec.sessionId, prepared.legFacts?.sessionBindings);
|
|
361
369
|
markChildrenStoppedByUserOnAbort(ac.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.subject);
|
|
362
370
|
let ledgerSink;
|
|
363
371
|
let ledgerTerminal = false;
|
|
@@ -530,7 +538,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
530
538
|
await deps.userInputLedger?.observeLegEvent(liveStream, ev);
|
|
531
539
|
await prepared.acceptance.observe(ev);
|
|
532
540
|
if (ev.type === "done")
|
|
533
|
-
prepared.acceptance.settle(ev.result);
|
|
541
|
+
await prepared.acceptance.settle(ev.result);
|
|
534
542
|
await liveWorkspace.observe(ev);
|
|
535
543
|
if (ledgerSink)
|
|
536
544
|
await manifestSeat?.drain(ledgerSink.append);
|
|
@@ -800,7 +808,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
800
808
|
evict();
|
|
801
809
|
if (!runRowSettled && durableTaskId && deps.runStore) {
|
|
802
810
|
try {
|
|
803
|
-
const row = await deps.runStore
|
|
811
|
+
const row = await runFactsOf(deps.runStore, durableTaskId);
|
|
804
812
|
if (row?.status === "running") {
|
|
805
813
|
const pending = await deps.checkpointStore?.findPendingTokenBySession(prepared.spec.sessionId, undefined, { axis: "run" });
|
|
806
814
|
const backstopCause = ac.cause();
|
|
@@ -938,7 +946,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
938
946
|
catch (e) {
|
|
939
947
|
return faultedAnswerOf(e, SUBMISSION_CLAIM_FACE.faulted);
|
|
940
948
|
}
|
|
941
|
-
|
|
949
|
+
commitLegBindings(deps, prepared.seat, prepared.spec.sessionId, prepared.legFacts?.sessionBindings);
|
|
942
950
|
const syncCancelCtrl = createRunAbort(principal ?? null);
|
|
943
951
|
markChildrenStoppedByUserOnAbort(syncCancelCtrl.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.subject);
|
|
944
952
|
if (durableTaskId && deps.runStore) {
|
|
@@ -974,15 +982,22 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
974
982
|
counters.uncountedBillableInflight++;
|
|
975
983
|
try {
|
|
976
984
|
const heldDecisions = await heldWorkflowParkDecisions(deps, prepared.spec.sessionId);
|
|
977
|
-
const compositionInternals = { ...heldDecisions, ...compositionLegRoot(prepared.legFacts?.
|
|
985
|
+
const compositionInternals = { ...heldDecisions, ...compositionLegRoot(prepared.legFacts?.sessionBindings.cwd) };
|
|
978
986
|
const verifyLeg = (v) => runWithVerification(prepared.runner, specWithSignal, v, compositionInternals);
|
|
979
987
|
const cascadeLeg = () => runCascade(prepared.runner, specWithSignal, cascadeConfig(deps.config.cascadeLadder, prepared.spec.limits?.maxCostUsd), compositionInternals);
|
|
980
988
|
const plainLeg = async () => {
|
|
981
989
|
const stream = prepared.runner.runTaskStream(specWithSignal, undefined, heldDecisions);
|
|
982
990
|
const syncWorkspace = createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), prepared.legFacts?.sessionWitness);
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
991
|
+
const anchorWriter = createRunAnchorWriter({
|
|
992
|
+
seat: deps.backend?.landedAttendants(),
|
|
993
|
+
sessionId: prepared.spec.sessionId,
|
|
994
|
+
owner: principal ?? null,
|
|
995
|
+
promptKey: durableTaskId,
|
|
996
|
+
witness: prepared.legFacts?.sessionWitness,
|
|
997
|
+
occupantOf: sessionOccupantReadOf(deps.sessionStorage),
|
|
998
|
+
leafOf: undefined,
|
|
999
|
+
});
|
|
1000
|
+
const anchor = new TurnAnchorCapture(undefined, "sync", anchorWriter.prompt);
|
|
986
1001
|
for await (const ev of stream) {
|
|
987
1002
|
observeSyncLegEvent(ev);
|
|
988
1003
|
switch (ev.type) {
|
|
@@ -1039,18 +1054,18 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
1039
1054
|
const syncPlane = outwardPlane(result.terminal);
|
|
1040
1055
|
const syncHeld = heldParkOf(result);
|
|
1041
1056
|
if (syncHeld !== undefined && deps.checkpointStore && deps.runStore && durableTaskId) {
|
|
1057
|
+
await prepared.acceptance.settle(result);
|
|
1042
1058
|
const parked = await commitParkRow({
|
|
1043
1059
|
runStore: deps.runStore, taskId: durableTaskId, word: syncHeld.word, result: exitResult, card: { token: syncHeld.token, sessionId: prepared.spec.sessionId }, cards: deps.checkpointStore, leg: "sync",
|
|
1044
1060
|
legId: heldLegOf(durableLegId, durableTaskId), staleWindowMs: deps.config.runStaleSec * 1000,
|
|
1045
1061
|
});
|
|
1046
|
-
prepared.acceptance.settle(result);
|
|
1047
1062
|
if (parked.kind === "ended")
|
|
1048
1063
|
return { status: 200, body: withSyncSubmitKeys(parked.row !== undefined ? syncSubmitBodyOfRow(parked.row) : { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "failed" }) };
|
|
1049
1064
|
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: syncHeld.word })) };
|
|
1050
1065
|
}
|
|
1066
|
+
await prepared.acceptance.settle(result);
|
|
1051
1067
|
if (durableTaskId && deps.runStore)
|
|
1052
1068
|
await deps.runStore.setTerminal(durableTaskId, syncPlane.status, exitResult, syncPlane.errorMessage ?? null);
|
|
1053
|
-
prepared.acceptance.settle(result);
|
|
1054
1069
|
finalizeTaskResult(result, principal, prepared.spec.objective);
|
|
1055
1070
|
noteRunOutcome(result);
|
|
1056
1071
|
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult)) };
|
|
@@ -9,7 +9,7 @@ import { bindSseLifecycle } from "../sse-lifecycle.js";
|
|
|
9
9
|
import { sendJson, sendError, sseHeaders, SSE_MAX_STREAM_MS, SSE_HEARTBEAT_IDLE_MS } from "../send.js";
|
|
10
10
|
import { filterFingerprint } from "../cursor-fingerprint.js";
|
|
11
11
|
import { sendUnauthorized } from "../principal-gate.js";
|
|
12
|
-
import { admitRunById, enter, entryIsFleet, readVisibleRun, routeListFilter,
|
|
12
|
+
import { admitRunById, enter, entryIsFleet, listVisibleRuns, readVisibleRun, routeListFilter, listOwnerOf, toolResultRefOwned } from "../owner-access.js";
|
|
13
13
|
import { listFilterOf } from "../../owner-faces.js";
|
|
14
14
|
import { assertNever } from "../route-ctx.js";
|
|
15
15
|
import * as facts from "../../capability-facts.js";
|
|
@@ -42,7 +42,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
|
|
|
42
42
|
const traceEntry = enter(req, res, deps, match.decl.id);
|
|
43
43
|
if (traceEntry === undefined)
|
|
44
44
|
return;
|
|
45
|
-
const
|
|
45
|
+
const traceFilter = listFilterOf(traceEntry.face, traceEntry.caller);
|
|
46
46
|
const runs = facts.durableRuns(deps);
|
|
47
47
|
if (!runs.available) {
|
|
48
48
|
sendError(res, 501, "capability.run_store_required", "trace API requires a durable run store (DB_BACKEND=mysql|pg|local)");
|
|
@@ -61,20 +61,20 @@ export async function handleTraceUsage(req, res, match, ctx) {
|
|
|
61
61
|
}
|
|
62
62
|
switch (match.decl.id) {
|
|
63
63
|
case "task-trace-list":
|
|
64
|
-
await handleTaskList(res, runStore, query,
|
|
64
|
+
await handleTaskList(res, runStore, query, traceFilter);
|
|
65
65
|
return;
|
|
66
66
|
case "task-trace-turns":
|
|
67
67
|
await handleTaskTurns(res, runStore, admittedRun, query);
|
|
68
68
|
return;
|
|
69
69
|
case "task-trace-stream":
|
|
70
|
-
await streamTaskTrace(req, res, runStore, admittedRun, match.search);
|
|
70
|
+
await streamTaskTrace(req, res, runStore, traceEntry, admittedRun, match.search);
|
|
71
71
|
return;
|
|
72
72
|
case "task-trace-artifacts":
|
|
73
73
|
await handleTaskArtifacts(res, runStore, admittedRun);
|
|
74
74
|
return;
|
|
75
75
|
case "task-tool-result": {
|
|
76
76
|
const ownedRun = admittedRun;
|
|
77
|
-
const readRun = ownedRun !== undefined ? async () => ownedRun : () => readVisibleRun(traceEntry, runStore, taskId);
|
|
77
|
+
const readRun = ownedRun !== undefined ? async () => ownedRun : async () => (await readVisibleRun(traceEntry, runStore, taskId))?.row;
|
|
78
78
|
await handleToolResult(res, deps.toolResultStore, taskId, readRun, safeDecode(match.params.ref), query);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
@@ -161,11 +161,12 @@ function decodeCursor(s, expectF) {
|
|
|
161
161
|
return undefined;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
async function handleTaskList(res, runStore, query,
|
|
164
|
+
async function handleTaskList(res, runStore, query, filter) {
|
|
165
165
|
const status = query.get("status") ?? undefined;
|
|
166
166
|
const jobId = query.get("jobId") ?? undefined;
|
|
167
167
|
const source = query.get("source") ?? undefined;
|
|
168
|
-
const
|
|
168
|
+
const namedOwner = query.get("owner") ?? undefined;
|
|
169
|
+
const owner = listOwnerOf(filter, namedOwner);
|
|
169
170
|
const limit = Math.min(100, Math.max(1, Number(query.get("limit") ?? 50) || 50));
|
|
170
171
|
const f = filterFingerprint([status, jobId, source, owner]);
|
|
171
172
|
const cursor = decodeCursor(query.get("cursor"), f);
|
|
@@ -173,7 +174,7 @@ async function handleTaskList(res, runStore, query, forceOwner) {
|
|
|
173
174
|
sendError(res, 400, "request.cursor_filter_mismatch", "cursor was issued under a different filter (status/jobId/source/owner) — restart from the first page without a cursor");
|
|
174
175
|
return;
|
|
175
176
|
}
|
|
176
|
-
const rows = await runStore
|
|
177
|
+
const rows = await listVisibleRuns(runStore, filter, namedOwner, { ...(status ? { status } : {}), ...(jobId ? { jobId } : {}), ...(source ? { source } : {}), ...(cursor ? { cursor } : {}), limit: limit + 1 });
|
|
177
178
|
const hasMore = rows.length > limit;
|
|
178
179
|
const page = hasMore ? rows.slice(0, limit) : rows;
|
|
179
180
|
const tasks = page.map((r) => taskSummary(r));
|
|
@@ -216,8 +217,7 @@ async function handleToolResult(res, store, taskId, readRun, ref, query) {
|
|
|
216
217
|
const run = await readRun();
|
|
217
218
|
if (!run)
|
|
218
219
|
return notFound();
|
|
219
|
-
const
|
|
220
|
-
const ownedByThisCaller = owner !== undefined && owner.sessionId === run.sessionId && (owner.taskId === undefined || owner.taskId === taskId);
|
|
220
|
+
const ownedByThisCaller = await toolResultRefOwned(store, ref, run);
|
|
221
221
|
if (!ownedByThisCaller)
|
|
222
222
|
return notFound();
|
|
223
223
|
if (!store)
|
|
@@ -240,7 +240,7 @@ async function handleTaskTurns(res, runStore, run, query) {
|
|
|
240
240
|
const nextCursor = eligible.length > limit && oldest ? String(oldest.seq) : undefined;
|
|
241
241
|
sendJson(res, 200, { turns, ...(nextCursor ? { nextCursor } : {}), retainedFrom });
|
|
242
242
|
}
|
|
243
|
-
async function streamTaskTrace(req, res, runStore, admitted, search) {
|
|
243
|
+
async function streamTaskTrace(req, res, runStore, entry, admitted, search) {
|
|
244
244
|
const taskId = admitted.taskId;
|
|
245
245
|
const lastId = Number(req.headers["last-event-id"] ?? new URLSearchParams(search).get("from") ?? 0);
|
|
246
246
|
let from = Number.isFinite(lastId) ? lastId : 0;
|
|
@@ -264,11 +264,11 @@ async function streamTaskTrace(req, res, runStore, admitted, search) {
|
|
|
264
264
|
}
|
|
265
265
|
};
|
|
266
266
|
while (!closed) {
|
|
267
|
-
const [events,
|
|
267
|
+
const [events, reread] = await Promise.all([runStore.getEvents(taskId, from), readVisibleRun(entry, runStore, taskId)]);
|
|
268
268
|
write(events);
|
|
269
|
-
if (!
|
|
269
|
+
if (!reread)
|
|
270
270
|
break;
|
|
271
|
-
const run =
|
|
271
|
+
const run = reread.row;
|
|
272
272
|
if (run.status !== "running") {
|
|
273
273
|
write(await runStore.getEvents(taskId, from));
|
|
274
274
|
if (!deliveredTerminal && isHolderDeathVerdict(run))
|
|
@@ -2,6 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
2
2
|
import { type WorkflowRun } from "@sema-agent/core";
|
|
3
3
|
import { type Admit } from "../../trace/projection-table.js";
|
|
4
4
|
import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js";
|
|
5
|
+
/** SVC-5 的 steer 路——`handle()` 里位置在 tasks/runs 之后(鉴权门之后),故是**独立**的域入口。 */
|
|
5
6
|
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
6
7
|
* = 「本域已应答」;走到函数尾才是「没匹配上」。跨域的东西一律在首行解构出来。 */
|
|
7
8
|
export declare function handleWorkflows(req: IncomingMessage, res: ServerResponse, match: RouteMatch<WorkflowsRouteId>, ctx: RouteCtx): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { persistedPlaneOf } from "../../terminal.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
3
|
+
import { subscribeWorkflow, deriveAgentDisplayStatus, callKeyOrdinal, runParkedOf, JOURNAL_INCOMPATIBLE_ERROR_CODE, WorkflowJournalIncompatibleError } from "@sema-agent/core";
|
|
4
4
|
import { redactSteerIn, STEER_IN_MAX_CHARS, STEER_IN_MAX_REQUEST_CHARS } from "../../orchestration/workflow-agent-steer.js";
|
|
5
5
|
import { journalEntryOfCell, journalEntryPayload, journalRowPayloadOf } from "../../plugins/workflow-journal-payload.js";
|
|
6
6
|
import { redactSecrets } from "../../trace/redact.js";
|
|
@@ -10,30 +10,18 @@ import { projectByTable } from "../../trace/projection-table.js";
|
|
|
10
10
|
const JOURNAL_PROJECTION_MEMO_CAP = 1024;
|
|
11
11
|
const journalProjectionMemo = new Map();
|
|
12
12
|
import { sendJson, sendError, sseHeaders } from "../send.js";
|
|
13
|
-
import {
|
|
13
|
+
import { explicitOperatorOk } from "../principal-gate.js";
|
|
14
14
|
import { partsOf } from "../../owner-brands.js";
|
|
15
|
-
import { taskSpecIdentityOf } from "../../engine-identity.js";
|
|
16
15
|
import { assertNever } from "../route-ctx.js";
|
|
17
|
-
import {
|
|
16
|
+
import { admitWorkflowRun, enter, judgeWorkflowRun, listVisibleWorkflows, refuse } from "../owner-access.js";
|
|
18
17
|
import * as facts from "../../capability-facts.js";
|
|
19
18
|
import { steerBodyKeyIssue } from "../../request-key-closure.js";
|
|
20
|
-
function sendWorkflowAbsent(res) {
|
|
21
|
-
sendError(res, 404, "not_found.workflow", "workflow not found");
|
|
22
|
-
}
|
|
23
|
-
const WORKFLOW_SESSION_ASSERTION = {
|
|
24
|
-
"workflow-detail": { phase: "accept", label: "workflow.detail" },
|
|
25
|
-
"workflow-journal": { phase: "accept", label: "workflow.journal" },
|
|
26
|
-
"workflow-stream": { phase: "accept", label: "workflow.stream" },
|
|
27
|
-
"workflow-agent-steer": { phase: "accept", label: "workflow.agent-steer" },
|
|
28
|
-
};
|
|
29
19
|
export async function handleWorkflows(req, res, match, ctx) {
|
|
30
20
|
const { deps } = ctx;
|
|
31
21
|
{
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
sendPrincipalRefusal(res, req, deps.config);
|
|
22
|
+
const wfEntry = enter(req, res, deps, match.decl.id);
|
|
23
|
+
if (wfEntry === undefined)
|
|
35
24
|
return;
|
|
36
|
-
}
|
|
37
25
|
let journalStore;
|
|
38
26
|
if (match.decl.id === "workflow-journal") {
|
|
39
27
|
const journalFace = facts.workflowsJournal(deps);
|
|
@@ -49,7 +37,6 @@ export async function handleWorkflows(req, res, match, ctx) {
|
|
|
49
37
|
return;
|
|
50
38
|
}
|
|
51
39
|
const runStore = runs.store;
|
|
52
|
-
const scope = taskSpecIdentityOf(subject === undefined ? undefined : partsOf(subject)).principal ?? "default";
|
|
53
40
|
const wfId = match.params.runId;
|
|
54
41
|
const isStream = match.decl.id === "workflow-stream";
|
|
55
42
|
if (match.decl.id === "workflows-list") {
|
|
@@ -57,7 +44,7 @@ export async function handleWorkflows(req, res, match, ctx) {
|
|
|
57
44
|
const statusFilter = q.get("status");
|
|
58
45
|
const limit = Math.min(100, Math.max(1, Number(q.get("limit") ?? 50) || 50));
|
|
59
46
|
const sessionFilter = q.get("session");
|
|
60
|
-
const sessionRuns = await
|
|
47
|
+
const sessionRuns = await listVisibleWorkflows(wfEntry, runStore, {
|
|
61
48
|
...(statusFilter ? { status: statusFilter } : {}),
|
|
62
49
|
limit,
|
|
63
50
|
...(sessionFilter !== null ? { session: sessionFilter } : {}),
|
|
@@ -71,15 +58,11 @@ export async function handleWorkflows(req, res, match, ctx) {
|
|
|
71
58
|
sendJson(res, 200, { workflows: redacted });
|
|
72
59
|
return;
|
|
73
60
|
}
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
sendWorkflowAbsent(res);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (!sessionAsserted(WORKFLOW_SESSION_ASSERTION[match.decl.id], req, run.originatingSessionId, callerOf(req, deps).operator)) {
|
|
80
|
-
sendWorkflowAbsent(res);
|
|
61
|
+
const wfAdmitted = await admitWorkflowRun(wfEntry, res, runStore, wfId);
|
|
62
|
+
if (wfAdmitted === undefined)
|
|
81
63
|
return;
|
|
82
|
-
|
|
64
|
+
const run = wfAdmitted.row;
|
|
65
|
+
const scope = run.scope;
|
|
83
66
|
if (match.decl.id === "workflow-journal") {
|
|
84
67
|
if (journalStore === undefined)
|
|
85
68
|
throw new Error("workflow-journal reached without the workflowsJournal journal witness");
|
|
@@ -182,12 +165,11 @@ export async function handleWorkflowAgentSteer(req, res, match, ctx) {
|
|
|
182
165
|
sendWorkflowsUnavailable(res, runs.why);
|
|
183
166
|
return;
|
|
184
167
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
if (deps.config.requirePrincipal && principal === undefined) {
|
|
188
|
-
sendPrincipalRefusal(res, req, deps.config);
|
|
168
|
+
const steerEntry = enter(req, res, deps, match.decl.id);
|
|
169
|
+
if (steerEntry === undefined)
|
|
189
170
|
return;
|
|
190
|
-
|
|
171
|
+
const subject = steerEntry.caller.subject;
|
|
172
|
+
const principal = subject === undefined ? undefined : partsOf(subject).person;
|
|
191
173
|
const wfRunId = safeDecode(match.params.runId);
|
|
192
174
|
const label = safeDecode(match.params.label);
|
|
193
175
|
if (wfRunId === null || label === null) {
|
|
@@ -211,14 +193,14 @@ export async function handleWorkflowAgentSteer(req, res, match, ctx) {
|
|
|
211
193
|
return;
|
|
212
194
|
}
|
|
213
195
|
const trusted = explicitOperatorOk(principal, deps.config);
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
sendWorkflowAbsent(res);
|
|
196
|
+
const wfVerdict = await judgeWorkflowRun(steerEntry, runs.store, wfRunId);
|
|
197
|
+
if (wfVerdict === "session_mismatch") {
|
|
198
|
+
refuse(steerEntry, res, "session_mismatch");
|
|
218
199
|
return;
|
|
219
200
|
}
|
|
220
|
-
|
|
221
|
-
|
|
201
|
+
const wfRun = typeof wfVerdict === "object" ? wfVerdict.row : undefined;
|
|
202
|
+
if (!trusted && wfRun === undefined) {
|
|
203
|
+
refuse(steerEntry, res, wfVerdict === "missing" ? "missing" : "not_visible");
|
|
222
204
|
return;
|
|
223
205
|
}
|
|
224
206
|
const sendNotRunningWf = (error) => sendError(res, 409, "steering.not_running", error);
|