@pikku/core 0.12.82 → 0.12.84
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 +101 -0
- package/README.md +1 -1
- package/dist/ecosystem/agent-scorer.d.ts +12 -0
- package/dist/ecosystem/agent-scorer.js +5 -0
- package/dist/ecosystem/agent.d.ts +18 -0
- package/dist/ecosystem/agent.js +6 -0
- package/dist/ecosystem/ai-agent.d.ts +18 -0
- package/dist/ecosystem/ai-agent.js +6 -0
- package/dist/ecosystem/ai-scorer.d.ts +12 -0
- package/dist/ecosystem/ai-scorer.js +5 -0
- package/dist/ecosystem/channel/local.d.ts +1 -0
- package/dist/ecosystem/channel/local.js +1 -0
- package/dist/ecosystem/channel.d.ts +12 -0
- package/dist/ecosystem/channel.js +4 -0
- package/dist/ecosystem/cli/channel.d.ts +16 -0
- package/dist/ecosystem/cli/channel.js +2 -0
- package/dist/ecosystem/cli.d.ts +9 -0
- package/dist/ecosystem/cli.js +2 -0
- package/dist/ecosystem/credential.d.ts +9 -0
- package/dist/ecosystem/credential.js +1 -0
- package/dist/ecosystem/dev.d.ts +8 -0
- package/dist/ecosystem/dev.js +1 -0
- package/dist/ecosystem/function.d.ts +13 -0
- package/dist/ecosystem/function.js +2 -0
- package/dist/ecosystem/gateway.d.ts +1 -0
- package/dist/ecosystem/gateway.js +1 -0
- package/dist/ecosystem/hmac.d.ts +1 -0
- package/dist/ecosystem/hmac.js +1 -0
- package/dist/ecosystem/http.d.ts +11 -0
- package/dist/ecosystem/http.js +3 -0
- package/dist/ecosystem/mcp.d.ts +3 -0
- package/dist/ecosystem/mcp.js +2 -0
- package/dist/ecosystem/middleware.d.ts +17 -0
- package/dist/ecosystem/middleware.js +6 -0
- package/dist/ecosystem/node-host-resolver.d.ts +1 -0
- package/dist/ecosystem/node-host-resolver.js +1 -0
- package/dist/ecosystem/node.d.ts +1 -0
- package/dist/ecosystem/node.js +1 -0
- package/dist/ecosystem/oauth2.d.ts +1 -0
- package/dist/ecosystem/oauth2.js +1 -0
- package/dist/ecosystem/persona.d.ts +15 -0
- package/dist/ecosystem/persona.js +4 -0
- package/dist/ecosystem/queue.d.ts +11 -0
- package/dist/ecosystem/queue.js +2 -0
- package/dist/ecosystem/remote.d.ts +8 -0
- package/dist/ecosystem/remote.js +1 -0
- package/dist/ecosystem/role.d.ts +3 -0
- package/dist/ecosystem/role.js +2 -0
- package/dist/ecosystem/rpc.d.ts +4 -0
- package/dist/ecosystem/rpc.js +2 -0
- package/dist/ecosystem/safe-fetch.d.ts +7 -0
- package/dist/ecosystem/safe-fetch.js +1 -0
- package/dist/ecosystem/scenario.d.ts +15 -0
- package/dist/ecosystem/scenario.js +4 -0
- package/dist/ecosystem/scheduler.d.ts +2 -0
- package/dist/ecosystem/scheduler.js +1 -0
- package/dist/ecosystem/schema.d.ts +1 -0
- package/dist/ecosystem/schema.js +1 -0
- package/dist/ecosystem/scope.d.ts +3 -0
- package/dist/ecosystem/scope.js +2 -0
- package/dist/ecosystem/secret.d.ts +9 -0
- package/dist/ecosystem/secret.js +1 -0
- package/dist/ecosystem/services/istanbul-coverage.d.ts +1 -0
- package/dist/ecosystem/services/istanbul-coverage.js +1 -0
- package/dist/ecosystem/services/local-content-request-handler.d.ts +9 -0
- package/dist/ecosystem/services/local-content-request-handler.js +1 -0
- package/dist/ecosystem/services/local-content.d.ts +1 -0
- package/dist/ecosystem/services/local-content.js +1 -0
- package/dist/ecosystem/services/v8-coverage.d.ts +1 -0
- package/dist/ecosystem/services/v8-coverage.js +1 -0
- package/dist/ecosystem/services.d.ts +28 -0
- package/dist/ecosystem/services.js +6 -0
- package/dist/ecosystem/testing.d.ts +7 -0
- package/dist/ecosystem/testing.js +1 -0
- package/dist/ecosystem/trigger.d.ts +1 -0
- package/dist/ecosystem/trigger.js +1 -0
- package/dist/ecosystem/types.d.ts +9 -0
- package/dist/ecosystem/types.js +5 -0
- package/dist/ecosystem/variable.d.ts +8 -0
- package/dist/ecosystem/variable.js +1 -0
- package/dist/ecosystem/virtual-user.d.ts +21 -0
- package/dist/ecosystem/virtual-user.js +5 -0
- package/dist/ecosystem/workflow.d.ts +18 -0
- package/dist/ecosystem/workflow.js +4 -0
- package/dist/index.d.ts +8 -8
- package/dist/index.js +3 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-cookie.d.ts +1 -1
- package/dist/middleware/cors.d.ts +1 -1
- package/dist/middleware/remote-auth.d.ts +1 -1
- package/dist/middleware/telemetry.d.ts +2 -2
- package/dist/services/agent-run-state-service.d.ts +29 -0
- package/dist/services/agent-run-state-service.js +1 -0
- package/dist/services/agent-runner-service.d.ts +220 -0
- package/dist/services/agent-runner-service.js +1 -0
- package/dist/services/agent-storage-service.d.ts +18 -0
- package/dist/services/agent-storage-service.js +1 -0
- package/dist/services/http-personas.d.ts +1 -1
- package/dist/services/http-personas.js +3 -3
- package/dist/services/in-memory-agent-run-state-service.d.ts +19 -0
- package/dist/services/in-memory-agent-run-state-service.js +54 -0
- package/dist/services/index.d.ts +9 -10
- package/dist/services/index.js +3 -3
- package/dist/services/meta-service.d.ts +5 -4
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/agent-run-service-tests.js +3 -3
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/agent-storage-service-tests.js +302 -0
- package/dist/testing/service-tests.d.ts +4 -4
- package/dist/testing/service-tests.js +4 -4
- package/dist/types/core.types.d.ts +12 -11
- package/dist/types/core.types.js +1 -1
- package/dist/types/state.types.d.ts +11 -6
- package/dist/wirings/actor-flow/run-conversation.d.ts +2 -2
- package/dist/wirings/agent/agent-agui.d.ts +79 -0
- package/dist/wirings/agent/agent-agui.js +327 -0
- package/dist/wirings/agent/agent-finalize.d.ts +58 -0
- package/dist/wirings/agent/agent-finalize.js +138 -0
- package/dist/wirings/agent/agent-helpers.d.ts +35 -0
- package/dist/wirings/agent/agent-helpers.js +47 -0
- package/dist/wirings/agent/agent-interrupt.d.ts +153 -0
- package/dist/wirings/agent/agent-interrupt.js +257 -0
- package/dist/wirings/agent/agent-memory.d.ts +42 -0
- package/dist/wirings/agent/agent-memory.js +333 -0
- package/dist/wirings/agent/agent-model-config.d.ts +16 -0
- package/dist/wirings/agent/agent-model-config.js +51 -0
- package/dist/wirings/agent/agent-prepare.d.ts +117 -0
- package/dist/wirings/agent/agent-prepare.js +728 -0
- package/dist/wirings/agent/agent-registry.d.ts +16 -0
- package/dist/wirings/agent/agent-registry.js +51 -0
- package/dist/wirings/agent/agent-rpc.d.ts +15 -0
- package/dist/wirings/agent/agent-rpc.js +53 -0
- package/dist/wirings/agent/agent-runner.d.ts +7 -0
- package/dist/wirings/agent/agent-runner.js +580 -0
- package/dist/wirings/agent/agent-stream.d.ts +41 -0
- package/dist/wirings/agent/agent-stream.js +1029 -0
- package/dist/wirings/agent/agent-turn.d.ts +57 -0
- package/dist/wirings/agent/agent-turn.js +82 -0
- package/dist/wirings/agent/agent-utils.d.ts +1 -0
- package/dist/wirings/agent/agent-utils.js +1 -0
- package/dist/wirings/agent/agent.types.d.ts +625 -0
- package/dist/wirings/agent/agent.types.js +1 -0
- package/dist/wirings/agent/index.d.ts +12 -0
- package/dist/wirings/agent/index.js +10 -0
- package/dist/wirings/agent/voice-input.d.ts +69 -0
- package/dist/wirings/agent/voice-input.js +150 -0
- package/dist/wirings/agent/voice-output.d.ts +85 -0
- package/dist/wirings/agent/voice-output.js +196 -0
- package/dist/wirings/agent-scorer/agent-scorer-grade.d.ts +26 -0
- package/dist/wirings/agent-scorer/agent-scorer-grade.js +33 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +17 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +92 -0
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +15 -0
- package/dist/wirings/agent-scorer/agent-scorer-live.js +38 -0
- package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +18 -0
- package/dist/wirings/agent-scorer/agent-scorer-registry.js +46 -0
- package/dist/wirings/agent-scorer/agent-scorer-sampling.d.ts +8 -0
- package/dist/wirings/agent-scorer/agent-scorer-sampling.js +31 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +10 -0
- package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +40 -0
- package/dist/wirings/agent-scorer/agent-scorer-worker.d.ts +15 -0
- package/dist/wirings/agent-scorer/agent-scorer-worker.js +60 -0
- package/dist/wirings/agent-scorer/agent-scorer.d.ts +39 -0
- package/dist/wirings/agent-scorer/agent-scorer.js +40 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +90 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.js +4 -0
- package/dist/wirings/agent-scorer/index.d.ts +6 -0
- package/dist/wirings/agent-scorer/index.js +5 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +2 -0
- package/dist/wirings/ai-agent/voice-output.d.ts +1 -2
- package/dist/wirings/channel/channel-rpc.types.d.ts +2 -2
- package/dist/wirings/rpc/addon-runner.d.ts +4 -0
- package/dist/wirings/rpc/addon-runner.js +14 -2
- package/dist/wirings/rpc/rpc-runner.d.ts +1 -1
- package/dist/wirings/rpc/rpc-runner.js +4 -2
- package/dist/wirings/rpc/rpc-types.d.ts +5 -1
- package/dist/wirings/rpc/wire-addon.d.ts +12 -0
- package/dist/wirings/rpc/wire-addon.js +4 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.js +1 -1
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +1 -1
- package/dist/wirings/workflow/feature.d.ts +2 -1
- package/dist/wirings/workflow/index.d.ts +3 -14
- package/dist/wirings/workflow/index.js +0 -8
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +10 -0
- package/dist/wirings/workflow/pikku-scenario-service.js +9 -0
- package/dist/wirings/workflow/run-timeline.d.ts +1 -2
- package/dist/wirings/workflow/scenario.types.d.ts +37 -0
- package/dist/wirings/workflow/scenario.types.js +1 -0
- package/dist/wirings/workflow/workflow.types.d.ts +2 -37
- package/knowledge/decisions/internals/{a-non-streaming-agent-run-registers-with-airunstate-too.md → a-non-streaming-agent-run-registers-with-agentrunstate-too.md} +6 -6
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +1 -1
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +1 -1
- package/knowledge/decisions/internals/{ai-agent-agui-bridge-obeys-the-client-ordering-contract.md → agent-agui-bridge-obeys-the-client-ordering-contract.md} +5 -5
- package/knowledge/decisions/internals/{ai-agent-audio-chunks-carry-the-format-the-provider-returned.md → agent-audio-chunks-carry-the-format-the-provider-returned.md} +2 -2
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +1 -1
- package/knowledge/decisions/internals/{ai-agent-credential-suspensions-hide-the-tool-result.md → agent-credential-suspensions-hide-the-tool-result.md} +2 -2
- package/knowledge/decisions/internals/{ai-agent-delegate-and-supervise-hide-different-text.md → agent-delegate-and-supervise-hide-different-text.md} +4 -4
- package/knowledge/decisions/internals/{ai-agent-llm-tool-arguments-have-nulls-stripped.md → agent-llm-tool-arguments-have-nulls-stripped.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-model-config-stays-a-single-resolution-seam.md → agent-model-config-stays-a-single-resolution-seam.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-onerror-hooks-cannot-change-the-failure.md → agent-onerror-hooks-cannot-change-the-failure.md} +6 -6
- package/knowledge/decisions/internals/{ai-agent-runner-methods-must-keep-their-receiver.md → agent-runner-methods-must-keep-their-receiver.md} +4 -4
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +1 -1
- package/knowledge/decisions/internals/{ai-agent-stream-persistence-is-best-effort.md → agent-stream-persistence-is-best-effort.md} +4 -4
- package/knowledge/decisions/internals/{ai-agent-sub-agents-inherit-the-parent-context-block.md → agent-sub-agents-inherit-the-parent-context-block.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-tool-execute-failures-are-logged-unconditionally.md → agent-tool-execute-failures-are-logged-unconditionally.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-voice-input-transcribes-audio-parts-in-place.md → agent-voice-input-transcribes-audio-parts-in-place.md} +2 -2
- package/knowledge/decisions/internals/{ai-agent-working-memory-is-persisted-only-when-valid.md → agent-working-memory-is-persisted-only-when-valid.md} +2 -2
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +2 -2
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +3 -3
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +2 -2
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +1 -1
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +1 -1
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +1 -1
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +1 -1
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +1 -1
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +5 -5
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +2 -2
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +2 -2
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +1 -1
- package/knowledge/decisions/security/{ai-agent-approval-forwarding-requires-a-symbol-brand.md → agent-approval-forwarding-requires-a-symbol-brand.md} +3 -3
- package/knowledge/decisions/security/{ai-agent-credential-requests-are-symbol-branded.md → agent-credential-requests-are-symbol-branded.md} +4 -4
- package/knowledge/decisions/security/{ai-agent-gate-requires-a-session-only-when-auth-is-true.md → agent-gate-requires-a-session-only-when-auth-is-true.md} +3 -3
- package/knowledge/decisions/security/{ai-agent-ownership-failures-never-echo-the-resource.md → agent-ownership-failures-never-echo-the-resource.md} +2 -2
- package/knowledge/decisions/security/{ai-agent-resume-re-runs-the-authorization-gate.md → agent-resume-re-runs-the-authorization-gate.md} +4 -4
- package/knowledge/decisions/security/{ai-agent-sessionless-deployments-have-no-thread-ownership.md → agent-sessionless-deployments-have-no-thread-ownership.md} +5 -5
- package/knowledge/decisions/security/{ai-agent-thread-ownership-composes-the-session-principal.md → agent-thread-ownership-composes-the-session-principal.md} +2 -2
- package/knowledge/decisions/security/{ai-agent-tool-filtering-reads-the-live-function-config.md → agent-tool-filtering-reads-the-live-function-config.md} +2 -2
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +3 -3
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +3 -3
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +20 -13
- package/knowledge/decisions/security/index.md +1 -2
- package/package.json +4 -4
- package/scripts/generate-api-report.mts +32 -8
- package/src/agent-naming.test.ts +68 -0
- package/src/ecosystem/agent-scorer.ts +24 -0
- package/src/ecosystem/agent.ts +42 -0
- package/src/ecosystem/channel/local.ts +1 -0
- package/src/ecosystem/channel.ts +22 -0
- package/src/ecosystem/cli/channel.ts +25 -0
- package/src/ecosystem/cli.ts +21 -0
- package/src/ecosystem/credential.ts +10 -0
- package/src/ecosystem/dev.ts +12 -0
- package/src/ecosystem/function.ts +28 -0
- package/src/ecosystem/gateway.ts +4 -0
- package/src/ecosystem/hmac.ts +1 -0
- package/src/ecosystem/http.ts +22 -0
- package/src/ecosystem/mcp.ts +17 -0
- package/src/ecosystem/middleware.ts +27 -0
- package/src/ecosystem/node-host-resolver.ts +1 -0
- package/src/ecosystem/node.ts +5 -0
- package/src/ecosystem/oauth2.ts +4 -0
- package/src/ecosystem/persona.ts +30 -0
- package/src/ecosystem/queue.ts +23 -0
- package/src/ecosystem/remote.ts +9 -0
- package/src/ecosystem/role.ts +13 -0
- package/src/ecosystem/rpc.ts +7 -0
- package/src/ecosystem/safe-fetch.ts +8 -0
- package/src/ecosystem/scenario.ts +32 -0
- package/src/ecosystem/scheduler.ts +5 -0
- package/src/ecosystem/schema.ts +1 -0
- package/src/ecosystem/scope.ts +14 -0
- package/src/ecosystem/secret.ts +15 -0
- package/src/ecosystem/services/istanbul-coverage.ts +1 -0
- package/src/ecosystem/services/local-content-request-handler.ts +16 -0
- package/src/ecosystem/services/local-content.ts +1 -0
- package/src/ecosystem/services/v8-coverage.ts +1 -0
- package/src/ecosystem/services.ts +82 -0
- package/src/ecosystem/testing.ts +8 -0
- package/src/ecosystem/trigger.ts +7 -0
- package/src/ecosystem/types.ts +34 -0
- package/src/ecosystem/variable.ts +14 -0
- package/src/ecosystem/virtual-user.ts +48 -0
- package/src/ecosystem/workflow.ts +68 -0
- package/src/index.ts +8 -19
- package/src/pikku-state.ts +3 -3
- package/src/public-surface.json +183 -91
- package/src/public-surface.json.README +20 -2
- package/src/public-surface.test.ts +31 -3
- package/src/services/{ai-run-state-service.ts → agent-run-state-service.ts} +5 -5
- package/src/services/{ai-agent-runner-service.ts → agent-runner-service.ts} +18 -18
- package/src/services/{ai-storage-service.ts → agent-storage-service.ts} +7 -7
- package/src/services/http-personas-converse.test.ts +3 -3
- package/src/services/http-personas.ts +4 -4
- package/src/services/{in-memory-ai-run-state-service.ts → in-memory-agent-run-state-service.ts} +7 -7
- package/src/services/index.ts +13 -24
- package/src/services/meta-service.ts +5 -7
- package/src/testing/service-tests/agent-run-service-tests.ts +4 -4
- package/src/testing/service-tests/{ai-storage-service-tests.ts → agent-storage-service-tests.ts} +8 -8
- package/src/testing/service-tests.ts +10 -8
- package/src/types/core.types.ts +13 -13
- package/src/types/state.types.ts +11 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +2 -2
- package/src/wirings/actor-flow/run-conversation.ts +7 -9
- package/src/wirings/{ai-agent/ai-agent-agui.test.ts → agent/agent-agui.test.ts} +126 -105
- package/src/wirings/{ai-agent/ai-agent-agui.ts → agent/agent-agui.ts} +7 -7
- package/src/wirings/{ai-agent/ai-agent-authorization.test.ts → agent/agent-authorization.test.ts} +6 -6
- package/src/wirings/{ai-agent/ai-agent-finalize.test.ts → agent/agent-finalize.test.ts} +17 -16
- package/src/wirings/{ai-agent/ai-agent-finalize.ts → agent/agent-finalize.ts} +22 -22
- package/src/wirings/{ai-agent/ai-agent-helpers.test.ts → agent/agent-helpers.test.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-helpers.ts → agent/agent-helpers.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-interrupt.test.ts → agent/agent-interrupt.test.ts} +67 -77
- package/src/wirings/{ai-agent/ai-agent-interrupt.ts → agent/agent-interrupt.ts} +5 -5
- package/src/wirings/{ai-agent/ai-agent-memory.test.ts → agent/agent-memory.test.ts} +12 -12
- package/src/wirings/{ai-agent/ai-agent-memory.ts → agent/agent-memory.ts} +36 -36
- package/src/wirings/{ai-agent/ai-agent-model-config.test.ts → agent/agent-model-config.test.ts} +2 -5
- package/src/wirings/{ai-agent/ai-agent-model-config.ts → agent/agent-model-config.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-prepare.test.ts → agent/agent-prepare.test.ts} +18 -18
- package/src/wirings/{ai-agent/ai-agent-prepare.ts → agent/agent-prepare.ts} +54 -51
- package/src/wirings/{ai-agent/ai-agent-registry.test.ts → agent/agent-registry.test.ts} +49 -43
- package/src/wirings/{ai-agent/ai-agent-registry.ts → agent/agent-registry.ts} +14 -14
- package/src/wirings/{ai-agent/ai-agent-resume-authorization.test.ts → agent/agent-resume-authorization.test.ts} +18 -18
- package/src/wirings/{ai-agent → agent}/agent-rpc.ts +16 -20
- package/src/wirings/{ai-agent/ai-agent-runner.test.ts → agent/agent-runner.test.ts} +105 -106
- package/src/wirings/{ai-agent/ai-agent-runner.ts → agent/agent-runner.ts} +90 -80
- package/src/wirings/{ai-agent/ai-agent-stream-output-hooks.test.ts → agent/agent-stream-output-hooks.test.ts} +25 -25
- package/src/wirings/{ai-agent/ai-agent-stream.test.ts → agent/agent-stream.test.ts} +147 -143
- package/src/wirings/{ai-agent/ai-agent-stream.ts → agent/agent-stream.ts} +147 -146
- package/src/wirings/{ai-agent/ai-agent-thread-ownership.test.ts → agent/agent-thread-ownership.test.ts} +24 -28
- package/src/wirings/{ai-agent/ai-agent-turn.test.ts → agent/agent-turn.test.ts} +3 -5
- package/src/wirings/{ai-agent/ai-agent-turn.ts → agent/agent-turn.ts} +7 -7
- package/src/wirings/{ai-agent/ai-agent.types.ts → agent/agent.types.ts} +51 -48
- package/src/wirings/agent/index.ts +56 -0
- package/src/wirings/{ai-agent → agent}/voice-input.test.ts +15 -15
- package/src/wirings/{ai-agent → agent}/voice-input.ts +11 -11
- package/src/wirings/{ai-agent → agent}/voice-output.test.ts +23 -23
- package/src/wirings/{ai-agent → agent}/voice-output.ts +11 -11
- package/src/wirings/{ai-scorer/ai-scorer-grade.test.ts → agent-scorer/agent-scorer-grade.test.ts} +8 -8
- package/src/wirings/{ai-scorer/ai-scorer-grade.ts → agent-scorer/agent-scorer-grade.ts} +9 -9
- package/src/wirings/{ai-scorer/ai-scorer-judge.test.ts → agent-scorer/agent-scorer-judge.test.ts} +11 -14
- package/src/wirings/{ai-scorer/ai-scorer-judge.ts → agent-scorer/agent-scorer-judge.ts} +11 -11
- package/src/wirings/{ai-scorer/ai-scorer-live.test.ts → agent-scorer/agent-scorer-live.test.ts} +11 -11
- package/src/wirings/{ai-scorer/ai-scorer-live.ts → agent-scorer/agent-scorer-live.ts} +3 -3
- package/src/wirings/{ai-scorer/ai-scorer-registry.ts → agent-scorer/agent-scorer-registry.ts} +11 -8
- package/src/wirings/{ai-scorer/ai-scorer-sampling.test.ts → agent-scorer/agent-scorer-sampling.test.ts} +1 -1
- package/src/wirings/{ai-scorer/ai-scorer-snapshots.test.ts → agent-scorer/agent-scorer-snapshots.test.ts} +2 -2
- package/src/wirings/{ai-scorer/ai-scorer-snapshots.ts → agent-scorer/agent-scorer-snapshots.ts} +1 -1
- package/src/wirings/{ai-scorer/ai-scorer-worker.test.ts → agent-scorer/agent-scorer-worker.test.ts} +15 -15
- package/src/wirings/{ai-scorer/ai-scorer-worker.ts → agent-scorer/agent-scorer-worker.ts} +9 -7
- package/src/wirings/{ai-scorer/ai-scorer.ts → agent-scorer/agent-scorer.ts} +7 -7
- package/src/wirings/{ai-scorer/ai-scorer.types.ts → agent-scorer/agent-scorer.types.ts} +6 -6
- package/src/wirings/agent-scorer/index.ts +22 -0
- package/src/wirings/channel/channel-rpc.types.ts +2 -2
- package/src/wirings/rpc/addon-runner.ts +31 -3
- package/src/wirings/rpc/addon-secrets.test.ts +130 -0
- package/src/wirings/rpc/rpc-runner.ts +4 -2
- package/src/wirings/rpc/rpc-types.ts +5 -1
- package/src/wirings/rpc/wire-addon.ts +16 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
- package/src/wirings/virtual-user/run-virtual-user.test.ts +2 -2
- package/src/wirings/virtual-user/run-virtual-user.ts +3 -3
- package/src/wirings/virtual-user/virtual-user-agents.ts +1 -1
- package/src/wirings/workflow/feature.ts +2 -5
- package/src/wirings/workflow/index.ts +1 -49
- package/src/wirings/workflow/pikku-scenario-service.ts +21 -1
- package/src/wirings/workflow/run-timeline.ts +1 -1
- package/src/wirings/workflow/scenario.types.ts +63 -0
- package/src/wirings/workflow/workflow.types.ts +1 -54
- package/src/wirings-stay-decoupled.test.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/src/wirings/ai-agent/index.ts +0 -65
- package/src/wirings/ai-scorer/index.ts +0 -24
- /package/src/wirings/{ai-agent/ai-agent-utils.ts → agent/agent-utils.ts} +0 -0
- /package/src/wirings/{ai-scorer/ai-scorer-sampling.ts → agent-scorer/agent-scorer-sampling.ts} +0 -0
|
@@ -5,12 +5,13 @@ import type { CoreChannel, ChannelsMeta } from '../wirings/channel/channel.types
|
|
|
5
5
|
import type { CLIMeta, CLIProgramState } from '../wirings/cli/cli.types.js';
|
|
6
6
|
import type { HTTPMethod, CoreHTTPFunctionWiring, HTTPWiringsMeta } from '../wirings/http/http.types.js';
|
|
7
7
|
import type { CoreMCPResource, MCPResourceMeta, MCPToolMeta, CoreMCPPrompt, MCPPromptMeta } from '../wirings/mcp/mcp.types.js';
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
8
|
+
import type { CoreAgent, AgentsMeta } from '../wirings/agent/agent.types.js';
|
|
9
|
+
import type { PikkuAgentScorer, ScorerMeta } from '../wirings/agent-scorer/agent-scorer.types.js';
|
|
10
10
|
import type { CoreGateway, GatewaysMeta } from '../wirings/gateway/gateway.types.js';
|
|
11
11
|
import type { CoreQueueWorker, QueueWorkersMeta } from '../wirings/queue/queue.types.js';
|
|
12
12
|
import type { CoreScheduledTask, ScheduledTasksMeta } from '../wirings/scheduler/scheduler.types.js';
|
|
13
|
-
import type { CoreWorkflow,
|
|
13
|
+
import type { CoreWorkflow, WorkflowsRuntimeMeta } from '../wirings/workflow/workflow.types.js';
|
|
14
|
+
import type { CoreFeature } from '../wirings/workflow/scenario.types.js';
|
|
14
15
|
import type { CoreTrigger, CoreTriggerSource, TriggerMeta, TriggerSourceMeta } from '../wirings/trigger/trigger.types.js';
|
|
15
16
|
import type { FunctionsMeta, CorePikkuMiddleware, CorePikkuMiddlewareGroup, CreateConfig, CreateSingletonServices, CreateWireServices, CoreConfig, CoreSingletonServices, CoreServices, CoreUserSession } from './core.types.js';
|
|
16
17
|
import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js';
|
|
@@ -41,6 +42,10 @@ export interface PikkuPackageState {
|
|
|
41
42
|
variableOverrides?: Record<string, string>;
|
|
42
43
|
/** Per-instance name-aliases: logical name the addon reads -> actual project credential name */
|
|
43
44
|
credentialOverrides?: Record<string, string>;
|
|
45
|
+
/** Secrets the host lends this instance, named as the addon reads them */
|
|
46
|
+
secretGrants?: string[];
|
|
47
|
+
/** Credentials the host lends this instance, named as the addon reads them */
|
|
48
|
+
credentialGrants?: string[];
|
|
44
49
|
/** Why this instance gets the whole `SecretService` rather than one scoped to its declared secrets */
|
|
45
50
|
globalSecrets?: string;
|
|
46
51
|
/** Why this instance gets the whole `CredentialService` rather than one scoped to its declared credentials */
|
|
@@ -100,9 +105,9 @@ export interface PikkuPackageState {
|
|
|
100
105
|
promptsMeta: MCPPromptMeta;
|
|
101
106
|
};
|
|
102
107
|
agent: {
|
|
103
|
-
agents: Map<string,
|
|
104
|
-
agentsMeta:
|
|
105
|
-
scorers: Map<string,
|
|
108
|
+
agents: Map<string, CoreAgent>;
|
|
109
|
+
agentsMeta: AgentsMeta;
|
|
110
|
+
scorers: Map<string, PikkuAgentScorer>;
|
|
106
111
|
scorersMeta: ScorerMeta;
|
|
107
112
|
/** Alias -> `provider/model`, from the `models` table in pikku.config.json. */
|
|
108
113
|
modelAliases: Record<string, string>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ActorFlowApprovalPolicy, ActorFlowVerdict, TargetAgentDriver } from './actor-flow.types.js';
|
|
2
2
|
import type { ResolvedPersona } from '../../services/personas-service.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AgentRunnerParams, AgentStepResult } from '../../services/agent-runner-service.js';
|
|
4
4
|
/** The LLM call the actor uses for its own turns/decisions/evaluation. */
|
|
5
|
-
export type ActorLLM = (params:
|
|
5
|
+
export type ActorLLM = (params: AgentRunnerParams) => Promise<AgentStepResult>;
|
|
6
6
|
export interface RunConversationParams {
|
|
7
7
|
/** The person being played — name, job title, personality. */
|
|
8
8
|
persona: ResolvedPersona;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { AgentStreamChannel } from './agent.types.js';
|
|
2
|
+
type AGUIEvent = {
|
|
3
|
+
type: 'TEXT_MESSAGE_START';
|
|
4
|
+
messageId: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'TEXT_MESSAGE_CONTENT';
|
|
7
|
+
messageId: string;
|
|
8
|
+
delta: string;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'TEXT_MESSAGE_END';
|
|
11
|
+
messageId: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'TOOL_CALL_START';
|
|
14
|
+
toolCallId: string;
|
|
15
|
+
toolCallName: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'TOOL_CALL_ARGS';
|
|
18
|
+
toolCallId: string;
|
|
19
|
+
delta: string;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'TOOL_CALL_END';
|
|
22
|
+
toolCallId: string;
|
|
23
|
+
toolCallName: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'TOOL_CALL_RESULT';
|
|
26
|
+
messageId: string;
|
|
27
|
+
toolCallId: string;
|
|
28
|
+
role: 'tool';
|
|
29
|
+
content: string;
|
|
30
|
+
} | {
|
|
31
|
+
type: 'THINKING_START';
|
|
32
|
+
} | {
|
|
33
|
+
type: 'THINKING_TEXT_MESSAGE_START';
|
|
34
|
+
messageId: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'THINKING_TEXT_MESSAGE_CONTENT';
|
|
37
|
+
messageId: string;
|
|
38
|
+
delta: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'THINKING_TEXT_MESSAGE_END';
|
|
41
|
+
messageId: string;
|
|
42
|
+
} | {
|
|
43
|
+
type: 'THINKING_END';
|
|
44
|
+
} | {
|
|
45
|
+
type: 'RUN_STARTED';
|
|
46
|
+
threadId: string;
|
|
47
|
+
runId: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: 'RUN_FINISHED';
|
|
50
|
+
threadId: string;
|
|
51
|
+
runId: string;
|
|
52
|
+
model?: string;
|
|
53
|
+
usage?: {
|
|
54
|
+
promptTokens: number;
|
|
55
|
+
completionTokens: number;
|
|
56
|
+
totalTokens: number;
|
|
57
|
+
};
|
|
58
|
+
} | {
|
|
59
|
+
type: 'RUN_ERROR';
|
|
60
|
+
message: string;
|
|
61
|
+
code?: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'STEP_STARTED';
|
|
64
|
+
stepName: string;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'STEP_FINISHED';
|
|
67
|
+
stepName: string;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'CUSTOM';
|
|
70
|
+
name: string;
|
|
71
|
+
value: unknown;
|
|
72
|
+
};
|
|
73
|
+
export type { AGUIEvent };
|
|
74
|
+
export type AGUIChannelOptions = {
|
|
75
|
+
threadId?: string;
|
|
76
|
+
runId?: string;
|
|
77
|
+
getRunId?: () => string | undefined;
|
|
78
|
+
};
|
|
79
|
+
export declare function wrapChannelWithAGUI(inner: AgentStreamChannel, options?: AGUIChannelOptions): AgentStreamChannel;
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { randomUUID } from './agent-utils.js';
|
|
2
|
+
function resultToString(result) {
|
|
3
|
+
if (typeof result === 'string')
|
|
4
|
+
return result;
|
|
5
|
+
try {
|
|
6
|
+
return JSON.stringify(result, (_key, val) => typeof val === 'bigint' ? val.toString() : val);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return String(result);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function wrapChannelWithAGUI(inner, options) {
|
|
13
|
+
const threadId = options?.threadId ?? randomUUID();
|
|
14
|
+
let runId = options?.runId ?? null;
|
|
15
|
+
function resolveRunId() {
|
|
16
|
+
if (!runId) {
|
|
17
|
+
runId = options?.getRunId?.() ?? randomUUID();
|
|
18
|
+
}
|
|
19
|
+
return runId;
|
|
20
|
+
}
|
|
21
|
+
let textMessageId = null;
|
|
22
|
+
let thinkingMessageId = null;
|
|
23
|
+
let openStepName = null;
|
|
24
|
+
let stepSeq = 0;
|
|
25
|
+
let runStartedSent = false;
|
|
26
|
+
let terminal = false;
|
|
27
|
+
let sawUsage = false;
|
|
28
|
+
let usageModel;
|
|
29
|
+
const usageTotals = { input: 0, output: 0 };
|
|
30
|
+
function send(event) {
|
|
31
|
+
if (!runStartedSent) {
|
|
32
|
+
runStartedSent = true;
|
|
33
|
+
inner.send({
|
|
34
|
+
type: 'RUN_STARTED',
|
|
35
|
+
threadId,
|
|
36
|
+
runId: resolveRunId(),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
inner.send(event);
|
|
40
|
+
}
|
|
41
|
+
function endTextMessage() {
|
|
42
|
+
if (textMessageId) {
|
|
43
|
+
send({ type: 'TEXT_MESSAGE_END', messageId: textMessageId });
|
|
44
|
+
textMessageId = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function endThinkingMessage() {
|
|
48
|
+
if (thinkingMessageId) {
|
|
49
|
+
send({ type: 'THINKING_TEXT_MESSAGE_END', messageId: thinkingMessageId });
|
|
50
|
+
send({ type: 'THINKING_END' });
|
|
51
|
+
thinkingMessageId = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function endStep() {
|
|
55
|
+
if (openStepName) {
|
|
56
|
+
send({ type: 'STEP_FINISHED', stepName: openStepName });
|
|
57
|
+
openStepName = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function ensureTextMessage() {
|
|
61
|
+
if (!textMessageId) {
|
|
62
|
+
textMessageId = randomUUID();
|
|
63
|
+
send({ type: 'TEXT_MESSAGE_START', messageId: textMessageId });
|
|
64
|
+
}
|
|
65
|
+
return textMessageId;
|
|
66
|
+
}
|
|
67
|
+
function ensureThinkingMessage() {
|
|
68
|
+
if (!thinkingMessageId) {
|
|
69
|
+
thinkingMessageId = randomUUID();
|
|
70
|
+
send({ type: 'THINKING_START' });
|
|
71
|
+
send({
|
|
72
|
+
type: 'THINKING_TEXT_MESSAGE_START',
|
|
73
|
+
messageId: thinkingMessageId,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return thinkingMessageId;
|
|
77
|
+
}
|
|
78
|
+
function finishRun() {
|
|
79
|
+
endTextMessage();
|
|
80
|
+
endThinkingMessage();
|
|
81
|
+
endStep();
|
|
82
|
+
send({
|
|
83
|
+
type: 'RUN_FINISHED',
|
|
84
|
+
threadId,
|
|
85
|
+
runId: resolveRunId(),
|
|
86
|
+
...(usageModel ? { model: usageModel } : {}),
|
|
87
|
+
...(sawUsage
|
|
88
|
+
? {
|
|
89
|
+
usage: {
|
|
90
|
+
promptTokens: usageTotals.input,
|
|
91
|
+
completionTokens: usageTotals.output,
|
|
92
|
+
totalTokens: usageTotals.input + usageTotals.output,
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
: {}),
|
|
96
|
+
});
|
|
97
|
+
terminal = true;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
channelId: inner.channelId,
|
|
101
|
+
openingData: inner.openingData,
|
|
102
|
+
get state() {
|
|
103
|
+
return inner.state;
|
|
104
|
+
},
|
|
105
|
+
setState: (s) => inner.setState(s),
|
|
106
|
+
getState: () => inner.getState(),
|
|
107
|
+
clearState: () => inner.clearState(),
|
|
108
|
+
// Delegated: the wrapper is a view over the same connection, so a peer
|
|
109
|
+
// reachable from the channel underneath is reachable from here too.
|
|
110
|
+
remote: (funcName, data) => inner.remote(funcName, data),
|
|
111
|
+
sendBinary: (data) => inner.sendBinary(data),
|
|
112
|
+
close: () => inner.close(),
|
|
113
|
+
send: (event) => {
|
|
114
|
+
if (terminal)
|
|
115
|
+
return;
|
|
116
|
+
switch (event.type) {
|
|
117
|
+
case 'text-delta': {
|
|
118
|
+
endThinkingMessage();
|
|
119
|
+
const id = ensureTextMessage();
|
|
120
|
+
send({
|
|
121
|
+
type: 'TEXT_MESSAGE_CONTENT',
|
|
122
|
+
messageId: id,
|
|
123
|
+
delta: event.text,
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case 'reasoning-delta': {
|
|
128
|
+
endTextMessage();
|
|
129
|
+
const id = ensureThinkingMessage();
|
|
130
|
+
send({
|
|
131
|
+
type: 'THINKING_TEXT_MESSAGE_CONTENT',
|
|
132
|
+
messageId: id,
|
|
133
|
+
delta: event.text,
|
|
134
|
+
});
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case 'tool-call': {
|
|
138
|
+
endTextMessage();
|
|
139
|
+
endThinkingMessage();
|
|
140
|
+
send({
|
|
141
|
+
type: 'TOOL_CALL_START',
|
|
142
|
+
toolCallId: event.toolCallId,
|
|
143
|
+
toolCallName: event.toolName,
|
|
144
|
+
});
|
|
145
|
+
send({
|
|
146
|
+
type: 'TOOL_CALL_ARGS',
|
|
147
|
+
toolCallId: event.toolCallId,
|
|
148
|
+
delta: resultToString(event.args) || '{}',
|
|
149
|
+
});
|
|
150
|
+
send({
|
|
151
|
+
type: 'TOOL_CALL_END',
|
|
152
|
+
toolCallId: event.toolCallId,
|
|
153
|
+
toolCallName: event.toolName,
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 'tool-result': {
|
|
158
|
+
send({
|
|
159
|
+
type: 'TOOL_CALL_RESULT',
|
|
160
|
+
messageId: randomUUID(),
|
|
161
|
+
toolCallId: event.toolCallId,
|
|
162
|
+
role: 'tool',
|
|
163
|
+
content: resultToString(event.result),
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'usage': {
|
|
168
|
+
endTextMessage();
|
|
169
|
+
endThinkingMessage();
|
|
170
|
+
sawUsage = true;
|
|
171
|
+
usageTotals.input += event.tokens.input;
|
|
172
|
+
usageTotals.output += event.tokens.output;
|
|
173
|
+
if (event.model)
|
|
174
|
+
usageModel = event.model;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case 'error': {
|
|
178
|
+
endTextMessage();
|
|
179
|
+
endThinkingMessage();
|
|
180
|
+
endStep();
|
|
181
|
+
send({ type: 'RUN_ERROR', message: event.message });
|
|
182
|
+
terminal = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'done': {
|
|
186
|
+
finishRun();
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'step-start': {
|
|
190
|
+
endTextMessage();
|
|
191
|
+
endThinkingMessage();
|
|
192
|
+
endStep();
|
|
193
|
+
stepSeq += 1;
|
|
194
|
+
openStepName = `${event.agent ?? 'step'}#${stepSeq}`;
|
|
195
|
+
send({ type: 'STEP_STARTED', stepName: openStepName });
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
case 'approval-request': {
|
|
199
|
+
endTextMessage();
|
|
200
|
+
endThinkingMessage();
|
|
201
|
+
send({
|
|
202
|
+
type: 'CUSTOM',
|
|
203
|
+
name: 'pikku:approval-request',
|
|
204
|
+
value: {
|
|
205
|
+
toolCallId: event.toolCallId,
|
|
206
|
+
toolName: event.toolName,
|
|
207
|
+
args: event.args,
|
|
208
|
+
reason: event.reason,
|
|
209
|
+
runId: event.runId,
|
|
210
|
+
agent: event.agent,
|
|
211
|
+
session: event.session,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
case 'credential-request': {
|
|
217
|
+
endTextMessage();
|
|
218
|
+
endThinkingMessage();
|
|
219
|
+
send({
|
|
220
|
+
type: 'CUSTOM',
|
|
221
|
+
name: 'pikku:credential-request',
|
|
222
|
+
value: {
|
|
223
|
+
toolCallId: event.toolCallId,
|
|
224
|
+
toolName: event.toolName,
|
|
225
|
+
args: event.args,
|
|
226
|
+
credentialName: event.credentialName,
|
|
227
|
+
credentialType: event.credentialType,
|
|
228
|
+
connectUrl: event.connectUrl,
|
|
229
|
+
runId: event.runId,
|
|
230
|
+
agent: event.agent,
|
|
231
|
+
session: event.session,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case 'generative-ui': {
|
|
237
|
+
send({
|
|
238
|
+
type: 'CUSTOM',
|
|
239
|
+
name: 'pikku:generative-ui',
|
|
240
|
+
value: { spec: event.spec },
|
|
241
|
+
});
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
case 'data': {
|
|
245
|
+
send({
|
|
246
|
+
type: 'CUSTOM',
|
|
247
|
+
name: 'pikku:data',
|
|
248
|
+
value: { name: event.name, data: event.data },
|
|
249
|
+
});
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case 'agent-call': {
|
|
253
|
+
send({
|
|
254
|
+
type: 'CUSTOM',
|
|
255
|
+
name: 'pikku:agent-call',
|
|
256
|
+
value: {
|
|
257
|
+
agentName: event.agentName,
|
|
258
|
+
session: event.session,
|
|
259
|
+
input: event.input,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case 'agent-result': {
|
|
265
|
+
send({
|
|
266
|
+
type: 'CUSTOM',
|
|
267
|
+
name: 'pikku:agent-result',
|
|
268
|
+
value: {
|
|
269
|
+
agentName: event.agentName,
|
|
270
|
+
session: event.session,
|
|
271
|
+
result: event.result,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 'suspended': {
|
|
277
|
+
send({
|
|
278
|
+
type: 'CUSTOM',
|
|
279
|
+
name: 'pikku:suspended',
|
|
280
|
+
value: { reason: event.reason, missingRpcs: event.missingRpcs },
|
|
281
|
+
});
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case 'interrupted': {
|
|
285
|
+
endTextMessage();
|
|
286
|
+
endThinkingMessage();
|
|
287
|
+
endStep();
|
|
288
|
+
send({
|
|
289
|
+
type: 'CUSTOM',
|
|
290
|
+
name: 'pikku:interrupted',
|
|
291
|
+
value: {
|
|
292
|
+
runId: event.runId,
|
|
293
|
+
text: event.text,
|
|
294
|
+
reason: event.reason,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
// knowledge: decisions/internals/agent-speech-travels-as-a-custom-agui-event.md
|
|
300
|
+
case 'audio-delta': {
|
|
301
|
+
send({
|
|
302
|
+
type: 'CUSTOM',
|
|
303
|
+
name: 'pikku:audio-delta',
|
|
304
|
+
value: {
|
|
305
|
+
data: event.data,
|
|
306
|
+
format: event.format,
|
|
307
|
+
...(event.text === undefined ? {} : { text: event.text }),
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
case 'audio-done': {
|
|
313
|
+
send({ type: 'CUSTOM', name: 'pikku:audio-done', value: {} });
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
case 'transcript': {
|
|
317
|
+
send({
|
|
318
|
+
type: 'CUSTOM',
|
|
319
|
+
name: 'pikku:transcript',
|
|
320
|
+
value: { text: event.text },
|
|
321
|
+
});
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { AgentStep, AgentMessage, PikkuAgentMiddlewareHooks } from './agent.types.js';
|
|
2
|
+
import type { AgentRunStateService } from '../../services/agent-run-state-service.js';
|
|
3
|
+
export type RunUsage = {
|
|
4
|
+
inputTokens: number;
|
|
5
|
+
outputTokens: number;
|
|
6
|
+
model?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Everything a finished run produced, after all middleware has had its say.
|
|
10
|
+
*
|
|
11
|
+
* One snapshot feeds persistence and anything that grades the run, so that what
|
|
12
|
+
* a scorer is shown is exactly what was stored — including the redactions.
|
|
13
|
+
*/
|
|
14
|
+
export type FinalizedRun = {
|
|
15
|
+
runId: string;
|
|
16
|
+
agentName: string;
|
|
17
|
+
threadId: string;
|
|
18
|
+
resourceId?: string;
|
|
19
|
+
/** The prompt the run answered — what a scorer grades the answer against. */
|
|
20
|
+
input: string;
|
|
21
|
+
text: string;
|
|
22
|
+
steps: AgentStep[];
|
|
23
|
+
usage: RunUsage;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The prompt a run answered: the most recent user turn, which is what the model
|
|
27
|
+
* was last asked. On a resumed run the earlier turns are context, not the ask.
|
|
28
|
+
*/
|
|
29
|
+
export declare const lastUserMessageText: (messages: AgentMessage[]) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Run the `modifyOutput` chain over a finished non-streaming run.
|
|
32
|
+
*
|
|
33
|
+
* Reverse order, matching the input chain: the middleware registered first
|
|
34
|
+
* wraps the others, so it sees the output last.
|
|
35
|
+
*/
|
|
36
|
+
export declare const applyOutputMiddleware: (agentMiddlewares: PikkuAgentMiddlewareHooks[], singletonServices: any, input: {
|
|
37
|
+
text: string;
|
|
38
|
+
messages: AgentMessage[];
|
|
39
|
+
steps: AgentStep[];
|
|
40
|
+
usage: {
|
|
41
|
+
inputTokens: number;
|
|
42
|
+
outputTokens: number;
|
|
43
|
+
};
|
|
44
|
+
}) => Promise<{
|
|
45
|
+
text: string;
|
|
46
|
+
messages: AgentMessage[];
|
|
47
|
+
steps: AgentStep[];
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* The one place a run ends successfully.
|
|
51
|
+
*
|
|
52
|
+
* Every path that completes a run — streamed, non-streamed, and resumed after a
|
|
53
|
+
* tool approval — goes through here, so that anything terminal is reachable
|
|
54
|
+
* from all of them and cannot be reordered by a middleware author. Nothing here
|
|
55
|
+
* may rewrite the run: by this point the output middleware has resolved and, on
|
|
56
|
+
* the streaming path, the client already has the reply.
|
|
57
|
+
*/
|
|
58
|
+
export declare const finalizeAgentRun: (agentRunState: AgentRunStateService, run: FinalizedRun) => Promise<void>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { pikkuState } from '../../pikku-state.js';
|
|
2
|
+
import { scoreFinishedRun } from '../agent-scorer/agent-scorer-live.js';
|
|
3
|
+
import { recordScoreSnapshot } from '../agent-scorer/agent-scorer-snapshots.js';
|
|
4
|
+
/**
|
|
5
|
+
* The prompt a run answered: the most recent user turn, which is what the model
|
|
6
|
+
* was last asked. On a resumed run the earlier turns are context, not the ask.
|
|
7
|
+
*/
|
|
8
|
+
export const lastUserMessageText = (messages) => {
|
|
9
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
10
|
+
const message = messages[i];
|
|
11
|
+
if (message?.role !== 'user')
|
|
12
|
+
continue;
|
|
13
|
+
if (typeof message.content === 'string')
|
|
14
|
+
return message.content;
|
|
15
|
+
if (Array.isArray(message.content)) {
|
|
16
|
+
return message.content
|
|
17
|
+
.filter((part) => part.type === 'text')
|
|
18
|
+
.map((part) => part.text)
|
|
19
|
+
.join('\n');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return '';
|
|
23
|
+
};
|
|
24
|
+
const flattenToolCalls = (steps) => steps.flatMap((step) => step.toolCalls ?? []);
|
|
25
|
+
/**
|
|
26
|
+
* Push a rewritten flat tool-call list back onto the steps it came from,
|
|
27
|
+
* preserving the step boundaries. A hook that adds or drops calls would make
|
|
28
|
+
* the boundaries meaningless, so a length change collapses them into the last
|
|
29
|
+
* step rather than silently mis-attributing calls to the wrong step.
|
|
30
|
+
*/
|
|
31
|
+
const distributeToolCalls = (steps, toolCalls) => {
|
|
32
|
+
if (toolCalls.length !== flattenToolCalls(steps).length) {
|
|
33
|
+
return steps.map((step, index) => ({
|
|
34
|
+
...step,
|
|
35
|
+
toolCalls: index === steps.length - 1 ? toolCalls : [],
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
let cursor = 0;
|
|
39
|
+
return steps.map((step) => {
|
|
40
|
+
if (!step.toolCalls)
|
|
41
|
+
return step;
|
|
42
|
+
const next = toolCalls.slice(cursor, cursor + step.toolCalls.length);
|
|
43
|
+
cursor += step.toolCalls.length;
|
|
44
|
+
return { ...step, toolCalls: next };
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Run the `modifyOutput` chain over a finished non-streaming run.
|
|
49
|
+
*
|
|
50
|
+
* Reverse order, matching the input chain: the middleware registered first
|
|
51
|
+
* wraps the others, so it sees the output last.
|
|
52
|
+
*/
|
|
53
|
+
export const applyOutputMiddleware = async (agentMiddlewares, singletonServices, input) => {
|
|
54
|
+
let text = input.text;
|
|
55
|
+
let messages = input.messages;
|
|
56
|
+
let steps = input.steps;
|
|
57
|
+
let toolCalls = flattenToolCalls(steps);
|
|
58
|
+
for (let i = agentMiddlewares.length - 1; i >= 0; i--) {
|
|
59
|
+
const mw = agentMiddlewares[i];
|
|
60
|
+
if (!mw.modifyOutput)
|
|
61
|
+
continue;
|
|
62
|
+
const result = await mw.modifyOutput(singletonServices, {
|
|
63
|
+
text,
|
|
64
|
+
messages,
|
|
65
|
+
usage: {
|
|
66
|
+
inputTokens: input.usage.inputTokens,
|
|
67
|
+
outputTokens: input.usage.outputTokens,
|
|
68
|
+
},
|
|
69
|
+
toolCalls,
|
|
70
|
+
});
|
|
71
|
+
text = result.text;
|
|
72
|
+
messages = result.messages;
|
|
73
|
+
if (result.toolCalls) {
|
|
74
|
+
toolCalls = result.toolCalls;
|
|
75
|
+
steps = distributeToolCalls(steps, toolCalls);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { text, messages, steps };
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* The one place a run ends successfully.
|
|
82
|
+
*
|
|
83
|
+
* Every path that completes a run — streamed, non-streamed, and resumed after a
|
|
84
|
+
* tool approval — goes through here, so that anything terminal is reachable
|
|
85
|
+
* from all of them and cannot be reordered by a middleware author. Nothing here
|
|
86
|
+
* may rewrite the run: by this point the output middleware has resolved and, on
|
|
87
|
+
* the streaming path, the client already has the reply.
|
|
88
|
+
*/
|
|
89
|
+
export const finalizeAgentRun = async (agentRunState, run) => {
|
|
90
|
+
await agentRunState.updateRun(run.runId, {
|
|
91
|
+
status: 'completed',
|
|
92
|
+
...(run.usage.model
|
|
93
|
+
? {
|
|
94
|
+
usage: {
|
|
95
|
+
inputTokens: run.usage.inputTokens,
|
|
96
|
+
outputTokens: run.usage.outputTokens,
|
|
97
|
+
model: run.usage.model,
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
: {}),
|
|
101
|
+
});
|
|
102
|
+
// Read rather than `getSingletonServices()`: a process that never registered
|
|
103
|
+
// them grades nothing, which is not an error at the point a run has already
|
|
104
|
+
// succeeded.
|
|
105
|
+
const services = pikkuState(null, 'package', 'singletonServices');
|
|
106
|
+
if (!services)
|
|
107
|
+
return;
|
|
108
|
+
const snapshot = {
|
|
109
|
+
runId: run.runId,
|
|
110
|
+
agentName: run.agentName,
|
|
111
|
+
threadId: run.threadId,
|
|
112
|
+
...(run.resourceId !== undefined ? { resourceId: run.resourceId } : {}),
|
|
113
|
+
input: run.input,
|
|
114
|
+
output: run.text,
|
|
115
|
+
toolCalls: run.steps.flatMap((step) => (step.toolCalls ?? []).map((call) => ({
|
|
116
|
+
name: call.name,
|
|
117
|
+
args: call.args,
|
|
118
|
+
result: call.result,
|
|
119
|
+
...(call.error !== undefined ? { error: call.error } : {}),
|
|
120
|
+
}))),
|
|
121
|
+
usage: {
|
|
122
|
+
inputTokens: run.usage.inputTokens,
|
|
123
|
+
outputTokens: run.usage.outputTokens,
|
|
124
|
+
...(run.usage.model !== undefined ? { model: run.usage.model } : {}),
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
// The same object a scenario grades, so an asserted score and a sampled one
|
|
128
|
+
// are the same measurement. A no-op unless a dev server turned retention on.
|
|
129
|
+
recordScoreSnapshot(snapshot);
|
|
130
|
+
// Best-effort and last: the client already has its answer, so a grading
|
|
131
|
+
// failure must not surface as a failed run.
|
|
132
|
+
try {
|
|
133
|
+
await scoreFinishedRun(snapshot, services);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
services.logger?.error(`[pikku] Live scoring failed for run ${run.runId}`, error);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentInterruptResult } from './agent-interrupt.js';
|
|
2
|
+
export declare function agent<TAgentMap extends Record<string, {
|
|
3
|
+
output: any;
|
|
4
|
+
}>>(agentName: string & keyof TAgentMap): {
|
|
5
|
+
func: (services: any, data: any, wire: any) => Promise<any>;
|
|
6
|
+
};
|
|
7
|
+
export declare function agentStream<TAgentMap extends Record<string, {
|
|
8
|
+
output: any;
|
|
9
|
+
}>>(agentName?: string & keyof TAgentMap): {
|
|
10
|
+
func: (services: any, data: any, wire: any) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
export declare function agentResume(): {
|
|
13
|
+
func: (services: any, data: {
|
|
14
|
+
runId: string;
|
|
15
|
+
toolCallId: string;
|
|
16
|
+
approved: boolean;
|
|
17
|
+
}, wire: any) => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
export declare function agentInterrupt(): {
|
|
20
|
+
func: (services: any, data: {
|
|
21
|
+
runId: string;
|
|
22
|
+
reason?: 'speech' | 'user' | 'timeout';
|
|
23
|
+
}, wire: any) => Promise<AgentInterruptResult>;
|
|
24
|
+
};
|
|
25
|
+
export declare function agentApprove<TAgentMap extends Record<string, {
|
|
26
|
+
output: any;
|
|
27
|
+
}>>(_agentName: string & keyof TAgentMap): {
|
|
28
|
+
func: (services: any, data: {
|
|
29
|
+
runId: string;
|
|
30
|
+
approvals: {
|
|
31
|
+
toolCallId: string;
|
|
32
|
+
approved: boolean;
|
|
33
|
+
}[];
|
|
34
|
+
}, wire: any) => Promise<any>;
|
|
35
|
+
};
|