@sema-agent/server 7.132.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 +266 -0
- package/README.md +8 -9
- package/README.zh-CN.md +7 -6
- package/USAGE.md +174 -55
- 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 +79 -19
- package/dist/approval-card.js +44 -13
- 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 +27 -10
- package/dist/audit.js +12 -16
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/execution-env.js +9 -7
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- 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/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +3 -0
- package/dist/boot/resolve-spec.js +60 -81
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-06-runners.d.ts +2 -0
- package/dist/boot/stage-06-runners.js +6 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -0
- package/dist/boot/stage-07-capability-layer.js +24 -3
- package/dist/boot/stage-08-reapers.d.ts +2 -0
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +3 -0
- package/dist/boot/stage-10-http-server.d.ts +3 -0
- package/dist/boot/stage-10-http-server.js +5 -6
- package/dist/boot/stores.js +2 -2
- package/dist/boot/web-admin.d.ts +4 -0
- package/dist/boot/web-admin.js +151 -63
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +8 -3
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/caller-text-echo.d.ts +9 -6
- package/dist/caller-text-echo.js +8 -11
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +21 -0
- package/dist/capabilities/hands-lane.js +10 -0
- package/dist/capabilities/mcp-probe.d.ts +36 -4
- package/dist/capabilities/mcp-probe.js +27 -4
- package/dist/capabilities/scenarios.d.ts +63 -7
- package/dist/capabilities/scenarios.js +39 -7
- 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 +43 -28
- 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-provider.d.ts +6 -1
- package/dist/config-provider.js +6 -2
- package/dist/config-types.d.ts +71 -14
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +121 -59
- 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 -23
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/execution-lane-caps.d.ts +49 -10
- package/dist/execution-lane-caps.js +43 -4
- 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 +10 -5
- package/dist/hooks/classic-stations.js +4 -4
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.js +2 -2
- package/dist/hooks/hook-runner.d.ts +127 -25
- package/dist/hooks/hook-runner.js +668 -287
- 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.js +103 -60
- package/dist/http/approval-sweeps.js +55 -18
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +16 -16
- package/dist/http/checkpoint-ctx.js +13 -10
- package/dist/http/claimed-run.d.ts +4 -3
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +2 -1
- package/dist/http/dispatch.js +10 -4
- package/dist/http/durable-run-leg.d.ts +4 -32
- package/dist/http/durable-run-leg.js +34 -10
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +48 -23
- package/dist/http/principal-gate.js +39 -12
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/request-guards.d.ts +16 -23
- package/dist/http/request-guards.js +30 -15
- 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 +3 -4
- package/dist/http/resume-legs.js +126 -69
- 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 +20 -4
- 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 +5 -1
- 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 +33 -106
- package/dist/http/routes/session-sync.js +15 -28
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/side-query.js +6 -4
- package/dist/http/routes/tasks.js +50 -14
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +24 -3
- package/dist/http/send.js +14 -2
- package/dist/http/server.d.ts +17 -18
- package/dist/http/server.js +15 -13
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.js +4 -3
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +10 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/lane-home-probe.d.ts +78 -9
- package/dist/lane-home-probe.js +78 -12
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +17 -5
- package/dist/limit-refusal.js +4 -1
- package/dist/mcp-assertion-header.d.ts +31 -10
- package/dist/mcp-assertion-header.js +10 -3
- package/dist/mcp-tool-faces.js +1 -3
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +23 -16
- 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 +5 -0
- package/dist/model-provider.js +4 -2
- package/dist/model-route-endpoint.d.ts +8 -11
- package/dist/model-route-endpoint.js +4 -7
- 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/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +35 -9
- package/dist/observability/fail-open.js +35 -9
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/prompt-manifest.d.ts +3 -17
- package/dist/observability/prompt-manifest.js +45 -42
- package/dist/observability/tool-trace.js +9 -9
- 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/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- 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 +38 -25
- package/dist/plugins/blob-backend.js +29 -19
- 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 +14 -0
- package/dist/plugins/checkpoint-store-sql.js +20 -2
- 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/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +6 -1
- package/dist/plugins/local-session-store.d.ts +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 +110 -5
- package/dist/plugins/one-time-migrations.js +320 -8
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +17 -4
- package/dist/plugins/pg-session-storage.js +29 -6
- package/dist/plugins/remote-env-adb.d.ts +6 -12
- package/dist/plugins/remote-env-adb.js +12 -2
- package/dist/plugins/remote-env-k8s.d.ts +8 -12
- package/dist/plugins/remote-env-k8s.js +23 -5
- package/dist/plugins/remote-env-local-docker.d.ts +10 -15
- package/dist/plugins/remote-env-local-docker.js +12 -9
- package/dist/plugins/remote-env-ssh.d.ts +10 -16
- package/dist/plugins/remote-env-ssh.js +17 -11
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- 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 +32 -6
- package/dist/plugins/session-epoch-anchor.js +2 -3
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/sql-driver.d.ts +74 -11
- package/dist/plugins/sql-driver.js +210 -12
- package/dist/plugins/sql-errors.d.ts +23 -0
- package/dist/plugins/sql-errors.js +21 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +40 -14
- 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 +3 -2
- package/dist/plugins/tidb-session-storage.js +2 -2
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +28 -4
- 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/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 +7 -0
- package/dist/request-key-closure.js +9 -1
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +26 -2
- package/dist/rule-entry-list.js +72 -12
- 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 +36 -6
- package/dist/runs.d.ts +10 -9
- package/dist/runs.js +21 -3
- 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/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- 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 +15 -4
- package/dist/spec-fields.js +21 -2
- package/dist/sql-engine-posture.d.ts +3 -1
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +3 -3
- package/dist/task-mcp.js +7 -66
- package/dist/task-settings.d.ts +89 -88
- package/dist/task-settings.js +71 -63
- package/dist/text-bidi.d.ts +0 -4
- package/dist/text-bidi.js +1 -3
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +303 -87
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +104 -22
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +3 -2
- package/dist/trace/project.d.ts +80 -12
- package/dist/trace/project.js +41 -28
- 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 +298 -2
- package/dist/trace/wire-projection-faces.js +154 -13
- 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/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/skills-mcp.js +4 -5
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
- package/package.json +7 -3
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { sendJson, sendError
|
|
2
|
+
import { sendJson, sendError } from "../send.js";
|
|
3
3
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendUnauthorized } from "../principal-gate.js";
|
|
4
4
|
import { assertNever } from "../route-ctx.js";
|
|
5
5
|
import * as facts from "../../capability-facts.js";
|
|
6
6
|
import { createLogger } from "../../observability/logger.js";
|
|
7
7
|
import { RULE_IMPORT_RETRY_AFTER_SEC, RULE_SCOPE_REFUSAL_SENTENCE, MAX_RULE_SCOPE_CHARS, buildCcImportLayerRootRefusal, parseRuleScope, serializeRuleScope } from "../../rules-consent.js";
|
|
8
|
-
import {
|
|
9
|
-
import { HttpError } from "../../security.js";
|
|
8
|
+
import { hasControlOrBidi } from "@sema-agent/settings-schema";
|
|
10
9
|
import { MAX_RULE_TEXT_CHARS, RULE_BEHAVIORS, isValidDurableScope } from "@sema-agent/core";
|
|
11
10
|
import { PERSISTED_RULE_MATCHES, isPersistedRuleTool, isDirectWritableRuleBehavior } from "../../permission-rule-vocab.js";
|
|
12
11
|
const logger = createLogger();
|
|
@@ -37,8 +36,7 @@ const CcImportPrepareBodySchema = z
|
|
|
37
36
|
function ccImportRootRefused(layer) {
|
|
38
37
|
return !isValidDurableScope({ kind: "project", root: layer.root });
|
|
39
38
|
}
|
|
40
|
-
const
|
|
41
|
-
const TicketStringSchema = z.string().min(1).max(190).refine((t) => !TICKET_CONTROL_CHARS_RE.test(t));
|
|
39
|
+
const TicketStringSchema = z.string().min(1).max(190).refine((t) => !hasControlOrBidi(t));
|
|
42
40
|
const CcImportRedeemBodySchema = z.object({ ticket: TicketStringSchema }).strict();
|
|
43
41
|
const LocalImportAddSchema = z
|
|
44
42
|
.object({
|
|
@@ -107,18 +105,7 @@ export async function handleRules(req, res, match, ctx) {
|
|
|
107
105
|
await handleRuleList(res, match.search, principal, lane, deps.config);
|
|
108
106
|
return;
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
rawBody = await readJson(req);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
if (err instanceof HttpError && err.status !== 400) {
|
|
116
|
-
sendHttpError(res, err);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
sendError(res, 400, "request.body_shape", "body must be valid JSON");
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
108
|
+
const rawBody = await readJson(req);
|
|
122
109
|
if (match.decl.id === "rules-revoke") {
|
|
123
110
|
await handleRuleRevoke(res, rawBody, principal, lane, deps.config);
|
|
124
111
|
return;
|
|
@@ -216,7 +203,7 @@ function resolveTargetPrincipal(requested, caller, config) {
|
|
|
216
203
|
return { ok: true, principal: caller };
|
|
217
204
|
if (!facts.operatorLane({ config }).available)
|
|
218
205
|
return { ok: false, why: "operator_principals_empty" };
|
|
219
|
-
if (!explicitOperatorOk(caller, config
|
|
206
|
+
if (!explicitOperatorOk(caller, config))
|
|
220
207
|
return { ok: false, why: "not_operator" };
|
|
221
208
|
return { ok: true, principal: requested };
|
|
222
209
|
}
|
|
@@ -133,6 +133,11 @@ export declare const RUN_VERBS_ROUTES: readonly [{
|
|
|
133
133
|
readonly pattern: RegExp;
|
|
134
134
|
readonly label: "/v1/tool-approvals/:id/respond";
|
|
135
135
|
readonly methods: readonly ["POST"];
|
|
136
|
+
}, {
|
|
137
|
+
readonly id: "tool-approval-read";
|
|
138
|
+
readonly pattern: RegExp;
|
|
139
|
+
readonly label: "/v1/tool-approvals/:id";
|
|
140
|
+
readonly methods: readonly ["GET"];
|
|
136
141
|
}, {
|
|
137
142
|
readonly id: "task-ask-decision";
|
|
138
143
|
readonly pattern: RegExp;
|
package/dist/http/routes/runs.js
CHANGED
|
@@ -5,7 +5,7 @@ import { uuidv7, mintCheckpointToken, CheckpointError, policyCannotAnswer, valid
|
|
|
5
5
|
import { isTerminalRunStatus, isParkedRunStatus, runProvenElsewhere } from "../../plugins/store-contracts.js";
|
|
6
6
|
import { LIVE_RUN_GATE_KINDS, TERMINAL_PARK_GATE_KINDS } from "../../plugins/checkpoint-store-sql.js";
|
|
7
7
|
import { redactSecrets } from "../../trace/redact.js";
|
|
8
|
-
import {
|
|
8
|
+
import { isUuidV7, encodeCheckpointScope } from "../../security.js";
|
|
9
9
|
import { redactSteerIn, STEER_IN_MAX_CHARS, STEER_IN_MAX_REQUEST_CHARS } from "../../orchestration/workflow-agent-steer.js";
|
|
10
10
|
import { defaultSubagentTailBus } from "../../fleet/subagent-tail-bus.js";
|
|
11
11
|
import { idemCallerOf, idemKeyOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
|
|
@@ -14,10 +14,10 @@ import { bindSseLifecycle } from "../sse-lifecycle.js";
|
|
|
14
14
|
import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSeat, storedCardDemandsAPerson } from "../../approval-card.js";
|
|
15
15
|
import { heldAskOf, liveSettledBy, readDecidedBy, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, DECIDED_BY_OUTSIDE_CLOSED_SET, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
|
|
16
16
|
import { ASK_DECISION_CONSUMER_ABSENT, outcomeOfDecidedRow, resolveStreamApprovalGate } from "../../tool-approval.js";
|
|
17
|
-
import { MAX_DECISION_NOTE_CHARS } from "../../approval-ask-machine.js";
|
|
17
|
+
import { MAX_DECISION_NOTE_CHARS, noteLandedOnRow, noteRecordedReceipt } from "../../approval-ask-machine.js";
|
|
18
18
|
import { causeOfAskRow } from "../../approval-deny-reasons.js";
|
|
19
19
|
import { normalizeRunEventType, screenedStoredEventData } from "../../trace/project.js";
|
|
20
|
-
import { sendJson, sendError, sendHttpError, sseHeaders } from "../send.js";
|
|
20
|
+
import { invalidJsonError, sendJson, sendError, sendHttpError, sseHeaders } from "../send.js";
|
|
21
21
|
import { mintCancelledResult } from "../../run-cancel-context.js";
|
|
22
22
|
import { acceptedInputKindOf } from "../../user-input-ledger.js";
|
|
23
23
|
import { INJECTION_TIERS } from "../../trace/injection-tier.js";
|
|
@@ -35,6 +35,7 @@ import { storedBodyReplayAnswer, storedBodyReplayLogFields } from "../checkpoint
|
|
|
35
35
|
import { serviceVersion } from "../../service-version.js";
|
|
36
36
|
import { storedBodyReplayRefusal } from "../stored-body-replay.js";
|
|
37
37
|
import { steerBodyKeyIssue } from "../../request-key-closure.js";
|
|
38
|
+
import { fieldConflictFacts } from "../../field-conflict.js";
|
|
38
39
|
const STEER_PRIORITY_WORDS = INJECTION_TIERS.map((tier) => `'${tier}'`);
|
|
39
40
|
const STEER_PRIORITY_UNION = STEER_PRIORITY_WORDS.join(" | ");
|
|
40
41
|
const STEER_PRIORITY_CHOICES = STEER_PRIORITY_WORDS.length <= 2 ? STEER_PRIORITY_WORDS.join(" or ") : `${STEER_PRIORITY_WORDS.slice(0, -1).join(", ")}, or ${STEER_PRIORITY_WORDS[STEER_PRIORITY_WORDS.length - 1]}`;
|
|
@@ -81,7 +82,7 @@ async function subagentReadGate(req, res, ctx, runId, search) {
|
|
|
81
82
|
sendPrincipalRefusal(res, req, deps.config);
|
|
82
83
|
return null;
|
|
83
84
|
}
|
|
84
|
-
const trusted = explicitOperatorOk(principal, deps.config
|
|
85
|
+
const trusted = explicitOperatorOk(principal, deps.config);
|
|
85
86
|
const run = await deps.runStore.getRun(runId);
|
|
86
87
|
if (!run) {
|
|
87
88
|
sendError(res, 404, "not_found.run", RUN_NOT_FOUND_MESSAGE);
|
|
@@ -399,18 +400,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
399
400
|
return;
|
|
400
401
|
}
|
|
401
402
|
const taskId = match.params.taskId;
|
|
402
|
-
|
|
403
|
-
try {
|
|
404
|
-
body = ((await readJson(req)) ?? {});
|
|
405
|
-
}
|
|
406
|
-
catch (e) {
|
|
407
|
-
if (e instanceof HttpError) {
|
|
408
|
-
sendHttpError(res, e);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
403
|
+
const body = ((await readJson(req)) ?? {});
|
|
414
404
|
if (typeof body.text !== "string" || body.text.length === 0) {
|
|
415
405
|
sendError(res, 400, "request.body_shape", `body must be { text: string (non-empty), mode?: 'all' | 'one-at-a-time', priority?: ${STEER_PRIORITY_UNION} }`);
|
|
416
406
|
return;
|
|
@@ -435,7 +425,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
435
425
|
const steerIdemRaw = headerStr(req.headers["idempotency-key"]);
|
|
436
426
|
const steerInputId = steerIdemRaw ? `idem-${idemKeyOf(steerIdemRaw, idemCallerOf(req, ctx), "run").slice(0, 32)}` : undefined;
|
|
437
427
|
const messageId = steerInputId ?? uuidv7();
|
|
438
|
-
const trusted = explicitOperatorOk(principal, deps.config
|
|
428
|
+
const trusted = explicitOperatorOk(principal, deps.config);
|
|
439
429
|
const steerInput = () => ({
|
|
440
430
|
text,
|
|
441
431
|
trusted,
|
|
@@ -724,18 +714,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
724
714
|
return;
|
|
725
715
|
}
|
|
726
716
|
const taskId = match.params.taskId;
|
|
727
|
-
|
|
728
|
-
try {
|
|
729
|
-
interruptRaw = await readJson(req);
|
|
730
|
-
}
|
|
731
|
-
catch (e) {
|
|
732
|
-
if (e instanceof HttpError) {
|
|
733
|
-
sendHttpError(res, e);
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
717
|
+
const interruptRaw = await readJson(req);
|
|
739
718
|
const interruptNormalized = interruptRaw === null || interruptRaw === undefined ? {} : interruptRaw;
|
|
740
719
|
if (typeof interruptNormalized !== "object" || Array.isArray(interruptNormalized)) {
|
|
741
720
|
sendError(res, 400, "request.body_shape", "body must be {} (bare halt: cut the in-flight turn and stop the run at this boundary) or { text: string (non-empty) } (cut + steer: the text reaches the model after the cut)");
|
|
@@ -759,7 +738,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
759
738
|
const interruptIdemRaw = headerStr(req.headers["idempotency-key"]);
|
|
760
739
|
const interruptInputId = interruptIdemRaw ? `idem-${idemKeyOf(interruptIdemRaw, idemCallerOf(req, ctx), "run").slice(0, 32)}` : uuidv7();
|
|
761
740
|
const interruptMessageId = interruptInputId;
|
|
762
|
-
const trusted = explicitOperatorOk(principal, deps.config
|
|
741
|
+
const trusted = explicitOperatorOk(principal, deps.config);
|
|
763
742
|
if (!interruptBare) {
|
|
764
743
|
try {
|
|
765
744
|
validatePendingSteer({ text, trusted, inputId: interruptInputId });
|
|
@@ -877,28 +856,17 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
877
856
|
sendError(res, 404, "not_found.run", RUN_NOT_FOUND_MESSAGE);
|
|
878
857
|
return;
|
|
879
858
|
}
|
|
880
|
-
const operator = explicitOperatorOk(principal, deps.config
|
|
859
|
+
const operator = explicitOperatorOk(principal, deps.config);
|
|
881
860
|
if (!operator && !runOwnerOk(req, res, run.owner))
|
|
882
861
|
return;
|
|
883
862
|
if (!runSessionAcceptOk(req, res, run, "run.compact"))
|
|
884
863
|
return;
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
if (parsed === null || typeof parsed !== "object") {
|
|
889
|
-
sendError(res, 400, "request.invalid_json", "body must be a JSON object when present");
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
compactBody = parsed;
|
|
893
|
-
}
|
|
894
|
-
catch (e) {
|
|
895
|
-
if (e instanceof HttpError) {
|
|
896
|
-
sendHttpError(res, e);
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
864
|
+
const parsed = await readJson(req);
|
|
865
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
866
|
+
sendHttpError(res, invalidJsonError("not_object"));
|
|
900
867
|
return;
|
|
901
868
|
}
|
|
869
|
+
const compactBody = parsed;
|
|
902
870
|
if (compactBody.instructions !== undefined && (typeof compactBody.instructions !== "string" || compactBody.instructions.length === 0 || [...compactBody.instructions].length > 2_048)) {
|
|
903
871
|
sendError(res, 400, "request.field_invalid", "instructions must be a non-empty string of at most 2048 characters (code points) when present — the engine caps compaction instructions there");
|
|
904
872
|
return;
|
|
@@ -938,18 +906,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
938
906
|
return;
|
|
939
907
|
}
|
|
940
908
|
const taskId = match.params.taskId;
|
|
941
|
-
|
|
942
|
-
try {
|
|
943
|
-
body = ((await readJson(req)) ?? {});
|
|
944
|
-
}
|
|
945
|
-
catch (e) {
|
|
946
|
-
if (e instanceof HttpError) {
|
|
947
|
-
sendHttpError(res, e);
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
951
|
-
return;
|
|
952
|
-
}
|
|
909
|
+
const body = ((await readJson(req)) ?? {});
|
|
953
910
|
if (typeof body.toolCallId !== "string" || body.toolCallId.length === 0 || body.toolCallId.length > 256) {
|
|
954
911
|
sendError(res, 400, "request.body_shape", "body must be { toolCallId: string (non-empty, ≤256 chars) }");
|
|
955
912
|
return;
|
|
@@ -959,7 +916,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
959
916
|
sendError(res, 404, "not_found.run", RUN_NOT_FOUND_MESSAGE);
|
|
960
917
|
return;
|
|
961
918
|
}
|
|
962
|
-
const operator = explicitOperatorOk(principal, deps.config
|
|
919
|
+
const operator = explicitOperatorOk(principal, deps.config);
|
|
963
920
|
if (!operator && !runOwnerOk(req, res, run.owner))
|
|
964
921
|
return;
|
|
965
922
|
if (!runSessionAcceptOk(req, res, run, "run.detach"))
|
|
@@ -1164,18 +1121,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1164
1121
|
sendError(res, 400, "request.path_malformed", "malformed subagent path (invalid percent-encoding)");
|
|
1165
1122
|
return;
|
|
1166
1123
|
}
|
|
1167
|
-
|
|
1168
|
-
try {
|
|
1169
|
-
body = ((await readJson(req)) ?? {});
|
|
1170
|
-
}
|
|
1171
|
-
catch (e) {
|
|
1172
|
-
if (e instanceof HttpError) {
|
|
1173
|
-
sendHttpError(res, e);
|
|
1174
|
-
return;
|
|
1175
|
-
}
|
|
1176
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1124
|
+
const body = ((await readJson(req)) ?? {});
|
|
1179
1125
|
if (typeof body.content !== "string" || body.content.length === 0) {
|
|
1180
1126
|
sendError(res, 400, "request.body_shape", "body must be { content: string (non-empty) }");
|
|
1181
1127
|
return;
|
|
@@ -1191,7 +1137,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1191
1137
|
sendError(res, 413, "steer.content_too_large", `content exceeds ${STEER_IN_MAX_REQUEST_CHARS} characters (got ${body.content.length}); note only the first ${STEER_IN_MAX_CHARS} are delivered anyway`);
|
|
1192
1138
|
return;
|
|
1193
1139
|
}
|
|
1194
|
-
const trusted = explicitOperatorOk(principal, deps.config
|
|
1140
|
+
const trusted = explicitOperatorOk(principal, deps.config);
|
|
1195
1141
|
const run = await runStore.getRun(runId);
|
|
1196
1142
|
if (!run) {
|
|
1197
1143
|
sendError(res, 404, "not_found.run", RUN_NOT_FOUND_MESSAGE);
|
|
@@ -1274,14 +1220,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1274
1220
|
return;
|
|
1275
1221
|
}
|
|
1276
1222
|
const id = match.params.id;
|
|
1277
|
-
|
|
1278
|
-
try {
|
|
1279
|
-
body = await readJson(req);
|
|
1280
|
-
}
|
|
1281
|
-
catch {
|
|
1282
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1283
|
-
return;
|
|
1284
|
-
}
|
|
1223
|
+
const body = await readJson(req);
|
|
1285
1224
|
const { status, body: respBody } = elicitFact.coordinator.respond(id, principal, body);
|
|
1286
1225
|
sendJson(res, status, respBody);
|
|
1287
1226
|
return;
|
|
@@ -1300,19 +1239,12 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1300
1239
|
return;
|
|
1301
1240
|
}
|
|
1302
1241
|
const id = match.params.id;
|
|
1303
|
-
|
|
1304
|
-
try {
|
|
1305
|
-
body = await readJson(req);
|
|
1306
|
-
}
|
|
1307
|
-
catch {
|
|
1308
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1309
|
-
return;
|
|
1310
|
-
}
|
|
1242
|
+
const body = await readJson(req);
|
|
1311
1243
|
const { status, body: respBody } = questionFact.coordinator.respond(id, principal, body);
|
|
1312
1244
|
sendJson(res, status, respBody);
|
|
1313
1245
|
return;
|
|
1314
1246
|
}
|
|
1315
|
-
if (match.decl.id === "tool-approval-respond") {
|
|
1247
|
+
if (match.decl.id === "tool-approval-respond" || match.decl.id === "tool-approval-read") {
|
|
1316
1248
|
if (rateLimited(req, res))
|
|
1317
1249
|
return;
|
|
1318
1250
|
const approvalFact = facts.toolApproval(deps);
|
|
@@ -1326,15 +1258,13 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1326
1258
|
return;
|
|
1327
1259
|
}
|
|
1328
1260
|
const id = match.params.id;
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1333
|
-
catch {
|
|
1334
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1261
|
+
if (match.decl.id === "tool-approval-read") {
|
|
1262
|
+
const { status, body: respBody } = await approvalFact.coordinator.readApproval(id, principal);
|
|
1263
|
+
sendJson(res, status, respBody);
|
|
1335
1264
|
return;
|
|
1336
1265
|
}
|
|
1337
|
-
const
|
|
1266
|
+
const body = await readJson(req);
|
|
1267
|
+
const { status, body: respBody } = await approvalFact.coordinator.respond(id, principal, body, req, { readRootGrantAccepted: facts.readRootGrant(deps).available });
|
|
1338
1268
|
const retryAfterSec = respBody.retryAfterSec;
|
|
1339
1269
|
if (typeof retryAfterSec === "number" && Number.isFinite(retryAfterSec) && retryAfterSec >= 0) {
|
|
1340
1270
|
res.setHeader("retry-after", String(Math.ceil(retryAfterSec)));
|
|
@@ -1356,14 +1286,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1356
1286
|
sendPrincipalRefusal(res, req, deps.config);
|
|
1357
1287
|
return;
|
|
1358
1288
|
}
|
|
1359
|
-
|
|
1360
|
-
try {
|
|
1361
|
-
rawBody = await readJson(req);
|
|
1362
|
-
}
|
|
1363
|
-
catch {
|
|
1364
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1289
|
+
const rawBody = await readJson(req);
|
|
1367
1290
|
const parsedBody = AskDecisionBodySchema.safeParse(rawBody);
|
|
1368
1291
|
if (!parsedBody.success) {
|
|
1369
1292
|
const retired = retiredDecisionKeyFacts(rawBody);
|
|
@@ -1401,7 +1324,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1401
1324
|
return;
|
|
1402
1325
|
}
|
|
1403
1326
|
const ownerOk = row0.owner === null || (principal !== undefined && row0.owner === principal);
|
|
1404
|
-
const operatorOk = explicitOperatorOk(principal, deps.config
|
|
1327
|
+
const operatorOk = explicitOperatorOk(principal, deps.config);
|
|
1405
1328
|
if (!ownerOk && !operatorOk) {
|
|
1406
1329
|
askNotFound();
|
|
1407
1330
|
return;
|
|
@@ -1440,6 +1363,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1440
1363
|
return true;
|
|
1441
1364
|
};
|
|
1442
1365
|
const decisionNoteEcho = (row) => (row.decisionNote === null ? {} : { decisionNote: row.decisionNote });
|
|
1366
|
+
const noteReceipt = (row) => noteRecordedReceipt(body.note, noteLandedOnRow(body.note, row.decisionNote));
|
|
1443
1367
|
const replayDecided = (row) => {
|
|
1444
1368
|
const storedActor = projectDecisionActor(row.decisionActor);
|
|
1445
1369
|
sendJson(res, 200, {
|
|
@@ -1449,6 +1373,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1449
1373
|
decidedAtMs: row.decidedAtMs,
|
|
1450
1374
|
...(storedActor ? { actor: storedActor } : {}),
|
|
1451
1375
|
...decisionNoteEcho(row),
|
|
1376
|
+
...noteReceipt(row),
|
|
1452
1377
|
});
|
|
1453
1378
|
};
|
|
1454
1379
|
const sendTerminal = (row) => {
|
|
@@ -1519,7 +1444,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1519
1444
|
return;
|
|
1520
1445
|
}
|
|
1521
1446
|
if (body.decision === "approve" && policyCannotAnswer(heldAskOf(storedCardDemandsAPerson(row0.cardJson)), decidedBy)) {
|
|
1522
|
-
sendError(res, 400, "request.field_conflict", POLICY_CANNOT_ALLOW_PERSON_ASK);
|
|
1447
|
+
sendError(res, 400, "request.field_conflict", POLICY_CANNOT_ALLOW_PERSON_ASK, fieldConflictFacts("policy_person_ask", ["decidedBy", "decision"]));
|
|
1523
1448
|
return;
|
|
1524
1449
|
}
|
|
1525
1450
|
let outcome;
|
|
@@ -1606,6 +1531,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1606
1531
|
...(forwarded ? { updatedInputForwarded: true } : {}),
|
|
1607
1532
|
...(settled === 0 ? { consumerState: ASK_DECISION_CONSUMER_ABSENT } : {}),
|
|
1608
1533
|
...decisionNoteEcho(outcome.row),
|
|
1534
|
+
...noteReceipt(outcome.row),
|
|
1609
1535
|
});
|
|
1610
1536
|
return;
|
|
1611
1537
|
}
|
|
@@ -1675,6 +1601,7 @@ export const RUN_VERBS_ROUTES = [
|
|
|
1675
1601
|
{ id: "elicitation-respond", pattern: /^\/v1\/elicitations\/(?<id>[^/]+)\/respond$/, label: "/v1/elicitations/:id/respond", methods: ["POST"] },
|
|
1676
1602
|
{ id: "question-respond", pattern: /^\/v1\/questions\/(?<id>[^/]+)\/respond$/, label: "/v1/questions/:id/respond", methods: ["POST"] },
|
|
1677
1603
|
{ id: "tool-approval-respond", pattern: /^\/v1\/tool-approvals\/(?<id>[^/]+)\/respond$/, label: "/v1/tool-approvals/:id/respond", methods: ["POST"] },
|
|
1604
|
+
{ id: "tool-approval-read", pattern: /^\/v1\/tool-approvals\/(?<id>[^/]+)$/, label: "/v1/tool-approvals/:id", methods: ["GET"] },
|
|
1678
1605
|
{ id: "task-ask-decision", pattern: /^\/v1\/tasks\/(?<taskId>[^/]+)\/asks\/(?<askId>[^/]+)\/decision$/, label: "/v1/tasks/:id/asks/:askId/decision", methods: ["POST"] },
|
|
1679
1606
|
];
|
|
1680
1607
|
//# sourceMappingURL=runs.js.map
|
|
@@ -6,8 +6,7 @@ import { exportSessionManifest, fileHistoryImportFace, replayFileHistory, replay
|
|
|
6
6
|
import * as facts from "../../capability-facts.js";
|
|
7
7
|
import { classifySyncRelationshipByIds, SyncConflictError } from "../../session-sync-kernel.js";
|
|
8
8
|
import { isUuidShape } from "../../security.js";
|
|
9
|
-
import {
|
|
10
|
-
import { sendJson, sendError, sendSessionError, sendSessionPolicyError, msg } from "../send.js";
|
|
9
|
+
import { sendJson, sendError, sendSessionError, sendSessionPolicyError, logRequestError, msg } from "../send.js";
|
|
11
10
|
import { buildDisplaySafeUrl } from "../../trace/redact.js";
|
|
12
11
|
import { gatedPrincipal, explicitOperatorOk, sendUnauthorized } from "../principal-gate.js";
|
|
13
12
|
const SYNC_BLOB_MAX_BYTES = 64 * 1024 * 1024;
|
|
@@ -187,17 +186,16 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
187
186
|
}
|
|
188
187
|
const fs = blobs.historyStore;
|
|
189
188
|
const body = await readRawBody(req, SYNC_BLOB_MAX_BYTES);
|
|
190
|
-
const sqlCap = deps.snapshotBlobSqlCap?.();
|
|
191
|
-
if (sqlCap !== undefined && body.byteLength > sqlCap.capBytes) {
|
|
192
|
-
sendError(res, 413, "blob_too_large_for_sql", sqlBlobCapRefusalText(body.byteLength, sqlCap), { wallSource: sqlCap.source });
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
189
|
if (createHash("sha256").update(body).digest("hex") !== hash) {
|
|
196
190
|
sendError(res, 400, "request.hash_mismatch", "blob hash mismatch");
|
|
197
191
|
return;
|
|
198
192
|
}
|
|
199
193
|
const put = await fs.putBlob(hash, new Uint8Array(body));
|
|
200
194
|
if (!put.ok) {
|
|
195
|
+
if (put.error.code === "blob_too_large_for_sql") {
|
|
196
|
+
sendError(res, 413, "blob_too_large_for_sql", put.error.message, { wallSource: put.error.wallSource });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
201
199
|
sendError(res, 502, put.error.code, "blob store write failed");
|
|
202
200
|
return;
|
|
203
201
|
}
|
|
@@ -216,14 +214,7 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
216
214
|
}
|
|
217
215
|
}).catch(() => { });
|
|
218
216
|
}
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
body = (await readJson(req));
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
217
|
+
const body = (await readJson(req));
|
|
227
218
|
if (!Array.isArray(body.entryIds) || !body.entryIds.every((x) => typeof x === "string")) {
|
|
228
219
|
sendError(res, 400, "request.field_invalid", "entryIds must be an array of strings");
|
|
229
220
|
return;
|
|
@@ -314,7 +305,7 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
314
305
|
return;
|
|
315
306
|
}
|
|
316
307
|
}
|
|
317
|
-
const opOk = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config
|
|
308
|
+
const opOk = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config);
|
|
318
309
|
if (deps.sessionPolicyStore) {
|
|
319
310
|
try {
|
|
320
311
|
await replayPolicyRecords(deps.sessionPolicyStore, sessionId, policy, opOk);
|
|
@@ -389,7 +380,7 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
389
380
|
}
|
|
390
381
|
}
|
|
391
382
|
const importingPrincipal = scope.fleetWide ? (owner ?? null) : scope.gateOwner;
|
|
392
|
-
const operatorOk = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config
|
|
383
|
+
const operatorOk = explicitOperatorOk(gatedPrincipal(req, deps.config), deps.config);
|
|
393
384
|
const token = randomBytes(8).toString("hex");
|
|
394
385
|
const handle = sessionStorage.beginImportStaging(sessionId, token);
|
|
395
386
|
const stagingId = handle.stagingId;
|
|
@@ -532,15 +523,18 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
532
523
|
sendJson(res, 200, { relation: committed.relation });
|
|
533
524
|
}
|
|
534
525
|
catch (e) {
|
|
526
|
+
await pending.handle.abort().catch(() => undefined);
|
|
527
|
+
cleanupStaging(stagingId);
|
|
535
528
|
if (e instanceof SyncConflictError) {
|
|
536
|
-
await pending.handle.abort().catch(() => undefined);
|
|
537
|
-
cleanupStaging(stagingId);
|
|
538
529
|
sendError(res, 409, "conflict", "sync conflict", { relation: e.relation });
|
|
539
530
|
return;
|
|
540
531
|
}
|
|
541
|
-
cleanupStaging(stagingId);
|
|
542
532
|
if (sendSessionPolicyError(res, e))
|
|
543
533
|
return;
|
|
534
|
+
if (sendSessionError(res, e, "import")) {
|
|
535
|
+
logRequestError(deps.logger, req, e);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
544
538
|
throw e;
|
|
545
539
|
}
|
|
546
540
|
return;
|
|
@@ -548,14 +542,7 @@ export async function handleSessionSync(req, res, match, ctx) {
|
|
|
548
542
|
if (match.decl.id === "session-sync-plan") {
|
|
549
543
|
if (!pushGateOk())
|
|
550
544
|
return;
|
|
551
|
-
|
|
552
|
-
try {
|
|
553
|
-
body = (await readJson(req));
|
|
554
|
-
}
|
|
555
|
-
catch {
|
|
556
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
545
|
+
const body = (await readJson(req));
|
|
559
546
|
if (!Array.isArray(body.entryIds) || !body.entryIds.every((x) => typeof x === "string")) {
|
|
560
547
|
sendError(res, 400, "request.field_invalid", "entryIds must be an array of strings");
|
|
561
548
|
return;
|