@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
|
@@ -37,10 +37,12 @@ import {
|
|
|
37
37
|
resolveOwnerResourceId,
|
|
38
38
|
agentSessionScope,
|
|
39
39
|
assertResourceOwner,
|
|
40
|
+
assertResourcePrincipalOwner,
|
|
40
41
|
assertAgentAuthorized,
|
|
41
42
|
ToolApprovalRequired,
|
|
42
43
|
ToolCredentialRequired,
|
|
43
44
|
APPROVAL_REQUIRED,
|
|
45
|
+
CREDENTIAL_REQUIRED,
|
|
44
46
|
type RunAIAgentParams,
|
|
45
47
|
type StreamAIAgentOptions,
|
|
46
48
|
type StreamContext,
|
|
@@ -48,10 +50,21 @@ import {
|
|
|
48
50
|
import { resolveModelConfig } from './ai-agent-model-config.js'
|
|
49
51
|
import type { AIRunStateService } from '../../services/ai-run-state-service.js'
|
|
50
52
|
import type { AIAgentRunnerService } from '../../services/ai-agent-runner-service.js'
|
|
53
|
+
import {
|
|
54
|
+
getInFlightTools,
|
|
55
|
+
isAbortError,
|
|
56
|
+
persistOrphanedToolResults,
|
|
57
|
+
registerInterruptibleRun,
|
|
58
|
+
signalRunInterrupt,
|
|
59
|
+
trackInterruptNote,
|
|
60
|
+
trackToolExecution,
|
|
61
|
+
type AgentInterruption,
|
|
62
|
+
type AgentInterruptResult,
|
|
63
|
+
} from './ai-agent-interrupt.js'
|
|
51
64
|
|
|
52
65
|
type PersistingChannel = AIStreamChannel & {
|
|
53
66
|
fullText: string
|
|
54
|
-
flush: () => Promise<void>
|
|
67
|
+
flush: (opts?: { interrupted?: boolean }) => Promise<void>
|
|
55
68
|
totalUsage: { inputTokens: number; outputTokens: number; model?: string }
|
|
56
69
|
}
|
|
57
70
|
|
|
@@ -75,7 +88,7 @@ function createPersistingChannel(
|
|
|
75
88
|
outputTokens: 0,
|
|
76
89
|
}
|
|
77
90
|
|
|
78
|
-
const flushStep = async () => {
|
|
91
|
+
const flushStep = async (opts?: { interrupted?: boolean }) => {
|
|
79
92
|
if (!storage) return
|
|
80
93
|
const text = stepText
|
|
81
94
|
const generativeUI = stepGenerativeUI
|
|
@@ -97,6 +110,7 @@ function createPersistingChannel(
|
|
|
97
110
|
]
|
|
98
111
|
: text || undefined,
|
|
99
112
|
toolCalls: calls.length > 0 ? calls : undefined,
|
|
113
|
+
...(opts?.interrupted ? { interrupted: true } : {}),
|
|
100
114
|
createdAt: new Date(),
|
|
101
115
|
}
|
|
102
116
|
const messages: AIMessage[] = [assistantMsg]
|
|
@@ -112,14 +126,6 @@ function createPersistingChannel(
|
|
|
112
126
|
}
|
|
113
127
|
}
|
|
114
128
|
|
|
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
129
|
const flushDetached = () => {
|
|
124
130
|
void flushStep().catch((error) => {
|
|
125
131
|
logger?.error('Failed to persist agent messages', {
|
|
@@ -145,11 +151,14 @@ function createPersistingChannel(
|
|
|
145
151
|
close: () => parent.close(),
|
|
146
152
|
sendBinary: (data) => parent.sendBinary(data),
|
|
147
153
|
send: (event: AIStreamEvent) => {
|
|
154
|
+
// Accumulated whether or not storage is configured: `fullText` is what
|
|
155
|
+
// the client was streamed, and an interrupted run has to be able to
|
|
156
|
+
// report the fragment it got through even with persistence turned off.
|
|
157
|
+
if (event.type === 'text-delta') fullText += event.text
|
|
148
158
|
if (storage) {
|
|
149
159
|
switch (event.type) {
|
|
150
160
|
case 'text-delta':
|
|
151
161
|
stepText += event.text
|
|
152
|
-
fullText += event.text
|
|
153
162
|
break
|
|
154
163
|
case 'tool-call':
|
|
155
164
|
stepToolCalls.push({
|
|
@@ -187,6 +196,7 @@ function createPersistingChannel(
|
|
|
187
196
|
setState: (s) => parent.setState(s),
|
|
188
197
|
getState: () => parent.getState(),
|
|
189
198
|
clearState: () => parent.clearState(),
|
|
199
|
+
remote: (funcName: string, data?: unknown) => parent.remote(funcName, data),
|
|
190
200
|
}
|
|
191
201
|
return channel
|
|
192
202
|
}
|
|
@@ -240,7 +250,6 @@ type StepLoopParams = {
|
|
|
240
250
|
streamChannel: AIStreamChannel
|
|
241
251
|
persistingChannel: PersistingChannel
|
|
242
252
|
channel: AIStreamChannel
|
|
243
|
-
runId: string
|
|
244
253
|
aiMiddlewares: PikkuAIMiddlewareHooks[]
|
|
245
254
|
}
|
|
246
255
|
|
|
@@ -259,7 +268,6 @@ async function runStreamStepLoop(
|
|
|
259
268
|
agentRunner,
|
|
260
269
|
streamChannel,
|
|
261
270
|
channel,
|
|
262
|
-
runId,
|
|
263
271
|
aiMiddlewares,
|
|
264
272
|
} = params
|
|
265
273
|
|
|
@@ -300,13 +308,8 @@ async function runStreamStepLoop(
|
|
|
300
308
|
|
|
301
309
|
if (stepResult.toolCalls.length === 0) break
|
|
302
310
|
|
|
303
|
-
const approvalsNeeded = checkForApprovals(
|
|
304
|
-
stepResult,
|
|
305
|
-
runnerParams.tools,
|
|
306
|
-
runId
|
|
307
|
-
)
|
|
311
|
+
const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools)
|
|
308
312
|
if (approvalsNeeded.length > 0) {
|
|
309
|
-
// For each approval, call approvalDescriptionFn if available
|
|
310
313
|
for (const approval of approvalsNeeded) {
|
|
311
314
|
const toolDef = runnerParams.tools.find(
|
|
312
315
|
(t) => t.name === approval.toolName
|
|
@@ -314,17 +317,14 @@ async function runStreamStepLoop(
|
|
|
314
317
|
if (toolDef?.approvalDescriptionFn && !approval.reason) {
|
|
315
318
|
try {
|
|
316
319
|
approval.reason = await toolDef.approvalDescriptionFn(approval.args)
|
|
317
|
-
} catch {
|
|
318
|
-
// If description generation fails, continue without it
|
|
319
|
-
}
|
|
320
|
+
} catch {}
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
323
|
return { outcome: 'approval', approvals: approvalsNeeded }
|
|
323
324
|
}
|
|
324
325
|
|
|
325
|
-
const credentialRequests = checkForCredentialRequests(stepResult
|
|
326
|
+
const credentialRequests = checkForCredentialRequests(stepResult)
|
|
326
327
|
if (credentialRequests.length > 0) {
|
|
327
|
-
// Append step messages so the tool result is preserved for resume
|
|
328
328
|
appendStepMessages(runnerParams, stepResult)
|
|
329
329
|
return { outcome: 'credential', credentialRequests }
|
|
330
330
|
}
|
|
@@ -337,8 +337,7 @@ async function runStreamStepLoop(
|
|
|
337
337
|
|
|
338
338
|
export function checkForApprovals(
|
|
339
339
|
stepResult: AIAgentStepResult,
|
|
340
|
-
tools: AIAgentRunnerParams['tools']
|
|
341
|
-
runId: string
|
|
340
|
+
tools: AIAgentRunnerParams['tools']
|
|
342
341
|
): ToolApprovalRequired[] {
|
|
343
342
|
const approvals: ToolApprovalRequired[] = []
|
|
344
343
|
for (const tc of stepResult.toolCalls) {
|
|
@@ -351,12 +350,6 @@ export function checkForApprovals(
|
|
|
351
350
|
continue
|
|
352
351
|
}
|
|
353
352
|
|
|
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
353
|
if (!toolDef?.forwardsApproval) {
|
|
361
354
|
continue
|
|
362
355
|
}
|
|
@@ -417,15 +410,15 @@ export function checkForApprovals(
|
|
|
417
410
|
}
|
|
418
411
|
|
|
419
412
|
export function checkForCredentialRequests(
|
|
420
|
-
stepResult: AIAgentStepResult
|
|
421
|
-
runId: string
|
|
413
|
+
stepResult: AIAgentStepResult
|
|
422
414
|
): ToolCredentialRequired[] {
|
|
423
415
|
const requests: ToolCredentialRequired[] = []
|
|
424
416
|
for (const tr of stepResult.toolResults) {
|
|
417
|
+
// knowledge: decisions/security/ai-agent-credential-requests-are-symbol-branded.md
|
|
425
418
|
if (
|
|
426
419
|
tr.result &&
|
|
427
420
|
typeof tr.result === 'object' &&
|
|
428
|
-
|
|
421
|
+
CREDENTIAL_REQUIRED in (tr.result as object)
|
|
429
422
|
) {
|
|
430
423
|
const r = tr.result as {
|
|
431
424
|
credentialName: string
|
|
@@ -579,10 +572,6 @@ function handleCredentialRequests(
|
|
|
579
572
|
pendingApprovals,
|
|
580
573
|
})
|
|
581
574
|
|
|
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
575
|
for (const req of requests) {
|
|
587
576
|
channel.send({
|
|
588
577
|
type: 'credential-request',
|
|
@@ -626,7 +615,6 @@ export async function streamAIAgent(
|
|
|
626
615
|
}
|
|
627
616
|
|
|
628
617
|
const streamContext: StreamContext = { channel, options }
|
|
629
|
-
// delegateState is attached after prepareAgentRun resolves the agent config
|
|
630
618
|
|
|
631
619
|
const {
|
|
632
620
|
agent,
|
|
@@ -710,6 +698,13 @@ export async function streamAIAgent(
|
|
|
710
698
|
})
|
|
711
699
|
options?.onRunCreated?.(runId)
|
|
712
700
|
|
|
701
|
+
// Registered before the first model call and released in `finally`, so the
|
|
702
|
+
// window in which an interrupt can land is exactly the window in which there
|
|
703
|
+
// is something to interrupt.
|
|
704
|
+
const interruptHandle = registerInterruptibleRun(runId)
|
|
705
|
+
runnerParams.abortSignal = interruptHandle.signal
|
|
706
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle)
|
|
707
|
+
|
|
713
708
|
if (storage) {
|
|
714
709
|
await storage.saveMessages(threadId, [userMessage])
|
|
715
710
|
}
|
|
@@ -725,6 +720,10 @@ export async function streamAIAgent(
|
|
|
725
720
|
event,
|
|
726
721
|
allEvents,
|
|
727
722
|
state,
|
|
723
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
724
|
+
// now and push the slow one when it is ready.
|
|
725
|
+
emit: next,
|
|
726
|
+
signal: interruptHandle.signal,
|
|
728
727
|
})
|
|
729
728
|
if (result == null) return
|
|
730
729
|
if (Array.isArray(result)) {
|
|
@@ -765,12 +764,12 @@ export async function streamAIAgent(
|
|
|
765
764
|
).channel as AIStreamChannel)
|
|
766
765
|
: persistingChannel
|
|
767
766
|
|
|
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
767
|
const credentialFilteredChannel: AIStreamChannel = {
|
|
773
768
|
...wrappedChannel,
|
|
769
|
+
// Returns what the inner send returns. Middleware runs asynchronously, so
|
|
770
|
+
// swallowing the promise here makes every `await channel.send(...)` upstream
|
|
771
|
+
// a no-op — including the one that waits for a buffering hook to flush
|
|
772
|
+
// before the channel closes.
|
|
774
773
|
send: (event: AIStreamEvent) => {
|
|
775
774
|
if (
|
|
776
775
|
event.type === 'tool-result' &&
|
|
@@ -780,15 +779,11 @@ export async function streamAIAgent(
|
|
|
780
779
|
) {
|
|
781
780
|
return
|
|
782
781
|
}
|
|
783
|
-
wrappedChannel.send(event)
|
|
782
|
+
return wrappedChannel.send(event)
|
|
784
783
|
},
|
|
785
784
|
}
|
|
786
785
|
|
|
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
|
|
786
|
+
const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length
|
|
792
787
|
const delegateState = { delegated: false }
|
|
793
788
|
if (isDelegateMode) {
|
|
794
789
|
streamContext.delegateState = delegateState
|
|
@@ -802,7 +797,7 @@ export async function streamAIAgent(
|
|
|
802
797
|
(event.type === 'text-delta' || event.type === 'reasoning-delta')
|
|
803
798
|
)
|
|
804
799
|
return
|
|
805
|
-
credentialFilteredChannel.send(event)
|
|
800
|
+
return credentialFilteredChannel.send(event)
|
|
806
801
|
},
|
|
807
802
|
delegateState,
|
|
808
803
|
}
|
|
@@ -817,7 +812,6 @@ export async function streamAIAgent(
|
|
|
817
812
|
streamChannel: outputChannel,
|
|
818
813
|
persistingChannel,
|
|
819
814
|
channel,
|
|
820
|
-
runId,
|
|
821
815
|
aiMiddlewares,
|
|
822
816
|
})
|
|
823
817
|
|
|
@@ -852,10 +846,41 @@ export async function streamAIAgent(
|
|
|
852
846
|
runId
|
|
853
847
|
)
|
|
854
848
|
|
|
855
|
-
channel
|
|
849
|
+
// Through the middleware rather than straight at the channel, and awaited.
|
|
850
|
+
// `done` is the only signal a stream hook gets that the reply is over, and
|
|
851
|
+
// the ones that buffer need it: `voiceOutput` speaks a trailing fragment
|
|
852
|
+
// that never reached a full stop, and waits for audio it has already paid
|
|
853
|
+
// to synthesize. Sent raw, that work is discarded by the `close()` below.
|
|
854
|
+
await outputChannel.send({ type: 'done' })
|
|
856
855
|
channel.close()
|
|
857
856
|
return persistingChannel.fullText
|
|
858
857
|
} catch (err) {
|
|
858
|
+
// An interrupt is not a failure: the truncated text is real output the user
|
|
859
|
+
// already heard part of, so it is persisted and marked rather than dropped.
|
|
860
|
+
const interruption = interruptHandle.interruption
|
|
861
|
+
if (interruption || isAbortError(err)) {
|
|
862
|
+
await persistingChannel.flush({ interrupted: true })
|
|
863
|
+
await aiRunState.updateRun(runId, { status: 'interrupted' })
|
|
864
|
+
// Deliberately not awaited. A tool still running must not hold the stream
|
|
865
|
+
// open — the whole point of barge-in is that the agent stops now — so the
|
|
866
|
+
// note lands later and the next run on this thread waits for it instead.
|
|
867
|
+
if (storage) {
|
|
868
|
+
trackInterruptNote(
|
|
869
|
+
threadId,
|
|
870
|
+
persistOrphanedToolResults(interruptHandle, storage, threadId)
|
|
871
|
+
)
|
|
872
|
+
}
|
|
873
|
+
channel.send({
|
|
874
|
+
type: 'interrupted',
|
|
875
|
+
runId,
|
|
876
|
+
text: persistingChannel.fullText,
|
|
877
|
+
reason: interruption?.reason ?? 'user',
|
|
878
|
+
})
|
|
879
|
+
channel.send({ type: 'done' })
|
|
880
|
+
channel.close()
|
|
881
|
+
return persistingChannel.fullText
|
|
882
|
+
}
|
|
883
|
+
|
|
859
884
|
for (const mw of aiMiddlewares) {
|
|
860
885
|
if (mw.onError) {
|
|
861
886
|
try {
|
|
@@ -864,9 +889,7 @@ export async function streamAIAgent(
|
|
|
864
889
|
stepNumber: -1,
|
|
865
890
|
messages: runnerParams.messages,
|
|
866
891
|
})
|
|
867
|
-
} catch {
|
|
868
|
-
// onError hooks must not affect error flow
|
|
869
|
-
}
|
|
892
|
+
} catch {}
|
|
870
893
|
}
|
|
871
894
|
}
|
|
872
895
|
await aiRunState.updateRun(runId, {
|
|
@@ -880,9 +903,74 @@ export async function streamAIAgent(
|
|
|
880
903
|
channel.send({ type: 'done' })
|
|
881
904
|
channel.close()
|
|
882
905
|
return persistingChannel.fullText
|
|
906
|
+
} finally {
|
|
907
|
+
interruptHandle.release()
|
|
883
908
|
}
|
|
884
909
|
}
|
|
885
910
|
|
|
911
|
+
/**
|
|
912
|
+
* Stop an in-flight run on behalf of a caller, after checking the run is theirs.
|
|
913
|
+
*
|
|
914
|
+
* Unlike {@link resumeAIAgent} this needs no channel: it does not continue the
|
|
915
|
+
* stream, it ends one. The `interrupted` event and the truncated message are
|
|
916
|
+
* emitted by the original {@link streamAIAgent} call on its own channel, so this
|
|
917
|
+
* can be reached over a plain RPC while the stream is held open elsewhere —
|
|
918
|
+
* which is exactly the shape a voice barge-in needs.
|
|
919
|
+
*
|
|
920
|
+
* Ownership is the whole gate, deliberately without {@link assertAgentAuthorized}.
|
|
921
|
+
* Resuming re-enters the agent and approves a tool call, so a revoked grant must
|
|
922
|
+
* block it; stopping is the opposite — if a caller's access to an agent was
|
|
923
|
+
* revoked mid-run, being able to stop their own run is harmless and arguably
|
|
924
|
+
* what you want.
|
|
925
|
+
*
|
|
926
|
+
* Returns `false` when there was nothing to stop. Racing a run that finishes on
|
|
927
|
+
* its own is the normal case in voice, so it is not an error.
|
|
928
|
+
*/
|
|
929
|
+
export async function interruptAIAgent(
|
|
930
|
+
input: { runId: string; reason?: AgentInterruption['reason'] },
|
|
931
|
+
params: RunAIAgentParams
|
|
932
|
+
): Promise<AgentInterruptResult> {
|
|
933
|
+
const { aiRunState, logger } = getSingletonServices()
|
|
934
|
+
if (!aiRunState) {
|
|
935
|
+
throw new Error('AIRunStateService not available in singletonServices')
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
const run = await aiRunState.getRun(input.runId)
|
|
939
|
+
if (!run) {
|
|
940
|
+
throw new Error(`No run found for runId ${input.runId}`)
|
|
941
|
+
}
|
|
942
|
+
assertResourceOwner(
|
|
943
|
+
resolveOwnerResourceId(
|
|
944
|
+
params,
|
|
945
|
+
agentSessionScope(run.agentName),
|
|
946
|
+
run.resourceId
|
|
947
|
+
),
|
|
948
|
+
run.resourceId,
|
|
949
|
+
'run'
|
|
950
|
+
)
|
|
951
|
+
|
|
952
|
+
const stopped = signalRunInterrupt(input.runId, {
|
|
953
|
+
reason: input.reason ?? 'user',
|
|
954
|
+
})
|
|
955
|
+
|
|
956
|
+
// A run still marked `running` that this process cannot abort is executing on
|
|
957
|
+
// another instance. Returning a bare `false` there is indistinguishable from
|
|
958
|
+
// "it already finished", so the one deployment shape this registry does not
|
|
959
|
+
// cover fails silently — an agent that simply refuses to shut up, with nothing
|
|
960
|
+
// in the logs. Say so instead. See `signalRunInterrupt` for the fix (fan the
|
|
961
|
+
// interrupt out over eventHub so every instance tries locally).
|
|
962
|
+
if (!stopped && run.status === 'running') {
|
|
963
|
+
logger?.warn(
|
|
964
|
+
`Could not interrupt run ${input.runId}: it is running in another process. ` +
|
|
965
|
+
'Interrupts are process-local; fan them out over eventHub to support multiple instances.'
|
|
966
|
+
)
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// Reported after the abort so it names what is *still* running: aborting the
|
|
970
|
+
// model call does nothing to a tool already executing.
|
|
971
|
+
return { stopped, inFlightTools: getInFlightTools(input.runId) }
|
|
972
|
+
}
|
|
973
|
+
|
|
886
974
|
export async function resumeAIAgent(
|
|
887
975
|
input: {
|
|
888
976
|
runId: string
|
|
@@ -903,12 +991,9 @@ export async function resumeAIAgent(
|
|
|
903
991
|
if (!run) {
|
|
904
992
|
throw new Error(`No run found for runId ${input.runId}`)
|
|
905
993
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
agentSessionScope(run.agentName),
|
|
910
|
-
run.resourceId
|
|
911
|
-
),
|
|
994
|
+
assertResourcePrincipalOwner(
|
|
995
|
+
params,
|
|
996
|
+
agentSessionScope(run.agentName),
|
|
912
997
|
run.resourceId,
|
|
913
998
|
'run'
|
|
914
999
|
)
|
|
@@ -924,10 +1009,6 @@ export async function resumeAIAgent(
|
|
|
924
1009
|
|
|
925
1010
|
const { agent, packageName, resolvedName } = resolveAgent(run.agentName)
|
|
926
1011
|
|
|
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
1012
|
await assertAgentAuthorized(agent, params, packageName)
|
|
932
1013
|
|
|
933
1014
|
await aiRunState.resolveApproval(
|
|
@@ -981,12 +1062,10 @@ export async function resumeAIAgent(
|
|
|
981
1062
|
result: denialResult,
|
|
982
1063
|
})
|
|
983
1064
|
|
|
984
|
-
// Check remaining pending approvals
|
|
985
1065
|
const updatedRun = await aiRunState.getRun(run.runId)
|
|
986
1066
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
987
1067
|
|
|
988
1068
|
if (remaining.length > 0) {
|
|
989
|
-
// Still waiting for more approvals - don't continue step loop
|
|
990
1069
|
channel.send({ type: 'done' })
|
|
991
1070
|
channel.close()
|
|
992
1071
|
return
|
|
@@ -1134,12 +1213,10 @@ export async function resumeAIAgent(
|
|
|
1134
1213
|
})
|
|
1135
1214
|
}
|
|
1136
1215
|
|
|
1137
|
-
// Check remaining pending approvals after processing this one
|
|
1138
1216
|
const updatedRun = await aiRunState.getRun(run.runId)
|
|
1139
1217
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
1140
1218
|
|
|
1141
1219
|
if (remaining.length > 0) {
|
|
1142
|
-
// Still waiting for more approvals - don't continue step loop
|
|
1143
1220
|
channel.send({ type: 'done' })
|
|
1144
1221
|
channel.close()
|
|
1145
1222
|
return
|
|
@@ -1224,6 +1301,12 @@ async function continueAfterToolResult(
|
|
|
1224
1301
|
}
|
|
1225
1302
|
}
|
|
1226
1303
|
|
|
1304
|
+
// Resuming is as interruptible as the first turn. It is the same person
|
|
1305
|
+
// listening to the same voice, and after an approval it is where most of the
|
|
1306
|
+
// reply actually gets spoken — an approved delete is followed by the agent
|
|
1307
|
+
// talking about it, and that is a normal thing to talk over.
|
|
1308
|
+
const interruptHandle = registerInterruptibleRun(run.runId)
|
|
1309
|
+
|
|
1227
1310
|
const streamMiddleware = aiMiddlewares
|
|
1228
1311
|
.filter((mw) => mw.modifyOutputStream)
|
|
1229
1312
|
.map((mw) => {
|
|
@@ -1235,6 +1318,10 @@ async function continueAfterToolResult(
|
|
|
1235
1318
|
event,
|
|
1236
1319
|
allEvents,
|
|
1237
1320
|
state,
|
|
1321
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
1322
|
+
// now and push the slow one when it is ready.
|
|
1323
|
+
emit: next,
|
|
1324
|
+
signal: interruptHandle.signal,
|
|
1238
1325
|
})
|
|
1239
1326
|
if (result == null) return
|
|
1240
1327
|
if (Array.isArray(result)) {
|
|
@@ -1297,11 +1384,15 @@ async function continueAfterToolResult(
|
|
|
1297
1384
|
tools: resumeTools,
|
|
1298
1385
|
maxSteps: 1,
|
|
1299
1386
|
toolChoice: (agent.toolChoice ?? 'auto') as 'auto' | 'required' | 'none',
|
|
1387
|
+
providerOptions: agent.providerOptions,
|
|
1300
1388
|
outputSchema: meta?.outputSchema
|
|
1301
1389
|
? pikkuState(packageName, 'misc', 'schemas').get(meta.outputSchema)
|
|
1302
1390
|
: undefined,
|
|
1303
1391
|
}
|
|
1304
1392
|
|
|
1393
|
+
runnerParams.abortSignal = interruptHandle.signal
|
|
1394
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle)
|
|
1395
|
+
|
|
1305
1396
|
try {
|
|
1306
1397
|
const loopResult = await runStreamStepLoop({
|
|
1307
1398
|
agent,
|
|
@@ -1311,7 +1402,6 @@ async function continueAfterToolResult(
|
|
|
1311
1402
|
streamChannel: wrappedChannel,
|
|
1312
1403
|
persistingChannel,
|
|
1313
1404
|
channel,
|
|
1314
|
-
runId: run.runId,
|
|
1315
1405
|
aiMiddlewares,
|
|
1316
1406
|
})
|
|
1317
1407
|
|
|
@@ -1346,9 +1436,36 @@ async function continueAfterToolResult(
|
|
|
1346
1436
|
run.runId
|
|
1347
1437
|
)
|
|
1348
1438
|
|
|
1349
|
-
|
|
1439
|
+
// Through the middleware, for the same reason as the first turn — and it
|
|
1440
|
+
// matters more here. After an approval, most of what gets spoken is the
|
|
1441
|
+
// agent talking about what it just did, so this is the half of the reply a
|
|
1442
|
+
// dropped flush would silence.
|
|
1443
|
+
await wrappedChannel.send({ type: 'done' })
|
|
1350
1444
|
channel.close()
|
|
1351
1445
|
} catch (err) {
|
|
1446
|
+
// Same reasoning as the first turn: an interrupt is not a failure, and the
|
|
1447
|
+
// part of the reply the user already heard is real output.
|
|
1448
|
+
const interruption = interruptHandle.interruption
|
|
1449
|
+
if (interruption || isAbortError(err)) {
|
|
1450
|
+
await persistingChannel.flush({ interrupted: true })
|
|
1451
|
+
await aiRunState.updateRun(run.runId, { status: 'interrupted' })
|
|
1452
|
+
if (storage) {
|
|
1453
|
+
trackInterruptNote(
|
|
1454
|
+
run.threadId,
|
|
1455
|
+
persistOrphanedToolResults(interruptHandle, storage, run.threadId)
|
|
1456
|
+
)
|
|
1457
|
+
}
|
|
1458
|
+
channel.send({
|
|
1459
|
+
type: 'interrupted',
|
|
1460
|
+
runId: run.runId,
|
|
1461
|
+
text: persistingChannel.fullText,
|
|
1462
|
+
reason: interruption?.reason ?? 'user',
|
|
1463
|
+
})
|
|
1464
|
+
channel.send({ type: 'done' })
|
|
1465
|
+
channel.close()
|
|
1466
|
+
return
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1352
1469
|
for (const mw of aiMiddlewares) {
|
|
1353
1470
|
if (mw.onError) {
|
|
1354
1471
|
try {
|
|
@@ -1357,9 +1474,7 @@ async function continueAfterToolResult(
|
|
|
1357
1474
|
stepNumber: -1,
|
|
1358
1475
|
messages: runnerParams.messages,
|
|
1359
1476
|
})
|
|
1360
|
-
} catch {
|
|
1361
|
-
// onError hooks must not affect error flow
|
|
1362
|
-
}
|
|
1477
|
+
} catch {}
|
|
1363
1478
|
}
|
|
1364
1479
|
}
|
|
1365
1480
|
await aiRunState.updateRun(run.runId, {
|
|
@@ -1372,5 +1487,7 @@ async function continueAfterToolResult(
|
|
|
1372
1487
|
})
|
|
1373
1488
|
channel.send({ type: 'done' })
|
|
1374
1489
|
channel.close()
|
|
1490
|
+
} finally {
|
|
1491
|
+
interruptHandle.release()
|
|
1375
1492
|
}
|
|
1376
1493
|
}
|