@pikku/core 0.12.71 → 0.12.74
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 +848 -0
- package/dist/crypto-utils.d.ts +30 -5
- package/dist/crypto-utils.js +146 -41
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +40 -30
- package/dist/function/functions.types.d.ts +44 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -11
- package/dist/handle-error.js +6 -18
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +3 -40
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +3 -2
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +8 -7
- package/dist/schema.d.ts +7 -17
- package/dist/schema.js +30 -18
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.js +1 -2
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +5 -6
- package/dist/services/index.js +2 -5
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +0 -4
- package/dist/services/local-secrets.js +0 -4
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +2 -37
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +9 -41
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +0 -4
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +5 -33
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +0 -7
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +19 -63
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +0 -17
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +99 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
- package/dist/wirings/ai-agent/voice-input.js +46 -3
- package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
- package/dist/wirings/ai-agent/voice-output.js +153 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
- package/dist/wirings/cli/channel/index.d.ts +4 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +1 -100
- package/dist/wirings/http/http-runner.js +12 -166
- package/dist/wirings/http/http.types.d.ts +16 -55
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +6 -36
- package/dist/wirings/http/pikku-fetch-http-request.js +56 -50
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +6 -16
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +28 -0
- package/dist/wirings/persona/define-personas.js +27 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +125 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +102 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +18 -89
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
- package/dist/wirings/rpc/remote-addon-auth.js +1 -9
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +27 -0
- package/dist/wirings/virtual-user/index.js +8 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +0 -18
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +0 -197
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +113 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +4 -2
- package/run-tests.sh +0 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +283 -55
- package/src/data-classification.ts +1 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +75 -7
- package/src/function/function-runner.ts +73 -30
- package/src/function/functions.types.ts +56 -136
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +8 -18
- package/src/index.ts +60 -1
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +0 -3
- package/src/middleware/auth-bearer.ts +3 -40
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +24 -9
- package/src/middleware/remote-auth.ts +10 -2
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +172 -0
- package/src/remote.ts +17 -7
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +35 -18
- package/src/scopes.ts +7 -48
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +1 -2
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/deployment-service.ts +3 -9
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +20 -15
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.ts +0 -4
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +2 -37
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.ts +9 -41
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +0 -4
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +5 -33
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +1 -7
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +19 -63
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +0 -26
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +116 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
- package/src/wirings/ai-agent/index.ts +35 -3
- package/src/wirings/ai-agent/voice-input.test.ts +72 -7
- package/src/wirings/ai-agent/voice-input.ts +48 -3
- package/src/wirings/ai-agent/voice-output.test.ts +422 -0
- package/src/wirings/ai-agent/voice-output.ts +216 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
- package/src/wirings/cli/channel/index.ts +9 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +12 -168
- package/src/wirings/http/http.types.ts +17 -62
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +88 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +74 -50
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +29 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +131 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +453 -0
- package/src/wirings/queue/queue-identity.ts +173 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +19 -89
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +59 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +1 -13
- package/src/wirings/rpc/rpc-runner.test.ts +186 -2
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +76 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.ts +0 -28
- package/src/wirings/workflow/scenario-service.test.ts +2 -9
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +159 -14
- package/src/wirings/workflow/scenario-step.types.ts +82 -6
- package/src/wirings/workflow/scenario-surface.test.ts +145 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +0 -203
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/services/gopass-secrets.ts +0 -78
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -16,18 +16,6 @@ export const clearChannelMiddlewareCache = () => {
|
|
|
16
16
|
delete channelMiddlewareCache[key];
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Combine the inherited (tag/named) channel middleware with any per-run
|
|
21
|
-
* middleware for a wiring.
|
|
22
|
-
*
|
|
23
|
-
* Only the statically-resolved inherited middleware is deterministic per `uid`
|
|
24
|
-
* and safe to cache. `wireChannelMiddleware` is a per-run set of closures (e.g.
|
|
25
|
-
* an AI agent's per-invocation stream middleware holding that run's
|
|
26
|
-
* thread/session state) and MUST NOT be cached — caching it lets a later run of
|
|
27
|
-
* the same `uid` reuse an earlier run's closures, leaking that run's state (and
|
|
28
|
-
* growing memory) across invocations. It is therefore appended fresh on every
|
|
29
|
-
* call after the cached inherited slice.
|
|
30
|
-
*/
|
|
31
19
|
export const combineChannelMiddleware = (wireType, uid, { wireInheritedChannelMiddleware, wireChannelMiddleware, packageName = null, } = {}) => {
|
|
32
20
|
const cacheKey = `${wireType}:${uid}`;
|
|
33
21
|
let inherited = channelMiddlewareCache[cacheKey];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ChannelRPCResponse } from './channel-rpc.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks in-flight reverse RPC calls for one channel. One registry per
|
|
4
|
+
* connection: ids are only unique within a socket, and a dropped socket must
|
|
5
|
+
* reject exactly the calls that were riding on it.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ChannelRPCRegistry {
|
|
8
|
+
private readonly timeoutMs;
|
|
9
|
+
private pending;
|
|
10
|
+
private nextId;
|
|
11
|
+
private closed;
|
|
12
|
+
constructor(timeoutMs?: number);
|
|
13
|
+
get inFlight(): number;
|
|
14
|
+
register(): {
|
|
15
|
+
id: string;
|
|
16
|
+
promise: Promise<unknown>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Stops the clock on a call whose peer is asking a human. The timeout exists
|
|
20
|
+
* to bound a peer that has gone away, and a person reading a prompt is not
|
|
21
|
+
* that; `rejectAll` still fails the call the moment the socket drops.
|
|
22
|
+
*
|
|
23
|
+
* Returns false for an unknown id — a pending frame for a call that already
|
|
24
|
+
* timed out is stale, not an error.
|
|
25
|
+
*/
|
|
26
|
+
hold(id: string): boolean;
|
|
27
|
+
/** Returns false for an unknown id, so a late reply is dropped. */
|
|
28
|
+
settle(response: ChannelRPCResponse): boolean;
|
|
29
|
+
/** Without this a caller awaits the full timeout on a connection that is gone. */
|
|
30
|
+
rejectAll(reason?: string): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ChannelRPCError, } from './channel-rpc.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks in-flight reverse RPC calls for one channel. One registry per
|
|
4
|
+
* connection: ids are only unique within a socket, and a dropped socket must
|
|
5
|
+
* reject exactly the calls that were riding on it.
|
|
6
|
+
*/
|
|
7
|
+
export class ChannelRPCRegistry {
|
|
8
|
+
timeoutMs;
|
|
9
|
+
pending = new Map();
|
|
10
|
+
nextId = 0;
|
|
11
|
+
closed = false;
|
|
12
|
+
constructor(timeoutMs = 30_000) {
|
|
13
|
+
this.timeoutMs = timeoutMs;
|
|
14
|
+
}
|
|
15
|
+
get inFlight() {
|
|
16
|
+
return this.pending.size;
|
|
17
|
+
}
|
|
18
|
+
register() {
|
|
19
|
+
if (this.closed) {
|
|
20
|
+
return {
|
|
21
|
+
id: '',
|
|
22
|
+
promise: Promise.reject(new ChannelRPCError('Channel is closed', 'closed')),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const id = `${++this.nextId}`;
|
|
26
|
+
const promise = new Promise((resolve, reject) => {
|
|
27
|
+
const timer = this.timeoutMs > 0
|
|
28
|
+
? setTimeout(() => {
|
|
29
|
+
this.pending.delete(id);
|
|
30
|
+
reject(new ChannelRPCError(`Channel RPC ${id} timed out after ${this.timeoutMs}ms`, 'timeout'));
|
|
31
|
+
}, this.timeoutMs)
|
|
32
|
+
: undefined;
|
|
33
|
+
// Never hold the process open waiting on a peer that may not answer.
|
|
34
|
+
timer?.unref?.();
|
|
35
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
36
|
+
});
|
|
37
|
+
return { id, promise };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Stops the clock on a call whose peer is asking a human. The timeout exists
|
|
41
|
+
* to bound a peer that has gone away, and a person reading a prompt is not
|
|
42
|
+
* that; `rejectAll` still fails the call the moment the socket drops.
|
|
43
|
+
*
|
|
44
|
+
* Returns false for an unknown id — a pending frame for a call that already
|
|
45
|
+
* timed out is stale, not an error.
|
|
46
|
+
*/
|
|
47
|
+
hold(id) {
|
|
48
|
+
const call = this.pending.get(id);
|
|
49
|
+
if (!call || call.awaitingHuman) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
clearTimeout(call.timer);
|
|
53
|
+
call.timer = undefined;
|
|
54
|
+
call.awaitingHuman = true;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
/** Returns false for an unknown id, so a late reply is dropped. */
|
|
58
|
+
settle(response) {
|
|
59
|
+
const call = this.pending.get(response.id);
|
|
60
|
+
if (!call) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
this.pending.delete(response.id);
|
|
64
|
+
clearTimeout(call.timer);
|
|
65
|
+
if (response.ok) {
|
|
66
|
+
call.resolve(response.result);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Peer input: a non-string name or message falls back rather than being
|
|
70
|
+
// attached to an Error, where it would surface as `[object Object]`.
|
|
71
|
+
const { name, message } = response.error ?? {};
|
|
72
|
+
const error = new ChannelRPCError(typeof message === 'string' ? message : 'Remote channel RPC failed', 'remote');
|
|
73
|
+
if (typeof name === 'string' && name.length > 0) {
|
|
74
|
+
error.name = name;
|
|
75
|
+
}
|
|
76
|
+
call.reject(error);
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
/** Without this a caller awaits the full timeout on a connection that is gone. */
|
|
81
|
+
rejectAll(reason = 'Channel closed') {
|
|
82
|
+
this.closed = true;
|
|
83
|
+
for (const [, call] of this.pending) {
|
|
84
|
+
clearTimeout(call.timer);
|
|
85
|
+
call.reject(new ChannelRPCError(reason, 'closed'));
|
|
86
|
+
}
|
|
87
|
+
this.pending.clear();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ApprovalRequester, type Capabilities } from './channel-rpc.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Answers reverse RPC requests arriving on a channel.
|
|
4
|
+
*
|
|
5
|
+
* `capabilities` is the authorisation boundary, not a convenience: the peer is
|
|
6
|
+
* asking this process to execute code, so only listed names run. An absent
|
|
7
|
+
* name is refused exactly like an unknown one, so the caller cannot probe for
|
|
8
|
+
* what this end can do.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createChannelRPCResponder: ({ capabilities, send, approve, }: {
|
|
11
|
+
capabilities: Capabilities;
|
|
12
|
+
send: (data: unknown) => Promise<void> | void;
|
|
13
|
+
/** Omitted means there is nobody to ask, which refuses rather than runs. */
|
|
14
|
+
approve?: ApprovalRequester;
|
|
15
|
+
}) => (message: unknown) => Promise<boolean>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CHANNEL_RPC_PENDING, CHANNEL_RPC_RESPONSE, isCapabilityDef, isChannelRPCRequest, resolveCapability, } from './channel-rpc.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Answers reverse RPC requests arriving on a channel.
|
|
4
|
+
*
|
|
5
|
+
* `capabilities` is the authorisation boundary, not a convenience: the peer is
|
|
6
|
+
* asking this process to execute code, so only listed names run. An absent
|
|
7
|
+
* name is refused exactly like an unknown one, so the caller cannot probe for
|
|
8
|
+
* what this end can do.
|
|
9
|
+
*/
|
|
10
|
+
export const createChannelRPCResponder = ({ capabilities, send, approve, }) => {
|
|
11
|
+
return async (message) => {
|
|
12
|
+
if (!isChannelRPCRequest(message)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const refuse = (name, why) => ({
|
|
16
|
+
action: CHANNEL_RPC_RESPONSE,
|
|
17
|
+
id: message.id,
|
|
18
|
+
ok: false,
|
|
19
|
+
error: { name, message: why },
|
|
20
|
+
});
|
|
21
|
+
// Own properties only: an object literal inherits from `Object.prototype`,
|
|
22
|
+
// so a peer asking for `toString` would otherwise resolve a real function.
|
|
23
|
+
const entry = Object.prototype.hasOwnProperty.call(capabilities, message.funcName)
|
|
24
|
+
? capabilities[message.funcName]
|
|
25
|
+
: undefined;
|
|
26
|
+
if (entry === undefined ||
|
|
27
|
+
(typeof entry !== 'function' && !isCapabilityDef(entry))) {
|
|
28
|
+
await send(refuse('RPCNotFoundError', `Capability not exposed: ${message.funcName}`));
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const { execute, needsApproval, approvalDescriptionFn } = resolveCapability(entry);
|
|
32
|
+
let response;
|
|
33
|
+
try {
|
|
34
|
+
if (needsApproval) {
|
|
35
|
+
if (!approve) {
|
|
36
|
+
await send(refuse('RPCNotApprovedError', `"${message.funcName}" needs approval and there is nobody to ask`));
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// Before the asking, not after: an answer arriving past the caller's
|
|
40
|
+
// timeout is dropped, silently discarding the human's decision.
|
|
41
|
+
const description = await approvalDescriptionFn?.(message.data);
|
|
42
|
+
await send({
|
|
43
|
+
action: CHANNEL_RPC_PENDING,
|
|
44
|
+
id: message.id,
|
|
45
|
+
reason: description ?? `approval for ${message.funcName}`,
|
|
46
|
+
});
|
|
47
|
+
const approved = await approve({
|
|
48
|
+
funcName: message.funcName,
|
|
49
|
+
data: message.data,
|
|
50
|
+
description,
|
|
51
|
+
});
|
|
52
|
+
if (!approved) {
|
|
53
|
+
await send(refuse('RPCDeniedError', `"${message.funcName}" was not approved`));
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
response = {
|
|
58
|
+
action: CHANNEL_RPC_RESPONSE,
|
|
59
|
+
id: message.id,
|
|
60
|
+
ok: true,
|
|
61
|
+
result: await execute(message.data),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
const error = e;
|
|
66
|
+
response = refuse(error?.name ?? 'Error', error?.message ?? String(e));
|
|
67
|
+
}
|
|
68
|
+
await send(response);
|
|
69
|
+
return true;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { DeploymentService } from '../../services/deployment-service.js';
|
|
2
|
+
import { ChannelRPCRegistry } from './channel-rpc-registry.js';
|
|
3
|
+
import { type ChannelRPCValidator } from './channel-rpc.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* `remote` for channels that only ever flow one way — a server-sent stream, an
|
|
6
|
+
* agent's output, a local CLI. Nothing is listening for a request on them, so
|
|
7
|
+
* the call is refused rather than waiting out a timeout.
|
|
8
|
+
*/
|
|
9
|
+
export declare const unsupportedChannelRemote: (funcName: string) => Promise<never>;
|
|
10
|
+
/**
|
|
11
|
+
* A `DeploymentService` whose transport is an open channel rather than an
|
|
12
|
+
* address, so a server-side function can call back into a peer that has no
|
|
13
|
+
* inbound route of its own.
|
|
14
|
+
*
|
|
15
|
+
* It slots into the existing `services.deploymentService` hole, leaving
|
|
16
|
+
* `rpc.remote` resolution, session propagation and traceId plumbing unchanged.
|
|
17
|
+
*/
|
|
18
|
+
export declare class ChannelDeploymentService implements DeploymentService {
|
|
19
|
+
private readonly send;
|
|
20
|
+
readonly registry: ChannelRPCRegistry;
|
|
21
|
+
private readonly validateInput?;
|
|
22
|
+
private readonly validateResult?;
|
|
23
|
+
constructor(send: (data: unknown) => Promise<void> | void, options?: {
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
validateInput?: ChannelRPCValidator;
|
|
26
|
+
validateResult?: ChannelRPCValidator;
|
|
27
|
+
});
|
|
28
|
+
init(): Promise<void>;
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
stop(): Promise<void>;
|
|
31
|
+
/** The channel owner must call this — the service has no read side. */
|
|
32
|
+
handleResponse(message: unknown): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* `session` is accepted to satisfy `DeploymentService` and deliberately not
|
|
35
|
+
* sent: the peer runs the capability as itself, on its own machine, so a
|
|
36
|
+
* session on the wire would carry the caller's credentials while authorising
|
|
37
|
+
* nothing.
|
|
38
|
+
*/
|
|
39
|
+
invoke(funcName: string, data: unknown, _session?: unknown, traceId?: string): Promise<unknown>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ChannelRPCRegistry } from './channel-rpc-registry.js';
|
|
2
|
+
import { CHANNEL_RPC_REQUEST, CHANNEL_RPC_RESPONSE, ChannelRPCError, isChannelRPCPending, isChannelRPCResponse, } from './channel-rpc.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* `remote` for channels that only ever flow one way — a server-sent stream, an
|
|
5
|
+
* agent's output, a local CLI. Nothing is listening for a request on them, so
|
|
6
|
+
* the call is refused rather than waiting out a timeout.
|
|
7
|
+
*/
|
|
8
|
+
export const unsupportedChannelRemote = async (funcName) => {
|
|
9
|
+
throw new ChannelRPCError(`Cannot call "${funcName}" remotely: this channel has no peer that answers`, 'unsupported');
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* A `DeploymentService` whose transport is an open channel rather than an
|
|
13
|
+
* address, so a server-side function can call back into a peer that has no
|
|
14
|
+
* inbound route of its own.
|
|
15
|
+
*
|
|
16
|
+
* It slots into the existing `services.deploymentService` hole, leaving
|
|
17
|
+
* `rpc.remote` resolution, session propagation and traceId plumbing unchanged.
|
|
18
|
+
*/
|
|
19
|
+
export class ChannelDeploymentService {
|
|
20
|
+
send;
|
|
21
|
+
registry;
|
|
22
|
+
validateInput;
|
|
23
|
+
validateResult;
|
|
24
|
+
constructor(send, options = {}) {
|
|
25
|
+
this.send = send;
|
|
26
|
+
this.registry = new ChannelRPCRegistry(options.timeoutMs);
|
|
27
|
+
this.validateInput = options.validateInput;
|
|
28
|
+
this.validateResult = options.validateResult;
|
|
29
|
+
}
|
|
30
|
+
async init() { }
|
|
31
|
+
async start() { }
|
|
32
|
+
async stop() {
|
|
33
|
+
this.registry.rejectAll('Deployment service stopped');
|
|
34
|
+
}
|
|
35
|
+
/** The channel owner must call this — the service has no read side. */
|
|
36
|
+
handleResponse(message) {
|
|
37
|
+
if (isChannelRPCPending(message)) {
|
|
38
|
+
return this.registry.hold(message.id);
|
|
39
|
+
}
|
|
40
|
+
return isChannelRPCResponse(message) ? this.registry.settle(message) : false;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `session` is accepted to satisfy `DeploymentService` and deliberately not
|
|
44
|
+
* sent: the peer runs the capability as itself, on its own machine, so a
|
|
45
|
+
* session on the wire would carry the caller's credentials while authorising
|
|
46
|
+
* nothing.
|
|
47
|
+
*/
|
|
48
|
+
async invoke(funcName, data, _session, traceId) {
|
|
49
|
+
// Not a security control — the peer must check what it is handed, and a
|
|
50
|
+
// hostile caller would send arguments that pass. It catches version drift
|
|
51
|
+
// and fails it here rather than inside the peer's process.
|
|
52
|
+
if (this.validateInput) {
|
|
53
|
+
try {
|
|
54
|
+
await this.validateInput(funcName, data);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
throw new ChannelRPCError(`Invalid arguments for "${funcName}": ${e?.message ?? String(e)}`, 'invalid');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const { id, promise } = this.registry.register();
|
|
61
|
+
// A closed registry answers with an already-rejected promise and no id.
|
|
62
|
+
// Returning it before the send keeps that rejection from sitting unobserved.
|
|
63
|
+
if (!id) {
|
|
64
|
+
return promise;
|
|
65
|
+
}
|
|
66
|
+
const request = {
|
|
67
|
+
action: CHANNEL_RPC_REQUEST,
|
|
68
|
+
id,
|
|
69
|
+
funcName,
|
|
70
|
+
data,
|
|
71
|
+
traceId,
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
await this.send(request);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
// The call is registered before the request goes out, so a failed send
|
|
78
|
+
// would otherwise leave an entry whose timeout rejects into an unhandled
|
|
79
|
+
// rejection with nobody waiting on it.
|
|
80
|
+
this.registry.settle({
|
|
81
|
+
action: CHANNEL_RPC_RESPONSE,
|
|
82
|
+
id,
|
|
83
|
+
ok: false,
|
|
84
|
+
error: {
|
|
85
|
+
name: e?.name ?? 'Error',
|
|
86
|
+
message: e?.message ?? String(e),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
promise.catch(() => { });
|
|
90
|
+
throw e;
|
|
91
|
+
}
|
|
92
|
+
const result = await promise;
|
|
93
|
+
if (!this.validateResult) {
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
// The peer answers with whatever it likes, so this is where a value that
|
|
97
|
+
// has been through nothing enters a server-side command.
|
|
98
|
+
try {
|
|
99
|
+
await this.validateResult(funcName, result);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
throw new ChannelRPCError(`Invalid result from "${funcName}": ${e?.message ?? String(e)}`, 'invalid');
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CoreSingletonServices } from '../../types/core.types.js';
|
|
2
|
+
import type { ChannelRPCValidator } from './channel-rpc.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Checks a capability's answer against the schema codegen generated from its
|
|
5
|
+
* declared return type — the same one an agent tool or an HTTP response is
|
|
6
|
+
* checked against.
|
|
7
|
+
*/
|
|
8
|
+
export declare const createChannelRPCResultValidator: (singletonServices: Pick<CoreSingletonServices, "logger" | "schema">, packageName?: string | null) => ChannelRPCValidator;
|
|
9
|
+
/**
|
|
10
|
+
* Checks outbound arguments against the declared input type. Unlike the result
|
|
11
|
+
* check this is not a boundary — it catches version drift, where a server built
|
|
12
|
+
* against a newer capability signature calls a client that predates it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createChannelRPCInputValidator: (singletonServices: Pick<CoreSingletonServices, "logger" | "schema">, packageName?: string | null) => ChannelRPCValidator;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { pikkuState } from '../../pikku-state.js';
|
|
2
|
+
import { validateSchema } from '../../schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* A name with no function metadata is left alone: it is a capability this app
|
|
5
|
+
* never declared a contract for, and failing it would break callers that
|
|
6
|
+
* deliberately treat the value as opaque.
|
|
7
|
+
*/
|
|
8
|
+
const createChannelRPCSchemaValidator = (key, singletonServices, packageName = null) => async (funcName, value) => {
|
|
9
|
+
const pikkuFuncId = pikkuState(packageName, 'rpc', 'meta')[funcName];
|
|
10
|
+
if (!pikkuFuncId) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const schemaName = pikkuState(packageName, 'function', 'meta')[pikkuFuncId]?.[key];
|
|
14
|
+
if (!schemaName) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await validateSchema(singletonServices.logger, singletonServices.schema, schemaName, value, packageName);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Checks a capability's answer against the schema codegen generated from its
|
|
21
|
+
* declared return type — the same one an agent tool or an HTTP response is
|
|
22
|
+
* checked against.
|
|
23
|
+
*/
|
|
24
|
+
export const createChannelRPCResultValidator = (singletonServices, packageName = null) => createChannelRPCSchemaValidator('outputSchemaName', singletonServices, packageName);
|
|
25
|
+
/**
|
|
26
|
+
* Checks outbound arguments against the declared input type. Unlike the result
|
|
27
|
+
* check this is not a boundary — it catches version drift, where a server built
|
|
28
|
+
* against a newer capability signature calls a client that predates it.
|
|
29
|
+
*/
|
|
30
|
+
export const createChannelRPCInputValidator = (singletonServices, packageName = null) => createChannelRPCSchemaValidator('inputSchemaName', singletonServices, packageName);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Envelope actions for request/response RPC carried over an already-open
|
|
3
|
+
* channel. Both directions share one socket, so every frame is tagged and
|
|
4
|
+
* correlated by `id`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CHANNEL_RPC_REQUEST = "pikku-rpc-request";
|
|
7
|
+
export declare const CHANNEL_RPC_RESPONSE = "pikku-rpc-response";
|
|
8
|
+
export declare const CHANNEL_RPC_PENDING = "pikku-rpc-pending";
|
|
9
|
+
export interface ChannelRPCRequest {
|
|
10
|
+
action: typeof CHANNEL_RPC_REQUEST;
|
|
11
|
+
id: string;
|
|
12
|
+
funcName: string;
|
|
13
|
+
data: unknown;
|
|
14
|
+
traceId?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ChannelRPCResponse {
|
|
17
|
+
action: typeof CHANNEL_RPC_RESPONSE;
|
|
18
|
+
id: string;
|
|
19
|
+
ok: boolean;
|
|
20
|
+
result?: unknown;
|
|
21
|
+
error?: {
|
|
22
|
+
name: string;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* "Still working on it — a human is being asked." Stops the caller's timeout,
|
|
28
|
+
* which otherwise fails any approval slower than it and then discards the
|
|
29
|
+
* answer when it arrives. Grants nothing: a peer that sends it dishonestly can
|
|
30
|
+
* only keep its own call waiting.
|
|
31
|
+
*/
|
|
32
|
+
export interface ChannelRPCPending {
|
|
33
|
+
action: typeof CHANNEL_RPC_PENDING;
|
|
34
|
+
id: string;
|
|
35
|
+
reason?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The guards check the whole envelope, not just the action tag: `id` is peer
|
|
39
|
+
* input and is used as a map key, so a frame carrying one of the wrong type
|
|
40
|
+
* must not reach `settle`.
|
|
41
|
+
*/
|
|
42
|
+
export declare const isChannelRPCRequest: (message: unknown) => message is ChannelRPCRequest;
|
|
43
|
+
export declare const isChannelRPCResponse: (message: unknown) => message is ChannelRPCResponse;
|
|
44
|
+
export declare const isChannelRPCPending: (message: unknown) => message is ChannelRPCPending;
|
|
45
|
+
/** `reason` exists so a dropped socket cannot look like a resolved call. */
|
|
46
|
+
export declare class ChannelRPCError extends Error {
|
|
47
|
+
readonly reason: 'timeout' | 'closed' | 'remote' | 'invalid' | 'unsupported';
|
|
48
|
+
constructor(message: string, reason: 'timeout' | 'closed' | 'remote' | 'invalid' | 'unsupported');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Whether a callable exposed to a remote decider needs a human to agree before
|
|
52
|
+
* it runs, and how to describe the invocation while asking.
|
|
53
|
+
*
|
|
54
|
+
* Shared with `AIAgentToolDef`: both are an allowlist of named callables
|
|
55
|
+
* invoked by something other than the code that wrote them. The runtime around
|
|
56
|
+
* them is not shared — an agent suspends and resumes, a reverse call is a live
|
|
57
|
+
* await.
|
|
58
|
+
*/
|
|
59
|
+
export interface ApprovalPolicy {
|
|
60
|
+
needsApproval: boolean;
|
|
61
|
+
approvalDescriptionFn?: (input: unknown) => Promise<string> | string;
|
|
62
|
+
}
|
|
63
|
+
export type CapabilityHandler = (data: any) => Promise<unknown> | unknown;
|
|
64
|
+
/**
|
|
65
|
+
* `needsApproval` is required here on purpose. On `AIAgentToolDef` the same
|
|
66
|
+
* field is optional and absence means "do not ask"; here absence means the
|
|
67
|
+
* opposite, so it must not be expressible — a bare function is the
|
|
68
|
+
* unclassified form.
|
|
69
|
+
*/
|
|
70
|
+
export interface CapabilityDef extends ApprovalPolicy {
|
|
71
|
+
execute: CapabilityHandler;
|
|
72
|
+
}
|
|
73
|
+
export type Capability = CapabilityHandler | CapabilityDef;
|
|
74
|
+
export type Capabilities = Record<string, Capability>;
|
|
75
|
+
export declare const isCapabilityDef: (capability: Capability) => capability is CapabilityDef;
|
|
76
|
+
/**
|
|
77
|
+
* A bare function is unclassified, which resolves to needing approval:
|
|
78
|
+
* forgetting the annotation costs a prompt rather than costing a key.
|
|
79
|
+
*/
|
|
80
|
+
export declare const resolveCapability: (capability: Capability) => {
|
|
81
|
+
execute: CapabilityHandler;
|
|
82
|
+
} & ApprovalPolicy;
|
|
83
|
+
/** Returning false refuses the call, and the peer is told so. */
|
|
84
|
+
export type ApprovalRequester = (request: {
|
|
85
|
+
funcName: string;
|
|
86
|
+
data: unknown;
|
|
87
|
+
description?: string;
|
|
88
|
+
}) => Promise<boolean> | boolean;
|
|
89
|
+
/** Checks one end of a call — arguments going out, or the answer coming back. */
|
|
90
|
+
export type ChannelRPCValidator = (funcName: string, value: unknown) => Promise<void> | void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Envelope actions for request/response RPC carried over an already-open
|
|
3
|
+
* channel. Both directions share one socket, so every frame is tagged and
|
|
4
|
+
* correlated by `id`.
|
|
5
|
+
*/
|
|
6
|
+
export const CHANNEL_RPC_REQUEST = 'pikku-rpc-request';
|
|
7
|
+
export const CHANNEL_RPC_RESPONSE = 'pikku-rpc-response';
|
|
8
|
+
export const CHANNEL_RPC_PENDING = 'pikku-rpc-pending';
|
|
9
|
+
const isRecord = (message) => typeof message === 'object' && message !== null;
|
|
10
|
+
/**
|
|
11
|
+
* The guards check the whole envelope, not just the action tag: `id` is peer
|
|
12
|
+
* input and is used as a map key, so a frame carrying one of the wrong type
|
|
13
|
+
* must not reach `settle`.
|
|
14
|
+
*/
|
|
15
|
+
export const isChannelRPCRequest = (message) => isRecord(message) &&
|
|
16
|
+
message.action === CHANNEL_RPC_REQUEST &&
|
|
17
|
+
typeof message.id === 'string' &&
|
|
18
|
+
message.id.length > 0 &&
|
|
19
|
+
typeof message.funcName === 'string' &&
|
|
20
|
+
message.funcName.length > 0 &&
|
|
21
|
+
(message.traceId === undefined || typeof message.traceId === 'string');
|
|
22
|
+
export const isChannelRPCResponse = (message) => isRecord(message) &&
|
|
23
|
+
message.action === CHANNEL_RPC_RESPONSE &&
|
|
24
|
+
typeof message.id === 'string' &&
|
|
25
|
+
message.id.length > 0 &&
|
|
26
|
+
typeof message.ok === 'boolean';
|
|
27
|
+
export const isChannelRPCPending = (message) => isRecord(message) &&
|
|
28
|
+
message.action === CHANNEL_RPC_PENDING &&
|
|
29
|
+
typeof message.id === 'string' &&
|
|
30
|
+
message.id.length > 0 &&
|
|
31
|
+
(message.reason === undefined || typeof message.reason === 'string');
|
|
32
|
+
/** `reason` exists so a dropped socket cannot look like a resolved call. */
|
|
33
|
+
export class ChannelRPCError extends Error {
|
|
34
|
+
reason;
|
|
35
|
+
constructor(message, reason) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.reason = reason;
|
|
38
|
+
this.name = 'ChannelRPCError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export const isCapabilityDef = (capability) => typeof capability === 'object' &&
|
|
42
|
+
capability !== null &&
|
|
43
|
+
typeof capability.execute === 'function';
|
|
44
|
+
/**
|
|
45
|
+
* A bare function is unclassified, which resolves to needing approval:
|
|
46
|
+
* forgetting the annotation costs a prompt rather than costing a key.
|
|
47
|
+
*/
|
|
48
|
+
export const resolveCapability = (capability) => isCapabilityDef(capability)
|
|
49
|
+
? capability
|
|
50
|
+
: { execute: capability, needsApproval: true };
|
|
@@ -2,10 +2,6 @@ import type { CorePikkuPermission } from '../../function/functions.types.js';
|
|
|
2
2
|
import type { SessionService } from '../../services/user-session-service.js';
|
|
3
3
|
import type { CorePikkuMiddleware } from '../../types/core.types.js';
|
|
4
4
|
import type { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from './channel.types.js';
|
|
5
|
-
/**
|
|
6
|
-
* Adds a channel and registers all functions referenced in it using the
|
|
7
|
-
* function names already stored in the channel metadata
|
|
8
|
-
*/
|
|
9
5
|
export declare const wireChannel: <In, Channel extends string, PikkuPermission extends CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware, ChannelFunction>(channel: CoreChannel<In, Channel, PikkuPermission, PikkuMiddleware, ChannelFunction>) => void;
|
|
10
6
|
export declare const openChannel: ({ route, coerceDataFromSchema, request, }: Pick<CoreChannel<unknown, string>, "route"> & RunChannelParams<unknown> & {
|
|
11
7
|
userSession: SessionService<any>;
|
|
@@ -3,53 +3,39 @@ import { addFunction } from '../../function/function-runner.js';
|
|
|
3
3
|
import { pikkuState, getSingletonServices } from '../../pikku-state.js';
|
|
4
4
|
import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js';
|
|
5
5
|
import { httpRouter } from '../http/routers/http-router.js';
|
|
6
|
-
/**
|
|
7
|
-
* Adds a channel and registers all functions referenced in it using the
|
|
8
|
-
* function names already stored in the channel metadata
|
|
9
|
-
*/
|
|
10
6
|
export const wireChannel = (channel) => {
|
|
11
|
-
// Get the channel metadata
|
|
12
7
|
const channelsMeta = pikkuState(null, 'channel', 'meta');
|
|
13
8
|
const channelMeta = channelsMeta[channel.name];
|
|
14
9
|
if (!channelMeta) {
|
|
15
10
|
console.warn(`[pikku] Skipping channel '${channel.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
16
11
|
return;
|
|
17
12
|
}
|
|
18
|
-
// Register onConnect function if provided
|
|
19
13
|
if (channel.onConnect && channelMeta.connect) {
|
|
20
14
|
addFunction(channelMeta.connect.pikkuFuncId, channel.onConnect);
|
|
21
15
|
}
|
|
22
|
-
// Register onDisconnect function if provided
|
|
23
16
|
if (channel.onDisconnect && channelMeta.disconnect) {
|
|
24
17
|
addFunction(channelMeta.disconnect.pikkuFuncId, channel.onDisconnect);
|
|
25
18
|
}
|
|
26
|
-
// Register onMessage function if provided
|
|
27
19
|
if (channel.onMessage && channelMeta.message?.pikkuFuncId) {
|
|
28
20
|
addFunction(channelMeta.message.pikkuFuncId, channel.onMessage.func instanceof Function
|
|
29
21
|
? channel.onMessage
|
|
30
22
|
: channel.onMessage.func);
|
|
31
23
|
}
|
|
32
|
-
// Register functions in onMessageWiring
|
|
33
24
|
if (channel.onMessageWiring && channelMeta.messageWirings) {
|
|
34
|
-
// Iterate through each channel in onMessageWiring
|
|
35
25
|
Object.entries(channel.onMessageWiring).forEach(([channelKey, wirings]) => {
|
|
36
26
|
const channelWirings = channelMeta.messageWirings[channelKey];
|
|
37
27
|
if (!channelWirings)
|
|
38
28
|
return;
|
|
39
|
-
// Iterate through each wiring in the channel
|
|
40
29
|
Object.entries(wirings).forEach(([wiringKey, handler]) => {
|
|
41
30
|
const wiringMeta = channelWirings[wiringKey];
|
|
42
31
|
if (!wiringMeta)
|
|
43
32
|
return;
|
|
44
|
-
// Register the function using the pikku name from metadata
|
|
45
|
-
// It could be a FuncConfig or a wiring override with a funcConfig
|
|
46
33
|
addFunction(wiringMeta.pikkuFuncId, handler.func instanceof Function
|
|
47
34
|
? handler
|
|
48
35
|
: handler.func);
|
|
49
36
|
});
|
|
50
37
|
});
|
|
51
38
|
}
|
|
52
|
-
// Store the channel configuration
|
|
53
39
|
pikkuState(null, 'channel', 'channels').set(channel.name, channel);
|
|
54
40
|
};
|
|
55
41
|
const getMatchingChannelConfig = (path) => {
|
|
@@ -13,16 +13,6 @@ export declare abstract class ChannelStore<ChannelType = unknown, OpeningData =
|
|
|
13
13
|
}> | (TypedChannel & {
|
|
14
14
|
pikkuUserId?: string;
|
|
15
15
|
});
|
|
16
|
-
/**
|
|
17
|
-
* Persist per-socket scratch state scoped to a single channel (keyed by
|
|
18
|
-
* channelId). This is intentionally separate from `SessionStore` (which is
|
|
19
|
-
* keyed by `pikkuUserId` and holds the user session — shared across HTTP
|
|
20
|
-
* and channel transports).
|
|
21
|
-
*
|
|
22
|
-
* Use this for ephemeral, channel-local data: a per-socket subscription
|
|
23
|
-
* filter, a step in a connection-bound state machine, the last command sent
|
|
24
|
-
* on this socket, etc. It is cleared when the channel is removed.
|
|
25
|
-
*/
|
|
26
16
|
abstract setState(channelId: string, state: unknown): Promise<void> | void;
|
|
27
17
|
abstract getState(channelId: string): Promise<unknown | undefined> | unknown | undefined;
|
|
28
18
|
abstract clearState(channelId: string): Promise<void> | void;
|