@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
|
@@ -1,40 +1,37 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
AgentStreamChannel,
|
|
3
|
+
AgentStreamEvent,
|
|
4
|
+
AgentStep,
|
|
5
|
+
AgentMessage,
|
|
6
|
+
AgentToolCall,
|
|
7
|
+
AgentToolResult,
|
|
8
|
+
PikkuAgentMiddlewareHooks,
|
|
9
9
|
AgentRunState,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from './
|
|
13
|
-
import {
|
|
14
|
-
finalizeAgentRun,
|
|
15
|
-
lastUserMessageText,
|
|
16
|
-
} from './ai-agent-finalize.js'
|
|
10
|
+
CoreAgent,
|
|
11
|
+
AgentMemoryConfig,
|
|
12
|
+
} from './agent.types.js'
|
|
13
|
+
import { finalizeAgentRun, lastUserMessageText } from './agent-finalize.js'
|
|
17
14
|
import { pikkuState, getSingletonServices } from '../../pikku-state.js'
|
|
18
|
-
import { applyInputMiddleware } from './
|
|
15
|
+
import { applyInputMiddleware } from './agent-turn.js'
|
|
19
16
|
import { AIProviderNotConfiguredError } from '../../errors/errors.js'
|
|
20
|
-
import { randomUUID } from './
|
|
17
|
+
import { randomUUID } from './agent-utils.js'
|
|
21
18
|
import { SPOKEN_TRANSCRIPT } from './voice-input.js'
|
|
22
19
|
import {
|
|
23
20
|
combineChannelMiddleware,
|
|
24
21
|
wrapChannelWithMiddleware,
|
|
25
22
|
} from '../channel/channel-middleware-runner.js'
|
|
26
|
-
import type {
|
|
23
|
+
import type { AgentStorageService } from '../../services/agent-storage-service.js'
|
|
27
24
|
import type {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} from '../../services/
|
|
25
|
+
AgentRunnerParams,
|
|
26
|
+
AgentStepResult,
|
|
27
|
+
} from '../../services/agent-runner-service.js'
|
|
31
28
|
|
|
32
29
|
import {
|
|
33
30
|
resolveMemoryServices,
|
|
34
31
|
loadContextMessages,
|
|
35
32
|
trimMessages,
|
|
36
33
|
getWorkingMemoryMiddleware,
|
|
37
|
-
} from './
|
|
34
|
+
} from './agent-memory.js'
|
|
38
35
|
import {
|
|
39
36
|
prepareAgentRun,
|
|
40
37
|
resolveAgent,
|
|
@@ -50,13 +47,13 @@ import {
|
|
|
50
47
|
ToolCredentialRequired,
|
|
51
48
|
APPROVAL_REQUIRED,
|
|
52
49
|
CREDENTIAL_REQUIRED,
|
|
53
|
-
type
|
|
54
|
-
type
|
|
50
|
+
type RunAgentParams,
|
|
51
|
+
type StreamAgentOptions,
|
|
55
52
|
type StreamContext,
|
|
56
|
-
} from './
|
|
57
|
-
import { resolveModelConfig } from './
|
|
58
|
-
import type {
|
|
59
|
-
import type {
|
|
53
|
+
} from './agent-prepare.js'
|
|
54
|
+
import { resolveModelConfig } from './agent-model-config.js'
|
|
55
|
+
import type { AgentRunStateService } from '../../services/agent-run-state-service.js'
|
|
56
|
+
import type { AgentRunnerService } from '../../services/agent-runner-service.js'
|
|
60
57
|
import {
|
|
61
58
|
getInFlightTools,
|
|
62
59
|
isAbortError,
|
|
@@ -67,27 +64,27 @@ import {
|
|
|
67
64
|
trackToolExecution,
|
|
68
65
|
type AgentInterruption,
|
|
69
66
|
type AgentInterruptResult,
|
|
70
|
-
} from './
|
|
67
|
+
} from './agent-interrupt.js'
|
|
71
68
|
|
|
72
|
-
type PersistingChannel =
|
|
69
|
+
type PersistingChannel = AgentStreamChannel & {
|
|
73
70
|
fullText: string
|
|
74
71
|
flush: (opts?: { interrupted?: boolean }) => Promise<void>
|
|
75
72
|
totalUsage: { inputTokens: number; outputTokens: number; model?: string }
|
|
76
73
|
/** Every tool the run called, kept for the whole run rather than per step. */
|
|
77
|
-
runToolCalls: NonNullable<
|
|
74
|
+
runToolCalls: NonNullable<AgentStep['toolCalls']>
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
function createPersistingChannel(
|
|
81
|
-
parent:
|
|
82
|
-
storage:
|
|
78
|
+
parent: AgentStreamChannel,
|
|
79
|
+
storage: AgentStorageService | undefined,
|
|
83
80
|
threadId: string,
|
|
84
81
|
logger?: { error: (...args: any[]) => void }
|
|
85
82
|
): PersistingChannel {
|
|
86
83
|
let fullText = ''
|
|
87
84
|
let stepText = ''
|
|
88
85
|
let stepGenerativeUI: unknown | null = null
|
|
89
|
-
let stepToolCalls:
|
|
90
|
-
let stepToolResults:
|
|
86
|
+
let stepToolCalls: AgentToolCall[] = []
|
|
87
|
+
let stepToolResults: AgentToolResult[] = []
|
|
91
88
|
const totalUsage: {
|
|
92
89
|
inputTokens: number
|
|
93
90
|
outputTokens: number
|
|
@@ -98,7 +95,7 @@ function createPersistingChannel(
|
|
|
98
95
|
}
|
|
99
96
|
// Survives the per-step flush below, which clears its own buffers: the run
|
|
100
97
|
// record needs every call the run made, not just the last step's.
|
|
101
|
-
const runToolCalls: NonNullable<
|
|
98
|
+
const runToolCalls: NonNullable<AgentStep['toolCalls']> = []
|
|
102
99
|
|
|
103
100
|
const flushStep = async (opts?: { interrupted?: boolean }) => {
|
|
104
101
|
if (!storage) return
|
|
@@ -111,7 +108,7 @@ function createPersistingChannel(
|
|
|
111
108
|
stepToolCalls = []
|
|
112
109
|
stepToolResults = []
|
|
113
110
|
if (text || generativeUI != null || calls.length > 0) {
|
|
114
|
-
const assistantMsg:
|
|
111
|
+
const assistantMsg: AgentMessage = {
|
|
115
112
|
id: randomUUID(),
|
|
116
113
|
role: 'assistant',
|
|
117
114
|
content:
|
|
@@ -125,7 +122,7 @@ function createPersistingChannel(
|
|
|
125
122
|
...(opts?.interrupted ? { interrupted: true } : {}),
|
|
126
123
|
createdAt: new Date(),
|
|
127
124
|
}
|
|
128
|
-
const messages:
|
|
125
|
+
const messages: AgentMessage[] = [assistantMsg]
|
|
129
126
|
if (results.length > 0) {
|
|
130
127
|
messages.push({
|
|
131
128
|
id: randomUUID(),
|
|
@@ -167,7 +164,7 @@ function createPersistingChannel(
|
|
|
167
164
|
flush: flushStep,
|
|
168
165
|
close: () => parent.close(),
|
|
169
166
|
sendBinary: (data) => parent.sendBinary(data),
|
|
170
|
-
send: (event:
|
|
167
|
+
send: (event: AgentStreamEvent) => {
|
|
171
168
|
// Accumulated whether or not storage is configured: `fullText` is what
|
|
172
169
|
// the client was streamed, and an interrupted run has to be able to
|
|
173
170
|
// report the fragment it got through even with persistence turned off.
|
|
@@ -259,11 +256,11 @@ const warnedUnstreamedOutputHooks = new Set<string>()
|
|
|
259
256
|
*/
|
|
260
257
|
const warnUnstreamedOutputHooks = (
|
|
261
258
|
agentName: string,
|
|
262
|
-
|
|
259
|
+
agentMiddlewares: PikkuAgentMiddlewareHooks[],
|
|
263
260
|
logger?: { warn: (...args: any[]) => void }
|
|
264
261
|
) => {
|
|
265
262
|
if (warnedUnstreamedOutputHooks.has(agentName)) return
|
|
266
|
-
const unstreamed =
|
|
263
|
+
const unstreamed = agentMiddlewares.some(
|
|
267
264
|
(mw) => mw.modifyOutput && !mw.modifyOutputStream
|
|
268
265
|
)
|
|
269
266
|
if (!unstreamed) return
|
|
@@ -275,7 +272,7 @@ const warnUnstreamedOutputHooks = (
|
|
|
275
272
|
|
|
276
273
|
async function postStreamCleanup(
|
|
277
274
|
persistingChannel: PersistingChannel,
|
|
278
|
-
|
|
275
|
+
agentRunState: AgentRunStateService,
|
|
279
276
|
runId: string,
|
|
280
277
|
run: {
|
|
281
278
|
agentName: string
|
|
@@ -284,7 +281,7 @@ async function postStreamCleanup(
|
|
|
284
281
|
input: string
|
|
285
282
|
}
|
|
286
283
|
): Promise<void> {
|
|
287
|
-
await finalizeAgentRun(
|
|
284
|
+
await finalizeAgentRun(agentRunState, {
|
|
288
285
|
runId,
|
|
289
286
|
agentName: run.agentName,
|
|
290
287
|
threadId: run.threadId,
|
|
@@ -304,14 +301,14 @@ async function postStreamCleanup(
|
|
|
304
301
|
}
|
|
305
302
|
|
|
306
303
|
type StepLoopParams = {
|
|
307
|
-
agent:
|
|
308
|
-
runnerParams:
|
|
304
|
+
agent: CoreAgent
|
|
305
|
+
runnerParams: AgentRunnerParams
|
|
309
306
|
maxSteps: number
|
|
310
|
-
agentRunner:
|
|
311
|
-
streamChannel:
|
|
307
|
+
agentRunner: AgentRunnerService
|
|
308
|
+
streamChannel: AgentStreamChannel
|
|
312
309
|
persistingChannel: PersistingChannel
|
|
313
|
-
channel:
|
|
314
|
-
|
|
310
|
+
channel: AgentStreamChannel
|
|
311
|
+
agentMiddlewares: PikkuAgentMiddlewareHooks[]
|
|
315
312
|
}
|
|
316
313
|
|
|
317
314
|
type StepLoopResult =
|
|
@@ -329,7 +326,7 @@ async function runStreamStepLoop(
|
|
|
329
326
|
agentRunner,
|
|
330
327
|
streamChannel,
|
|
331
328
|
channel,
|
|
332
|
-
|
|
329
|
+
agentMiddlewares,
|
|
333
330
|
} = params
|
|
334
331
|
|
|
335
332
|
const singletonServices = getSingletonServices()
|
|
@@ -354,7 +351,7 @@ async function runStreamStepLoop(
|
|
|
354
351
|
|
|
355
352
|
const stepResult = await agentRunner.stream(runnerParams, streamChannel)
|
|
356
353
|
|
|
357
|
-
for (const mw of
|
|
354
|
+
for (const mw of agentMiddlewares) {
|
|
358
355
|
if (mw.afterStep) {
|
|
359
356
|
await mw.afterStep(singletonServices, {
|
|
360
357
|
stepNumber: step,
|
|
@@ -397,8 +394,8 @@ async function runStreamStepLoop(
|
|
|
397
394
|
}
|
|
398
395
|
|
|
399
396
|
export function checkForApprovals(
|
|
400
|
-
stepResult:
|
|
401
|
-
tools:
|
|
397
|
+
stepResult: AgentStepResult,
|
|
398
|
+
tools: AgentRunnerParams['tools']
|
|
402
399
|
): ToolApprovalRequired[] {
|
|
403
400
|
const approvals: ToolApprovalRequired[] = []
|
|
404
401
|
for (const tc of stepResult.toolCalls) {
|
|
@@ -471,11 +468,11 @@ export function checkForApprovals(
|
|
|
471
468
|
}
|
|
472
469
|
|
|
473
470
|
export function checkForCredentialRequests(
|
|
474
|
-
stepResult:
|
|
471
|
+
stepResult: AgentStepResult
|
|
475
472
|
): ToolCredentialRequired[] {
|
|
476
473
|
const requests: ToolCredentialRequired[] = []
|
|
477
474
|
for (const tr of stepResult.toolResults) {
|
|
478
|
-
// knowledge: decisions/security/
|
|
475
|
+
// knowledge: decisions/security/agent-credential-requests-are-symbol-branded.md
|
|
479
476
|
if (
|
|
480
477
|
tr.result &&
|
|
481
478
|
typeof tr.result === 'object' &&
|
|
@@ -505,8 +502,8 @@ export function checkForCredentialRequests(
|
|
|
505
502
|
}
|
|
506
503
|
|
|
507
504
|
export function appendStepMessages(
|
|
508
|
-
runnerParams:
|
|
509
|
-
stepResult:
|
|
505
|
+
runnerParams: AgentRunnerParams,
|
|
506
|
+
stepResult: AgentStepResult
|
|
510
507
|
): void {
|
|
511
508
|
const structuredOutput =
|
|
512
509
|
stepResult.object && typeof stepResult.object === 'object'
|
|
@@ -522,7 +519,7 @@ export function appendStepMessages(
|
|
|
522
519
|
]
|
|
523
520
|
: stepResult.text || undefined
|
|
524
521
|
|
|
525
|
-
const assistantMsg:
|
|
522
|
+
const assistantMsg: AgentMessage = {
|
|
526
523
|
id: randomUUID(),
|
|
527
524
|
role: 'assistant',
|
|
528
525
|
content: assistantContent,
|
|
@@ -542,7 +539,7 @@ export function appendStepMessages(
|
|
|
542
539
|
runnerParams.messages.push(assistantMsg)
|
|
543
540
|
|
|
544
541
|
if (stepResult.toolResults.length > 0) {
|
|
545
|
-
const toolMsg:
|
|
542
|
+
const toolMsg: AgentMessage = {
|
|
546
543
|
id: randomUUID(),
|
|
547
544
|
role: 'tool',
|
|
548
545
|
toolResults: stepResult.toolResults.map((tr) => ({
|
|
@@ -560,8 +557,8 @@ export function appendStepMessages(
|
|
|
560
557
|
function handleApprovals(
|
|
561
558
|
approvals: ToolApprovalRequired[],
|
|
562
559
|
runId: string,
|
|
563
|
-
channel:
|
|
564
|
-
|
|
560
|
+
channel: AgentStreamChannel,
|
|
561
|
+
agentRunState: AgentRunStateService,
|
|
565
562
|
persistingChannel: PersistingChannel
|
|
566
563
|
): Promise<void> {
|
|
567
564
|
return (async () => {
|
|
@@ -585,7 +582,7 @@ function handleApprovals(
|
|
|
585
582
|
}
|
|
586
583
|
)
|
|
587
584
|
|
|
588
|
-
await
|
|
585
|
+
await agentRunState.updateRun(runId, {
|
|
589
586
|
status: 'suspended',
|
|
590
587
|
suspendReason: 'approval',
|
|
591
588
|
pendingApprovals,
|
|
@@ -610,8 +607,8 @@ function handleApprovals(
|
|
|
610
607
|
function handleCredentialRequests(
|
|
611
608
|
requests: ToolCredentialRequired[],
|
|
612
609
|
runId: string,
|
|
613
|
-
channel:
|
|
614
|
-
|
|
610
|
+
channel: AgentStreamChannel,
|
|
611
|
+
agentRunState: AgentRunStateService,
|
|
615
612
|
persistingChannel: PersistingChannel
|
|
616
613
|
): Promise<void> {
|
|
617
614
|
return (async () => {
|
|
@@ -627,7 +624,7 @@ function handleCredentialRequests(
|
|
|
627
624
|
connectUrl: req.connectUrl,
|
|
628
625
|
}))
|
|
629
626
|
|
|
630
|
-
await
|
|
627
|
+
await agentRunState.updateRun(runId, {
|
|
631
628
|
status: 'suspended',
|
|
632
629
|
suspendReason: 'credential',
|
|
633
630
|
pendingApprovals,
|
|
@@ -650,7 +647,7 @@ function handleCredentialRequests(
|
|
|
650
647
|
})()
|
|
651
648
|
}
|
|
652
649
|
|
|
653
|
-
export async function
|
|
650
|
+
export async function streamAgent(
|
|
654
651
|
agentName: string,
|
|
655
652
|
input: {
|
|
656
653
|
message: string
|
|
@@ -659,10 +656,10 @@ export async function streamAIAgent(
|
|
|
659
656
|
model?: string
|
|
660
657
|
temperature?: number
|
|
661
658
|
},
|
|
662
|
-
channel:
|
|
663
|
-
params:
|
|
659
|
+
channel: AgentStreamChannel,
|
|
660
|
+
params: RunAgentParams,
|
|
664
661
|
agentSessionMap?: Map<string, string>,
|
|
665
|
-
options?:
|
|
662
|
+
options?: StreamAgentOptions
|
|
666
663
|
): Promise<string> {
|
|
667
664
|
const sessionMap = agentSessionMap ?? new Map<string, string>()
|
|
668
665
|
|
|
@@ -701,13 +698,13 @@ export async function streamAIAgent(
|
|
|
701
698
|
runnerParams.agentId = agentName
|
|
702
699
|
|
|
703
700
|
const singletonServices = getSingletonServices()
|
|
704
|
-
const {
|
|
705
|
-
if (!
|
|
706
|
-
throw new Error('
|
|
701
|
+
const { agentRunState } = singletonServices
|
|
702
|
+
if (!agentRunState) {
|
|
703
|
+
throw new Error('AgentRunStateService not available in singletonServices')
|
|
707
704
|
}
|
|
708
705
|
|
|
709
706
|
if (missingRpcs.length > 0) {
|
|
710
|
-
await
|
|
707
|
+
await agentRunState.createRun({
|
|
711
708
|
agentName,
|
|
712
709
|
threadId,
|
|
713
710
|
resourceId: normalizedInput.resourceId,
|
|
@@ -723,22 +720,22 @@ export async function streamAIAgent(
|
|
|
723
720
|
return ''
|
|
724
721
|
}
|
|
725
722
|
|
|
726
|
-
const
|
|
723
|
+
const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
|
|
727
724
|
...getWorkingMemoryMiddleware(memoryConfig, storage, {
|
|
728
725
|
threadId,
|
|
729
726
|
workingMemorySchemaName,
|
|
730
727
|
logger: singletonServices.logger,
|
|
731
728
|
schemaService: singletonServices.schema,
|
|
732
729
|
}),
|
|
733
|
-
...(agent.
|
|
730
|
+
...(agent.agentMiddleware ?? []),
|
|
734
731
|
]
|
|
735
732
|
|
|
736
|
-
// One bag per run, shared by every middleware — see
|
|
733
|
+
// One bag per run, shared by every middleware — see PikkuAgentMiddlewareHooks.
|
|
737
734
|
const sharedNotes: Record<string, unknown> = {}
|
|
738
735
|
|
|
739
736
|
const { messages: modifiedMessages, instructions: modifiedInstructions } =
|
|
740
737
|
await applyInputMiddleware(
|
|
741
|
-
|
|
738
|
+
agentMiddlewares,
|
|
742
739
|
singletonServices,
|
|
743
740
|
{
|
|
744
741
|
messages: runnerParams.messages,
|
|
@@ -760,7 +757,7 @@ export async function streamAIAgent(
|
|
|
760
757
|
const persistedUserMessage =
|
|
761
758
|
lastModified?.id === userMessage.id ? lastModified : userMessage
|
|
762
759
|
|
|
763
|
-
const runId = await
|
|
760
|
+
const runId = await agentRunState.createRun({
|
|
764
761
|
agentName,
|
|
765
762
|
threadId,
|
|
766
763
|
resourceId: normalizedInput.resourceId,
|
|
@@ -782,13 +779,17 @@ export async function streamAIAgent(
|
|
|
782
779
|
await storage.saveMessages(threadId, [persistedUserMessage])
|
|
783
780
|
}
|
|
784
781
|
|
|
785
|
-
warnUnstreamedOutputHooks(
|
|
782
|
+
warnUnstreamedOutputHooks(
|
|
783
|
+
agentName,
|
|
784
|
+
agentMiddlewares,
|
|
785
|
+
singletonServices.logger
|
|
786
|
+
)
|
|
786
787
|
|
|
787
|
-
const streamMiddleware =
|
|
788
|
+
const streamMiddleware = agentMiddlewares
|
|
788
789
|
.filter((mw) => mw.modifyOutputStream)
|
|
789
790
|
.map((mw) => {
|
|
790
791
|
const state: Record<string, unknown> = {}
|
|
791
|
-
const allEvents:
|
|
792
|
+
const allEvents: AgentStreamEvent[] = []
|
|
792
793
|
return async (services: any, event: any, next: any) => {
|
|
793
794
|
allEvents.push(event)
|
|
794
795
|
const result = await mw.modifyOutputStream!(services, {
|
|
@@ -837,13 +838,13 @@ export async function streamAIAgent(
|
|
|
837
838
|
{ channel: persistingChannel },
|
|
838
839
|
singletonServices,
|
|
839
840
|
allChannelMiddleware
|
|
840
|
-
).channel as
|
|
841
|
+
).channel as AgentStreamChannel)
|
|
841
842
|
: persistingChannel
|
|
842
843
|
|
|
843
|
-
const credentialFilteredChannel:
|
|
844
|
+
const credentialFilteredChannel: AgentStreamChannel = {
|
|
844
845
|
...wrappedChannel,
|
|
845
846
|
// knowledge: decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md
|
|
846
|
-
send: (event:
|
|
847
|
+
send: (event: AgentStreamEvent) => {
|
|
847
848
|
if (
|
|
848
849
|
event.type === 'tool-result' &&
|
|
849
850
|
event.result !== null &&
|
|
@@ -864,7 +865,7 @@ export async function streamAIAgent(
|
|
|
864
865
|
const outputChannel = isDelegateMode
|
|
865
866
|
? {
|
|
866
867
|
...credentialFilteredChannel,
|
|
867
|
-
send: (event:
|
|
868
|
+
send: (event: AgentStreamEvent) => {
|
|
868
869
|
if (
|
|
869
870
|
delegateState.delegated &&
|
|
870
871
|
(event.type === 'text-delta' || event.type === 'reasoning-delta')
|
|
@@ -885,7 +886,7 @@ export async function streamAIAgent(
|
|
|
885
886
|
streamChannel: outputChannel,
|
|
886
887
|
persistingChannel,
|
|
887
888
|
channel,
|
|
888
|
-
|
|
889
|
+
agentMiddlewares,
|
|
889
890
|
})
|
|
890
891
|
|
|
891
892
|
if (loopResult.outcome === 'approval') {
|
|
@@ -893,7 +894,7 @@ export async function streamAIAgent(
|
|
|
893
894
|
loopResult.approvals,
|
|
894
895
|
runId,
|
|
895
896
|
channel,
|
|
896
|
-
|
|
897
|
+
agentRunState,
|
|
897
898
|
persistingChannel
|
|
898
899
|
)
|
|
899
900
|
return persistingChannel.fullText
|
|
@@ -904,13 +905,13 @@ export async function streamAIAgent(
|
|
|
904
905
|
loopResult.credentialRequests,
|
|
905
906
|
runId,
|
|
906
907
|
channel,
|
|
907
|
-
|
|
908
|
+
agentRunState,
|
|
908
909
|
persistingChannel
|
|
909
910
|
)
|
|
910
911
|
return persistingChannel.fullText
|
|
911
912
|
}
|
|
912
913
|
|
|
913
|
-
await postStreamCleanup(persistingChannel,
|
|
914
|
+
await postStreamCleanup(persistingChannel, agentRunState, runId, {
|
|
914
915
|
agentName,
|
|
915
916
|
threadId,
|
|
916
917
|
resourceId: input.resourceId,
|
|
@@ -927,7 +928,7 @@ export async function streamAIAgent(
|
|
|
927
928
|
const interruption = interruptHandle.interruption
|
|
928
929
|
if (interruption || isAbortError(err)) {
|
|
929
930
|
await persistingChannel.flush({ interrupted: true })
|
|
930
|
-
await
|
|
931
|
+
await agentRunState.updateRun(runId, { status: 'interrupted' })
|
|
931
932
|
// Deliberately not awaited. A tool still running must not hold the stream
|
|
932
933
|
// open — the whole point of barge-in is that the agent stops now — so the
|
|
933
934
|
// note lands later and the next run on this thread waits for it instead.
|
|
@@ -948,7 +949,7 @@ export async function streamAIAgent(
|
|
|
948
949
|
return persistingChannel.fullText
|
|
949
950
|
}
|
|
950
951
|
|
|
951
|
-
for (const mw of
|
|
952
|
+
for (const mw of agentMiddlewares) {
|
|
952
953
|
if (mw.onError) {
|
|
953
954
|
try {
|
|
954
955
|
await mw.onError(singletonServices, {
|
|
@@ -959,7 +960,7 @@ export async function streamAIAgent(
|
|
|
959
960
|
} catch {}
|
|
960
961
|
}
|
|
961
962
|
}
|
|
962
|
-
await
|
|
963
|
+
await agentRunState.updateRun(runId, {
|
|
963
964
|
status: 'failed',
|
|
964
965
|
errorMessage: err instanceof Error ? err.message : String(err),
|
|
965
966
|
})
|
|
@@ -978,9 +979,9 @@ export async function streamAIAgent(
|
|
|
978
979
|
/**
|
|
979
980
|
* Stop an in-flight run on behalf of a caller, after checking the run is theirs.
|
|
980
981
|
*
|
|
981
|
-
* Unlike {@link
|
|
982
|
+
* Unlike {@link resumeAgent} this needs no channel: it does not continue the
|
|
982
983
|
* stream, it ends one. The `interrupted` event and the truncated message are
|
|
983
|
-
* emitted by the original {@link
|
|
984
|
+
* emitted by the original {@link streamAgent} call on its own channel, so this
|
|
984
985
|
* can be reached over a plain RPC while the stream is held open elsewhere —
|
|
985
986
|
* which is exactly the shape a voice barge-in needs.
|
|
986
987
|
*
|
|
@@ -993,16 +994,16 @@ export async function streamAIAgent(
|
|
|
993
994
|
* Returns `false` when there was nothing to stop. Racing a run that finishes on
|
|
994
995
|
* its own is the normal case in voice, so it is not an error.
|
|
995
996
|
*/
|
|
996
|
-
export async function
|
|
997
|
+
export async function interruptAgent(
|
|
997
998
|
input: { runId: string; reason?: AgentInterruption['reason'] },
|
|
998
|
-
params:
|
|
999
|
+
params: RunAgentParams
|
|
999
1000
|
): Promise<AgentInterruptResult> {
|
|
1000
|
-
const {
|
|
1001
|
-
if (!
|
|
1002
|
-
throw new Error('
|
|
1001
|
+
const { agentRunState, logger } = getSingletonServices()
|
|
1002
|
+
if (!agentRunState) {
|
|
1003
|
+
throw new Error('AgentRunStateService not available in singletonServices')
|
|
1003
1004
|
}
|
|
1004
1005
|
|
|
1005
|
-
const run = await
|
|
1006
|
+
const run = await agentRunState.getRun(input.runId)
|
|
1006
1007
|
if (!run) {
|
|
1007
1008
|
throw new Error(`No run found for runId ${input.runId}`)
|
|
1008
1009
|
}
|
|
@@ -1033,23 +1034,23 @@ export async function interruptAIAgent(
|
|
|
1033
1034
|
return { stopped, inFlightTools: getInFlightTools(input.runId) }
|
|
1034
1035
|
}
|
|
1035
1036
|
|
|
1036
|
-
export async function
|
|
1037
|
+
export async function resumeAgent(
|
|
1037
1038
|
input: {
|
|
1038
1039
|
runId: string
|
|
1039
1040
|
toolCallId: string
|
|
1040
1041
|
approved: boolean
|
|
1041
1042
|
},
|
|
1042
|
-
channel:
|
|
1043
|
-
params:
|
|
1044
|
-
options?:
|
|
1043
|
+
channel: AgentStreamChannel,
|
|
1044
|
+
params: RunAgentParams,
|
|
1045
|
+
options?: StreamAgentOptions
|
|
1045
1046
|
): Promise<void> {
|
|
1046
1047
|
const singletonServices = getSingletonServices()
|
|
1047
|
-
const {
|
|
1048
|
-
if (!
|
|
1049
|
-
throw new Error('
|
|
1048
|
+
const { agentRunState } = singletonServices
|
|
1049
|
+
if (!agentRunState) {
|
|
1050
|
+
throw new Error('AgentRunStateService not available in singletonServices')
|
|
1050
1051
|
}
|
|
1051
1052
|
|
|
1052
|
-
const run = await
|
|
1053
|
+
const run = await agentRunState.getRun(input.runId)
|
|
1053
1054
|
if (!run) {
|
|
1054
1055
|
throw new Error(`No run found for runId ${input.runId}`)
|
|
1055
1056
|
}
|
|
@@ -1076,7 +1077,7 @@ export async function resumeAIAgent(
|
|
|
1076
1077
|
// The read above is not a claim — concurrent resumes all see the same pending
|
|
1077
1078
|
// approval. `resolveApproval` is the claim, and the loser must not go on to
|
|
1078
1079
|
// run the tool a second time.
|
|
1079
|
-
const claimed = await
|
|
1080
|
+
const claimed = await agentRunState.resolveApproval(
|
|
1080
1081
|
input.toolCallId,
|
|
1081
1082
|
input.approved ? 'approved' : 'denied'
|
|
1082
1083
|
)
|
|
@@ -1088,14 +1089,14 @@ export async function resumeAIAgent(
|
|
|
1088
1089
|
|
|
1089
1090
|
const { storage } = resolveMemoryServices(agent, singletonServices)
|
|
1090
1091
|
const memoryConfig = agent.memory
|
|
1091
|
-
const agentRunner = singletonServices.
|
|
1092
|
+
const agentRunner = singletonServices.agentRunner
|
|
1092
1093
|
if (!agentRunner) {
|
|
1093
1094
|
throw new AIProviderNotConfiguredError()
|
|
1094
1095
|
}
|
|
1095
1096
|
|
|
1096
1097
|
if (!input.approved) {
|
|
1097
1098
|
if (pending.type === 'agent-call') {
|
|
1098
|
-
await
|
|
1099
|
+
await agentRunState.updateRun(pending.agentRunId, { status: 'failed' })
|
|
1099
1100
|
}
|
|
1100
1101
|
|
|
1101
1102
|
const denialResult =
|
|
@@ -1132,7 +1133,7 @@ export async function resumeAIAgent(
|
|
|
1132
1133
|
result: denialResult,
|
|
1133
1134
|
})
|
|
1134
1135
|
|
|
1135
|
-
const updatedRun = await
|
|
1136
|
+
const updatedRun = await agentRunState.getRun(run.runId)
|
|
1136
1137
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
1137
1138
|
|
|
1138
1139
|
if (remaining.length > 0) {
|
|
@@ -1141,7 +1142,7 @@ export async function resumeAIAgent(
|
|
|
1141
1142
|
return
|
|
1142
1143
|
}
|
|
1143
1144
|
|
|
1144
|
-
await
|
|
1145
|
+
await agentRunState.updateRun(run.runId, { status: 'running' })
|
|
1145
1146
|
|
|
1146
1147
|
await continueAfterToolResult(
|
|
1147
1148
|
run,
|
|
@@ -1153,14 +1154,14 @@ export async function resumeAIAgent(
|
|
|
1153
1154
|
agentRunner,
|
|
1154
1155
|
channel,
|
|
1155
1156
|
params,
|
|
1156
|
-
|
|
1157
|
+
agentRunState,
|
|
1157
1158
|
options
|
|
1158
1159
|
)
|
|
1159
1160
|
return
|
|
1160
1161
|
}
|
|
1161
1162
|
|
|
1162
1163
|
if (pending.type === 'agent-call') {
|
|
1163
|
-
const subRun = await
|
|
1164
|
+
const subRun = await agentRunState.getRun(pending.agentRunId)
|
|
1164
1165
|
if (!subRun) {
|
|
1165
1166
|
throw new Error(`Sub-agent run not found: ${pending.agentRunId}`)
|
|
1166
1167
|
}
|
|
@@ -1181,7 +1182,7 @@ export async function resumeAIAgent(
|
|
|
1181
1182
|
input: null,
|
|
1182
1183
|
})
|
|
1183
1184
|
|
|
1184
|
-
await
|
|
1185
|
+
await resumeAgent(
|
|
1185
1186
|
{
|
|
1186
1187
|
runId: pending.agentRunId,
|
|
1187
1188
|
toolCallId: subPending.toolCallId,
|
|
@@ -1220,8 +1221,8 @@ export async function resumeAIAgent(
|
|
|
1220
1221
|
channel,
|
|
1221
1222
|
options: { ...options, requiresToolApproval: false },
|
|
1222
1223
|
}
|
|
1223
|
-
const
|
|
1224
|
-
agent.
|
|
1224
|
+
const agentMiddlewaresForResume: PikkuAgentMiddlewareHooks[] =
|
|
1225
|
+
agent.agentMiddleware ?? []
|
|
1225
1226
|
const { tools } = await buildToolDefs(
|
|
1226
1227
|
params,
|
|
1227
1228
|
new Map<string, string>(),
|
|
@@ -1229,7 +1230,7 @@ export async function resumeAIAgent(
|
|
|
1229
1230
|
resolvedName,
|
|
1230
1231
|
packageName,
|
|
1231
1232
|
streamContext,
|
|
1232
|
-
|
|
1233
|
+
agentMiddlewaresForResume
|
|
1233
1234
|
)
|
|
1234
1235
|
|
|
1235
1236
|
const matchingTool = tools.find((t) => t.name === pending.toolName)
|
|
@@ -1284,7 +1285,7 @@ export async function resumeAIAgent(
|
|
|
1284
1285
|
})
|
|
1285
1286
|
}
|
|
1286
1287
|
|
|
1287
|
-
const updatedRun = await
|
|
1288
|
+
const updatedRun = await agentRunState.getRun(run.runId)
|
|
1288
1289
|
const remaining = updatedRun?.pendingApprovals ?? []
|
|
1289
1290
|
|
|
1290
1291
|
if (remaining.length > 0) {
|
|
@@ -1293,7 +1294,7 @@ export async function resumeAIAgent(
|
|
|
1293
1294
|
return
|
|
1294
1295
|
}
|
|
1295
1296
|
|
|
1296
|
-
await
|
|
1297
|
+
await agentRunState.updateRun(run.runId, { status: 'running' })
|
|
1297
1298
|
|
|
1298
1299
|
await continueAfterToolResult(
|
|
1299
1300
|
run,
|
|
@@ -1305,23 +1306,23 @@ export async function resumeAIAgent(
|
|
|
1305
1306
|
agentRunner,
|
|
1306
1307
|
channel,
|
|
1307
1308
|
params,
|
|
1308
|
-
|
|
1309
|
+
agentRunState,
|
|
1309
1310
|
options
|
|
1310
1311
|
)
|
|
1311
1312
|
}
|
|
1312
1313
|
|
|
1313
1314
|
async function continueAfterToolResult(
|
|
1314
1315
|
run: AgentRunState,
|
|
1315
|
-
agent:
|
|
1316
|
+
agent: CoreAgent,
|
|
1316
1317
|
packageName: string | null,
|
|
1317
1318
|
resolvedName: string,
|
|
1318
|
-
storage:
|
|
1319
|
-
memoryConfig:
|
|
1320
|
-
agentRunner:
|
|
1321
|
-
channel:
|
|
1322
|
-
params:
|
|
1323
|
-
|
|
1324
|
-
options?:
|
|
1319
|
+
storage: AgentStorageService | undefined,
|
|
1320
|
+
memoryConfig: AgentMemoryConfig | undefined,
|
|
1321
|
+
agentRunner: AgentRunnerService,
|
|
1322
|
+
channel: AgentStreamChannel,
|
|
1323
|
+
params: RunAgentParams,
|
|
1324
|
+
agentRunState: AgentRunStateService,
|
|
1325
|
+
options?: StreamAgentOptions
|
|
1325
1326
|
): Promise<void> {
|
|
1326
1327
|
const singletonServices = getSingletonServices()
|
|
1327
1328
|
const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta')
|
|
@@ -1350,21 +1351,21 @@ async function continueAfterToolResult(
|
|
|
1350
1351
|
|
|
1351
1352
|
const instructions = await buildInstructions(resolvedName, packageName)
|
|
1352
1353
|
|
|
1353
|
-
const
|
|
1354
|
+
const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
|
|
1354
1355
|
...getWorkingMemoryMiddleware(memoryConfig, storage, {
|
|
1355
1356
|
threadId: run.threadId,
|
|
1356
1357
|
workingMemorySchemaName,
|
|
1357
1358
|
logger: singletonServices.logger,
|
|
1358
1359
|
schemaService: singletonServices.schema,
|
|
1359
1360
|
}),
|
|
1360
|
-
...(agent.
|
|
1361
|
+
...(agent.agentMiddleware ?? []),
|
|
1361
1362
|
]
|
|
1362
|
-
// One bag per run, shared by every middleware — see
|
|
1363
|
+
// One bag per run, shared by every middleware — see PikkuAgentMiddlewareHooks.
|
|
1363
1364
|
const sharedNotes: Record<string, unknown> = {}
|
|
1364
1365
|
|
|
1365
1366
|
const { messages: modifiedMessages, instructions: modifiedInstructions } =
|
|
1366
1367
|
await applyInputMiddleware(
|
|
1367
|
-
|
|
1368
|
+
agentMiddlewares,
|
|
1368
1369
|
singletonServices,
|
|
1369
1370
|
{ messages: trimmedMessages, instructions: instructions },
|
|
1370
1371
|
sharedNotes
|
|
@@ -1375,15 +1376,15 @@ async function continueAfterToolResult(
|
|
|
1375
1376
|
|
|
1376
1377
|
warnUnstreamedOutputHooks(
|
|
1377
1378
|
run.agentName,
|
|
1378
|
-
|
|
1379
|
+
agentMiddlewares,
|
|
1379
1380
|
singletonServices.logger
|
|
1380
1381
|
)
|
|
1381
1382
|
|
|
1382
|
-
const streamMiddleware =
|
|
1383
|
+
const streamMiddleware = agentMiddlewares
|
|
1383
1384
|
.filter((mw) => mw.modifyOutputStream)
|
|
1384
1385
|
.map((mw) => {
|
|
1385
1386
|
const state: Record<string, unknown> = {}
|
|
1386
|
-
const allEvents:
|
|
1387
|
+
const allEvents: AgentStreamEvent[] = []
|
|
1387
1388
|
return async (services: any, event: any, next: any) => {
|
|
1388
1389
|
allEvents.push(event)
|
|
1389
1390
|
const result = await mw.modifyOutputStream!(services, {
|
|
@@ -1430,7 +1431,7 @@ async function continueAfterToolResult(
|
|
|
1430
1431
|
{ channel: persistingChannel },
|
|
1431
1432
|
singletonServices,
|
|
1432
1433
|
allChannelMiddleware
|
|
1433
|
-
).channel as
|
|
1434
|
+
).channel as AgentStreamChannel)
|
|
1434
1435
|
: persistingChannel
|
|
1435
1436
|
|
|
1436
1437
|
const streamContext: StreamContext = { channel, options }
|
|
@@ -1442,14 +1443,14 @@ async function continueAfterToolResult(
|
|
|
1442
1443
|
resolvedName,
|
|
1443
1444
|
packageName,
|
|
1444
1445
|
streamContext,
|
|
1445
|
-
|
|
1446
|
+
agentMiddlewares
|
|
1446
1447
|
)
|
|
1447
1448
|
).tools
|
|
1448
1449
|
|
|
1449
1450
|
const resolved = resolveModelConfig(resolvedName, agent)
|
|
1450
1451
|
const maxSteps = resolved.maxSteps ?? 10
|
|
1451
1452
|
|
|
1452
|
-
const runnerParams:
|
|
1453
|
+
const runnerParams: AgentRunnerParams = {
|
|
1453
1454
|
model: resolved.model,
|
|
1454
1455
|
temperature: resolved.temperature,
|
|
1455
1456
|
instructions: modifiedInstructions,
|
|
@@ -1475,7 +1476,7 @@ async function continueAfterToolResult(
|
|
|
1475
1476
|
streamChannel: wrappedChannel,
|
|
1476
1477
|
persistingChannel,
|
|
1477
1478
|
channel,
|
|
1478
|
-
|
|
1479
|
+
agentMiddlewares,
|
|
1479
1480
|
})
|
|
1480
1481
|
|
|
1481
1482
|
if (loopResult.outcome === 'approval') {
|
|
@@ -1483,7 +1484,7 @@ async function continueAfterToolResult(
|
|
|
1483
1484
|
loopResult.approvals,
|
|
1484
1485
|
run.runId,
|
|
1485
1486
|
channel,
|
|
1486
|
-
|
|
1487
|
+
agentRunState,
|
|
1487
1488
|
persistingChannel
|
|
1488
1489
|
)
|
|
1489
1490
|
return
|
|
@@ -1494,13 +1495,13 @@ async function continueAfterToolResult(
|
|
|
1494
1495
|
loopResult.credentialRequests,
|
|
1495
1496
|
run.runId,
|
|
1496
1497
|
channel,
|
|
1497
|
-
|
|
1498
|
+
agentRunState,
|
|
1498
1499
|
persistingChannel
|
|
1499
1500
|
)
|
|
1500
1501
|
return
|
|
1501
1502
|
}
|
|
1502
1503
|
|
|
1503
|
-
await postStreamCleanup(persistingChannel,
|
|
1504
|
+
await postStreamCleanup(persistingChannel, agentRunState, run.runId, {
|
|
1504
1505
|
...run,
|
|
1505
1506
|
input: lastUserMessageText(runnerParams.messages),
|
|
1506
1507
|
})
|
|
@@ -1514,7 +1515,7 @@ async function continueAfterToolResult(
|
|
|
1514
1515
|
const interruption = interruptHandle.interruption
|
|
1515
1516
|
if (interruption || isAbortError(err)) {
|
|
1516
1517
|
await persistingChannel.flush({ interrupted: true })
|
|
1517
|
-
await
|
|
1518
|
+
await agentRunState.updateRun(run.runId, { status: 'interrupted' })
|
|
1518
1519
|
if (storage) {
|
|
1519
1520
|
trackInterruptNote(
|
|
1520
1521
|
run.threadId,
|
|
@@ -1532,7 +1533,7 @@ async function continueAfterToolResult(
|
|
|
1532
1533
|
return
|
|
1533
1534
|
}
|
|
1534
1535
|
|
|
1535
|
-
for (const mw of
|
|
1536
|
+
for (const mw of agentMiddlewares) {
|
|
1536
1537
|
if (mw.onError) {
|
|
1537
1538
|
try {
|
|
1538
1539
|
await mw.onError(singletonServices, {
|
|
@@ -1543,7 +1544,7 @@ async function continueAfterToolResult(
|
|
|
1543
1544
|
} catch {}
|
|
1544
1545
|
}
|
|
1545
1546
|
}
|
|
1546
|
-
await
|
|
1547
|
+
await agentRunState.updateRun(run.runId, {
|
|
1547
1548
|
status: 'failed',
|
|
1548
1549
|
errorMessage: err instanceof Error ? err.message : String(err),
|
|
1549
1550
|
})
|