@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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { readFileSync, readdirSync } from 'node:fs'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { join, dirname, relative } from 'node:path'
|
|
6
|
+
|
|
7
|
+
const srcRoot = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
const thisFile = fileURLToPath(import.meta.url)
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Names removed from the public surface, each with the entry point that must
|
|
12
|
+
* no longer carry it.
|
|
13
|
+
*
|
|
14
|
+
* They survived as throwing stubs only so the pinned bootstrap CLI could
|
|
15
|
+
* resolve the import; `@pikku/cli@0.12.96` emits none of them, so the stubs
|
|
16
|
+
* went too.
|
|
17
|
+
*/
|
|
18
|
+
const REMOVED = [
|
|
19
|
+
{ name: 'addTagPermission', entry: './middleware/index.js' },
|
|
20
|
+
{ name: 'addHTTPPermission', entry: './wirings/http/index.js' },
|
|
21
|
+
{ name: 'ZodLike', entry: './index.js' },
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
const collectSourceFiles = (directory: string): string[] =>
|
|
25
|
+
readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
26
|
+
const entryPath = join(directory, entry.name)
|
|
27
|
+
if (entry.isDirectory()) {
|
|
28
|
+
return entry.name === 'dist' ? [] : collectSourceFiles(entryPath)
|
|
29
|
+
}
|
|
30
|
+
return /\.ts$/.test(entry.name) ? [entryPath] : []
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('removed legacy exports stay removed', () => {
|
|
34
|
+
for (const { name, entry } of REMOVED) {
|
|
35
|
+
test(`${entry} no longer exports ${name}`, async () => {
|
|
36
|
+
const module = await import(entry)
|
|
37
|
+
assert.equal(
|
|
38
|
+
name in module,
|
|
39
|
+
false,
|
|
40
|
+
`${entry} exports ${name} again; it was removed in #972`
|
|
41
|
+
)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
test('no source file mentions the removed permission wrappers', () => {
|
|
46
|
+
const offenders = collectSourceFiles(srcRoot)
|
|
47
|
+
.filter(
|
|
48
|
+
(file) =>
|
|
49
|
+
file !== thisFile &&
|
|
50
|
+
/\baddTagPermission\b|\baddHTTPPermission\b|\bZodLike\b/.test(
|
|
51
|
+
readFileSync(file, 'utf-8')
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
.map((file) => relative(srcRoot, file))
|
|
55
|
+
|
|
56
|
+
assert.deepEqual(
|
|
57
|
+
offenders,
|
|
58
|
+
[],
|
|
59
|
+
`removed names still referenced in:\n${offenders.join('\n')}`
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
})
|
package/src/schema.test.ts
CHANGED
|
@@ -265,6 +265,84 @@ describe('Schema', () => {
|
|
|
265
265
|
await validateSchema(logger, schemaService, null, {})
|
|
266
266
|
})
|
|
267
267
|
|
|
268
|
+
test('strips undefined-valued properties before validating', async () => {
|
|
269
|
+
addSchema('undefinedProps', {
|
|
270
|
+
properties: { name: { type: 'string' }, count: { type: 'number' } },
|
|
271
|
+
})
|
|
272
|
+
const logger = {
|
|
273
|
+
info: () => {},
|
|
274
|
+
warn: () => {},
|
|
275
|
+
error: () => {},
|
|
276
|
+
debug: () => {},
|
|
277
|
+
} as any
|
|
278
|
+
let seen: any
|
|
279
|
+
const schemaService = {
|
|
280
|
+
compileSchema: async () => {},
|
|
281
|
+
validateSchema: async (_name: string, data: any) => {
|
|
282
|
+
seen = data
|
|
283
|
+
},
|
|
284
|
+
getSchemaNames: () => new Set<string>(),
|
|
285
|
+
}
|
|
286
|
+
await validateSchema(logger, schemaService, 'undefinedProps', {
|
|
287
|
+
name: 'ada',
|
|
288
|
+
count: undefined,
|
|
289
|
+
})
|
|
290
|
+
assert.deepStrictEqual(seen, { name: 'ada' })
|
|
291
|
+
assert.ok(!('count' in seen))
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
test('strips undefined nested in objects and arrays', async () => {
|
|
295
|
+
addSchema('nestedUndefined', { properties: {} })
|
|
296
|
+
const logger = {
|
|
297
|
+
info: () => {},
|
|
298
|
+
warn: () => {},
|
|
299
|
+
error: () => {},
|
|
300
|
+
debug: () => {},
|
|
301
|
+
} as any
|
|
302
|
+
let seen: any
|
|
303
|
+
const schemaService = {
|
|
304
|
+
compileSchema: async () => {},
|
|
305
|
+
validateSchema: async (_name: string, data: any) => {
|
|
306
|
+
seen = data
|
|
307
|
+
},
|
|
308
|
+
getSchemaNames: () => new Set<string>(),
|
|
309
|
+
}
|
|
310
|
+
await validateSchema(logger, schemaService, 'nestedUndefined', {
|
|
311
|
+
nested: { keep: 1, drop: undefined },
|
|
312
|
+
list: [{ keep: 2, drop: undefined }],
|
|
313
|
+
})
|
|
314
|
+
assert.deepStrictEqual(seen, {
|
|
315
|
+
nested: { keep: 1 },
|
|
316
|
+
list: [{ keep: 2 }],
|
|
317
|
+
})
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('leaves Date instances intact while stripping', async () => {
|
|
321
|
+
addSchema('withDate', { properties: {} })
|
|
322
|
+
const logger = {
|
|
323
|
+
info: () => {},
|
|
324
|
+
warn: () => {},
|
|
325
|
+
error: () => {},
|
|
326
|
+
debug: () => {},
|
|
327
|
+
} as any
|
|
328
|
+
const when = new Date('2020-01-01T00:00:00.000Z')
|
|
329
|
+
let seen: any
|
|
330
|
+
const schemaService = {
|
|
331
|
+
compileSchema: async () => {},
|
|
332
|
+
validateSchema: async (_name: string, data: any) => {
|
|
333
|
+
seen = data
|
|
334
|
+
},
|
|
335
|
+
getSchemaNames: () => new Set<string>(),
|
|
336
|
+
}
|
|
337
|
+
await validateSchema(logger, schemaService, 'withDate', {
|
|
338
|
+
when,
|
|
339
|
+
drop: undefined,
|
|
340
|
+
})
|
|
341
|
+
assert.ok(seen.when instanceof Date)
|
|
342
|
+
assert.equal(seen.when.getTime(), when.getTime())
|
|
343
|
+
assert.ok(!('drop' in seen))
|
|
344
|
+
})
|
|
345
|
+
|
|
268
346
|
test('should throw MissingSchemaError when schema not found', async () => {
|
|
269
347
|
const logger = {
|
|
270
348
|
info: () => {},
|
package/src/schema.ts
CHANGED
|
@@ -135,6 +135,41 @@ export const coerceTopLevelDataFromSchema = (
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Drops object properties whose value is literally `undefined`.
|
|
140
|
+
*
|
|
141
|
+
* JSON Schema has no way to describe such a property, and the validator refuses
|
|
142
|
+
* the whole instance rather than reporting it — `{ a: undefined }` throws
|
|
143
|
+
* "Instances of \"undefined\" type are not supported" instead of validating.
|
|
144
|
+
*
|
|
145
|
+
* That matters because whether a payload can contain one depends on how the
|
|
146
|
+
* call travelled. Over HTTP `JSON.stringify` drops these keys before the
|
|
147
|
+
* request is built, so they never arrive. Dispatched in-process — an inline
|
|
148
|
+
* workflow step calling an RPC — the object is handed over as-is, and
|
|
149
|
+
* `{ retries: data.maybeRetries }` with the field omitted by the caller is
|
|
150
|
+
* enough to kill the step. Normalising here makes the two paths agree, and an
|
|
151
|
+
* explicitly-undefined *required* field now reports as the missing property it
|
|
152
|
+
* is rather than as an internal error.
|
|
153
|
+
*
|
|
154
|
+
* Deliberately not a JSON round-trip: `coerceTopLevelDataFromSchema` puts real
|
|
155
|
+
* `Date` instances on the data first, and stringifying would flatten them back
|
|
156
|
+
* to strings the validator has never been given.
|
|
157
|
+
*/
|
|
158
|
+
const stripUndefinedValues = <T>(value: T): T => {
|
|
159
|
+
if (Array.isArray(value)) return value.map(stripUndefinedValues) as T
|
|
160
|
+
if (value === null || typeof value !== 'object') return value
|
|
161
|
+
// Only plain objects: a Date, Map or class instance is data, not a bag of
|
|
162
|
+
// properties to be rewritten.
|
|
163
|
+
const prototype = Object.getPrototypeOf(value)
|
|
164
|
+
if (prototype !== Object.prototype && prototype !== null) return value
|
|
165
|
+
|
|
166
|
+
return Object.fromEntries(
|
|
167
|
+
Object.entries(value)
|
|
168
|
+
.filter(([, entry]) => entry !== undefined)
|
|
169
|
+
.map(([key, entry]) => [key, stripUndefinedValues(entry)])
|
|
170
|
+
) as T
|
|
171
|
+
}
|
|
172
|
+
|
|
138
173
|
export const validateSchema = async (
|
|
139
174
|
logger: Logger,
|
|
140
175
|
schemaService: SchemaService | undefined,
|
|
@@ -164,6 +199,6 @@ export const validateSchema = async (
|
|
|
164
199
|
)
|
|
165
200
|
}
|
|
166
201
|
await schemaService.compileSchema(key, schema)
|
|
167
|
-
await schemaService.validateSchema(key, data ?? {})
|
|
202
|
+
await schemaService.validateSchema(key, stripUndefinedValues(data ?? {}))
|
|
168
203
|
}
|
|
169
204
|
}
|
|
@@ -52,7 +52,18 @@ export type AIAgentStepResult = {
|
|
|
52
52
|
text: string
|
|
53
53
|
object?: unknown
|
|
54
54
|
toolCalls: { toolCallId: string; toolName: string; args: unknown }[]
|
|
55
|
-
toolResults: {
|
|
55
|
+
toolResults: {
|
|
56
|
+
toolCallId: string
|
|
57
|
+
toolName: string
|
|
58
|
+
result: unknown
|
|
59
|
+
/**
|
|
60
|
+
* Set when the tool threw rather than returned. Carried as its own field
|
|
61
|
+
* because `result` is a rendered string by the time anything downstream
|
|
62
|
+
* reads it, and "did this tool fail" is not answerable by looking for an
|
|
63
|
+
* `Error:` prefix in text a tool could legitimately have returned.
|
|
64
|
+
*/
|
|
65
|
+
error?: string
|
|
66
|
+
}[]
|
|
56
67
|
usage: { inputTokens: number; outputTokens: number }
|
|
57
68
|
finishReason: 'stop' | 'tool-calls' | 'length' | 'error' | 'unknown'
|
|
58
69
|
reasoningContent?: string
|
|
@@ -2,19 +2,36 @@ import type {
|
|
|
2
2
|
AgentRunState,
|
|
3
3
|
PendingApproval,
|
|
4
4
|
} from '../wirings/ai-agent/ai-agent.types.js'
|
|
5
|
+
import type { AIRunScore } from '../wirings/ai-scorer/ai-scorer.types.js'
|
|
5
6
|
|
|
6
7
|
export type CreateRunInput = Omit<AgentRunState, 'runId'>
|
|
7
8
|
|
|
9
|
+
export type SaveScoreInput = Omit<AIRunScore, 'createdAt'>
|
|
10
|
+
|
|
8
11
|
export interface AIRunStateService {
|
|
9
12
|
createRun(run: CreateRunInput): Promise<string>
|
|
10
13
|
updateRun(runId: string, updates: Partial<AgentRunState>): Promise<void>
|
|
11
14
|
getRun(runId: string): Promise<AgentRunState | null>
|
|
12
15
|
getRunsByThread(threadId: string): Promise<AgentRunState[]>
|
|
16
|
+
/**
|
|
17
|
+
* Claims an approval: removes it from the run's pending list and records the
|
|
18
|
+
* decision, as one atomic step. Returns whether THIS caller made the claim —
|
|
19
|
+
* concurrent approvals of the same tool call produce exactly one `true`, and
|
|
20
|
+
* only that caller may run the tool.
|
|
21
|
+
*/
|
|
13
22
|
resolveApproval(
|
|
14
23
|
toolCallId: string,
|
|
15
24
|
status: 'approved' | 'denied'
|
|
16
|
-
): Promise<
|
|
25
|
+
): Promise<boolean>
|
|
17
26
|
findRunByToolCallId(
|
|
18
27
|
toolCallId: string
|
|
19
28
|
): Promise<{ run: AgentRunState; approval: PendingApproval } | null>
|
|
29
|
+
/**
|
|
30
|
+
* Record one scorer's grade of a finished run. A run accumulates one row per
|
|
31
|
+
* scorer, and a scorer may grade the same run more than once — a retried job
|
|
32
|
+
* appends rather than replaces, so a re-grade never silently overwrites the
|
|
33
|
+
* grade that was acted on.
|
|
34
|
+
*/
|
|
35
|
+
saveScore(score: SaveScoreInput): Promise<void>
|
|
36
|
+
getScores(runId: string): Promise<AIRunScore[]>
|
|
20
37
|
}
|
|
@@ -150,7 +150,7 @@ class DisabledInvocationAudit implements AuditLog {
|
|
|
150
150
|
if (!this.warned) {
|
|
151
151
|
this.warned = true
|
|
152
152
|
// knowledge: decisions/security/a-dropped-audit-write-is-always-logged.md
|
|
153
|
-
const logger =
|
|
153
|
+
const logger = this.wire.logger ?? this.logger
|
|
154
154
|
logger?.warn?.(
|
|
155
155
|
`audit.write() dropped for '${this.wire.functionId ?? 'unknown function'}' — the function has no audit config (set audit: true on it)`
|
|
156
156
|
)
|
|
@@ -207,7 +207,7 @@ class InvocationAuditLog implements AuditLog {
|
|
|
207
207
|
await this.service.audit(event)
|
|
208
208
|
}
|
|
209
209
|
} catch (error) {
|
|
210
|
-
const logger =
|
|
210
|
+
const logger = this.wire.logger ?? this.logger
|
|
211
211
|
logger?.warn?.('best-effort audit flush failed', error)
|
|
212
212
|
}
|
|
213
213
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AIRunStateService,
|
|
3
3
|
CreateRunInput,
|
|
4
|
+
SaveScoreInput,
|
|
4
5
|
} from './ai-run-state-service.js'
|
|
5
6
|
import type {
|
|
6
7
|
AgentRunState,
|
|
7
8
|
PendingApproval,
|
|
8
9
|
} from '../wirings/ai-agent/ai-agent.types.js'
|
|
10
|
+
import type { AIRunScore } from '../wirings/ai-scorer/ai-scorer.types.js'
|
|
9
11
|
|
|
10
12
|
export class InMemoryAIRunStateService implements AIRunStateService {
|
|
11
13
|
private runs = new Map<string, AgentRunState>()
|
|
14
|
+
private scores = new Map<string, AIRunScore[]>()
|
|
12
15
|
private counter = 0
|
|
13
16
|
|
|
14
17
|
async createRun(run: CreateRunInput): Promise<string> {
|
|
@@ -38,7 +41,7 @@ export class InMemoryAIRunStateService implements AIRunStateService {
|
|
|
38
41
|
async resolveApproval(
|
|
39
42
|
toolCallId: string,
|
|
40
43
|
status: 'approved' | 'denied'
|
|
41
|
-
): Promise<
|
|
44
|
+
): Promise<boolean> {
|
|
42
45
|
for (const run of this.runs.values()) {
|
|
43
46
|
if (run.pendingApprovals) {
|
|
44
47
|
const approval = run.pendingApprovals.find(
|
|
@@ -49,10 +52,11 @@ export class InMemoryAIRunStateService implements AIRunStateService {
|
|
|
49
52
|
(a) => a.toolCallId !== toolCallId
|
|
50
53
|
)
|
|
51
54
|
run.updatedAt = new Date()
|
|
52
|
-
return
|
|
55
|
+
return true
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
}
|
|
59
|
+
return false
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
async findRunByToolCallId(
|
|
@@ -70,4 +74,14 @@ export class InMemoryAIRunStateService implements AIRunStateService {
|
|
|
70
74
|
}
|
|
71
75
|
return null
|
|
72
76
|
}
|
|
77
|
+
|
|
78
|
+
async saveScore(score: SaveScoreInput): Promise<void> {
|
|
79
|
+
const existing = this.scores.get(score.runId) ?? []
|
|
80
|
+
existing.push({ ...score, createdAt: new Date() })
|
|
81
|
+
this.scores.set(score.runId, existing)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async getScores(runId: string): Promise<AIRunScore[]> {
|
|
85
|
+
return [...(this.scores.get(runId) ?? [])]
|
|
86
|
+
}
|
|
73
87
|
}
|
|
@@ -142,6 +142,7 @@ export class InMemoryWorkflowService
|
|
|
142
142
|
const step: StepState & { stepName: string } = {
|
|
143
143
|
stepId,
|
|
144
144
|
status: 'pending',
|
|
145
|
+
rpcName,
|
|
145
146
|
attemptCount: 1,
|
|
146
147
|
retries: stepOptions?.retries,
|
|
147
148
|
retryDelay: stepOptions?.retryDelay,
|
|
@@ -273,6 +274,7 @@ export class InMemoryWorkflowService
|
|
|
273
274
|
const newStep: StepState & { stepName: string } = {
|
|
274
275
|
stepId: newStepId,
|
|
275
276
|
status,
|
|
277
|
+
rpcName: failedStep.rpcName,
|
|
276
278
|
attemptCount: failedStep.attemptCount + 1,
|
|
277
279
|
retries: failedStep.retries,
|
|
278
280
|
retryDelay: failedStep.retryDelay,
|
package/src/services/index.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
export { LogLevel } from './logger.js'
|
|
2
2
|
export { ScopedSecretService } from './scoped-secret-service.js'
|
|
3
|
+
export { ScopedCredentialService } from './scoped-credential-service.js'
|
|
3
4
|
export {
|
|
4
5
|
PikkuSessionService,
|
|
5
6
|
createMiddlewareSessionWireProps,
|
|
6
|
-
createFunctionSessionWireProps,
|
|
7
7
|
} from './user-session-service.js'
|
|
8
8
|
export { TypedSecretService } from './typed-secret-service.js'
|
|
9
9
|
export {
|
|
10
10
|
PikkuCredentialWireService,
|
|
11
|
-
createMiddlewareCredentialWireProps,
|
|
12
|
-
createWireServicesCredentialWireProps,
|
|
13
11
|
} from './credential-wire-service.js'
|
|
14
12
|
export { TypedVariablesService } from './typed-variables-service.js'
|
|
15
13
|
export { LocalSecretService } from './local-secrets.js'
|
|
@@ -39,21 +37,14 @@ export type {
|
|
|
39
37
|
export type {
|
|
40
38
|
ScenarioPersona,
|
|
41
39
|
ResolvedPersona,
|
|
42
|
-
ScenarioPersonaOf,
|
|
43
40
|
ScenarioPersonas,
|
|
44
|
-
ScenarioInvokeOptions,
|
|
45
|
-
ScenarioRpcMap,
|
|
46
41
|
ScenarioHttpResponse,
|
|
47
42
|
} from './personas-service.js'
|
|
48
|
-
//
|
|
49
|
-
// `readScenarioHttpResponse`, `postScenarioJson` — is exported from
|
|
50
|
-
// `@pikku/core/persona`, not from here. Types are free; those are values, and
|
|
51
|
-
// they reach the actor-flow and agent runners, which no production server runs.
|
|
43
|
+
// knowledge: decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md
|
|
52
44
|
export type { HttpPersonasConfig } from './http-personas.js'
|
|
53
45
|
export type { JWTService } from './jwt-service.js'
|
|
54
46
|
export type {
|
|
55
47
|
EmailService,
|
|
56
|
-
EmailTemplateReference,
|
|
57
48
|
SendEmailInput,
|
|
58
49
|
SendEmailResult,
|
|
59
50
|
SendHTMLEmailInput,
|
|
@@ -62,12 +53,10 @@ export type {
|
|
|
62
53
|
} from './email-service.js'
|
|
63
54
|
export {
|
|
64
55
|
DEFAULT_WEBHOOK_RETRIES,
|
|
65
|
-
DEFAULT_WEBHOOK_SIGNATURE_HEADER,
|
|
66
56
|
PIKKU_OUTGOING_WEBHOOK_QUEUE_NAME,
|
|
67
57
|
WebhookService,
|
|
68
58
|
type SendWebhookInput,
|
|
69
59
|
type SendWebhookResult,
|
|
70
|
-
type WebhookAttemptRecord,
|
|
71
60
|
type WebhookAttemptResult,
|
|
72
61
|
type WebhookDeliveryRecord,
|
|
73
62
|
type WebhookDeliveryWithAttempts,
|
|
@@ -97,52 +86,30 @@ export type {
|
|
|
97
86
|
AIAgentRunnerParams,
|
|
98
87
|
AIAgentRunnerResult,
|
|
99
88
|
AIAgentStepResult,
|
|
100
|
-
AIEmbedManyParams,
|
|
101
|
-
AIEmbedManyResult,
|
|
102
|
-
AIEmbedParams,
|
|
103
|
-
AIEmbedResult,
|
|
104
|
-
AIGenerateImageParams,
|
|
105
|
-
AIGenerateImagePrompt,
|
|
106
|
-
AIGenerateImageResult,
|
|
107
|
-
AIGenerateSpeechParams,
|
|
108
|
-
AIGenerateSpeechResult,
|
|
109
|
-
AIProviderOptions,
|
|
110
|
-
AIRerankParams,
|
|
111
|
-
AIRerankResult,
|
|
112
|
-
AITranscriptionParams,
|
|
113
|
-
AITranscriptionResult,
|
|
114
89
|
AIAgentRunnerService,
|
|
115
90
|
} from './ai-agent-runner-service.js'
|
|
116
91
|
export type { AIEmbeddingService } from './ai-embedding-service.js'
|
|
117
92
|
export type {
|
|
118
93
|
CreateRunInput,
|
|
94
|
+
SaveScoreInput,
|
|
119
95
|
AIRunStateService,
|
|
120
96
|
} from './ai-run-state-service.js'
|
|
121
97
|
export type {
|
|
122
|
-
CredentialStatus,
|
|
123
98
|
CredentialMeta,
|
|
124
99
|
} from './typed-secret-service.js'
|
|
125
100
|
export type { CredentialService } from './credential-service.js'
|
|
126
101
|
export { TypedCredentialService } from './typed-credential-service.js'
|
|
127
102
|
export type {
|
|
128
|
-
CredentialStatusInfo,
|
|
129
103
|
CredentialMetaInfo,
|
|
130
104
|
} from './typed-credential-service.js'
|
|
131
|
-
export type {
|
|
105
|
+
export type { VariableMeta } from './typed-variables-service.js'
|
|
132
106
|
export type { MetaService } from './meta-service.js'
|
|
133
107
|
export type { SessionStore } from './session-store.js'
|
|
134
108
|
export type { ScopeService, Role } from './scope-service.js'
|
|
135
|
-
export {
|
|
136
|
-
assertRoleIsMutable,
|
|
137
|
-
assertRoleNameAvailable,
|
|
138
|
-
roleLockReason,
|
|
139
|
-
} from './system-role-guard.js'
|
|
140
109
|
export type { IsSystemRole } from './system-role-guard.js'
|
|
141
110
|
export {
|
|
142
111
|
NoopAuditService,
|
|
143
112
|
createInvocationAudit,
|
|
144
|
-
resolveAuditConfig,
|
|
145
|
-
resolveAuditUserIdentityFromWire,
|
|
146
113
|
} from './audit-service.js'
|
|
147
114
|
export type {
|
|
148
115
|
AuditConfig,
|
|
@@ -150,10 +117,7 @@ export type {
|
|
|
150
117
|
AuditEvent,
|
|
151
118
|
AuditEventBatch,
|
|
152
119
|
AuditLog,
|
|
153
|
-
AuditLogWriteInput,
|
|
154
|
-
AuditOutcome,
|
|
155
120
|
AuditService,
|
|
156
|
-
AuditSource,
|
|
157
121
|
AuditUserIdentity,
|
|
158
122
|
ResolvedAuditConfig,
|
|
159
123
|
} from './audit-service.js'
|
|
@@ -177,17 +141,10 @@ export type {
|
|
|
177
141
|
AgentMeta,
|
|
178
142
|
EmailsMeta,
|
|
179
143
|
EmailTemplateMeta,
|
|
180
|
-
EmailTemplateLocaleMeta,
|
|
181
|
-
EmailTemplateAssets,
|
|
182
144
|
} from './meta-service.js'
|
|
183
145
|
export type {
|
|
184
146
|
CoverageService,
|
|
185
|
-
CoverageSnapshot,
|
|
186
|
-
LineHits,
|
|
187
147
|
ScriptCoverage,
|
|
188
|
-
FunctionCoverage,
|
|
189
|
-
CoverageRange,
|
|
190
|
-
CoverageStatus,
|
|
191
148
|
FunctionCoverageEntry,
|
|
192
149
|
FunctionCoverageReport,
|
|
193
150
|
CoverageFunctionMeta,
|
|
@@ -81,11 +81,17 @@ describe('createLocalContentRequestHandler', () => {
|
|
|
81
81
|
test('refuses an upload whose key escapes the content directory', async () => {
|
|
82
82
|
writeFileSync(join(tmpDir, '..', 'pikku-handler-secret.txt'), 'secret')
|
|
83
83
|
try {
|
|
84
|
+
// Signed for the escaping path itself, so it clears the signature gate
|
|
85
|
+
// and the path-escape guard is what rejects it.
|
|
86
|
+
const signed = await content.signURL({
|
|
87
|
+
url: '/upload/bucket/..%2f..%2fpikku-handler-secret.txt',
|
|
88
|
+
dateLessThan: new Date(Date.now() + 60_000),
|
|
89
|
+
} as any)
|
|
84
90
|
const response = await handler(
|
|
85
|
-
new Request(
|
|
86
|
-
'
|
|
87
|
-
|
|
88
|
-
)
|
|
91
|
+
new Request(`http://localhost${signed}`, {
|
|
92
|
+
method: 'PUT',
|
|
93
|
+
body: 'overwritten',
|
|
94
|
+
})
|
|
89
95
|
)
|
|
90
96
|
assert.equal(response?.status, 400)
|
|
91
97
|
assert.equal(
|
|
@@ -104,6 +110,33 @@ describe('createLocalContentRequestHandler', () => {
|
|
|
104
110
|
assert.equal(response?.status, 400)
|
|
105
111
|
})
|
|
106
112
|
|
|
113
|
+
test('refuses an unsigned PUT to the upload prefix', async () => {
|
|
114
|
+
const put = await handler(
|
|
115
|
+
new Request('http://localhost/upload/bucket/evil.bin', {
|
|
116
|
+
method: 'PUT',
|
|
117
|
+
body: 'attacker-controlled',
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
assert.equal(put?.status, 403, 'an upload URL must be signed like a read')
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('refuses a PUT whose signature was minted for a different key', async () => {
|
|
124
|
+
const { uploadUrl } = await content.getUploadURL({
|
|
125
|
+
bucket: 'bucket',
|
|
126
|
+
fileKey: 'legit/one.bin',
|
|
127
|
+
contentType: 'application/octet-stream',
|
|
128
|
+
} as any)
|
|
129
|
+
const query = uploadUrl.slice(uploadUrl.indexOf('?'))
|
|
130
|
+
// Same signature, a different target path.
|
|
131
|
+
const put = await handler(
|
|
132
|
+
new Request(`http://localhost/upload/bucket/other.bin${query}`, {
|
|
133
|
+
method: 'PUT',
|
|
134
|
+
body: 'payload',
|
|
135
|
+
})
|
|
136
|
+
)
|
|
137
|
+
assert.equal(put?.status, 403)
|
|
138
|
+
})
|
|
139
|
+
|
|
107
140
|
test('round-trips an upload and a signed read', async () => {
|
|
108
141
|
const { uploadUrl } = await content.getUploadURL({
|
|
109
142
|
bucket: 'bucket',
|
|
@@ -188,8 +221,13 @@ describe('createLocalContentRequestHandler', () => {
|
|
|
188
221
|
})
|
|
189
222
|
|
|
190
223
|
test('rejects a body over the size limit without writing it', async () => {
|
|
224
|
+
const { uploadUrl } = await content.getUploadURL({
|
|
225
|
+
bucket: 'bucket',
|
|
226
|
+
fileKey: 'big.bin',
|
|
227
|
+
contentType: 'application/octet-stream',
|
|
228
|
+
} as any)
|
|
191
229
|
const response = await handler(
|
|
192
|
-
new Request(
|
|
230
|
+
new Request(`http://localhost${uploadUrl}`, {
|
|
193
231
|
method: 'PUT',
|
|
194
232
|
body: Buffer.alloc(1024 * 1024 + 1),
|
|
195
233
|
})
|