@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,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stack of things this user is in the middle of — and the whole of the
|
|
3
|
+
* engine's randomness.
|
|
4
|
+
*
|
|
5
|
+
* A real person does not run a flow end to end: they start something, get
|
|
6
|
+
* pulled away, do a bit of something else, come back to a world that moved
|
|
7
|
+
* underneath them, and sometimes never come back at all. Modelling that as a
|
|
8
|
+
* stack of partially-completed intents is what produces the bugs worth having —
|
|
9
|
+
* half-mutated state, a flow resumed against changed data, an invite accepted
|
|
10
|
+
* after the plan changed — none of which a scripted scenario can reach.
|
|
11
|
+
*
|
|
12
|
+
* Scheduling is the engine's job and the model's turns are not: the model
|
|
13
|
+
* decides what to do *within* the active intent, the stack decides which intent
|
|
14
|
+
* that is. Keeping the split there is what makes a run reproducible from a seed
|
|
15
|
+
* while the work inside it stays free.
|
|
16
|
+
*
|
|
17
|
+
* A feature is only where an intent comes from. Nothing here tracks whether one
|
|
18
|
+
* was "completed correctly", and the model is never told an intent boundary
|
|
19
|
+
* exists.
|
|
20
|
+
*/
|
|
21
|
+
export class IntentStack {
|
|
22
|
+
rng;
|
|
23
|
+
profile;
|
|
24
|
+
maxOpen;
|
|
25
|
+
tracked = [];
|
|
26
|
+
unstarted;
|
|
27
|
+
active = null;
|
|
28
|
+
counter = 0;
|
|
29
|
+
constructor(sources, rng, profile,
|
|
30
|
+
/** Cap on intents open at once, so a distractible user still finishes things. */
|
|
31
|
+
maxOpen = 3) {
|
|
32
|
+
this.rng = rng;
|
|
33
|
+
this.profile = profile;
|
|
34
|
+
this.maxOpen = maxOpen;
|
|
35
|
+
this.unstarted = [...sources];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Pick the intent for this tick, or `null` when there is nothing left to do.
|
|
39
|
+
*
|
|
40
|
+
* The first tick always starts something; after that the four moves are
|
|
41
|
+
* weighted by the disposition, and a move that has nowhere to go degrades to
|
|
42
|
+
* `continue` rather than stalling the run.
|
|
43
|
+
*/
|
|
44
|
+
next(step) {
|
|
45
|
+
if (!this.active) {
|
|
46
|
+
const started = this.startOrResume();
|
|
47
|
+
if (!started)
|
|
48
|
+
return null;
|
|
49
|
+
started.steps.push(step);
|
|
50
|
+
this.active = started;
|
|
51
|
+
return { intent: started, move: 'start' };
|
|
52
|
+
}
|
|
53
|
+
const move = this.rng.weighted(this.profile.moves) ?? 'continue';
|
|
54
|
+
if (move === 'continue') {
|
|
55
|
+
this.active.steps.push(step);
|
|
56
|
+
return { intent: this.active, move: 'continue' };
|
|
57
|
+
}
|
|
58
|
+
const current = this.active;
|
|
59
|
+
if (move === 'abandon') {
|
|
60
|
+
current.status = 'abandoned';
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
current.status = 'suspended';
|
|
64
|
+
current.suspensions++;
|
|
65
|
+
}
|
|
66
|
+
this.active = null;
|
|
67
|
+
const next = move === 'resume' ? this.resumeSuspended() : this.startOrResume(current);
|
|
68
|
+
if (!next) {
|
|
69
|
+
// Nowhere to go: keep working on what we had rather than ending a run
|
|
70
|
+
// early. An abandoned intent stays abandoned — that decision stands.
|
|
71
|
+
if (current.status === 'abandoned')
|
|
72
|
+
return null;
|
|
73
|
+
current.status = 'open';
|
|
74
|
+
current.suspensions--;
|
|
75
|
+
current.steps.push(step);
|
|
76
|
+
this.active = current;
|
|
77
|
+
return { intent: current, move: 'continue' };
|
|
78
|
+
}
|
|
79
|
+
next.status = 'open';
|
|
80
|
+
next.steps.push(step);
|
|
81
|
+
this.active = next;
|
|
82
|
+
return { intent: next, move };
|
|
83
|
+
}
|
|
84
|
+
/** Mark the active intent finished; the next tick schedules something else. */
|
|
85
|
+
complete(summary) {
|
|
86
|
+
if (!this.active)
|
|
87
|
+
return;
|
|
88
|
+
this.active.status = 'completed';
|
|
89
|
+
this.active.summary = summary;
|
|
90
|
+
this.active = null;
|
|
91
|
+
}
|
|
92
|
+
/** Mark the active intent as one the user could not get through. */
|
|
93
|
+
stuck(reason) {
|
|
94
|
+
if (!this.active)
|
|
95
|
+
return;
|
|
96
|
+
this.active.status = 'stuck';
|
|
97
|
+
this.active.summary = reason;
|
|
98
|
+
this.active = null;
|
|
99
|
+
}
|
|
100
|
+
/** Every intent the run touched, in the order it first opened them. */
|
|
101
|
+
records() {
|
|
102
|
+
return this.tracked.map((intent) => ({
|
|
103
|
+
id: intent.id,
|
|
104
|
+
sourceId: intent.source.id,
|
|
105
|
+
title: intent.source.title,
|
|
106
|
+
status: intent.status,
|
|
107
|
+
steps: [...intent.steps],
|
|
108
|
+
suspensions: intent.suspensions,
|
|
109
|
+
summary: intent.summary,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
/** Prefer opening something new, falling back to picking a suspended one up. */
|
|
113
|
+
startOrResume(exclude) {
|
|
114
|
+
const openCount = this.tracked.filter((intent) => intent.status === 'open' || intent.status === 'suspended').length;
|
|
115
|
+
if (this.unstarted.length > 0 && openCount < this.maxOpen) {
|
|
116
|
+
const source = this.rng.pick(this.unstarted);
|
|
117
|
+
this.unstarted.splice(this.unstarted.indexOf(source), 1);
|
|
118
|
+
const intent = {
|
|
119
|
+
id: `intent_${++this.counter}`,
|
|
120
|
+
source,
|
|
121
|
+
status: 'open',
|
|
122
|
+
steps: [],
|
|
123
|
+
suspensions: 0,
|
|
124
|
+
};
|
|
125
|
+
this.tracked.push(intent);
|
|
126
|
+
return intent;
|
|
127
|
+
}
|
|
128
|
+
return this.resumeSuspended(exclude);
|
|
129
|
+
}
|
|
130
|
+
resumeSuspended(exclude) {
|
|
131
|
+
const suspended = this.tracked.filter((intent) => intent.status === 'suspended' && intent !== exclude);
|
|
132
|
+
return this.rng.pick(suspended) ?? null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The intents a persona may be given: those whose source names them, plus every
|
|
137
|
+
* source that names nobody.
|
|
138
|
+
*
|
|
139
|
+
* This is a free lookup rather than new authoring — scenario meta already
|
|
140
|
+
* records which personas each scenario runs as.
|
|
141
|
+
*/
|
|
142
|
+
export const intentsForPersona = (sources, personaId) => sources.filter((source) => !source.personas?.length || source.personas.includes(personaId));
|
|
@@ -0,0 +1,24 @@
|
|
|
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 declare const createRng: (seed: number) => {
|
|
12
|
+
next: () => number;
|
|
13
|
+
/** True with probability `p`. */
|
|
14
|
+
chance: (p: number) => boolean;
|
|
15
|
+
/** A uniform pick, or undefined for an empty list. */
|
|
16
|
+
pick: <T>(items: readonly T[]) => T | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* A weighted pick over `[key, weight]` pairs. Zero-weight keys can never be
|
|
19
|
+
* drawn, which is how a disposition switches a move off entirely.
|
|
20
|
+
*/
|
|
21
|
+
weighted: <K extends string>(weights: Readonly<Record<K, number>>) => K | undefined;
|
|
22
|
+
};
|
|
23
|
+
/** The seeded generator the engine threads through a whole run. */
|
|
24
|
+
export type VirtualUserRng = ReturnType<typeof createRng>;
|
|
@@ -0,0 +1,44 @@
|
|
|
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) => {
|
|
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) => next() < p,
|
|
24
|
+
/** A uniform pick, or undefined for an empty list. */
|
|
25
|
+
pick: (items) => items.length === 0 ? undefined : items[Math.floor(next() * items.length)],
|
|
26
|
+
/**
|
|
27
|
+
* A weighted pick over `[key, weight]` pairs. Zero-weight keys can never be
|
|
28
|
+
* drawn, which is how a disposition switches a move off entirely.
|
|
29
|
+
*/
|
|
30
|
+
weighted: (weights) => {
|
|
31
|
+
const entries = Object.entries(weights).filter(([, weight]) => weight > 0);
|
|
32
|
+
const total = entries.reduce((sum, [, weight]) => sum + weight, 0);
|
|
33
|
+
if (total <= 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
let roll = next() * total;
|
|
36
|
+
for (const [key, weight] of entries) {
|
|
37
|
+
roll -= weight;
|
|
38
|
+
if (roll <= 0)
|
|
39
|
+
return key;
|
|
40
|
+
}
|
|
41
|
+
return entries[entries.length - 1]?.[0];
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ScenarioPersona } from '../../services/personas-service.js';
|
|
2
|
+
import type { VirtualUserTarget } from './virtual-user.types.js';
|
|
3
|
+
export interface PersonaTargetOptions {
|
|
4
|
+
/** Model the persona uses for its side of a conversation with an agent. */
|
|
5
|
+
model?: string;
|
|
6
|
+
/** Agents this user may talk to. Omit to leave `talkTo` unavailable. */
|
|
7
|
+
agents?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Drive a virtual user through a signed-in persona.
|
|
11
|
+
*
|
|
12
|
+
* This is the only place the engine meets the network. A persona already signs
|
|
13
|
+
* in as a real user over the app's own auth, keeps its cookies, re-logs-in when
|
|
14
|
+
* a session expires mid-run and reports a status as data rather than throwing —
|
|
15
|
+
* everything a user imitating a user needs, and none of it worth building twice.
|
|
16
|
+
*
|
|
17
|
+
* `invokeRaw` rather than `invoke` matters: to a virtual user a 403 is not an
|
|
18
|
+
* error, it is the system saying no, which is information it should be allowed
|
|
19
|
+
* to act on.
|
|
20
|
+
*/
|
|
21
|
+
export declare const personaVirtualUserTarget: (persona: ScenarioPersona, { model, agents }?: PersonaTargetOptions) => VirtualUserTarget;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive a virtual user through a signed-in persona.
|
|
3
|
+
*
|
|
4
|
+
* This is the only place the engine meets the network. A persona already signs
|
|
5
|
+
* in as a real user over the app's own auth, keeps its cookies, re-logs-in when
|
|
6
|
+
* a session expires mid-run and reports a status as data rather than throwing —
|
|
7
|
+
* everything a user imitating a user needs, and none of it worth building twice.
|
|
8
|
+
*
|
|
9
|
+
* `invokeRaw` rather than `invoke` matters: to a virtual user a 403 is not an
|
|
10
|
+
* error, it is the system saying no, which is information it should be allowed
|
|
11
|
+
* to act on.
|
|
12
|
+
*/
|
|
13
|
+
export const personaVirtualUserTarget = (persona, { model, agents } = {}) => ({
|
|
14
|
+
call: (rpcName, args) => persona.invokeRaw(rpcName, args),
|
|
15
|
+
talkTo: agents?.length
|
|
16
|
+
? async (agent, task) => {
|
|
17
|
+
if (!agents.includes(agent)) {
|
|
18
|
+
return {
|
|
19
|
+
passed: false,
|
|
20
|
+
reasoning: `There is no assistant called '${agent}'.`,
|
|
21
|
+
transcript: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return persona.converse({
|
|
25
|
+
agent,
|
|
26
|
+
task,
|
|
27
|
+
// A user asking for something judges the answer by whether they got
|
|
28
|
+
// what they asked for. There is no separate criterion to hold it to.
|
|
29
|
+
evaluate: `The assistant did what was asked: ${task}`,
|
|
30
|
+
model,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
: undefined,
|
|
34
|
+
});
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { ScenarioHttpResponse } from '../../services/personas-service.js';
|
|
2
|
+
import type { ActorFlowVerdict } from '../actor-flow/actor-flow.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* How a virtual user behaves, mechanically. A disposition changes the loop, the
|
|
5
|
+
* input generation, the memory and the oracle — anything that only changes how
|
|
6
|
+
* the user *talks* is persona prose (`ResolvedPersona.personality`) and does
|
|
7
|
+
* not belong here.
|
|
8
|
+
*
|
|
9
|
+
* - `realistic` — schema-first, goal-directed, plausible values (default).
|
|
10
|
+
* - `careless` — repeats, abandons, double-submits, boundary values.
|
|
11
|
+
* - `newcomer` — starts with empty memory and must discover everything.
|
|
12
|
+
* - `stale` — seeded from an earlier run's ids, some no longer valid.
|
|
13
|
+
* - `auditor` — pursues no goal; reads one truth from several places and compares.
|
|
14
|
+
* - `adversarial` — probes authorization and tenancy; a 2xx can be the finding.
|
|
15
|
+
* - `accountable` — pursues its goals for real; the only one production allows.
|
|
16
|
+
*
|
|
17
|
+
* `accountable` sits opposite `adversarial` on an *intent* axis — bad faith
|
|
18
|
+
* against good faith — where `careless` and `thorough` are a *care* axis. It is
|
|
19
|
+
* the one disposition whose actions carry consequences: no oracle, no rollback,
|
|
20
|
+
* and every call attributed to the persona in the audit log like anyone else's.
|
|
21
|
+
*/
|
|
22
|
+
export type VirtualUserDisposition = 'realistic' | 'careless' | 'newcomer' | 'stale' | 'auditor' | 'adversarial' | 'accountable';
|
|
23
|
+
/**
|
|
24
|
+
* The one disposition a production environment accepts.
|
|
25
|
+
*
|
|
26
|
+
* Every other disposition exists to find out what the product does wrong, which
|
|
27
|
+
* is not a thing to do to real customers' data. Named here so the declaration
|
|
28
|
+
* check and the sign-in check cannot drift apart.
|
|
29
|
+
*/
|
|
30
|
+
export declare const PRODUCTION_DISPOSITION: VirtualUserDisposition;
|
|
31
|
+
/**
|
|
32
|
+
* Hard caps the engine enforces itself. Anything the engine cannot count —
|
|
33
|
+
* money above all — belongs in {@link RunVirtualUserParams.stop} instead.
|
|
34
|
+
*/
|
|
35
|
+
export interface VirtualUserBudget {
|
|
36
|
+
/** Model turns, including ones that produced no call. */
|
|
37
|
+
steps?: number;
|
|
38
|
+
/** Non-read RPC calls. */
|
|
39
|
+
mutations?: number;
|
|
40
|
+
/** Wall clock, as ms or a duration string (`'30m'`). */
|
|
41
|
+
duration?: number | string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The running count handed to {@link RunVirtualUserParams.stop}. Pikku collects
|
|
45
|
+
* it because only the engine sees every step; what it is *worth* is the app's,
|
|
46
|
+
* which is why no price or currency appears anywhere in core.
|
|
47
|
+
*/
|
|
48
|
+
export interface VirtualUserTally {
|
|
49
|
+
steps: number;
|
|
50
|
+
calls: number;
|
|
51
|
+
mutations: number;
|
|
52
|
+
tokensIn: number;
|
|
53
|
+
tokensOut: number;
|
|
54
|
+
model: string;
|
|
55
|
+
elapsedMs: number;
|
|
56
|
+
findings: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* One RPC as the virtual user sees it before reading its schema: enough to
|
|
60
|
+
* choose from, not enough to call with. The whole catalogue goes in the prompt,
|
|
61
|
+
* so this stays deliberately compact — a project with 430 RPCs renders to
|
|
62
|
+
* roughly 8k tokens, which is cheaper than any retrieval step and hides nothing.
|
|
63
|
+
*/
|
|
64
|
+
export interface ApiCatalogueEntry {
|
|
65
|
+
name: string;
|
|
66
|
+
/** Top-level input property names, for choosing between similar endpoints. */
|
|
67
|
+
inputKeys?: readonly string[];
|
|
68
|
+
/** Top-level output property names. */
|
|
69
|
+
outputKeys?: readonly string[];
|
|
70
|
+
description?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the call only reads. `undefined` means nobody annotated it — which
|
|
73
|
+
* is not the same as safe, so the engine falls back to a name heuristic and
|
|
74
|
+
* reports how many entries it had to guess at.
|
|
75
|
+
*/
|
|
76
|
+
readonly?: boolean;
|
|
77
|
+
/** Declared by the app as needing a human's approval — denied by default. */
|
|
78
|
+
approvalRequired?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Scopes the session must hold to call this, all of them.
|
|
81
|
+
*
|
|
82
|
+
* Splits the catalogue in two: what a persona's roles entitle it to reach,
|
|
83
|
+
* and what they do not. Scopes rather than permission-function names because
|
|
84
|
+
* a scope is declared and checkable, whereas a permission is arbitrary code
|
|
85
|
+
* whose verdict nobody can predict without running it.
|
|
86
|
+
*/
|
|
87
|
+
scopes?: readonly string[];
|
|
88
|
+
tags?: readonly string[];
|
|
89
|
+
/** JSON schema returned by `describe`, before the user may call. */
|
|
90
|
+
inputSchema?: Record<string, unknown>;
|
|
91
|
+
outputSchema?: Record<string, unknown>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Where an intent comes from: a feature or scenario in the app's own words.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately prose. The virtual user never receives the scenario's step graph
|
|
97
|
+
* — no rpc names, no `$ref` dataflow — because finding the API itself is the
|
|
98
|
+
* behaviour under test, and those graphs are a build-time artifact that no
|
|
99
|
+
* deployed stage carries.
|
|
100
|
+
*/
|
|
101
|
+
export interface IntentSource {
|
|
102
|
+
id: string;
|
|
103
|
+
title: string;
|
|
104
|
+
description?: string;
|
|
105
|
+
/** Step prose, as a person would be told it. Never rpc names. */
|
|
106
|
+
steps?: readonly string[];
|
|
107
|
+
tags?: readonly string[];
|
|
108
|
+
/** Persona ids this intent is available to. Empty means everyone. */
|
|
109
|
+
personas?: readonly string[];
|
|
110
|
+
}
|
|
111
|
+
/** Why the engine flagged something. */
|
|
112
|
+
export type VirtualUserFindingKind = 'server-error' | 'transport-error' | 'schema-violation' | 'unexpected-success' | 'custom';
|
|
113
|
+
/** Something worth a human's attention, found while imitating a user. */
|
|
114
|
+
export interface VirtualUserFinding {
|
|
115
|
+
kind: VirtualUserFindingKind;
|
|
116
|
+
detail: string;
|
|
117
|
+
rpcName?: string;
|
|
118
|
+
status?: number;
|
|
119
|
+
intentId?: string;
|
|
120
|
+
/** Step index within the run, so the transcript can be replayed to here. */
|
|
121
|
+
step: number;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The transport the virtual user acts through. HTTP in production (an
|
|
125
|
+
* `HttpPersona`), but the engine only sees this contract — which is what
|
|
126
|
+
* lets the whole loop be tested without a network.
|
|
127
|
+
*/
|
|
128
|
+
export interface VirtualUserTarget {
|
|
129
|
+
/** Invoke an RPC as this user, reporting the status as data rather than throwing. */
|
|
130
|
+
call(rpcName: string, args: unknown): Promise<ScenarioHttpResponse>;
|
|
131
|
+
/** Converse with an AI agent in persona. Omitted by apps that have no agents. */
|
|
132
|
+
talkTo?(agent: string, task: string): Promise<ActorFlowVerdict>;
|
|
133
|
+
/** Send a fixture file. Omitted by apps with no upload surface. */
|
|
134
|
+
upload?(file: string): Promise<ScenarioHttpResponse>;
|
|
135
|
+
}
|
|
136
|
+
/** What the model chose to do this turn. */
|
|
137
|
+
export type VirtualUserAction = {
|
|
138
|
+
kind: 'describe';
|
|
139
|
+
rpcName: string;
|
|
140
|
+
} | {
|
|
141
|
+
kind: 'call';
|
|
142
|
+
rpcName: string;
|
|
143
|
+
args?: unknown;
|
|
144
|
+
} | {
|
|
145
|
+
kind: 'talkTo';
|
|
146
|
+
agent: string;
|
|
147
|
+
task: string;
|
|
148
|
+
} | {
|
|
149
|
+
kind: 'upload';
|
|
150
|
+
file: string;
|
|
151
|
+
} | {
|
|
152
|
+
kind: 'complete';
|
|
153
|
+
summary?: string;
|
|
154
|
+
} | {
|
|
155
|
+
kind: 'stuck';
|
|
156
|
+
reason?: string;
|
|
157
|
+
};
|
|
158
|
+
/** How an intent ended, or that it has not. */
|
|
159
|
+
export type IntentStatus = 'open' | 'suspended' | 'completed' | 'abandoned' | 'stuck';
|
|
160
|
+
/** One intent's life within a run. */
|
|
161
|
+
export interface IntentRecord {
|
|
162
|
+
id: string;
|
|
163
|
+
sourceId: string;
|
|
164
|
+
title: string;
|
|
165
|
+
status: IntentStatus;
|
|
166
|
+
/** Step indices at which this intent was the active one. */
|
|
167
|
+
steps: number[];
|
|
168
|
+
/** How many times it was put down and picked back up. */
|
|
169
|
+
suspensions: number;
|
|
170
|
+
summary?: string;
|
|
171
|
+
}
|
|
172
|
+
/** One turn: what the engine scheduled, what the model did, what came back. */
|
|
173
|
+
export interface StepRecord {
|
|
174
|
+
index: number;
|
|
175
|
+
intentId?: string;
|
|
176
|
+
action: VirtualUserAction | {
|
|
177
|
+
kind: 'invalid';
|
|
178
|
+
detail: string;
|
|
179
|
+
};
|
|
180
|
+
status?: number;
|
|
181
|
+
ok?: boolean;
|
|
182
|
+
/** Truncated response text, so a run record stays readable. */
|
|
183
|
+
response?: string;
|
|
184
|
+
findingKinds?: VirtualUserFindingKind[];
|
|
185
|
+
tokensIn: number;
|
|
186
|
+
tokensOut: number;
|
|
187
|
+
}
|
|
188
|
+
/** Everything a run produced. Seeded, so it replays. */
|
|
189
|
+
export interface VirtualUserRunResult {
|
|
190
|
+
seed: number;
|
|
191
|
+
tally: VirtualUserTally;
|
|
192
|
+
findings: VirtualUserFinding[];
|
|
193
|
+
intents: IntentRecord[];
|
|
194
|
+
steps: StepRecord[];
|
|
195
|
+
/** Ids and slugs the user saw, for seeding a later `stale` run. */
|
|
196
|
+
memory: Record<string, string>;
|
|
197
|
+
/** Why the run ended. */
|
|
198
|
+
stoppedBy: 'no-intents' | 'budget-steps' | 'budget-mutations' | 'budget-duration' | 'stop-hook' | 'exhausted';
|
|
199
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one disposition a production environment accepts.
|
|
3
|
+
*
|
|
4
|
+
* Every other disposition exists to find out what the product does wrong, which
|
|
5
|
+
* is not a thing to do to real customers' data. Named here so the declaration
|
|
6
|
+
* check and the sign-in check cannot drift apart.
|
|
7
|
+
*/
|
|
8
|
+
export const PRODUCTION_DISPOSITION = 'accountable';
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
6
|
import type { WorkflowRun } from '../workflow.types.js';
|
|
7
|
-
import type {
|
|
8
|
-
import type { ScenarioStepOptions, ScenarioStepPhase } from '../scenario-step.types.js';
|
|
7
|
+
import type { ScenarioPersona } from '../../../services/personas-service.js';
|
|
8
|
+
import type { ScenarioStepOptions, ScenarioStepPhase, ScenarioSurface } from '../scenario-step.types.js';
|
|
9
9
|
/**
|
|
10
10
|
* Workflow step options
|
|
11
11
|
*/
|
|
@@ -29,7 +29,7 @@ export interface WorkflowStepOptions {
|
|
|
29
29
|
* internally — so auth middleware and permissions are exercised end-to-end.
|
|
30
30
|
* The step is recorded durably like any RPC step.
|
|
31
31
|
*/
|
|
32
|
-
actor?:
|
|
32
|
+
actor?: ScenarioPersona;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Options for workflow.expectEventually() — a durable polling step used by
|
|
@@ -204,8 +204,8 @@ export interface ScenarioStepMeta {
|
|
|
204
204
|
options?: WorkflowStepOptions;
|
|
205
205
|
/** Scenario actor name this step runs as ({ actor: actors.x }) */
|
|
206
206
|
actor?: string;
|
|
207
|
-
/** Mirrors the step function
|
|
208
|
-
|
|
207
|
+
/** Mirrors the surfaces the step function declares a binding for */
|
|
208
|
+
surfaces?: ScenarioSurface[];
|
|
209
209
|
}
|
|
210
210
|
/**
|
|
211
211
|
* Simple condition expression (leaf node)
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { pikkuState } from '../../../pikku-state.js';
|
|
2
2
|
import { addFunction } from '../../../function/function-runner.js';
|
|
3
|
-
/**
|
|
4
|
-
* Add a workflow to the system
|
|
5
|
-
* This is called by the generated workflow wirings
|
|
6
|
-
*/
|
|
7
3
|
export const addWorkflow = (workflowName, workflowFunc, packageName = null) => {
|
|
8
4
|
const meta = pikkuState(packageName, 'workflows', 'meta');
|
|
9
5
|
const workflowMeta = meta[workflowName];
|
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
import type { CoreFeature, CoreWorkflow, FeaturePlanEntry } from './workflow.types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Register a feature under the name it is exported as. Called from generated
|
|
4
|
-
* wiring, the same way `addWorkflow` is.
|
|
5
|
-
*/
|
|
6
2
|
export declare const addFeature: (featureId: string, feature: CoreFeature, packageName?: string | null) => void;
|
|
7
|
-
/**
|
|
8
|
-
* Resolve every feature's scenario references back to the names their
|
|
9
|
-
* scenarios are registered under.
|
|
10
|
-
*
|
|
11
|
-
* Matching is by **object identity**: `pikkuScenario` returns its config
|
|
12
|
-
* verbatim and `addWorkflow` registers that same object, so a feature holding
|
|
13
|
-
* the imported identifier holds the very object that was registered. Nothing
|
|
14
|
-
* is matched by shape, by name, or by any other guess — which is also why a
|
|
15
|
-
* scenario built inline inside a feature (and therefore never registered)
|
|
16
|
-
* comes back as unresolved rather than silently running as something else.
|
|
17
|
-
*
|
|
18
|
-
* Entries are returned in declaration order, features in registration order.
|
|
19
|
-
* A scenario's effective tags are its own plus the containing feature's, so
|
|
20
|
-
* `--tags credential` selects through the feature.
|
|
21
|
-
*/
|
|
22
3
|
export declare const resolveFeatureScenarios: (features: Map<string, CoreFeature>, registrations: Map<string, CoreWorkflow>) => {
|
|
23
4
|
entries: FeaturePlanEntry[];
|
|
24
5
|
unresolved: Array<{
|
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
import { pikkuState } from '../../pikku-state.js';
|
|
2
|
-
/**
|
|
3
|
-
* Register a feature under the name it is exported as. Called from generated
|
|
4
|
-
* wiring, the same way `addWorkflow` is.
|
|
5
|
-
*/
|
|
6
2
|
export const addFeature = (featureId, feature, packageName = null) => {
|
|
7
3
|
pikkuState(packageName, 'workflows', 'features').set(featureId, feature);
|
|
8
4
|
};
|
|
9
|
-
/**
|
|
10
|
-
* Resolve every feature's scenario references back to the names their
|
|
11
|
-
* scenarios are registered under.
|
|
12
|
-
*
|
|
13
|
-
* Matching is by **object identity**: `pikkuScenario` returns its config
|
|
14
|
-
* verbatim and `addWorkflow` registers that same object, so a feature holding
|
|
15
|
-
* the imported identifier holds the very object that was registered. Nothing
|
|
16
|
-
* is matched by shape, by name, or by any other guess — which is also why a
|
|
17
|
-
* scenario built inline inside a feature (and therefore never registered)
|
|
18
|
-
* comes back as unresolved rather than silently running as something else.
|
|
19
|
-
*
|
|
20
|
-
* Entries are returned in declaration order, features in registration order.
|
|
21
|
-
* A scenario's effective tags are its own plus the containing feature's, so
|
|
22
|
-
* `--tags credential` selects through the feature.
|
|
23
|
-
*/
|
|
24
5
|
export const resolveFeatureScenarios = (features, registrations) => {
|
|
25
6
|
const nameByConfig = new Map();
|
|
26
7
|
for (const [name, registration] of registrations) {
|