@pikku/core 0.12.79 → 0.12.80
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 +161 -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/function/function-runner.js +20 -42
- package/dist/function/functions.types.d.ts +9 -5
- package/dist/index.d.ts +4 -9
- package/dist/index.js +3 -8
- 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 +12 -5
- package/dist/schema.js +35 -1
- package/dist/services/ai-run-state-service.d.ts +7 -1
- package/dist/services/in-memory-ai-run-state-service.d.ts +1 -1
- package/dist/services/in-memory-ai-run-state-service.js +2 -1
- package/dist/services/in-memory-workflow-service.js +2 -0
- 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/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 +226 -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 -1
- package/dist/types/state.types.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-memory.js +3 -1
- package/dist/wirings/ai-agent/ai-agent-prepare.js +3 -9
- package/dist/wirings/ai-agent/ai-agent-runner.js +28 -107
- package/dist/wirings/ai-agent/ai-agent-stream.js +20 -61
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +56 -0
- package/dist/wirings/ai-agent/ai-agent-turn.js +81 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +1 -1
- package/dist/wirings/ai-agent/voice-input.js +1 -6
- package/dist/wirings/ai-agent/voice-output.js +2 -12
- 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/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/cli-runner.js +4 -2
- package/dist/wirings/cli/cli.types.d.ts +0 -8
- package/dist/wirings/cli/command-parser.js +13 -0
- package/dist/wirings/gateway/gateway-runner.js +9 -2
- 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 +6 -13
- package/dist/wirings/http/http.types.d.ts +0 -10
- package/dist/wirings/http/index.d.ts +1 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +0 -7
- package/dist/wirings/mcp/mcp-runner.js +0 -6
- package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
- package/dist/wirings/rpc/rpc-runner.js +53 -86
- package/dist/wirings/rpc/rpc-types.d.ts +3 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -2
- 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/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 +29 -2
- 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 +7 -2
- package/dist/wirings/workflow/index.js +5 -1
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
- package/dist/wirings/workflow/pikku-scenario-service.js +38 -10
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -147
- package/dist/wirings/workflow/pikku-workflow-service.js +71 -493
- package/dist/wirings/workflow/workflow-approval.d.ts +39 -0
- package/dist/wirings/workflow/workflow-approval.js +114 -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-engine.types.js +1 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +16 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +29 -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 +7 -0
- 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/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-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 +38 -26
- 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/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-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 +34 -0
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -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 +7 -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 +13 -3
- package/scripts/generate-api-report.d.mts +1 -0
- package/scripts/generate-api-report.mjs +89 -0
- package/scripts/generate-api-report.mts +218 -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/function/function-runner.test.ts +1 -1
- package/src/function/function-runner.ts +28 -39
- package/src/function/functions.types.ts +15 -9
- package/src/handle-error.ts +1 -1
- package/src/index.ts +3 -22
- 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 +17 -6
- package/src/public-surface.json +578 -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-run-state-service.ts +7 -1
- package/src/services/audit-service.ts +2 -2
- package/src/services/in-memory-ai-run-state-service.ts +3 -2
- package/src/services/in-memory-workflow-service.ts +2 -0
- package/src/services/index.ts +1 -4
- 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/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 +286 -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 +15 -1
- package/src/types/state.types.ts +1 -1
- 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-interrupt.test.ts +2 -1
- package/src/wirings/ai-agent/ai-agent-memory.ts +8 -1
- package/src/wirings/ai-agent/ai-agent-prepare.ts +10 -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 +49 -120
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +36 -63
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
- package/src/wirings/ai-agent/ai-agent-turn.ts +121 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +1 -1
- package/src/wirings/ai-agent/voice-input.ts +1 -6
- package/src/wirings/ai-agent/voice-output.ts +2 -12
- 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/local/local-channel-runner.ts +1 -1
- 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-client-runner.ts +4 -1
- package/src/wirings/cli/cli-runner.ts +7 -4
- 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/gateway/gateway-channel-meta.test.ts +44 -0
- package/src/wirings/gateway/gateway-runner.ts +27 -19
- package/src/wirings/http/http-routes.ts +4 -1
- package/src/wirings/http/http-runner.ts +11 -26
- package/src/wirings/http/http.types.ts +0 -15
- package/src/wirings/http/index.ts +1 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
- package/src/wirings/http/web-request.ts +1 -1
- package/src/wirings/mcp/mcp-runner.ts +2 -16
- 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/queue-runner.ts +1 -1
- package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
- package/src/wirings/rpc/rpc-runner.ts +58 -136
- package/src/wirings/rpc/rpc-types.ts +7 -0
- package/src/wirings/rpc/wire-addon.ts +3 -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/pikku-trigger-service.ts +0 -5
- package/src/wirings/trigger/trigger-runner.ts +7 -5
- 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 +35 -2
- 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 +4 -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 +12 -4
- package/src/wirings/workflow/pikku-scenario-service.ts +54 -25
- package/src/wirings/workflow/pikku-workflow-service.test.ts +2 -2
- package/src/wirings/workflow/pikku-workflow-service.ts +190 -743
- package/src/wirings/workflow/scenario-hooks.test.ts +51 -0
- package/src/wirings/workflow/workflow-approval.ts +185 -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 +215 -0
- package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
- package/src/wirings/workflow/workflow-run-ownership.ts +36 -0
- package/src/wirings/workflow/workflow-suspend.ts +61 -0
- package/src/wirings/workflow/workflow.types.ts +7 -0
- package/src/wirings-stay-decoupled.test.ts +123 -0
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/internal.ts +0 -10
|
@@ -73,10 +73,6 @@ export interface PikkuHTTP<In = unknown> {
|
|
|
73
73
|
response?: PikkuHTTPResponse
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export type RequestHeaders =
|
|
77
|
-
| Record<string, string | string[] | undefined>
|
|
78
|
-
| ((headerName: string) => string | string[] | undefined)
|
|
79
|
-
|
|
80
76
|
export type PikkuQuery<T = Record<string, string | undefined>> = Record<
|
|
81
77
|
string,
|
|
82
78
|
string | T | null | Array<T | null>
|
|
@@ -207,17 +203,6 @@ export type HTTPWiringMeta = CommonWireMeta & {
|
|
|
207
203
|
}
|
|
208
204
|
export type HTTPWiringsMeta = Record<HTTPMethod, Record<string, HTTPWiringMeta>>
|
|
209
205
|
|
|
210
|
-
export type HTTPFunctionsMeta = Array<{
|
|
211
|
-
name: string
|
|
212
|
-
inputs: string[] | null
|
|
213
|
-
outputs: string[] | null
|
|
214
|
-
}>
|
|
215
|
-
|
|
216
|
-
export type HTTPWiringMiddleware = {
|
|
217
|
-
route: string
|
|
218
|
-
middleware: CorePikkuMiddleware[]
|
|
219
|
-
}
|
|
220
|
-
|
|
221
206
|
export interface PikkuHTTPRequest<In = unknown> {
|
|
222
207
|
method(): HTTPMethod
|
|
223
208
|
path(): string
|
|
@@ -6,13 +6,7 @@ export type { PikkuFetchHTTPRequestOptions } from './pikku-fetch-http-request.js
|
|
|
6
6
|
export { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
|
|
7
7
|
export { logRoutes } from './log-http-routes.js'
|
|
8
8
|
|
|
9
|
-
export {
|
|
10
|
-
fetch,
|
|
11
|
-
fetchData,
|
|
12
|
-
wireHTTP,
|
|
13
|
-
addHTTPMiddleware,
|
|
14
|
-
addHTTPPermission,
|
|
15
|
-
} from './http-runner.js'
|
|
9
|
+
export { fetch, fetchData, wireHTTP, addHTTPMiddleware } from './http-runner.js'
|
|
16
10
|
|
|
17
11
|
export { wireHTTPRoutes, defineHTTPRoutes } from './http-routes.js'
|
|
18
12
|
export { toWebRequest, applyWebResponse } from './web-request.js'
|
|
@@ -248,7 +248,7 @@ function valuesAreEquivalent(a: unknown, b: unknown): boolean {
|
|
|
248
248
|
return coerce(a) === coerce(b)
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
function coerce(value: unknown):
|
|
251
|
+
function coerce(value: unknown): unknown {
|
|
252
252
|
if (typeof value === 'boolean' || typeof value === 'number') return value
|
|
253
253
|
if (typeof value === 'string') {
|
|
254
254
|
if (value === 'true') return true
|
|
@@ -256,5 +256,5 @@ function coerce(value: unknown): string | number | boolean {
|
|
|
256
256
|
const num = Number(value)
|
|
257
257
|
return isNaN(num) ? value : num
|
|
258
258
|
}
|
|
259
|
-
return value
|
|
259
|
+
return value
|
|
260
260
|
}
|
|
@@ -40,7 +40,7 @@ export function toWebRequest(req: PikkuHTTPRequest, baseUrl?: string): Request {
|
|
|
40
40
|
if (
|
|
41
41
|
parsed &&
|
|
42
42
|
typeof parsed === 'object' &&
|
|
43
|
-
Object.keys(parsed as
|
|
43
|
+
Object.keys(parsed as object).length > 0
|
|
44
44
|
) {
|
|
45
45
|
let reconstructed: string
|
|
46
46
|
if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
@@ -39,12 +39,6 @@ export type RunMCPEndpointParams<Tools extends string = any> = {
|
|
|
39
39
|
exposeErrors?: boolean
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export type JsonRpcError = {
|
|
43
|
-
code: number
|
|
44
|
-
message: string
|
|
45
|
-
data?: any
|
|
46
|
-
}
|
|
47
|
-
|
|
48
42
|
export const wireMCPResource = <
|
|
49
43
|
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
50
44
|
CorePikkuFunctionSessionless<any, any>
|
|
@@ -60,7 +54,7 @@ export const wireMCPResource = <
|
|
|
60
54
|
)
|
|
61
55
|
return
|
|
62
56
|
}
|
|
63
|
-
addFunction(mcpResourceMeta.pikkuFuncId, mcpResource.func
|
|
57
|
+
addFunction(mcpResourceMeta.pikkuFuncId, mcpResource.func)
|
|
64
58
|
const resources = pikkuState(null, 'mcp', 'resources')
|
|
65
59
|
if (resources.has(mcpResource.uri)) {
|
|
66
60
|
throw new Error(`MCP resource already exists: ${mcpResource.uri}`)
|
|
@@ -83,7 +77,7 @@ export const wireMCPPrompt = <
|
|
|
83
77
|
)
|
|
84
78
|
return
|
|
85
79
|
}
|
|
86
|
-
addFunction(mcpPromptMeta.pikkuFuncId, mcpPrompt.func
|
|
80
|
+
addFunction(mcpPromptMeta.pikkuFuncId, mcpPrompt.func)
|
|
87
81
|
const prompts = pikkuState(null, 'mcp', 'prompts')
|
|
88
82
|
if (prompts.has(mcpPrompt.name)) {
|
|
89
83
|
throw new Error(`MCP prompt already exists: ${mcpPrompt.name}`)
|
|
@@ -293,10 +287,6 @@ async function runMCPPikkuFunc(
|
|
|
293
287
|
}
|
|
294
288
|
}
|
|
295
289
|
|
|
296
|
-
export const getMCPResources = () => {
|
|
297
|
-
return pikkuState(null, 'mcp', 'resources')
|
|
298
|
-
}
|
|
299
|
-
|
|
300
290
|
export const getMCPResourcesMeta = () => {
|
|
301
291
|
return pikkuState(null, 'mcp', 'resourcesMeta')
|
|
302
292
|
}
|
|
@@ -305,10 +295,6 @@ export const getMCPToolsMeta = () => {
|
|
|
305
295
|
return pikkuState(null, 'mcp', 'toolsMeta')
|
|
306
296
|
}
|
|
307
297
|
|
|
308
|
-
export const getMCPPrompts = () => {
|
|
309
|
-
return pikkuState(null, 'mcp', 'prompts')
|
|
310
|
-
}
|
|
311
|
-
|
|
312
298
|
export const getMCPPromptsMeta = () => {
|
|
313
299
|
return pikkuState(null, 'mcp', 'promptsMeta')
|
|
314
300
|
}
|
|
@@ -44,7 +44,11 @@ describe('resolvePersonaEnvironments', () => {
|
|
|
44
44
|
describe('personaEnvironmentErrors', () => {
|
|
45
45
|
test('a persona that declares nothing cannot be wrong', () => {
|
|
46
46
|
assert.deepEqual(
|
|
47
|
-
personaEnvironmentErrors(
|
|
47
|
+
personaEnvironmentErrors(
|
|
48
|
+
'shopper',
|
|
49
|
+
{ disposition: 'careless' },
|
|
50
|
+
ENVIRONMENTS
|
|
51
|
+
),
|
|
48
52
|
[]
|
|
49
53
|
)
|
|
50
54
|
})
|
|
@@ -106,8 +110,15 @@ describe('personaEnvironmentErrors', () => {
|
|
|
106
110
|
})
|
|
107
111
|
|
|
108
112
|
test('with nothing configured it says where environments go', () => {
|
|
109
|
-
const [error] = personaEnvironmentErrors(
|
|
110
|
-
|
|
113
|
+
const [error] = personaEnvironmentErrors(
|
|
114
|
+
'shopper',
|
|
115
|
+
{ environments: ['x'] },
|
|
116
|
+
{}
|
|
117
|
+
)
|
|
118
|
+
assert.match(
|
|
119
|
+
error!,
|
|
120
|
+
/Declare it under 'environments' in pikku\.config\.json/
|
|
121
|
+
)
|
|
111
122
|
})
|
|
112
123
|
})
|
|
113
124
|
|
|
@@ -23,7 +23,10 @@ describe('computed addresses', () => {
|
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
test('without a run id the address is the stable, seedable form', () => {
|
|
26
|
-
assert.equal(
|
|
26
|
+
assert.equal(
|
|
27
|
+
personaEmail('susan', 'mail.example.com'),
|
|
28
|
+
'susan@mail.example.com'
|
|
29
|
+
)
|
|
27
30
|
})
|
|
28
31
|
|
|
29
32
|
test('an id that is not address-shaped is reduced to one', () => {
|
|
@@ -34,7 +37,10 @@ describe('computed addresses', () => {
|
|
|
34
37
|
})
|
|
35
38
|
|
|
36
39
|
test('an id with nothing usable in it is refused rather than guessed at', () => {
|
|
37
|
-
assert.throws(
|
|
40
|
+
assert.throws(
|
|
41
|
+
() => personaEmail('...', 'example.com'),
|
|
42
|
+
/no usable email label/
|
|
43
|
+
)
|
|
38
44
|
})
|
|
39
45
|
|
|
40
46
|
// A synthetic domain was rejected precisely because it makes every
|
|
@@ -97,7 +103,11 @@ describe('verifying roles at sign-in', () => {
|
|
|
97
103
|
})
|
|
98
104
|
|
|
99
105
|
test('order and duplication are not drift', () => {
|
|
100
|
-
const v = verifyPersonaRoles(
|
|
106
|
+
const v = verifyPersonaRoles(
|
|
107
|
+
'yasser',
|
|
108
|
+
['admin', 'buyer'],
|
|
109
|
+
['buyer', 'admin', 'buyer']
|
|
110
|
+
)
|
|
101
111
|
assert.equal(v.ok, true)
|
|
102
112
|
})
|
|
103
113
|
|
|
@@ -58,7 +58,7 @@ export const wireQueueWorker = <
|
|
|
58
58
|
func: queueWorker.func.func,
|
|
59
59
|
auth: queueWorker.func.auth,
|
|
60
60
|
permissions: queueWorker.func.permissions,
|
|
61
|
-
middleware: queueWorker.func.middleware
|
|
61
|
+
middleware: queueWorker.func.middleware,
|
|
62
62
|
tags: queueWorker.func.tags,
|
|
63
63
|
})
|
|
64
64
|
|
|
@@ -8,11 +8,7 @@ import {
|
|
|
8
8
|
clearMiddlewareCache,
|
|
9
9
|
} from '../../middleware-runner.js'
|
|
10
10
|
import { ForbiddenError } from '../../errors/errors.js'
|
|
11
|
-
import {
|
|
12
|
-
resolveAddonAuth,
|
|
13
|
-
resolveAddonTags,
|
|
14
|
-
wireAddon,
|
|
15
|
-
} from './wire-addon.js'
|
|
11
|
+
import { resolveAddonAuth, resolveAddonTags, wireAddon } from './wire-addon.js'
|
|
16
12
|
|
|
17
13
|
const ADDON_PACKAGE = '@addon/console'
|
|
18
14
|
|
|
@@ -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,
|
|
@@ -405,10 +400,7 @@ export class ContextAwareRPCService {
|
|
|
405
400
|
resolved = resolvePikkuFunction(rpcName, this.packageName)
|
|
406
401
|
} catch (e) {
|
|
407
402
|
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
|
|
403
|
+
const session = await resolveWireSession(this.wire)
|
|
412
404
|
return this.services.deploymentService.invoke(
|
|
413
405
|
rpcName,
|
|
414
406
|
data,
|
|
@@ -462,108 +454,15 @@ export class ContextAwareRPCService {
|
|
|
462
454
|
)
|
|
463
455
|
}
|
|
464
456
|
|
|
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
|
-
}
|
|
457
|
+
/**
|
|
458
|
+
* The agent facade, built on access.
|
|
459
|
+
*
|
|
460
|
+
* The implementation lives in `ai-agent/agent-rpc.ts` so the agent surface is
|
|
461
|
+
* one file rather than a wing of this one; a getter rather than a field so a
|
|
462
|
+
* request that never touches an agent never builds it.
|
|
463
|
+
*/
|
|
464
|
+
public get agent(): PikkuRPC['agent'] {
|
|
465
|
+
return createAgentRPC(this.wire, this.options)
|
|
567
466
|
}
|
|
568
467
|
|
|
569
468
|
public async remote<In = any, Out = any>(
|
|
@@ -577,10 +476,7 @@ export class ContextAwareRPCService {
|
|
|
577
476
|
)
|
|
578
477
|
}
|
|
579
478
|
|
|
580
|
-
const session =
|
|
581
|
-
this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
582
|
-
? await this.wire.getSession()
|
|
583
|
-
: (this.wire as any).session
|
|
479
|
+
const session = await resolveWireSession(this.wire)
|
|
584
480
|
|
|
585
481
|
return this.services.deploymentService.invoke(
|
|
586
482
|
funcName,
|
|
@@ -619,18 +515,44 @@ export class PikkuRPCService<
|
|
|
619
515
|
options,
|
|
620
516
|
packageName
|
|
621
517
|
)
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
518
|
+
// `TypedRPC` is named by the caller from its generated RPC map. Nothing
|
|
519
|
+
// concrete can satisfy a type the caller has not chosen yet.
|
|
520
|
+
return new ContextRPCView(serviceRPC, depth) as TypedRPC
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* The per-invocation `wire.rpc`.
|
|
526
|
+
*
|
|
527
|
+
* A class rather than an object literal because `agent` has to stay lazy — most
|
|
528
|
+
* requests never touch it — and an accessor declared on an object literal is
|
|
529
|
+
* defined per instance, which drops the literal off V8's fast construction
|
|
530
|
+
* path. Measured at ~1.15µs per request as a literal against ~0.47µs here, on
|
|
531
|
+
* the hot path every request takes.
|
|
532
|
+
*
|
|
533
|
+
* knowledge: decisions/internals/the-per-invocation-rpc-view-is-a-class.md
|
|
534
|
+
*/
|
|
535
|
+
class ContextRPCView {
|
|
536
|
+
public readonly global = false
|
|
537
|
+
public readonly invoke: ContextAwareRPCService['rpc']
|
|
538
|
+
public readonly remote: ContextAwareRPCService['remote']
|
|
539
|
+
public readonly exposed: ContextAwareRPCService['rpcExposed']
|
|
540
|
+
public readonly startWorkflow: ContextAwareRPCService['startWorkflow']
|
|
541
|
+
public readonly rpcWithWire: ContextAwareRPCService['rpcWithWire']
|
|
542
|
+
|
|
543
|
+
constructor(
|
|
544
|
+
private readonly serviceRPC: ContextAwareRPCService,
|
|
545
|
+
public readonly depth: number
|
|
546
|
+
) {
|
|
547
|
+
this.invoke = serviceRPC.rpc.bind(serviceRPC)
|
|
548
|
+
this.remote = serviceRPC.remote.bind(serviceRPC)
|
|
549
|
+
this.exposed = serviceRPC.rpcExposed.bind(serviceRPC)
|
|
550
|
+
this.startWorkflow = serviceRPC.startWorkflow.bind(serviceRPC)
|
|
551
|
+
this.rpcWithWire = serviceRPC.rpcWithWire.bind(serviceRPC)
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
get agent() {
|
|
555
|
+
return this.serviceRPC.agent
|
|
634
556
|
}
|
|
635
557
|
}
|
|
636
558
|
|
|
@@ -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
|
|
@@ -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
|
})
|
|
@@ -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({
|