@pikku/core 0.12.143 → 0.12.145
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/dist/analytics/analytics.d.ts +14 -0
- package/dist/analytics/analytics.js +14 -0
- package/dist/analytics/analytics.types.d.ts +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
- package/dist/analytics/mint-cookie.d.ts +1 -0
- package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
- package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
- package/dist/classification/data-classification.d.ts +13 -0
- package/dist/classification/secret-value.d.ts +7 -0
- package/dist/classification/secret-value.js +7 -0
- package/dist/crypto-utils.d.ts +93 -0
- package/dist/crypto-utils.js +92 -0
- package/dist/dev/hot-reload.d.ts +16 -0
- package/dist/dev/hot-reload.js +16 -1
- package/dist/dev/module-runner.js +7 -3
- package/dist/dev/reload-meta.js +1 -1
- package/dist/errors/error-handler.d.ts +9 -0
- package/dist/errors/error-handler.js +8 -0
- package/dist/errors/errors.d.ts +219 -0
- package/dist/errors/errors.js +227 -0
- package/dist/errors/serialized-error.d.ts +4 -0
- package/dist/function/abort-scope.d.ts +5 -0
- package/dist/function/function-meta.types.d.ts +20 -0
- package/dist/function/function-runner.d.ts +41 -0
- package/dist/function/function-runner.js +57 -11
- package/dist/function/functions.types.d.ts +59 -0
- package/dist/function/functions.types.js +23 -0
- package/dist/function/list.types.d.ts +4 -0
- package/dist/lifecycle.d.ts +12 -1
- package/dist/lifecycle.js +12 -1
- package/dist/middleware/addon-scope-cap.d.ts +4 -0
- package/dist/middleware/addon-scope-cap.js +7 -3
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.js +5 -13
- package/dist/middleware/auth-cookie.js +3 -3
- package/dist/middleware/middleware-factories.d.ts +17 -0
- package/dist/middleware/middleware-factories.js +17 -0
- package/dist/middleware/middleware.types.d.ts +23 -0
- package/dist/middleware/remote-auth.d.ts +15 -0
- package/dist/middleware/remote-auth.js +18 -3
- package/dist/middleware/remote-jobs-secret.js +2 -10
- package/dist/middleware-runner.d.ts +7 -0
- package/dist/middleware-runner.js +23 -7
- package/dist/permissions.d.ts +13 -0
- package/dist/permissions.js +13 -0
- package/dist/pikku-state.d.ts +49 -0
- package/dist/pikku-state.js +49 -0
- package/dist/remote.js +20 -5
- package/dist/schema.d.ts +36 -0
- package/dist/schema.js +36 -0
- package/dist/services/agent-run-state-service.d.ts +8 -0
- package/dist/services/agent-runner-service.d.ts +24 -0
- package/dist/services/agent-storage-service.d.ts +8 -0
- package/dist/services/ai-embedding-service.d.ts +4 -0
- package/dist/services/audit-service.d.ts +48 -0
- package/dist/services/audit-service.js +22 -0
- package/dist/services/content-service.d.ts +34 -0
- package/dist/services/credential-wire-service.d.ts +9 -0
- package/dist/services/credential-wire-service.js +9 -0
- package/dist/services/deployment-service.d.ts +14 -0
- package/dist/services/email-service.d.ts +20 -0
- package/dist/services/email-template.d.ts +24 -0
- package/dist/services/email-template.js +12 -0
- package/dist/services/file-scenario-run-store.d.ts +5 -0
- package/dist/services/file-scenario-run-store.js +4 -0
- package/dist/services/gateway-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
- package/dist/services/in-memory-agent-run-state-service.js +5 -0
- package/dist/services/in-memory-lease-service.d.ts +5 -0
- package/dist/services/in-memory-lease-service.js +5 -0
- package/dist/services/in-memory-session-store.d.ts +4 -0
- package/dist/services/in-memory-session-store.js +4 -0
- package/dist/services/incoming-webhook-queue.d.ts +2 -0
- package/dist/services/incoming-webhook-queue.js +2 -0
- package/dist/services/incoming-webhook-service.d.ts +9 -1
- package/dist/services/incoming-webhook-service.js +1 -1
- package/dist/services/index.d.ts +1 -5
- package/dist/services/index.js +1 -5
- package/dist/services/jwt-service.d.ts +8 -0
- package/dist/services/lease-service.d.ts +5 -0
- package/dist/services/lease-service.js +1 -0
- package/dist/services/local-content-request-handler.d.ts +20 -0
- package/dist/services/local-content-request-handler.js +11 -0
- package/dist/services/local-content.d.ts +45 -0
- package/dist/services/local-content.js +35 -0
- package/dist/services/local-credential-service.d.ts +5 -0
- package/dist/services/local-credential-service.js +5 -0
- package/dist/services/local-email-service.d.ts +7 -0
- package/dist/services/local-email-service.js +7 -0
- package/dist/services/local-secrets.d.ts +8 -0
- package/dist/services/local-secrets.js +8 -0
- package/dist/services/local-variables.d.ts +6 -0
- package/dist/services/local-variables.js +6 -0
- package/dist/services/logger.d.ts +4 -0
- package/dist/services/logger.js +4 -0
- package/dist/services/meta-service.d.ts +38 -0
- package/dist/services/meta-service.js +6 -0
- package/dist/services/queue-webhook-service.d.ts +19 -0
- package/dist/services/queue-webhook-service.js +19 -0
- package/dist/services/remote-jobs.d.ts +8 -13
- package/dist/services/remote-jobs.js +3 -54
- package/dist/services/scenario-cookie-jar.d.ts +4 -0
- package/dist/services/scheduler-service.d.ts +13 -0
- package/dist/services/scheduler-service.js +8 -0
- package/dist/services/schema-service.d.ts +9 -0
- package/dist/services/scope-service.d.ts +10 -0
- package/dist/services/scoped-secret-service.d.ts +5 -0
- package/dist/services/scoped-secret-service.js +5 -0
- package/dist/services/secret-host-binding.d.ts +5 -0
- package/dist/services/secret-host-binding.js +5 -0
- package/dist/services/secret-service.d.ts +19 -1
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +6 -0
- package/dist/services/session-store.d.ts +5 -0
- package/dist/services/stub-tracker.d.ts +1 -0
- package/dist/services/temporary-file-service.d.ts +9 -0
- package/dist/services/temporary-file-service.js +9 -0
- package/dist/services/trigger-service.d.ts +4 -0
- package/dist/services/trigger-source-store.d.ts +13 -0
- package/dist/services/trigger-source-store.js +7 -0
- package/dist/services/typed-credential-service.d.ts +6 -0
- package/dist/services/typed-credential-service.js +5 -0
- package/dist/services/typed-secret-service.d.ts +12 -0
- package/dist/services/typed-secret-service.js +11 -0
- package/dist/services/typed-variables-service.d.ts +1 -0
- package/dist/services/user-session-service.d.ts +31 -1
- package/dist/services/user-session-service.js +29 -3
- package/dist/services/v8-coverage-service.d.ts +27 -0
- package/dist/services/v8-coverage-service.js +5 -0
- package/dist/services/variables-service.d.ts +8 -0
- package/dist/services/virtual-user-sign-in.d.ts +1 -0
- package/dist/services/virtual-user-statement.d.ts +8 -0
- package/dist/services/virtual-user-statement.js +4 -0
- package/dist/services/webhook-service.d.ts +25 -0
- package/dist/services/webhook-service.js +15 -0
- package/dist/services/workflow-service.d.ts +6 -0
- package/dist/test-utils.js +1 -1
- package/dist/testing/service-tests.d.ts +4 -0
- package/dist/time-utils.d.ts +15 -0
- package/dist/time-utils.js +14 -0
- package/dist/types/core.types.d.ts +80 -0
- package/dist/types/state.types.d.ts +4 -0
- package/dist/utils/hmac.d.ts +3 -0
- package/dist/utils/safe-fetch.d.ts +14 -0
- package/dist/utils/safe-fetch.js +13 -0
- package/dist/utils/stable-stringify.d.ts +11 -0
- package/dist/utils/stable-stringify.js +33 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +22 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +7 -0
- package/dist/wirings/addon/define-screens.d.ts +2 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
- package/dist/wirings/addon/remote-addon-auth.js +5 -0
- package/dist/wirings/addon/wire-addon.d.ts +4 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
- package/dist/wirings/agent/agent-agui.d.ts +14 -5
- package/dist/wirings/agent/agent-agui.js +17 -6
- package/dist/wirings/agent/agent-helpers.d.ts +61 -1
- package/dist/wirings/agent/agent-helpers.js +62 -2
- package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
- package/dist/wirings/agent/agent-output.d.ts +20 -0
- package/dist/wirings/agent/agent-output.js +69 -0
- package/dist/wirings/agent/agent-prepare.d.ts +41 -0
- package/dist/wirings/agent/agent-prepare.js +38 -2
- package/dist/wirings/agent/agent-registry.d.ts +8 -0
- package/dist/wirings/agent/agent-registry.js +10 -4
- package/dist/wirings/agent/agent-runner.d.ts +33 -0
- package/dist/wirings/agent/agent-runner.js +40 -7
- package/dist/wirings/agent/agent-stream.d.ts +30 -0
- package/dist/wirings/agent/agent-stream.js +33 -11
- package/dist/wirings/agent/agent.types.d.ts +43 -0
- package/dist/wirings/agent/voice-input.d.ts +12 -0
- package/dist/wirings/agent/voice-input.js +12 -0
- package/dist/wirings/agent/voice-output.d.ts +14 -0
- package/dist/wirings/agent/voice-output.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
- package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
- package/dist/wirings/channel/channel-common.js +1 -1
- package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
- package/dist/wirings/channel/channel-runner.d.ts +22 -0
- package/dist/wirings/channel/channel-runner.js +22 -0
- package/dist/wirings/channel/channel-store.d.ts +8 -0
- package/dist/wirings/channel/channel-store.js +7 -0
- package/dist/wirings/channel/channel.types.d.ts +18 -0
- package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
- package/dist/wirings/channel/define-channel-routes.js +5 -0
- package/dist/wirings/channel/eventhub-service.d.ts +9 -0
- package/dist/wirings/channel/eventhub-store.d.ts +1 -0
- package/dist/wirings/channel/eventhub-store.js +1 -0
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/index.js +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
- package/dist/wirings/channel/local/local-channel-handler.js +1 -0
- package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
- package/dist/wirings/channel/local/local-channel-runner.js +13 -0
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
- package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
- package/dist/wirings/channel/log-channels.d.ts +1 -0
- package/dist/wirings/channel/log-channels.js +1 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
- package/dist/wirings/cli/cli-runner.d.ts +43 -0
- package/dist/wirings/cli/cli-runner.js +43 -0
- package/dist/wirings/cli/cli.types.d.ts +4 -0
- package/dist/wirings/cli/command-parser.d.ts +13 -0
- package/dist/wirings/cli/command-parser.js +16 -0
- package/dist/wirings/credential/credential-overrides.d.ts +1 -0
- package/dist/wirings/credential/credential.types.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
- package/dist/wirings/credential/validate-credential-definitions.js +7 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
- package/dist/wirings/flag/flag.types.d.ts +3 -0
- package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
- package/dist/wirings/gateway/gateway-runner.js +23 -0
- package/dist/wirings/gateway/gateway.types.d.ts +3 -0
- package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
- package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
- package/dist/wirings/http/http-routes.d.ts +21 -0
- package/dist/wirings/http/http-routes.js +11 -0
- package/dist/wirings/http/http-runner.d.ts +71 -0
- package/dist/wirings/http/http-runner.js +73 -5
- package/dist/wirings/http/http.types.d.ts +27 -0
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/log-http-routes.d.ts +1 -0
- package/dist/wirings/http/log-http-routes.js +1 -0
- package/dist/wirings/http/merge-request-data.d.ts +12 -0
- package/dist/wirings/http/merge-request-data.js +42 -0
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
- package/dist/wirings/http/routers/http-router.d.ts +6 -0
- package/dist/wirings/http/routers/http-router.js +6 -0
- package/dist/wirings/http/web-request.d.ts +17 -0
- package/dist/wirings/http/web-request.js +17 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
- package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
- package/dist/wirings/mcp/mcp-runner.js +62 -0
- package/dist/wirings/mcp/mcp.types.d.ts +12 -0
- package/dist/wirings/node/node.types.d.ts +4 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
- package/dist/{services → wirings/queue}/in-memory-queue-service.d.ts +9 -1
- package/dist/{services → wirings/queue}/in-memory-queue-service.js +9 -1
- package/dist/wirings/queue/index.d.ts +1 -0
- package/dist/wirings/queue/index.js +1 -0
- package/dist/wirings/queue/queue-identity.js +2 -14
- package/dist/wirings/queue/queue-runner.d.ts +37 -0
- package/dist/wirings/queue/queue-runner.js +37 -0
- package/dist/wirings/queue/queue.types.d.ts +35 -0
- package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
- package/dist/wirings/queue/register-queue-helper.js +11 -0
- package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
- package/dist/wirings/queue/remote-queue-job.js +41 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
- package/dist/wirings/role/role.types.d.ts +3 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
- package/dist/wirings/rpc/rpc-runner.js +37 -2
- package/dist/wirings/rpc/rpc-types.d.ts +2 -0
- package/dist/wirings/scheduler/index.d.ts +1 -0
- package/dist/wirings/scheduler/index.js +1 -0
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
- package/dist/wirings/scheduler/log-schedulers.js +1 -0
- package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
- package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
- package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
- package/dist/wirings/scheduler/scheduler-runner.js +28 -0
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -0
- package/dist/wirings/scope/scope.types.d.ts +5 -0
- package/dist/wirings/secret/index.d.ts +2 -2
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +26 -1
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
- package/dist/wirings/secret/validate-secret-definitions.js +15 -0
- package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
- package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
- package/dist/wirings/trigger/index.d.ts +1 -1
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
- package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
- package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
- package/dist/wirings/trigger/trigger-runner.js +35 -2
- package/dist/wirings/trigger/trigger.types.d.ts +26 -4
- package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
- package/dist/wirings/trigger/webhook-source-runner.js +19 -0
- package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
- package/dist/wirings/trigger/webhook-source.types.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
- package/dist/wirings/variable/validate-variable-definitions.js +7 -0
- package/dist/wirings/variable/variable.types.d.ts +7 -0
- package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
- package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
- package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
- package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
- package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
- package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
- package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
- package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
- package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
- package/dist/wirings/workflow/feature.d.ts +12 -0
- package/dist/wirings/workflow/feature.js +12 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
- package/dist/wirings/workflow/graph/graph-node.js +5 -0
- package/dist/wirings/workflow/graph/template.d.ts +6 -0
- package/dist/wirings/workflow/graph/template.js +5 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
- package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
- package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
- package/dist/wirings/workflow/run-timeline.d.ts +21 -0
- package/dist/wirings/workflow/run-timeline.js +15 -7
- package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
- package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
- package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
- package/dist/wirings/workflow/scenario-prose.js +6 -0
- package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
- package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
- package/dist/wirings/workflow/scenario-step.types.js +1 -0
- package/dist/wirings/workflow/scenario-surface.js +1 -13
- package/dist/wirings/workflow/scenario.types.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
- package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
- package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
- package/dist/wirings/workflow/workflow-constants.js +10 -1
- package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
- package/dist/wirings/workflow/workflow-errors.js +13 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
- package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
- package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
- package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
- package/dist/wirings/workflow/workflow.types.d.ts +40 -0
- package/package.json +26 -9
- package/CHANGELOG.md +0 -6978
- package/dist/services/in-memory-trigger-service.d.ts +0 -4
- package/dist/services/local-gateway-service.d.ts +0 -6
- package/dist/utils/hash.d.ts +0 -2
- package/dist/utils/hash.js +0 -23
- package/knowledge/decisions/index.md +0 -19
- package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
- package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
- package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
- package/knowledge/decisions/internals/a-latency-budget-is-asserted-by-its-cause.md +0 -32
- package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
- package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
- package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
- package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
- package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
- package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
- package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
- package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
- package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -49
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
- package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
- package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
- package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
- package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
- package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
- package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
- package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
- package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
- package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
- package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
- package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
- package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
- package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
- package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
- package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
- package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
- package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
- package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
- package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
- package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
- package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
- package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
- package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
- package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
- package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
- package/knowledge/decisions/internals/index.md +0 -182
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
- package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
- package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
- package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
- package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
- package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
- package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
- package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
- package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
- package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
- package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
- package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
- package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
- package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
- package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
- package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
- package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
- package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
- package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
- package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
- package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
- package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
- package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
- package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
- package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
- package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
- package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
- package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
- package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
- package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
- package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
- package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
- package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
- package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
- package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
- package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
- package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
- package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
- package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
- package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
- package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
- package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
- package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
- package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
- package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
- package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
- package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
- package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
- package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
- package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
- package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
- package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
- package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
- package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
- package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
- package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
- package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
- package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
- package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
- package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
- package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
- package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
- package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
- package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
- package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
- package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
- package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
- package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
- package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
- package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
- package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
- package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
- package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
- package/knowledge/decisions/security/index.md +0 -135
- package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
- package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
- package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
- package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
- package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
- package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
- package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
- package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
- package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
- package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
- package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
- package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
- package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
- package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
- package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
- package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
- package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
- package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
- package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
- package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
- package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
- package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
- package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
- package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
- package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
- package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
- package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
- package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
- package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
- package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
- package/knowledge/index.md +0 -24
- package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
- package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
- package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
- package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
- package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
- package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
- package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
- package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
- package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
- package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
- package/knowledge/questions/index.md +0 -41
- package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
- package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
- package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
- package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
- package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
- package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
- package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
- package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
- package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
- package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
- package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
- package/knowledge/questions/staging-impersonation-rules.md +0 -27
- package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
- package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -33
- package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
- package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
- package/run-tests.sh +0 -68
- package/scripts/generate-api-report.d.mts +0 -1
- package/scripts/generate-api-report.mjs +0 -96
- package/scripts/generate-api-report.mts +0 -333
- package/src/public-surface.json +0 -637
- package/src/public-surface.json.README +0 -43
- /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
- /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
|
@@ -1,14 +1,49 @@
|
|
|
1
1
|
import type { AgentInterruptResult } from './agent-interrupt.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a function config that runs `agentName` to completion through `rpc.agent.run` and
|
|
4
|
+
* returns its result, for wiring an agent as an ordinary (non-streaming) endpoint.
|
|
5
|
+
*
|
|
6
|
+
* The agent's own `auth`, `scopes` and `permissions` are checked on every call, and the thread
|
|
7
|
+
* is partitioned under the caller's session principal, so a client-supplied `resourceId` can never
|
|
8
|
+
* reach another user's thread. A run that hits a tool needing approval returns `status: 'suspended'`
|
|
9
|
+
* with its `pendingApprovals`.
|
|
10
|
+
*
|
|
11
|
+
* @param agentName - The agent to run.
|
|
12
|
+
* @returns A `{ func }` to pass to `wireHTTP`, `wireChannel` or similar.
|
|
13
|
+
* @example snippet: aiAgentInvoke
|
|
14
|
+
*/
|
|
2
15
|
export declare function agent<TAgentMap extends Record<string, {
|
|
3
16
|
output: any;
|
|
4
17
|
}>>(agentName: string & keyof TAgentMap): {
|
|
5
18
|
func: (services: any, data: any, wire: any) => Promise<any>;
|
|
6
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Builds a function config that streams an agent run to the wire's channel as AG-UI events,
|
|
22
|
+
* through `rpc.agent.stream`. Requires a wiring that provides a channel (an SSE route or a
|
|
23
|
+
* WebSocket); authorization and thread partitioning are as for `agent`.
|
|
24
|
+
*
|
|
25
|
+
* @param agentName - The agent to stream. When omitted, it is read from `agentName` on the input,
|
|
26
|
+
* so one route can serve several agents; every agent stays subject to its own auth checks.
|
|
27
|
+
* @returns A `{ func }` to pass to a streaming wiring.
|
|
28
|
+
* @throws Error when no agent name is given either way, or the wire has no channel.
|
|
29
|
+
* @example snippet: aiAgentStream
|
|
30
|
+
*/
|
|
7
31
|
export declare function agentStream<TAgentMap extends Record<string, {
|
|
8
32
|
output: any;
|
|
9
33
|
}>>(agentName?: string & keyof TAgentMap): {
|
|
10
34
|
func: (services: any, data: any, wire: any) => Promise<void>;
|
|
11
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Builds a function config that answers one pending tool approval on a suspended run and streams
|
|
38
|
+
* the continuation, through `rpc.agent.resume`.
|
|
39
|
+
*
|
|
40
|
+
* Only the run's owner (the session principal it was created under) may resume it, and the agent's
|
|
41
|
+
* auth checks run again, so a revoked grant blocks the resume. Concurrent resumes of the same tool
|
|
42
|
+
* call are claimed atomically; the loser fails rather than running the tool twice.
|
|
43
|
+
*
|
|
44
|
+
* @returns A `{ func }` taking `{ runId, toolCallId, approved }`, for a streaming wiring.
|
|
45
|
+
* @example snippet: agentApproval
|
|
46
|
+
*/
|
|
12
47
|
export declare function agentResume(): {
|
|
13
48
|
func: (services: any, data: {
|
|
14
49
|
runId: string;
|
|
@@ -16,15 +51,40 @@ export declare function agentResume(): {
|
|
|
16
51
|
approved: boolean;
|
|
17
52
|
}, wire: any) => Promise<void>;
|
|
18
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Builds a function config that stops a running agent (barge-in, a stop button, a timeout),
|
|
56
|
+
* through `rpc.agent.interrupt`.
|
|
57
|
+
*
|
|
58
|
+
* Only the run's owner may interrupt it; the agent's auth checks are deliberately not re-run, so a
|
|
59
|
+
* user can always stop their own run. Tools already executing keep running and are reported in the
|
|
60
|
+
* result rather than rolled back.
|
|
61
|
+
*
|
|
62
|
+
* @returns A `{ func }` taking `{ runId, reason? }` and returning whether the run was stopped and
|
|
63
|
+
* which tools were still in flight.
|
|
64
|
+
*/
|
|
19
65
|
export declare function agentInterrupt(): {
|
|
20
66
|
func: (services: any, data: {
|
|
21
67
|
runId: string;
|
|
22
68
|
reason?: 'speech' | 'user' | 'timeout';
|
|
23
69
|
}, wire: any) => Promise<AgentInterruptResult>;
|
|
24
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Builds a function config that answers a batch of pending tool approvals and runs the suspended
|
|
73
|
+
* agent to completion without streaming, through `rpc.agent.approve`.
|
|
74
|
+
*
|
|
75
|
+
* Ownership, re-authorization and the once-only claim behave as for `agentResume`. The route is
|
|
76
|
+
* scoped to `agentName`: a run that belongs to any other agent is refused with a `ForbiddenError`
|
|
77
|
+
* (403), even when the caller owns it.
|
|
78
|
+
*
|
|
79
|
+
* @param agentName - The agent this route answers approvals for; also types the result.
|
|
80
|
+
* @returns A `{ func }` taking `{ runId, approvals }`.
|
|
81
|
+
* @throws ForbiddenError when the run belongs to a different agent.
|
|
82
|
+
* @throws Error when every approval in the batch was already resolved by another caller.
|
|
83
|
+
* @example snippet: agentApproval
|
|
84
|
+
*/
|
|
25
85
|
export declare function agentApprove<TAgentMap extends Record<string, {
|
|
26
86
|
output: any;
|
|
27
|
-
}>>(
|
|
87
|
+
}>>(agentName: string & keyof TAgentMap): {
|
|
28
88
|
func: (services: any, data: {
|
|
29
89
|
runId: string;
|
|
30
90
|
approvals: {
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a function config that runs `agentName` to completion through `rpc.agent.run` and
|
|
3
|
+
* returns its result, for wiring an agent as an ordinary (non-streaming) endpoint.
|
|
4
|
+
*
|
|
5
|
+
* The agent's own `auth`, `scopes` and `permissions` are checked on every call, and the thread
|
|
6
|
+
* is partitioned under the caller's session principal, so a client-supplied `resourceId` can never
|
|
7
|
+
* reach another user's thread. A run that hits a tool needing approval returns `status: 'suspended'`
|
|
8
|
+
* with its `pendingApprovals`.
|
|
9
|
+
*
|
|
10
|
+
* @param agentName - The agent to run.
|
|
11
|
+
* @returns A `{ func }` to pass to `wireHTTP`, `wireChannel` or similar.
|
|
12
|
+
* @example snippet: aiAgentInvoke
|
|
13
|
+
*/
|
|
1
14
|
export function agent(agentName) {
|
|
2
15
|
return {
|
|
3
16
|
func: async (_services, data, { rpc }) => {
|
|
@@ -5,6 +18,17 @@ export function agent(agentName) {
|
|
|
5
18
|
},
|
|
6
19
|
};
|
|
7
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds a function config that streams an agent run to the wire's channel as AG-UI events,
|
|
23
|
+
* through `rpc.agent.stream`. Requires a wiring that provides a channel (an SSE route or a
|
|
24
|
+
* WebSocket); authorization and thread partitioning are as for `agent`.
|
|
25
|
+
*
|
|
26
|
+
* @param agentName - The agent to stream. When omitted, it is read from `agentName` on the input,
|
|
27
|
+
* so one route can serve several agents; every agent stays subject to its own auth checks.
|
|
28
|
+
* @returns A `{ func }` to pass to a streaming wiring.
|
|
29
|
+
* @throws Error when no agent name is given either way, or the wire has no channel.
|
|
30
|
+
* @example snippet: aiAgentStream
|
|
31
|
+
*/
|
|
8
32
|
export function agentStream(agentName) {
|
|
9
33
|
return {
|
|
10
34
|
func: async (_services, data, { rpc }) => {
|
|
@@ -21,6 +45,17 @@ export function agentStream(agentName) {
|
|
|
21
45
|
},
|
|
22
46
|
};
|
|
23
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Builds a function config that answers one pending tool approval on a suspended run and streams
|
|
50
|
+
* the continuation, through `rpc.agent.resume`.
|
|
51
|
+
*
|
|
52
|
+
* Only the run's owner (the session principal it was created under) may resume it, and the agent's
|
|
53
|
+
* auth checks run again, so a revoked grant blocks the resume. Concurrent resumes of the same tool
|
|
54
|
+
* call are claimed atomically; the loser fails rather than running the tool twice.
|
|
55
|
+
*
|
|
56
|
+
* @returns A `{ func }` taking `{ runId, toolCallId, approved }`, for a streaming wiring.
|
|
57
|
+
* @example snippet: agentApproval
|
|
58
|
+
*/
|
|
24
59
|
export function agentResume() {
|
|
25
60
|
return {
|
|
26
61
|
func: async (_services, data, { rpc }) => {
|
|
@@ -31,6 +66,17 @@ export function agentResume() {
|
|
|
31
66
|
},
|
|
32
67
|
};
|
|
33
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Builds a function config that stops a running agent (barge-in, a stop button, a timeout),
|
|
71
|
+
* through `rpc.agent.interrupt`.
|
|
72
|
+
*
|
|
73
|
+
* Only the run's owner may interrupt it; the agent's auth checks are deliberately not re-run, so a
|
|
74
|
+
* user can always stop their own run. Tools already executing keep running and are reported in the
|
|
75
|
+
* result rather than rolled back.
|
|
76
|
+
*
|
|
77
|
+
* @returns A `{ func }` taking `{ runId, reason? }` and returning whether the run was stopped and
|
|
78
|
+
* which tools were still in flight.
|
|
79
|
+
*/
|
|
34
80
|
export function agentInterrupt() {
|
|
35
81
|
return {
|
|
36
82
|
func: async (_services, data, { rpc }) => {
|
|
@@ -38,10 +84,24 @@ export function agentInterrupt() {
|
|
|
38
84
|
},
|
|
39
85
|
};
|
|
40
86
|
}
|
|
41
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Builds a function config that answers a batch of pending tool approvals and runs the suspended
|
|
89
|
+
* agent to completion without streaming, through `rpc.agent.approve`.
|
|
90
|
+
*
|
|
91
|
+
* Ownership, re-authorization and the once-only claim behave as for `agentResume`. The route is
|
|
92
|
+
* scoped to `agentName`: a run that belongs to any other agent is refused with a `ForbiddenError`
|
|
93
|
+
* (403), even when the caller owns it.
|
|
94
|
+
*
|
|
95
|
+
* @param agentName - The agent this route answers approvals for; also types the result.
|
|
96
|
+
* @returns A `{ func }` taking `{ runId, approvals }`.
|
|
97
|
+
* @throws ForbiddenError when the run belongs to a different agent.
|
|
98
|
+
* @throws Error when every approval in the batch was already resolved by another caller.
|
|
99
|
+
* @example snippet: agentApproval
|
|
100
|
+
*/
|
|
101
|
+
export function agentApprove(agentName) {
|
|
42
102
|
return {
|
|
43
103
|
func: async (_services, data, { rpc }) => {
|
|
44
|
-
return rpc.agent.approve(data.runId, data.approvals);
|
|
104
|
+
return rpc.agent.approve(data.runId, data.approvals, agentName);
|
|
45
105
|
},
|
|
46
106
|
};
|
|
47
107
|
}
|
|
@@ -60,6 +60,11 @@ export interface AgentInterruptResult {
|
|
|
60
60
|
*/
|
|
61
61
|
inFlightTools: string[];
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* A live run's interrupt handle: the abort signal the model call listens to, plus tracking for
|
|
65
|
+
* tools still executing when an interrupt lands.
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
63
68
|
export interface InterruptibleRunHandle {
|
|
64
69
|
readonly signal: AbortSignal;
|
|
65
70
|
/** Set at the moment the run is interrupted; `undefined` on a clean run. */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes the `null`s a provider sends for optional fields.
|
|
3
|
+
*
|
|
4
|
+
* Strict structured-output modes (OpenAI's among them) require every property,
|
|
5
|
+
* so a runner widens each optional one to nullable and the model answers
|
|
6
|
+
* `null` for "absent". Validating that against the schema the agent declared —
|
|
7
|
+
* where the field is optional, not nullable — would reject a valid answer, so
|
|
8
|
+
* a `null` is dropped wherever the original schema neither requires the field
|
|
9
|
+
* nor allows `null` for it. Anything else is left for validation to judge.
|
|
10
|
+
*/
|
|
11
|
+
export declare const dropNullOptionals: (schema: unknown, value: unknown) => unknown;
|
|
12
|
+
/**
|
|
13
|
+
* Checks a `pikkuAgent`'s structured output against the output schema it was
|
|
14
|
+
* declared with, which codegen compiled to JSON Schema under `schemaName`.
|
|
15
|
+
*
|
|
16
|
+
* Returns the object with provider `null`s for optional fields removed; throws
|
|
17
|
+
* `AgentOutputValidationError` when it does not match. No object — the run
|
|
18
|
+
* ended on text — is returned as is.
|
|
19
|
+
*/
|
|
20
|
+
export declare const validateAgentOutput: (agentName: string, schemaName: string | null | undefined, object: unknown, packageName?: string | null) => Promise<unknown>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { AgentOutputValidationError, UnprocessableContentError, } from '../../errors/errors.js';
|
|
2
|
+
import { getSingletonServices, pikkuState } from '../../pikku-state.js';
|
|
3
|
+
import { validateSchema } from '../../schema.js';
|
|
4
|
+
const allowsNull = (schema) => {
|
|
5
|
+
if (!schema)
|
|
6
|
+
return true;
|
|
7
|
+
if (schema.type === 'null')
|
|
8
|
+
return true;
|
|
9
|
+
if (Array.isArray(schema.type) && schema.type.includes('null'))
|
|
10
|
+
return true;
|
|
11
|
+
return [...(schema.anyOf ?? []), ...(schema.oneOf ?? [])].some(allowsNull);
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Removes the `null`s a provider sends for optional fields.
|
|
15
|
+
*
|
|
16
|
+
* Strict structured-output modes (OpenAI's among them) require every property,
|
|
17
|
+
* so a runner widens each optional one to nullable and the model answers
|
|
18
|
+
* `null` for "absent". Validating that against the schema the agent declared —
|
|
19
|
+
* where the field is optional, not nullable — would reject a valid answer, so
|
|
20
|
+
* a `null` is dropped wherever the original schema neither requires the field
|
|
21
|
+
* nor allows `null` for it. Anything else is left for validation to judge.
|
|
22
|
+
*/
|
|
23
|
+
export const dropNullOptionals = (schema, value) => {
|
|
24
|
+
const node = schema;
|
|
25
|
+
if (!node || typeof node !== 'object' || value === null)
|
|
26
|
+
return value;
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
return node.items
|
|
29
|
+
? value.map((item) => dropNullOptionals(node.items, item))
|
|
30
|
+
: value;
|
|
31
|
+
}
|
|
32
|
+
if (typeof value !== 'object' || !node.properties)
|
|
33
|
+
return value;
|
|
34
|
+
const required = new Set(node.required ?? []);
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const [key, field] of Object.entries(value)) {
|
|
37
|
+
const fieldSchema = node.properties[key];
|
|
38
|
+
if (field === null && !required.has(key) && !allowsNull(fieldSchema)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
result[key] = dropNullOptionals(fieldSchema, field);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
// knowledge: decisions/internals/agent-structured-output-is-validated-against-the-declared-schema.md
|
|
46
|
+
/**
|
|
47
|
+
* Checks a `pikkuAgent`'s structured output against the output schema it was
|
|
48
|
+
* declared with, which codegen compiled to JSON Schema under `schemaName`.
|
|
49
|
+
*
|
|
50
|
+
* Returns the object with provider `null`s for optional fields removed; throws
|
|
51
|
+
* `AgentOutputValidationError` when it does not match. No object — the run
|
|
52
|
+
* ended on text — is returned as is.
|
|
53
|
+
*/
|
|
54
|
+
export const validateAgentOutput = async (agentName, schemaName, object, packageName = null) => {
|
|
55
|
+
if (!schemaName || object === undefined)
|
|
56
|
+
return object;
|
|
57
|
+
const normalized = dropNullOptionals(pikkuState(packageName, 'misc', 'schemas').get(schemaName), object);
|
|
58
|
+
const { logger, schema } = getSingletonServices();
|
|
59
|
+
try {
|
|
60
|
+
await validateSchema(logger, schema, schemaName, normalized, packageName);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (error instanceof UnprocessableContentError) {
|
|
64
|
+
throw new AgentOutputValidationError(agentName, [error.message]);
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
return normalized;
|
|
69
|
+
};
|
|
@@ -3,6 +3,10 @@ import type { CoreAgent, AgentInput, AgentToolDef, AgentMessage, AgentStreamChan
|
|
|
3
3
|
import type { AgentRunnerParams } from '../../services/agent-runner-service.js';
|
|
4
4
|
import { PikkuError } from '../../errors/error-handler.js';
|
|
5
5
|
import type { SessionService } from '../../services/user-session-service.js';
|
|
6
|
+
/**
|
|
7
|
+
* Per-request context for running an agent: the caller's session, credential access and, for
|
|
8
|
+
* a sessionless request, the minted anonymous owner id.
|
|
9
|
+
*/
|
|
6
10
|
export type RunAgentParams = {
|
|
7
11
|
sessionService?: SessionService<CoreUserSession>;
|
|
8
12
|
/** Credential accessor for the current request — used to read per-user overrides (e.g. AI_API_KEY). */
|
|
@@ -13,17 +17,41 @@ export type RunAgentParams = {
|
|
|
13
17
|
export declare function resolveSessionPrincipal(params: RunAgentParams, sessionScope: SessionScope | undefined): string | undefined;
|
|
14
18
|
export declare function resolveOwnerResourceId(params: RunAgentParams, sessionScope: SessionScope | undefined, requestedResourceId: string): string;
|
|
15
19
|
export declare function assertResourcePrincipalOwner(params: RunAgentParams, sessionScope: SessionScope | undefined, storedResourceId: string, kind: 'thread' | 'run'): void;
|
|
20
|
+
/**
|
|
21
|
+
* Refuses a run that belongs to a different agent than the one a route was
|
|
22
|
+
* built for. Ownership is checked first, so only the run's owner learns which
|
|
23
|
+
* agent it belongs to.
|
|
24
|
+
*/
|
|
25
|
+
export declare function assertRunBelongsToAgent(run: {
|
|
26
|
+
runId: string;
|
|
27
|
+
agentName: string;
|
|
28
|
+
}, expectedAgentName: string | undefined): void;
|
|
16
29
|
export declare function agentSessionScope(agentName: string): SessionScope;
|
|
17
30
|
export declare function assertResourceOwner(ownerResourceId: string, storedResourceId: string, kind: 'thread' | 'run'): void;
|
|
18
31
|
export declare function sessionPrincipals(session: {
|
|
19
32
|
userId?: string;
|
|
20
33
|
orgId?: string;
|
|
21
34
|
} | undefined): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Whether a stored thread or run `resourceId` belongs to `principal`: it is the principal itself
|
|
37
|
+
* or one of its `principal:` sub-partitions.
|
|
38
|
+
*/
|
|
22
39
|
export declare function isOwnedByPrincipal(storedResourceId: string, principal: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The principals (user id, then org id) a session may list threads for. Pass it as the `owners`
|
|
42
|
+
* filter to `AgentRunService.listThreads`; an empty array, for a missing session, matches nothing.
|
|
43
|
+
*/
|
|
23
44
|
export declare function threadOwnerConstraint(session: {
|
|
24
45
|
userId?: string;
|
|
25
46
|
orgId?: string;
|
|
26
47
|
} | undefined): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Whether `session` may read the thread or run stored under `storedResourceId`: true only when the
|
|
50
|
+
* resource belongs to the session's user or org. A missing session is always refused.
|
|
51
|
+
*
|
|
52
|
+
* Use it before returning a thread over the wire; answering "not found" for both a missing and a
|
|
53
|
+
* forbidden thread avoids revealing which threads exist.
|
|
54
|
+
*/
|
|
27
55
|
export declare function canAccessThread(storedResourceId: string, session: {
|
|
28
56
|
userId?: string;
|
|
29
57
|
orgId?: string;
|
|
@@ -42,6 +70,10 @@ export declare function canAccessThread(storedResourceId: string, session: {
|
|
|
42
70
|
* against it.
|
|
43
71
|
*/
|
|
44
72
|
export declare const agentCallOptions: (input: AgentInput) => AgentInput;
|
|
73
|
+
/**
|
|
74
|
+
* Options for a streamed run: which tool calls need approval (`'all'`, only tools that declare it,
|
|
75
|
+
* or none) and a callback receiving the run id once it is created.
|
|
76
|
+
*/
|
|
45
77
|
export type StreamAgentOptions = {
|
|
46
78
|
requiresToolApproval?: 'all' | 'explicit' | false;
|
|
47
79
|
onRunCreated?: (runId: string) => void;
|
|
@@ -53,6 +85,10 @@ export declare const APPROVAL_REQUIRED: unique symbol;
|
|
|
53
85
|
* has crossed a JSON boundary has lost the brand and is treated as untrusted.
|
|
54
86
|
*/
|
|
55
87
|
export declare const CREDENTIAL_REQUIRED: unique symbol;
|
|
88
|
+
/**
|
|
89
|
+
* Raised when a tool call needs a human's approval before it runs. The run is suspended with the
|
|
90
|
+
* call recorded in `pendingApprovals`, and resumes through `agentResume` or `agentApprove`.
|
|
91
|
+
*/
|
|
56
92
|
export declare class ToolApprovalRequired extends PikkuError {
|
|
57
93
|
readonly toolCallId: string;
|
|
58
94
|
readonly toolName: string;
|
|
@@ -63,6 +99,11 @@ export declare class ToolApprovalRequired extends PikkuError {
|
|
|
63
99
|
readonly agentRunId?: string;
|
|
64
100
|
constructor(toolCallId: string, toolName: string, args: unknown, reason?: string, displayToolName?: string, displayArgs?: unknown, agentRunId?: string);
|
|
65
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Raised when a tool needs a credential the user has not connected. The run is suspended and the
|
|
104
|
+
* client is sent the credential's name, type and connect URL. Only requests pikku itself produced
|
|
105
|
+
* are honoured, so tool output cannot forge one.
|
|
106
|
+
*/
|
|
66
107
|
export declare class ToolCredentialRequired extends PikkuError {
|
|
67
108
|
readonly toolCallId: string;
|
|
68
109
|
readonly toolName: string;
|
|
@@ -7,8 +7,6 @@ import { pikkuState, getSingletonServices } from '../../pikku-state.js';
|
|
|
7
7
|
import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js';
|
|
8
8
|
import { randomUUID } from './agent-utils.js';
|
|
9
9
|
import { awaitPendingInterruptNote } from './agent-interrupt.js';
|
|
10
|
-
import { streamAgent } from './agent-stream.js';
|
|
11
|
-
import { runAgent } from './agent-runner.js';
|
|
12
10
|
import { resolveNamespace, ContextAwareRPCService, } from '../../wirings/rpc/rpc-runner.js';
|
|
13
11
|
import { getOrCreatePackageSingletonServices } from '../../wirings/addon/addon-runner.js';
|
|
14
12
|
import { resolveMemoryServices, loadContextMessages, trimMessages, } from './agent-memory.js';
|
|
@@ -41,6 +39,16 @@ export function assertResourcePrincipalOwner(params, sessionScope, storedResourc
|
|
|
41
39
|
throw new ForbiddenError(`Not authorized to access this ${kind}`);
|
|
42
40
|
}
|
|
43
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Refuses a run that belongs to a different agent than the one a route was
|
|
44
|
+
* built for. Ownership is checked first, so only the run's owner learns which
|
|
45
|
+
* agent it belongs to.
|
|
46
|
+
*/
|
|
47
|
+
export function assertRunBelongsToAgent(run, expectedAgentName) {
|
|
48
|
+
if (expectedAgentName && run.agentName !== expectedAgentName) {
|
|
49
|
+
throw new ForbiddenError(`Run ${run.runId} belongs to agent '${run.agentName}', not '${expectedAgentName}'`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
44
52
|
export function agentSessionScope(agentName) {
|
|
45
53
|
return resolveAgent(agentName).agent.sessionScope ?? 'user';
|
|
46
54
|
}
|
|
@@ -52,13 +60,28 @@ export function assertResourceOwner(ownerResourceId, storedResourceId, kind) {
|
|
|
52
60
|
export function sessionPrincipals(session) {
|
|
53
61
|
return [session?.userId, session?.orgId].filter((principal) => Boolean(principal));
|
|
54
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether a stored thread or run `resourceId` belongs to `principal`: it is the principal itself
|
|
65
|
+
* or one of its `principal:` sub-partitions.
|
|
66
|
+
*/
|
|
55
67
|
export function isOwnedByPrincipal(storedResourceId, principal) {
|
|
56
68
|
return (storedResourceId === principal ||
|
|
57
69
|
storedResourceId.startsWith(`${principal}:`));
|
|
58
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* The principals (user id, then org id) a session may list threads for. Pass it as the `owners`
|
|
73
|
+
* filter to `AgentRunService.listThreads`; an empty array, for a missing session, matches nothing.
|
|
74
|
+
*/
|
|
59
75
|
export function threadOwnerConstraint(session) {
|
|
60
76
|
return sessionPrincipals(session);
|
|
61
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether `session` may read the thread or run stored under `storedResourceId`: true only when the
|
|
80
|
+
* resource belongs to the session's user or org. A missing session is always refused.
|
|
81
|
+
*
|
|
82
|
+
* Use it before returning a thread over the wire; answering "not found" for both a missing and a
|
|
83
|
+
* forbidden thread avoids revealing which threads exist.
|
|
84
|
+
*/
|
|
62
85
|
export function canAccessThread(storedResourceId, session) {
|
|
63
86
|
const principals = sessionPrincipals(session);
|
|
64
87
|
if (principals.length === 0)
|
|
@@ -96,6 +119,10 @@ export const APPROVAL_REQUIRED = Symbol('pikku.ai.approvalRequired');
|
|
|
96
119
|
* has crossed a JSON boundary has lost the brand and is treated as untrusted.
|
|
97
120
|
*/
|
|
98
121
|
export const CREDENTIAL_REQUIRED = Symbol('pikku.ai.credentialRequired');
|
|
122
|
+
/**
|
|
123
|
+
* Raised when a tool call needs a human's approval before it runs. The run is suspended with the
|
|
124
|
+
* call recorded in `pendingApprovals`, and resumes through `agentResume` or `agentApprove`.
|
|
125
|
+
*/
|
|
99
126
|
export class ToolApprovalRequired extends PikkuError {
|
|
100
127
|
toolCallId;
|
|
101
128
|
toolName;
|
|
@@ -115,6 +142,11 @@ export class ToolApprovalRequired extends PikkuError {
|
|
|
115
142
|
this.agentRunId = agentRunId;
|
|
116
143
|
}
|
|
117
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Raised when a tool needs a credential the user has not connected. The run is suspended and the
|
|
147
|
+
* client is sent the credential's name, type and connect URL. Only requests pikku itself produced
|
|
148
|
+
* are honoured, so tool output cannot forge one.
|
|
149
|
+
*/
|
|
118
150
|
export class ToolCredentialRequired extends PikkuError {
|
|
119
151
|
toolCallId;
|
|
120
152
|
toolName;
|
|
@@ -460,6 +492,8 @@ export async function buildToolDefs(params, agentSessionMap, resourceId, agentNa
|
|
|
460
492
|
threadId = randomUUID();
|
|
461
493
|
agentSessionMap.set(sessionKey, threadId);
|
|
462
494
|
}
|
|
495
|
+
// A sub-agent runs on the same runners that build these tools. They
|
|
496
|
+
// import this module, so importing them back statically is a cycle.
|
|
463
497
|
if (streamContext) {
|
|
464
498
|
const isDelegate = agentMode !== 'supervise';
|
|
465
499
|
if (isDelegate && streamContext.delegateState) {
|
|
@@ -484,6 +518,7 @@ export async function buildToolDefs(params, agentSessionMap, resourceId, agentNa
|
|
|
484
518
|
await subChannel.send(event);
|
|
485
519
|
},
|
|
486
520
|
};
|
|
521
|
+
const { streamAgent } = await import('./agent-stream.js');
|
|
487
522
|
const resultText = await streamAgent(subAgentName, buildSubAgentRunInput(message, threadId, resourceId, parentContext), effectiveChannel, params, agentSessionMap, streamContext.options);
|
|
488
523
|
if (subChannel.approvals.length > 0) {
|
|
489
524
|
return {
|
|
@@ -503,6 +538,7 @@ export async function buildToolDefs(params, agentSessionMap, resourceId, agentNa
|
|
|
503
538
|
});
|
|
504
539
|
return resultText;
|
|
505
540
|
}
|
|
541
|
+
const { runAgent } = await import('./agent-runner.js');
|
|
506
542
|
const result = await runAgent(subAgentName, buildSubAgentRunInput(message, threadId, resourceId, parentContext), params, agentSessionMap);
|
|
507
543
|
if (result.status === 'suspended' &&
|
|
508
544
|
result.pendingApprovals?.length) {
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { CoreAgent } from './agent.types.js';
|
|
2
2
|
import type { AgentRunStateService } from '../../services/agent-run-state-service.js';
|
|
3
3
|
import { type RunAgentParams } from './agent-prepare.js';
|
|
4
|
+
/**
|
|
5
|
+
* Registers an agent's runtime config under its name. Called by generated code.
|
|
6
|
+
*
|
|
7
|
+
* Skipped with a warning when the inspector recorded no metadata for the agent.
|
|
8
|
+
*
|
|
9
|
+
* @throws Error when an agent with the same name is already registered.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
4
12
|
export declare const addAgent: (agentName: string, agent: CoreAgent<any, any>, packageName?: string | null) => void;
|
|
5
13
|
export declare function approveAgent(agentRunState: AgentRunStateService, runId: string, approvals: {
|
|
6
14
|
toolCallId: string;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { pikkuState } from '../../pikku-state.js';
|
|
2
|
-
import { agentSessionScope, assertAgentAuthorized, assertResourcePrincipalOwner, resolveAgent, } from './agent-prepare.js';
|
|
2
|
+
import { agentSessionScope, assertAgentAuthorized, assertResourcePrincipalOwner, assertRunBelongsToAgent, resolveAgent, } from './agent-prepare.js';
|
|
3
|
+
/**
|
|
4
|
+
* Registers an agent's runtime config under its name. Called by generated code.
|
|
5
|
+
*
|
|
6
|
+
* Skipped with a warning when the inspector recorded no metadata for the agent.
|
|
7
|
+
*
|
|
8
|
+
* @throws Error when an agent with the same name is already registered.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
3
11
|
export const addAgent = (agentName, agent, packageName = null) => {
|
|
4
12
|
const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta');
|
|
5
13
|
const agentMeta = agentsMeta[agentName];
|
|
@@ -20,9 +28,7 @@ export async function approveAgent(agentRunState, runId, approvals, expectedAgen
|
|
|
20
28
|
if (!run)
|
|
21
29
|
throw new Error('Run not found: ' + runId);
|
|
22
30
|
assertResourcePrincipalOwner(params, agentSessionScope(run.agentName), run.resourceId, 'run');
|
|
23
|
-
|
|
24
|
-
throw new Error(`Run ${runId} belongs to agent '${run.agentName}', not '${expectedAgentName}'`);
|
|
25
|
-
}
|
|
31
|
+
assertRunBelongsToAgent(run, expectedAgentName);
|
|
26
32
|
if (run.status !== 'suspended')
|
|
27
33
|
throw new Error('Run is not suspended: ' + run.status);
|
|
28
34
|
const { agent, packageName } = resolveAgent(run.agentName);
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import type { AgentInput, AgentOutput } from './agent.types.js';
|
|
2
2
|
import { type RunAgentParams } from './agent-prepare.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runs an agent to completion: loads the thread, applies agent middleware, calls the model step by
|
|
5
|
+
* step (up to the agent's `maxSteps`) and persists the messages and run state.
|
|
6
|
+
*
|
|
7
|
+
* Before anything runs, the agent's `auth`, `scopes` and `permissions` are checked against the
|
|
8
|
+
* session, and `input.resourceId` is partitioned under the session principal (or an anonymous id
|
|
9
|
+
* minted per request), so a caller cannot address another user's thread.
|
|
10
|
+
*
|
|
11
|
+
* @param agentName - The agent to run.
|
|
12
|
+
* @param input - The user message, thread and resource ids, and optional model overrides.
|
|
13
|
+
* @param params - The caller's session and credential access.
|
|
14
|
+
* @param agentSessionMap - Sub-agent session ids, shared across delegated calls in one run.
|
|
15
|
+
* @returns The run's text or structured output, its steps and usage. A run that needs approval or
|
|
16
|
+
* a credential, or names RPCs that are not registered, returns `status: 'suspended'` instead.
|
|
17
|
+
* @throws MissingSessionError when the agent requires auth and there is no session; ForbiddenError
|
|
18
|
+
* for a scope or permission failure or a thread owned by someone else; AIProviderNotConfiguredError
|
|
19
|
+
* when no `agentRunner` service is set.
|
|
20
|
+
*/
|
|
3
21
|
export declare function runAgent(agentName: string, input: AgentInput, params: RunAgentParams, agentSessionMap?: Map<string, string>): Promise<AgentOutput>;
|
|
22
|
+
/**
|
|
23
|
+
* Answers pending approvals on a suspended run and runs it to completion without streaming. Backs
|
|
24
|
+
* `rpc.agent.approve`.
|
|
25
|
+
*
|
|
26
|
+
* Only the run's owner may resume it, and the agent is re-authorized. Each approval is claimed
|
|
27
|
+
* atomically, so concurrent callers cannot run the same tool twice.
|
|
28
|
+
*
|
|
29
|
+
* @param runId - The suspended run.
|
|
30
|
+
* @param approvals - The decision for each pending tool call.
|
|
31
|
+
* @param params - The caller's session.
|
|
32
|
+
* @param expectedAgentName - When given, the run must belong to this agent.
|
|
33
|
+
* @returns The run's final output, or `status: 'suspended'` again if more approvals are needed.
|
|
34
|
+
* @throws ForbiddenError when the caller does not own the run; Error when the run is missing, not
|
|
35
|
+
* suspended, belongs to another agent, or every approval was already claimed.
|
|
36
|
+
*/
|
|
4
37
|
export declare function resumeAgentSync(runId: string, approvals: {
|
|
5
38
|
toolCallId: string;
|
|
6
39
|
approved: boolean;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { saveMessages, resolveMemoryServices, loadContextMessages, trimMessages, getWorkingMemoryMiddleware, } from './agent-memory.js';
|
|
2
|
-
import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, resolveOwnerResourceId, agentSessionScope, assertResourcePrincipalOwner, assertAgentAuthorized, } from './agent-prepare.js';
|
|
2
|
+
import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, resolveOwnerResourceId, agentSessionScope, assertResourcePrincipalOwner, assertRunBelongsToAgent, assertAgentAuthorized, } from './agent-prepare.js';
|
|
3
3
|
import { checkForApprovals, appendStepMessages } from './agent-stream.js';
|
|
4
4
|
import { AgentInterruptedError, isAbortError, persistOrphanedToolResults, registerInterruptibleRun, trackInterruptNote, trackToolExecution, } from './agent-interrupt.js';
|
|
5
5
|
import { pikkuState, getSingletonServices } from '../../pikku-state.js';
|
|
6
6
|
import { applyInputMiddleware, describeApprovals, notifyAfterStep, toAccumulatedStep, } from './agent-turn.js';
|
|
7
7
|
import { applyOutputMiddleware, finalizeAgentRun, lastUserMessageText, } from './agent-finalize.js';
|
|
8
8
|
import { resolveModelConfig } from './agent-model-config.js';
|
|
9
|
+
import { validateAgentOutput } from './agent-output.js';
|
|
9
10
|
import { AIProviderNotConfiguredError } from '../../errors/errors.js';
|
|
10
11
|
import { deniedToolResult, randomUUID } from './agent-utils.js';
|
|
11
12
|
function stripNulls(obj) {
|
|
@@ -33,13 +34,31 @@ function extractStructuredAssistantOutput(object) {
|
|
|
33
34
|
uiSpec: record.ui ?? null,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Runs an agent to completion: loads the thread, applies agent middleware, calls the model step by
|
|
39
|
+
* step (up to the agent's `maxSteps`) and persists the messages and run state.
|
|
40
|
+
*
|
|
41
|
+
* Before anything runs, the agent's `auth`, `scopes` and `permissions` are checked against the
|
|
42
|
+
* session, and `input.resourceId` is partitioned under the session principal (or an anonymous id
|
|
43
|
+
* minted per request), so a caller cannot address another user's thread.
|
|
44
|
+
*
|
|
45
|
+
* @param agentName - The agent to run.
|
|
46
|
+
* @param input - The user message, thread and resource ids, and optional model overrides.
|
|
47
|
+
* @param params - The caller's session and credential access.
|
|
48
|
+
* @param agentSessionMap - Sub-agent session ids, shared across delegated calls in one run.
|
|
49
|
+
* @returns The run's text or structured output, its steps and usage. A run that needs approval or
|
|
50
|
+
* a credential, or names RPCs that are not registered, returns `status: 'suspended'` instead.
|
|
51
|
+
* @throws MissingSessionError when the agent requires auth and there is no session; ForbiddenError
|
|
52
|
+
* for a scope or permission failure or a thread owned by someone else; AIProviderNotConfiguredError
|
|
53
|
+
* when no `agentRunner` service is set.
|
|
54
|
+
*/
|
|
36
55
|
export async function runAgent(agentName, input, params, agentSessionMap) {
|
|
37
56
|
const sessionMap = agentSessionMap ?? new Map();
|
|
38
57
|
input = {
|
|
39
58
|
...input,
|
|
40
59
|
resourceId: resolveOwnerResourceId(params, agentSessionScope(agentName), input.resourceId),
|
|
41
60
|
};
|
|
42
|
-
const { agent, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, maxSteps, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName, input, params, sessionMap);
|
|
61
|
+
const { agent, packageName, resolvedName, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, maxSteps, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName, input, params, sessionMap);
|
|
43
62
|
runnerParams.agentId = agentName;
|
|
44
63
|
const singletonServices = getSingletonServices();
|
|
45
64
|
const { agentRunState } = singletonServices;
|
|
@@ -186,7 +205,8 @@ export async function runAgent(agentName, input, params, agentSessionMap) {
|
|
|
186
205
|
}
|
|
187
206
|
appendStepMessages(runnerParams, stepResult);
|
|
188
207
|
}
|
|
189
|
-
const finalObject =
|
|
208
|
+
const finalObject = await validateAgentOutput(agentName, pikkuState(packageName, 'agent', 'agentsMeta')[resolvedName]
|
|
209
|
+
?.outputSchema, lastStepResult?.object, packageName);
|
|
190
210
|
const structuredOutput = extractStructuredAssistantOutput(finalObject);
|
|
191
211
|
const finalText = structuredOutput.text ?? lastStepResult?.text ?? '';
|
|
192
212
|
const result = {
|
|
@@ -255,6 +275,21 @@ export async function runAgent(agentName, input, params, agentSessionMap) {
|
|
|
255
275
|
interruptHandle.release();
|
|
256
276
|
}
|
|
257
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Answers pending approvals on a suspended run and runs it to completion without streaming. Backs
|
|
280
|
+
* `rpc.agent.approve`.
|
|
281
|
+
*
|
|
282
|
+
* Only the run's owner may resume it, and the agent is re-authorized. Each approval is claimed
|
|
283
|
+
* atomically, so concurrent callers cannot run the same tool twice.
|
|
284
|
+
*
|
|
285
|
+
* @param runId - The suspended run.
|
|
286
|
+
* @param approvals - The decision for each pending tool call.
|
|
287
|
+
* @param params - The caller's session.
|
|
288
|
+
* @param expectedAgentName - When given, the run must belong to this agent.
|
|
289
|
+
* @returns The run's final output, or `status: 'suspended'` again if more approvals are needed.
|
|
290
|
+
* @throws ForbiddenError when the caller does not own the run; Error when the run is missing, not
|
|
291
|
+
* suspended, belongs to another agent, or every approval was already claimed.
|
|
292
|
+
*/
|
|
258
293
|
export async function resumeAgentSync(runId, approvals, params, expectedAgentName) {
|
|
259
294
|
const singletonServices = getSingletonServices();
|
|
260
295
|
const { agentRunState } = singletonServices;
|
|
@@ -265,9 +300,7 @@ export async function resumeAgentSync(runId, approvals, params, expectedAgentNam
|
|
|
265
300
|
if (!run)
|
|
266
301
|
throw new Error(`No run found for runId ${runId}`);
|
|
267
302
|
assertResourcePrincipalOwner(params, agentSessionScope(run.agentName), run.resourceId, 'run');
|
|
268
|
-
|
|
269
|
-
throw new Error(`Run ${runId} belongs to agent '${run.agentName}', not '${expectedAgentName}'`);
|
|
270
|
-
}
|
|
303
|
+
assertRunBelongsToAgent(run, expectedAgentName);
|
|
271
304
|
if (run.status !== 'suspended') {
|
|
272
305
|
throw new Error(`Run ${runId} is not suspended (status: ${run.status})`);
|
|
273
306
|
}
|
|
@@ -510,7 +543,7 @@ async function continueAfterToolResultSync(run, agent, packageName, resolvedName
|
|
|
510
543
|
appendStepMessages(runnerParams, stepResult);
|
|
511
544
|
}
|
|
512
545
|
const finalText = lastStepResult?.text ?? '';
|
|
513
|
-
const finalObject = lastStepResult?.object;
|
|
546
|
+
const finalObject = await validateAgentOutput(run.agentName, meta?.outputSchema, lastStepResult?.object, packageName);
|
|
514
547
|
const result = {
|
|
515
548
|
text: finalText,
|
|
516
549
|
steps: accumulatedSteps,
|