@pikku/core 0.12.79 → 0.12.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +473 -0
- package/dist/dev/hot-reload.js +1 -6
- package/dist/ecosystem.d.ts +27 -0
- package/dist/ecosystem.js +26 -0
- package/dist/errors/error-handler.js +4 -2
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/function/function-runner.js +22 -47
- package/dist/function/functions.types.d.ts +9 -5
- package/dist/function/index.d.ts +1 -1
- package/dist/index.d.ts +14 -19
- package/dist/index.js +6 -11
- package/dist/middleware/auth-cookie.d.ts +0 -4
- package/dist/middleware/auth-cookie.js +38 -2
- package/dist/middleware/cors.js +1 -0
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/remote-auth.js +14 -3
- package/dist/permissions.d.ts +8 -10
- package/dist/permissions.js +0 -11
- package/dist/pikku-state.js +16 -5
- package/dist/schema.js +35 -1
- package/dist/services/ai-agent-runner-service.d.ts +7 -0
- package/dist/services/ai-run-state-service.d.ts +17 -1
- package/dist/services/in-memory-ai-run-state-service.d.ts +6 -2
- package/dist/services/in-memory-ai-run-state-service.js +11 -1
- package/dist/services/in-memory-workflow-service.js +2 -0
- package/dist/services/index.d.ts +15 -15
- package/dist/services/index.js +5 -5
- package/dist/services/local-content-request-handler.d.ts +21 -0
- package/dist/services/local-content-request-handler.js +72 -53
- package/dist/services/local-content.d.ts +6 -0
- package/dist/services/local-content.js +14 -1
- package/dist/services/scoped-credential-service.d.ts +21 -0
- package/dist/services/scoped-credential-service.js +53 -0
- package/dist/services/workflow-service.d.ts +4 -2
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +10 -0
- package/dist/testing/service-tests/agent-run-service-tests.js +72 -0
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/ai-storage-service-tests.js +302 -0
- package/dist/testing/service-tests/channel-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/channel-store-tests.js +72 -0
- package/dist/testing/service-tests/credential-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/credential-service-tests.js +109 -0
- package/dist/testing/service-tests/deployment-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/deployment-service-tests.js +21 -0
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/event-hub-store-tests.js +34 -0
- package/dist/testing/service-tests/secret-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/secret-service-tests.js +80 -0
- package/dist/testing/service-tests/session-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/session-store-tests.js +43 -0
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/workflow-run-service-tests.js +42 -0
- package/dist/testing/service-tests/workflow-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/workflow-service-tests.js +150 -0
- package/dist/testing/service-tests.d.ts +6 -0
- package/dist/testing/service-tests.js +26 -791
- package/dist/types/core.types.d.ts +11 -3
- package/dist/types/state.types.d.ts +14 -1
- package/dist/wirings/actor-flow/index.d.ts +1 -1
- package/dist/wirings/actor-flow/run-conversation.js +1 -6
- package/dist/wirings/ai-agent/agent-rpc.d.ts +15 -0
- package/dist/wirings/ai-agent/agent-rpc.js +53 -0
- package/dist/wirings/ai-agent/ai-agent-agui.js +1 -5
- package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +58 -0
- package/dist/wirings/ai-agent/ai-agent-finalize.js +138 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +1 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +2 -8
- package/dist/wirings/ai-agent/ai-agent-memory.js +37 -18
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +44 -1
- package/dist/wirings/ai-agent/ai-agent-prepare.js +5 -9
- package/dist/wirings/ai-agent/ai-agent-runner.js +89 -147
- package/dist/wirings/ai-agent/ai-agent-stream.js +109 -97
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +57 -0
- package/dist/wirings/ai-agent/ai-agent-turn.js +82 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +47 -2
- package/dist/wirings/ai-agent/index.d.ts +8 -7
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.js +1 -6
- package/dist/wirings/ai-agent/voice-output.js +2 -12
- package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +26 -0
- package/dist/wirings/ai-scorer/ai-scorer-grade.js +33 -0
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +17 -0
- package/dist/wirings/ai-scorer/ai-scorer-judge.js +92 -0
- package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +15 -0
- package/dist/wirings/ai-scorer/ai-scorer-live.js +38 -0
- package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +18 -0
- package/dist/wirings/ai-scorer/ai-scorer-registry.js +46 -0
- package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +8 -0
- package/dist/wirings/ai-scorer/ai-scorer-sampling.js +31 -0
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +10 -0
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +40 -0
- package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +15 -0
- package/dist/wirings/ai-scorer/ai-scorer-worker.js +58 -0
- package/dist/wirings/ai-scorer/ai-scorer.d.ts +39 -0
- package/dist/wirings/ai-scorer/ai-scorer.js +40 -0
- package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +90 -0
- package/dist/wirings/ai-scorer/ai-scorer.types.js +4 -0
- package/dist/wirings/ai-scorer/index.d.ts +6 -0
- package/dist/wirings/ai-scorer/index.js +5 -0
- package/dist/wirings/channel/channel-common.js +1 -0
- package/dist/wirings/channel/channel-handler.js +3 -5
- package/dist/wirings/channel/channel-rpc-service.d.ts +0 -6
- package/dist/wirings/channel/channel-rpc-service.js +0 -8
- package/dist/wirings/channel/channel-rpc.types.d.ts +6 -0
- package/dist/wirings/channel/channel-rpc.types.js +8 -0
- package/dist/wirings/channel/channel-runner.d.ts +1 -3
- package/dist/wirings/channel/channel-runner.js +16 -8
- package/dist/wirings/channel/channel.types.d.ts +2 -0
- package/dist/wirings/channel/index.d.ts +5 -6
- package/dist/wirings/channel/index.js +3 -4
- package/dist/wirings/channel/local/local-channel-runner.js +8 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +3 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +2 -0
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +9 -1
- package/dist/wirings/cli/channel/index.d.ts +1 -2
- package/dist/wirings/cli/channel/index.js +0 -1
- package/dist/wirings/cli/cli-runner.js +17 -3
- package/dist/wirings/cli/cli.types.d.ts +0 -8
- package/dist/wirings/cli/command-parser.js +13 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/gateway/gateway-runner.js +9 -2
- package/dist/wirings/gateway/index.d.ts +1 -1
- package/dist/wirings/http/http-routes.js +2 -0
- package/dist/wirings/http/http-runner.d.ts +0 -10
- package/dist/wirings/http/http-runner.js +14 -15
- package/dist/wirings/http/http.types.d.ts +0 -10
- package/dist/wirings/http/index.d.ts +2 -3
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/mcp/index.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +15 -7
- package/dist/wirings/mcp/mcp-runner.js +18 -11
- package/dist/wirings/persona/index.d.ts +3 -4
- package/dist/wirings/persona/index.js +2 -3
- package/dist/wirings/queue/index.d.ts +1 -3
- package/dist/wirings/queue/index.js +1 -3
- package/dist/wirings/rpc/addon-runner.d.ts +4 -0
- package/dist/wirings/rpc/addon-runner.js +19 -3
- package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
- package/dist/wirings/rpc/rpc-runner.js +55 -86
- package/dist/wirings/rpc/rpc-types.d.ts +7 -0
- package/dist/wirings/rpc/wire-addon.d.ts +13 -0
- package/dist/wirings/rpc/wire-addon.js +4 -0
- package/dist/wirings/scheduler/index.d.ts +1 -1
- package/dist/wirings/secret/validate-secret-definitions.js +2 -2
- package/dist/wirings/trigger/index.d.ts +1 -1
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +0 -4
- package/dist/wirings/trigger/trigger-runner.js +1 -0
- package/dist/wirings/virtual-user/index.d.ts +5 -6
- package/dist/wirings/virtual-user/index.js +2 -4
- package/dist/wirings/virtual-user/run-virtual-user.js +11 -11
- package/dist/wirings/virtual-user/virtual-user-derive.js +4 -25
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +1 -4
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +100 -3
- package/dist/wirings/workflow/feature.js +7 -4
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -2
- package/dist/wirings/workflow/graph/graph-runner.js +8 -7
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -4
- package/dist/wirings/workflow/index.d.ts +12 -7
- package/dist/wirings/workflow/index.js +7 -3
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
- package/dist/wirings/workflow/pikku-scenario-service.js +64 -10
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -147
- package/dist/wirings/workflow/pikku-workflow-service.js +85 -493
- package/dist/wirings/workflow/scenario-step.types.d.ts +8 -0
- package/dist/wirings/workflow/workflow-approval-audit.d.ts +16 -0
- package/dist/wirings/workflow/workflow-approval-audit.js +40 -0
- package/dist/wirings/workflow/workflow-approval-policy.d.ts +20 -0
- package/dist/wirings/workflow/workflow-approval-policy.js +48 -0
- package/dist/wirings/workflow/workflow-approval.d.ts +67 -0
- package/dist/wirings/workflow/workflow-approval.js +177 -0
- package/dist/wirings/workflow/workflow-constants.d.ts +26 -0
- package/dist/wirings/workflow/workflow-constants.js +35 -0
- package/dist/wirings/workflow/workflow-errors.d.ts +58 -0
- package/dist/wirings/workflow/workflow-errors.js +112 -0
- package/dist/wirings/workflow/workflow-meta-resolver.d.ts +11 -0
- package/dist/wirings/workflow/workflow-meta-resolver.js +31 -0
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +8 -0
- package/dist/wirings/workflow/workflow-queue-routing.js +38 -0
- package/dist/wirings/workflow/workflow-queue-wiring.d.ts +20 -0
- package/dist/wirings/workflow/workflow-queue-wiring.js +79 -0
- package/dist/wirings/workflow/workflow-recovery.d.ts +68 -0
- package/dist/wirings/workflow/workflow-recovery.js +101 -0
- package/dist/wirings/workflow/workflow-run-engine.types.d.ts +54 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +17 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +30 -0
- package/dist/wirings/workflow/workflow-suspend.d.ts +12 -0
- package/dist/wirings/workflow/workflow-suspend.js +33 -0
- package/dist/wirings/workflow/workflow.types.d.ts +8 -1
- package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-airunstate-too.md +22 -0
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +20 -0
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +21 -0
- package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +21 -0
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +46 -0
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +45 -0
- package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +32 -0
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +21 -0
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +22 -0
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +39 -0
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +23 -0
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +25 -0
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +22 -0
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +20 -0
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +22 -0
- package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +66 -0
- package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +33 -0
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +43 -0
- package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +26 -0
- package/knowledge/decisions/internals/index.md +42 -3
- package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +21 -0
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +24 -0
- package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +34 -0
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +24 -0
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +22 -0
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +26 -0
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +43 -0
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +58 -0
- package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +40 -0
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +40 -0
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +28 -0
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +25 -0
- package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +21 -0
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +22 -0
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +25 -0
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +115 -0
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +21 -0
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +24 -0
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +35 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +4 -2
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +37 -0
- package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +33 -0
- package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +33 -0
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +37 -0
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +28 -0
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +50 -0
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -0
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +59 -0
- package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +24 -0
- package/knowledge/decisions/security/index.md +9 -0
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +35 -0
- package/knowledge/questions/index.md +2 -1
- package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +44 -0
- package/package.json +15 -3
- package/scripts/generate-api-report.d.mts +1 -0
- package/scripts/generate-api-report.mjs +89 -0
- package/scripts/generate-api-report.mts +343 -0
- package/src/api-report.test.ts +69 -0
- package/src/column-form.ts +1 -4
- package/src/crypto-utils.test.ts +15 -2
- package/src/dev/hot-reload.ts +2 -7
- package/src/ecosystem.ts +40 -0
- package/src/errors/error-handler.ts +5 -3
- package/src/errors/error.test.ts +4 -1
- package/src/errors/index.ts +1 -1
- package/src/function/function-runner.test.ts +53 -1
- package/src/function/function-runner.ts +33 -48
- package/src/function/functions.types.ts +15 -9
- package/src/function/index.ts +0 -2
- package/src/handle-error.ts +1 -1
- package/src/index.ts +3 -57
- package/src/middleware/auth-cookie.test.ts +50 -0
- package/src/middleware/auth-cookie.ts +38 -2
- package/src/middleware/cors.ts +2 -1
- package/src/middleware/index.ts +1 -1
- package/src/middleware/remote-auth.test.ts +43 -0
- package/src/middleware/remote-auth.ts +17 -3
- package/src/middleware-runner.ts +4 -2
- package/src/no-any-casts.test.ts +57 -0
- package/src/permissions.test.ts +3 -1
- package/src/permissions.ts +22 -24
- package/src/pikku-state.ts +22 -6
- package/src/public-surface.json +554 -0
- package/src/public-surface.json.README +25 -0
- package/src/public-surface.test.ts +105 -0
- package/src/removed-legacy-exports.test.ts +62 -0
- package/src/schema.test.ts +78 -0
- package/src/schema.ts +36 -1
- package/src/services/ai-agent-runner-service.ts +12 -1
- package/src/services/ai-run-state-service.ts +18 -1
- package/src/services/audit-service.ts +2 -2
- package/src/services/in-memory-ai-run-state-service.ts +16 -2
- package/src/services/in-memory-workflow-service.ts +2 -0
- package/src/services/index.ts +4 -47
- package/src/services/local-content-request-handler.test.ts +43 -5
- package/src/services/local-content-request-handler.ts +103 -74
- package/src/services/local-content.ts +15 -1
- package/src/services/local-email-service.ts +5 -1
- package/src/services/scoped-credential-service.test.ts +86 -0
- package/src/services/scoped-credential-service.ts +63 -0
- package/src/services/system-role-guard.test.ts +4 -1
- package/src/services/workflow-service.ts +9 -2
- package/src/side-effects-are-declared.test.ts +84 -0
- package/src/source-files-stay-composable.test.ts +41 -0
- package/src/testing/service-tests/agent-run-service-tests.ts +98 -0
- package/src/testing/service-tests/ai-storage-service-tests.ts +379 -0
- package/src/testing/service-tests/channel-store-tests.ts +98 -0
- package/src/testing/service-tests/credential-service-tests.ts +143 -0
- package/src/testing/service-tests/deployment-service-tests.ts +33 -0
- package/src/testing/service-tests/event-hub-store-tests.ts +48 -0
- package/src/testing/service-tests/secret-service-tests.ts +105 -0
- package/src/testing/service-tests/session-store-tests.ts +62 -0
- package/src/testing/service-tests/workflow-run-service-tests.ts +59 -0
- package/src/testing/service-tests/workflow-service-tests.ts +308 -0
- package/src/testing/service-tests.ts +31 -1111
- package/src/types/core.types.ts +14 -3
- package/src/types/state.types.ts +17 -1
- package/src/wirings/actor-flow/index.ts +0 -3
- package/src/wirings/actor-flow/run-conversation.ts +1 -6
- package/src/wirings/ai-agent/agent-rpc.ts +120 -0
- package/src/wirings/ai-agent/ai-agent-agui.ts +1 -5
- package/src/wirings/ai-agent/ai-agent-finalize.test.ts +186 -0
- package/src/wirings/ai-agent/ai-agent-finalize.ts +197 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +2 -1
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +1 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +62 -39
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +72 -3
- package/src/wirings/ai-agent/ai-agent-model-config.ts +49 -1
- package/src/wirings/ai-agent/ai-agent-prepare.ts +12 -12
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +1 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +82 -2
- package/src/wirings/ai-agent/ai-agent-runner.ts +120 -160
- package/src/wirings/ai-agent/ai-agent-stream-output-hooks.test.ts +353 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +152 -117
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
- package/src/wirings/ai-agent/ai-agent-turn.test.ts +67 -0
- package/src/wirings/ai-agent/ai-agent-turn.ts +122 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +65 -5
- package/src/wirings/ai-agent/index.ts +2 -16
- package/src/wirings/ai-agent/voice-input.ts +1 -6
- package/src/wirings/ai-agent/voice-output.ts +2 -12
- package/src/wirings/ai-scorer/ai-scorer-grade.test.ts +106 -0
- package/src/wirings/ai-scorer/ai-scorer-grade.ts +55 -0
- package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +143 -0
- package/src/wirings/ai-scorer/ai-scorer-judge.ts +120 -0
- package/src/wirings/ai-scorer/ai-scorer-live.test.ts +174 -0
- package/src/wirings/ai-scorer/ai-scorer-live.ts +56 -0
- package/src/wirings/ai-scorer/ai-scorer-registry.ts +63 -0
- package/src/wirings/ai-scorer/ai-scorer-sampling.test.ts +34 -0
- package/src/wirings/ai-scorer/ai-scorer-sampling.ts +36 -0
- package/src/wirings/ai-scorer/ai-scorer-snapshots.test.ts +49 -0
- package/src/wirings/ai-scorer/ai-scorer-snapshots.ts +46 -0
- package/src/wirings/ai-scorer/ai-scorer-worker.test.ts +122 -0
- package/src/wirings/ai-scorer/ai-scorer-worker.ts +69 -0
- package/src/wirings/ai-scorer/ai-scorer.ts +76 -0
- package/src/wirings/ai-scorer/ai-scorer.types.ts +107 -0
- package/src/wirings/ai-scorer/index.ts +24 -0
- package/src/wirings/channel/channel-common.ts +5 -2
- package/src/wirings/channel/channel-handler-shapes.test.ts +72 -0
- package/src/wirings/channel/channel-handler.ts +7 -7
- package/src/wirings/channel/channel-rpc-service.ts +0 -14
- package/src/wirings/channel/channel-rpc.test.ts +25 -4
- package/src/wirings/channel/channel-rpc.types.ts +14 -0
- package/src/wirings/channel/channel-runner.ts +33 -20
- package/src/wirings/channel/channel.types.ts +2 -0
- package/src/wirings/channel/index.ts +1 -20
- package/src/wirings/channel/local/local-channel-runner.test.ts +68 -0
- package/src/wirings/channel/local/local-channel-runner.ts +9 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +2 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +6 -3
- package/src/wirings/cli/channel/cli-channel-runner.ts +3 -1
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +23 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +12 -1
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +4 -1
- package/src/wirings/cli/channel/index.ts +0 -7
- package/src/wirings/cli/cli-runner.test.ts +68 -0
- package/src/wirings/cli/cli-runner.ts +25 -5
- package/src/wirings/cli/cli.types.ts +0 -39
- package/src/wirings/cli/command-parser.test.ts +19 -0
- package/src/wirings/cli/command-parser.ts +17 -1
- package/src/wirings/credential/index.ts +0 -1
- package/src/wirings/gateway/gateway-channel-meta.test.ts +44 -0
- package/src/wirings/gateway/gateway-runner.ts +27 -19
- package/src/wirings/gateway/index.ts +0 -3
- package/src/wirings/http/http-routes.ts +4 -1
- package/src/wirings/http/http-runner.test.ts +66 -0
- package/src/wirings/http/http-runner.ts +21 -28
- package/src/wirings/http/http.types.ts +0 -15
- package/src/wirings/http/index.ts +2 -8
- package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
- package/src/wirings/http/web-request.ts +1 -1
- package/src/wirings/mcp/index.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +181 -0
- package/src/wirings/mcp/mcp-runner.ts +37 -21
- package/src/wirings/persona/index.ts +0 -8
- package/src/wirings/persona/persona-environments.test.ts +14 -3
- package/src/wirings/persona/persona.test.ts +13 -3
- package/src/wirings/persona/validate-personas.ts +5 -1
- package/src/wirings/queue/index.ts +0 -14
- package/src/wirings/queue/queue-runner.ts +1 -1
- package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
- package/src/wirings/rpc/addon-runner.ts +34 -3
- package/src/wirings/rpc/addon-secrets.test.ts +261 -0
- package/src/wirings/rpc/rpc-runner.test.ts +2 -0
- package/src/wirings/rpc/rpc-runner.ts +60 -136
- package/src/wirings/rpc/rpc-types.ts +11 -0
- package/src/wirings/rpc/wire-addon.ts +20 -1
- package/src/wirings/scheduler/index.ts +0 -1
- package/src/wirings/secret/validate-secret-definitions.test.ts +22 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -2
- package/src/wirings/trigger/index.ts +0 -1
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -5
- package/src/wirings/trigger/trigger-runner.ts +7 -5
- package/src/wirings/virtual-user/index.ts +0 -16
- package/src/wirings/virtual-user/run-virtual-user.test.ts +18 -9
- package/src/wirings/virtual-user/run-virtual-user.ts +28 -15
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +4 -1
- package/src/wirings/virtual-user/virtual-user-derive.ts +4 -25
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +7 -2
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +1 -4
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +13 -3
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +117 -4
- package/src/wirings/workflow/feature.ts +7 -4
- package/src/wirings/workflow/graph/graph-node.ts +1 -1
- package/src/wirings/workflow/graph/graph-runner.test.ts +76 -2
- package/src/wirings/workflow/graph/graph-runner.ts +13 -16
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -5
- package/src/wirings/workflow/index.ts +14 -24
- package/src/wirings/workflow/pikku-scenario-service.ts +101 -27
- package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -14
- package/src/wirings/workflow/pikku-workflow-service.ts +214 -743
- package/src/wirings/workflow/scenario-expectations.test.ts +75 -0
- package/src/wirings/workflow/scenario-hooks.test.ts +52 -0
- package/src/wirings/workflow/scenario-step.types.ts +8 -0
- package/src/wirings/workflow/workflow-approval-audit.ts +47 -0
- package/src/wirings/workflow/workflow-approval-policy.test.ts +524 -0
- package/src/wirings/workflow/workflow-approval-policy.ts +68 -0
- package/src/wirings/workflow/workflow-approval.ts +289 -0
- package/src/wirings/workflow/workflow-child-run-session.test.ts +89 -0
- package/src/wirings/workflow/workflow-constants.ts +47 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
- package/src/wirings/workflow/workflow-errors.ts +128 -0
- package/src/wirings/workflow/workflow-inline-authority.test.ts +12 -6
- package/src/wirings/workflow/workflow-meta-resolver.ts +45 -0
- package/src/wirings/workflow/workflow-missing-meta.test.ts +92 -0
- package/src/wirings/workflow/workflow-queue-routing.ts +85 -0
- package/src/wirings/workflow/workflow-queue-wiring.ts +149 -0
- package/src/wirings/workflow/workflow-recovery.ts +162 -0
- package/src/wirings/workflow/workflow-retry-policy.test.ts +1 -1
- package/src/wirings/workflow/workflow-run-authority.test.ts +212 -0
- package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
- package/src/wirings/workflow/workflow-run-ownership.ts +37 -0
- package/src/wirings/workflow/workflow-suspend.ts +61 -0
- package/src/wirings/workflow/workflow.types.ts +7 -9
- package/src/wirings-stay-decoupled.test.ts +127 -0
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/internal.d.ts +0 -3
- package/dist/internal.js +0 -2
- package/dist/middleware/timeout.d.ts +0 -9
- package/dist/middleware/timeout.js +0 -15
- package/dist/pikku-response.d.ts +0 -6
- package/dist/pikku-response.js +0 -6
- package/dist/services/gopass-secrets.d.ts +0 -15
- package/dist/services/gopass-secrets.js +0 -76
- package/dist/services/http-scenario-actors.d.ts +0 -75
- package/dist/services/http-scenario-actors.js +0 -195
- package/dist/services/http-user-flow-actors.d.ts +0 -67
- package/dist/services/http-user-flow-actors.js +0 -193
- package/dist/services/scenario-actors-service.d.ts +0 -127
- package/dist/services/scenario-actors-service.js +0 -40
- package/dist/services/user-flow-actors-service.d.ts +0 -39
- package/dist/wirings/credential/wire-credential.d.ts +0 -48
- package/dist/wirings/credential/wire-credential.js +0 -47
- package/dist/wirings/oauth2/oauth2-client.d.ts +0 -47
- package/dist/wirings/oauth2/oauth2-client.js +0 -263
- package/dist/wirings/oauth2/oauth2-routes.d.ts +0 -35
- package/dist/wirings/oauth2/oauth2-routes.js +0 -146
- package/dist/wirings/scope/wire-scope.d.ts +0 -33
- package/dist/wirings/scope/wire-scope.js +0 -32
- package/dist/wirings/workflow/dsl/index.d.ts +0 -5
- package/dist/wirings/workflow/dsl/index.js +0 -4
- package/dist/wirings/workflow/graph/index.d.ts +0 -5
- package/dist/wirings/workflow/graph/index.js +0 -4
- package/src/internal.ts +0 -10
- /package/dist/{services/user-flow-actors-service.js → wirings/workflow/workflow-run-engine.types.js} +0 -0
|
@@ -13,6 +13,14 @@ import { PikkuError, addError } from '../../errors/error-handler.js'
|
|
|
13
13
|
import type { PikkuRPC, ResolvedFunction } from './rpc-types.js'
|
|
14
14
|
import { parseVersionedId } from '../../version.js'
|
|
15
15
|
import { resolveRemoteAddonToken } from './remote-addon-auth.js'
|
|
16
|
+
import { createAgentRPC } from '../ai-agent/agent-rpc.js'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The session for a wire: read through `getSession` when a runner attached one,
|
|
20
|
+
* otherwise whatever was placed on the wire directly.
|
|
21
|
+
*/
|
|
22
|
+
const resolveWireSession = async (wire: PikkuRawWire) =>
|
|
23
|
+
typeof wire.getSession === 'function' ? await wire.getSession() : wire.session
|
|
16
24
|
|
|
17
25
|
export class RPCNotFoundError extends PikkuError {
|
|
18
26
|
public readonly rpcName: string
|
|
@@ -55,16 +63,6 @@ addError(RemoteAddonRequestError, {
|
|
|
55
63
|
status: 502,
|
|
56
64
|
message: 'Remote addon request failed.',
|
|
57
65
|
})
|
|
58
|
-
import type { AIAgentInput } from '../ai-agent/ai-agent.types.js'
|
|
59
|
-
import type { AIStreamChannel } from '../ai-agent/ai-agent.types.js'
|
|
60
|
-
import type { StreamAIAgentOptions } from '../ai-agent/ai-agent-prepare.js'
|
|
61
|
-
import { runAIAgent, resumeAIAgentSync } from '../ai-agent/ai-agent-runner.js'
|
|
62
|
-
import {
|
|
63
|
-
streamAIAgent,
|
|
64
|
-
resumeAIAgent,
|
|
65
|
-
interruptAIAgent,
|
|
66
|
-
} from '../ai-agent/ai-agent-stream.js'
|
|
67
|
-
import { wrapChannelWithAGUI } from '../ai-agent/ai-agent-agui.js'
|
|
68
66
|
|
|
69
67
|
export const resolveNamespace = (
|
|
70
68
|
namespacedFunction: string
|
|
@@ -209,10 +207,7 @@ export class ContextAwareRPCService {
|
|
|
209
207
|
} catch (e) {
|
|
210
208
|
if (e instanceof RPCNotFoundError) {
|
|
211
209
|
if (this.services.deploymentService) {
|
|
212
|
-
const session =
|
|
213
|
-
this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
214
|
-
? await this.wire.getSession()
|
|
215
|
-
: (this.wire as any).session
|
|
210
|
+
const session = await resolveWireSession(this.wire)
|
|
216
211
|
return this.services.deploymentService.invoke(
|
|
217
212
|
funcName,
|
|
218
213
|
data,
|
|
@@ -289,6 +284,8 @@ export class ContextAwareRPCService {
|
|
|
289
284
|
secretOverrides: resolved.addonConfig?.secretOverrides,
|
|
290
285
|
variableOverrides: resolved.addonConfig?.variableOverrides,
|
|
291
286
|
credentialOverrides: resolved.addonConfig?.credentialOverrides,
|
|
287
|
+
globalSecrets: resolved.addonConfig?.globalSecrets,
|
|
288
|
+
globalCredentials: resolved.addonConfig?.globalCredentials,
|
|
292
289
|
},
|
|
293
290
|
}
|
|
294
291
|
}
|
|
@@ -405,10 +402,7 @@ export class ContextAwareRPCService {
|
|
|
405
402
|
resolved = resolvePikkuFunction(rpcName, this.packageName)
|
|
406
403
|
} catch (e) {
|
|
407
404
|
if (e instanceof RPCNotFoundError && this.services.deploymentService) {
|
|
408
|
-
const session =
|
|
409
|
-
this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
410
|
-
? await this.wire.getSession()
|
|
411
|
-
: (this.wire as any).session
|
|
405
|
+
const session = await resolveWireSession(this.wire)
|
|
412
406
|
return this.services.deploymentService.invoke(
|
|
413
407
|
rpcName,
|
|
414
408
|
data,
|
|
@@ -462,108 +456,15 @@ export class ContextAwareRPCService {
|
|
|
462
456
|
)
|
|
463
457
|
}
|
|
464
458
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
result: result.object ?? result.text,
|
|
475
|
-
usage: result.usage,
|
|
476
|
-
...(result.status === 'suspended' && {
|
|
477
|
-
status: 'suspended' as const,
|
|
478
|
-
pendingApprovals: result.pendingApprovals,
|
|
479
|
-
}),
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
stream: async (
|
|
483
|
-
agentName: string,
|
|
484
|
-
input: {
|
|
485
|
-
message: string
|
|
486
|
-
threadId: string
|
|
487
|
-
resourceId: string
|
|
488
|
-
model?: string
|
|
489
|
-
temperature?: number
|
|
490
|
-
},
|
|
491
|
-
options?: StreamAIAgentOptions
|
|
492
|
-
) => {
|
|
493
|
-
const channel = this.wire.channel as unknown as AIStreamChannel
|
|
494
|
-
if (!channel) throw new Error('No channel available for streaming')
|
|
495
|
-
let currentRunId: string | undefined
|
|
496
|
-
await streamAIAgent(
|
|
497
|
-
agentName,
|
|
498
|
-
input,
|
|
499
|
-
wrapChannelWithAGUI(channel, {
|
|
500
|
-
threadId: input.threadId,
|
|
501
|
-
getRunId: () => currentRunId,
|
|
502
|
-
}),
|
|
503
|
-
{
|
|
504
|
-
sessionService: this.options.sessionService,
|
|
505
|
-
getCredential: this.wire.getCredential?.bind(this.wire),
|
|
506
|
-
},
|
|
507
|
-
undefined,
|
|
508
|
-
{
|
|
509
|
-
...options,
|
|
510
|
-
onRunCreated: (runId) => {
|
|
511
|
-
currentRunId = runId
|
|
512
|
-
options?.onRunCreated?.(runId)
|
|
513
|
-
},
|
|
514
|
-
}
|
|
515
|
-
)
|
|
516
|
-
},
|
|
517
|
-
resume: async (
|
|
518
|
-
runId: string,
|
|
519
|
-
input: { toolCallId: string; approved: boolean },
|
|
520
|
-
options?: StreamAIAgentOptions
|
|
521
|
-
) => {
|
|
522
|
-
const channel = this.wire.channel as unknown as AIStreamChannel
|
|
523
|
-
if (!channel) throw new Error('No channel available for streaming')
|
|
524
|
-
await resumeAIAgent(
|
|
525
|
-
{ runId, ...input },
|
|
526
|
-
wrapChannelWithAGUI(channel, { runId }),
|
|
527
|
-
{
|
|
528
|
-
sessionService: this.options.sessionService,
|
|
529
|
-
getCredential: this.wire.getCredential?.bind(this.wire),
|
|
530
|
-
},
|
|
531
|
-
options
|
|
532
|
-
)
|
|
533
|
-
},
|
|
534
|
-
interrupt: async (
|
|
535
|
-
runId: string,
|
|
536
|
-
reason?: 'speech' | 'user' | 'timeout'
|
|
537
|
-
) => {
|
|
538
|
-
return interruptAIAgent(
|
|
539
|
-
{ runId, ...(reason ? { reason } : {}) },
|
|
540
|
-
{ sessionService: this.options.sessionService }
|
|
541
|
-
)
|
|
542
|
-
},
|
|
543
|
-
approve: async (
|
|
544
|
-
runId: string,
|
|
545
|
-
approvals: { toolCallId: string; approved: boolean }[],
|
|
546
|
-
expectedAgentName?: string
|
|
547
|
-
) => {
|
|
548
|
-
const result = await resumeAIAgentSync(
|
|
549
|
-
runId,
|
|
550
|
-
approvals,
|
|
551
|
-
{
|
|
552
|
-
sessionService: this.options.sessionService,
|
|
553
|
-
},
|
|
554
|
-
expectedAgentName
|
|
555
|
-
)
|
|
556
|
-
return {
|
|
557
|
-
runId: result.runId,
|
|
558
|
-
result: result.object ?? result.text,
|
|
559
|
-
usage: result.usage,
|
|
560
|
-
...(result.status === 'suspended' && {
|
|
561
|
-
status: 'suspended' as const,
|
|
562
|
-
pendingApprovals: result.pendingApprovals,
|
|
563
|
-
}),
|
|
564
|
-
}
|
|
565
|
-
},
|
|
566
|
-
}
|
|
459
|
+
/**
|
|
460
|
+
* The agent facade, built on access.
|
|
461
|
+
*
|
|
462
|
+
* The implementation lives in `ai-agent/agent-rpc.ts` so the agent surface is
|
|
463
|
+
* one file rather than a wing of this one; a getter rather than a field so a
|
|
464
|
+
* request that never touches an agent never builds it.
|
|
465
|
+
*/
|
|
466
|
+
public get agent(): PikkuRPC['agent'] {
|
|
467
|
+
return createAgentRPC(this.wire, this.options)
|
|
567
468
|
}
|
|
568
469
|
|
|
569
470
|
public async remote<In = any, Out = any>(
|
|
@@ -577,10 +478,7 @@ export class ContextAwareRPCService {
|
|
|
577
478
|
)
|
|
578
479
|
}
|
|
579
480
|
|
|
580
|
-
const session =
|
|
581
|
-
this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
582
|
-
? await this.wire.getSession()
|
|
583
|
-
: (this.wire as any).session
|
|
481
|
+
const session = await resolveWireSession(this.wire)
|
|
584
482
|
|
|
585
483
|
return this.services.deploymentService.invoke(
|
|
586
484
|
funcName,
|
|
@@ -619,18 +517,44 @@ export class PikkuRPCService<
|
|
|
619
517
|
options,
|
|
620
518
|
packageName
|
|
621
519
|
)
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
520
|
+
// `TypedRPC` is named by the caller from its generated RPC map. Nothing
|
|
521
|
+
// concrete can satisfy a type the caller has not chosen yet.
|
|
522
|
+
return new ContextRPCView(serviceRPC, depth) as TypedRPC
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* The per-invocation `wire.rpc`.
|
|
528
|
+
*
|
|
529
|
+
* A class rather than an object literal because `agent` has to stay lazy — most
|
|
530
|
+
* requests never touch it — and an accessor declared on an object literal is
|
|
531
|
+
* defined per instance, which drops the literal off V8's fast construction
|
|
532
|
+
* path. Measured at ~1.15µs per request as a literal against ~0.47µs here, on
|
|
533
|
+
* the hot path every request takes.
|
|
534
|
+
*
|
|
535
|
+
* knowledge: decisions/internals/the-per-invocation-rpc-view-is-a-class.md
|
|
536
|
+
*/
|
|
537
|
+
class ContextRPCView {
|
|
538
|
+
public readonly global = false
|
|
539
|
+
public readonly invoke: ContextAwareRPCService['rpc']
|
|
540
|
+
public readonly remote: ContextAwareRPCService['remote']
|
|
541
|
+
public readonly exposed: ContextAwareRPCService['rpcExposed']
|
|
542
|
+
public readonly startWorkflow: ContextAwareRPCService['startWorkflow']
|
|
543
|
+
public readonly rpcWithWire: ContextAwareRPCService['rpcWithWire']
|
|
544
|
+
|
|
545
|
+
constructor(
|
|
546
|
+
private readonly serviceRPC: ContextAwareRPCService,
|
|
547
|
+
public readonly depth: number
|
|
548
|
+
) {
|
|
549
|
+
this.invoke = serviceRPC.rpc.bind(serviceRPC)
|
|
550
|
+
this.remote = serviceRPC.remote.bind(serviceRPC)
|
|
551
|
+
this.exposed = serviceRPC.rpcExposed.bind(serviceRPC)
|
|
552
|
+
this.startWorkflow = serviceRPC.startWorkflow.bind(serviceRPC)
|
|
553
|
+
this.rpcWithWire = serviceRPC.rpcWithWire.bind(serviceRPC)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
get agent() {
|
|
557
|
+
return this.serviceRPC.agent
|
|
634
558
|
}
|
|
635
559
|
}
|
|
636
560
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PikkuRawWire } from '../../types/core.types.js'
|
|
1
2
|
import type { AgentInterruptResult } from '../ai-agent/ai-agent-interrupt.js'
|
|
2
3
|
|
|
3
4
|
export type PikkuRPC<
|
|
@@ -12,6 +13,12 @@ export type PikkuRPC<
|
|
|
12
13
|
invoke: Invoke
|
|
13
14
|
remote: Remote
|
|
14
15
|
exposed: (name: string, data: any) => Promise<any>
|
|
16
|
+
/** Invoke an RPC with explicit wire fields merged over the caller's. */
|
|
17
|
+
rpcWithWire: <In = any, Out = any>(
|
|
18
|
+
rpcName: string,
|
|
19
|
+
data: In,
|
|
20
|
+
wire: PikkuRawWire
|
|
21
|
+
) => Promise<Out>
|
|
15
22
|
startWorkflow: startWorkflow
|
|
16
23
|
agent: {
|
|
17
24
|
run: AgentRun
|
|
@@ -60,6 +67,10 @@ export interface ResolvedFunction {
|
|
|
60
67
|
secretOverrides?: Record<string, string>
|
|
61
68
|
variableOverrides?: Record<string, string>
|
|
62
69
|
credentialOverrides?: Record<string, string>
|
|
70
|
+
/** Set by the consuming app: hand this instance the unscoped `SecretService` */
|
|
71
|
+
globalSecrets?: string
|
|
72
|
+
/** Set by the consuming app: hand this instance the unscoped `CredentialService` */
|
|
73
|
+
globalCredentials?: string
|
|
63
74
|
/** Set by `wireRemoteAddon`: dispatch this namespace's RPCs over HTTP */
|
|
64
75
|
remote?: boolean
|
|
65
76
|
serverUrl?: string | ((services: any) => string | Promise<string>)
|
|
@@ -14,6 +14,19 @@ export type WireAddonConfig = {
|
|
|
14
14
|
secretOverrides?: Record<string, string>
|
|
15
15
|
variableOverrides?: Record<string, string>
|
|
16
16
|
credentialOverrides?: Record<string, string>
|
|
17
|
+
/**
|
|
18
|
+
* Hands this instance the whole `SecretService` instead of one scoped to the
|
|
19
|
+
* secrets it declared. The value is the reason, recorded in the deploy
|
|
20
|
+
* manifest — an addon that names secrets at runtime cannot be scoped, and
|
|
21
|
+
* only the consuming app, never the addon, can grant it.
|
|
22
|
+
*/
|
|
23
|
+
globalSecrets?: string
|
|
24
|
+
/**
|
|
25
|
+
* Hands this instance the whole `CredentialService` instead of one narrowed
|
|
26
|
+
* to the credentials it declared. The value is the reason, recorded in the
|
|
27
|
+
* deploy manifest, and only the consuming app can grant it.
|
|
28
|
+
*/
|
|
29
|
+
globalCredentials?: string
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
export const wireAddon = (config: WireAddonConfig): void => {
|
|
@@ -32,6 +45,10 @@ export const wireAddon = (config: WireAddonConfig): void => {
|
|
|
32
45
|
...(config.credentialOverrides
|
|
33
46
|
? { credentialOverrides: config.credentialOverrides }
|
|
34
47
|
: {}),
|
|
48
|
+
...(config.globalSecrets ? { globalSecrets: config.globalSecrets } : {}),
|
|
49
|
+
...(config.globalCredentials
|
|
50
|
+
? { globalCredentials: config.globalCredentials }
|
|
51
|
+
: {}),
|
|
35
52
|
})
|
|
36
53
|
}
|
|
37
54
|
|
|
@@ -61,7 +78,9 @@ const governingAddonConfigs = (
|
|
|
61
78
|
}
|
|
62
79
|
}
|
|
63
80
|
|
|
64
|
-
return [...addons.values()].filter(
|
|
81
|
+
return [...addons.values()].filter(
|
|
82
|
+
(config) => config?.package === packageName
|
|
83
|
+
)
|
|
65
84
|
}
|
|
66
85
|
|
|
67
86
|
const unionOf = (
|
|
@@ -22,6 +22,28 @@ describe('validateAndBuildSecretDefinitionsMeta', () => {
|
|
|
22
22
|
assert.strictEqual(result['stripe'].displayName, 'Stripe')
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
+
test('carries allowedHosts into the meta so the egress binding is enforced', () => {
|
|
26
|
+
const definitions = [
|
|
27
|
+
{
|
|
28
|
+
name: 'notion',
|
|
29
|
+
displayName: 'Notion',
|
|
30
|
+
secretId: 'NOTION_KEY',
|
|
31
|
+
allowedHosts: ['api.notion.com', '*.notion.com'],
|
|
32
|
+
sourceFile: 'a.ts',
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
const result = validateAndBuildSecretDefinitionsMeta(
|
|
36
|
+
definitions as any,
|
|
37
|
+
new Map()
|
|
38
|
+
)
|
|
39
|
+
// assertSecretAllowedForHost reads allowedHosts off this meta; if it is
|
|
40
|
+
// dropped here the host binding silently permits every host.
|
|
41
|
+
assert.deepStrictEqual(result['notion']!.allowedHosts, [
|
|
42
|
+
'api.notion.com',
|
|
43
|
+
'*.notion.com',
|
|
44
|
+
])
|
|
45
|
+
})
|
|
46
|
+
|
|
25
47
|
test('should allow duplicate secretId with same schema', () => {
|
|
26
48
|
const schemaLookup = new Map([
|
|
27
49
|
['schema1', { variableName: 'Schema', sourceFile: 'types.ts' }],
|
|
@@ -56,8 +56,8 @@ export function validateAndBuildSecretDefinitionsMeta(
|
|
|
56
56
|
schema: def.schema,
|
|
57
57
|
oauth2: def.oauth2,
|
|
58
58
|
rotationPeriod: def.rotationPeriod,
|
|
59
|
-
docsUrl: def.docsUrl,
|
|
60
59
|
allowedHosts: def.allowedHosts,
|
|
60
|
+
docsUrl: def.docsUrl,
|
|
61
61
|
sourceFile: def.sourceFile,
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -75,8 +75,8 @@ export function validateAndBuildSecretDefinitionsMeta(
|
|
|
75
75
|
schema: def.schema,
|
|
76
76
|
oauth2: def.oauth2,
|
|
77
77
|
rotationPeriod: def.rotationPeriod,
|
|
78
|
-
docsUrl: def.docsUrl,
|
|
79
78
|
allowedHosts: def.allowedHosts,
|
|
79
|
+
docsUrl: def.docsUrl,
|
|
80
80
|
sourceFile: def.sourceFile,
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -14,11 +14,6 @@ export type TriggerTarget = {
|
|
|
14
14
|
startNode?: string
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export type TriggerSourceInfo = {
|
|
18
|
-
name: string
|
|
19
|
-
input: unknown
|
|
20
|
-
}
|
|
21
|
-
|
|
22
17
|
export abstract class PikkuTriggerService implements TriggerService {
|
|
23
18
|
protected activeTriggers = new Map<string, TriggerInstance>()
|
|
24
19
|
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getCreateWireServices,
|
|
11
11
|
} from '../../pikku-state.js'
|
|
12
12
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
13
|
+
import type { CorePikkuFunctionConfig } from '../../function/functions.types.js'
|
|
13
14
|
import { PikkuMissingMetaError } from '../../errors/errors.js'
|
|
14
15
|
|
|
15
16
|
export const wireTrigger = (trigger: CoreTrigger) => {
|
|
@@ -22,10 +23,10 @@ export const wireTrigger = (trigger: CoreTrigger) => {
|
|
|
22
23
|
return
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
addFunction(triggerMeta.pikkuFuncId, trigger.func
|
|
26
|
+
addFunction(triggerMeta.pikkuFuncId, trigger.func)
|
|
26
27
|
|
|
27
28
|
const triggers = pikkuState(null, 'trigger', 'triggers')
|
|
28
|
-
triggers.set(trigger.name, trigger
|
|
29
|
+
triggers.set(trigger.name, trigger)
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// knowledge: decisions/internals/trigger-declaration-is-split-from-trigger-source.md
|
|
@@ -45,11 +46,12 @@ export const wireTriggerSource = <TInput = unknown, TOutput = unknown>(
|
|
|
45
46
|
if (triggerSources.has(source.name)) {
|
|
46
47
|
throw new Error(`Trigger source already exists: ${source.name}`)
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
+
// knowledge: decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md
|
|
50
|
+
triggerSources.set(source.name, source as CoreTriggerSource)
|
|
49
51
|
|
|
50
52
|
addFunction(
|
|
51
53
|
triggerSourceMeta.pikkuFuncId,
|
|
52
|
-
source.func as any,
|
|
54
|
+
source.func as CorePikkuFunctionConfig<any, any>,
|
|
53
55
|
triggerSourceMeta.packageName
|
|
54
56
|
)
|
|
55
57
|
}
|
|
@@ -94,7 +96,7 @@ export async function setupTrigger<TInput = unknown, TOutput = unknown>({
|
|
|
94
96
|
singletonServices,
|
|
95
97
|
createWireServices,
|
|
96
98
|
auth: false,
|
|
97
|
-
data: () => input
|
|
99
|
+
data: () => input,
|
|
98
100
|
wire,
|
|
99
101
|
packageName: sourceMeta.packageName || null,
|
|
100
102
|
})
|
|
@@ -18,25 +18,16 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export type {
|
|
20
20
|
ApiCatalogueEntry,
|
|
21
|
-
IntentRecord,
|
|
22
21
|
IntentSource,
|
|
23
|
-
IntentStatus,
|
|
24
|
-
StepRecord,
|
|
25
|
-
VirtualUserAction,
|
|
26
|
-
VirtualUserBudget,
|
|
27
22
|
VirtualUserDisposition,
|
|
28
23
|
VirtualUserFinding,
|
|
29
|
-
VirtualUserFindingKind,
|
|
30
24
|
VirtualUserRunResult,
|
|
31
|
-
VirtualUserTally,
|
|
32
25
|
VirtualUserTarget,
|
|
33
26
|
} from './virtual-user.types.js'
|
|
34
27
|
export { PRODUCTION_DISPOSITION } from './virtual-user.types.js'
|
|
35
28
|
export {
|
|
36
29
|
runVirtualUser,
|
|
37
|
-
rememberIds,
|
|
38
30
|
type RunVirtualUserParams,
|
|
39
|
-
type VirtualUserCallContext,
|
|
40
31
|
} from './run-virtual-user.js'
|
|
41
32
|
export {
|
|
42
33
|
personaScopes,
|
|
@@ -57,26 +48,19 @@ export {
|
|
|
57
48
|
} from './virtual-user-dispositions.js'
|
|
58
49
|
export {
|
|
59
50
|
catalogueClassification,
|
|
60
|
-
catalogueIndex,
|
|
61
51
|
catalogueLookup,
|
|
62
|
-
describeEntry,
|
|
63
52
|
isReadOnly,
|
|
64
53
|
reachableCatalogue,
|
|
65
|
-
renderCatalogue,
|
|
66
54
|
unreachableCatalogue,
|
|
67
55
|
} from './virtual-user-catalogue.js'
|
|
68
56
|
export {
|
|
69
|
-
reachableAgents,
|
|
70
57
|
type AgentReachability,
|
|
71
58
|
type ReachableAgent,
|
|
72
59
|
} from './virtual-user-agents.js'
|
|
73
60
|
export {
|
|
74
61
|
IntentStack,
|
|
75
62
|
intentsForPersona,
|
|
76
|
-
type IntentMove,
|
|
77
|
-
type ScheduledTick,
|
|
78
63
|
} from './virtual-user-intents.js'
|
|
79
|
-
export { createRng, type VirtualUserRng } from './virtual-user-rng.js'
|
|
80
64
|
export {
|
|
81
65
|
deriveCatalogue,
|
|
82
66
|
deriveIntents,
|
|
@@ -41,7 +41,11 @@ const CATALOGUE: ApiCatalogueEntry[] = [
|
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
const INTENTS: IntentSource[] = [
|
|
44
|
-
{
|
|
44
|
+
{
|
|
45
|
+
id: 'onboard',
|
|
46
|
+
title: 'set up your first project',
|
|
47
|
+
steps: ['sign in', 'make a project'],
|
|
48
|
+
},
|
|
45
49
|
]
|
|
46
50
|
|
|
47
51
|
const PERSONA = {
|
|
@@ -84,10 +88,7 @@ const scripted = (
|
|
|
84
88
|
return { llm, turns: () => turn }
|
|
85
89
|
}
|
|
86
90
|
|
|
87
|
-
const respond = <T>(
|
|
88
|
-
status: number,
|
|
89
|
-
body: T
|
|
90
|
-
): ScenarioHttpResponse<T> => ({
|
|
91
|
+
const respond = <T>(status: number, body: T): ScenarioHttpResponse<T> => ({
|
|
91
92
|
status,
|
|
92
93
|
ok: status >= 200 && status < 300,
|
|
93
94
|
body,
|
|
@@ -126,7 +127,12 @@ describe('running a virtual user', () => {
|
|
|
126
127
|
{ kind: 'complete', summary: 'done' },
|
|
127
128
|
])
|
|
128
129
|
|
|
129
|
-
const result = await runVirtualUser({
|
|
130
|
+
const result = await runVirtualUser({
|
|
131
|
+
...base,
|
|
132
|
+
target,
|
|
133
|
+
llm,
|
|
134
|
+
budget: { steps: 3 },
|
|
135
|
+
})
|
|
130
136
|
|
|
131
137
|
// The first attempt cost a step and bought the schema; only the second
|
|
132
138
|
// reached the server.
|
|
@@ -355,7 +361,9 @@ describe('what a virtual user reports', () => {
|
|
|
355
361
|
})
|
|
356
362
|
|
|
357
363
|
test('an app-specific oracle can add what the engine cannot know', async () => {
|
|
358
|
-
const target = recordingTarget(() =>
|
|
364
|
+
const target = recordingTarget(() =>
|
|
365
|
+
respond(200, { orgId: 'someone-else' })
|
|
366
|
+
)
|
|
359
367
|
const { llm } = scripted(walkTo('listProjects'))
|
|
360
368
|
|
|
361
369
|
const result = await runVirtualUser({
|
|
@@ -595,8 +603,9 @@ describe('goals and persona', () => {
|
|
|
595
603
|
test('goals in the user’s own words become intents alongside the derived ones', async () => {
|
|
596
604
|
const seen: string[] = []
|
|
597
605
|
const target = recordingTarget(() => respond(200, {}))
|
|
598
|
-
const { llm } = scripted(
|
|
599
|
-
|
|
606
|
+
const { llm } = scripted(
|
|
607
|
+
[{ kind: 'complete' }, { kind: 'complete' }],
|
|
608
|
+
(_i, m) => seen.push(...m)
|
|
600
609
|
)
|
|
601
610
|
|
|
602
611
|
const result = await runVirtualUser({
|
|
@@ -143,8 +143,12 @@ const msg = (role: AIMessage['role'], content: string): AIMessage => ({
|
|
|
143
143
|
})
|
|
144
144
|
|
|
145
145
|
/** Read a structured result, falling back to parsing JSON out of the text. */
|
|
146
|
-
const readObject = <T>(result: {
|
|
147
|
-
|
|
146
|
+
const readObject = <T>(result: {
|
|
147
|
+
object?: unknown
|
|
148
|
+
text?: string
|
|
149
|
+
}): T | null => {
|
|
150
|
+
if (result.object && typeof result.object === 'object')
|
|
151
|
+
return result.object as T
|
|
148
152
|
if (result.text) {
|
|
149
153
|
try {
|
|
150
154
|
return JSON.parse(result.text) as T
|
|
@@ -201,7 +205,11 @@ export const rememberIds = (
|
|
|
201
205
|
return into
|
|
202
206
|
}
|
|
203
207
|
for (const [key, value] of Object.entries(body)) {
|
|
204
|
-
if (
|
|
208
|
+
if (
|
|
209
|
+
typeof value === 'string' &&
|
|
210
|
+
MEMORABLE.test(key) &&
|
|
211
|
+
value.length < 200
|
|
212
|
+
) {
|
|
205
213
|
into[key] = value
|
|
206
214
|
} else if (typeof value === 'object') {
|
|
207
215
|
rememberIds(value, into, depth + 1)
|
|
@@ -237,7 +245,10 @@ const personaInstructions = (
|
|
|
237
245
|
'',
|
|
238
246
|
agents.length
|
|
239
247
|
? `Assistants you can talk to:\n${agents
|
|
240
|
-
.map(
|
|
248
|
+
.map(
|
|
249
|
+
(agent) =>
|
|
250
|
+
`- ${agent.name}${agent.description ? `: ${agent.description}` : ''}`
|
|
251
|
+
)
|
|
241
252
|
.join('\n')}`
|
|
242
253
|
: '',
|
|
243
254
|
fixtures.length ? `Files you have: ${fixtures.join(', ')}` : '',
|
|
@@ -351,7 +362,10 @@ export const runVirtualUser = async (
|
|
|
351
362
|
stoppedBy = 'budget-duration'
|
|
352
363
|
break
|
|
353
364
|
}
|
|
354
|
-
if (
|
|
365
|
+
if (
|
|
366
|
+
budget?.mutations !== undefined &&
|
|
367
|
+
tally.mutations >= budget.mutations
|
|
368
|
+
) {
|
|
355
369
|
stoppedBy = 'budget-mutations'
|
|
356
370
|
break
|
|
357
371
|
}
|
|
@@ -402,10 +416,7 @@ export const runVirtualUser = async (
|
|
|
402
416
|
)
|
|
403
417
|
)
|
|
404
418
|
}
|
|
405
|
-
//
|
|
406
|
-
// `stale` almost always trusts them, a newcomer has none to trust, and an
|
|
407
|
-
// auditor checks nearly everything — which is the whole difference between
|
|
408
|
-
// those runs, expressed as one roll rather than as prose.
|
|
419
|
+
// knowledge: decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md
|
|
409
420
|
if (Object.keys(memory).length && !rng.chance(profile.reReadRate)) {
|
|
410
421
|
messages.push(
|
|
411
422
|
msg(
|
|
@@ -448,7 +459,9 @@ export const runVirtualUser = async (
|
|
|
448
459
|
|
|
449
460
|
if (!raw || typeof raw.kind !== 'string') {
|
|
450
461
|
steps.push(record)
|
|
451
|
-
messages.push(
|
|
462
|
+
messages.push(
|
|
463
|
+
msg('user', 'That was not a valid action. Choose one action.')
|
|
464
|
+
)
|
|
452
465
|
continue
|
|
453
466
|
}
|
|
454
467
|
|
|
@@ -550,10 +563,7 @@ export const runVirtualUser = async (
|
|
|
550
563
|
continue
|
|
551
564
|
}
|
|
552
565
|
|
|
553
|
-
//
|
|
554
|
-
// read-only disposition is never offered a mutation and an approval-gated
|
|
555
|
-
// endpoint is never offered at all, so `index` is the gate and there is no
|
|
556
|
-
// second one here to drift out of step with it.
|
|
566
|
+
// knowledge: decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md
|
|
557
567
|
const mutating = !isReadOnly(entry)
|
|
558
568
|
|
|
559
569
|
const args = readArgs((action as { args?: unknown }).args)
|
|
@@ -566,7 +576,10 @@ export const runVirtualUser = async (
|
|
|
566
576
|
try {
|
|
567
577
|
response = await target.call(entry.name, args)
|
|
568
578
|
} catch (error) {
|
|
569
|
-
record.findingKinds = [
|
|
579
|
+
record.findingKinds = [
|
|
580
|
+
...(record.findingKinds ?? []),
|
|
581
|
+
'transport-error',
|
|
582
|
+
]
|
|
570
583
|
addFinding({
|
|
571
584
|
kind: 'transport-error',
|
|
572
585
|
detail: `${entry.name} threw: ${(error as Error).message}`,
|
|
@@ -45,7 +45,10 @@ describe('reachableAgents', () => {
|
|
|
45
45
|
|
|
46
46
|
test('carries the description through, which is what the model chooses on', () => {
|
|
47
47
|
const [router] = reachableAgents(AGENTS, ['content:write'])
|
|
48
|
-
assert.equal(
|
|
48
|
+
assert.equal(
|
|
49
|
+
router!.description,
|
|
50
|
+
'Routes requests to the right domain agent'
|
|
51
|
+
)
|
|
49
52
|
})
|
|
50
53
|
|
|
51
54
|
test('omits description rather than passing undefined', () => {
|