@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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A seeded PRNG, so a run replays exactly.
|
|
3
|
+
*
|
|
4
|
+
* Reproducibility is the whole point: a virtual user that finds something has
|
|
5
|
+
* to be re-runnable into the same finding before it can be shrunk into a
|
|
6
|
+
* regression scenario. `Math.random` would make every finding a one-off story.
|
|
7
|
+
*
|
|
8
|
+
* mulberry32 — 32 bits of state, uniform enough for scheduling weights, and
|
|
9
|
+
* short enough to read.
|
|
10
|
+
*/
|
|
11
|
+
export const createRng = (seed: number) => {
|
|
12
|
+
let state = seed >>> 0
|
|
13
|
+
const next = () => {
|
|
14
|
+
state = (state + 0x6d2b79f5) >>> 0
|
|
15
|
+
let t = state
|
|
16
|
+
t = Math.imul(t ^ (t >>> 15), t | 1)
|
|
17
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
|
|
18
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
next,
|
|
22
|
+
/** True with probability `p`. */
|
|
23
|
+
chance: (p: number) => next() < p,
|
|
24
|
+
/** A uniform pick, or undefined for an empty list. */
|
|
25
|
+
pick: <T>(items: readonly T[]): T | undefined =>
|
|
26
|
+
items.length === 0 ? undefined : items[Math.floor(next() * items.length)],
|
|
27
|
+
/**
|
|
28
|
+
* A weighted pick over `[key, weight]` pairs. Zero-weight keys can never be
|
|
29
|
+
* drawn, which is how a disposition switches a move off entirely.
|
|
30
|
+
*/
|
|
31
|
+
weighted: <K extends string>(
|
|
32
|
+
weights: Readonly<Record<K, number>>
|
|
33
|
+
): K | undefined => {
|
|
34
|
+
const entries = (Object.entries(weights) as [K, number][]).filter(
|
|
35
|
+
([, weight]) => weight > 0
|
|
36
|
+
)
|
|
37
|
+
const total = entries.reduce((sum, [, weight]) => sum + weight, 0)
|
|
38
|
+
if (total <= 0) return undefined
|
|
39
|
+
let roll = next() * total
|
|
40
|
+
for (const [key, weight] of entries) {
|
|
41
|
+
roll -= weight
|
|
42
|
+
if (roll <= 0) return key
|
|
43
|
+
}
|
|
44
|
+
return entries[entries.length - 1]?.[0]
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The seeded generator the engine threads through a whole run. */
|
|
50
|
+
export type VirtualUserRng = ReturnType<typeof createRng>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ScenarioPersona } from '../../services/personas-service.js'
|
|
2
|
+
import type { VirtualUserTarget } from './virtual-user.types.js'
|
|
3
|
+
|
|
4
|
+
export interface PersonaTargetOptions {
|
|
5
|
+
/** Model the persona uses for its side of a conversation with an agent. */
|
|
6
|
+
model?: string
|
|
7
|
+
/** Agents this user may talk to. Omit to leave `talkTo` unavailable. */
|
|
8
|
+
agents?: readonly string[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Drive a virtual user through a signed-in persona.
|
|
13
|
+
*
|
|
14
|
+
* This is the only place the engine meets the network. A persona already signs
|
|
15
|
+
* in as a real user over the app's own auth, keeps its cookies, re-logs-in when
|
|
16
|
+
* a session expires mid-run and reports a status as data rather than throwing —
|
|
17
|
+
* everything a user imitating a user needs, and none of it worth building twice.
|
|
18
|
+
*
|
|
19
|
+
* `invokeRaw` rather than `invoke` matters: to a virtual user a 403 is not an
|
|
20
|
+
* error, it is the system saying no, which is information it should be allowed
|
|
21
|
+
* to act on.
|
|
22
|
+
*/
|
|
23
|
+
export const personaVirtualUserTarget = (
|
|
24
|
+
persona: ScenarioPersona,
|
|
25
|
+
{ model, agents }: PersonaTargetOptions = {}
|
|
26
|
+
): VirtualUserTarget => ({
|
|
27
|
+
call: (rpcName, args) => persona.invokeRaw(rpcName, args),
|
|
28
|
+
talkTo: agents?.length
|
|
29
|
+
? async (agent, task) => {
|
|
30
|
+
if (!agents.includes(agent)) {
|
|
31
|
+
return {
|
|
32
|
+
passed: false,
|
|
33
|
+
reasoning: `There is no assistant called '${agent}'.`,
|
|
34
|
+
transcript: [],
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return persona.converse({
|
|
38
|
+
agent,
|
|
39
|
+
task,
|
|
40
|
+
// A user asking for something judges the answer by whether they got
|
|
41
|
+
// what they asked for. There is no separate criterion to hold it to.
|
|
42
|
+
evaluate: `The assistant did what was asked: ${task}`,
|
|
43
|
+
model,
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
47
|
+
})
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import type { ScenarioHttpResponse } from '../../services/personas-service.js'
|
|
2
|
+
import type { ActorFlowVerdict } from '../actor-flow/actor-flow.types.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* How a virtual user behaves, mechanically. A disposition changes the loop, the
|
|
6
|
+
* input generation, the memory and the oracle — anything that only changes how
|
|
7
|
+
* the user *talks* is persona prose (`ResolvedPersona.personality`) and does
|
|
8
|
+
* not belong here.
|
|
9
|
+
*
|
|
10
|
+
* - `realistic` — schema-first, goal-directed, plausible values (default).
|
|
11
|
+
* - `careless` — repeats, abandons, double-submits, boundary values.
|
|
12
|
+
* - `newcomer` — starts with empty memory and must discover everything.
|
|
13
|
+
* - `stale` — seeded from an earlier run's ids, some no longer valid.
|
|
14
|
+
* - `auditor` — pursues no goal; reads one truth from several places and compares.
|
|
15
|
+
* - `adversarial` — probes authorization and tenancy; a 2xx can be the finding.
|
|
16
|
+
* - `accountable` — pursues its goals for real; the only one production allows.
|
|
17
|
+
*
|
|
18
|
+
* `accountable` sits opposite `adversarial` on an *intent* axis — bad faith
|
|
19
|
+
* against good faith — where `careless` and `thorough` are a *care* axis. It is
|
|
20
|
+
* the one disposition whose actions carry consequences: no oracle, no rollback,
|
|
21
|
+
* and every call attributed to the persona in the audit log like anyone else's.
|
|
22
|
+
*/
|
|
23
|
+
export type VirtualUserDisposition =
|
|
24
|
+
| 'realistic'
|
|
25
|
+
| 'careless'
|
|
26
|
+
| 'newcomer'
|
|
27
|
+
| 'stale'
|
|
28
|
+
| 'auditor'
|
|
29
|
+
| 'adversarial'
|
|
30
|
+
| 'accountable'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The one disposition a production environment accepts.
|
|
34
|
+
*
|
|
35
|
+
* Every other disposition exists to find out what the product does wrong, which
|
|
36
|
+
* is not a thing to do to real customers' data. Named here so the declaration
|
|
37
|
+
* check and the sign-in check cannot drift apart.
|
|
38
|
+
*/
|
|
39
|
+
export const PRODUCTION_DISPOSITION: VirtualUserDisposition = 'accountable'
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Hard caps the engine enforces itself. Anything the engine cannot count —
|
|
43
|
+
* money above all — belongs in {@link RunVirtualUserParams.stop} instead.
|
|
44
|
+
*/
|
|
45
|
+
export interface VirtualUserBudget {
|
|
46
|
+
/** Model turns, including ones that produced no call. */
|
|
47
|
+
steps?: number
|
|
48
|
+
/** Non-read RPC calls. */
|
|
49
|
+
mutations?: number
|
|
50
|
+
/** Wall clock, as ms or a duration string (`'30m'`). */
|
|
51
|
+
duration?: number | string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The running count handed to {@link RunVirtualUserParams.stop}. Pikku collects
|
|
56
|
+
* it because only the engine sees every step; what it is *worth* is the app's,
|
|
57
|
+
* which is why no price or currency appears anywhere in core.
|
|
58
|
+
*/
|
|
59
|
+
export interface VirtualUserTally {
|
|
60
|
+
steps: number
|
|
61
|
+
calls: number
|
|
62
|
+
mutations: number
|
|
63
|
+
tokensIn: number
|
|
64
|
+
tokensOut: number
|
|
65
|
+
model: string
|
|
66
|
+
elapsedMs: number
|
|
67
|
+
findings: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* One RPC as the virtual user sees it before reading its schema: enough to
|
|
72
|
+
* choose from, not enough to call with. The whole catalogue goes in the prompt,
|
|
73
|
+
* so this stays deliberately compact — a project with 430 RPCs renders to
|
|
74
|
+
* roughly 8k tokens, which is cheaper than any retrieval step and hides nothing.
|
|
75
|
+
*/
|
|
76
|
+
export interface ApiCatalogueEntry {
|
|
77
|
+
name: string
|
|
78
|
+
/** Top-level input property names, for choosing between similar endpoints. */
|
|
79
|
+
inputKeys?: readonly string[]
|
|
80
|
+
/** Top-level output property names. */
|
|
81
|
+
outputKeys?: readonly string[]
|
|
82
|
+
description?: string
|
|
83
|
+
/**
|
|
84
|
+
* Whether the call only reads. `undefined` means nobody annotated it — which
|
|
85
|
+
* is not the same as safe, so the engine falls back to a name heuristic and
|
|
86
|
+
* reports how many entries it had to guess at.
|
|
87
|
+
*/
|
|
88
|
+
readonly?: boolean
|
|
89
|
+
/** Declared by the app as needing a human's approval — denied by default. */
|
|
90
|
+
approvalRequired?: boolean
|
|
91
|
+
/**
|
|
92
|
+
* Scopes the session must hold to call this, all of them.
|
|
93
|
+
*
|
|
94
|
+
* Splits the catalogue in two: what a persona's roles entitle it to reach,
|
|
95
|
+
* and what they do not. Scopes rather than permission-function names because
|
|
96
|
+
* a scope is declared and checkable, whereas a permission is arbitrary code
|
|
97
|
+
* whose verdict nobody can predict without running it.
|
|
98
|
+
*/
|
|
99
|
+
scopes?: readonly string[]
|
|
100
|
+
tags?: readonly string[]
|
|
101
|
+
/** JSON schema returned by `describe`, before the user may call. */
|
|
102
|
+
inputSchema?: Record<string, unknown>
|
|
103
|
+
outputSchema?: Record<string, unknown>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Where an intent comes from: a feature or scenario in the app's own words.
|
|
108
|
+
*
|
|
109
|
+
* Deliberately prose. The virtual user never receives the scenario's step graph
|
|
110
|
+
* — no rpc names, no `$ref` dataflow — because finding the API itself is the
|
|
111
|
+
* behaviour under test, and those graphs are a build-time artifact that no
|
|
112
|
+
* deployed stage carries.
|
|
113
|
+
*/
|
|
114
|
+
export interface IntentSource {
|
|
115
|
+
id: string
|
|
116
|
+
title: string
|
|
117
|
+
description?: string
|
|
118
|
+
/** Step prose, as a person would be told it. Never rpc names. */
|
|
119
|
+
steps?: readonly string[]
|
|
120
|
+
tags?: readonly string[]
|
|
121
|
+
/** Persona ids this intent is available to. Empty means everyone. */
|
|
122
|
+
personas?: readonly string[]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Why the engine flagged something. */
|
|
126
|
+
export type VirtualUserFindingKind =
|
|
127
|
+
| 'server-error'
|
|
128
|
+
| 'transport-error'
|
|
129
|
+
| 'schema-violation'
|
|
130
|
+
| 'unexpected-success'
|
|
131
|
+
| 'custom'
|
|
132
|
+
|
|
133
|
+
/** Something worth a human's attention, found while imitating a user. */
|
|
134
|
+
export interface VirtualUserFinding {
|
|
135
|
+
kind: VirtualUserFindingKind
|
|
136
|
+
detail: string
|
|
137
|
+
rpcName?: string
|
|
138
|
+
status?: number
|
|
139
|
+
intentId?: string
|
|
140
|
+
/** Step index within the run, so the transcript can be replayed to here. */
|
|
141
|
+
step: number
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The transport the virtual user acts through. HTTP in production (an
|
|
146
|
+
* `HttpPersona`), but the engine only sees this contract — which is what
|
|
147
|
+
* lets the whole loop be tested without a network.
|
|
148
|
+
*/
|
|
149
|
+
export interface VirtualUserTarget {
|
|
150
|
+
/** Invoke an RPC as this user, reporting the status as data rather than throwing. */
|
|
151
|
+
call(rpcName: string, args: unknown): Promise<ScenarioHttpResponse>
|
|
152
|
+
/** Converse with an AI agent in persona. Omitted by apps that have no agents. */
|
|
153
|
+
talkTo?(agent: string, task: string): Promise<ActorFlowVerdict>
|
|
154
|
+
/** Send a fixture file. Omitted by apps with no upload surface. */
|
|
155
|
+
upload?(file: string): Promise<ScenarioHttpResponse>
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** What the model chose to do this turn. */
|
|
159
|
+
export type VirtualUserAction =
|
|
160
|
+
| { kind: 'describe'; rpcName: string }
|
|
161
|
+
| { kind: 'call'; rpcName: string; args?: unknown }
|
|
162
|
+
| { kind: 'talkTo'; agent: string; task: string }
|
|
163
|
+
| { kind: 'upload'; file: string }
|
|
164
|
+
| { kind: 'complete'; summary?: string }
|
|
165
|
+
| { kind: 'stuck'; reason?: string }
|
|
166
|
+
|
|
167
|
+
/** How an intent ended, or that it has not. */
|
|
168
|
+
export type IntentStatus =
|
|
169
|
+
| 'open'
|
|
170
|
+
| 'suspended'
|
|
171
|
+
| 'completed'
|
|
172
|
+
| 'abandoned'
|
|
173
|
+
| 'stuck'
|
|
174
|
+
|
|
175
|
+
/** One intent's life within a run. */
|
|
176
|
+
export interface IntentRecord {
|
|
177
|
+
id: string
|
|
178
|
+
sourceId: string
|
|
179
|
+
title: string
|
|
180
|
+
status: IntentStatus
|
|
181
|
+
/** Step indices at which this intent was the active one. */
|
|
182
|
+
steps: number[]
|
|
183
|
+
/** How many times it was put down and picked back up. */
|
|
184
|
+
suspensions: number
|
|
185
|
+
summary?: string
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** One turn: what the engine scheduled, what the model did, what came back. */
|
|
189
|
+
export interface StepRecord {
|
|
190
|
+
index: number
|
|
191
|
+
intentId?: string
|
|
192
|
+
action: VirtualUserAction | { kind: 'invalid'; detail: string }
|
|
193
|
+
status?: number
|
|
194
|
+
ok?: boolean
|
|
195
|
+
/** Truncated response text, so a run record stays readable. */
|
|
196
|
+
response?: string
|
|
197
|
+
findingKinds?: VirtualUserFindingKind[]
|
|
198
|
+
tokensIn: number
|
|
199
|
+
tokensOut: number
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Everything a run produced. Seeded, so it replays. */
|
|
203
|
+
export interface VirtualUserRunResult {
|
|
204
|
+
seed: number
|
|
205
|
+
tally: VirtualUserTally
|
|
206
|
+
findings: VirtualUserFinding[]
|
|
207
|
+
intents: IntentRecord[]
|
|
208
|
+
steps: StepRecord[]
|
|
209
|
+
/** Ids and slugs the user saw, for seeding a later `stale` run. */
|
|
210
|
+
memory: Record<string, string>
|
|
211
|
+
/** Why the run ended. */
|
|
212
|
+
stoppedBy:
|
|
213
|
+
| 'no-intents'
|
|
214
|
+
| 'budget-steps'
|
|
215
|
+
| 'budget-mutations'
|
|
216
|
+
| 'budget-duration'
|
|
217
|
+
| 'stop-hook'
|
|
218
|
+
| 'exhausted'
|
|
219
|
+
}
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
7
7
|
|
|
8
8
|
import type { WorkflowRun } from '../workflow.types.js'
|
|
9
|
-
import type {
|
|
9
|
+
import type { ScenarioPersona } from '../../../services/personas-service.js'
|
|
10
10
|
import type {
|
|
11
11
|
ScenarioStepOptions,
|
|
12
12
|
ScenarioStepPhase,
|
|
13
|
+
ScenarioSurface,
|
|
13
14
|
} from '../scenario-step.types.js'
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -35,7 +36,7 @@ export interface WorkflowStepOptions {
|
|
|
35
36
|
* internally — so auth middleware and permissions are exercised end-to-end.
|
|
36
37
|
* The step is recorded durably like any RPC step.
|
|
37
38
|
*/
|
|
38
|
-
actor?:
|
|
39
|
+
actor?: ScenarioPersona
|
|
39
40
|
// Future: timeout, failFast, priority
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -221,8 +222,8 @@ export interface ScenarioStepMeta {
|
|
|
221
222
|
options?: WorkflowStepOptions
|
|
222
223
|
/** Scenario actor name this step runs as ({ actor: actors.x }) */
|
|
223
224
|
actor?: string
|
|
224
|
-
/** Mirrors the step function
|
|
225
|
-
|
|
225
|
+
/** Mirrors the surfaces the step function declares a binding for */
|
|
226
|
+
surfaces?: ScenarioSurface[]
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
/**
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { pikkuState } from '../../../pikku-state.js'
|
|
2
2
|
import { addFunction } from '../../../function/function-runner.js'
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Add a workflow to the system
|
|
6
|
-
* This is called by the generated workflow wirings
|
|
7
|
-
*/
|
|
8
4
|
export const addWorkflow = (
|
|
9
5
|
workflowName: string,
|
|
10
6
|
workflowFunc: any,
|
|
@@ -5,10 +5,6 @@ import type {
|
|
|
5
5
|
FeaturePlanEntry,
|
|
6
6
|
} from './workflow.types.js'
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Register a feature under the name it is exported as. Called from generated
|
|
10
|
-
* wiring, the same way `addWorkflow` is.
|
|
11
|
-
*/
|
|
12
8
|
export const addFeature = (
|
|
13
9
|
featureId: string,
|
|
14
10
|
feature: CoreFeature,
|
|
@@ -17,21 +13,6 @@ export const addFeature = (
|
|
|
17
13
|
pikkuState(packageName, 'workflows', 'features').set(featureId, feature)
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
/**
|
|
21
|
-
* Resolve every feature's scenario references back to the names their
|
|
22
|
-
* scenarios are registered under.
|
|
23
|
-
*
|
|
24
|
-
* Matching is by **object identity**: `pikkuScenario` returns its config
|
|
25
|
-
* verbatim and `addWorkflow` registers that same object, so a feature holding
|
|
26
|
-
* the imported identifier holds the very object that was registered. Nothing
|
|
27
|
-
* is matched by shape, by name, or by any other guess — which is also why a
|
|
28
|
-
* scenario built inline inside a feature (and therefore never registered)
|
|
29
|
-
* comes back as unresolved rather than silently running as something else.
|
|
30
|
-
*
|
|
31
|
-
* Entries are returned in declaration order, features in registration order.
|
|
32
|
-
* A scenario's effective tags are its own plus the containing feature's, so
|
|
33
|
-
* `--tags credential` selects through the feature.
|
|
34
|
-
*/
|
|
35
16
|
export const resolveFeatureScenarios = (
|
|
36
17
|
features: Map<string, CoreFeature>,
|
|
37
18
|
registrations: Map<string, CoreWorkflow>
|
|
@@ -4,82 +4,11 @@ import type {
|
|
|
4
4
|
RefValue,
|
|
5
5
|
} from './workflow-graph.types.js'
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Standard RPC handler interface (matches generated FlattenedRPCMap entries)
|
|
9
|
-
*/
|
|
10
7
|
export interface RPCHandler<I = any, O = any> {
|
|
11
8
|
input: I
|
|
12
9
|
output: O
|
|
13
10
|
}
|
|
14
11
|
|
|
15
|
-
/**
|
|
16
|
-
* Compute output types for all nodes based on their func (RPC name)
|
|
17
|
-
*/
|
|
18
|
-
export type NodeOutputMap<
|
|
19
|
-
Nodes extends Record<string, { func: string }>,
|
|
20
|
-
RPCMap extends Record<string, RPCHandler>,
|
|
21
|
-
> = {
|
|
22
|
-
[K in keyof Nodes]: Nodes[K]['func'] extends keyof RPCMap
|
|
23
|
-
? RPCMap[Nodes[K]['func']]['output']
|
|
24
|
-
: unknown
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Node definition with RPC name reference
|
|
29
|
-
*/
|
|
30
|
-
export interface GraphNodeDef<
|
|
31
|
-
RPCMap extends Record<string, RPCHandler>,
|
|
32
|
-
NodeIds extends string = string,
|
|
33
|
-
NodeOutputs extends Record<string, any> = Record<string, any>,
|
|
34
|
-
> {
|
|
35
|
-
/** RPC function name (must be a key in RPCMap) */
|
|
36
|
-
func: keyof RPCMap & string
|
|
37
|
-
/** Input mapping - reference outputs from other nodes with autocomplete */
|
|
38
|
-
input?: (
|
|
39
|
-
ref: <N extends keyof NodeOutputs & string>(
|
|
40
|
-
nodeId: N,
|
|
41
|
-
path: keyof NodeOutputs[N] & string
|
|
42
|
-
) => RefValue
|
|
43
|
-
) => Record<string, unknown>
|
|
44
|
-
/** Next node(s) to execute */
|
|
45
|
-
next?: NextConfig<NodeIds>
|
|
46
|
-
/** Error handling - node(s) to execute on error */
|
|
47
|
-
onError?: NodeIds | NodeIds[]
|
|
48
|
-
/** Maximum retry attempts allowed (excludes the initial attempt) */
|
|
49
|
-
retries?: number
|
|
50
|
-
/** Delay between retries — milliseconds, duration string, or 'exponential' */
|
|
51
|
-
retryDelay?: string | number
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Helper to create a type-safe graph definition with RPC autocomplete.
|
|
56
|
-
* Pass node IDs as first type parameter for type-safe next/ref/output key completion.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* // Import the typed graph from generated types
|
|
61
|
-
* import { pikkuWorkflowGraph } from './.pikku/workflow/pikku-workflow-types.gen.js'
|
|
62
|
-
*
|
|
63
|
-
* export const myGraph = pikkuWorkflowGraph({
|
|
64
|
-
* name: 'myWorkflow',
|
|
65
|
-
* nodes: {
|
|
66
|
-
* entry: 'createUserProfile', // autocompletes RPC names
|
|
67
|
-
* sendWelcome: 'sendEmail',
|
|
68
|
-
* },
|
|
69
|
-
* config: {
|
|
70
|
-
* entry: { next: 'sendWelcome' },
|
|
71
|
-
* sendWelcome: {
|
|
72
|
-
* input: (ref) => ({
|
|
73
|
-
* to: ref('entry', 'email'), // 'entry' and 'email' both autocomplete
|
|
74
|
-
* }),
|
|
75
|
-
* },
|
|
76
|
-
* },
|
|
77
|
-
* })
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
/**
|
|
81
|
-
* Type to compute output types for all nodes based on their func mapping
|
|
82
|
-
*/
|
|
83
12
|
type ComputeNodeOutputs<
|
|
84
13
|
FuncMap extends Record<string, string>,
|
|
85
14
|
RPCMap extends Record<string, RPCHandler>,
|
|
@@ -89,9 +18,6 @@ type ComputeNodeOutputs<
|
|
|
89
18
|
: unknown
|
|
90
19
|
}
|
|
91
20
|
|
|
92
|
-
/**
|
|
93
|
-
* Type to compute input types for all nodes based on their func mapping
|
|
94
|
-
*/
|
|
95
21
|
type ComputeNodeInputs<
|
|
96
22
|
FuncMap extends Record<string, string>,
|
|
97
23
|
RPCMap extends Record<string, RPCHandler>,
|
|
@@ -101,15 +27,8 @@ type ComputeNodeInputs<
|
|
|
101
27
|
: unknown
|
|
102
28
|
}
|
|
103
29
|
|
|
104
|
-
/**
|
|
105
|
-
* Typed ref value - carries the type of the referenced field as a phantom type.
|
|
106
|
-
* At runtime this is just RefValue, but TypeScript tracks the type T.
|
|
107
|
-
*/
|
|
108
30
|
export type TypedRef<T> = RefValue & { __phantomType?: T }
|
|
109
31
|
|
|
110
|
-
/**
|
|
111
|
-
* Map input type fields to allow TypedRef of matching type as an alternative
|
|
112
|
-
*/
|
|
113
32
|
type InputWithRefs<T> = {
|
|
114
33
|
[K in keyof T]: T[K] | TypedRef<T[K]>
|
|
115
34
|
}
|
|
@@ -126,7 +45,6 @@ export function createGraph<RPCMap extends Record<string, RPCHandler>>() {
|
|
|
126
45
|
> => {
|
|
127
46
|
type NodeIds = Extract<keyof FuncMap, string>
|
|
128
47
|
|
|
129
|
-
// If no nodes provided, return just the funcMap converted to graph nodes
|
|
130
48
|
if (!nodesOrBuilder) {
|
|
131
49
|
const result: Record<string, GraphNodeConfig<string>> = {}
|
|
132
50
|
for (const [nodeId, rpcName] of Object.entries(funcMap)) {
|
|
@@ -159,9 +77,6 @@ export function createGraph<RPCMap extends Record<string, RPCHandler>>() {
|
|
|
159
77
|
}
|
|
160
78
|
}
|
|
161
79
|
|
|
162
|
-
/**
|
|
163
|
-
* Type helper for node configuration map
|
|
164
|
-
*/
|
|
165
80
|
type GraphNodeConfigMap<
|
|
166
81
|
FuncMap extends Record<string, string>,
|
|
167
82
|
RPCMap extends Record<string, RPCHandler>,
|
|
@@ -180,57 +95,6 @@ type GraphNodeConfigMap<
|
|
|
180
95
|
onError?: Extract<keyof FuncMap, string> | Extract<keyof FuncMap, string>[]
|
|
181
96
|
retries?: number
|
|
182
97
|
retryDelay?: string | number
|
|
183
|
-
/** Free-text node documentation. Non-semantic — excluded from graphHash. */
|
|
184
98
|
notes?: string
|
|
185
99
|
}
|
|
186
100
|
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Untyped graph for use without RPC map.
|
|
190
|
-
* Pass node IDs as type parameter for type-safe next/ref, or omit for untyped usage.
|
|
191
|
-
*
|
|
192
|
-
* @example
|
|
193
|
-
* ```typescript
|
|
194
|
-
* // Typed usage - next and ref are type-checked
|
|
195
|
-
* graph<'entry' | 'sendWelcome'>({
|
|
196
|
-
* entry: { func: 'createUserProfile', next: 'sendWelcome' },
|
|
197
|
-
* sendWelcome: { func: 'sendEmail', input: (ref) => ({ to: ref('entry', 'email') }) },
|
|
198
|
-
* })
|
|
199
|
-
*
|
|
200
|
-
* // Untyped usage - no type checking on next/ref
|
|
201
|
-
* graph({
|
|
202
|
-
* entry: { func: 'createUserProfile', next: 'sendWelcome' },
|
|
203
|
-
* sendWelcome: { func: 'sendEmail' },
|
|
204
|
-
* })
|
|
205
|
-
* ```
|
|
206
|
-
*/
|
|
207
|
-
export function graph<NodeIds extends string = string>(
|
|
208
|
-
nodes: Record<
|
|
209
|
-
NodeIds,
|
|
210
|
-
{
|
|
211
|
-
func: string
|
|
212
|
-
next?: NextConfig<NodeIds>
|
|
213
|
-
input?: (
|
|
214
|
-
ref: (nodeId: NodeIds, path: string) => RefValue
|
|
215
|
-
) => Record<string, unknown>
|
|
216
|
-
onError?: NodeIds | NodeIds[]
|
|
217
|
-
retries?: number
|
|
218
|
-
retryDelay?: string | number
|
|
219
|
-
}
|
|
220
|
-
>
|
|
221
|
-
): Record<NodeIds, GraphNodeConfig<NodeIds>> {
|
|
222
|
-
const result: Record<string, GraphNodeConfig<string>> = {}
|
|
223
|
-
|
|
224
|
-
for (const [nodeId, def] of Object.entries(nodes) as [string, any][]) {
|
|
225
|
-
result[nodeId] = {
|
|
226
|
-
func: def.func,
|
|
227
|
-
input: def.input as any,
|
|
228
|
-
next: def.next,
|
|
229
|
-
onError: def.onError,
|
|
230
|
-
retries: def.retries,
|
|
231
|
-
retryDelay: def.retryDelay,
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return result as Record<NodeIds, GraphNodeConfig<NodeIds>>
|
|
236
|
-
}
|
|
@@ -258,8 +258,6 @@ describe('graph-runner bugs', () => {
|
|
|
258
258
|
},
|
|
259
259
|
} as any)
|
|
260
260
|
|
|
261
|
-
// start → a, where a loops back through b once, then exits to c:
|
|
262
|
-
// start → a --retry--> b → a --done--> c
|
|
263
261
|
const meta: WorkflowRuntimeMeta = {
|
|
264
262
|
name: 'testCyclicGraph',
|
|
265
263
|
pikkuFuncId: 'testCyclicGraph',
|
|
@@ -274,11 +272,16 @@ describe('graph-runner bugs', () => {
|
|
|
274
272
|
},
|
|
275
273
|
}
|
|
276
274
|
|
|
277
|
-
const runId = await ws.createRun(
|
|
278
|
-
|
|
279
|
-
|
|
275
|
+
const runId = await ws.createRun(
|
|
276
|
+
'testCyclicGraph',
|
|
277
|
+
{},
|
|
278
|
+
false,
|
|
279
|
+
'cyclic-hash',
|
|
280
|
+
{
|
|
281
|
+
type: 'test',
|
|
282
|
+
}
|
|
283
|
+
)
|
|
280
284
|
|
|
281
|
-
// Succeed a queued step (taking an optional branch), then advance the graph.
|
|
282
285
|
const advance = async (stepName: string, branch?: string) => {
|
|
283
286
|
const step = await ws.getStepState(runId, stepName)
|
|
284
287
|
await ws.setStepRunning(step.stepId)
|
|
@@ -287,15 +290,13 @@ describe('graph-runner bugs', () => {
|
|
|
287
290
|
await continueGraph(ws, runId, 'testCyclicGraph', meta)
|
|
288
291
|
}
|
|
289
292
|
|
|
290
|
-
await continueGraph(ws, runId, 'testCyclicGraph', meta)
|
|
293
|
+
await continueGraph(ws, runId, 'testCyclicGraph', meta)
|
|
291
294
|
await advance('start')
|
|
292
|
-
await advance('a', 'retry')
|
|
293
|
-
await advance('b')
|
|
294
|
-
await advance('a#1', 'done')
|
|
295
|
+
await advance('a', 'retry')
|
|
296
|
+
await advance('b')
|
|
297
|
+
await advance('a#1', 'done')
|
|
295
298
|
await advance('c')
|
|
296
299
|
|
|
297
|
-
// Each step records the predecessor it was reached from; the cyclic
|
|
298
|
-
// revisit is a fresh ordinal instance (a#1) with its own provenance.
|
|
299
300
|
assert.deepEqual(queued, [
|
|
300
301
|
{ stepName: 'start', fromStepName: undefined },
|
|
301
302
|
{ stepName: 'a', fromStepName: 'start' },
|
|
@@ -307,7 +308,6 @@ describe('graph-runner bugs', () => {
|
|
|
307
308
|
const run = await ws.getRun(runId)
|
|
308
309
|
assert.equal(run?.status, 'completed')
|
|
309
310
|
|
|
310
|
-
// Reconstruct the walked path purely from the fromStepName chain.
|
|
311
311
|
const instances = await ws.getStepInstances(runId)
|
|
312
312
|
const from = new Map(instances.map((i) => [i.stepName, i.fromStepName]))
|
|
313
313
|
const path: string[] = []
|
|
@@ -419,7 +419,6 @@ describe('graph-runner bugs', () => {
|
|
|
419
419
|
test('inline graph revisits a cyclic node and records the walked path via fromStepName', async () => {
|
|
420
420
|
const ws = new InMemoryWorkflowService()
|
|
421
421
|
|
|
422
|
-
// attempt loops back to itself via `again` until it converges to `done`.
|
|
423
422
|
const mockRpcService = {
|
|
424
423
|
rpcWithWire: async (rpcName: string, _data: any, wire: any) => {
|
|
425
424
|
if (rpcName === 'cyclicBegin') return { attempts: 3 }
|
|
@@ -464,7 +463,6 @@ describe('graph-runner bugs', () => {
|
|
|
464
463
|
const run = await ws.getRun(runId)
|
|
465
464
|
assert.equal(run?.status, 'completed')
|
|
466
465
|
|
|
467
|
-
// The self-cycle produced three ordinal instances of `attempt`.
|
|
468
466
|
const instances = await ws.getStepInstances(runId)
|
|
469
467
|
const names = instances.map((i) => i.stepName).sort()
|
|
470
468
|
assert.ok(
|
|
@@ -474,8 +472,6 @@ describe('graph-runner bugs', () => {
|
|
|
474
472
|
`expected attempt/attempt#1/attempt#2, got ${JSON.stringify(names)}`
|
|
475
473
|
)
|
|
476
474
|
|
|
477
|
-
// Walk the fromStepName chain back from the terminal node — inline now
|
|
478
|
-
// records provenance identical to the queued path.
|
|
479
475
|
const from = new Map(instances.map((i) => [i.stepName, i.fromStepName]))
|
|
480
476
|
const path: string[] = []
|
|
481
477
|
let cursor: string | undefined = 'finish'
|
|
@@ -483,7 +479,13 @@ describe('graph-runner bugs', () => {
|
|
|
483
479
|
path.unshift(cursor)
|
|
484
480
|
cursor = from.get(cursor) ?? undefined
|
|
485
481
|
}
|
|
486
|
-
assert.deepEqual(path, [
|
|
482
|
+
assert.deepEqual(path, [
|
|
483
|
+
'begin',
|
|
484
|
+
'attempt',
|
|
485
|
+
'attempt#1',
|
|
486
|
+
'attempt#2',
|
|
487
|
+
'finish',
|
|
488
|
+
])
|
|
487
489
|
|
|
488
490
|
delete metaState['testInlineCyclic']
|
|
489
491
|
})
|
|
@@ -647,7 +649,6 @@ describe('graph-runner bugs', () => {
|
|
|
647
649
|
},
|
|
648
650
|
}
|
|
649
651
|
|
|
650
|
-
// Set up queue service to verify nothing is queued
|
|
651
652
|
let queued = false
|
|
652
653
|
pikkuState(null, 'package', 'singletonServices', {
|
|
653
654
|
queueService: {
|