@namzu/sdk 49.0.0 → 50.1.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/CHANGELOG.md +541 -0
- package/README.md +137 -125
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +1 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/examples/SupervisorAgent.js +1 -0
- package/dist/agents/examples/SupervisorAgent.js.map +1 -1
- package/dist/agents/runAgent.d.ts +2 -0
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +1 -0
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/authorization/shell-lexer.d.ts.map +1 -1
- package/dist/authorization/shell-lexer.js +16 -1
- package/dist/authorization/shell-lexer.js.map +1 -1
- package/dist/bridge/acp/permission.d.ts +8 -2
- package/dist/bridge/acp/permission.d.ts.map +1 -1
- package/dist/bridge/acp/permission.js +1 -0
- package/dist/bridge/acp/permission.js.map +1 -1
- package/dist/bridge/acp/server.d.ts +25 -1
- package/dist/bridge/acp/server.d.ts.map +1 -1
- package/dist/bridge/acp/server.js +205 -21
- package/dist/bridge/acp/server.js.map +1 -1
- package/dist/bridge/acp/tasks.d.ts +5 -0
- package/dist/bridge/acp/tasks.d.ts.map +1 -0
- package/dist/bridge/acp/tasks.js +19 -0
- package/dist/bridge/acp/tasks.js.map +1 -0
- package/dist/bridge/acp/update.d.ts.map +1 -1
- package/dist/bridge/acp/update.js +148 -13
- package/dist/bridge/acp/update.js.map +1 -1
- package/dist/config/runtime.d.ts +31 -31
- package/dist/connector/mcp/adapter.d.ts.map +1 -1
- package/dist/connector/mcp/adapter.js +11 -4
- package/dist/connector/mcp/adapter.js.map +1 -1
- package/dist/connector/mcp/client.d.ts.map +1 -1
- package/dist/connector/mcp/client.js +6 -3
- package/dist/connector/mcp/client.js.map +1 -1
- package/dist/constants/acp/index.d.ts +3 -0
- package/dist/constants/acp/index.d.ts.map +1 -1
- package/dist/constants/acp/index.js +3 -0
- package/dist/constants/acp/index.js.map +1 -1
- package/dist/contracts/a2a.d.ts +80 -80
- package/dist/contracts/schemas.d.ts +2 -2
- package/dist/contracts/session/schemas.d.ts +10 -10
- package/dist/manager/agent/lifecycle.d.ts +11 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +178 -3
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/plan/lifecycle.d.ts +7 -8
- package/dist/manager/plan/lifecycle.d.ts.map +1 -1
- package/dist/manager/plan/lifecycle.js +7 -8
- package/dist/manager/plan/lifecycle.js.map +1 -1
- package/dist/manager/resident/consumption.d.ts +8 -8
- package/dist/manager/resident/learning-cycle.d.ts +2 -2
- package/dist/manager/resident/learning-observation.d.ts +12 -12
- package/dist/manager/resident/learning.d.ts +82 -82
- package/dist/manager/resident/outbox.d.ts +8 -8
- package/dist/manager/resident/proposal.d.ts +2 -2
- package/dist/manager/resident/store.d.ts +10 -10
- package/dist/manager/session/attribution.d.ts +1 -0
- package/dist/manager/session/attribution.d.ts.map +1 -1
- package/dist/manager/session/attribution.js +9 -1
- package/dist/manager/session/attribution.js.map +1 -1
- package/dist/manager/session/streamed-message-identity.d.ts +6 -0
- package/dist/manager/session/streamed-message-identity.d.ts.map +1 -0
- package/dist/manager/session/streamed-message-identity.js +14 -0
- package/dist/manager/session/streamed-message-identity.js.map +1 -0
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +4 -3
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/pals/activity/causality.d.ts +23 -0
- package/dist/pals/activity/causality.d.ts.map +1 -0
- package/dist/pals/activity/causality.js +205 -0
- package/dist/pals/activity/causality.js.map +1 -0
- package/dist/pals/activity/projection.d.ts +5 -0
- package/dist/pals/activity/projection.d.ts.map +1 -0
- package/dist/pals/activity/projection.js +79 -0
- package/dist/pals/activity/projection.js.map +1 -0
- package/dist/pals/activity/source.d.ts +16 -0
- package/dist/pals/activity/source.d.ts.map +1 -0
- package/dist/pals/activity/source.js +235 -0
- package/dist/pals/activity/source.js.map +1 -0
- package/dist/pals/activity/subscription-policy.d.ts +38 -0
- package/dist/pals/activity/subscription-policy.d.ts.map +1 -0
- package/dist/pals/activity/subscription-policy.js +183 -0
- package/dist/pals/activity/subscription-policy.js.map +1 -0
- package/dist/pals/activity/subscription-schema.d.ts +353 -0
- package/dist/pals/activity/subscription-schema.d.ts.map +1 -0
- package/dist/pals/activity/subscription-schema.js +24 -0
- package/dist/pals/activity/subscription-schema.js.map +1 -0
- package/dist/pals/activity/subscription-store.d.ts +25 -0
- package/dist/pals/activity/subscription-store.d.ts.map +1 -0
- package/dist/pals/activity/subscription-store.js +152 -0
- package/dist/pals/activity/subscription-store.js.map +1 -0
- package/dist/pals/activity/subscription-types.d.ts +42 -0
- package/dist/pals/activity/subscription-types.d.ts.map +1 -0
- package/dist/pals/activity/subscription-types.js +2 -0
- package/dist/pals/activity/subscription-types.js.map +1 -0
- package/dist/pals/activity/subscriptions.d.ts +32 -0
- package/dist/pals/activity/subscriptions.d.ts.map +1 -0
- package/dist/pals/activity/subscriptions.js +151 -0
- package/dist/pals/activity/subscriptions.js.map +1 -0
- package/dist/pals/activity/types.d.ts +77 -0
- package/dist/pals/activity/types.d.ts.map +1 -0
- package/dist/pals/activity/types.js +2 -0
- package/dist/pals/activity/types.js.map +1 -0
- package/dist/pals/channels/ingress.d.ts +9 -0
- package/dist/pals/channels/ingress.d.ts.map +1 -0
- package/dist/pals/channels/ingress.js +131 -0
- package/dist/pals/channels/ingress.js.map +1 -0
- package/dist/pals/channels/routes.d.ts +20 -0
- package/dist/pals/channels/routes.d.ts.map +1 -0
- package/dist/pals/channels/routes.js +111 -0
- package/dist/pals/channels/routes.js.map +1 -0
- package/dist/pals/channels/routing.d.ts +37 -0
- package/dist/pals/channels/routing.d.ts.map +1 -0
- package/dist/pals/channels/routing.js +150 -0
- package/dist/pals/channels/routing.js.map +1 -0
- package/dist/pals/channels/schema.d.ts +234 -0
- package/dist/pals/channels/schema.d.ts.map +1 -0
- package/dist/pals/channels/schema.js +94 -0
- package/dist/pals/channels/schema.js.map +1 -0
- package/dist/pals/channels/types.d.ts +115 -0
- package/dist/pals/channels/types.d.ts.map +1 -0
- package/dist/pals/channels/types.js +2 -0
- package/dist/pals/channels/types.js.map +1 -0
- package/dist/pals/communication/broker.d.ts +8 -0
- package/dist/pals/communication/broker.d.ts.map +1 -0
- package/dist/pals/communication/broker.js +121 -0
- package/dist/pals/communication/broker.js.map +1 -0
- package/dist/pals/communication/dispatch.d.ts +4 -0
- package/dist/pals/communication/dispatch.d.ts.map +1 -0
- package/dist/pals/communication/dispatch.js +57 -0
- package/dist/pals/communication/dispatch.js.map +1 -0
- package/dist/pals/communication/inbound.d.ts +9 -0
- package/dist/pals/communication/inbound.d.ts.map +1 -0
- package/dist/pals/communication/inbound.js +155 -0
- package/dist/pals/communication/inbound.js.map +1 -0
- package/dist/pals/communication/ingress-dispatch.d.ts +5 -0
- package/dist/pals/communication/ingress-dispatch.d.ts.map +1 -0
- package/dist/pals/communication/ingress-dispatch.js +51 -0
- package/dist/pals/communication/ingress-dispatch.js.map +1 -0
- package/dist/pals/communication/ingress-inbound.d.ts +9 -0
- package/dist/pals/communication/ingress-inbound.d.ts.map +1 -0
- package/dist/pals/communication/ingress-inbound.js +222 -0
- package/dist/pals/communication/ingress-inbound.js.map +1 -0
- package/dist/pals/communication/ingress-schema.d.ts +7829 -0
- package/dist/pals/communication/ingress-schema.d.ts.map +1 -0
- package/dist/pals/communication/ingress-schema.js +479 -0
- package/dist/pals/communication/ingress-schema.js.map +1 -0
- package/dist/pals/communication/ingress-types.d.ts +187 -0
- package/dist/pals/communication/ingress-types.d.ts.map +1 -0
- package/dist/pals/communication/ingress-types.js +73 -0
- package/dist/pals/communication/ingress-types.js.map +1 -0
- package/dist/pals/communication/operator.d.ts +75 -0
- package/dist/pals/communication/operator.d.ts.map +1 -0
- package/dist/pals/communication/operator.js +217 -0
- package/dist/pals/communication/operator.js.map +1 -0
- package/dist/pals/communication/policy.d.ts +41 -0
- package/dist/pals/communication/policy.d.ts.map +1 -0
- package/dist/pals/communication/policy.js +138 -0
- package/dist/pals/communication/policy.js.map +1 -0
- package/dist/pals/communication/schema.d.ts +2000 -0
- package/dist/pals/communication/schema.d.ts.map +1 -0
- package/dist/pals/communication/schema.js +170 -0
- package/dist/pals/communication/schema.js.map +1 -0
- package/dist/pals/communication/store.d.ts +61 -0
- package/dist/pals/communication/store.d.ts.map +1 -0
- package/dist/pals/communication/store.js +450 -0
- package/dist/pals/communication/store.js.map +1 -0
- package/dist/pals/communication/tools.d.ts +23 -0
- package/dist/pals/communication/tools.d.ts.map +1 -0
- package/dist/pals/communication/tools.js +107 -0
- package/dist/pals/communication/tools.js.map +1 -0
- package/dist/pals/communication/types.d.ts +168 -0
- package/dist/pals/communication/types.d.ts.map +1 -0
- package/dist/pals/communication/types.js +24 -0
- package/dist/pals/communication/types.js.map +1 -0
- package/dist/pals/communication/verify.d.ts +22 -0
- package/dist/pals/communication/verify.d.ts.map +1 -0
- package/dist/pals/communication/verify.js +142 -0
- package/dist/pals/communication/verify.js.map +1 -0
- package/dist/pals/lifecycle.d.ts +37 -0
- package/dist/pals/lifecycle.d.ts.map +1 -0
- package/dist/pals/lifecycle.js +22 -0
- package/dist/pals/lifecycle.js.map +1 -0
- package/dist/pals/prompt.d.ts +30 -0
- package/dist/pals/prompt.d.ts.map +1 -0
- package/dist/pals/prompt.js +65 -0
- package/dist/pals/prompt.js.map +1 -0
- package/dist/pals/reference-images.d.ts +44 -0
- package/dist/pals/reference-images.d.ts.map +1 -0
- package/dist/pals/reference-images.js +248 -0
- package/dist/pals/reference-images.js.map +1 -0
- package/dist/pals/runtime.d.ts +46 -0
- package/dist/pals/runtime.d.ts.map +1 -0
- package/dist/pals/runtime.js +624 -0
- package/dist/pals/runtime.js.map +1 -0
- package/dist/pals/store.d.ts +26 -0
- package/dist/pals/store.d.ts.map +1 -0
- package/dist/pals/store.js +334 -0
- package/dist/pals/store.js.map +1 -0
- package/dist/pals/types.d.ts +145 -0
- package/dist/pals/types.d.ts.map +1 -0
- package/dist/pals/types.js +2 -0
- package/dist/pals/types.js.map +1 -0
- package/dist/peers/envelope.js +1 -1
- package/dist/peers/envelope.js.map +1 -1
- package/dist/peers/protocol.d.ts +83 -83
- package/dist/peers/record.d.ts +10 -10
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +7 -2
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/process/kill-tree.d.ts.map +1 -1
- package/dist/process/kill-tree.js +9 -1
- package/dist/process/kill-tree.js.map +1 -1
- package/dist/provider/errors.d.ts +19 -0
- package/dist/provider/errors.d.ts.map +1 -1
- package/dist/provider/errors.js +123 -2
- package/dist/provider/errors.js.map +1 -1
- package/dist/provider/strict-schema.d.ts +28 -0
- package/dist/provider/strict-schema.d.ts.map +1 -1
- package/dist/provider/strict-schema.js +86 -0
- package/dist/provider/strict-schema.js.map +1 -1
- package/dist/public-runtime.d.ts +42 -14
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +36 -8
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +8 -3
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +8 -3
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +27 -7
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/presentation.d.ts +1 -0
- package/dist/registry/tool/presentation.d.ts.map +1 -1
- package/dist/registry/tool/presentation.js +9 -7
- package/dist/registry/tool/presentation.js.map +1 -1
- package/dist/runtime/harness-session/index.d.ts +5 -0
- package/dist/runtime/harness-session/index.d.ts.map +1 -0
- package/dist/runtime/harness-session/index.js +928 -0
- package/dist/runtime/harness-session/index.js.map +1 -0
- package/dist/runtime/harness-session/journal.d.ts +37 -0
- package/dist/runtime/harness-session/journal.d.ts.map +1 -0
- package/dist/runtime/harness-session/journal.js +177 -0
- package/dist/runtime/harness-session/journal.js.map +1 -0
- package/dist/runtime/harness-session/saved-view.d.ts +8 -0
- package/dist/runtime/harness-session/saved-view.d.ts.map +1 -0
- package/dist/runtime/harness-session/saved-view.js +112 -0
- package/dist/runtime/harness-session/saved-view.js.map +1 -0
- package/dist/runtime/jobs/awaited-jobs.d.ts +2 -1
- package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
- package/dist/runtime/jobs/awaited-jobs.js +2 -1
- package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
- package/dist/runtime/jobs/registry.d.ts +56 -1
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +351 -34
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/abandon-turn.d.ts +12 -1
- package/dist/runtime/query/abandon-turn.d.ts.map +1 -1
- package/dist/runtime/query/abandon-turn.js +3 -1
- package/dist/runtime/query/abandon-turn.js.map +1 -1
- package/dist/runtime/query/checkpoint.d.ts +4 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +10 -0
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/durable-inbound.d.ts +5 -0
- package/dist/runtime/query/durable-inbound.d.ts.map +1 -0
- package/dist/runtime/query/durable-inbound.js +89 -0
- package/dist/runtime/query/durable-inbound.js.map +1 -0
- package/dist/runtime/query/events.d.ts +4 -0
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +22 -5
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.d.ts +5 -1
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +85 -13
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +41 -18
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +227 -114
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +3 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +21 -4
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +18 -6
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +144 -67
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.d.ts +9 -5
- package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.js +61 -6
- package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +4 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +99 -16
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/observation-context.d.ts +2 -2
- package/dist/runtime/query/observation-context.d.ts.map +1 -1
- package/dist/runtime/query/observation-context.js +20 -13
- package/dist/runtime/query/observation-context.js.map +1 -1
- package/dist/runtime/query/prepare-turn.js +2 -2
- package/dist/runtime/query/prepare-turn.js.map +1 -1
- package/dist/runtime/query/prompt-cache.d.ts +1 -0
- package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
- package/dist/runtime/query/prompt-cache.js +2 -0
- package/dist/runtime/query/prompt-cache.js.map +1 -1
- package/dist/runtime/query/prompt.d.ts +2 -0
- package/dist/runtime/query/prompt.d.ts.map +1 -1
- package/dist/runtime/query/prompt.js +23 -1
- package/dist/runtime/query/prompt.js.map +1 -1
- package/dist/runtime/query/repeat-call.d.ts +12 -3
- package/dist/runtime/query/repeat-call.d.ts.map +1 -1
- package/dist/runtime/query/repeat-call.js +33 -10
- package/dist/runtime/query/repeat-call.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts +5 -6
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +30 -3
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/resume-session.js +1 -1
- package/dist/runtime/query/resume-session.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +8 -1
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +6 -0
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/saved-presentation.d.ts +13 -0
- package/dist/runtime/query/saved-presentation.d.ts.map +1 -0
- package/dist/runtime/query/saved-presentation.js +63 -0
- package/dist/runtime/query/saved-presentation.js.map +1 -0
- package/dist/runtime/query/steering.d.ts +6 -9
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/tool-executions.d.ts +7 -3
- package/dist/runtime/query/tool-executions.d.ts.map +1 -1
- package/dist/runtime/query/tool-executions.js +89 -9
- package/dist/runtime/query/tool-executions.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +3 -1
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +3 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +25 -1
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +102 -8
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/scheduler/delegating.d.ts.map +1 -1
- package/dist/scheduler/delegating.js +5 -0
- package/dist/scheduler/delegating.js.map +1 -1
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +2 -0
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/summary/materialize.d.ts +10 -6
- package/dist/session/summary/materialize.d.ts.map +1 -1
- package/dist/session/summary/materialize.js +41 -8
- package/dist/session/summary/materialize.js.map +1 -1
- package/dist/store/budget/ledger.d.ts +9 -0
- package/dist/store/budget/ledger.d.ts.map +1 -1
- package/dist/store/budget/ledger.js +58 -6
- package/dist/store/budget/ledger.js.map +1 -1
- package/dist/store/evidence/index-page.d.ts +12 -12
- package/dist/store/evidence/source-text.d.ts +4 -4
- package/dist/store/session/disk.d.ts +9 -4
- package/dist/store/session/disk.d.ts.map +1 -1
- package/dist/store/session/disk.js +57 -11
- package/dist/store/session/disk.js.map +1 -1
- package/dist/store/session/memory.d.ts +5 -3
- package/dist/store/session/memory.d.ts.map +1 -1
- package/dist/store/session/memory.js +24 -7
- package/dist/store/session/memory.js.map +1 -1
- package/dist/store/session-log/core.d.ts +26 -6
- package/dist/store/session-log/core.d.ts.map +1 -1
- package/dist/store/session-log/core.js +61 -8
- package/dist/store/session-log/core.js.map +1 -1
- package/dist/store/session-log/disk.d.ts +2 -2
- package/dist/store/session-log/disk.d.ts.map +1 -1
- package/dist/store/session-log/disk.js +1 -0
- package/dist/store/session-log/disk.js.map +1 -1
- package/dist/store/session-log/fold.d.ts +7 -0
- package/dist/store/session-log/fold.d.ts.map +1 -1
- package/dist/store/session-log/fold.js +21 -0
- package/dist/store/session-log/fold.js.map +1 -1
- package/dist/store/session-log/index.d.ts +5 -3
- package/dist/store/session-log/index.d.ts.map +1 -1
- package/dist/store/session-log/index.js +3 -1
- package/dist/store/session-log/index.js.map +1 -1
- package/dist/store/session-log/memory.d.ts +1 -1
- package/dist/store/session-log/memory.d.ts.map +1 -1
- package/dist/store/session-log/memory.js +1 -0
- package/dist/store/session-log/memory.js.map +1 -1
- package/dist/store/session-log/spill.d.ts +10 -3
- package/dist/store/session-log/spill.d.ts.map +1 -1
- package/dist/store/session-log/spill.js +70 -5
- package/dist/store/session-log/spill.js.map +1 -1
- package/dist/store/session-log/structured-result.d.ts +21 -0
- package/dist/store/session-log/structured-result.d.ts.map +1 -0
- package/dist/store/session-log/structured-result.js +67 -0
- package/dist/store/session-log/structured-result.js.map +1 -0
- package/dist/store/task/disk.d.ts +11 -0
- package/dist/store/task/disk.d.ts.map +1 -1
- package/dist/store/task/disk.js +41 -2
- package/dist/store/task/disk.js.map +1 -1
- package/dist/store/task/memory.d.ts.map +1 -1
- package/dist/store/task/memory.js +15 -3
- package/dist/store/task/memory.js.map +1 -1
- package/dist/tools/admit-facts.d.ts +13 -0
- package/dist/tools/admit-facts.d.ts.map +1 -0
- package/dist/tools/admit-facts.js +142 -0
- package/dist/tools/admit-facts.js.map +1 -0
- package/dist/tools/builtins/bash.d.ts +4 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +108 -22
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/browser.d.ts +10 -10
- package/dist/tools/builtins/computer-use.d.ts +90 -90
- package/dist/tools/builtins/edit.d.ts +17 -0
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +46 -1
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/file-write-result.d.ts.map +1 -1
- package/dist/tools/builtins/file-write-result.js +13 -0
- package/dist/tools/builtins/file-write-result.js.map +1 -1
- package/dist/tools/builtins/glob.d.ts.map +1 -1
- package/dist/tools/builtins/glob.js +12 -0
- package/dist/tools/builtins/glob.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +14 -0
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/index.d.ts +2 -0
- package/dist/tools/builtins/index.d.ts.map +1 -1
- package/dist/tools/builtins/index.js +1 -0
- package/dist/tools/builtins/index.js.map +1 -1
- package/dist/tools/builtins/job.d.ts.map +1 -1
- package/dist/tools/builtins/job.js +4 -1
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/lsp.d.ts +2 -2
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +49 -0
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/view-image.d.ts +24 -0
- package/dist/tools/builtins/view-image.d.ts.map +1 -0
- package/dist/tools/builtins/view-image.js +385 -0
- package/dist/tools/builtins/view-image.js.map +1 -0
- package/dist/tools/builtins/wait-for-job-bounds.d.ts +2 -0
- package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
- package/dist/tools/builtins/wait-for-job-bounds.js +1 -0
- package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
- package/dist/tools/builtins/wait-for-job.d.ts +2 -0
- package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
- package/dist/tools/builtins/wait-for-job.js +104 -6
- package/dist/tools/builtins/wait-for-job.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +1 -0
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/command-shell.d.ts +37 -2
- package/dist/tools/command-shell.d.ts.map +1 -1
- package/dist/tools/command-shell.js +100 -3
- package/dist/tools/command-shell.js.map +1 -1
- package/dist/tools/coordinator/agent.d.ts +9 -19
- package/dist/tools/coordinator/agent.d.ts.map +1 -1
- package/dist/tools/coordinator/agent.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +127 -67
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/coordinator/wait-with-idle-bound.d.ts +2 -0
- package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
- package/dist/tools/coordinator/wait-with-idle-bound.js +1 -1
- package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +4 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/failure-facts.d.ts +8 -0
- package/dist/tools/failure-facts.d.ts.map +1 -0
- package/dist/tools/failure-facts.js +24 -0
- package/dist/tools/failure-facts.js.map +1 -0
- package/dist/tools/host-output.d.ts +24 -0
- package/dist/tools/host-output.d.ts.map +1 -0
- package/dist/tools/host-output.js +117 -0
- package/dist/tools/host-output.js.map +1 -0
- package/dist/tools/oem-code-pages.d.ts +8 -0
- package/dist/tools/oem-code-pages.d.ts.map +1 -0
- package/dist/tools/oem-code-pages.js +23 -0
- package/dist/tools/oem-code-pages.js.map +1 -0
- package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
- package/dist/tools/schedules/schedule-tool.js +35 -6
- package/dist/tools/schedules/schedule-tool.js.map +1 -1
- package/dist/tools/schedules/types.d.ts +23 -3
- package/dist/tools/schedules/types.d.ts.map +1 -1
- package/dist/tools/task/list.d.ts.map +1 -1
- package/dist/tools/task/list.js +14 -6
- package/dist/tools/task/list.js.map +1 -1
- package/dist/tools/task/present.d.ts.map +1 -1
- package/dist/tools/task/present.js +26 -6
- package/dist/tools/task/present.js.map +1 -1
- package/dist/tools/task/update.d.ts.map +1 -1
- package/dist/tools/task/update.js +12 -5
- package/dist/tools/task/update.js.map +1 -1
- package/dist/tools/text-window.d.ts +19 -0
- package/dist/tools/text-window.d.ts.map +1 -0
- package/dist/tools/text-window.js +83 -0
- package/dist/tools/text-window.js.map +1 -0
- package/dist/toolsets/manager.d.ts +11 -0
- package/dist/toolsets/manager.d.ts.map +1 -1
- package/dist/toolsets/manager.js +45 -1
- package/dist/toolsets/manager.js.map +1 -1
- package/dist/types/acp/index.d.ts +137 -1
- package/dist/types/acp/index.d.ts.map +1 -1
- package/dist/types/agent/base.d.ts +3 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/manager.d.ts +8 -23
- package/dist/types/agent/manager.d.ts.map +1 -1
- package/dist/types/agent/scheduler.d.ts +10 -1
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +4 -0
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/authorization/index.d.ts +30 -30
- package/dist/types/connector/mcp.d.ts +7 -0
- package/dist/types/connector/mcp.d.ts.map +1 -1
- package/dist/types/errors/catalog.d.ts.map +1 -1
- package/dist/types/errors/catalog.js +4 -2
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/harness/schema.d.ts +354 -0
- package/dist/types/harness/schema.d.ts.map +1 -0
- package/dist/types/harness/schema.js +203 -0
- package/dist/types/harness/schema.js.map +1 -0
- package/dist/types/harness/session.d.ts +278 -0
- package/dist/types/harness/session.d.ts.map +1 -0
- package/dist/types/harness/session.js +2 -0
- package/dist/types/harness/session.js.map +1 -0
- package/dist/types/hitl/index.d.ts +12 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/job/index.d.ts +47 -0
- package/dist/types/job/index.d.ts.map +1 -0
- package/dist/types/job/index.js +2 -0
- package/dist/types/job/index.js.map +1 -0
- package/dist/types/message/inbound-delivery.d.ts +44 -0
- package/dist/types/message/inbound-delivery.d.ts.map +1 -0
- package/dist/types/message/inbound-delivery.js +14 -0
- package/dist/types/message/inbound-delivery.js.map +1 -0
- package/dist/types/message/index.d.ts +4 -1
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +5 -1
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +6 -6
- package/dist/types/sandbox/index.d.ts +39 -2
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js.map +1 -1
- package/dist/types/session/checkpoint.d.ts +24 -17
- package/dist/types/session/checkpoint.d.ts.map +1 -1
- package/dist/types/session/checkpoint.js +1 -0
- package/dist/types/session/checkpoint.js.map +1 -1
- package/dist/types/session/events.d.ts +23 -1
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +1514 -565
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +89 -1
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/session/step.d.ts +2 -0
- package/dist/types/session/step.d.ts.map +1 -1
- package/dist/types/session/step.js.map +1 -1
- package/dist/types/session/store.d.ts +19 -10
- package/dist/types/session/store.d.ts.map +1 -1
- package/dist/types/session/tool-execution.d.ts +6 -0
- package/dist/types/session/tool-execution.d.ts.map +1 -1
- package/dist/types/structured-output/index.d.ts +12 -2
- package/dist/types/structured-output/index.d.ts.map +1 -1
- package/dist/types/summary/ref.d.ts +3 -1
- package/dist/types/summary/ref.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +32 -4
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +106 -0
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/dist/utils/json-snapshot.d.ts +6 -2
- package/dist/utils/json-snapshot.d.ts.map +1 -1
- package/dist/utils/json-snapshot.js +19 -9
- package/dist/utils/json-snapshot.js.map +1 -1
- package/dist/utils/structured-result-json.d.ts +5 -0
- package/dist/utils/structured-result-json.d.ts.map +1 -0
- package/dist/utils/structured-result-json.js +10 -0
- package/dist/utils/structured-result-json.js.map +1 -0
- package/package.json +1 -1
- package/src/agents/QueryAgent.ts +1 -0
- package/src/agents/examples/SupervisorAgent.ts +1 -0
- package/src/agents/runAgent.ts +3 -0
- package/src/authorization/shell-lexer.ts +16 -1
- package/src/bridge/acp/permission.ts +17 -3
- package/src/bridge/acp/server.ts +271 -25
- package/src/bridge/acp/tasks.ts +23 -0
- package/src/bridge/acp/update.ts +167 -13
- package/src/connector/mcp/adapter.ts +16 -4
- package/src/connector/mcp/client.ts +6 -2
- package/src/constants/acp/index.ts +4 -0
- package/src/manager/agent/lifecycle.ts +230 -3
- package/src/manager/plan/lifecycle.ts +11 -9
- package/src/manager/session/attribution.ts +12 -2
- package/src/manager/session/streamed-message-identity.ts +21 -0
- package/src/manager/session/turn-recorder.ts +4 -3
- package/src/pals/activity/causality.ts +261 -0
- package/src/pals/activity/projection.ts +89 -0
- package/src/pals/activity/source.ts +240 -0
- package/src/pals/activity/subscription-policy.ts +230 -0
- package/src/pals/activity/subscription-schema.ts +27 -0
- package/src/pals/activity/subscription-store.ts +172 -0
- package/src/pals/activity/subscription-types.ts +48 -0
- package/src/pals/activity/subscriptions.ts +209 -0
- package/src/pals/activity/types.ts +108 -0
- package/src/pals/channels/ingress.ts +153 -0
- package/src/pals/channels/routes.ts +118 -0
- package/src/pals/channels/routing.ts +197 -0
- package/src/pals/channels/schema.ts +108 -0
- package/src/pals/channels/types.ts +156 -0
- package/src/pals/communication/broker.ts +131 -0
- package/src/pals/communication/dispatch.ts +66 -0
- package/src/pals/communication/inbound.ts +193 -0
- package/src/pals/communication/ingress-dispatch.ts +63 -0
- package/src/pals/communication/ingress-inbound.ts +269 -0
- package/src/pals/communication/ingress-schema.ts +526 -0
- package/src/pals/communication/ingress-types.ts +336 -0
- package/src/pals/communication/operator.ts +315 -0
- package/src/pals/communication/policy.ts +174 -0
- package/src/pals/communication/schema.ts +173 -0
- package/src/pals/communication/store.ts +577 -0
- package/src/pals/communication/tools.ts +139 -0
- package/src/pals/communication/types.ts +227 -0
- package/src/pals/communication/verify.ts +220 -0
- package/src/pals/lifecycle.ts +54 -0
- package/src/pals/prompt.ts +101 -0
- package/src/pals/reference-images.ts +322 -0
- package/src/pals/runtime.ts +670 -0
- package/src/pals/store.ts +369 -0
- package/src/pals/types.ts +157 -0
- package/src/peers/envelope.ts +1 -1
- package/src/plugin/shell-hook.ts +8 -2
- package/src/process/kill-tree.ts +10 -1
- package/src/provider/errors.ts +135 -2
- package/src/provider/strict-schema.ts +90 -0
- package/src/public-runtime.ts +118 -12
- package/src/public-tools.ts +13 -1
- package/src/public-types.ts +69 -7
- package/src/registry/tool/presentation.ts +9 -4
- package/src/runtime/harness-session/index.ts +1125 -0
- package/src/runtime/harness-session/journal.ts +209 -0
- package/src/runtime/harness-session/saved-view.ts +122 -0
- package/src/runtime/jobs/awaited-jobs.ts +2 -1
- package/src/runtime/jobs/registry.ts +397 -41
- package/src/runtime/query/abandon-turn.ts +18 -2
- package/src/runtime/query/checkpoint.ts +11 -0
- package/src/runtime/query/durable-inbound.ts +101 -0
- package/src/runtime/query/events.ts +22 -5
- package/src/runtime/query/executor/tool-call-admission.ts +125 -32
- package/src/runtime/query/executor.ts +316 -130
- package/src/runtime/query/index.ts +24 -4
- package/src/runtime/query/iteration/index.ts +218 -104
- package/src/runtime/query/iteration/outstanding-work.ts +55 -7
- package/src/runtime/query/iteration/phases/context.ts +4 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +118 -21
- package/src/runtime/query/observation-context.ts +22 -16
- package/src/runtime/query/prepare-turn.ts +2 -2
- package/src/runtime/query/prompt-cache.ts +3 -0
- package/src/runtime/query/prompt.ts +32 -1
- package/src/runtime/query/repeat-call.ts +40 -10
- package/src/runtime/query/resume-pending.ts +60 -7
- package/src/runtime/query/resume-session.ts +1 -1
- package/src/runtime/query/review-policy.ts +23 -2
- package/src/runtime/query/saved-presentation.ts +70 -0
- package/src/runtime/query/steering.ts +6 -9
- package/src/runtime/query/tool-executions.ts +108 -9
- package/src/runtime/query/tooling.ts +6 -1
- package/src/scheduler/completion-inbox.ts +108 -7
- package/src/scheduler/delegating.ts +5 -0
- package/src/scheduler/local.ts +2 -0
- package/src/session/summary/materialize.ts +51 -9
- package/src/store/budget/ledger.ts +60 -5
- package/src/store/session/disk.ts +77 -10
- package/src/store/session/memory.ts +32 -7
- package/src/store/session-log/core.ts +118 -11
- package/src/store/session-log/disk.ts +9 -2
- package/src/store/session-log/fold.ts +22 -0
- package/src/store/session-log/index.ts +5 -0
- package/src/store/session-log/memory.ts +2 -1
- package/src/store/session-log/spill.ts +89 -6
- package/src/store/session-log/structured-result.ts +96 -0
- package/src/store/task/disk.ts +46 -2
- package/src/store/task/memory.ts +13 -3
- package/src/tools/admit-facts.ts +145 -0
- package/src/tools/builtins/bash.ts +132 -24
- package/src/tools/builtins/edit.ts +54 -1
- package/src/tools/builtins/file-write-result.ts +14 -0
- package/src/tools/builtins/glob.ts +12 -0
- package/src/tools/builtins/grep.ts +14 -0
- package/src/tools/builtins/index.ts +2 -0
- package/src/tools/builtins/job.ts +4 -1
- package/src/tools/builtins/read-file.ts +57 -0
- package/src/tools/builtins/view-image.ts +409 -0
- package/src/tools/builtins/wait-for-job-bounds.ts +3 -0
- package/src/tools/builtins/wait-for-job.ts +141 -32
- package/src/tools/builtins/write-file.ts +4 -2
- package/src/tools/command-shell.ts +132 -5
- package/src/tools/coordinator/agent.ts +9 -19
- package/src/tools/coordinator/index.ts +150 -75
- package/src/tools/coordinator/wait-with-idle-bound.ts +3 -1
- package/src/tools/defineTool.ts +4 -0
- package/src/tools/failure-facts.ts +24 -0
- package/src/tools/host-output.ts +136 -0
- package/src/tools/oem-code-pages.ts +22 -0
- package/src/tools/schedules/schedule-tool.ts +38 -5
- package/src/tools/schedules/types.ts +23 -3
- package/src/tools/task/list.ts +15 -7
- package/src/tools/task/present.ts +37 -7
- package/src/tools/task/update.ts +12 -5
- package/src/tools/text-window.ts +87 -0
- package/src/toolsets/manager.ts +58 -1
- package/src/types/acp/index.ts +150 -4
- package/src/types/agent/base.ts +3 -0
- package/src/types/agent/manager.ts +8 -23
- package/src/types/agent/scheduler.ts +10 -1
- package/src/types/agent/task.ts +4 -0
- package/src/types/connector/mcp.ts +7 -0
- package/src/types/errors/catalog.ts +4 -2
- package/src/types/harness/schema.ts +203 -0
- package/src/types/harness/session.ts +306 -0
- package/src/types/hitl/index.ts +17 -1
- package/src/types/job/index.ts +42 -0
- package/src/types/message/inbound-delivery.ts +63 -0
- package/src/types/message/index.ts +8 -1
- package/src/types/sandbox/index.ts +46 -0
- package/src/types/session/checkpoint.ts +4 -1
- package/src/types/session/events.ts +23 -1
- package/src/types/session/records.ts +114 -2
- package/src/types/session/step.ts +2 -0
- package/src/types/session/store.ts +23 -9
- package/src/types/session/tool-execution.ts +6 -0
- package/src/types/structured-output/index.ts +13 -2
- package/src/types/summary/ref.ts +3 -1
- package/src/types/tool/index.ts +39 -5
- package/src/types/tool/presentation.ts +121 -0
- package/src/utils/json-snapshot.ts +26 -9
- package/src/utils/structured-result-json.ts +10 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { PalAddress } from '../communication/types.js'
|
|
2
|
+
import type { PalActivityCursor, PalActivityFact, PalActivityScope } from './types.js'
|
|
3
|
+
|
|
4
|
+
/** Host-owned, immutable observation scope and destination, with separately revocable consent. */
|
|
5
|
+
export interface PalActivitySubscription {
|
|
6
|
+
readonly v: 1
|
|
7
|
+
readonly id: string
|
|
8
|
+
readonly revision: number
|
|
9
|
+
readonly configurationRevision: number
|
|
10
|
+
readonly scope: PalActivityScope
|
|
11
|
+
readonly recipient: PalAddress
|
|
12
|
+
readonly enabled: boolean
|
|
13
|
+
readonly cursor: PalActivityCursor | null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PalActivitySubscriptionStore {
|
|
17
|
+
get(id: string): Promise<PalActivitySubscription | null>
|
|
18
|
+
create(input: {
|
|
19
|
+
readonly id: string
|
|
20
|
+
readonly scope: PalActivityScope
|
|
21
|
+
readonly recipient: PalAddress
|
|
22
|
+
readonly enabled: boolean
|
|
23
|
+
}): Promise<PalActivitySubscription>
|
|
24
|
+
setEnabled(input: {
|
|
25
|
+
readonly id: string
|
|
26
|
+
readonly expectedRevision: number
|
|
27
|
+
readonly enabled: boolean
|
|
28
|
+
}): Promise<PalActivitySubscription>
|
|
29
|
+
/** Only an unchanged cursor emitted by the trusted original-journal source may be committed. */
|
|
30
|
+
advance(
|
|
31
|
+
subscription: PalActivitySubscription,
|
|
32
|
+
cursor: PalActivityCursor,
|
|
33
|
+
): Promise<PalActivitySubscription>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface PalActivitySubscriptionAuthorizationRequest {
|
|
37
|
+
/** `accept` requires observe, disclose and receive together immediately before inbox acceptance. */
|
|
38
|
+
readonly phase: 'observe' | 'disclose' | 'receive' | 'accept'
|
|
39
|
+
readonly subscription: PalActivitySubscription
|
|
40
|
+
readonly fact?: PalActivityFact
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface PalActivitySubscriptionResult {
|
|
44
|
+
readonly subscription: PalActivitySubscription
|
|
45
|
+
readonly accepted: readonly string[]
|
|
46
|
+
readonly suppressed: readonly string[]
|
|
47
|
+
readonly complete: boolean
|
|
48
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import { ingressIntentDigest, ingressIntentId } from '../communication/ingress-schema.js'
|
|
4
|
+
import type { PalIngressStore, PalObservationIntent } from '../communication/ingress-types.js'
|
|
5
|
+
import { freezeCommunicationValue, hash, label } from '../communication/schema.js'
|
|
6
|
+
import type { PalMessageAuthorization, PalMessageGrant } from '../communication/types.js'
|
|
7
|
+
import type { PalStore } from '../types.js'
|
|
8
|
+
import { createPalActivitySource } from './source.js'
|
|
9
|
+
import { subscriptionSchema } from './subscription-schema.js'
|
|
10
|
+
import type {
|
|
11
|
+
PalActivitySubscriptionAuthorizationRequest,
|
|
12
|
+
PalActivitySubscriptionResult,
|
|
13
|
+
PalActivitySubscriptionStore,
|
|
14
|
+
} from './subscription-types.js'
|
|
15
|
+
import type {
|
|
16
|
+
PalActivityFact,
|
|
17
|
+
PalActivityReadOptions,
|
|
18
|
+
PalActivityScope,
|
|
19
|
+
PalActivitySourceOptions,
|
|
20
|
+
} from './types.js'
|
|
21
|
+
|
|
22
|
+
export class PalActivitySubscriptionDeniedError extends Error {
|
|
23
|
+
override readonly name = 'PalActivitySubscriptionDeniedError'
|
|
24
|
+
constructor() {
|
|
25
|
+
super('Current Pal observation, disclosure and recipient consent are required.')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PalActivitySubscriptionRunnerOptions {
|
|
30
|
+
readonly subscriptions: PalActivitySubscriptionStore
|
|
31
|
+
readonly ingress: PalIngressStore
|
|
32
|
+
readonly pals: PalStore
|
|
33
|
+
readonly openJournal: PalActivitySourceOptions['openJournal']
|
|
34
|
+
/**
|
|
35
|
+
* Trusted current host policy. Observation, disclosure and receipt are independent decisions;
|
|
36
|
+
* the final `accept` phase must require all three together under current consent.
|
|
37
|
+
*/
|
|
38
|
+
readonly authorize: (
|
|
39
|
+
request: PalActivitySubscriptionAuthorizationRequest,
|
|
40
|
+
signal: AbortSignal,
|
|
41
|
+
) => Promise<PalMessageAuthorization>
|
|
42
|
+
/**
|
|
43
|
+
* Resolve prior subscription IDs from original turn delivery evidence retained by the host.
|
|
44
|
+
* An independent turn yields []; unknown or incomplete evidence must reject. Never accept
|
|
45
|
+
* a model, renderer or remote client's assertion about its own provenance.
|
|
46
|
+
*/
|
|
47
|
+
readonly resolveCausality: (
|
|
48
|
+
scope: PalActivityScope,
|
|
49
|
+
fact: PalActivityFact,
|
|
50
|
+
signal: AbortSignal,
|
|
51
|
+
) => Promise<readonly string[]>
|
|
52
|
+
readonly now?: () => number
|
|
53
|
+
/** Hint only. Observer failures and pending promises cannot prevent acceptance/progress. */
|
|
54
|
+
readonly notify?: (palId: string) => void | Promise<void>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** One bounded page, no daemon and no inference. Progress follows durable inbox acceptance. */
|
|
58
|
+
export async function publishPalActivityOnce(
|
|
59
|
+
options: PalActivitySubscriptionRunnerOptions,
|
|
60
|
+
id: string,
|
|
61
|
+
input: Omit<PalActivityReadOptions, 'cursor'>,
|
|
62
|
+
): Promise<PalActivitySubscriptionResult> {
|
|
63
|
+
const subscriptionId = z.string().uuid().parse(id)
|
|
64
|
+
const { signal } = input
|
|
65
|
+
const { subscriptions, ingress, pals, openJournal, authorize, resolveCausality, notify } = options
|
|
66
|
+
const now = options.now ?? Date.now
|
|
67
|
+
if (
|
|
68
|
+
typeof authorize !== 'function' ||
|
|
69
|
+
typeof resolveCausality !== 'function' ||
|
|
70
|
+
typeof openJournal !== 'function'
|
|
71
|
+
)
|
|
72
|
+
throw new TypeError(
|
|
73
|
+
'Pal subscriptions require trusted policy, causality and original journal ports.',
|
|
74
|
+
)
|
|
75
|
+
signal.throwIfAborted()
|
|
76
|
+
const stored = await subscriptions.get(subscriptionId)
|
|
77
|
+
if (!stored) throw new PalActivitySubscriptionDeniedError()
|
|
78
|
+
const subscription = freezeCommunicationValue(subscriptionSchema.parse(stored))
|
|
79
|
+
async function current() {
|
|
80
|
+
signal.throwIfAborted()
|
|
81
|
+
const value = await subscriptions.get(subscriptionId)
|
|
82
|
+
signal.throwIfAborted()
|
|
83
|
+
if (
|
|
84
|
+
!value?.enabled ||
|
|
85
|
+
value.configurationRevision !== subscription.configurationRevision ||
|
|
86
|
+
!isDeepStrictEqual(value.scope, subscription.scope) ||
|
|
87
|
+
!isDeepStrictEqual(value.recipient, subscription.recipient)
|
|
88
|
+
)
|
|
89
|
+
throw new PalActivitySubscriptionDeniedError()
|
|
90
|
+
}
|
|
91
|
+
async function permitted(
|
|
92
|
+
phase: PalActivitySubscriptionAuthorizationRequest['phase'],
|
|
93
|
+
fact?: PalActivityFact,
|
|
94
|
+
): Promise<PalMessageGrant> {
|
|
95
|
+
await current()
|
|
96
|
+
const decision = await authorize(
|
|
97
|
+
freezeCommunicationValue({
|
|
98
|
+
phase,
|
|
99
|
+
subscription,
|
|
100
|
+
...(fact ? { fact } : {}),
|
|
101
|
+
}),
|
|
102
|
+
signal,
|
|
103
|
+
)
|
|
104
|
+
signal.throwIfAborted()
|
|
105
|
+
if (!decision.allow) throw new PalActivitySubscriptionDeniedError()
|
|
106
|
+
const grant = freezeCommunicationValue(
|
|
107
|
+
z.object({ id: label, revision: label }).strict().parse(decision.grant),
|
|
108
|
+
)
|
|
109
|
+
await current()
|
|
110
|
+
return grant
|
|
111
|
+
}
|
|
112
|
+
const source = createPalActivitySource({
|
|
113
|
+
scope: subscription.scope,
|
|
114
|
+
pals,
|
|
115
|
+
openJournal,
|
|
116
|
+
async authorize() {
|
|
117
|
+
await permitted('observe')
|
|
118
|
+
return true
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
const page = await source.read({
|
|
122
|
+
signal,
|
|
123
|
+
maxRecords: input.maxRecords,
|
|
124
|
+
maxReadBytes: input.maxReadBytes,
|
|
125
|
+
...(subscription.cursor ? { cursor: subscription.cursor } : {}),
|
|
126
|
+
})
|
|
127
|
+
const accepted: string[] = []
|
|
128
|
+
const suppressed: string[] = []
|
|
129
|
+
for (const fact of page.facts) {
|
|
130
|
+
const observed = await permitted('observe', fact)
|
|
131
|
+
const lineage = z
|
|
132
|
+
.array(z.string().uuid())
|
|
133
|
+
.refine((ids) => new Set(ids).size === ids.length)
|
|
134
|
+
.parse(await resolveCausality(subscription.scope, fact, signal))
|
|
135
|
+
signal.throwIfAborted()
|
|
136
|
+
await current()
|
|
137
|
+
if (lineage.includes(subscription.id)) {
|
|
138
|
+
suppressed.push(fact.id)
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
const disclosed = await permitted('disclose', fact)
|
|
142
|
+
const received = await permitted('receive', fact)
|
|
143
|
+
const recipient = pals.get(subscription.recipient.palId)
|
|
144
|
+
if (!recipient) throw new PalActivitySubscriptionDeniedError()
|
|
145
|
+
const acceptedGrant = await permitted('accept', fact)
|
|
146
|
+
const draft = {
|
|
147
|
+
kind: 'observation' as const,
|
|
148
|
+
operationId: fact.id,
|
|
149
|
+
source: {
|
|
150
|
+
kind: 'host-observation' as const,
|
|
151
|
+
subscriptionId: subscription.id,
|
|
152
|
+
scope: subscription.scope,
|
|
153
|
+
},
|
|
154
|
+
recipient: subscription.recipient,
|
|
155
|
+
routeKey: {
|
|
156
|
+
v: 1 as const,
|
|
157
|
+
kind: 'observation' as const,
|
|
158
|
+
recipient: subscription.recipient,
|
|
159
|
+
subscriptionId: subscription.id,
|
|
160
|
+
scope: subscription.scope,
|
|
161
|
+
},
|
|
162
|
+
fact,
|
|
163
|
+
subscriptionTrail: [...lineage, subscription.id],
|
|
164
|
+
replyTo: null,
|
|
165
|
+
grant: {
|
|
166
|
+
id: hash([
|
|
167
|
+
'pal-observation-grants/1',
|
|
168
|
+
subscription.id,
|
|
169
|
+
observed.id,
|
|
170
|
+
disclosed.id,
|
|
171
|
+
received.id,
|
|
172
|
+
acceptedGrant.id,
|
|
173
|
+
]),
|
|
174
|
+
revision: hash([
|
|
175
|
+
subscription.configurationRevision,
|
|
176
|
+
observed.revision,
|
|
177
|
+
disclosed.revision,
|
|
178
|
+
received.revision,
|
|
179
|
+
acceptedGrant.revision,
|
|
180
|
+
]),
|
|
181
|
+
},
|
|
182
|
+
createdAt: now(),
|
|
183
|
+
}
|
|
184
|
+
const intentId = ingressIntentId(draft)
|
|
185
|
+
const intent = freezeCommunicationValue({
|
|
186
|
+
...draft,
|
|
187
|
+
id: intentId,
|
|
188
|
+
digest: ingressIntentDigest({ ...draft, id: intentId }),
|
|
189
|
+
}) as PalObservationIntent
|
|
190
|
+
await ingress.acceptIngress(intent, recipient.revision)
|
|
191
|
+
accepted.push(intent.id)
|
|
192
|
+
if (notify) {
|
|
193
|
+
try {
|
|
194
|
+
Promise.resolve(notify(subscription.recipient.palId)).catch(() => {})
|
|
195
|
+
} catch {}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
await permitted('observe')
|
|
199
|
+
const next =
|
|
200
|
+
subscription.cursor && isDeepStrictEqual(subscription.cursor, page.cursor)
|
|
201
|
+
? subscription
|
|
202
|
+
: await subscriptions.advance(subscription, page.cursor)
|
|
203
|
+
return freezeCommunicationValue({
|
|
204
|
+
subscription: next,
|
|
205
|
+
accepted,
|
|
206
|
+
suppressed,
|
|
207
|
+
complete: page.complete,
|
|
208
|
+
})
|
|
209
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { LogBytes } from '../../store/session-log/chain.js'
|
|
2
|
+
import type { SessionLog } from '../../store/session-log/core.js'
|
|
3
|
+
import type { ActivityStatus, ActivityType } from '../../types/activity/index.js'
|
|
4
|
+
import type {
|
|
5
|
+
ActivityId,
|
|
6
|
+
CheckpointId,
|
|
7
|
+
ProjectId,
|
|
8
|
+
SessionId,
|
|
9
|
+
TenantId,
|
|
10
|
+
ToolUseId,
|
|
11
|
+
TurnId,
|
|
12
|
+
} from '../../types/ids/index.js'
|
|
13
|
+
import type { RecordPointer } from '../../types/session/records.js'
|
|
14
|
+
import type { PalStore } from '../types.js'
|
|
15
|
+
|
|
16
|
+
export interface PalActivityScope {
|
|
17
|
+
readonly tenantId: TenantId
|
|
18
|
+
readonly projectId: ProjectId
|
|
19
|
+
readonly palId: string
|
|
20
|
+
readonly profileRevision: number
|
|
21
|
+
readonly sessionId: SessionId
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* An unchanged previously emitted cursor, stored and resolved by the trusted host.
|
|
26
|
+
* Never accept a model, renderer or remote client's anchor directly. scopeHash binds
|
|
27
|
+
* ownership but does not authenticate a cursor; consumed prefixes are not rescanned.
|
|
28
|
+
*/
|
|
29
|
+
export interface PalActivityCursor {
|
|
30
|
+
readonly v: 1
|
|
31
|
+
readonly scopeHash: string
|
|
32
|
+
readonly root: RecordPointer
|
|
33
|
+
readonly after: RecordPointer
|
|
34
|
+
readonly generation: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type PalActivityFactType =
|
|
38
|
+
| 'turn_started'
|
|
39
|
+
| 'turn_resuming'
|
|
40
|
+
| 'turn_paused'
|
|
41
|
+
| 'turn_completed'
|
|
42
|
+
| 'turn_failed'
|
|
43
|
+
| 'activity_created'
|
|
44
|
+
| 'activity_updated'
|
|
45
|
+
| 'tool_executing'
|
|
46
|
+
| 'tool_completed'
|
|
47
|
+
| 'tool_review_requested'
|
|
48
|
+
| 'tool_review_completed'
|
|
49
|
+
| 'checkpoint_created'
|
|
50
|
+
|
|
51
|
+
/** Allow-listed facts only. No descriptions, tool names, arguments, results or errors. */
|
|
52
|
+
export interface PalActivityFact {
|
|
53
|
+
readonly id: string
|
|
54
|
+
readonly type: PalActivityFactType
|
|
55
|
+
readonly sessionId: SessionId
|
|
56
|
+
readonly turnId?: TurnId
|
|
57
|
+
readonly seq: number
|
|
58
|
+
readonly generation: number
|
|
59
|
+
readonly at: string
|
|
60
|
+
readonly activityId?: ActivityId
|
|
61
|
+
readonly activityType?: ActivityType
|
|
62
|
+
readonly status?: ActivityStatus
|
|
63
|
+
readonly toolUseId?: ToolUseId
|
|
64
|
+
readonly checkpointId?: CheckpointId
|
|
65
|
+
readonly reviewDecision?: 'approved' | 'modified' | 'rejected'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Host-owned read ports MUST address the same original journal, never a transcript cache. */
|
|
69
|
+
export interface PalActivityJournal {
|
|
70
|
+
readonly log: Pick<SessionLog, 'sessionId'>
|
|
71
|
+
readonly bytes: LogBytes
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface PalActivitySourceOptions {
|
|
75
|
+
readonly scope: PalActivityScope
|
|
76
|
+
readonly pals: PalStore
|
|
77
|
+
/** Current observation consent; checked before opening, original byte reads and output. */
|
|
78
|
+
readonly authorize: (scope: PalActivityScope, signal: AbortSignal) => Promise<boolean>
|
|
79
|
+
readonly openJournal: (
|
|
80
|
+
scope: PalActivityScope,
|
|
81
|
+
signal: AbortSignal,
|
|
82
|
+
) => Promise<PalActivityJournal>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface PalActivityReadOptions {
|
|
86
|
+
readonly signal: AbortSignal
|
|
87
|
+
/** Trusted host-stored output of an earlier read; never untrusted client input. */
|
|
88
|
+
readonly cursor?: PalActivityCursor
|
|
89
|
+
/** Maximum new history records inspected, including omitted records, excluding anchors (1–256). */
|
|
90
|
+
readonly maxRecords: number
|
|
91
|
+
/** Total bytes requested from the journal, including root/cursor anchors (1–16 MiB). */
|
|
92
|
+
readonly maxReadBytes: number
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface PalActivityPage {
|
|
96
|
+
readonly scope: PalActivityScope
|
|
97
|
+
readonly facts: readonly PalActivityFact[]
|
|
98
|
+
readonly cursor: PalActivityCursor
|
|
99
|
+
/** Only the captured byte boundary was reached; later appends require another read. */
|
|
100
|
+
readonly complete: boolean
|
|
101
|
+
readonly scannedRecords: number
|
|
102
|
+
readonly readBytes: number
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface PalActivitySource {
|
|
106
|
+
readonly scope: PalActivityScope
|
|
107
|
+
read(options: PalActivityReadOptions): Promise<PalActivityPage>
|
|
108
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
2
|
+
import {
|
|
3
|
+
ingressIntentDigest,
|
|
4
|
+
ingressIntentId,
|
|
5
|
+
ingressIntentSchema,
|
|
6
|
+
} from '../communication/ingress-schema.js'
|
|
7
|
+
import type { PalChannelIdentity, PalChannelIntent } from '../communication/ingress-types.js'
|
|
8
|
+
import { addressSchema, freezeCommunicationValue } from '../communication/schema.js'
|
|
9
|
+
import {
|
|
10
|
+
captureConnection,
|
|
11
|
+
checkedDecision,
|
|
12
|
+
checkedIdentity,
|
|
13
|
+
verifiedMessageSchema,
|
|
14
|
+
} from './schema.js'
|
|
15
|
+
import type { PalChannelAuthorizationRequest, PalChannelIngressOptions } from './types.js'
|
|
16
|
+
|
|
17
|
+
/** Authenticated channel ingress. Raw event fields never choose host credentials or Namzu identities. */
|
|
18
|
+
export class PalChannelIngress {
|
|
19
|
+
private readonly connection
|
|
20
|
+
private readonly options: PalChannelIngressOptions
|
|
21
|
+
constructor(options: PalChannelIngressOptions) {
|
|
22
|
+
if (
|
|
23
|
+
typeof options.verify !== 'function' ||
|
|
24
|
+
typeof options.authorize !== 'function' ||
|
|
25
|
+
typeof options.selectRecipient !== 'function'
|
|
26
|
+
)
|
|
27
|
+
throw new Error(
|
|
28
|
+
'Channel ingress requires trusted verification, target selection and current authorization.',
|
|
29
|
+
)
|
|
30
|
+
this.connection = captureConnection(options.connection)
|
|
31
|
+
this.options = Object.freeze({ ...options })
|
|
32
|
+
}
|
|
33
|
+
async accept(raw: unknown, signal: AbortSignal = new AbortController().signal) {
|
|
34
|
+
signal.throwIfAborted()
|
|
35
|
+
// Capture before the verifier's first asynchronous boundary, including JavaScript host input.
|
|
36
|
+
const event = freezeCommunicationValue(
|
|
37
|
+
verifiedMessageSchema.parse(
|
|
38
|
+
await this.options.verify(structuredClone(raw), this.connection, signal),
|
|
39
|
+
),
|
|
40
|
+
)
|
|
41
|
+
signal.throwIfAborted()
|
|
42
|
+
const source = checkedIdentity(this.connection, {
|
|
43
|
+
externalTenantId: event.externalTenantId,
|
|
44
|
+
nativeConversationId: event.nativeConversationId,
|
|
45
|
+
nativeChannelId: event.nativeChannelId,
|
|
46
|
+
nativeThreadId: event.nativeThreadId,
|
|
47
|
+
actorId: event.actorId,
|
|
48
|
+
eventId: event.eventId,
|
|
49
|
+
kind: 'channel',
|
|
50
|
+
tenantId: this.connection.tenantId,
|
|
51
|
+
provider: this.connection.provider,
|
|
52
|
+
connectionId: this.connection.connectionId,
|
|
53
|
+
})
|
|
54
|
+
const identity: PalChannelIdentity = {
|
|
55
|
+
provider: source.provider,
|
|
56
|
+
connectionId: source.connectionId,
|
|
57
|
+
externalTenantId: source.externalTenantId,
|
|
58
|
+
nativeConversationId: source.nativeConversationId,
|
|
59
|
+
nativeChannelId: source.nativeChannelId,
|
|
60
|
+
nativeThreadId: source.nativeThreadId,
|
|
61
|
+
}
|
|
62
|
+
const { routes, pals, store } = this.options
|
|
63
|
+
const existing = await routes.get(this.connection, identity)
|
|
64
|
+
let decision = existing ? checkedDecision(existing) : null
|
|
65
|
+
if (!decision) {
|
|
66
|
+
const recipient = freezeCommunicationValue(
|
|
67
|
+
addressSchema.parse(await this.options.selectRecipient(event, this.connection)),
|
|
68
|
+
)
|
|
69
|
+
if (recipient.tenantId !== this.connection.tenantId)
|
|
70
|
+
throw new Error('Cross-tenant channel routing is refused.')
|
|
71
|
+
const pal = pals.get(recipient.palId)
|
|
72
|
+
if (!pal) throw new Error('Channel recipient Pal is unavailable.')
|
|
73
|
+
decision = checkedDecision({
|
|
74
|
+
v: 1,
|
|
75
|
+
revision: 1,
|
|
76
|
+
identity,
|
|
77
|
+
recipient,
|
|
78
|
+
profileRevision: pal.revision,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
const request: PalChannelAuthorizationRequest = freezeCommunicationValue({
|
|
82
|
+
phase: 'accept',
|
|
83
|
+
kind: 'channel',
|
|
84
|
+
source,
|
|
85
|
+
recipient: decision.recipient,
|
|
86
|
+
routeKey: {
|
|
87
|
+
v: 1,
|
|
88
|
+
kind: 'channel',
|
|
89
|
+
...identity,
|
|
90
|
+
recipient: decision.recipient,
|
|
91
|
+
},
|
|
92
|
+
body: event.body,
|
|
93
|
+
replyTo: null,
|
|
94
|
+
})
|
|
95
|
+
let allowed = freezeCommunicationValue(structuredClone(await this.options.authorize(request)))
|
|
96
|
+
signal.throwIfAborted()
|
|
97
|
+
if (allowed.allow !== true) throw new Error(`Channel ingress refused: ${allowed.reason}`)
|
|
98
|
+
// Only authorized traffic can publish a routing decision. Concurrent first events share one target.
|
|
99
|
+
const reserved = checkedDecision(await routes.reserve(decision))
|
|
100
|
+
if (!isDeepStrictEqual(reserved, decision))
|
|
101
|
+
throw new Error('Channel routing decision changed during acceptance.')
|
|
102
|
+
decision = reserved
|
|
103
|
+
pals.getRevision(decision.recipient.palId, decision.profileRevision)
|
|
104
|
+
if (!pals.get(decision.recipient.palId))
|
|
105
|
+
throw new Error('Channel recipient Pal is unavailable.')
|
|
106
|
+
// Routing publication can await another process. Re-read event authority before committing its input.
|
|
107
|
+
allowed = freezeCommunicationValue(structuredClone(await this.options.authorize(request)))
|
|
108
|
+
signal.throwIfAborted()
|
|
109
|
+
if (allowed.allow !== true) throw new Error(`Channel ingress refused: ${allowed.reason}`)
|
|
110
|
+
const intent = {
|
|
111
|
+
kind: 'channel' as const,
|
|
112
|
+
source,
|
|
113
|
+
recipient: decision.recipient,
|
|
114
|
+
routeKey: request.routeKey,
|
|
115
|
+
body: event.body,
|
|
116
|
+
replyTo: null,
|
|
117
|
+
operationId: source.eventId,
|
|
118
|
+
grant: allowed.grant,
|
|
119
|
+
createdAt: (this.options.now ?? Date.now)(),
|
|
120
|
+
}
|
|
121
|
+
const identified = { ...intent, id: ingressIntentId(intent) }
|
|
122
|
+
const immutable = freezeCommunicationValue(
|
|
123
|
+
ingressIntentSchema.parse({
|
|
124
|
+
...identified,
|
|
125
|
+
digest: ingressIntentDigest(identified),
|
|
126
|
+
}),
|
|
127
|
+
) as PalChannelIntent
|
|
128
|
+
signal.throwIfAborted()
|
|
129
|
+
const receipt = await store.acceptIngress(immutable, decision.profileRevision)
|
|
130
|
+
const binding = await store.routeIngress(immutable.routeKey)
|
|
131
|
+
if (
|
|
132
|
+
!binding ||
|
|
133
|
+
binding.sessionId !== receipt.sessionId ||
|
|
134
|
+
binding.profileRevision !== decision.profileRevision
|
|
135
|
+
)
|
|
136
|
+
throw new Error('Channel acceptance does not match its immutable target binding.')
|
|
137
|
+
const report = (error: unknown) => {
|
|
138
|
+
try {
|
|
139
|
+
void Promise.resolve(this.options.onNotificationError?.(error, receipt)).catch(
|
|
140
|
+
() => undefined,
|
|
141
|
+
)
|
|
142
|
+
} catch {
|
|
143
|
+
/* Committed receipt remains accepted. */
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
void Promise.resolve(this.options.host?.notify?.(decision.recipient)).catch(report)
|
|
148
|
+
} catch (error) {
|
|
149
|
+
report(error)
|
|
150
|
+
}
|
|
151
|
+
return receipt
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { chmodSync, lstatSync, mkdirSync, readdirSync, realpathSync } from 'node:fs'
|
|
2
|
+
import { join, resolve } from 'node:path'
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
4
|
+
import { DiskRevisionRecordStore } from '../../store/kv/revision-record-store.js'
|
|
5
|
+
import { defineSchema } from '../../store/schema.js'
|
|
6
|
+
import { channelRouteKeySchema } from '../communication/ingress-schema.js'
|
|
7
|
+
import type { PalChannelIdentity } from '../communication/ingress-types.js'
|
|
8
|
+
import { captureConnection, checkedDecision, decisionId } from './schema.js'
|
|
9
|
+
import type { PalChannelConnection, PalChannelRouteDecision, PalChannelRoutes } from './types.js'
|
|
10
|
+
|
|
11
|
+
export class PalChannelRouteConflictError extends Error {
|
|
12
|
+
override readonly name = 'PalChannelRouteConflictError'
|
|
13
|
+
}
|
|
14
|
+
class ExistingDecision extends Error {
|
|
15
|
+
constructor(readonly decision: PalChannelRouteDecision) {
|
|
16
|
+
super('Existing immutable channel route.')
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function storedDecision(value: PalChannelRouteDecision): PalChannelRouteDecision {
|
|
20
|
+
// DiskRecordStore validates its own envelope; it is not part of the public route identity.
|
|
21
|
+
const { schemaVersion: _version, ...body } = value as PalChannelRouteDecision & {
|
|
22
|
+
schemaVersion?: number
|
|
23
|
+
}
|
|
24
|
+
return checkedDecision(body)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Immutable target decisions only. Session and delivery ownership remain in PalIngressStore. */
|
|
28
|
+
export class DiskPalChannelRoutes implements PalChannelRoutes {
|
|
29
|
+
private readonly root: string
|
|
30
|
+
private readonly secure: (path: string) => void
|
|
31
|
+
private readonly records = new DiskRevisionRecordStore<PalChannelRouteDecision>(
|
|
32
|
+
defineSchema({ kind: 'pal-channel-route', current: 1, migrations: {} }),
|
|
33
|
+
'Pal channel route',
|
|
34
|
+
(record) => record.revision,
|
|
35
|
+
)
|
|
36
|
+
constructor(options: {
|
|
37
|
+
root: string
|
|
38
|
+
secureDirectory?: (path: string) => void
|
|
39
|
+
}) {
|
|
40
|
+
this.root = resolve(options.root)
|
|
41
|
+
this.secure =
|
|
42
|
+
options.secureDirectory ??
|
|
43
|
+
((path) => {
|
|
44
|
+
if (process.platform !== 'win32') chmodSync(path, 0o700)
|
|
45
|
+
})
|
|
46
|
+
this.directory(this.root)
|
|
47
|
+
}
|
|
48
|
+
private directory(path: string) {
|
|
49
|
+
mkdirSync(path, { recursive: true, mode: 0o700 })
|
|
50
|
+
const entry = lstatSync(path)
|
|
51
|
+
if (!entry.isDirectory() || entry.isSymbolicLink() || realpathSync(path) !== path)
|
|
52
|
+
throw new Error('Channel routes require real directories without aliases.')
|
|
53
|
+
this.secure(path)
|
|
54
|
+
}
|
|
55
|
+
private location(id: string) {
|
|
56
|
+
this.directory(this.root)
|
|
57
|
+
const directory = join(this.root, id)
|
|
58
|
+
this.directory(directory)
|
|
59
|
+
const revisionsDir = join(directory, 'revisions')
|
|
60
|
+
this.directory(revisionsDir)
|
|
61
|
+
for (const name of readdirSync(revisionsDir)) {
|
|
62
|
+
if (!/^[1-9][0-9]*\.json$/u.test(name)) continue
|
|
63
|
+
const entry = lstatSync(join(revisionsDir, name))
|
|
64
|
+
if (!entry.isFile() || entry.isSymbolicLink())
|
|
65
|
+
throw new Error('Channel route commits must be real files.')
|
|
66
|
+
}
|
|
67
|
+
const legacyPath = join(directory, 'route.json')
|
|
68
|
+
try {
|
|
69
|
+
const legacy = lstatSync(legacyPath)
|
|
70
|
+
if (!legacy.isFile() || legacy.isSymbolicLink())
|
|
71
|
+
throw new Error('Channel route projections must be real files.')
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
|
|
74
|
+
}
|
|
75
|
+
return { legacyPath, revisionsDir, publishLegacyProjection: false }
|
|
76
|
+
}
|
|
77
|
+
async get(input: PalChannelConnection, value: PalChannelIdentity) {
|
|
78
|
+
const connection = captureConnection(input)
|
|
79
|
+
const identity = channelRouteKeySchema
|
|
80
|
+
.omit({ v: true, kind: true, recipient: true })
|
|
81
|
+
.parse(value)
|
|
82
|
+
if (
|
|
83
|
+
identity.provider !== connection.provider ||
|
|
84
|
+
identity.connectionId !== connection.connectionId ||
|
|
85
|
+
identity.externalTenantId !== connection.externalTenantId
|
|
86
|
+
)
|
|
87
|
+
throw new Error('Foreign channel route connection.')
|
|
88
|
+
const id = decisionId({
|
|
89
|
+
identity,
|
|
90
|
+
recipient: { tenantId: connection.tenantId, palId: '' },
|
|
91
|
+
})
|
|
92
|
+
const stored = await this.records.read(this.location(id))
|
|
93
|
+
if (!stored) return null
|
|
94
|
+
const decision = storedDecision(stored)
|
|
95
|
+
if (decisionId(decision) !== id || !isDeepStrictEqual(decision.identity, identity))
|
|
96
|
+
throw new Error('Channel route identity changed.')
|
|
97
|
+
return decision
|
|
98
|
+
}
|
|
99
|
+
async reserve(input: PalChannelRouteDecision) {
|
|
100
|
+
const decision = checkedDecision(input)
|
|
101
|
+
try {
|
|
102
|
+
return await this.records.transact(this.location(decisionId(decision)), (stored) => {
|
|
103
|
+
if (stored) {
|
|
104
|
+
const current = storedDecision(stored)
|
|
105
|
+
if (!isDeepStrictEqual(current, decision))
|
|
106
|
+
throw new PalChannelRouteConflictError(
|
|
107
|
+
'This native conversation already has an immutable Pal target.',
|
|
108
|
+
)
|
|
109
|
+
throw new ExistingDecision(current)
|
|
110
|
+
}
|
|
111
|
+
return { record: decision, result: decision }
|
|
112
|
+
})
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof ExistingDecision) return error.decision
|
|
115
|
+
throw error
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|