@sema-agent/server 7.131.0 → 7.133.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 +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +31 -13
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +47 -32
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -28
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +118 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 引擎的 `classic.*` 站 —— 本仓挂 handler 的唯一入口(core 7.52.0 起扩展点 = mods 注册,`Hooks` 记录退役)。
|
|
3
|
+
*
|
|
4
|
+
* 三件事只写在这里:
|
|
5
|
+
* ① **事件名 → { `e` 型, 答案型 }**:core 逐个导出了每站的 `e` 型与答案型,但没有导出二者的映射(宿主侧配对是今天的唯一读法)。
|
|
6
|
+
* 这张对位表是那一配对的唯一一份;core 导出映射型的那一版,本表改读它、删掉手写的十一行。
|
|
7
|
+
* ② **handler 怎么挂**:链成员「无意见 ⇒ `next(e)`」(链 handler 返回 `undefined` 是站点违约,refuse 站上即 fail-closed 拒),
|
|
8
|
+
* 观察者「恒返回 `undefined`」(观察者的判词不采纳、被引擎报告)。两条都在 {@link hangClassic} / {@link observeClassic} 里成形,
|
|
9
|
+
* 调用方只写「这一站我答什么」或「这一站我看什么」,不再各自记得这两条。
|
|
10
|
+
* ③ **信号**:引擎交给每只 handler 的 `next.signal` 是「这只 handler 的预算 ∪ 这次派发被取消」的合成(core 的派发器自合成,本仓不另合成第二份)。
|
|
11
|
+
* 它是 handler 体的第二个入参 —— 触发之后 handler 不再起新事、在飞的子进程要叫停(`hooks/hook-runner.ts` 的命令钩子腿)。
|
|
12
|
+
*
|
|
13
|
+
* 站的集合 = 引擎事件表里有站的 `classic.*` 名(一条钉从 `MOD_EVENT_TABLE` 派生对拍,不手抄第二份)。
|
|
14
|
+
* 观察站(`StopFailure` / `PostCompact` / `PermissionDenied`)只许观察者:答案形是「无」,core 的迁移配方要求挂 `{ observe: true }`。
|
|
15
|
+
*/
|
|
16
|
+
import type { EngineDollar, On, PermissionDeniedPayload, PostCompactEvent, PostToolBatchEvent, PostToolBatchResult, PostToolUseEvent, PostToolUseFailureEvent, PostToolUseFailureResult, PostToolUseResult, PreCompactEvent, PreCompactResult, PreToolUseEvent, PreToolUseResult, StopEvent, StopFailureEvent, StopHookResult, UserPromptSubmitEvent, UserPromptSubmitResult } from "@sema-agent/core";
|
|
17
|
+
/** 每一站的 `e` 型与答案型(答案 `void` = 观察站)。 */
|
|
18
|
+
export interface ClassicStationTypes {
|
|
19
|
+
"classic.PreToolUse": {
|
|
20
|
+
e: PreToolUseEvent;
|
|
21
|
+
answer: PreToolUseResult;
|
|
22
|
+
};
|
|
23
|
+
"classic.PostToolUse": {
|
|
24
|
+
e: PostToolUseEvent;
|
|
25
|
+
answer: PostToolUseResult;
|
|
26
|
+
};
|
|
27
|
+
"classic.PostToolUseFailure": {
|
|
28
|
+
e: PostToolUseFailureEvent;
|
|
29
|
+
answer: PostToolUseFailureResult;
|
|
30
|
+
};
|
|
31
|
+
"classic.PostToolBatch": {
|
|
32
|
+
e: PostToolBatchEvent;
|
|
33
|
+
answer: PostToolBatchResult;
|
|
34
|
+
};
|
|
35
|
+
"classic.UserPromptSubmit": {
|
|
36
|
+
e: UserPromptSubmitEvent;
|
|
37
|
+
answer: UserPromptSubmitResult;
|
|
38
|
+
};
|
|
39
|
+
"classic.Stop": {
|
|
40
|
+
e: StopEvent;
|
|
41
|
+
answer: StopHookResult;
|
|
42
|
+
};
|
|
43
|
+
"classic.SubagentStop": {
|
|
44
|
+
e: StopEvent;
|
|
45
|
+
answer: StopHookResult;
|
|
46
|
+
};
|
|
47
|
+
"classic.StopFailure": {
|
|
48
|
+
e: StopFailureEvent;
|
|
49
|
+
answer: void;
|
|
50
|
+
};
|
|
51
|
+
"classic.PreCompact": {
|
|
52
|
+
e: PreCompactEvent;
|
|
53
|
+
answer: PreCompactResult;
|
|
54
|
+
};
|
|
55
|
+
"classic.PostCompact": {
|
|
56
|
+
e: PostCompactEvent;
|
|
57
|
+
answer: void;
|
|
58
|
+
};
|
|
59
|
+
"classic.PermissionDenied": {
|
|
60
|
+
e: PermissionDeniedPayload;
|
|
61
|
+
answer: void;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export type ClassicStation = keyof ClassicStationTypes;
|
|
65
|
+
/** 每一站能挂什么:`chain` = 链成员(会作答)与观察者都可;`observe` = 只许观察者。 */
|
|
66
|
+
export declare const CLASSIC_STATION_ROLE: {
|
|
67
|
+
readonly "classic.PreToolUse": "chain";
|
|
68
|
+
readonly "classic.PostToolUse": "chain";
|
|
69
|
+
readonly "classic.PostToolUseFailure": "chain";
|
|
70
|
+
readonly "classic.PostToolBatch": "chain";
|
|
71
|
+
readonly "classic.UserPromptSubmit": "chain";
|
|
72
|
+
readonly "classic.Stop": "chain";
|
|
73
|
+
readonly "classic.SubagentStop": "chain";
|
|
74
|
+
readonly "classic.StopFailure": "observe";
|
|
75
|
+
readonly "classic.PreCompact": "chain";
|
|
76
|
+
readonly "classic.PostCompact": "observe";
|
|
77
|
+
readonly "classic.PermissionDenied": "observe";
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* 一站的 handler 体:读 `e`,答这一站的答案;`undefined` = 无意见(链成员由 {@link hangClassic} 交给 `next(e)`)。
|
|
81
|
+
* `signal` = 引擎交给这只 handler 的 `next.signal`(预算到 ∪ 派发被取消;见头注 ③)。
|
|
82
|
+
*/
|
|
83
|
+
export type ClassicAnswer<K extends ClassicStation> = (e: ClassicStationTypes[K]["e"], signal: AbortSignal) => Promise<ClassicStationTypes[K]["answer"] | undefined>;
|
|
84
|
+
/**
|
|
85
|
+
* 按站的角色挂一只 handler:链站 ⇒ 链成员 `(await answer(e)) ?? next(e)`;观察站 ⇒ 观察者(体照跑、恒返回 `undefined`)。
|
|
86
|
+
* `e` 的型由 {@link ClassicStationTypes} 给(引擎交来的是本站的 `e`;配对见头注 ①)。
|
|
87
|
+
*/
|
|
88
|
+
export declare function hangClassic<K extends ClassicStation>(on: On<EngineDollar>, station: K, answer: ClassicAnswer<K>): void;
|
|
89
|
+
/** 挂一只观察者(任何站都可):拿分离副本、不进链、恒返回 `undefined`;`signal` 同 {@link ClassicAnswer}。 */
|
|
90
|
+
export declare function observeClassic<K extends ClassicStation>(on: On<EngineDollar>, station: K, watch: (e: ClassicStationTypes[K]["e"], signal: AbortSignal) => void | Promise<void>): void;
|
|
91
|
+
//# sourceMappingURL=classic-stations.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const CLASSIC_STATION_ROLE = {
|
|
2
|
+
"classic.PreToolUse": "chain",
|
|
3
|
+
"classic.PostToolUse": "chain",
|
|
4
|
+
"classic.PostToolUseFailure": "chain",
|
|
5
|
+
"classic.PostToolBatch": "chain",
|
|
6
|
+
"classic.UserPromptSubmit": "chain",
|
|
7
|
+
"classic.Stop": "chain",
|
|
8
|
+
"classic.SubagentStop": "chain",
|
|
9
|
+
"classic.StopFailure": "observe",
|
|
10
|
+
"classic.PreCompact": "chain",
|
|
11
|
+
"classic.PostCompact": "observe",
|
|
12
|
+
"classic.PermissionDenied": "observe",
|
|
13
|
+
};
|
|
14
|
+
export function hangClassic(on, station, answer) {
|
|
15
|
+
if (CLASSIC_STATION_ROLE[station] === "observe") {
|
|
16
|
+
observeClassic(on, station, async (e, signal) => void (await answer(e, signal)));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
on(station, async (_$, e, next) => (await answer(e, next.signal)) ?? next(e));
|
|
20
|
+
}
|
|
21
|
+
export function observeClassic(on, station, watch) {
|
|
22
|
+
on(station, async (_$, e, next) => {
|
|
23
|
+
await watch(e, next.signal);
|
|
24
|
+
return undefined;
|
|
25
|
+
}, { observe: true });
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=classic-stations.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CommandHookEntry } from "@sema-agent/settings-schema/hooks";
|
|
2
|
+
/** command 条目的插件上下文(wire 键 `plugin`)。 */
|
|
3
|
+
export interface HookPluginContext {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly root: string;
|
|
6
|
+
readonly dataDir?: string;
|
|
7
|
+
readonly options?: Readonly<Record<string, string>>;
|
|
8
|
+
}
|
|
9
|
+
/** 本仓会跑的 command 条目:契约形 + 本仓读的两只 wire 键。 */
|
|
10
|
+
export type RunnableCommandHookEntry = CommandHookEntry & {
|
|
11
|
+
readonly args?: readonly string[];
|
|
12
|
+
readonly plugin?: HookPluginContext;
|
|
13
|
+
};
|
|
14
|
+
/** 受理面:`args` 合形(串数组、元素无 NUL)⇒ 拷贝;否则 `undefined`。 */
|
|
15
|
+
export declare function readHookArgs(raw: unknown): string[] | undefined;
|
|
16
|
+
/** 受理面:`plugin` 合形 ⇒ 拷贝;否则 `undefined`。路径与 `skills[i].baseDir` 同一只判(契约包 `isAbsoluteHostPath`:绝对、无 `..` 段、无 NUL、有长度上限);不做存在性检查(那是执行面的事)。 */
|
|
17
|
+
export declare function readHookPlugin(raw: unknown): HookPluginContext | undefined;
|
|
18
|
+
/** 插件上下文的总字符数(服务侧上限 `plugin` 帽的量):名 + 根 + 数据目录 + 各选项的键与值。 */
|
|
19
|
+
export declare function hookPluginChars(p: HookPluginContext): number;
|
|
20
|
+
/** 命令行的字符数(服务侧上限 `command` 帽的量):`command` 加上 exec 形每个元素(各计一个分隔)。 */
|
|
21
|
+
export declare function commandLineChars(entry: {
|
|
22
|
+
readonly command: string;
|
|
23
|
+
readonly args?: readonly string[];
|
|
24
|
+
}): number;
|
|
25
|
+
/** 插件上下文 → 它注入的环境变量(无 `plugin` ⇒ 空)。 */
|
|
26
|
+
export declare function hookPluginEnv(p: HookPluginContext | undefined): Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* 起法:shell 形交回命令串(shell 由调用点落定),exec 形交回可执行名与参数,起不来交回真因(进调用点的 `spawnError`)。
|
|
29
|
+
* `env` = 这条 hook 的**有效环境层**({@link composeHookEnvLayer} 的产物;调用点铺在基础 allowlist 之上,不再自己合并任何一层)。
|
|
30
|
+
*/
|
|
31
|
+
export type CommandSpawnPlan = {
|
|
32
|
+
readonly kind: "shell";
|
|
33
|
+
readonly command: string;
|
|
34
|
+
readonly env: Readonly<Record<string, string>>;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: "exec";
|
|
37
|
+
readonly file: string;
|
|
38
|
+
readonly args: readonly string[];
|
|
39
|
+
readonly env: Readonly<Record<string, string>>;
|
|
40
|
+
} | {
|
|
41
|
+
readonly kind: "refused";
|
|
42
|
+
readonly error: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* 一条 command hook 的**有效环境层**(基础 allowlist 之上的那一层)—— **唯一铺法**,后铺者赢:`CLAUDE_PROJECT_DIR` 的缺省(`cwd`,hook 的工作目录;请求没写它才取)< 请求 `settings.env`(`requestEnv`;
|
|
46
|
+
* 请求自己写了 `CLAUDE_PROJECT_DIR` 就是它,空串也照用)< 条目自己的插件上下文({@link hookPluginEnv})。键的枚举顺序 = 请求的键在前、`CLAUDE_PROJECT_DIR` 缺省时接后、插件键最后。调用点传**原料**(工作目录与请求 env),不预先取舍 `CLAUDE_PROJECT_DIR`。
|
|
47
|
+
* 「有没有值」的判据、exec 形的占位替换、shell 形子进程的环境都读这一个对象(见文件头);http 条目的 `$NAME` 插值取环境也走这一只(无插件上下文)。
|
|
48
|
+
*/
|
|
49
|
+
export declare function composeHookEnvLayer(requestEnv: Readonly<Record<string, string>> | undefined, cwd: string, plugin: HookPluginContext | undefined): Record<string, string> & {
|
|
50
|
+
CLAUDE_PROJECT_DIR: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* 一条 command 条目的起法(规则见文件头)。`cwd` = 本次 hook 的工作目录(`CLAUDE_PROJECT_DIR` 的缺省值);`requestEnv` = 请求 `settings.env`(hook 环境的一层;**必传**:没有就显式传 `undefined`,
|
|
54
|
+
* 漏传是编译红,不会静默丢掉请求给的 env),合并与读法见 {@link composeHookEnvLayer} / {@link contextVarValue}。有副作用的只有两步,都只在条目带 `plugin` 时发生:读插件根是否是目录、建数据目录(CC 同:注入即建)。
|
|
55
|
+
*/
|
|
56
|
+
export declare function planCommandSpawn(entry: RunnableCommandHookEntry, cwd: string, requestEnv: Readonly<Record<string, string>> | undefined): Promise<CommandSpawnPlan>;
|
|
57
|
+
//# sourceMappingURL=command-spawn.d.ts.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { mkdir, stat } from "node:fs/promises";
|
|
2
|
+
import { isAbsoluteHostPath } from "@sema-agent/settings-schema";
|
|
3
|
+
const PLUGIN_MEMBERS = new Set(["name", "root", "dataDir", "options"]);
|
|
4
|
+
const OPTION_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5
|
+
function isRecord(v) {
|
|
6
|
+
if (v === null || typeof v !== "object" || Array.isArray(v))
|
|
7
|
+
return false;
|
|
8
|
+
const proto = Object.getPrototypeOf(v);
|
|
9
|
+
return proto === Object.prototype || proto === null;
|
|
10
|
+
}
|
|
11
|
+
export function readHookArgs(raw) {
|
|
12
|
+
if (!Array.isArray(raw))
|
|
13
|
+
return undefined;
|
|
14
|
+
const out = [];
|
|
15
|
+
for (const a of raw) {
|
|
16
|
+
if (typeof a !== "string" || a.includes("\0"))
|
|
17
|
+
return undefined;
|
|
18
|
+
out.push(a);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
export function readHookPlugin(raw) {
|
|
23
|
+
if (!isRecord(raw))
|
|
24
|
+
return undefined;
|
|
25
|
+
for (const k of Object.keys(raw))
|
|
26
|
+
if (!PLUGIN_MEMBERS.has(k))
|
|
27
|
+
return undefined;
|
|
28
|
+
const { name, root, dataDir, options } = raw;
|
|
29
|
+
if (typeof name !== "string" || name.length === 0 || name.includes("\0"))
|
|
30
|
+
return undefined;
|
|
31
|
+
if (!isAbsoluteHostPath(root))
|
|
32
|
+
return undefined;
|
|
33
|
+
if (dataDir !== undefined && !isAbsoluteHostPath(dataDir))
|
|
34
|
+
return undefined;
|
|
35
|
+
let opts;
|
|
36
|
+
if (options !== undefined) {
|
|
37
|
+
if (!isRecord(options))
|
|
38
|
+
return undefined;
|
|
39
|
+
const entries = Object.entries(options);
|
|
40
|
+
for (const [k, v] of entries)
|
|
41
|
+
if (!OPTION_KEY.test(k) || typeof v !== "string" || v.includes("\0"))
|
|
42
|
+
return undefined;
|
|
43
|
+
opts = Object.fromEntries(entries);
|
|
44
|
+
}
|
|
45
|
+
return { name, root: root, ...(dataDir !== undefined ? { dataDir: dataDir } : {}), ...(opts !== undefined ? { options: opts } : {}) };
|
|
46
|
+
}
|
|
47
|
+
export function hookPluginChars(p) {
|
|
48
|
+
return p.name.length + p.root.length + (p.dataDir?.length ?? 0) + Object.entries(p.options ?? {}).reduce((n, [k, v]) => n + k.length + v.length, 0);
|
|
49
|
+
}
|
|
50
|
+
export function commandLineChars(entry) {
|
|
51
|
+
return entry.command.length + (entry.args ?? []).reduce((n, a) => n + 1 + a.length, 0);
|
|
52
|
+
}
|
|
53
|
+
export function hookPluginEnv(p) {
|
|
54
|
+
if (p === undefined)
|
|
55
|
+
return {};
|
|
56
|
+
const env = { CLAUDE_PLUGIN_ROOT: p.root };
|
|
57
|
+
if (p.dataDir !== undefined)
|
|
58
|
+
env.CLAUDE_PLUGIN_DATA = p.dataDir;
|
|
59
|
+
for (const [k, v] of Object.entries(p.options ?? {}))
|
|
60
|
+
env[`CLAUDE_PLUGIN_OPTION_${k.toUpperCase()}`] = v;
|
|
61
|
+
return env;
|
|
62
|
+
}
|
|
63
|
+
const CONTEXT_VARS = [
|
|
64
|
+
["CLAUDE_PLUGIN_ROOT", "${CLAUDE_PLUGIN_ROOT}"],
|
|
65
|
+
["CLAUDE_PLUGIN_DATA", "${CLAUDE_PLUGIN_DATA}"],
|
|
66
|
+
];
|
|
67
|
+
const ROOT_REF = CONTEXT_VARS[0][1];
|
|
68
|
+
const SUBSTITUTION_NAMES = ["CLAUDE_PROJECT_DIR", "CLAUDE_PLUGIN_ROOT", "CLAUDE_PLUGIN_DATA"];
|
|
69
|
+
const refOf = (name) => "${" + name + "}";
|
|
70
|
+
export function composeHookEnvLayer(requestEnv, cwd, plugin) {
|
|
71
|
+
return { ...requestEnv, CLAUDE_PROJECT_DIR: requestEnv?.CLAUDE_PROJECT_DIR ?? cwd, ...hookPluginEnv(plugin) };
|
|
72
|
+
}
|
|
73
|
+
function contextVarValue(name, layer) {
|
|
74
|
+
const v = layer[name];
|
|
75
|
+
return v !== undefined && v.length > 0 ? v : undefined;
|
|
76
|
+
}
|
|
77
|
+
export async function planCommandSpawn(entry, cwd, requestEnv) {
|
|
78
|
+
const texts = [entry.command, ...(entry.args ?? [])];
|
|
79
|
+
const p = entry.plugin;
|
|
80
|
+
const env = composeHookEnvLayer(requestEnv, cwd, p);
|
|
81
|
+
const values = new Map([["CLAUDE_PROJECT_DIR", env.CLAUDE_PROJECT_DIR]]);
|
|
82
|
+
for (const [name, ref] of CONTEXT_VARS) {
|
|
83
|
+
const value = contextVarValue(name, env);
|
|
84
|
+
if (value !== undefined) {
|
|
85
|
+
values.set(name, value);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (!texts.some((t) => t.includes(ref)))
|
|
89
|
+
continue;
|
|
90
|
+
return {
|
|
91
|
+
kind: "refused",
|
|
92
|
+
error: p !== undefined
|
|
93
|
+
? `hook command references ${ref} but only ${ROOT_REF} is available for this hook (it carries no plugin data directory and the request settings.env does not set ${name})`
|
|
94
|
+
: `hook command references ${ref} but the hook is not associated with a plugin and the request settings.env does not set ${name} (the variable is only available to hooks that carry a plugin context, or to a request that sets it in settings.env)`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (p !== undefined) {
|
|
98
|
+
const isDir = await stat(p.root).then((s) => s.isDirectory(), () => false);
|
|
99
|
+
if (!isDir)
|
|
100
|
+
return { kind: "refused", error: `plugin directory does not exist: ${p.root} (${p.name} — reinstall the plugin)` };
|
|
101
|
+
if (p.dataDir !== undefined) {
|
|
102
|
+
try {
|
|
103
|
+
await mkdir(p.dataDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
return { kind: "refused", error: `plugin data directory could not be created: ${p.dataDir} (${e instanceof Error ? e.message : String(e)})` };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (entry.args === undefined)
|
|
111
|
+
return { kind: "shell", command: entry.command, env };
|
|
112
|
+
const substitute = (s) => {
|
|
113
|
+
if (!s.includes("${"))
|
|
114
|
+
return s;
|
|
115
|
+
let out = "";
|
|
116
|
+
let i = 0;
|
|
117
|
+
while (i < s.length) {
|
|
118
|
+
const at = s.indexOf("${", i);
|
|
119
|
+
if (at === -1) {
|
|
120
|
+
out += s.slice(i);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
out += s.slice(i, at);
|
|
124
|
+
const hit = SUBSTITUTION_NAMES.find((name) => s.startsWith(refOf(name), at));
|
|
125
|
+
const v = hit === undefined ? undefined : values.get(hit);
|
|
126
|
+
if (hit !== undefined && v !== undefined) {
|
|
127
|
+
out += v;
|
|
128
|
+
i = at + refOf(hit).length;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
out += "${";
|
|
132
|
+
i = at + 2;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
};
|
|
137
|
+
return { kind: "exec", file: substitute(entry.command), args: entry.args.map(substitute), env };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=command-spawn.js.map
|
package/dist/hooks/hook-llm.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ModelKeyRef } from "../key-resolver.js";
|
|
2
2
|
import type { ServiceConfig } from "../config-types.js";
|
|
3
|
-
import type { HookLlmCall } from "./hook-runner.js";
|
|
3
|
+
import type { HookLlmCall, HookLlmFailureCode } from "./hook-runner.js";
|
|
4
4
|
/**
|
|
5
5
|
* hookLlm(prompt 条目/session titler 的模型载体)= 直连一次非流式 completion,从 main.ts 抽出成可注入
|
|
6
6
|
* 单元(fetchImpl/keyResolver 可假),因为这条 wire 在每个默认部署上都活(titler),必须可单测。
|
|
@@ -16,13 +16,13 @@ import type { HookLlmCall } from "./hook-runner.js";
|
|
|
16
16
|
*
|
|
17
17
|
* 🔴 **选线 = 引擎主路由同一只判词**(S-1630):「这只模型走 openai-completions 还是 anthropic-messages」不是本面的事,
|
|
18
18
|
* 是引擎主路由的事 —— `brain.ts` 按 `model.provider` 在「anthropic 路由(仅当 ANTHROPIC 凭据把它装上)/ 网关栈」之间选,
|
|
19
|
-
* 路由没装时整台机器只有网关这一只 brain,**连 `provider:"anthropic"` 的模型也落网关**(`
|
|
19
|
+
* 路由没装时整台机器只有网关这一只 brain,**连 `provider:"anthropic"` 的模型也落网关**(判词 `brainLaneFor` = 引擎 `brainLaneOf` 对装上的路由表的答案,
|
|
20
20
|
* 端点判官 / 降级腿 / 启动摘要读的是同一只)。本面此前自己按 `provider === "anthropic"` / `api === "anthropic-messages"`
|
|
21
21
|
* 字面判线 ⇒ 在 `MODEL_PROVIDER=anthropic` 而只配了网关的部署上,主请求去网关、标题与 hooks 的 llm 面却要找一条没装的
|
|
22
22
|
* anthropic 路由,整条拒发(零请求,只落 fail-open 标签)。现在本面只问那一只判词,不留第二个读法 —— 含 `api` 词:
|
|
23
23
|
* 引擎不按 `api` 选线(core 的 `createRoutingBrain` 缺省按 `provider` 键),settings-schema 的 `ModelEntry` 又强制两个词同真同假。
|
|
24
|
-
* (core
|
|
25
|
-
* `dispatchBrainLane`
|
|
24
|
+
* (S-1630 的 (a) 路已兑现:core 7.53.0 #1842 根导出了那只判官 `brainLaneOf(model, routes)` —— `createRoutingBrain` 对每个请求问的就是它;
|
|
25
|
+
* 本仓自写的合取 `dispatchBrainLane` 随之退役,本调用点与另三处一并改问它。)
|
|
26
26
|
*/
|
|
27
27
|
export type HookModelPick = {
|
|
28
28
|
ok: true;
|
|
@@ -30,9 +30,12 @@ export type HookModelPick = {
|
|
|
30
30
|
providerModelId: string;
|
|
31
31
|
baseUrl: string;
|
|
32
32
|
api: "openai-completions" | "anthropic-messages";
|
|
33
|
-
}
|
|
33
|
+
}
|
|
34
|
+
/** 选不出来的那一臂自带失败码(S-1635):两个载体(prompt 直连 / agent 子代理)共用这一只选模闸,同一只判词同一个码。 */
|
|
35
|
+
| {
|
|
34
36
|
ok: false;
|
|
35
37
|
error: string;
|
|
38
|
+
code: Extract<HookLlmFailureCode, "model_unresolved">;
|
|
36
39
|
};
|
|
37
40
|
/**
|
|
38
41
|
* 🔴 **hook 失败展示文本的唯一铸点**(S-494;`build*` = 返回纯数据的一只纯函数)。
|
package/dist/hooks/hook-llm.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { admitRouteRequest, BrainError, joinRequestUrl, resolveRouteCredential, routeKeyOf } from "@sema-agent/core";
|
|
2
2
|
import { matchCatalogModel, refusedCatalogEntry, servedModelTableLeg } from "../model-select.js";
|
|
3
|
-
import { modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
3
|
+
import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
4
4
|
import { resolveOpenaiRouteEndpoint } from "../model-route-endpoint.js";
|
|
5
|
-
import {
|
|
5
|
+
import { anthropicRouteRoot, brainLaneFor, routeTableOf } from "../model-provider.js";
|
|
6
6
|
import { egressRedirectRefusal } from "../egress-redirect.js";
|
|
7
7
|
import { buildDisplaySafeRefusal, redactSecrets } from "../trace/redact.js";
|
|
8
|
+
const unresolvedPick = (error) => ({ ok: false, error, code: "model_unresolved" });
|
|
8
9
|
export function buildHookFailureText(raw) {
|
|
9
10
|
if (raw === "")
|
|
10
11
|
return raw;
|
|
@@ -15,68 +16,86 @@ export function buildHookFailureText(raw) {
|
|
|
15
16
|
return `[hook failure text withheld: redactor threw ${err instanceof Error ? err.name : typeof err}]`;
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
const ROUTE_REFUSAL_CODES = {
|
|
20
|
+
"route.credential_mismatch": true,
|
|
21
|
+
"route.credential_missing": true,
|
|
22
|
+
"route.credential_origin_mismatch": true,
|
|
23
|
+
"route.credential_answer_conflict": true,
|
|
24
|
+
};
|
|
25
|
+
const ROUTE_REFUSAL_LEAD = "[invalid_request] ";
|
|
26
|
+
function gateRefusal(pick, e, declaredRoot) {
|
|
27
|
+
const raw = e instanceof Error ? e.message : String(e);
|
|
28
|
+
const text = e instanceof BrainError && raw.startsWith(ROUTE_REFUSAL_LEAD) ? raw.slice(ROUTE_REFUSAL_LEAD.length) : raw;
|
|
29
|
+
const code = Object.keys(ROUTE_REFUSAL_CODES).find((c) => text.startsWith(`${c}:`)) ?? "unclassified";
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
code: "route_refused",
|
|
33
|
+
error: `hook model "${pick.catalogRef}" cannot be routed (${code}) — ` + buildDisplaySafeRefusal(text, [pick.baseUrl, declaredRoot ?? ""]),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
18
36
|
export function createHookLlm(deps) {
|
|
19
37
|
const { config, metrics } = deps;
|
|
20
|
-
const anthropicRouteBaseUrl = () => config.anthropic
|
|
21
|
-
const shapeFrom = (
|
|
22
|
-
const
|
|
38
|
+
const anthropicRouteBaseUrl = () => anthropicRouteRoot(config.anthropic ?? {});
|
|
39
|
+
const shapeFrom = (m, providerModelId = m.id) => {
|
|
40
|
+
const catalogRef = m.name;
|
|
41
|
+
const lane = brainLaneFor(m.provider, routeTableOf(config));
|
|
23
42
|
switch (lane) {
|
|
24
43
|
case "anthropic":
|
|
25
|
-
return { ok: true, catalogRef, providerModelId, baseUrl: m
|
|
44
|
+
return { ok: true, catalogRef, providerModelId, baseUrl: m.baseUrl || anthropicRouteBaseUrl(), api: "anthropic-messages" };
|
|
26
45
|
case "gateway": {
|
|
27
46
|
const endpoint = resolveOpenaiRouteEndpoint(catalogRef, m, config.gatewayBaseUrl, servedModelTableLeg(config));
|
|
28
|
-
return endpoint.ok ? { ok: true, catalogRef, providerModelId, baseUrl: endpoint.baseUrl, api: "openai-completions" } :
|
|
47
|
+
return endpoint.ok ? { ok: true, catalogRef, providerModelId, baseUrl: endpoint.baseUrl, api: "openai-completions" } : unresolvedPick(endpoint.refusal);
|
|
29
48
|
}
|
|
30
49
|
}
|
|
31
50
|
};
|
|
32
51
|
const hookModelFor = (requested) => {
|
|
33
|
-
const
|
|
52
|
+
const ownEntry = (ref) => (Object.hasOwn(config.models, ref) ? config.models[ref] : undefined);
|
|
34
53
|
const unavailable = (field, ref) => {
|
|
35
|
-
if (
|
|
54
|
+
if (ownEntry(ref) !== undefined)
|
|
36
55
|
return undefined;
|
|
37
56
|
const hit = refusedCatalogEntry(ref, config.modelRefusals);
|
|
38
|
-
return hit === undefined ? undefined :
|
|
57
|
+
return hit === undefined ? undefined : unresolvedPick(modelUnavailableMessage(field, ref, hit.name, hit.refusal));
|
|
39
58
|
};
|
|
40
59
|
if (requested === undefined) {
|
|
41
60
|
const sum = config.roles.summarize;
|
|
42
61
|
const roleModel = typeof sum === "string" ? sum : sum && typeof sum === "object" && "model" in sum && typeof sum.model === "string" ? sum.model : undefined;
|
|
43
|
-
if (roleModel !== undefined)
|
|
44
|
-
|
|
45
|
-
|
|
62
|
+
if (roleModel !== undefined) {
|
|
63
|
+
const entry = ownEntry(roleModel);
|
|
64
|
+
return unavailable("summarize role model", roleModel) ?? (entry ? shapeFrom(entry) : shapeFrom(config.model, roleModel));
|
|
65
|
+
}
|
|
66
|
+
return shapeFrom(config.model);
|
|
46
67
|
}
|
|
47
|
-
|
|
48
|
-
|
|
68
|
+
const matchedKey = matchCatalogModel(requested, config.models, config.modelRefusals);
|
|
69
|
+
if (matchedKey !== undefined)
|
|
70
|
+
return shapeFrom(config.models[matchedKey]);
|
|
49
71
|
if (Object.hasOwn(config.modelRefusals ?? {}, requested))
|
|
50
72
|
return unavailable("hook model", requested);
|
|
51
|
-
const byId = matchCatalogModel(requested, config.models, config.modelRefusals);
|
|
52
|
-
if (byId !== undefined)
|
|
53
|
-
return shape(byId);
|
|
54
73
|
if (requested === config.model.id)
|
|
55
|
-
return shapeFrom(
|
|
56
|
-
return unavailable("hook model", requested) ??
|
|
74
|
+
return shapeFrom(config.model);
|
|
75
|
+
return unavailable("hook model", requested) ?? unresolvedPick(`hook model "${echoModelRef(requested)}" is not in this deployment's catalog`);
|
|
57
76
|
};
|
|
58
77
|
const judgeRoute = (pick, perModelKey, deploymentKey, declaredRoot) => {
|
|
59
78
|
const credential = resolveRouteCredential({
|
|
60
79
|
...(perModelKey !== undefined ? { optionsApiKey: perModelKey } : {}),
|
|
61
80
|
...(deploymentKey !== undefined ? { configApiKey: deploymentKey } : {}),
|
|
62
81
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ok: false,
|
|
67
|
-
error: `hook model "${pick.catalogRef}" cannot be routed (${verdict.code}) — ` +
|
|
68
|
-
buildDisplaySafeRefusal(routeRefusalText(verdict), [pick.baseUrl, declaredRoot ?? ""]),
|
|
69
|
-
};
|
|
82
|
+
let admission;
|
|
83
|
+
try {
|
|
84
|
+
admission = admitRouteRequest({ id: pick.catalogRef, baseUrl: pick.baseUrl }, credential, { ...(declaredRoot !== undefined ? { baseUrl: declaredRoot } : {}) });
|
|
70
85
|
}
|
|
71
|
-
|
|
86
|
+
catch (e) {
|
|
87
|
+
return gateRefusal(pick, e, declaredRoot);
|
|
88
|
+
}
|
|
89
|
+
if (credential.source === "absent" && routeKeyOf(pick.baseUrl) !== routeKeyOf(declaredRoot)) {
|
|
72
90
|
return {
|
|
73
91
|
ok: false,
|
|
92
|
+
code: "route_refused",
|
|
74
93
|
error: `hook model "${pick.catalogRef}" points at ${pick.baseUrl}, which this deployment did not declare as its own endpoint, ` +
|
|
75
94
|
`and no per-model credential resolved — refusing to send the prompt there (it embeds user content; an unauthenticated ` +
|
|
76
95
|
`request still hands that content to whoever operates that URL)`,
|
|
77
96
|
};
|
|
78
97
|
}
|
|
79
|
-
return { ok: true, credential };
|
|
98
|
+
return { ok: true, credential, admission };
|
|
80
99
|
};
|
|
81
100
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
82
101
|
const callLlm = async ({ prompt, model, timeoutMs, system, maxOutputTokens }) => {
|
|
@@ -85,6 +104,7 @@ export function createHookLlm(deps) {
|
|
|
85
104
|
return pick;
|
|
86
105
|
const ac = new AbortController();
|
|
87
106
|
const t = setTimeout(() => ac.abort(), timeoutMs);
|
|
107
|
+
let phase = "assemble";
|
|
88
108
|
try {
|
|
89
109
|
const keyResolver = deps.getKeyResolver();
|
|
90
110
|
let perModelKey;
|
|
@@ -93,17 +113,21 @@ export function createHookLlm(deps) {
|
|
|
93
113
|
perModelKey = (await keyResolver({ name: pick.catalogRef }))?.apiKey;
|
|
94
114
|
}
|
|
95
115
|
catch (e) {
|
|
96
|
-
return { ok: false, error: `per-model key resolution for "${pick.catalogRef}" failed — refusing to fall back to the shared route credential (${String(e)})
|
|
116
|
+
return { ok: false, error: `per-model key resolution for "${pick.catalogRef}" failed — refusing to fall back to the shared route credential (${String(e)})`, code: "credential_custody_failed" };
|
|
97
117
|
}
|
|
98
118
|
}
|
|
99
119
|
let url;
|
|
100
120
|
let headers;
|
|
101
121
|
let body;
|
|
122
|
+
let admitted;
|
|
123
|
+
let declaredRoot;
|
|
102
124
|
if (pick.api === "anthropic-messages") {
|
|
103
125
|
const routeBase = anthropicRouteBaseUrl();
|
|
126
|
+
declaredRoot = routeBase;
|
|
104
127
|
const routed = judgeRoute(pick, perModelKey, config.anthropic?.authToken ?? config.anthropic?.apiKey, routeBase);
|
|
105
128
|
if (!routed.ok)
|
|
106
129
|
return routed;
|
|
130
|
+
admitted = routed.admission;
|
|
107
131
|
url = joinRequestUrl(pick.baseUrl, "/v1/messages");
|
|
108
132
|
headers = {
|
|
109
133
|
"content-type": "application/json",
|
|
@@ -121,29 +145,47 @@ export function createHookLlm(deps) {
|
|
|
121
145
|
body = JSON.stringify({ model: pick.providerModelId, max_tokens: maxTokens, ...(system ? { system } : {}), messages: [{ role: "user", content: prompt }] });
|
|
122
146
|
}
|
|
123
147
|
else {
|
|
148
|
+
declaredRoot = config.gatewayBaseUrl;
|
|
124
149
|
const routed = judgeRoute(pick, perModelKey, config.gatewayApiKey, config.gatewayBaseUrl);
|
|
125
150
|
if (!routed.ok)
|
|
126
151
|
return routed;
|
|
152
|
+
admitted = routed.admission;
|
|
127
153
|
const hookKey = routed.credential.apiKey;
|
|
128
154
|
url = joinRequestUrl(pick.baseUrl, "/chat/completions");
|
|
129
155
|
headers = { "content-type": "application/json", ...(hookKey ? { authorization: `Bearer ${hookKey}` } : {}) };
|
|
130
156
|
body = JSON.stringify({ model: pick.providerModelId, ...(maxOutputTokens !== undefined ? { max_tokens: maxOutputTokens } : {}), messages: [...(system ? [{ role: "system", content: system }] : []), { role: "user", content: prompt }], stream: false });
|
|
131
157
|
}
|
|
158
|
+
try {
|
|
159
|
+
admitted();
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
return gateRefusal(pick, e, declaredRoot);
|
|
163
|
+
}
|
|
164
|
+
phase = "transport";
|
|
132
165
|
const r = await fetchImpl(url, { method: "POST", headers, body, signal: ac.signal, redirect: "manual" });
|
|
133
166
|
const redirected = egressRedirectRefusal(r, "declare the final endpoint as this route's base URL");
|
|
134
167
|
if (redirected !== undefined)
|
|
135
168
|
return { ok: false, error: `hook llm ${redirected}`, code: "redirect_refused" };
|
|
136
169
|
if (!r.ok)
|
|
137
|
-
return { ok: false, error: `hook llm HTTP ${r.status}
|
|
170
|
+
return { ok: false, error: `hook llm HTTP ${r.status}`, code: "bad_response" };
|
|
171
|
+
let answered;
|
|
172
|
+
try {
|
|
173
|
+
answered = await r.json();
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
if (ac.signal.aborted || e?.name !== "SyntaxError")
|
|
177
|
+
throw e;
|
|
178
|
+
return { ok: false, error: "hook llm answered with a body that is not JSON", code: "bad_response" };
|
|
179
|
+
}
|
|
138
180
|
let text;
|
|
139
181
|
if (pick.api === "anthropic-messages") {
|
|
140
|
-
const j =
|
|
141
|
-
const parts = (Array.isArray(j
|
|
182
|
+
const j = answered;
|
|
183
|
+
const parts = (Array.isArray(j?.content) ? j.content : []).filter((b) => b?.type === "text" && typeof b.text === "string").map((b) => b.text);
|
|
142
184
|
text = parts.length > 0 ? parts.join("") : undefined;
|
|
143
185
|
}
|
|
144
186
|
else {
|
|
145
|
-
const j =
|
|
146
|
-
text = j
|
|
187
|
+
const j = answered;
|
|
188
|
+
text = j?.choices?.[0]?.message?.content ?? undefined;
|
|
147
189
|
}
|
|
148
190
|
metrics.inc("hook_llm_calls_total", { type: "prompt" });
|
|
149
191
|
return typeof text === "string" ? { ok: true, text } : { ok: false, error: "hook llm returned no content", code: "no_content" };
|
|
@@ -153,6 +195,7 @@ export function createHookLlm(deps) {
|
|
|
153
195
|
return {
|
|
154
196
|
ok: false,
|
|
155
197
|
error: ac.signal.aborted ? "hook llm timeout" : `hook llm request to ${pick.baseUrl} failed: ${String(e)}${cause ? ` (${String(cause)})` : ""}`,
|
|
198
|
+
code: ac.signal.aborted || phase === "transport" ? "unreachable" : "route_refused",
|
|
156
199
|
};
|
|
157
200
|
}
|
|
158
201
|
finally {
|