@pikku/core 0.12.72 → 0.12.77
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 +1171 -0
- package/dist/column-form.d.ts +32 -0
- package/dist/column-form.js +42 -0
- package/dist/crypto-utils.d.ts +43 -7
- package/dist/crypto-utils.js +163 -42
- package/dist/data-classification.d.ts +44 -0
- 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 +37 -32
- package/dist/function/functions.types.d.ts +57 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/index.d.ts +1 -1
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -13
- package/dist/handle-error.js +0 -18
- package/dist/index.d.ts +11 -5
- package/dist/index.js +7 -2
- 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 +5 -41
- 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 +4 -3
- 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 +9 -8
- package/dist/schema.d.ts +5 -39
- package/dist/schema.js +5 -39
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/secret-value.d.ts +56 -0
- package/dist/secret-value.js +46 -0
- 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.d.ts +74 -4
- package/dist/services/audit-service.js +8 -7
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/credential-wire-service.d.ts +5 -0
- package/dist/services/credential-wire-service.js +9 -1
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/email-service.d.ts +2 -1
- 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 +8 -9
- package/dist/services/index.js +3 -6
- 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-request-handler.d.ts +29 -0
- package/dist/services/local-content-request-handler.js +176 -0
- 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 +4 -7
- package/dist/services/local-secrets.js +7 -7
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +22 -40
- 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 +10 -42
- 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 +4 -7
- 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 +12 -35
- 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 +5 -11
- 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 +21 -64
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +6 -23
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +120 -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 +46 -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 +65 -132
- 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 +63 -22
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +180 -64
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +124 -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 +59 -1
- package/dist/wirings/ai-agent/voice-input.js +90 -12
- package/dist/wirings/ai-agent/voice-output.d.ts +69 -1
- package/dist/wirings/ai-agent/voice-output.js +162 -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 +38 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +129 -0
- package/dist/wirings/cli/channel/index.d.ts +5 -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 +0 -99
- package/dist/wirings/http/http-runner.js +9 -165
- package/dist/wirings/http/http.types.d.ts +14 -55
- 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 +0 -40
- package/dist/wirings/http/pikku-fetch-http-request.js +0 -58
- 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 +1 -4
- package/dist/wirings/mcp/mcp-runner.js +1 -14
- 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 +32 -0
- package/dist/wirings/persona/define-personas.js +31 -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 +136 -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 +103 -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 +20 -90
- 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 +17 -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 +3 -13
- package/dist/wirings/rpc/remote-addon-auth.js +7 -11
- 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 +30 -0
- package/dist/wirings/virtual-user/index.js +10 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +54 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.js +49 -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-run-store.d.ts +90 -0
- package/dist/wirings/virtual-user/virtual-user-run-store.js +1 -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 +19 -15
- 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 -43
- 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 +1 -19
- 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 +84 -12
- 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 +5 -195
- 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/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +48 -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-column-form-is-an-axis-of-its-own.md +84 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +41 -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 +117 -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/one-project-shape-check-two-validators.md +53 -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/scenarios-live-in-files-named-for-them.md +48 -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/validate-checks-personas-through-a-shared-module.md +43 -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 +6 -2
- package/run-tests.sh +0 -0
- package/src/column-form.test.ts +97 -0
- package/src/column-form.ts +58 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +306 -59
- package/src/data-classification.ts +45 -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 +0 -7
- package/src/function/function-runner.ts +62 -32
- package/src/function/functions.types.ts +95 -138
- package/src/function/index.ts +1 -0
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/handle-error.ts +0 -18
- package/src/index.ts +84 -3
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +3 -5
- package/src/middleware/auth-bearer.ts +5 -41
- 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 +26 -10
- package/src/middleware/remote-auth.ts +11 -3
- 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 +173 -0
- package/src/remote.ts +18 -8
- package/src/schema.ts +5 -39
- package/src/scopes.ts +7 -48
- package/src/secret-value.test.ts +204 -0
- package/src/secret-value.ts +111 -0
- 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 +88 -11
- 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/credential-wire-service.ts +9 -1
- package/src/services/deployment-service.ts +3 -9
- package/src/services/email-service.ts +3 -1
- 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 +23 -18
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content-request-handler.test.ts +202 -0
- package/src/services/local-content-request-handler.ts +267 -0
- 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.test.ts +20 -5
- package/src/services/local-secrets.ts +15 -11
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +31 -46
- 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.test.ts +2 -1
- package/src/services/queue-webhook-service.ts +10 -42
- 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 +4 -7
- 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 +12 -35
- 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 +12 -14
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +23 -64
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +6 -32
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +137 -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 +91 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +49 -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 +89 -139
- 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 +85 -35
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +224 -76
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +130 -5
- package/src/wirings/ai-agent/index.ts +37 -3
- package/src/wirings/ai-agent/voice-input.test.ts +137 -7
- package/src/wirings/ai-agent/voice-input.ts +96 -12
- package/src/wirings/ai-agent/voice-output.test.ts +512 -0
- package/src/wirings/ai-agent/voice-output.ts +243 -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 +185 -0
- package/src/wirings/cli/channel/index.ts +13 -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 +8 -167
- package/src/wirings/http/http.types.ts +15 -62
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +2 -10
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -58
- 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.ts +2 -17
- 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 +33 -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 +142 -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 +454 -0
- package/src/wirings/queue/queue-identity.ts +176 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +25 -90
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +60 -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 +9 -16
- package/src/wirings/rpc/rpc-runner.test.ts +192 -6
- 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 +88 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +115 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +95 -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-run-store.ts +98 -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 +19 -20
- 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 -61
- 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.test.ts +5 -7
- package/src/wirings/workflow/scenario-prose.ts +1 -29
- package/src/wirings/workflow/scenario-service.test.ts +2 -10
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +163 -19
- package/src/wirings/workflow/scenario-step.types.ts +94 -12
- package/src/wirings/workflow/scenario-surface.test.ts +146 -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 +5 -201
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +12 -0
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- 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
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
import { pikkuState, getSingletonServices } from '../../pikku-state.js'
|
|
13
13
|
import { AIProviderNotConfiguredError } from '../../errors/errors.js'
|
|
14
14
|
import { randomUUID } from './ai-agent-utils.js'
|
|
15
|
+
import { SPOKEN_TRANSCRIPT } from './voice-input.js'
|
|
15
16
|
import {
|
|
16
17
|
combineChannelMiddleware,
|
|
17
18
|
wrapChannelWithMiddleware,
|
|
@@ -37,10 +38,12 @@ import {
|
|
|
37
38
|
resolveOwnerResourceId,
|
|
38
39
|
agentSessionScope,
|
|
39
40
|
assertResourceOwner,
|
|
41
|
+
assertResourcePrincipalOwner,
|
|
40
42
|
assertAgentAuthorized,
|
|
41
43
|
ToolApprovalRequired,
|
|
42
44
|
ToolCredentialRequired,
|
|
43
45
|
APPROVAL_REQUIRED,
|
|
46
|
+
CREDENTIAL_REQUIRED,
|
|
44
47
|
type RunAIAgentParams,
|
|
45
48
|
type StreamAIAgentOptions,
|
|
46
49
|
type StreamContext,
|
|
@@ -48,10 +51,21 @@ import {
|
|
|
48
51
|
import { resolveModelConfig } from './ai-agent-model-config.js'
|
|
49
52
|
import type { AIRunStateService } from '../../services/ai-run-state-service.js'
|
|
50
53
|
import type { AIAgentRunnerService } from '../../services/ai-agent-runner-service.js'
|
|
54
|
+
import {
|
|
55
|
+
getInFlightTools,
|
|
56
|
+
isAbortError,
|
|
57
|
+
persistOrphanedToolResults,
|
|
58
|
+
registerInterruptibleRun,
|
|
59
|
+
signalRunInterrupt,
|
|
60
|
+
trackInterruptNote,
|
|
61
|
+
trackToolExecution,
|
|
62
|
+
type AgentInterruption,
|
|
63
|
+
type AgentInterruptResult,
|
|
64
|
+
} from './ai-agent-interrupt.js'
|
|
51
65
|
|
|
52
66
|
type PersistingChannel = AIStreamChannel & {
|
|
53
67
|
fullText: string
|
|
54
|
-
flush: () => Promise<void>
|
|
68
|
+
flush: (opts?: { interrupted?: boolean }) => Promise<void>
|
|
55
69
|
totalUsage: { inputTokens: number; outputTokens: number; model?: string }
|
|
56
70
|
}
|
|
57
71
|
|
|
@@ -75,7 +89,7 @@ function createPersistingChannel(
|
|
|
75
89
|
outputTokens: 0,
|
|
76
90
|
}
|
|
77
91
|
|
|
78
|
-
const flushStep = async () => {
|
|
92
|
+
const flushStep = async (opts?: { interrupted?: boolean }) => {
|
|
79
93
|
if (!storage) return
|
|
80
94
|
const text = stepText
|
|
81
95
|
const generativeUI = stepGenerativeUI
|
|
@@ -97,6 +111,7 @@ function createPersistingChannel(
|
|
|
97
111
|
]
|
|
98
112
|
: text || undefined,
|
|
99
113
|
toolCalls: calls.length > 0 ? calls : undefined,
|
|
114
|
+
...(opts?.interrupted ? { interrupted: true } : {}),
|
|
100
115
|
createdAt: new Date(),
|
|
101
116
|
}
|
|
102
117
|
const messages: AIMessage[] = [assistantMsg]
|
|
@@ -112,14 +127,6 @@ function createPersistingChannel(
|
|
|
112
127
|
}
|
|
113
128
|
}
|
|
114
129
|
|
|
115
|
-
/**
|
|
116
|
-
* `send` is synchronous and so cannot await the flush. A rejection would have
|
|
117
|
-
* nothing to propagate to and would take the process down as an unhandled
|
|
118
|
-
* rejection — a model reusing a toolCallId, which is a primary key in AI
|
|
119
|
-
* storage, is enough to trigger it. Persistence from inside `send` is
|
|
120
|
-
* therefore best-effort: the run carries on, and the awaited `flush()` on the
|
|
121
|
-
* suspend paths still surfaces failures to its caller.
|
|
122
|
-
*/
|
|
123
130
|
const flushDetached = () => {
|
|
124
131
|
void flushStep().catch((error) => {
|
|
125
132
|
logger?.error('Failed to persist agent messages', {
|
|
@@ -145,11 +152,14 @@ function createPersistingChannel(
|
|
|
145
152
|
close: () => parent.close(),
|
|
146
153
|
sendBinary: (data) => parent.sendBinary(data),
|
|
147
154
|
send: (event: AIStreamEvent) => {
|
|
155
|
+
// Accumulated whether or not storage is configured: `fullText` is what
|
|
156
|
+
// the client was streamed, and an interrupted run has to be able to
|
|
157
|
+
// report the fragment it got through even with persistence turned off.
|
|
158
|
+
if (event.type === 'text-delta') fullText += event.text
|
|
148
159
|
if (storage) {
|
|
149
160
|
switch (event.type) {
|
|
150
161
|
case 'text-delta':
|
|
151
162
|
stepText += event.text
|
|
152
|
-
fullText += event.text
|
|
153
163
|
break
|
|
154
164
|
case 'tool-call':
|
|
155
165
|
stepToolCalls.push({
|
|
@@ -187,6 +197,7 @@ function createPersistingChannel(
|
|
|
187
197
|
setState: (s) => parent.setState(s),
|
|
188
198
|
getState: () => parent.getState(),
|
|
189
199
|
clearState: () => parent.clearState(),
|
|
200
|
+
remote: (funcName: string, data?: unknown) => parent.remote(funcName, data),
|
|
190
201
|
}
|
|
191
202
|
return channel
|
|
192
203
|
}
|
|
@@ -240,7 +251,6 @@ type StepLoopParams = {
|
|
|
240
251
|
streamChannel: AIStreamChannel
|
|
241
252
|
persistingChannel: PersistingChannel
|
|
242
253
|
channel: AIStreamChannel
|
|
243
|
-
runId: string
|
|
244
254
|
aiMiddlewares: PikkuAIMiddlewareHooks[]
|
|
245
255
|
}
|
|
246
256
|
|
|
@@ -259,7 +269,6 @@ async function runStreamStepLoop(
|
|
|
259
269
|
agentRunner,
|
|
260
270
|
streamChannel,
|
|
261
271
|
channel,
|
|
262
|
-
runId,
|
|
263
272
|
aiMiddlewares,
|
|
264
273
|
} = params
|
|
265
274
|
|
|
@@ -300,13 +309,8 @@ async function runStreamStepLoop(
|
|
|
300
309
|
|
|
301
310
|
if (stepResult.toolCalls.length === 0) break
|
|
302
311
|
|
|
303
|
-
const approvalsNeeded = checkForApprovals(
|
|
304
|
-
stepResult,
|
|
305
|
-
runnerParams.tools,
|
|
306
|
-
runId
|
|
307
|
-
)
|
|
312
|
+
const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools)
|
|
308
313
|
if (approvalsNeeded.length > 0) {
|
|
309
|
-
// For each approval, call approvalDescriptionFn if available
|
|
310
314
|
for (const approval of approvalsNeeded) {
|
|
311
315
|
const toolDef = runnerParams.tools.find(
|
|
312
316
|
(t) => t.name === approval.toolName
|
|
@@ -314,17 +318,14 @@ async function runStreamStepLoop(
|
|
|
314
318
|
if (toolDef?.approvalDescriptionFn && !approval.reason) {
|
|
315
319
|
try {
|
|
316
320
|
approval.reason = await toolDef.approvalDescriptionFn(approval.args)
|
|
317
|
-
} catch {
|
|
318
|
-
// If description generation fails, continue without it
|
|
319
|
-
}
|
|
321
|
+
} catch {}
|
|
320
322
|
}
|
|
321
323
|
}
|
|
322
324
|
return { outcome: 'approval', approvals: approvalsNeeded }
|
|
323
325
|
}
|
|
324
326
|
|
|
325
|
-
const credentialRequests = checkForCredentialRequests(stepResult
|
|
327
|
+
const credentialRequests = checkForCredentialRequests(stepResult)
|
|
326
328
|
if (credentialRequests.length > 0) {
|
|
327
|
-
// Append step messages so the tool result is preserved for resume
|
|
328
329
|
appendStepMessages(runnerParams, stepResult)
|
|
329
330
|
return { outcome: 'credential', credentialRequests }
|
|
330
331
|
}
|
|
@@ -337,8 +338,7 @@ async function runStreamStepLoop(
|
|
|
337
338
|
|
|
338
339
|
export function checkForApprovals(
|
|
339
340
|
stepResult: AIAgentStepResult,
|
|
340
|
-
tools: AIAgentRunnerParams['tools']
|
|
341
|
-
runId: string
|
|
341
|
+
tools: AIAgentRunnerParams['tools']
|
|
342
342
|
): ToolApprovalRequired[] {
|
|
343
343
|
const approvals: ToolApprovalRequired[] = []
|
|
344
344
|
for (const tc of stepResult.toolCalls) {
|
|
@@ -351,12 +351,6 @@ export function checkForApprovals(
|
|
|
351
351
|
continue
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
// The approval marker is only trusted from a framework tool declared with
|
|
355
|
-
// `forwardsApproval` (the sub-agent delegating tools) AND carrying the
|
|
356
|
-
// non-forgeable `APPROVAL_REQUIRED` Symbol brand. A plain tool's output — or
|
|
357
|
-
// a delegating tool's LLM-shaped `result.object`, which an attacker can
|
|
358
|
-
// influence — is plain JSON and can never carry the Symbol, so it can never
|
|
359
|
-
// forge an approval/suspension.
|
|
360
354
|
if (!toolDef?.forwardsApproval) {
|
|
361
355
|
continue
|
|
362
356
|
}
|
|
@@ -417,15 +411,15 @@ export function checkForApprovals(
|
|
|
417
411
|
}
|
|
418
412
|
|
|
419
413
|
export function checkForCredentialRequests(
|
|
420
|
-
stepResult: AIAgentStepResult
|
|
421
|
-
runId: string
|
|
414
|
+
stepResult: AIAgentStepResult
|
|
422
415
|
): ToolCredentialRequired[] {
|
|
423
416
|
const requests: ToolCredentialRequired[] = []
|
|
424
417
|
for (const tr of stepResult.toolResults) {
|
|
418
|
+
// knowledge: decisions/security/ai-agent-credential-requests-are-symbol-branded.md
|
|
425
419
|
if (
|
|
426
420
|
tr.result &&
|
|
427
421
|
typeof tr.result === 'object' &&
|
|
428
|
-
|
|
422
|
+
CREDENTIAL_REQUIRED in (tr.result as object)
|
|
429
423
|
) {
|
|
430
424
|
const r = tr.result as {
|
|
431
425
|
credentialName: string
|
|
@@ -579,10 +573,6 @@ function handleCredentialRequests(
|
|
|
579
573
|
pendingApprovals,
|
|
580
574
|
})
|
|
581
575
|
|
|
582
|
-
// The __credentialRequired tool result is suppressed from the stream, so
|
|
583
|
-
// credential-request events (with the runId needed for /resume) are the
|
|
584
|
-
// client's signal to show Connect/Ignore buttons — mirroring how
|
|
585
|
-
// approval-request suspensions work.
|
|
586
576
|
for (const req of requests) {
|
|
587
577
|
channel.send({
|
|
588
578
|
type: 'credential-request',
|
|
@@ -626,7 +616,6 @@ export async function streamAIAgent(
|
|
|
626
616
|
}
|
|
627
617
|
|
|
628
618
|
const streamContext: StreamContext = { channel, options }
|
|
629
|
-
// delegateState is attached after prepareAgentRun resolves the agent config
|
|
630
619
|
|
|
631
620
|
const {
|
|
632
621
|
agent,
|
|
@@ -684,6 +673,9 @@ export async function streamAIAgent(
|
|
|
684
673
|
...(agent.aiMiddleware ?? []),
|
|
685
674
|
]
|
|
686
675
|
|
|
676
|
+
// One bag per run, shared by every middleware — see PikkuAIMiddlewareHooks.
|
|
677
|
+
const sharedNotes: Record<string, unknown> = {}
|
|
678
|
+
|
|
687
679
|
let modifiedMessages = runnerParams.messages
|
|
688
680
|
let modifiedInstructions = runnerParams.instructions
|
|
689
681
|
for (const mw of aiMiddlewares) {
|
|
@@ -691,6 +683,7 @@ export async function streamAIAgent(
|
|
|
691
683
|
const result = await mw.modifyInput(singletonServices, {
|
|
692
684
|
messages: modifiedMessages,
|
|
693
685
|
instructions: modifiedInstructions,
|
|
686
|
+
shared: sharedNotes,
|
|
694
687
|
})
|
|
695
688
|
modifiedMessages = result.messages
|
|
696
689
|
modifiedInstructions = result.instructions
|
|
@@ -699,6 +692,26 @@ export async function streamAIAgent(
|
|
|
699
692
|
runnerParams.messages = modifiedMessages
|
|
700
693
|
runnerParams.instructions = modifiedInstructions
|
|
701
694
|
|
|
695
|
+
// Sent on the raw channel, ahead of the run. A voice client sent audio and so
|
|
696
|
+
// has no idea what it said; until this arrives its own message is a blank
|
|
697
|
+
// bubble. Ahead of the run rather than alongside it because the answer starts
|
|
698
|
+
// streaming within a few hundred milliseconds, and a question that appears
|
|
699
|
+
// after its answer reads as the wrong question.
|
|
700
|
+
const transcript = sharedNotes[SPOKEN_TRANSCRIPT]
|
|
701
|
+
if (typeof transcript === 'string') {
|
|
702
|
+
channel.send({ type: 'transcript', text: transcript })
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// What goes into thread history is what the model was actually asked. For a
|
|
706
|
+
// spoken turn that is not what arrived over the wire: the wire carried a
|
|
707
|
+
// base64 audio blob, and persisting it would write megabytes of unreadable
|
|
708
|
+
// data into the history while losing the only readable record of the turn.
|
|
709
|
+
// Identity-checked rather than assumed — a middleware is free to rewrite the
|
|
710
|
+
// message list into something with no relation to the turn.
|
|
711
|
+
const lastModified = modifiedMessages[modifiedMessages.length - 1]
|
|
712
|
+
const persistedUserMessage =
|
|
713
|
+
lastModified?.id === userMessage.id ? lastModified : userMessage
|
|
714
|
+
|
|
702
715
|
const runId = await aiRunState.createRun({
|
|
703
716
|
agentName,
|
|
704
717
|
threadId,
|
|
@@ -710,8 +723,15 @@ export async function streamAIAgent(
|
|
|
710
723
|
})
|
|
711
724
|
options?.onRunCreated?.(runId)
|
|
712
725
|
|
|
726
|
+
// Registered before the first model call and released in `finally`, so the
|
|
727
|
+
// window in which an interrupt can land is exactly the window in which there
|
|
728
|
+
// is something to interrupt.
|
|
729
|
+
const interruptHandle = registerInterruptibleRun(runId)
|
|
730
|
+
runnerParams.abortSignal = interruptHandle.signal
|
|
731
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle)
|
|
732
|
+
|
|
713
733
|
if (storage) {
|
|
714
|
-
await storage.saveMessages(threadId, [
|
|
734
|
+
await storage.saveMessages(threadId, [persistedUserMessage])
|
|
715
735
|
}
|
|
716
736
|
|
|
717
737
|
const streamMiddleware = aiMiddlewares
|
|
@@ -725,6 +745,11 @@ export async function streamAIAgent(
|
|
|
725
745
|
event,
|
|
726
746
|
allEvents,
|
|
727
747
|
state,
|
|
748
|
+
shared: sharedNotes,
|
|
749
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
750
|
+
// now and push the slow one when it is ready.
|
|
751
|
+
emit: next,
|
|
752
|
+
signal: interruptHandle.signal,
|
|
728
753
|
})
|
|
729
754
|
if (result == null) return
|
|
730
755
|
if (Array.isArray(result)) {
|
|
@@ -765,12 +790,12 @@ export async function streamAIAgent(
|
|
|
765
790
|
).channel as AIStreamChannel)
|
|
766
791
|
: persistingChannel
|
|
767
792
|
|
|
768
|
-
// Tool results carrying the __credentialRequired marker must never reach
|
|
769
|
-
// the client or persisted history: the run suspends with credential-request
|
|
770
|
-
// events instead (mirroring approvals), and leaving the tool call
|
|
771
|
-
// unresulted is what lets the client resume it after connecting.
|
|
772
793
|
const credentialFilteredChannel: AIStreamChannel = {
|
|
773
794
|
...wrappedChannel,
|
|
795
|
+
// Returns what the inner send returns. Middleware runs asynchronously, so
|
|
796
|
+
// swallowing the promise here makes every `await channel.send(...)` upstream
|
|
797
|
+
// a no-op — including the one that waits for a buffering hook to flush
|
|
798
|
+
// before the channel closes.
|
|
774
799
|
send: (event: AIStreamEvent) => {
|
|
775
800
|
if (
|
|
776
801
|
event.type === 'tool-result' &&
|
|
@@ -780,15 +805,11 @@ export async function streamAIAgent(
|
|
|
780
805
|
) {
|
|
781
806
|
return
|
|
782
807
|
}
|
|
783
|
-
wrappedChannel.send(event)
|
|
808
|
+
return wrappedChannel.send(event)
|
|
784
809
|
},
|
|
785
810
|
}
|
|
786
811
|
|
|
787
|
-
|
|
788
|
-
// AFTER a sub-agent has been called. If the parent responds directly (no delegation),
|
|
789
|
-
// its text goes through normally. Sub-agent text bypasses this path entirely
|
|
790
|
-
// (goes through subChannel → channel directly).
|
|
791
|
-
const isDelegateMode = agent.agentMode !== 'supervise' && meta.agents?.length
|
|
812
|
+
const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length
|
|
792
813
|
const delegateState = { delegated: false }
|
|
793
814
|
if (isDelegateMode) {
|
|
794
815
|
streamContext.delegateState = delegateState
|
|
@@ -802,7 +823,7 @@ export async function streamAIAgent(
|
|
|
802
823
|
(event.type === 'text-delta' || event.type === 'reasoning-delta')
|
|
803
824
|
)
|
|
804
825
|
return
|
|
805
|
-
credentialFilteredChannel.send(event)
|
|
826
|
+
return credentialFilteredChannel.send(event)
|
|
806
827
|
},
|
|
807
828
|
delegateState,
|
|
808
829
|
}
|
|
@@ -817,7 +838,6 @@ export async function streamAIAgent(
|
|
|
817
838
|
streamChannel: outputChannel,
|
|
818
839
|
persistingChannel,
|
|
819
840
|
channel,
|
|
820
|
-
runId,
|
|
821
841
|
aiMiddlewares,
|
|
822
842
|
})
|
|
823
843
|
|
|
@@ -852,10 +872,41 @@ export async function streamAIAgent(
|
|
|
852
872
|
runId
|
|
853
873
|
)
|
|
854
874
|
|
|
855
|
-
channel
|
|
875
|
+
// Through the middleware rather than straight at the channel, and awaited.
|
|
876
|
+
// `done` is the only signal a stream hook gets that the reply is over, and
|
|
877
|
+
// the ones that buffer need it: `voiceOutput` speaks a trailing fragment
|
|
878
|
+
// that never reached a full stop, and waits for audio it has already paid
|
|
879
|
+
// to synthesize. Sent raw, that work is discarded by the `close()` below.
|
|
880
|
+
await outputChannel.send({ type: 'done' })
|
|
856
881
|
channel.close()
|
|
857
882
|
return persistingChannel.fullText
|
|
858
883
|
} catch (err) {
|
|
884
|
+
// An interrupt is not a failure: the truncated text is real output the user
|
|
885
|
+
// already heard part of, so it is persisted and marked rather than dropped.
|
|
886
|
+
const interruption = interruptHandle.interruption
|
|
887
|
+
if (interruption || isAbortError(err)) {
|
|
888
|
+
await persistingChannel.flush({ interrupted: true })
|
|
889
|
+
await aiRunState.updateRun(runId, { status: 'interrupted' })
|
|
890
|
+
// Deliberately not awaited. A tool still running must not hold the stream
|
|
891
|
+
// open — the whole point of barge-in is that the agent stops now — so the
|
|
892
|
+
// note lands later and the next run on this thread waits for it instead.
|
|
893
|
+
if (storage) {
|
|
894
|
+
trackInterruptNote(
|
|
895
|
+
threadId,
|
|
896
|
+
persistOrphanedToolResults(interruptHandle, storage, threadId)
|
|
897
|
+
)
|
|
898
|
+
}
|
|
899
|
+
channel.send({
|
|
900
|
+
type: 'interrupted',
|
|
901
|
+
runId,
|
|
902
|
+
text: persistingChannel.fullText,
|
|
903
|
+
reason: interruption?.reason ?? 'user',
|
|
904
|
+
})
|
|
905
|
+
channel.send({ type: 'done' })
|
|
906
|
+
channel.close()
|
|
907
|
+
return persistingChannel.fullText
|
|
908
|
+
}
|
|
909
|
+
|
|
859
910
|
for (const mw of aiMiddlewares) {
|
|
860
911
|
if (mw.onError) {
|
|
861
912
|
try {
|
|
@@ -864,9 +915,7 @@ export async function streamAIAgent(
|
|
|
864
915
|
stepNumber: -1,
|
|
865
916
|
messages: runnerParams.messages,
|
|
866
917
|
})
|
|
867
|
-
} catch {
|
|
868
|
-
// onError hooks must not affect error flow
|
|
869
|
-
}
|
|
918
|
+
} catch {}
|
|
870
919
|
}
|
|
871
920
|
}
|
|
872
921
|
await aiRunState.updateRun(runId, {
|
|
@@ -880,7 +929,72 @@ export async function streamAIAgent(
|
|
|
880
929
|
channel.send({ type: 'done' })
|
|
881
930
|
channel.close()
|
|
882
931
|
return persistingChannel.fullText
|
|
932
|
+
} finally {
|
|
933
|
+
interruptHandle.release()
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Stop an in-flight run on behalf of a caller, after checking the run is theirs.
|
|
939
|
+
*
|
|
940
|
+
* Unlike {@link resumeAIAgent} this needs no channel: it does not continue the
|
|
941
|
+
* stream, it ends one. The `interrupted` event and the truncated message are
|
|
942
|
+
* emitted by the original {@link streamAIAgent} call on its own channel, so this
|
|
943
|
+
* can be reached over a plain RPC while the stream is held open elsewhere —
|
|
944
|
+
* which is exactly the shape a voice barge-in needs.
|
|
945
|
+
*
|
|
946
|
+
* Ownership is the whole gate, deliberately without {@link assertAgentAuthorized}.
|
|
947
|
+
* Resuming re-enters the agent and approves a tool call, so a revoked grant must
|
|
948
|
+
* block it; stopping is the opposite — if a caller's access to an agent was
|
|
949
|
+
* revoked mid-run, being able to stop their own run is harmless and arguably
|
|
950
|
+
* what you want.
|
|
951
|
+
*
|
|
952
|
+
* Returns `false` when there was nothing to stop. Racing a run that finishes on
|
|
953
|
+
* its own is the normal case in voice, so it is not an error.
|
|
954
|
+
*/
|
|
955
|
+
export async function interruptAIAgent(
|
|
956
|
+
input: { runId: string; reason?: AgentInterruption['reason'] },
|
|
957
|
+
params: RunAIAgentParams
|
|
958
|
+
): Promise<AgentInterruptResult> {
|
|
959
|
+
const { aiRunState, logger } = getSingletonServices()
|
|
960
|
+
if (!aiRunState) {
|
|
961
|
+
throw new Error('AIRunStateService not available in singletonServices')
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const run = await aiRunState.getRun(input.runId)
|
|
965
|
+
if (!run) {
|
|
966
|
+
throw new Error(`No run found for runId ${input.runId}`)
|
|
883
967
|
}
|
|
968
|
+
assertResourceOwner(
|
|
969
|
+
resolveOwnerResourceId(
|
|
970
|
+
params,
|
|
971
|
+
agentSessionScope(run.agentName),
|
|
972
|
+
run.resourceId
|
|
973
|
+
),
|
|
974
|
+
run.resourceId,
|
|
975
|
+
'run'
|
|
976
|
+
)
|
|
977
|
+
|
|
978
|
+
const stopped = signalRunInterrupt(input.runId, {
|
|
979
|
+
reason: input.reason ?? 'user',
|
|
980
|
+
})
|
|
981
|
+
|
|
982
|
+
// A run still marked `running` that this process cannot abort is executing on
|
|
983
|
+
// another instance. Returning a bare `false` there is indistinguishable from
|
|
984
|
+
// "it already finished", so the one deployment shape this registry does not
|
|
985
|
+
// cover fails silently — an agent that simply refuses to shut up, with nothing
|
|
986
|
+
// in the logs. Say so instead. See `signalRunInterrupt` for the fix (fan the
|
|
987
|
+
// interrupt out over eventHub so every instance tries locally).
|
|
988
|
+
if (!stopped && run.status === 'running') {
|
|
989
|
+
logger?.warn(
|
|
990
|
+
`Could not interrupt run ${input.runId}: it is running in another process. ` +
|
|
991
|
+
'Interrupts are process-local; fan them out over eventHub to support multiple instances.'
|
|
992
|
+
)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// Reported after the abort so it names what is *still* running: aborting the
|
|
996
|
+
// model call does nothing to a tool already executing.
|
|
997
|
+
return { stopped, inFlightTools: getInFlightTools(input.runId) }
|
|
884
998
|
}
|
|
885
999
|
|
|
886
1000
|
export async function resumeAIAgent(
|
|
@@ -903,12 +1017,9 @@ export async function resumeAIAgent(
|
|
|
903
1017
|
if (!run) {
|
|
904
1018
|
throw new Error(`No run found for runId ${input.runId}`)
|
|
905
1019
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
agentSessionScope(run.agentName),
|
|
910
|
-
run.resourceId
|
|
911
|
-
),
|
|
1020
|
+
assertResourcePrincipalOwner(
|
|
1021
|
+
params,
|
|
1022
|
+
agentSessionScope(run.agentName),
|
|
912
1023
|
run.resourceId,
|
|
913
1024
|
'run'
|
|
914
1025
|
)
|
|
@@ -924,10 +1035,6 @@ export async function resumeAIAgent(
|
|
|
924
1035
|
|
|
925
1036
|
const { agent, packageName, resolvedName } = resolveAgent(run.agentName)
|
|
926
1037
|
|
|
927
|
-
// Gate before resolving the approval: recording it is a persisted side
|
|
928
|
-
// effect, so an unauthorized caller must not reach it. Run ownership alone is
|
|
929
|
-
// not enough — a grant revoked while the run was suspended must stop the
|
|
930
|
-
// caller from approving its pending tool calls.
|
|
931
1038
|
await assertAgentAuthorized(agent, params, packageName)
|
|
932
1039
|
|
|
933
1040
|
await aiRunState.resolveApproval(
|
|
@@ -981,12 +1088,10 @@ export async function resumeAIAgent(
|
|
|
981
1088
|
result: denialResult,
|
|
982
1089
|
})
|
|
983
1090
|
|
|
984
|
-
// Check remaining pending approvals
|
|
985
1091
|
const updatedRun = await aiRunState.getRun(run.runId)
|
|
986
1092
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
987
1093
|
|
|
988
1094
|
if (remaining.length > 0) {
|
|
989
|
-
// Still waiting for more approvals - don't continue step loop
|
|
990
1095
|
channel.send({ type: 'done' })
|
|
991
1096
|
channel.close()
|
|
992
1097
|
return
|
|
@@ -1134,12 +1239,10 @@ export async function resumeAIAgent(
|
|
|
1134
1239
|
})
|
|
1135
1240
|
}
|
|
1136
1241
|
|
|
1137
|
-
// Check remaining pending approvals after processing this one
|
|
1138
1242
|
const updatedRun = await aiRunState.getRun(run.runId)
|
|
1139
1243
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
1140
1244
|
|
|
1141
1245
|
if (remaining.length > 0) {
|
|
1142
|
-
// Still waiting for more approvals - don't continue step loop
|
|
1143
1246
|
channel.send({ type: 'done' })
|
|
1144
1247
|
channel.close()
|
|
1145
1248
|
return
|
|
@@ -1211,6 +1314,9 @@ async function continueAfterToolResult(
|
|
|
1211
1314
|
}),
|
|
1212
1315
|
...(agent.aiMiddleware ?? []),
|
|
1213
1316
|
]
|
|
1317
|
+
// One bag per run, shared by every middleware — see PikkuAIMiddlewareHooks.
|
|
1318
|
+
const sharedNotes: Record<string, unknown> = {}
|
|
1319
|
+
|
|
1214
1320
|
let modifiedMessages = trimmedMessages
|
|
1215
1321
|
let modifiedInstructions = instructions
|
|
1216
1322
|
for (const mw of aiMiddlewares) {
|
|
@@ -1218,12 +1324,19 @@ async function continueAfterToolResult(
|
|
|
1218
1324
|
const result = await mw.modifyInput(singletonServices, {
|
|
1219
1325
|
messages: modifiedMessages,
|
|
1220
1326
|
instructions: modifiedInstructions,
|
|
1327
|
+
shared: sharedNotes,
|
|
1221
1328
|
})
|
|
1222
1329
|
modifiedMessages = result.messages
|
|
1223
1330
|
modifiedInstructions = result.instructions
|
|
1224
1331
|
}
|
|
1225
1332
|
}
|
|
1226
1333
|
|
|
1334
|
+
// Resuming is as interruptible as the first turn. It is the same person
|
|
1335
|
+
// listening to the same voice, and after an approval it is where most of the
|
|
1336
|
+
// reply actually gets spoken — an approved delete is followed by the agent
|
|
1337
|
+
// talking about it, and that is a normal thing to talk over.
|
|
1338
|
+
const interruptHandle = registerInterruptibleRun(run.runId)
|
|
1339
|
+
|
|
1227
1340
|
const streamMiddleware = aiMiddlewares
|
|
1228
1341
|
.filter((mw) => mw.modifyOutputStream)
|
|
1229
1342
|
.map((mw) => {
|
|
@@ -1235,6 +1348,11 @@ async function continueAfterToolResult(
|
|
|
1235
1348
|
event,
|
|
1236
1349
|
allEvents,
|
|
1237
1350
|
state,
|
|
1351
|
+
shared: sharedNotes,
|
|
1352
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
1353
|
+
// now and push the slow one when it is ready.
|
|
1354
|
+
emit: next,
|
|
1355
|
+
signal: interruptHandle.signal,
|
|
1238
1356
|
})
|
|
1239
1357
|
if (result == null) return
|
|
1240
1358
|
if (Array.isArray(result)) {
|
|
@@ -1297,11 +1415,15 @@ async function continueAfterToolResult(
|
|
|
1297
1415
|
tools: resumeTools,
|
|
1298
1416
|
maxSteps: 1,
|
|
1299
1417
|
toolChoice: (agent.toolChoice ?? 'auto') as 'auto' | 'required' | 'none',
|
|
1418
|
+
providerOptions: agent.providerOptions,
|
|
1300
1419
|
outputSchema: meta?.outputSchema
|
|
1301
1420
|
? pikkuState(packageName, 'misc', 'schemas').get(meta.outputSchema)
|
|
1302
1421
|
: undefined,
|
|
1303
1422
|
}
|
|
1304
1423
|
|
|
1424
|
+
runnerParams.abortSignal = interruptHandle.signal
|
|
1425
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle)
|
|
1426
|
+
|
|
1305
1427
|
try {
|
|
1306
1428
|
const loopResult = await runStreamStepLoop({
|
|
1307
1429
|
agent,
|
|
@@ -1311,7 +1433,6 @@ async function continueAfterToolResult(
|
|
|
1311
1433
|
streamChannel: wrappedChannel,
|
|
1312
1434
|
persistingChannel,
|
|
1313
1435
|
channel,
|
|
1314
|
-
runId: run.runId,
|
|
1315
1436
|
aiMiddlewares,
|
|
1316
1437
|
})
|
|
1317
1438
|
|
|
@@ -1346,9 +1467,36 @@ async function continueAfterToolResult(
|
|
|
1346
1467
|
run.runId
|
|
1347
1468
|
)
|
|
1348
1469
|
|
|
1349
|
-
|
|
1470
|
+
// Through the middleware, for the same reason as the first turn — and it
|
|
1471
|
+
// matters more here. After an approval, most of what gets spoken is the
|
|
1472
|
+
// agent talking about what it just did, so this is the half of the reply a
|
|
1473
|
+
// dropped flush would silence.
|
|
1474
|
+
await wrappedChannel.send({ type: 'done' })
|
|
1350
1475
|
channel.close()
|
|
1351
1476
|
} catch (err) {
|
|
1477
|
+
// Same reasoning as the first turn: an interrupt is not a failure, and the
|
|
1478
|
+
// part of the reply the user already heard is real output.
|
|
1479
|
+
const interruption = interruptHandle.interruption
|
|
1480
|
+
if (interruption || isAbortError(err)) {
|
|
1481
|
+
await persistingChannel.flush({ interrupted: true })
|
|
1482
|
+
await aiRunState.updateRun(run.runId, { status: 'interrupted' })
|
|
1483
|
+
if (storage) {
|
|
1484
|
+
trackInterruptNote(
|
|
1485
|
+
run.threadId,
|
|
1486
|
+
persistOrphanedToolResults(interruptHandle, storage, run.threadId)
|
|
1487
|
+
)
|
|
1488
|
+
}
|
|
1489
|
+
channel.send({
|
|
1490
|
+
type: 'interrupted',
|
|
1491
|
+
runId: run.runId,
|
|
1492
|
+
text: persistingChannel.fullText,
|
|
1493
|
+
reason: interruption?.reason ?? 'user',
|
|
1494
|
+
})
|
|
1495
|
+
channel.send({ type: 'done' })
|
|
1496
|
+
channel.close()
|
|
1497
|
+
return
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1352
1500
|
for (const mw of aiMiddlewares) {
|
|
1353
1501
|
if (mw.onError) {
|
|
1354
1502
|
try {
|
|
@@ -1357,9 +1505,7 @@ async function continueAfterToolResult(
|
|
|
1357
1505
|
stepNumber: -1,
|
|
1358
1506
|
messages: runnerParams.messages,
|
|
1359
1507
|
})
|
|
1360
|
-
} catch {
|
|
1361
|
-
// onError hooks must not affect error flow
|
|
1362
|
-
}
|
|
1508
|
+
} catch {}
|
|
1363
1509
|
}
|
|
1364
1510
|
}
|
|
1365
1511
|
await aiRunState.updateRun(run.runId, {
|
|
@@ -1372,5 +1518,7 @@ async function continueAfterToolResult(
|
|
|
1372
1518
|
})
|
|
1373
1519
|
channel.send({ type: 'done' })
|
|
1374
1520
|
channel.close()
|
|
1521
|
+
} finally {
|
|
1522
|
+
interruptHandle.release()
|
|
1375
1523
|
}
|
|
1376
1524
|
}
|