@pikku/core 0.12.72 → 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 +793 -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 +37 -32
- 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 -13
- package/dist/handle-error.js +0 -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 +5 -39
- package/dist/schema.js +5 -39
- 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 +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 +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 -1
- 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 +0 -7
- package/src/function/function-runner.ts +62 -32
- 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/handle-error.ts +0 -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.ts +5 -39
- 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 +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 +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/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
|
@@ -3,8 +3,9 @@ import { AIProviderNotConfiguredError } from '../../errors/errors.js';
|
|
|
3
3
|
import { randomUUID } from './ai-agent-utils.js';
|
|
4
4
|
import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../channel/channel-middleware-runner.js';
|
|
5
5
|
import { resolveMemoryServices, loadContextMessages, trimMessages, getWorkingMemoryMiddleware, } from './ai-agent-memory.js';
|
|
6
|
-
import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, createScopedChannel, resolveOwnerResourceId, agentSessionScope, assertResourceOwner, assertAgentAuthorized, ToolApprovalRequired, ToolCredentialRequired, APPROVAL_REQUIRED, } from './ai-agent-prepare.js';
|
|
6
|
+
import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, createScopedChannel, resolveOwnerResourceId, agentSessionScope, assertResourceOwner, assertResourcePrincipalOwner, assertAgentAuthorized, ToolApprovalRequired, ToolCredentialRequired, APPROVAL_REQUIRED, CREDENTIAL_REQUIRED, } from './ai-agent-prepare.js';
|
|
7
7
|
import { resolveModelConfig } from './ai-agent-model-config.js';
|
|
8
|
+
import { getInFlightTools, isAbortError, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
|
|
8
9
|
function createPersistingChannel(parent, storage, threadId, logger) {
|
|
9
10
|
let fullText = '';
|
|
10
11
|
let stepText = '';
|
|
@@ -15,7 +16,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
|
|
|
15
16
|
inputTokens: 0,
|
|
16
17
|
outputTokens: 0,
|
|
17
18
|
};
|
|
18
|
-
const flushStep = async () => {
|
|
19
|
+
const flushStep = async (opts) => {
|
|
19
20
|
if (!storage)
|
|
20
21
|
return;
|
|
21
22
|
const text = stepText;
|
|
@@ -37,6 +38,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
|
|
|
37
38
|
]
|
|
38
39
|
: text || undefined,
|
|
39
40
|
toolCalls: calls.length > 0 ? calls : undefined,
|
|
41
|
+
...(opts?.interrupted ? { interrupted: true } : {}),
|
|
40
42
|
createdAt: new Date(),
|
|
41
43
|
};
|
|
42
44
|
const messages = [assistantMsg];
|
|
@@ -51,14 +53,6 @@ function createPersistingChannel(parent, storage, threadId, logger) {
|
|
|
51
53
|
await storage.saveMessages(threadId, messages);
|
|
52
54
|
}
|
|
53
55
|
};
|
|
54
|
-
/**
|
|
55
|
-
* `send` is synchronous and so cannot await the flush. A rejection would have
|
|
56
|
-
* nothing to propagate to and would take the process down as an unhandled
|
|
57
|
-
* rejection — a model reusing a toolCallId, which is a primary key in AI
|
|
58
|
-
* storage, is enough to trigger it. Persistence from inside `send` is
|
|
59
|
-
* therefore best-effort: the run carries on, and the awaited `flush()` on the
|
|
60
|
-
* suspend paths still surfaces failures to its caller.
|
|
61
|
-
*/
|
|
62
56
|
const flushDetached = () => {
|
|
63
57
|
void flushStep().catch((error) => {
|
|
64
58
|
logger?.error('Failed to persist agent messages', {
|
|
@@ -83,11 +77,15 @@ function createPersistingChannel(parent, storage, threadId, logger) {
|
|
|
83
77
|
close: () => parent.close(),
|
|
84
78
|
sendBinary: (data) => parent.sendBinary(data),
|
|
85
79
|
send: (event) => {
|
|
80
|
+
// Accumulated whether or not storage is configured: `fullText` is what
|
|
81
|
+
// the client was streamed, and an interrupted run has to be able to
|
|
82
|
+
// report the fragment it got through even with persistence turned off.
|
|
83
|
+
if (event.type === 'text-delta')
|
|
84
|
+
fullText += event.text;
|
|
86
85
|
if (storage) {
|
|
87
86
|
switch (event.type) {
|
|
88
87
|
case 'text-delta':
|
|
89
88
|
stepText += event.text;
|
|
90
|
-
fullText += event.text;
|
|
91
89
|
break;
|
|
92
90
|
case 'tool-call':
|
|
93
91
|
stepToolCalls.push({
|
|
@@ -125,6 +123,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
|
|
|
125
123
|
setState: (s) => parent.setState(s),
|
|
126
124
|
getState: () => parent.getState(),
|
|
127
125
|
clearState: () => parent.clearState(),
|
|
126
|
+
remote: (funcName, data) => parent.remote(funcName, data),
|
|
128
127
|
};
|
|
129
128
|
return channel;
|
|
130
129
|
}
|
|
@@ -161,7 +160,7 @@ async function postStreamCleanup(persistingChannel, aiMiddlewares, singletonServ
|
|
|
161
160
|
});
|
|
162
161
|
}
|
|
163
162
|
async function runStreamStepLoop(params) {
|
|
164
|
-
const { agent, runnerParams, maxSteps, agentRunner, streamChannel, channel,
|
|
163
|
+
const { agent, runnerParams, maxSteps, agentRunner, streamChannel, channel, aiMiddlewares, } = params;
|
|
165
164
|
const singletonServices = getSingletonServices();
|
|
166
165
|
for (let step = 0; step < maxSteps; step++) {
|
|
167
166
|
if (agent.prepareStep) {
|
|
@@ -195,25 +194,21 @@ async function runStreamStepLoop(params) {
|
|
|
195
194
|
}
|
|
196
195
|
if (stepResult.toolCalls.length === 0)
|
|
197
196
|
break;
|
|
198
|
-
const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools
|
|
197
|
+
const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools);
|
|
199
198
|
if (approvalsNeeded.length > 0) {
|
|
200
|
-
// For each approval, call approvalDescriptionFn if available
|
|
201
199
|
for (const approval of approvalsNeeded) {
|
|
202
200
|
const toolDef = runnerParams.tools.find((t) => t.name === approval.toolName);
|
|
203
201
|
if (toolDef?.approvalDescriptionFn && !approval.reason) {
|
|
204
202
|
try {
|
|
205
203
|
approval.reason = await toolDef.approvalDescriptionFn(approval.args);
|
|
206
204
|
}
|
|
207
|
-
catch {
|
|
208
|
-
// If description generation fails, continue without it
|
|
209
|
-
}
|
|
205
|
+
catch { }
|
|
210
206
|
}
|
|
211
207
|
}
|
|
212
208
|
return { outcome: 'approval', approvals: approvalsNeeded };
|
|
213
209
|
}
|
|
214
|
-
const credentialRequests = checkForCredentialRequests(stepResult
|
|
210
|
+
const credentialRequests = checkForCredentialRequests(stepResult);
|
|
215
211
|
if (credentialRequests.length > 0) {
|
|
216
|
-
// Append step messages so the tool result is preserved for resume
|
|
217
212
|
appendStepMessages(runnerParams, stepResult);
|
|
218
213
|
return { outcome: 'credential', credentialRequests };
|
|
219
214
|
}
|
|
@@ -221,7 +216,7 @@ async function runStreamStepLoop(params) {
|
|
|
221
216
|
}
|
|
222
217
|
return { outcome: 'done' };
|
|
223
218
|
}
|
|
224
|
-
export function checkForApprovals(stepResult, tools
|
|
219
|
+
export function checkForApprovals(stepResult, tools) {
|
|
225
220
|
const approvals = [];
|
|
226
221
|
for (const tc of stepResult.toolCalls) {
|
|
227
222
|
const toolDef = tools.find((t) => t.name === tc.toolName);
|
|
@@ -229,12 +224,6 @@ export function checkForApprovals(stepResult, tools, runId) {
|
|
|
229
224
|
approvals.push(new ToolApprovalRequired(tc.toolCallId, tc.toolName, tc.args));
|
|
230
225
|
continue;
|
|
231
226
|
}
|
|
232
|
-
// The approval marker is only trusted from a framework tool declared with
|
|
233
|
-
// `forwardsApproval` (the sub-agent delegating tools) AND carrying the
|
|
234
|
-
// non-forgeable `APPROVAL_REQUIRED` Symbol brand. A plain tool's output — or
|
|
235
|
-
// a delegating tool's LLM-shaped `result.object`, which an attacker can
|
|
236
|
-
// influence — is plain JSON and can never carry the Symbol, so it can never
|
|
237
|
-
// forge an approval/suspension.
|
|
238
227
|
if (!toolDef?.forwardsApproval) {
|
|
239
228
|
continue;
|
|
240
229
|
}
|
|
@@ -255,12 +244,13 @@ export function checkForApprovals(stepResult, tools, runId) {
|
|
|
255
244
|
}
|
|
256
245
|
return approvals;
|
|
257
246
|
}
|
|
258
|
-
export function checkForCredentialRequests(stepResult
|
|
247
|
+
export function checkForCredentialRequests(stepResult) {
|
|
259
248
|
const requests = [];
|
|
260
249
|
for (const tr of stepResult.toolResults) {
|
|
250
|
+
// knowledge: decisions/security/ai-agent-credential-requests-are-symbol-branded.md
|
|
261
251
|
if (tr.result &&
|
|
262
252
|
typeof tr.result === 'object' &&
|
|
263
|
-
|
|
253
|
+
CREDENTIAL_REQUIRED in tr.result) {
|
|
264
254
|
const r = tr.result;
|
|
265
255
|
const tc = stepResult.toolCalls.find((t) => t.toolCallId === tr.toolCallId);
|
|
266
256
|
requests.push(new ToolCredentialRequired(tr.toolCallId, tc?.toolName ?? 'unknown', tc?.args ?? {}, r.credentialName, r.credentialType, r.connectUrl));
|
|
@@ -366,10 +356,6 @@ function handleCredentialRequests(requests, runId, channel, aiRunState, persisti
|
|
|
366
356
|
suspendReason: 'credential',
|
|
367
357
|
pendingApprovals,
|
|
368
358
|
});
|
|
369
|
-
// The __credentialRequired tool result is suppressed from the stream, so
|
|
370
|
-
// credential-request events (with the runId needed for /resume) are the
|
|
371
|
-
// client's signal to show Connect/Ignore buttons — mirroring how
|
|
372
|
-
// approval-request suspensions work.
|
|
373
359
|
for (const req of requests) {
|
|
374
360
|
channel.send({
|
|
375
361
|
type: 'credential-request',
|
|
@@ -393,7 +379,6 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
393
379
|
resourceId: resolveOwnerResourceId(params, agentSessionScope(agentName), input.resourceId),
|
|
394
380
|
};
|
|
395
381
|
const streamContext = { channel, options };
|
|
396
|
-
// delegateState is attached after prepareAgentRun resolves the agent config
|
|
397
382
|
const { agent, packageName, resolvedName, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, maxSteps, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName, normalizedInput, params, sessionMap, streamContext);
|
|
398
383
|
runnerParams.agentId = agentName;
|
|
399
384
|
const singletonServices = getSingletonServices();
|
|
@@ -450,6 +435,12 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
450
435
|
updatedAt: new Date(),
|
|
451
436
|
});
|
|
452
437
|
options?.onRunCreated?.(runId);
|
|
438
|
+
// Registered before the first model call and released in `finally`, so the
|
|
439
|
+
// window in which an interrupt can land is exactly the window in which there
|
|
440
|
+
// is something to interrupt.
|
|
441
|
+
const interruptHandle = registerInterruptibleRun(runId);
|
|
442
|
+
runnerParams.abortSignal = interruptHandle.signal;
|
|
443
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle);
|
|
453
444
|
if (storage) {
|
|
454
445
|
await storage.saveMessages(threadId, [userMessage]);
|
|
455
446
|
}
|
|
@@ -464,6 +455,10 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
464
455
|
event,
|
|
465
456
|
allEvents,
|
|
466
457
|
state,
|
|
458
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
459
|
+
// now and push the slow one when it is ready.
|
|
460
|
+
emit: next,
|
|
461
|
+
signal: interruptHandle.signal,
|
|
467
462
|
});
|
|
468
463
|
if (result == null)
|
|
469
464
|
return;
|
|
@@ -489,12 +484,12 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
489
484
|
const wrappedChannel = allChannelMiddleware.length > 0
|
|
490
485
|
? wrapChannelWithMiddleware({ channel: persistingChannel }, singletonServices, allChannelMiddleware).channel
|
|
491
486
|
: persistingChannel;
|
|
492
|
-
// Tool results carrying the __credentialRequired marker must never reach
|
|
493
|
-
// the client or persisted history: the run suspends with credential-request
|
|
494
|
-
// events instead (mirroring approvals), and leaving the tool call
|
|
495
|
-
// unresulted is what lets the client resume it after connecting.
|
|
496
487
|
const credentialFilteredChannel = {
|
|
497
488
|
...wrappedChannel,
|
|
489
|
+
// Returns what the inner send returns. Middleware runs asynchronously, so
|
|
490
|
+
// swallowing the promise here makes every `await channel.send(...)` upstream
|
|
491
|
+
// a no-op — including the one that waits for a buffering hook to flush
|
|
492
|
+
// before the channel closes.
|
|
498
493
|
send: (event) => {
|
|
499
494
|
if (event.type === 'tool-result' &&
|
|
500
495
|
event.result !== null &&
|
|
@@ -502,14 +497,10 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
502
497
|
'__credentialRequired' in event.result) {
|
|
503
498
|
return;
|
|
504
499
|
}
|
|
505
|
-
wrappedChannel.send(event);
|
|
500
|
+
return wrappedChannel.send(event);
|
|
506
501
|
},
|
|
507
502
|
};
|
|
508
|
-
|
|
509
|
-
// AFTER a sub-agent has been called. If the parent responds directly (no delegation),
|
|
510
|
-
// its text goes through normally. Sub-agent text bypasses this path entirely
|
|
511
|
-
// (goes through subChannel → channel directly).
|
|
512
|
-
const isDelegateMode = agent.agentMode !== 'supervise' && meta.agents?.length;
|
|
503
|
+
const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length;
|
|
513
504
|
const delegateState = { delegated: false };
|
|
514
505
|
if (isDelegateMode) {
|
|
515
506
|
streamContext.delegateState = delegateState;
|
|
@@ -521,7 +512,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
521
512
|
if (delegateState.delegated &&
|
|
522
513
|
(event.type === 'text-delta' || event.type === 'reasoning-delta'))
|
|
523
514
|
return;
|
|
524
|
-
credentialFilteredChannel.send(event);
|
|
515
|
+
return credentialFilteredChannel.send(event);
|
|
525
516
|
},
|
|
526
517
|
delegateState,
|
|
527
518
|
}
|
|
@@ -535,7 +526,6 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
535
526
|
streamChannel: outputChannel,
|
|
536
527
|
persistingChannel,
|
|
537
528
|
channel,
|
|
538
|
-
runId,
|
|
539
529
|
aiMiddlewares,
|
|
540
530
|
});
|
|
541
531
|
if (loopResult.outcome === 'approval') {
|
|
@@ -547,11 +537,38 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
547
537
|
return persistingChannel.fullText;
|
|
548
538
|
}
|
|
549
539
|
await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, runnerParams.messages, aiRunState, runId);
|
|
550
|
-
channel
|
|
540
|
+
// Through the middleware rather than straight at the channel, and awaited.
|
|
541
|
+
// `done` is the only signal a stream hook gets that the reply is over, and
|
|
542
|
+
// the ones that buffer need it: `voiceOutput` speaks a trailing fragment
|
|
543
|
+
// that never reached a full stop, and waits for audio it has already paid
|
|
544
|
+
// to synthesize. Sent raw, that work is discarded by the `close()` below.
|
|
545
|
+
await outputChannel.send({ type: 'done' });
|
|
551
546
|
channel.close();
|
|
552
547
|
return persistingChannel.fullText;
|
|
553
548
|
}
|
|
554
549
|
catch (err) {
|
|
550
|
+
// An interrupt is not a failure: the truncated text is real output the user
|
|
551
|
+
// already heard part of, so it is persisted and marked rather than dropped.
|
|
552
|
+
const interruption = interruptHandle.interruption;
|
|
553
|
+
if (interruption || isAbortError(err)) {
|
|
554
|
+
await persistingChannel.flush({ interrupted: true });
|
|
555
|
+
await aiRunState.updateRun(runId, { status: 'interrupted' });
|
|
556
|
+
// Deliberately not awaited. A tool still running must not hold the stream
|
|
557
|
+
// open — the whole point of barge-in is that the agent stops now — so the
|
|
558
|
+
// note lands later and the next run on this thread waits for it instead.
|
|
559
|
+
if (storage) {
|
|
560
|
+
trackInterruptNote(threadId, persistOrphanedToolResults(interruptHandle, storage, threadId));
|
|
561
|
+
}
|
|
562
|
+
channel.send({
|
|
563
|
+
type: 'interrupted',
|
|
564
|
+
runId,
|
|
565
|
+
text: persistingChannel.fullText,
|
|
566
|
+
reason: interruption?.reason ?? 'user',
|
|
567
|
+
});
|
|
568
|
+
channel.send({ type: 'done' });
|
|
569
|
+
channel.close();
|
|
570
|
+
return persistingChannel.fullText;
|
|
571
|
+
}
|
|
555
572
|
for (const mw of aiMiddlewares) {
|
|
556
573
|
if (mw.onError) {
|
|
557
574
|
try {
|
|
@@ -561,9 +578,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
561
578
|
messages: runnerParams.messages,
|
|
562
579
|
});
|
|
563
580
|
}
|
|
564
|
-
catch {
|
|
565
|
-
// onError hooks must not affect error flow
|
|
566
|
-
}
|
|
581
|
+
catch { }
|
|
567
582
|
}
|
|
568
583
|
}
|
|
569
584
|
await aiRunState.updateRun(runId, {
|
|
@@ -578,6 +593,54 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
578
593
|
channel.close();
|
|
579
594
|
return persistingChannel.fullText;
|
|
580
595
|
}
|
|
596
|
+
finally {
|
|
597
|
+
interruptHandle.release();
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Stop an in-flight run on behalf of a caller, after checking the run is theirs.
|
|
602
|
+
*
|
|
603
|
+
* Unlike {@link resumeAIAgent} this needs no channel: it does not continue the
|
|
604
|
+
* stream, it ends one. The `interrupted` event and the truncated message are
|
|
605
|
+
* emitted by the original {@link streamAIAgent} call on its own channel, so this
|
|
606
|
+
* can be reached over a plain RPC while the stream is held open elsewhere —
|
|
607
|
+
* which is exactly the shape a voice barge-in needs.
|
|
608
|
+
*
|
|
609
|
+
* Ownership is the whole gate, deliberately without {@link assertAgentAuthorized}.
|
|
610
|
+
* Resuming re-enters the agent and approves a tool call, so a revoked grant must
|
|
611
|
+
* block it; stopping is the opposite — if a caller's access to an agent was
|
|
612
|
+
* revoked mid-run, being able to stop their own run is harmless and arguably
|
|
613
|
+
* what you want.
|
|
614
|
+
*
|
|
615
|
+
* Returns `false` when there was nothing to stop. Racing a run that finishes on
|
|
616
|
+
* its own is the normal case in voice, so it is not an error.
|
|
617
|
+
*/
|
|
618
|
+
export async function interruptAIAgent(input, params) {
|
|
619
|
+
const { aiRunState, logger } = getSingletonServices();
|
|
620
|
+
if (!aiRunState) {
|
|
621
|
+
throw new Error('AIRunStateService not available in singletonServices');
|
|
622
|
+
}
|
|
623
|
+
const run = await aiRunState.getRun(input.runId);
|
|
624
|
+
if (!run) {
|
|
625
|
+
throw new Error(`No run found for runId ${input.runId}`);
|
|
626
|
+
}
|
|
627
|
+
assertResourceOwner(resolveOwnerResourceId(params, agentSessionScope(run.agentName), run.resourceId), run.resourceId, 'run');
|
|
628
|
+
const stopped = signalRunInterrupt(input.runId, {
|
|
629
|
+
reason: input.reason ?? 'user',
|
|
630
|
+
});
|
|
631
|
+
// A run still marked `running` that this process cannot abort is executing on
|
|
632
|
+
// another instance. Returning a bare `false` there is indistinguishable from
|
|
633
|
+
// "it already finished", so the one deployment shape this registry does not
|
|
634
|
+
// cover fails silently — an agent that simply refuses to shut up, with nothing
|
|
635
|
+
// in the logs. Say so instead. See `signalRunInterrupt` for the fix (fan the
|
|
636
|
+
// interrupt out over eventHub so every instance tries locally).
|
|
637
|
+
if (!stopped && run.status === 'running') {
|
|
638
|
+
logger?.warn(`Could not interrupt run ${input.runId}: it is running in another process. ` +
|
|
639
|
+
'Interrupts are process-local; fan them out over eventHub to support multiple instances.');
|
|
640
|
+
}
|
|
641
|
+
// Reported after the abort so it names what is *still* running: aborting the
|
|
642
|
+
// model call does nothing to a tool already executing.
|
|
643
|
+
return { stopped, inFlightTools: getInFlightTools(input.runId) };
|
|
581
644
|
}
|
|
582
645
|
export async function resumeAIAgent(input, channel, params, options) {
|
|
583
646
|
const singletonServices = getSingletonServices();
|
|
@@ -589,16 +652,12 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
589
652
|
if (!run) {
|
|
590
653
|
throw new Error(`No run found for runId ${input.runId}`);
|
|
591
654
|
}
|
|
592
|
-
|
|
655
|
+
assertResourcePrincipalOwner(params, agentSessionScope(run.agentName), run.resourceId, 'run');
|
|
593
656
|
const pending = run.pendingApprovals?.find((p) => p.toolCallId === input.toolCallId);
|
|
594
657
|
if (!pending) {
|
|
595
658
|
throw new Error(`No pending approval for toolCallId ${input.toolCallId} on run ${input.runId}`);
|
|
596
659
|
}
|
|
597
660
|
const { agent, packageName, resolvedName } = resolveAgent(run.agentName);
|
|
598
|
-
// Gate before resolving the approval: recording it is a persisted side
|
|
599
|
-
// effect, so an unauthorized caller must not reach it. Run ownership alone is
|
|
600
|
-
// not enough — a grant revoked while the run was suspended must stop the
|
|
601
|
-
// caller from approving its pending tool calls.
|
|
602
661
|
await assertAgentAuthorized(agent, params, packageName);
|
|
603
662
|
await aiRunState.resolveApproval(input.toolCallId, input.approved ? 'approved' : 'denied');
|
|
604
663
|
const { storage } = resolveMemoryServices(agent, singletonServices);
|
|
@@ -639,11 +698,9 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
639
698
|
: pending.agentName,
|
|
640
699
|
result: denialResult,
|
|
641
700
|
});
|
|
642
|
-
// Check remaining pending approvals
|
|
643
701
|
const updatedRun = await aiRunState.getRun(run.runId);
|
|
644
702
|
const remaining = updatedRun?.pendingApprovals ?? [];
|
|
645
703
|
if (remaining.length > 0) {
|
|
646
|
-
// Still waiting for more approvals - don't continue step loop
|
|
647
704
|
channel.send({ type: 'done' });
|
|
648
705
|
channel.close();
|
|
649
706
|
return;
|
|
@@ -748,11 +805,9 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
748
805
|
...(isError ? { isError: true } : {}),
|
|
749
806
|
});
|
|
750
807
|
}
|
|
751
|
-
// Check remaining pending approvals after processing this one
|
|
752
808
|
const updatedRun = await aiRunState.getRun(run.runId);
|
|
753
809
|
const remaining = updatedRun?.pendingApprovals ?? [];
|
|
754
810
|
if (remaining.length > 0) {
|
|
755
|
-
// Still waiting for more approvals - don't continue step loop
|
|
756
811
|
channel.send({ type: 'done' });
|
|
757
812
|
channel.close();
|
|
758
813
|
return;
|
|
@@ -798,6 +853,11 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
798
853
|
modifiedInstructions = result.instructions;
|
|
799
854
|
}
|
|
800
855
|
}
|
|
856
|
+
// Resuming is as interruptible as the first turn. It is the same person
|
|
857
|
+
// listening to the same voice, and after an approval it is where most of the
|
|
858
|
+
// reply actually gets spoken — an approved delete is followed by the agent
|
|
859
|
+
// talking about it, and that is a normal thing to talk over.
|
|
860
|
+
const interruptHandle = registerInterruptibleRun(run.runId);
|
|
801
861
|
const streamMiddleware = aiMiddlewares
|
|
802
862
|
.filter((mw) => mw.modifyOutputStream)
|
|
803
863
|
.map((mw) => {
|
|
@@ -809,6 +869,10 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
809
869
|
event,
|
|
810
870
|
allEvents,
|
|
811
871
|
state,
|
|
872
|
+
// Sends downstream directly, so a hook can hand back the fast event
|
|
873
|
+
// now and push the slow one when it is ready.
|
|
874
|
+
emit: next,
|
|
875
|
+
signal: interruptHandle.signal,
|
|
812
876
|
});
|
|
813
877
|
if (result == null)
|
|
814
878
|
return;
|
|
@@ -844,10 +908,13 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
844
908
|
tools: resumeTools,
|
|
845
909
|
maxSteps: 1,
|
|
846
910
|
toolChoice: (agent.toolChoice ?? 'auto'),
|
|
911
|
+
providerOptions: agent.providerOptions,
|
|
847
912
|
outputSchema: meta?.outputSchema
|
|
848
913
|
? pikkuState(packageName, 'misc', 'schemas').get(meta.outputSchema)
|
|
849
914
|
: undefined,
|
|
850
915
|
};
|
|
916
|
+
runnerParams.abortSignal = interruptHandle.signal;
|
|
917
|
+
runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle);
|
|
851
918
|
try {
|
|
852
919
|
const loopResult = await runStreamStepLoop({
|
|
853
920
|
agent,
|
|
@@ -857,7 +924,6 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
857
924
|
streamChannel: wrappedChannel,
|
|
858
925
|
persistingChannel,
|
|
859
926
|
channel,
|
|
860
|
-
runId: run.runId,
|
|
861
927
|
aiMiddlewares,
|
|
862
928
|
});
|
|
863
929
|
if (loopResult.outcome === 'approval') {
|
|
@@ -869,10 +935,33 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
869
935
|
return;
|
|
870
936
|
}
|
|
871
937
|
await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, runnerParams.messages, aiRunState, run.runId);
|
|
872
|
-
|
|
938
|
+
// Through the middleware, for the same reason as the first turn — and it
|
|
939
|
+
// matters more here. After an approval, most of what gets spoken is the
|
|
940
|
+
// agent talking about what it just did, so this is the half of the reply a
|
|
941
|
+
// dropped flush would silence.
|
|
942
|
+
await wrappedChannel.send({ type: 'done' });
|
|
873
943
|
channel.close();
|
|
874
944
|
}
|
|
875
945
|
catch (err) {
|
|
946
|
+
// Same reasoning as the first turn: an interrupt is not a failure, and the
|
|
947
|
+
// part of the reply the user already heard is real output.
|
|
948
|
+
const interruption = interruptHandle.interruption;
|
|
949
|
+
if (interruption || isAbortError(err)) {
|
|
950
|
+
await persistingChannel.flush({ interrupted: true });
|
|
951
|
+
await aiRunState.updateRun(run.runId, { status: 'interrupted' });
|
|
952
|
+
if (storage) {
|
|
953
|
+
trackInterruptNote(run.threadId, persistOrphanedToolResults(interruptHandle, storage, run.threadId));
|
|
954
|
+
}
|
|
955
|
+
channel.send({
|
|
956
|
+
type: 'interrupted',
|
|
957
|
+
runId: run.runId,
|
|
958
|
+
text: persistingChannel.fullText,
|
|
959
|
+
reason: interruption?.reason ?? 'user',
|
|
960
|
+
});
|
|
961
|
+
channel.send({ type: 'done' });
|
|
962
|
+
channel.close();
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
876
965
|
for (const mw of aiMiddlewares) {
|
|
877
966
|
if (mw.onError) {
|
|
878
967
|
try {
|
|
@@ -882,9 +971,7 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
882
971
|
messages: runnerParams.messages,
|
|
883
972
|
});
|
|
884
973
|
}
|
|
885
|
-
catch {
|
|
886
|
-
// onError hooks must not affect error flow
|
|
887
|
-
}
|
|
974
|
+
catch { }
|
|
888
975
|
}
|
|
889
976
|
}
|
|
890
977
|
await aiRunState.updateRun(run.runId, {
|
|
@@ -898,4 +985,7 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
898
985
|
channel.send({ type: 'done' });
|
|
899
986
|
channel.close();
|
|
900
987
|
}
|
|
988
|
+
finally {
|
|
989
|
+
interruptHandle.release();
|
|
990
|
+
}
|
|
901
991
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { CorePermissionGroup, CorePikkuPermission } from '../../function/functions.types.js';
|
|
2
2
|
import type { CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
|
|
3
|
+
import type { AIProviderOptions } from '../../services/ai-agent-runner-service.js';
|
|
3
4
|
import type { PikkuChannel } from '../channel/channel.types.js';
|
|
4
5
|
import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js';
|
|
6
|
+
import type { ApprovalPolicy } from '../channel/channel-rpc.js';
|
|
5
7
|
export interface AIThread {
|
|
6
8
|
id: string;
|
|
7
9
|
resourceId: string;
|
|
@@ -49,6 +51,23 @@ export interface AIMessage {
|
|
|
49
51
|
toolCalls?: AIToolCall[];
|
|
50
52
|
toolResults?: AIToolResult[];
|
|
51
53
|
reasoningContent?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Set on an assistant message whose generation was cut short by
|
|
56
|
+
* an interrupt — the text is a mid-sentence fragment, not a reply.
|
|
57
|
+
* Carried into the next turn's context so the model can see it said only
|
|
58
|
+
* this much before being talked over, and decide for itself whether to
|
|
59
|
+
* resume, restate or move on. Storage that drops unknown fields loses the
|
|
60
|
+
* marker but keeps the fragment, which degrades to a truncated reply.
|
|
61
|
+
*/
|
|
62
|
+
interrupted?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Set on a tool message whose result arrived after the run was interrupted,
|
|
65
|
+
* so the model never got to describe it. The work happened; only the reply
|
|
66
|
+
* about it was lost. It is ordinary thread context on the next turn — the
|
|
67
|
+
* model raises it unprompted ("that deploy did go through") rather than the
|
|
68
|
+
* result being silently dropped or replayed as a fresh tool call.
|
|
69
|
+
*/
|
|
70
|
+
undelivered?: boolean;
|
|
52
71
|
createdAt: Date;
|
|
53
72
|
}
|
|
54
73
|
export interface AIAgentStep {
|
|
@@ -113,13 +132,24 @@ export interface AIAgentOutput {
|
|
|
113
132
|
* another user's or org's threads.
|
|
114
133
|
*/
|
|
115
134
|
export type SessionScope = 'user' | 'org';
|
|
116
|
-
|
|
135
|
+
/**
|
|
136
|
+
* `ApprovalPolicy` is shared with channel capabilities, but `Partial` here:
|
|
137
|
+
* absent `needsApproval` means "do not ask", which is safe because a tool is
|
|
138
|
+
* written by whoever runs the server it executes on. A capability runs on
|
|
139
|
+
* someone else's machine, so it requires the field instead.
|
|
140
|
+
*/
|
|
141
|
+
export interface AIAgentToolDef extends Partial<ApprovalPolicy> {
|
|
117
142
|
name: string;
|
|
118
143
|
description: string;
|
|
119
144
|
inputSchema: Record<string, unknown>;
|
|
120
145
|
execute: (input: unknown) => Promise<unknown>;
|
|
121
|
-
|
|
122
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Mirrors the pikku function's `readonly` flag. A read that gets interrupted
|
|
148
|
+
* is discarded rather than reported: nothing changed, and by the next turn
|
|
149
|
+
* the data may be stale anyway — re-reading is cheaper than explaining a
|
|
150
|
+
* result the user never asked to hear about.
|
|
151
|
+
*/
|
|
152
|
+
readonly?: boolean;
|
|
123
153
|
/**
|
|
124
154
|
* Set only by the framework on sub-agent delegating tools. Such a tool may
|
|
125
155
|
* legitimately return an `__approvalRequired` marker to forward a nested
|
|
@@ -144,6 +174,27 @@ export interface PikkuAIMiddlewareHooks<State extends Record<string, unknown> =
|
|
|
144
174
|
event: AIStreamEvent;
|
|
145
175
|
allEvents: readonly AIStreamEvent[];
|
|
146
176
|
state: State;
|
|
177
|
+
/**
|
|
178
|
+
* Push an event into the stream *after* this call has returned.
|
|
179
|
+
*
|
|
180
|
+
* Returning events blocks the stream until the hook resolves, which is
|
|
181
|
+
* right for anything derived from the event and wrong for anything slow.
|
|
182
|
+
* Speech is the motivating case: awaiting a text-to-speech call before
|
|
183
|
+
* returning the text delta stalls the reader at every full stop and
|
|
184
|
+
* serialises synthesis behind playback. Return the text immediately,
|
|
185
|
+
* start the slow work, and `emit` its result when it lands.
|
|
186
|
+
*
|
|
187
|
+
* Ordering among emitted events is the caller's problem — chain them if
|
|
188
|
+
* it matters — and a hook that emits must make sure anything still
|
|
189
|
+
* outstanding has landed before it lets `done` through.
|
|
190
|
+
*/
|
|
191
|
+
emit: (event: AIStreamEvent) => Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Aborts when the run is interrupted. Pass it to any provider call the
|
|
194
|
+
* hook makes: work started for a reply the user has already talked over
|
|
195
|
+
* is billed but never heard.
|
|
196
|
+
*/
|
|
197
|
+
signal?: AbortSignal;
|
|
147
198
|
}) => Promise<AIStreamEvent | AIStreamEvent[] | null> | AIStreamEvent | AIStreamEvent[] | null;
|
|
148
199
|
modifyOutput?: (services: Services, ctx: {
|
|
149
200
|
text: string;
|
|
@@ -216,8 +267,19 @@ export type CoreAIAgent<PikkuPermission = CorePikkuPermission<any, any>, PikkuMi
|
|
|
216
267
|
description: string;
|
|
217
268
|
summary?: string;
|
|
218
269
|
errors?: string[];
|
|
270
|
+
/**
|
|
271
|
+
* The three fields below are the system prompt. `buildInstructions` joins
|
|
272
|
+
* whichever are set with a blank line, always in this order — role, then
|
|
273
|
+
* personality, then goal — and appends the tool-usage rules if the agent has
|
|
274
|
+
* tools. Nothing checks them against each other: the split is there to keep a
|
|
275
|
+
* prompt legible, and text put in the wrong one still reaches the model.
|
|
276
|
+
*
|
|
277
|
+
* Who the agent is. 'You are a support engineer triaging inbound bugs.'
|
|
278
|
+
*/
|
|
219
279
|
role?: string;
|
|
280
|
+
/** How it should sound: tone, vocabulary, how much it says at a time. */
|
|
220
281
|
personality?: string;
|
|
282
|
+
/** What it is for — the only one of the three that is required. */
|
|
221
283
|
goal: string;
|
|
222
284
|
model: string;
|
|
223
285
|
temperature?: number;
|
|
@@ -230,6 +292,16 @@ export type CoreAIAgent<PikkuPermission = CorePikkuPermission<any, any>, PikkuMi
|
|
|
230
292
|
memory?: AIAgentMemoryConfig;
|
|
231
293
|
maxSteps?: number;
|
|
232
294
|
toolChoice?: 'auto' | 'required' | 'none';
|
|
295
|
+
/**
|
|
296
|
+
* Per-provider model settings, keyed by provider id and passed through
|
|
297
|
+
* untouched — for anything only one vendor offers, which the fields above
|
|
298
|
+
* deliberately do not try to unify.
|
|
299
|
+
*
|
|
300
|
+
* `{ openai: { reasoningEffort: 'minimal' } }` is the one that matters for
|
|
301
|
+
* voice: on gpt-5-mini it measured 0.9s to first token against 2.5s at the
|
|
302
|
+
* default, and a spoken reply is waited through rather than skimmed.
|
|
303
|
+
*/
|
|
304
|
+
providerOptions?: AIProviderOptions;
|
|
233
305
|
input?: unknown;
|
|
234
306
|
output?: unknown;
|
|
235
307
|
tags?: string[];
|
|
@@ -361,6 +433,14 @@ export type AIStreamEvent = {
|
|
|
361
433
|
type: 'suspended';
|
|
362
434
|
reason: 'rpc-missing';
|
|
363
435
|
missingRpcs: string[];
|
|
436
|
+
} | {
|
|
437
|
+
type: 'interrupted';
|
|
438
|
+
runId: string;
|
|
439
|
+
/** The truncated assistant text at the moment generation stopped. */
|
|
440
|
+
text: string;
|
|
441
|
+
reason: 'speech' | 'user' | 'timeout';
|
|
442
|
+
agent?: string;
|
|
443
|
+
session?: string;
|
|
364
444
|
} | {
|
|
365
445
|
type: 'done';
|
|
366
446
|
};
|
|
@@ -392,7 +472,7 @@ export interface AgentRunState {
|
|
|
392
472
|
agentName: string;
|
|
393
473
|
threadId: string;
|
|
394
474
|
resourceId: string;
|
|
395
|
-
status: 'running' | 'suspended' | 'completed' | 'failed';
|
|
475
|
+
status: 'running' | 'suspended' | 'completed' | 'failed' | 'interrupted';
|
|
396
476
|
errorMessage?: string;
|
|
397
477
|
suspendReason?: 'approval' | 'credential' | 'rpc-missing';
|
|
398
478
|
missingRpcs?: string[];
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export { agent, agentStream, agentResume, agentApprove, } from './ai-agent-helpers.js';
|
|
1
|
+
export { agent, agentStream, agentResume, agentApprove, agentInterrupt, } from './ai-agent-helpers.js';
|
|
2
2
|
export { wrapChannelWithAGUI, type AGUIEvent } from './ai-agent-agui.js';
|
|
3
3
|
export { runAIAgent, resumeAIAgentSync } from './ai-agent-runner.js';
|
|
4
|
-
export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js';
|
|
5
|
-
export { voiceInput } from './voice-input.js';
|
|
6
|
-
export { voiceOutput } from './voice-output.js';
|
|
4
|
+
export { streamAIAgent, resumeAIAgent, interruptAIAgent, } from './ai-agent-stream.js';
|
|
5
|
+
export { voiceInput, readsAsNonSpeech, NoSpeechDetectedError, } from './voice-input.js';
|
|
6
|
+
export { voiceOutput, unspeakableScripts, voiceForText, type SpeakableScripts, } from './voice-output.js';
|
|
7
|
+
export { AgentInterruptedError, awaitPendingInterruptNote, getInFlightTools, isAbortError, isRunInterruptible, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
|
|
8
|
+
export type { AgentInterruption, AgentInterruptResult, InterruptibleRunHandle, OrphanedToolResult, } from './ai-agent-interrupt.js';
|
|
7
9
|
export { type RunAIAgentParams, type StreamAIAgentOptions, ToolApprovalRequired, ToolCredentialRequired, canAccessThread, isOwnedByPrincipal, sessionPrincipals, threadOwnerConstraint, } from './ai-agent-prepare.js';
|
|
8
10
|
export { addAIAgent, approveAIAgent, getAIAgents, getAIAgentsMeta, } from './ai-agent-registry.js';
|
|
9
11
|
export type { AIAgentInput, AIAgentInputAttachment, AIAgentMeta, AIAgentMemoryConfig, AIAgentStep, AIContentPart, AgentRunRow, AgentRunService, AgentRunState, AIMessage, AIStreamChannel, AIStreamEvent, AIThread, CoreAIAgent, PendingApproval, PikkuAIMiddlewareHooks, } from './ai-agent.types.js';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { agent, agentStream, agentResume, agentApprove, } from './ai-agent-helpers.js';
|
|
1
|
+
export { agent, agentStream, agentResume, agentApprove, agentInterrupt, } from './ai-agent-helpers.js';
|
|
2
2
|
export { wrapChannelWithAGUI } from './ai-agent-agui.js';
|
|
3
3
|
export { runAIAgent, resumeAIAgentSync } from './ai-agent-runner.js';
|
|
4
|
-
export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js';
|
|
5
|
-
export { voiceInput } from './voice-input.js';
|
|
6
|
-
export { voiceOutput } from './voice-output.js';
|
|
4
|
+
export { streamAIAgent, resumeAIAgent, interruptAIAgent, } from './ai-agent-stream.js';
|
|
5
|
+
export { voiceInput, readsAsNonSpeech, NoSpeechDetectedError, } from './voice-input.js';
|
|
6
|
+
export { voiceOutput, unspeakableScripts, voiceForText, } from './voice-output.js';
|
|
7
|
+
export { AgentInterruptedError, awaitPendingInterruptNote, getInFlightTools, isAbortError, isRunInterruptible, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
|
|
7
8
|
export { ToolApprovalRequired, ToolCredentialRequired, canAccessThread, isOwnedByPrincipal, sessionPrincipals, threadOwnerConstraint, } from './ai-agent-prepare.js';
|
|
8
9
|
export { addAIAgent, approveAIAgent, getAIAgents, getAIAgentsMeta, } from './ai-agent-registry.js';
|