@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
package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: The AG-UI bridge obeys the client's event-ordering contract exactly
|
|
4
|
+
description: RUN_STARTED opens lazily, RUN_FINISHED fires once on done, and step names are globally sequential — a violation makes the client drop the whole stream
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# The AG-UI bridge obeys the client's event-ordering contract exactly
|
|
9
|
+
|
|
10
|
+
`wrapChannelWithAGUI` in `packages/core/src/wirings/ai-agent/ai-agent-agui.ts`
|
|
11
|
+
translates pikku stream events into AG-UI events under three rules that
|
|
12
|
+
`@ag-ui/client`'s `verifyEvents` enforces on the browser side:
|
|
13
|
+
|
|
14
|
+
`RUN_STARTED` is emitted lazily, from the first translated event, because the
|
|
15
|
+
client rejects anything that arrives before it — and because the real
|
|
16
|
+
`AIRunStateService` run id only exists after the channel has been wrapped, which
|
|
17
|
+
is why `AGUIChannelOptions.getRunId` and `StreamAIAgentOptions.onRunCreated`
|
|
18
|
+
exist as late-bound sources. `RUN_FINISHED` is terminal for the client, so it is
|
|
19
|
+
sent exactly once, on `done`, carrying usage accumulated across all steps; per-step
|
|
20
|
+
`usage` events must not finish the run, or a multi-step tool run would emit later
|
|
21
|
+
steps after the terminal event and the client would drop the whole stream.
|
|
22
|
+
Step names must be unique among active steps, and sub-agents reuse step numbers
|
|
23
|
+
on the shared channel, so each `step-start` closes the previous step and takes a
|
|
24
|
+
sequential name. `ai-agent-agui.test.ts` re-implements those ordering rules so
|
|
25
|
+
the bridge is checked against the same contract the browser applies.
|
|
26
|
+
|
|
27
|
+
**What this rules out:** emitting `RUN_STARTED` eagerly at wrap time; finishing
|
|
28
|
+
the run on the `usage` event so token counts arrive earlier; and naming AG-UI
|
|
29
|
+
steps after `event.stepNumber`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Audio chunks are labelled with the format the provider actually returned
|
|
4
|
+
description: The configured format is only a request, so the response's own format wins with the request and pcm16 as fallbacks
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Audio chunks are labelled with the format the provider actually returned
|
|
9
|
+
|
|
10
|
+
`synthesizeAudio` in `packages/core/src/wirings/ai-agent/voice-output.ts` labels
|
|
11
|
+
each `audio-delta` event with `result.audio.format` first, falling back to the
|
|
12
|
+
requested `config.format` and finally to `pcm16`.
|
|
13
|
+
|
|
14
|
+
Speech providers treat the output format as a preference: an unsupported or
|
|
15
|
+
omitted value silently yields whatever the provider defaults to. Stamping the
|
|
16
|
+
requested format on the chunk would tell the client to decode bytes it did not
|
|
17
|
+
receive, producing noise rather than an error.
|
|
18
|
+
|
|
19
|
+
**What this rules out:** labelling chunks from `config.format` because "we asked
|
|
20
|
+
for it", and dropping the fallback chain to a single source.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A credential-required tool result never reaches the client or the transcript
|
|
4
|
+
description: The run suspends with credential-request events instead, leaving the tool call unresulted so it can be resumed after connecting
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A credential-required tool result never reaches the client or the transcript
|
|
9
|
+
|
|
10
|
+
When a tool returns the `__credentialRequired` marker,
|
|
11
|
+
`streamAIAgent` in `packages/core/src/wirings/ai-agent/ai-agent-stream.ts`
|
|
12
|
+
filters that `tool-result` out of the channel before it can be streamed or
|
|
13
|
+
persisted, and `handleCredentialRequests` suspends the run and emits
|
|
14
|
+
`credential-request` events carrying the `runId` instead. Those events — not the
|
|
15
|
+
tool result — are what tells a client to show Connect/Ignore, mirroring how
|
|
16
|
+
approval suspensions work.
|
|
17
|
+
|
|
18
|
+
Leaving the tool call unresulted in the persisted history is what makes the
|
|
19
|
+
resume possible: once the credential is connected, `/resume` re-executes the call
|
|
20
|
+
against a history that does not already contain a bogus answer. `runStreamStepLoop`
|
|
21
|
+
still appends the step messages before returning the credential outcome, so the
|
|
22
|
+
assistant's tool call itself survives into the resume.
|
|
23
|
+
|
|
24
|
+
**What this rules out:** streaming the marker result as a normal tool result and
|
|
25
|
+
filtering it client-side; persisting it as the tool's answer; and skipping
|
|
26
|
+
`appendStepMessages` on the credential path because the run is about to suspend.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Delegate mode hides the parent's later text, supervise mode hides the sub-agent's
|
|
4
|
+
description: Exactly one voice reaches the client per agent-mode; approvals and tool events always flow through either way
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Delegate mode hides the parent's later text, supervise mode hides the sub-agent's
|
|
9
|
+
|
|
10
|
+
An agent with sub-agents runs in one of two modes. In `'delegate'` (the default,
|
|
11
|
+
handled in `streamAIAgent` in `ai-agent-stream.ts`) the parent's `text-delta` and
|
|
12
|
+
`reasoning-delta` events are suppressed *after* the first sub-agent call —
|
|
13
|
+
`delegateState.delegated` is the latch — so a parent that answers directly still
|
|
14
|
+
streams normally, while a parent that hands off does not narrate over its
|
|
15
|
+
sub-agent. In `'supervise'` (handled where the sub-agent channel is built in
|
|
16
|
+
`buildToolDefs` in `ai-agent-prepare.ts`) the inverse holds: the sub-agent's text
|
|
17
|
+
and reasoning are dropped and only the supervisor speaks.
|
|
18
|
+
|
|
19
|
+
Suppression is confined to text and reasoning. Approval requests, tool calls,
|
|
20
|
+
tool results, usage and errors flow through in both modes, because a suppressed
|
|
21
|
+
approval would deadlock the run.
|
|
22
|
+
|
|
23
|
+
**What this rules out:** filtering sub-agent events at the transport instead of
|
|
24
|
+
at the scoped channel; suppressing parent text unconditionally in delegate mode
|
|
25
|
+
(direct answers would vanish); and adding new event types to either filter
|
|
26
|
+
without checking they are not part of the approval handshake.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Nulls are stripped from approved tool arguments before execution
|
|
4
|
+
description: LLMs emit null for optional fields where the schema layer expects undefined, so a resumed tool call is cleaned recursively first
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Nulls are stripped from approved tool arguments before execution
|
|
9
|
+
|
|
10
|
+
`resumeAIAgentSync` in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/ai-agent-runner.ts` runs `stripNulls` over
|
|
12
|
+
the persisted arguments of an approved tool call before invoking the tool.
|
|
13
|
+
|
|
14
|
+
Models routinely fill every property in a JSON schema, using `null` to mean "not
|
|
15
|
+
provided". Pikku's validation layer models an absent optional field as
|
|
16
|
+
`undefined`, and a `null` fails the check outright. The value is stored as the
|
|
17
|
+
model produced it — the approval prompt should show what the model actually asked
|
|
18
|
+
for — so the cleanup happens at execution time, recursively, including inside
|
|
19
|
+
arrays and nested objects.
|
|
20
|
+
|
|
21
|
+
**What this rules out:** normalizing the arguments at approval-capture time
|
|
22
|
+
(the approval UI would no longer reflect the model's real request), and a
|
|
23
|
+
shallow single-level null strip.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Model resolution stays a single seam even though it is currently a passthrough
|
|
4
|
+
description: resolveModelConfig looks removable but is the one merge point for per-request model overrides
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Model resolution stays a single seam even though it is currently a passthrough
|
|
9
|
+
|
|
10
|
+
`resolveModelConfig` in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/ai-agent-model-config.ts` returns the
|
|
12
|
+
agent's `model`, `temperature` and `maxSteps` unchanged, and ignores its
|
|
13
|
+
`_agentName` argument. It reads as dead indirection and is not.
|
|
14
|
+
|
|
15
|
+
Models are declared per agent in the provider-qualified `provider/model` form
|
|
16
|
+
(`openai/gpt-5-mini`); there is no config-level alias map to consult, which is
|
|
17
|
+
why the current body is a copy. The function exists so that every caller —
|
|
18
|
+
`prepareAgentRun`, both resume paths, and the per-request `input.model` /
|
|
19
|
+
`input.temperature` overrides applied in `ai-agent-prepare.ts` — assembles the
|
|
20
|
+
effective config the same way, through one place that can grow an alias map,
|
|
21
|
+
per-tenant defaults or provider fallbacks without touching them.
|
|
22
|
+
|
|
23
|
+
**What this rules out:** inlining `agent.model` / `agent.temperature` at the four
|
|
24
|
+
call sites and deleting the function, and dropping the unused `_agentName`
|
|
25
|
+
parameter from the signature.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: An aiMiddleware onError hook cannot change how a run fails
|
|
4
|
+
description: Hook throws are swallowed so observability code can never convert, mask, or replace the original error
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# An aiMiddleware onError hook cannot change how a run fails
|
|
9
|
+
|
|
10
|
+
Every `onError` invocation on the agent failure paths — in `streamAIAgent` and
|
|
11
|
+
`continueAfterToolResult` (`ai-agent-stream.ts`) and in `runAIAgent` and
|
|
12
|
+
`continueAfterToolResultSync` (`ai-agent-runner.ts`) — is wrapped in its own
|
|
13
|
+
`try/catch` that discards whatever the hook throws. The run is then marked
|
|
14
|
+
`failed` with the original error message, and the original error propagates.
|
|
15
|
+
|
|
16
|
+
`onError` is an observability hook: logging, metrics, alerting. A logger that is
|
|
17
|
+
itself broken must not turn a diagnosable agent failure into a confusing one, and
|
|
18
|
+
must not stop the remaining hooks from running or the run state from being
|
|
19
|
+
updated.
|
|
20
|
+
|
|
21
|
+
**What this rules out:** awaiting the hooks without a guard, and using `onError`
|
|
22
|
+
as an error-transformation hook whose throw replaces the original failure.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: AI runner methods must be called on the runner, never as detached references
|
|
4
|
+
description: Implementations use this internally, so grabbing transcribe or generateSpeech as a bare function loses the receiver and throws at runtime
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# AI runner methods must be called on the runner, never as detached references
|
|
9
|
+
|
|
10
|
+
The voice middlewares in `voice-input.ts` and `voice-output.ts` invoke
|
|
11
|
+
`aiAgentRunner.transcribe(...)` and `aiAgentRunner.generateSpeech?.(...)` as
|
|
12
|
+
method calls on the service object, and only ever test them for presence.
|
|
13
|
+
|
|
14
|
+
`AIAgentRunnerService` is an interface implemented by classes — the reference
|
|
15
|
+
implementation's `transcribe` calls `this.getModel(...)`. Extracting the method
|
|
16
|
+
into a local (`const { transcribe } = services.aiAgentRunner`) type-checks
|
|
17
|
+
cleanly and then fails at runtime with `this` undefined. The regression is
|
|
18
|
+
pinned by a runner in `voice-input.test.ts` whose `transcribe` deliberately reads
|
|
19
|
+
instance state through `this`.
|
|
20
|
+
|
|
21
|
+
**What this rules out:** destructuring runner methods for brevity, and passing
|
|
22
|
+
`runner.transcribe` as a callback without binding it.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Persisting an agent stream from send is best-effort and must never reject
|
|
4
|
+
description: The persisting channel flushes fire-and-forget because send is synchronous; a storage failure degrades the transcript instead of killing the process
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Persisting an agent stream from send is best-effort and must never reject
|
|
9
|
+
|
|
10
|
+
`createPersistingChannel` in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/ai-agent-stream.ts` accumulates step text,
|
|
12
|
+
tool calls and tool results, and writes them via `flushDetached` on the `usage`
|
|
13
|
+
and `done` events. `AIStreamChannel.send` is synchronous, so it cannot await the
|
|
14
|
+
write. An unawaited rejection has nothing to propagate to and surfaces as an
|
|
15
|
+
`unhandledRejection`, which takes the whole server process down — a model
|
|
16
|
+
reusing a `toolCallId`, which is a primary key in AI storage, is enough to
|
|
17
|
+
trigger it. `flushDetached` therefore catches and logs, and the run carries on.
|
|
18
|
+
|
|
19
|
+
The awaited `flush()` on the suspend paths (`handleApprovals`,
|
|
20
|
+
`handleCredentialRequests`) is the seam that still surfaces persistence failures
|
|
21
|
+
to a caller. The regression test lives in `ai-agent-stream.test.ts`; because the
|
|
22
|
+
floating promise settles on a later macrotask, the assertion has to wait a real
|
|
23
|
+
timer before checking that no `unhandledRejection` fired.
|
|
24
|
+
|
|
25
|
+
**What this rules out:** letting `flushStep()` be called bare from `send`,
|
|
26
|
+
rethrowing from the catch to "not hide" storage errors, and asserting on
|
|
27
|
+
unhandled rejections synchronously after the last event.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A delegated sub-agent inherits the parent run's context block
|
|
4
|
+
description: The sub-agent tool schema carries only message and session, so the parent's identifier block is forwarded rather than re-typed by the model
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A delegated sub-agent inherits the parent run's context block
|
|
9
|
+
|
|
10
|
+
`buildSubAgentRunInput` in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/ai-agent-prepare.ts` forwards the parent
|
|
12
|
+
run's `AIAgentInput.context` — the "Current context" identifier block with
|
|
13
|
+
organization, project and stage ids — into every delegated sub-agent run, on
|
|
14
|
+
both the streaming and non-streaming paths. `buildToolDefs` threads it down as
|
|
15
|
+
`parentContext` for the same reason.
|
|
16
|
+
|
|
17
|
+
A sub-agent is exposed to the parent model as a tool whose input schema is only
|
|
18
|
+
`{ message, session }`. Without inheritance the sub-agent never sees the
|
|
19
|
+
authoritative ids and has to rely on the parent model re-typing them into
|
|
20
|
+
`message`. Weaker models mangle that, and the result is schema and permission
|
|
21
|
+
rejections followed by retry loops rather than a clean failure.
|
|
22
|
+
|
|
23
|
+
**What this rules out:** constructing the sub-agent run input inline from
|
|
24
|
+
`{ message, threadId, resourceId }`, widening the sub-agent tool schema so the
|
|
25
|
+
model supplies the ids itself, and dropping `parentContext` from `buildToolDefs`
|
|
26
|
+
because "nothing reads it here".
|
package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A tool's execute() failure is logged before the AI SDK swallows it
|
|
4
|
+
description: Every agent tool is wrapped in a logging try/catch, because a thrown tool error otherwise becomes a conversational reply and is invisible server-side
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A tool's execute() failure is logged before the AI SDK swallows it
|
|
9
|
+
|
|
10
|
+
`buildToolDefs` in `packages/core/src/wirings/ai-agent/ai-agent-prepare.ts`
|
|
11
|
+
wraps every tool it builds — RPC tools, sub-agent delegations and workflow tools
|
|
12
|
+
alike — in a `try/catch` that logs through `singletonServices.logger` and
|
|
13
|
+
rethrows.
|
|
14
|
+
|
|
15
|
+
A tool's `execute()` can throw for ordinary reasons: bad model-supplied input, an
|
|
16
|
+
RPC failure, a database error. The AI SDK catches that at the tool-call boundary
|
|
17
|
+
and turns it into a conversational "tool error" reply to the model. The exception
|
|
18
|
+
never reaches pikku's own logger, so without this wrapper a consistently failing
|
|
19
|
+
tool is undiagnosable from the server side — the only symptom is an agent that
|
|
20
|
+
keeps apologising. The wrapper is applied unconditionally, not only when an
|
|
21
|
+
`aiMiddleware` `afterToolCall` hook happens to be registered.
|
|
22
|
+
|
|
23
|
+
**What this rules out:** folding the logging into the optional middleware
|
|
24
|
+
wrapper below it, and relying on the AI SDK's own error reporting for tool
|
|
25
|
+
failures.
|
package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Voice input transcribes audio parts sequentially and in place
|
|
4
|
+
description: Each audio part is replaced by its text where it sat, one at a time, bounding concurrent downloads and preserving content order
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Voice input transcribes audio parts sequentially and in place
|
|
9
|
+
|
|
10
|
+
The `voiceInput` middleware in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/voice-input.ts` walks the last user
|
|
12
|
+
message's content parts in order and swaps each audio part for a text part at the
|
|
13
|
+
same index, awaiting one transcription before starting the next.
|
|
14
|
+
|
|
15
|
+
Order matters because the surrounding text parts are the user's own framing of
|
|
16
|
+
the audio; hoisting transcripts to the end would reorder the prompt. Sequencing
|
|
17
|
+
matters because a message can carry many attachments: a `Promise.all` would fan
|
|
18
|
+
out an unbounded number of concurrent multi-megabyte downloads and provider
|
|
19
|
+
transcription calls from a single request.
|
|
20
|
+
|
|
21
|
+
**What this rules out:** parallelizing the loop with `Promise.all`, and
|
|
22
|
+
collecting transcripts into a separate block appended to the message.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Working memory is persisted only when the merged value validates
|
|
4
|
+
description: A failed schema check logs and drops the update rather than saving it, because invalid state poisons every later read
|
|
5
|
+
tags: ai-agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Working memory is persisted only when the merged value validates
|
|
9
|
+
|
|
10
|
+
`createWorkingMemoryMiddleware` in
|
|
11
|
+
`packages/core/src/wirings/ai-agent/ai-agent-memory.ts` parses the model's
|
|
12
|
+
`<working_memory>` block, deep-merges it into the stored value, validates the
|
|
13
|
+
merge against the agent's working-memory schema when one is declared, and calls
|
|
14
|
+
`saveWorkingMemory` only if the merge is valid. An invalid merge is logged as a
|
|
15
|
+
warning and discarded.
|
|
16
|
+
|
|
17
|
+
Working memory is read back into the system prompt on every subsequent run of the
|
|
18
|
+
thread, so a bad write is not a one-turn mistake — it is a permanently malformed
|
|
19
|
+
prompt that the model then has to reason around, and which the model itself
|
|
20
|
+
cannot repair. Dropping the update is recoverable; the next turn simply tries
|
|
21
|
+
again.
|
|
22
|
+
|
|
23
|
+
**What this rules out:** saving first and validating on read, persisting the raw
|
|
24
|
+
model output before the merge, and treating a validation failure as fatal to the
|
|
25
|
+
run.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Channel message handlers accept three config shapes
|
|
4
|
+
description: onMessage may be a function config, a wrapper with middleware, or a wrapper around a function config — the runtime discriminates structurally
|
|
5
|
+
tags: channel
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Channel message handlers accept three config shapes
|
|
9
|
+
|
|
10
|
+
`processMessageHandlers` in
|
|
11
|
+
`packages/core/src/wirings/channel/channel-handler.ts` has to tell apart three
|
|
12
|
+
things a caller may put on `onMessage` or inside `onMessageWiring`:
|
|
13
|
+
|
|
14
|
+
- a direct function config, where `onMessage.func` is a plain `Function`;
|
|
15
|
+
- a wrapper, where `onMessage.func` is itself a `CorePikkuFunctionConfig` and so
|
|
16
|
+
has its own nested `.func`;
|
|
17
|
+
- a simple wrapper, which carries a plain `Function` under `func` *and* a
|
|
18
|
+
sibling `middleware` array.
|
|
19
|
+
|
|
20
|
+
The `isWrapper` check tests exactly that: an object with `func`, where either
|
|
21
|
+
`func` is an object that itself has `func`, or the object also has `middleware`.
|
|
22
|
+
Only a wrapper contributes message-level middleware; a direct config contributes
|
|
23
|
+
none. `wireChannel` in `channel-runner.ts` performs the mirror-image unwrapping
|
|
24
|
+
when registering the function, using `(handler as any).func instanceof Function`
|
|
25
|
+
to decide whether to register the handler or its inner `func`.
|
|
26
|
+
|
|
27
|
+
**What this rules out:** narrowing on a single property (`'middleware' in
|
|
28
|
+
onMessage` alone misclassifies a nested function config; `'func' in onMessage`
|
|
29
|
+
alone misclassifies a direct config), and reducing the accepted shapes without
|
|
30
|
+
updating both this discriminator and the registration path in `wireChannel`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Channel middleware caching covers only statically resolved middleware
|
|
4
|
+
description: Inherited tag/named middleware is cached per uid; per-run closures are appended fresh every call, at the cost of re-allocating the array
|
|
5
|
+
tags: channel
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Channel middleware caching covers only statically resolved middleware
|
|
9
|
+
|
|
10
|
+
`combineChannelMiddleware` in
|
|
11
|
+
`packages/core/src/wirings/channel/channel-middleware-runner.ts` caches only the
|
|
12
|
+
`wireInheritedChannelMiddleware` slice — the tag groups and named middleware
|
|
13
|
+
resolved out of `pikkuState` — under the key `${wireType}:${uid}`. That slice is
|
|
14
|
+
deterministic for a given `uid`. `wireChannelMiddleware` is not: it is a per-run
|
|
15
|
+
set of closures, such as an AI agent's per-invocation stream middleware holding
|
|
16
|
+
that run's thread and session state. Caching it would let a later run of the same
|
|
17
|
+
`uid` reuse an earlier run's closures, leaking that run's state into a different
|
|
18
|
+
user's stream and growing memory run over run. It is therefore appended fresh on
|
|
19
|
+
every call, after the cached inherited slice.
|
|
20
|
+
|
|
21
|
+
The `uid` matters as much as the cache split. `processMessageHandlers` in
|
|
22
|
+
`channel-handler.ts` builds it from the channel name *plus* the routing property
|
|
23
|
+
and router value (`${name}:${routingProperty}:${routerValue}`, or
|
|
24
|
+
`${name}:default`), because several message routes on one channel may point at
|
|
25
|
+
the same function — a key based on the function alone would serve one route's
|
|
26
|
+
middleware chain to another. Ordering within the combined chain is also fixed:
|
|
27
|
+
channel-level `middleware` runs before message-level `middleware`.
|
|
28
|
+
|
|
29
|
+
**What this rules out:** extending the cache key's value to include
|
|
30
|
+
`wireChannelMiddleware`, memoising the whole combined array, or simplifying the
|
|
31
|
+
cache key down to the channel or function name.
|
package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: Channel state is per-socket, session state is per-user
|
|
4
|
+
description: ChannelStore holds connection-scoped scratch data keyed by channelId, deliberately separate from the pikkuUserId-keyed SessionStore
|
|
5
|
+
tags: channel
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Channel state is per-socket, session state is per-user
|
|
9
|
+
|
|
10
|
+
`ChannelStore.setState` / `getState` / `clearState` in
|
|
11
|
+
`packages/core/src/wirings/channel/channel-store.ts` are keyed by `channelId` and
|
|
12
|
+
hold scratch data that belongs to one socket: a per-connection subscription
|
|
13
|
+
filter, the current step of a connection-bound state machine, the last command
|
|
14
|
+
this socket sent. The store clears it when the channel is removed. `SessionStore`
|
|
15
|
+
is keyed by `pikkuUserId` and holds the user session, which is shared across HTTP
|
|
16
|
+
and channel transports and outlives any one connection.
|
|
17
|
+
|
|
18
|
+
The two are separate stores because their lifetimes and their scopes differ. One
|
|
19
|
+
user may hold several sockets at once; writing socket-local data into the session
|
|
20
|
+
would let those sockets overwrite each other and would leak connection state into
|
|
21
|
+
HTTP requests. The serverless runner in `serverless/serverless-channel-runner.ts`
|
|
22
|
+
rebinds `channel.setState/getState/clearState` onto the `ChannelStore` on every
|
|
23
|
+
connect, message and disconnect precisely because there is no in-process channel
|
|
24
|
+
object to hang the state off between invocations.
|
|
25
|
+
|
|
26
|
+
**What this rules out:** backing `channel.setState` with the session store, or
|
|
27
|
+
merging the two stores behind one interface "since both are key-value". Also
|
|
28
|
+
rules out assuming channel state survives a reconnect — a new socket is a new
|
|
29
|
+
`channelId` and starts empty.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: A channel's user id is persisted only after onConnect middleware has run
|
|
4
|
+
description: The channelId to pikkuUserId mapping is written post-onConnect, because auth middleware is what establishes the session
|
|
5
|
+
tags: channel
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# A channel's user id is persisted only after onConnect middleware has run
|
|
9
|
+
|
|
10
|
+
`runChannelConnect` in
|
|
11
|
+
`packages/core/src/wirings/channel/serverless/serverless-channel-runner.ts`
|
|
12
|
+
reads `userSession.getPikkuUserId()` and calls `channelStore.setPikkuUserId`
|
|
13
|
+
*after* `runChannelLifecycleWithMiddleware` has executed the `onConnect`
|
|
14
|
+
lifecycle, not before.
|
|
15
|
+
|
|
16
|
+
Auth middleware runs as part of that lifecycle — it is what inspects the upgrade
|
|
17
|
+
request's cookie or token and calls `setSession`. Before it runs there is no
|
|
18
|
+
`pikkuUserId` to store, so an earlier write would persist `undefined` and the
|
|
19
|
+
channel would stay anonymous for its whole life. That mapping is what
|
|
20
|
+
`runChannelMessage` and `runChannelDisconnect` later use to rehydrate the session
|
|
21
|
+
from the `sessionStore` on each subsequent invocation, since serverless keeps
|
|
22
|
+
nothing in memory between them.
|
|
23
|
+
|
|
24
|
+
**What this rules out:** moving the `setPikkuUserId` call up next to
|
|
25
|
+
`channelStore.addChannel` to group the store writes together, and assuming a
|
|
26
|
+
session exists on the wire before `onConnect` has completed. It also means an
|
|
27
|
+
`onConnect` handler that throws leaves the channel with no user mapping — the
|
|
28
|
+
error path deliberately does not persist one.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: CLI option names are camelCase in state and kebab-case on the command line
|
|
4
|
+
description: Option keys match the function's input field names so they can be plucked by schema, and are converted to kebab only for display and parsing
|
|
5
|
+
tags: cli
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# CLI option names are camelCase in state and kebab-case on the command line
|
|
9
|
+
|
|
10
|
+
Every option key in `CLIOptions`, `CLICommandMeta.options` and the parsed
|
|
11
|
+
`ParsedCommand.options` is camelCase, because it must line up with a field name
|
|
12
|
+
on the command function's input type — that is what makes
|
|
13
|
+
`pluckCLIData` in `packages/core/src/wirings/cli/cli-runner.ts` able to select
|
|
14
|
+
fields by schema property name. Users type kebab-case.
|
|
15
|
+
|
|
16
|
+
`toCamelCase` and `toKebabCase` in
|
|
17
|
+
`packages/core/src/wirings/cli/command-parser.ts` are the only two points where
|
|
18
|
+
the conversion happens. The parser normalises every incoming `--from-plan` to
|
|
19
|
+
`fromPlan` on the way in, and both `formatOptions` (help text) and the
|
|
20
|
+
"Missing required option" / "Invalid value for" errors render back to kebab on
|
|
21
|
+
the way out. `suggestOption` deliberately compares the typed string against
|
|
22
|
+
*both* forms, so `--autoApply` and `--auto-apply` both find `autoApply`.
|
|
23
|
+
|
|
24
|
+
**What this rules out:** storing option keys kebab-cased anywhere in CLI state or
|
|
25
|
+
metadata — the schema pluck would then match nothing and every option would be
|
|
26
|
+
dropped. It also rules out emitting camelCase in help text or error messages,
|
|
27
|
+
which would tell users to type a flag spelling that works only by accident.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: CLI parse errors are routed by message prefix
|
|
4
|
+
description: The CLI runners decide between printing help and printing errors by string-matching the prefixes the parser writes, so those message strings are an interface
|
|
5
|
+
tags: cli
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# CLI parse errors are routed by message prefix
|
|
9
|
+
|
|
10
|
+
`parseCLIArguments` in `packages/core/src/wirings/cli/command-parser.ts` returns
|
|
11
|
+
a flat `string[]` of errors. It has no error codes and no error types. The
|
|
12
|
+
consumers — `executeCLI` in `cli-runner.ts` and `handleRawCLI` in
|
|
13
|
+
`channel/cli-raw-channel-runner.ts` — decide whether the user made a routing
|
|
14
|
+
mistake (show the help text) or a value mistake (print the errors) by
|
|
15
|
+
`error.startsWith(...)` against three literals: `'Unknown command:'`,
|
|
16
|
+
`'Command not found:'` and `'Missing subcommand:'`.
|
|
17
|
+
|
|
18
|
+
This is why the parser pushes `Missing subcommand: <path>` for a group command
|
|
19
|
+
that has subcommands but no `pikkuFuncId` of its own, rather than simply
|
|
20
|
+
returning the command meta and letting the runner discover it is unrunnable. The
|
|
21
|
+
message *is* the routing signal. Rewording any of those three strings, or
|
|
22
|
+
localising them, silently turns "show me the subcommands" into a raw error dump.
|
|
23
|
+
|
|
24
|
+
**What this rules out:** editing those error message prefixes without updating
|
|
25
|
+
every `startsWith` site, and adding a new "this is a routing problem" parse error
|
|
26
|
+
without registering its prefix in both runners. If this needs to grow, replace
|
|
27
|
+
the whole scheme with a discriminated error type in one change — do not add a
|
|
28
|
+
fourth magic prefix.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: CLI stdout is reserved for machine-readable output
|
|
4
|
+
description: The default renderer emits single-line NDJSON, diagnostics go to stderr, and --json only hijacks rendering for commands that declared a renderer
|
|
5
|
+
tags: cli
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# CLI stdout is reserved for machine-readable output
|
|
9
|
+
|
|
10
|
+
`defaultJSONRenderer` in `packages/core/src/wirings/cli/cli-runner.ts` (and its
|
|
11
|
+
twin in `channel/cli-channel-runner.ts`) calls `JSON.stringify` without an
|
|
12
|
+
indent argument. That is not laziness: one result per line is NDJSON, which stays
|
|
13
|
+
parseable when a command streams multiple results through the CLI channel.
|
|
14
|
+
Pretty-printing spreads one record over many lines and breaks every line-oriented
|
|
15
|
+
consumer downstream.
|
|
16
|
+
|
|
17
|
+
Two rules follow from the same principle in `executeCLI`. Parse warnings —
|
|
18
|
+
non-fatal by design, see the unknown-options decision — are written with
|
|
19
|
+
`console.error`, so they never interleave into a command's machine-readable
|
|
20
|
+
stdout. And `--json` / `--output json` only substitutes `defaultJSONRenderer`
|
|
21
|
+
when the command declared its own `render`; a command with no renderer is one
|
|
22
|
+
that prints inline as it works, and forcing its return value through the JSON
|
|
23
|
+
renderer would append a stray record after output that was never structured to
|
|
24
|
+
begin with. The `commandRenderer !== undefined` guard in the render block is what
|
|
25
|
+
enforces that.
|
|
26
|
+
|
|
27
|
+
Error formatting follows too: `isExpectedError(error)` prints `error.message`
|
|
28
|
+
alone with no `Error:` prefix, because an expected `PikkuError` (a build gate
|
|
29
|
+
tripping, a validation failure) has a message written to be read as the whole
|
|
30
|
+
output. Anything else is logged as an object so its stack survives.
|
|
31
|
+
|
|
32
|
+
**What this rules out:** adding an indent argument to `defaultJSONRenderer`,
|
|
33
|
+
routing warnings or progress messages to stdout, and dropping the
|
|
34
|
+
`commandRenderer !== undefined` condition so `--json` applies uniformly.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: CLI unknown long options warn instead of failing
|
|
4
|
+
description: Unrecognised --long options are accepted, warned about and dropped so older binaries tolerate newer invocations, while unknown short flags stay hard errors
|
|
5
|
+
tags: cli
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# CLI unknown long options warn instead of failing
|
|
9
|
+
|
|
10
|
+
`warnUnknownOption` in `packages/core/src/wirings/cli/command-parser.ts` pushes
|
|
11
|
+
onto `ParsedCommand.warnings`, not `ParsedCommand.errors`, so an unrecognised
|
|
12
|
+
`--long` option does not abort the command. The value is still parsed into
|
|
13
|
+
`optionArgs`, but `pluckCLIData` in `cli-runner.ts` drops anything absent from
|
|
14
|
+
the function's input schema — so the option is silently ignored at execution
|
|
15
|
+
time. The warning exists precisely so that dropping is not silent.
|
|
16
|
+
|
|
17
|
+
The reason is forward compatibility: a script or wrapper written against a newer
|
|
18
|
+
command version may pass options an older installed binary does not know, and
|
|
19
|
+
failing hard there turns a harmless extra flag into a broken pipeline.
|
|
20
|
+
`RESERVED_OPTIONS` exempts flags the runner handles itself (`help`) from the
|
|
21
|
+
warning. Unknown *short* flags are treated differently — they go to
|
|
22
|
+
`result.errors` and do fail — because a bundled short-flag cluster like `-abc`
|
|
23
|
+
cannot be reliably attributed, and a typo'd short flag is far more likely than a
|
|
24
|
+
version skew.
|
|
25
|
+
|
|
26
|
+
**What this rules out:** promoting unknown long options to errors "for
|
|
27
|
+
strictness", and removing the warning on the grounds that the schema pluck
|
|
28
|
+
already handles it — that restores the silent drop this was added to end. It also
|
|
29
|
+
rules out making unknown short flags non-fatal for symmetry.
|
package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: decision
|
|
3
|
+
title: The data-classification brand is an optional property
|
|
4
|
+
description: Making __classification__ required would break ordinary Kysely operands, so the brand only constrains values flowing out
|
|
5
|
+
tags: core
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# The data-classification brand is an optional property
|
|
9
|
+
|
|
10
|
+
`Private<T>`, `Pii<T>` and `Secret<T>` in
|
|
11
|
+
`packages/core/src/data-classification.ts` brand a type with
|
|
12
|
+
`{ readonly __classification__?: 'private' | 'pii' | 'secret' }` — and the
|
|
13
|
+
marker is **optional on purpose**.
|
|
14
|
+
|
|
15
|
+
A required property would make a plain value unassignable to a branded column: a
|
|
16
|
+
`string` could no longer be passed where `Private<string>` is expected, which
|
|
17
|
+
breaks every ordinary Kysely query operand — `where('email', '=', someString)`,
|
|
18
|
+
inserts, and `.set(...)`. Making it optional keeps the brand structurally present
|
|
19
|
+
so static analysis still sees it, while letting plain values flow *in*. The
|
|
20
|
+
asymmetry is the point: the brand constrains what comes out of a query, not what
|
|
21
|
+
goes into one.
|
|
22
|
+
|
|
23
|
+
The consumer is `@pikku/inspector`, whose `findPiiPaths` reads the level union
|
|
24
|
+
directly and whose PKU910 output check detects the brand on a function's return
|
|
25
|
+
type. The brands are populated from `-- @private` / `-- @secret` / `-- @public`
|
|
26
|
+
SQL comment annotations via `pikku db migrate`, which regenerates
|
|
27
|
+
`outDir/db/schema.d.ts` and `outDir/db/classification.gen.ts`.
|
|
28
|
+
|
|
29
|
+
**What this rules out:** making `__classification__` required to get stronger
|
|
30
|
+
guarantees, or replacing the optional property with a unique symbol / nominal
|
|
31
|
+
brand that behaves like a required one. Either change compiles here and then
|
|
32
|
+
breaks every generated Kysely call site in every downstream project. It also
|
|
33
|
+
rules out renaming the property or narrowing its literal union without updating
|
|
34
|
+
`findPiiPaths` in the inspector, which matches on both.
|