@cleocode/core 2026.6.12 → 2026.6.13
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/dist/conduit/local-transport.d.ts +12 -0
- package/dist/conduit/local-transport.d.ts.map +1 -1
- package/dist/conduit/local-transport.js +53 -23
- package/dist/conduit/local-transport.js.map +1 -1
- package/dist/crypto/credentials.d.ts +37 -0
- package/dist/crypto/credentials.d.ts.map +1 -1
- package/dist/crypto/credentials.js +110 -0
- package/dist/crypto/credentials.js.map +1 -1
- package/dist/dispatch/contracts/derive-output-contract.d.ts +86 -0
- package/dist/dispatch/contracts/derive-output-contract.d.ts.map +1 -0
- package/dist/dispatch/contracts/derive-output-contract.js +347 -0
- package/dist/dispatch/contracts/derive-output-contract.js.map +1 -0
- package/dist/dispatch/contracts/ensures-schema.d.ts +77 -0
- package/dist/dispatch/contracts/ensures-schema.d.ts.map +1 -0
- package/dist/dispatch/contracts/ensures-schema.js +91 -0
- package/dist/dispatch/contracts/ensures-schema.js.map +1 -0
- package/dist/dispatch/contracts/output-contracts.d.ts +27 -5
- package/dist/dispatch/contracts/output-contracts.d.ts.map +1 -1
- package/dist/dispatch/contracts/output-contracts.js +29 -6
- package/dist/dispatch/contracts/output-contracts.js.map +1 -1
- package/dist/docs/export-document.js +2294 -1250
- package/dist/docs/export-document.js.map +3 -3
- package/dist/go/driver.d.ts +132 -7
- package/dist/go/driver.d.ts.map +1 -1
- package/dist/go/driver.js +135 -10
- package/dist/go/driver.js.map +1 -1
- package/dist/go/index.d.ts +1 -1
- package/dist/go/index.d.ts.map +1 -1
- package/dist/go/index.js +1 -1
- package/dist/go/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +13 -10
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +11 -11
- package/dist/internal.js.map +1 -1
- package/dist/lifecycle/engine-ops.d.ts.map +1 -1
- package/dist/lifecycle/engine-ops.js +7 -4
- package/dist/lifecycle/engine-ops.js.map +1 -1
- package/dist/lifecycle/ivtr-loop.d.ts +108 -183
- package/dist/lifecycle/ivtr-loop.d.ts.map +1 -1
- package/dist/lifecycle/ivtr-loop.js +207 -522
- package/dist/lifecycle/ivtr-loop.js.map +1 -1
- package/dist/llm/auxiliary-fallback.js +1 -1
- package/dist/llm/auxiliary-fallback.js.map +1 -1
- package/dist/llm/cli-ops.d.ts +14 -1
- package/dist/llm/cli-ops.d.ts.map +1 -1
- package/dist/llm/cli-ops.js +41 -12
- package/dist/llm/cli-ops.js.map +1 -1
- package/dist/llm/concrete-session.d.ts.map +1 -1
- package/dist/llm/concrete-session.js +4 -0
- package/dist/llm/concrete-session.js.map +1 -1
- package/dist/llm/credentials.d.ts +35 -0
- package/dist/llm/credentials.d.ts.map +1 -1
- package/dist/llm/credentials.js +49 -0
- package/dist/llm/credentials.js.map +1 -1
- package/dist/llm/index.d.ts +4 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +4 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/pi/gondolin-loader.d.ts +241 -0
- package/dist/llm/pi/gondolin-loader.d.ts.map +1 -0
- package/dist/llm/pi/gondolin-loader.js +195 -0
- package/dist/llm/pi/gondolin-loader.js.map +1 -0
- package/dist/llm/pi/index.d.ts +28 -0
- package/dist/llm/pi/index.d.ts.map +1 -0
- package/dist/llm/pi/index.js +27 -0
- package/dist/llm/pi/index.js.map +1 -0
- package/dist/llm/pi/pi-agent-adapter.d.ts +135 -0
- package/dist/llm/pi/pi-agent-adapter.d.ts.map +1 -0
- package/dist/llm/pi/pi-agent-adapter.js +329 -0
- package/dist/llm/pi/pi-agent-adapter.js.map +1 -0
- package/dist/llm/pi/pi-errors.d.ts +161 -0
- package/dist/llm/pi/pi-errors.d.ts.map +1 -0
- package/dist/llm/pi/pi-errors.js +296 -0
- package/dist/llm/pi/pi-errors.js.map +1 -0
- package/dist/llm/pi/pi-execution-env.d.ts +286 -0
- package/dist/llm/pi/pi-execution-env.d.ts.map +1 -0
- package/dist/llm/pi/pi-execution-env.js +406 -0
- package/dist/llm/pi/pi-execution-env.js.map +1 -0
- package/dist/llm/pi/pi-gondolin-env.d.ts +227 -0
- package/dist/llm/pi/pi-gondolin-env.d.ts.map +1 -0
- package/dist/llm/pi/pi-gondolin-env.js +541 -0
- package/dist/llm/pi/pi-gondolin-env.js.map +1 -0
- package/dist/llm/pi/pi-session-storage.d.ts +154 -0
- package/dist/llm/pi/pi-session-storage.d.ts.map +1 -0
- package/dist/llm/pi/pi-session-storage.js +314 -0
- package/dist/llm/pi/pi-session-storage.js.map +1 -0
- package/dist/llm/pi/pi-stream-fn.d.ts +124 -0
- package/dist/llm/pi/pi-stream-fn.d.ts.map +1 -0
- package/dist/llm/pi/pi-stream-fn.js +504 -0
- package/dist/llm/pi/pi-stream-fn.js.map +1 -0
- package/dist/llm/pi/pi-tool-bridge.d.ts +99 -0
- package/dist/llm/pi/pi-tool-bridge.d.ts.map +1 -0
- package/dist/llm/pi/pi-tool-bridge.js +117 -0
- package/dist/llm/pi/pi-tool-bridge.js.map +1 -0
- package/dist/llm/pi/pi-types.d.ts +56 -0
- package/dist/llm/pi/pi-types.d.ts.map +1 -0
- package/dist/llm/pi/pi-types.js +16 -0
- package/dist/llm/pi/pi-types.js.map +1 -0
- package/dist/llm/pi/resolve-execution-env.d.ts +194 -0
- package/dist/llm/pi/resolve-execution-env.d.ts.map +1 -0
- package/dist/llm/pi/resolve-execution-env.js +132 -0
- package/dist/llm/pi/resolve-execution-env.js.map +1 -0
- package/dist/llm/plugin-facade.js +2253 -1151
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/role-executor.d.ts.map +1 -1
- package/dist/llm/role-executor.js +8 -5
- package/dist/llm/role-executor.js.map +1 -1
- package/dist/llm/role-resolver.d.ts +46 -14
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +178 -20
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/sealed-credential.d.ts +125 -0
- package/dist/llm/sealed-credential.d.ts.map +1 -0
- package/dist/llm/sealed-credential.js +133 -0
- package/dist/llm/sealed-credential.js.map +1 -0
- package/dist/llm/session-factory.d.ts.map +1 -1
- package/dist/llm/session-factory.js +6 -2
- package/dist/llm/session-factory.js.map +1 -1
- package/dist/llm/system-key.d.ts +67 -0
- package/dist/llm/system-key.d.ts.map +1 -0
- package/dist/llm/system-key.js +87 -0
- package/dist/llm/system-key.js.map +1 -0
- package/dist/llm/system-of-use-registry.d.ts +119 -0
- package/dist/llm/system-of-use-registry.d.ts.map +1 -0
- package/dist/llm/system-of-use-registry.js +200 -0
- package/dist/llm/system-of-use-registry.js.map +1 -0
- package/dist/llm/system-resolver.d.ts +32 -10
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/llm/system-resolver.js +70 -18
- package/dist/llm/system-resolver.js.map +1 -1
- package/dist/memory/brain-writer-thread.d.ts.map +1 -1
- package/dist/memory/brain-writer-thread.js +116 -11
- package/dist/memory/brain-writer-thread.js.map +1 -1
- package/dist/memory/claude-mem-migration.d.ts.map +1 -1
- package/dist/memory/claude-mem-migration.js +21 -0
- package/dist/memory/claude-mem-migration.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +32 -25
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/llm-backend-resolver.js +23 -5
- package/dist/memory/llm-backend-resolver.js.map +1 -1
- package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
- package/dist/nexus/migrations/M-split-graph.js +60 -53
- package/dist/nexus/migrations/M-split-graph.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +20 -2
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/release/engine-ops.js +2 -2
- package/dist/release/engine-ops.js.map +1 -1
- package/dist/routing/capability-matrix.d.ts.map +1 -1
- package/dist/routing/capability-matrix.js +0 -57
- package/dist/routing/capability-matrix.js.map +1 -1
- package/dist/selfimprove/budget.d.ts +206 -0
- package/dist/selfimprove/budget.d.ts.map +1 -0
- package/dist/selfimprove/budget.js +203 -0
- package/dist/selfimprove/budget.js.map +1 -0
- package/dist/selfimprove/dhq-adapter.d.ts +105 -0
- package/dist/selfimprove/dhq-adapter.d.ts.map +1 -0
- package/dist/selfimprove/dhq-adapter.js +95 -0
- package/dist/selfimprove/dhq-adapter.js.map +1 -0
- package/dist/selfimprove/draft-pr.d.ts +129 -0
- package/dist/selfimprove/draft-pr.d.ts.map +1 -0
- package/dist/selfimprove/draft-pr.js +158 -0
- package/dist/selfimprove/draft-pr.js.map +1 -0
- package/dist/selfimprove/envelope-diff.d.ts +162 -0
- package/dist/selfimprove/envelope-diff.d.ts.map +1 -0
- package/dist/selfimprove/envelope-diff.js +321 -0
- package/dist/selfimprove/envelope-diff.js.map +1 -0
- package/dist/selfimprove/replay.d.ts +121 -0
- package/dist/selfimprove/replay.d.ts.map +1 -0
- package/dist/selfimprove/replay.js +109 -0
- package/dist/selfimprove/replay.js.map +1 -0
- package/dist/selfimprove/run-loop.d.ts +148 -0
- package/dist/selfimprove/run-loop.d.ts.map +1 -0
- package/dist/selfimprove/run-loop.js +240 -0
- package/dist/selfimprove/run-loop.js.map +1 -0
- package/dist/selfimprove/scenario.d.ts +145 -0
- package/dist/selfimprove/scenario.d.ts.map +1 -0
- package/dist/selfimprove/scenario.js +243 -0
- package/dist/selfimprove/scenario.js.map +1 -0
- package/dist/sentient/daemon-entry.js +5 -0
- package/dist/sentient/daemon-entry.js.map +1 -1
- package/dist/sentient/daemon.d.ts.map +1 -1
- package/dist/sentient/daemon.js +19 -0
- package/dist/sentient/daemon.js.map +1 -1
- package/dist/sentient/hygiene-scan.d.ts.map +1 -1
- package/dist/sentient/hygiene-scan.js +14 -6
- package/dist/sentient/hygiene-scan.js.map +1 -1
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +13 -9
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/connection-session-handle.d.ts +161 -0
- package/dist/sessions/connection-session-handle.d.ts.map +1 -0
- package/dist/sessions/connection-session-handle.js +168 -0
- package/dist/sessions/connection-session-handle.js.map +1 -0
- package/dist/sessions/handoff.d.ts.map +1 -1
- package/dist/sessions/handoff.js +9 -0
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts +4 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +31 -1
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-id.d.ts +34 -0
- package/dist/sessions/session-id.d.ts.map +1 -1
- package/dist/sessions/session-id.js +37 -0
- package/dist/sessions/session-id.js.map +1 -1
- package/dist/sessions/session-manifest-mirror.d.ts +115 -0
- package/dist/sessions/session-manifest-mirror.d.ts.map +1 -0
- package/dist/sessions/session-manifest-mirror.js +250 -0
- package/dist/sessions/session-manifest-mirror.js.map +1 -0
- package/dist/sessions/session-switch.d.ts.map +1 -1
- package/dist/sessions/session-switch.js +5 -2
- package/dist/sessions/session-switch.js.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +2 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +2 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +87 -47
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/pi-session-store.d.ts +151 -0
- package/dist/store/pi-session-store.d.ts.map +1 -0
- package/dist/store/pi-session-store.js +166 -0
- package/dist/store/pi-session-store.js.map +1 -0
- package/dist/store/safety-data-accessor.d.ts +1 -0
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +5 -0
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/schema/cleo-global/accounts.d.ts +357 -0
- package/dist/store/schema/cleo-global/accounts.d.ts.map +1 -0
- package/dist/store/schema/cleo-global/accounts.js +136 -0
- package/dist/store/schema/cleo-global/accounts.js.map +1 -0
- package/dist/store/schema/cleo-global/index.d.ts +2 -0
- package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/index.js +2 -0
- package/dist/store/schema/cleo-global/index.js.map +1 -1
- package/dist/store/schema/cleo-global/session-manifest.d.ts +217 -0
- package/dist/store/schema/cleo-global/session-manifest.d.ts.map +1 -0
- package/dist/store/schema/cleo-global/session-manifest.js +99 -0
- package/dist/store/schema/cleo-global/session-manifest.js.map +1 -0
- package/dist/store/schema/cleo-project/tasks-core.d.ts +16 -0
- package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/tasks-core.js +14 -0
- package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
- package/dist/store/schema/tasks.d.ts +16 -0
- package/dist/store/schema/tasks.d.ts.map +1 -1
- package/dist/store/schema/tasks.js +10 -0
- package/dist/store/schema/tasks.js.map +1 -1
- package/dist/store/selfimprove-dhq-schema.d.ts +284 -0
- package/dist/store/selfimprove-dhq-schema.d.ts.map +1 -0
- package/dist/store/selfimprove-dhq-schema.js +128 -0
- package/dist/store/selfimprove-dhq-schema.js.map +1 -0
- package/dist/store/selfimprove-dhq-store.d.ts +175 -0
- package/dist/store/selfimprove-dhq-store.d.ts.map +1 -0
- package/dist/store/selfimprove-dhq-store.js +182 -0
- package/dist/store/selfimprove-dhq-store.js.map +1 -0
- package/dist/store/session-store.d.ts +52 -13
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +71 -13
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +7 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +1 -0
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +5 -0
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +32 -0
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/store/writer-lease-schema.d.ts +392 -0
- package/dist/store/writer-lease-schema.d.ts.map +1 -0
- package/dist/store/writer-lease-schema.js +142 -0
- package/dist/store/writer-lease-schema.js.map +1 -0
- package/dist/store/writer-lease.d.ts +368 -0
- package/dist/store/writer-lease.d.ts.map +1 -0
- package/dist/store/writer-lease.js +1002 -0
- package/dist/store/writer-lease.js.map +1 -0
- package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
- package/dist/tasks/backfill-child-projections.js +14 -9
- package/dist/tasks/backfill-child-projections.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +7 -10
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +14 -7
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +10 -4
- package/dist/telemetry/index.js.map +1 -1
- package/dist/tools/agent-registry.d.ts +250 -0
- package/dist/tools/agent-registry.d.ts.map +1 -0
- package/dist/tools/agent-registry.js +292 -0
- package/dist/tools/agent-registry.js.map +1 -0
- package/dist/tools/agent-tool-families.d.ts +107 -0
- package/dist/tools/agent-tool-families.d.ts.map +1 -0
- package/dist/tools/agent-tool-families.js +527 -0
- package/dist/tools/agent-tool-families.js.map +1 -0
- package/dist/tools/browser-driver.d.ts +183 -0
- package/dist/tools/browser-driver.d.ts.map +1 -0
- package/dist/tools/browser-driver.js +242 -0
- package/dist/tools/browser-driver.js.map +1 -0
- package/dist/tools/builtin-agent-tools.d.ts +36 -0
- package/dist/tools/builtin-agent-tools.d.ts.map +1 -0
- package/dist/tools/builtin-agent-tools.js +150 -0
- package/dist/tools/builtin-agent-tools.js.map +1 -0
- package/dist/tools/dispatch.d.ts +370 -0
- package/dist/tools/dispatch.d.ts.map +1 -0
- package/dist/tools/dispatch.js +505 -0
- package/dist/tools/dispatch.js.map +1 -0
- package/dist/tools/env-scrub.d.ts +93 -0
- package/dist/tools/env-scrub.d.ts.map +1 -0
- package/dist/tools/env-scrub.js +176 -0
- package/dist/tools/env-scrub.js.map +1 -0
- package/dist/tools/fs.d.ts +30 -0
- package/dist/tools/fs.d.ts.map +1 -1
- package/dist/tools/fs.js +55 -2
- package/dist/tools/fs.js.map +1 -1
- package/dist/tools/guard.d.ts +15 -0
- package/dist/tools/guard.d.ts.map +1 -1
- package/dist/tools/guard.js +49 -12
- package/dist/tools/guard.js.map +1 -1
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +37 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/pty.d.ts +45 -0
- package/dist/tools/pty.d.ts.map +1 -0
- package/dist/tools/pty.js +166 -0
- package/dist/tools/pty.js.map +1 -0
- package/dist/tools/schema-gen.d.ts +57 -0
- package/dist/tools/schema-gen.d.ts.map +1 -0
- package/dist/tools/schema-gen.js +52 -0
- package/dist/tools/schema-gen.js.map +1 -0
- package/dist/tools/shell.d.ts +12 -0
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +14 -1
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/web-agent-tools.d.ts +72 -0
- package/dist/tools/web-agent-tools.d.ts.map +1 -0
- package/dist/tools/web-agent-tools.js +393 -0
- package/dist/tools/web-agent-tools.js.map +1 -0
- package/dist/tools/web-search-backends.d.ts +156 -0
- package/dist/tools/web-search-backends.d.ts.map +1 -0
- package/dist/tools/web-search-backends.js +290 -0
- package/dist/tools/web-search-backends.js.map +1 -0
- package/dist/validation/ops.d.ts +1 -15
- package/dist/validation/ops.d.ts.map +1 -1
- package/dist/validation/ops.js +0 -20
- package/dist/validation/ops.js.map +1 -1
- package/migrations/drizzle-cleo-global/20260607000000_t11891-writer-leases/migration.sql +55 -0
- package/migrations/drizzle-cleo-global/20260607010000_t11639-session-manifest/migration.sql +43 -0
- package/migrations/drizzle-cleo-global/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
- package/migrations/drizzle-cleo-global/20260608010000_t11709-accounts-credential-pool/migration.sql +72 -0
- package/migrations/drizzle-cleo-global/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
- package/migrations/drizzle-cleo-project/20260607000000_t11891-writer-leases/migration.sql +55 -0
- package/migrations/drizzle-cleo-project/20260607010000_t11639-session-parent/migration.sql +22 -0
- package/migrations/drizzle-cleo-project/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
- package/migrations/drizzle-cleo-project/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
- package/package.json +15 -13
- package/dist/lifecycle/chain-composition.d.ts +0 -30
- package/dist/lifecycle/chain-composition.d.ts.map +0 -1
- package/dist/lifecycle/chain-composition.js +0 -152
- package/dist/lifecycle/chain-composition.js.map +0 -1
- package/dist/lifecycle/chain-store.d.ts +0 -70
- package/dist/lifecycle/chain-store.d.ts.map +0 -1
- package/dist/lifecycle/chain-store.js +0 -246
- package/dist/lifecycle/chain-store.js.map +0 -1
- package/dist/lifecycle/default-chain.d.ts +0 -39
- package/dist/lifecycle/default-chain.d.ts.map +0 -1
- package/dist/lifecycle/default-chain.js +0 -176
- package/dist/lifecycle/default-chain.js.map +0 -1
- package/dist/lifecycle/tessera-engine.d.ts +0 -48
- package/dist/lifecycle/tessera-engine.d.ts.map +0 -1
- package/dist/lifecycle/tessera-engine.js +0 -249
- package/dist/lifecycle/tessera-engine.js.map +0 -1
- package/dist/validation/chain-validation.d.ts +0 -43
- package/dist/validation/chain-validation.d.ts.map +0 -1
- package/dist/validation/chain-validation.js +0 -146
- package/dist/validation/chain-validation.js.map +0 -1
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleo-owned Pi `StreamFn` — the Gate-13-respecting LLM route (T11761 · S2 · T11898).
|
|
3
|
+
*
|
|
4
|
+
* Pi's agent loop performs every LLM call through a single pluggable seam: the
|
|
5
|
+
* `streamFn` passed as the 6th positional arg to `runAgentLoop`. The DEFAULT
|
|
6
|
+
* streamFn (`pi-ai`'s `streamSimple`) resolves a provider from `pi-ai`'s own
|
|
7
|
+
* registry and falls back to reading `process.env[<PROVIDER>_API_KEY]` when no
|
|
8
|
+
* explicit key is supplied — a credential-resolution path OUTSIDE Cleo's E9
|
|
9
|
+
* chokepoint, and a Gate-13 violation.
|
|
10
|
+
*
|
|
11
|
+
* {@link createPiStreamFn} supplies a Cleo-owned replacement that routes the
|
|
12
|
+
* loop's LLM calls through {@link resolveLLMForSystem} (the E9 resolution
|
|
13
|
+
* chokepoint) → {@link ModelRunner.build} (the single SSoT transport factory).
|
|
14
|
+
* Passing this streamFn to `runAgentLoop` means `pi-ai`'s `stream.ts` /
|
|
15
|
+
* `withEnvApiKey` is NEVER reached for the loop — the registry env-fallback
|
|
16
|
+
* cannot fire (foundation §5.1, the single most important suppression lever).
|
|
17
|
+
*
|
|
18
|
+
* ## Detached-producer teardown (T11898)
|
|
19
|
+
*
|
|
20
|
+
* The returned `StreamFn` MUST return its stream synchronously, so the async
|
|
21
|
+
* producer is detached (`void produce(...)`). To stop that producer outliving
|
|
22
|
+
* the call that started it, `ctx.signal` (the `wrapPiCall`-managed loop abort
|
|
23
|
+
* signal) is threaded into the per-call `SendOptions.signal` AND the producer's
|
|
24
|
+
* consumption loop bails on `signal.aborted` and explicitly returns the
|
|
25
|
+
* iterator. Teardown therefore holds even against a transport that ignores the
|
|
26
|
+
* signal option — closing the residual exit-escape window the daemon exit-guard
|
|
27
|
+
* (`installDaemonExitGuard`) backstops.
|
|
28
|
+
*
|
|
29
|
+
* ## Gate-13 cleanliness (verified)
|
|
30
|
+
*
|
|
31
|
+
* This file CALLS `resolveLLMForSystem` + `ModelRunner.build` only. It constructs
|
|
32
|
+
* NO transport (`new *Transport`), NO SDK client (`createAnthropic` /
|
|
33
|
+
* `new Anthropic`), reads NO `*_API_KEY` env var, and carries NO hardcoded model
|
|
34
|
+
* literal — all of that stays inside `model-runner.ts` / `transports/**` (the
|
|
35
|
+
* Gate-13 allowlist). The descriptor's `model` comes from the resolver
|
|
36
|
+
* (registry / role-config), never a literal here.
|
|
37
|
+
*
|
|
38
|
+
* ## Tool wire-through (T1739 — registry consumability)
|
|
39
|
+
*
|
|
40
|
+
* The Pi loop carries its tools (the agent registry's `toOpenAITools()` output) on
|
|
41
|
+
* `Context.tools`. {@link toTransportTools} projects them onto the per-call
|
|
42
|
+
* `SendOptions.tools`, which `ConcreteSession._buildRequest` forwards onto
|
|
43
|
+
* `TransportRequest.tools` — so the wire-level transport advertises them to the
|
|
44
|
+
* model. This closes the streamFn → transport tool link: registry tools given to
|
|
45
|
+
* the loop are reachable by the model. (Tool-CALL *execution* — binding Pi's
|
|
46
|
+
* `ExecutionEnv` onto the guarded surface — is a later subtask; only the schema
|
|
47
|
+
* advertisement flows here.)
|
|
48
|
+
*
|
|
49
|
+
* ## Zod ↔ TypeBox quarantine (Gate 10)
|
|
50
|
+
*
|
|
51
|
+
* Pi tool schemas are TypeBox, but `pi-ai`'s `validateToolArguments` also accepts
|
|
52
|
+
* plain JSON-schema tools. Cleo tool definitions are Zod (live in `core/src/llm/`).
|
|
53
|
+
* {@link zodToolToTransportTool} converts a Zod schema → JSON Schema via Zod v4's
|
|
54
|
+
* native `z.toJSONSchema` (NO `zod-to-json-schema` dep, NO typebox value-import),
|
|
55
|
+
* so the cleo↔Pi tool boundary carries ZERO typebox. {@link toTransportTools}
|
|
56
|
+
* passes the loop's Pi `Tool.parameters` (a TypeBox `TSchema` that is structurally
|
|
57
|
+
* a JSON Schema object) through verbatim — also WITHOUT a typebox value-import.
|
|
58
|
+
* typebox remains a transitive dep used only INSIDE `pi-agent-core`; it never
|
|
59
|
+
* appears in cleo source and never reaches `packages/contracts/`.
|
|
60
|
+
*
|
|
61
|
+
* @epic T10403
|
|
62
|
+
* @task T11761
|
|
63
|
+
* @task T11898
|
|
64
|
+
* @task T1739
|
|
65
|
+
*/
|
|
66
|
+
// VALUE import: the FACTORY that builds the stream Pi's `StreamFn` MUST return.
|
|
67
|
+
// `AssistantMessageEventStream` itself collides in the `pi-ai` barrel (re-exported
|
|
68
|
+
// both as a value AND as a type-only name), so the class cannot be value-imported;
|
|
69
|
+
// `createAssistantMessageEventStream()` is the clean value export. Importing it
|
|
70
|
+
// from the `pi-ai` barrel evaluates `register-builtins` (populates the registry
|
|
71
|
+
// with inert lazy closures — NO env read, NO client construction at import;
|
|
72
|
+
// foundation §3.2). We OWN the loop's LLM path via this custom streamFn, so the
|
|
73
|
+
// registry is never CONSULTED — populated-but-unused, the accepted inert side
|
|
74
|
+
// effect, not a leak.
|
|
75
|
+
import { createAssistantMessageEventStream } from '@earendil-works/pi-ai';
|
|
76
|
+
import { getLogger } from '../../logger.js';
|
|
77
|
+
import { zodSchemaToOpenAITool } from '../../tools/schema-gen.js';
|
|
78
|
+
import { ModelRunner } from '../model-runner.js';
|
|
79
|
+
import { resolveLLMForSystem } from '../system-resolver.js';
|
|
80
|
+
import { wrapPiError } from './pi-errors.js';
|
|
81
|
+
/**
|
|
82
|
+
* Convert a Cleo Zod-schema tool into a JSON-schema {@link TransportTool}.
|
|
83
|
+
*
|
|
84
|
+
* Thin wrapper over the SINGLE shared generator
|
|
85
|
+
* {@link zodSchemaToOpenAITool} (`core/src/tools/schema-gen.ts`) so the Pi bridge
|
|
86
|
+
* and the agent registry (T1739 · AC3) share ONE conversion doctrine and cannot
|
|
87
|
+
* drift (DRY). Uses Zod v4's native `z.toJSONSchema` — no `zod-to-json-schema`
|
|
88
|
+
* dependency and, crucially, NO typebox value-import. The resulting `inputSchema`
|
|
89
|
+
* is a plain JSON Schema object the transport passes through verbatim.
|
|
90
|
+
*
|
|
91
|
+
* @param tool - The Cleo Zod tool.
|
|
92
|
+
* @returns The transport-shaped JSON-schema tool.
|
|
93
|
+
*/
|
|
94
|
+
export function zodToolToTransportTool(tool) {
|
|
95
|
+
return zodSchemaToOpenAITool(tool);
|
|
96
|
+
}
|
|
97
|
+
const logger = getLogger('pi-stream-fn');
|
|
98
|
+
/**
|
|
99
|
+
* Build a Cleo-owned {@link StreamFn} for one Pi agent run.
|
|
100
|
+
*
|
|
101
|
+
* The returned function matches Pi's `StreamFn` contract structurally:
|
|
102
|
+
* `(model, context, options?) => AssistantMessageEventStream`. It MUST NOT throw
|
|
103
|
+
* — every failure is encoded as a terminal `error` event on the returned stream
|
|
104
|
+
* (Pi's never-throw streaming contract).
|
|
105
|
+
*
|
|
106
|
+
* Flow per call:
|
|
107
|
+
* 1. `resolveLLMForSystem(ctx.system)` — the E9 resolution chokepoint.
|
|
108
|
+
* 2. Build a clean {@link ResolvedLLMDescriptor} from the resolved fields.
|
|
109
|
+
* 3. `ModelRunner.build(descriptor)` — the single SSoT transport factory.
|
|
110
|
+
* 4. Stream `NormalizedDelta` chunks from the built transport session and
|
|
111
|
+
* project them onto Pi's `AssistantMessageEvent` protocol, terminating with
|
|
112
|
+
* a `done` (success) or `error` (failure) event.
|
|
113
|
+
*
|
|
114
|
+
* `pi-ai`'s `stream.ts` / `withEnvApiKey` is never reached — the registry
|
|
115
|
+
* env-fallback cannot fire for the loop.
|
|
116
|
+
*
|
|
117
|
+
* @param ctx - The Pi run context (system-of-use label + identity + signal).
|
|
118
|
+
* @returns A Cleo-owned `StreamFn`.
|
|
119
|
+
*/
|
|
120
|
+
export function createPiStreamFn(ctx) {
|
|
121
|
+
return (model, context, options) => {
|
|
122
|
+
const out = createAssistantMessageEventStream();
|
|
123
|
+
// Detach the async producer; the stream itself is returned synchronously so
|
|
124
|
+
// the loop can begin consuming immediately (Pi's contract).
|
|
125
|
+
void produce(out, model, context, options, ctx).catch((err) => {
|
|
126
|
+
// A failure escaping the producer is encoded as a terminal error event —
|
|
127
|
+
// never thrown (Pi's `StreamFn` must not throw / reject).
|
|
128
|
+
emitError(out, model, wrapPiError(err).message);
|
|
129
|
+
});
|
|
130
|
+
return out;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Drive the cleo transport session and project its deltas onto Pi's event stream.
|
|
135
|
+
*
|
|
136
|
+
* @param out - The Pi event stream to push events onto.
|
|
137
|
+
* @param model - Pi's model descriptor for this call (id/provider/api carried for
|
|
138
|
+
* the terminal `AssistantMessage` shape; resolution is by `ctx.system`, NOT by
|
|
139
|
+
* this model id — the resolver/registry is the SSoT).
|
|
140
|
+
* @param context - The Pi request context (system prompt + messages + tools). The
|
|
141
|
+
* `tools` (the agent registry's `toOpenAITools()` output, set on `Context.tools`
|
|
142
|
+
* by the loop) are projected onto the per-call `SendOptions.tools` →
|
|
143
|
+
* `TransportRequest.tools`, so the wire-level transport advertises them.
|
|
144
|
+
* @param _options - Pi stream options (reserved; thinking/temperature flow via
|
|
145
|
+
* the resolved descriptor's capabilities in a later subtask).
|
|
146
|
+
* @param ctx - The Pi run context (system-of-use label + loop abort `signal`
|
|
147
|
+
* threaded into the per-call `SendOptions` and the producer teardown).
|
|
148
|
+
*/
|
|
149
|
+
async function produce(out, model, context, _options, ctx) {
|
|
150
|
+
// 1. E9 resolution chokepoint. Never throws (resolver contract).
|
|
151
|
+
const resolved = await resolveLLMForSystem(ctx.system, {
|
|
152
|
+
...(ctx.projectRoot !== undefined ? { projectRoot: ctx.projectRoot } : {}),
|
|
153
|
+
});
|
|
154
|
+
if (!resolved.sealedCredential && resolved.authType !== 'aws_sdk') {
|
|
155
|
+
// No credential reachable — surface a typed terminal error (graceful: the
|
|
156
|
+
// loop sees an error AssistantMessage and stops, the daemon is unharmed).
|
|
157
|
+
emitError(out, model, `no credential resolved for system "${ctx.system}"`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// 2. Clean descriptor from resolved fields (NO model literal here — the model
|
|
161
|
+
// is whatever the resolver/registry produced). The plaintext token is
|
|
162
|
+
// materialized from the sealed handle ONLY here, at the wire boundary that
|
|
163
|
+
// feeds ModelRunner — never carried inline on the resolver envelope (E10).
|
|
164
|
+
const descriptor = await toDescriptor(resolved);
|
|
165
|
+
// 3. Single SSoT transport factory. The transport/client construction lives
|
|
166
|
+
// inside ModelRunner — this file constructs nothing.
|
|
167
|
+
const built = await ModelRunner.build(descriptor);
|
|
168
|
+
// 4. Stream deltas → Pi events.
|
|
169
|
+
const aggregate = freshAssistantMessage(descriptor.model, model);
|
|
170
|
+
out.push({ type: 'start', partial: aggregate });
|
|
171
|
+
const messages = toTransportMessages(context);
|
|
172
|
+
let text = '';
|
|
173
|
+
let stop = 'stop';
|
|
174
|
+
let started = false;
|
|
175
|
+
// Thread the run's abort signal into the per-call SendOptions so the session
|
|
176
|
+
// can observe it. The signal is the SAME `wrapPiCall`-managed signal handed to
|
|
177
|
+
// the loop — when the loop aborts (or `wrapPiCall` settles/tears down), this
|
|
178
|
+
// detached producer is told to stop. CRUCIALLY, abort teardown does NOT rely on
|
|
179
|
+
// the transport honouring the signal: the `for await` below also bails on
|
|
180
|
+
// `signal.aborted` and explicitly returns the iterator, so the producer cannot
|
|
181
|
+
// outlive the call even against a transport that ignores the option (T11898).
|
|
182
|
+
const signal = ctx.signal;
|
|
183
|
+
if (signal?.aborted) {
|
|
184
|
+
emitAborted(out, model);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Thread the loop's tools (the agent registry's `toOpenAITools()` output, set on
|
|
188
|
+
// `Context.tools` by the loop) onto the per-call `SendOptions` so the wire-level
|
|
189
|
+
// transport advertises them to the model. This is the streamFn → session.stream
|
|
190
|
+
// → `TransportRequest.tools` link that makes registry tools reachable by the
|
|
191
|
+
// model. Omitted when the loop carries no tools (a tool-free call).
|
|
192
|
+
const tools = toTransportTools(context);
|
|
193
|
+
const sendOpts = signal && tools.length > 0
|
|
194
|
+
? { signal, tools }
|
|
195
|
+
: signal
|
|
196
|
+
? { signal }
|
|
197
|
+
: tools.length > 0
|
|
198
|
+
? { tools }
|
|
199
|
+
: {};
|
|
200
|
+
const stream = built.session.stream(messages, sendOpts);
|
|
201
|
+
const iterator = stream[Symbol.asyncIterator]();
|
|
202
|
+
// Proactive teardown: the instant the signal aborts — even mid-`next()` await —
|
|
203
|
+
// call the iterator's `return()` so a transport that ignores `SendOptions.signal`
|
|
204
|
+
// still has its underlying stream torn down. The per-iteration `signal.aborted`
|
|
205
|
+
// check below is the cooperative second line that emits the terminal event.
|
|
206
|
+
const onAbort = () => {
|
|
207
|
+
void closeIterator(iterator);
|
|
208
|
+
};
|
|
209
|
+
if (signal)
|
|
210
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
211
|
+
try {
|
|
212
|
+
while (true) {
|
|
213
|
+
if (signal?.aborted) {
|
|
214
|
+
// Loop aborted (or wrapPiCall settled) — tear the iterator down so the
|
|
215
|
+
// detached producer stops streaming, then emit a terminal aborted event.
|
|
216
|
+
await closeIterator(iterator);
|
|
217
|
+
emitAborted(out, model);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const next = await iterator.next();
|
|
221
|
+
if (next.done)
|
|
222
|
+
break;
|
|
223
|
+
const delta = next.value;
|
|
224
|
+
if (delta.text) {
|
|
225
|
+
if (!started) {
|
|
226
|
+
started = true;
|
|
227
|
+
out.push({ type: 'text_start', contentIndex: 0, partial: aggregate });
|
|
228
|
+
}
|
|
229
|
+
text += delta.text;
|
|
230
|
+
setText(aggregate, text);
|
|
231
|
+
out.push({ type: 'text_delta', contentIndex: 0, delta: delta.text, partial: aggregate });
|
|
232
|
+
}
|
|
233
|
+
if (delta.stopReason) {
|
|
234
|
+
stop = normalizeStop(delta.stopReason);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
// An abort surfacing as a thrown error → terminal aborted event; any other
|
|
240
|
+
// mid-stream transport failure → terminal error event (never thrown).
|
|
241
|
+
await closeIterator(iterator);
|
|
242
|
+
if (signal?.aborted || isAbortError(err)) {
|
|
243
|
+
emitAborted(out, model);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
emitError(out, model, wrapPiError(err).message);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
// Always detach the abort listener — every early `return` above runs this.
|
|
251
|
+
if (signal)
|
|
252
|
+
signal.removeEventListener('abort', onAbort);
|
|
253
|
+
}
|
|
254
|
+
if (started) {
|
|
255
|
+
out.push({ type: 'text_end', contentIndex: 0, content: text, partial: aggregate });
|
|
256
|
+
}
|
|
257
|
+
setText(aggregate, text);
|
|
258
|
+
aggregate.stopReason = stop;
|
|
259
|
+
logger.debug({ system: ctx.system, model: descriptor.model, stop }, 'pi stream complete');
|
|
260
|
+
out.push({ type: 'done', reason: doneReason(stop), message: aggregate });
|
|
261
|
+
out.end(aggregate);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Build a {@link ResolvedLLMDescriptor} from a resolved-for-system envelope.
|
|
265
|
+
*
|
|
266
|
+
* Only the descriptor surface `ModelRunner.build` consumes is projected — the
|
|
267
|
+
* resolver's extra `client` field is dropped so no SDK client leaks through this
|
|
268
|
+
* boundary. The `model` comes from the resolver (registry/role-config), never a
|
|
269
|
+
* literal.
|
|
270
|
+
*
|
|
271
|
+
* E10 (T11753): the plaintext token is materialized HERE — at the wire boundary
|
|
272
|
+
* that feeds `ModelRunner` — by invoking `resolved.sealedCredential.fetch()`.
|
|
273
|
+
* It is written into the descriptor's `credential.apiKey` (consumed only inside
|
|
274
|
+
* the `ModelRunner` chokepoint) and never returned up the resolver stack. This
|
|
275
|
+
* is async because `fetch()` is the on-demand decrypt point.
|
|
276
|
+
*
|
|
277
|
+
* @param resolved - The `resolveLLMForSystem` envelope.
|
|
278
|
+
* @returns A clean descriptor for `ModelRunner.build`.
|
|
279
|
+
*/
|
|
280
|
+
async function toDescriptor(resolved) {
|
|
281
|
+
// Materialize the plaintext from the sealed handle ONLY at this wire boundary.
|
|
282
|
+
const apiKey = resolved.sealedCredential ? (await resolved.sealedCredential.fetch()).value : null;
|
|
283
|
+
return {
|
|
284
|
+
provider: resolved.provider,
|
|
285
|
+
model: resolved.model,
|
|
286
|
+
credential: resolved.credential
|
|
287
|
+
? {
|
|
288
|
+
provider: resolved.credential.provider,
|
|
289
|
+
apiKey,
|
|
290
|
+
source: resolved.credential.source,
|
|
291
|
+
authType: resolved.credential.authType,
|
|
292
|
+
}
|
|
293
|
+
: null,
|
|
294
|
+
source: resolved.source,
|
|
295
|
+
...(resolved.credentialLabel !== undefined
|
|
296
|
+
? { credentialLabel: resolved.credentialLabel }
|
|
297
|
+
: {}),
|
|
298
|
+
apiMode: resolved.apiMode,
|
|
299
|
+
baseUrl: resolved.baseUrl,
|
|
300
|
+
authType: resolved.authType,
|
|
301
|
+
...(resolved.capabilities !== undefined ? { capabilities: resolved.capabilities } : {}),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Project a Pi {@link Context} onto Cleo {@link TransportMessage}s.
|
|
306
|
+
*
|
|
307
|
+
* Pi messages carry rich content blocks; for the v0 read/stream path we project
|
|
308
|
+
* to the transport's text form. The system prompt is threaded separately by the
|
|
309
|
+
* transport (carried on the request, not as a message), so only user/assistant/
|
|
310
|
+
* tool turns are mapped.
|
|
311
|
+
*
|
|
312
|
+
* @param context - Pi's request context.
|
|
313
|
+
* @returns Cleo transport messages.
|
|
314
|
+
*/
|
|
315
|
+
function toTransportMessages(context) {
|
|
316
|
+
return context.messages.map((m) => {
|
|
317
|
+
const role = m.role === 'assistant' ? 'assistant' : m.role === 'toolResult' ? 'tool' : 'user';
|
|
318
|
+
const content = extractText(m);
|
|
319
|
+
const msg = { role, content };
|
|
320
|
+
if (m.role === 'toolResult' && m.toolCallId) {
|
|
321
|
+
return { ...msg, toolUseId: m.toolCallId };
|
|
322
|
+
}
|
|
323
|
+
return msg;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Project the Pi {@link Context}'s tools onto OpenAI-format {@link TransportTool}[]
|
|
328
|
+
* for the wire request.
|
|
329
|
+
*
|
|
330
|
+
* The agent registry (T1739) emits OpenAI-format tools via `toOpenAITools()`; the
|
|
331
|
+
* Pi loop carries tools on `Context.tools` as Pi `Tool`s whose `parameters` is a
|
|
332
|
+
* TypeBox `TSchema` — which IS a plain JSON Schema object at runtime. We map it
|
|
333
|
+
* straight onto `inputSchema` WITHOUT importing typebox's `Value` (Gate-10 / Zod↔
|
|
334
|
+
* TypeBox quarantine): the schema object is passed through structurally. This is
|
|
335
|
+
* the `streamFn → SendOptions.tools → TransportRequest.tools` link that makes the
|
|
336
|
+
* registry's tools reachable by the model.
|
|
337
|
+
*
|
|
338
|
+
* @param context - The Pi request context.
|
|
339
|
+
* @returns OpenAI-format transport tools (empty when the context carries none).
|
|
340
|
+
*/
|
|
341
|
+
function toTransportTools(context) {
|
|
342
|
+
const tools = context.tools;
|
|
343
|
+
if (!tools || tools.length === 0)
|
|
344
|
+
return [];
|
|
345
|
+
return tools.map((t) => ({
|
|
346
|
+
name: t.name,
|
|
347
|
+
description: t.description,
|
|
348
|
+
// `t.parameters` is a TypeBox `TSchema`, structurally a JSON Schema object.
|
|
349
|
+
// Structural pass-through — no typebox value-import crosses the boundary.
|
|
350
|
+
inputSchema: t.parameters,
|
|
351
|
+
}));
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Extract a plain-text representation of a Pi message's content for the v0
|
|
355
|
+
* transport projection.
|
|
356
|
+
*
|
|
357
|
+
* @param m - A Pi message (user/assistant/toolResult).
|
|
358
|
+
* @returns The concatenated visible text.
|
|
359
|
+
*/
|
|
360
|
+
function extractText(m) {
|
|
361
|
+
const content = m.content;
|
|
362
|
+
if (typeof content === 'string')
|
|
363
|
+
return content;
|
|
364
|
+
if (Array.isArray(content)) {
|
|
365
|
+
return content
|
|
366
|
+
.map((c) => typeof c === 'object' && c !== null && 'text' in c ? String(c.text) : '')
|
|
367
|
+
.join('');
|
|
368
|
+
}
|
|
369
|
+
return '';
|
|
370
|
+
}
|
|
371
|
+
/** Build a fresh, empty Pi {@link AssistantMessage} to accumulate the response into. */
|
|
372
|
+
function freshAssistantMessage(model, piModel) {
|
|
373
|
+
return {
|
|
374
|
+
role: 'assistant',
|
|
375
|
+
content: [],
|
|
376
|
+
api: piModel.api,
|
|
377
|
+
provider: piModel.provider,
|
|
378
|
+
model,
|
|
379
|
+
usage: zeroUsage(),
|
|
380
|
+
stopReason: 'stop',
|
|
381
|
+
timestamp: Date.now(),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/** Set (or replace) the single text content block on an accumulating message. */
|
|
385
|
+
function setText(message, text) {
|
|
386
|
+
const block = { type: 'text', text };
|
|
387
|
+
// Replace the content array with a single text block (v0 — no tool-call/
|
|
388
|
+
// thinking projection on this path yet).
|
|
389
|
+
message.content = text ? [block] : [];
|
|
390
|
+
}
|
|
391
|
+
/** A zeroed {@link AssistantMessage} usage record (token accounting is S3+). */
|
|
392
|
+
function zeroUsage() {
|
|
393
|
+
return {
|
|
394
|
+
input: 0,
|
|
395
|
+
output: 0,
|
|
396
|
+
cacheRead: 0,
|
|
397
|
+
cacheWrite: 0,
|
|
398
|
+
totalTokens: 0,
|
|
399
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
/** Map a Cleo normalized stop-reason string onto Pi's {@link StopReason} union. */
|
|
403
|
+
function normalizeStop(reason) {
|
|
404
|
+
switch (reason) {
|
|
405
|
+
case 'length':
|
|
406
|
+
case 'max_tokens':
|
|
407
|
+
return 'length';
|
|
408
|
+
case 'tool_use':
|
|
409
|
+
case 'toolUse':
|
|
410
|
+
return 'toolUse';
|
|
411
|
+
case 'error':
|
|
412
|
+
return 'error';
|
|
413
|
+
case 'aborted':
|
|
414
|
+
return 'aborted';
|
|
415
|
+
default:
|
|
416
|
+
return 'stop';
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/** Narrow a {@link StopReason} to the subset valid on Pi's `done` event. */
|
|
420
|
+
function doneReason(stop) {
|
|
421
|
+
return stop === 'length' ? 'length' : stop === 'toolUse' ? 'toolUse' : 'stop';
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Emit a terminal `error` event + `end` on a Pi stream (the never-throw failure
|
|
425
|
+
* channel). Used for resolution/credential/transport failures.
|
|
426
|
+
*
|
|
427
|
+
* @param out - The Pi event stream.
|
|
428
|
+
* @param piModel - The Pi model descriptor (for the error AssistantMessage shape).
|
|
429
|
+
* @param message - Human-readable failure reason.
|
|
430
|
+
*/
|
|
431
|
+
function emitError(out, piModel, message) {
|
|
432
|
+
const errMsg = {
|
|
433
|
+
role: 'assistant',
|
|
434
|
+
content: [],
|
|
435
|
+
api: piModel.api,
|
|
436
|
+
provider: piModel.provider,
|
|
437
|
+
model: piModel.id,
|
|
438
|
+
usage: zeroUsage(),
|
|
439
|
+
stopReason: 'error',
|
|
440
|
+
errorMessage: message,
|
|
441
|
+
timestamp: Date.now(),
|
|
442
|
+
};
|
|
443
|
+
out.push({ type: 'error', reason: 'error', error: errMsg });
|
|
444
|
+
out.end(errMsg);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Emit a terminal aborted `error` event + `end` on a Pi stream.
|
|
448
|
+
*
|
|
449
|
+
* Distinct from {@link emitError}: an abort is an intentional teardown (loop
|
|
450
|
+
* cancelled / `wrapPiCall` settled), so the terminal message carries
|
|
451
|
+
* `stopReason: 'aborted'` rather than `'error'`. The daemon survives either way;
|
|
452
|
+
* this just gives the loop the precise terminal reason.
|
|
453
|
+
*
|
|
454
|
+
* @param out - The Pi event stream.
|
|
455
|
+
* @param piModel - The Pi model descriptor (for the aborted AssistantMessage shape).
|
|
456
|
+
*/
|
|
457
|
+
function emitAborted(out, piModel) {
|
|
458
|
+
const abortedMsg = {
|
|
459
|
+
role: 'assistant',
|
|
460
|
+
content: [],
|
|
461
|
+
api: piModel.api,
|
|
462
|
+
provider: piModel.provider,
|
|
463
|
+
model: piModel.id,
|
|
464
|
+
usage: zeroUsage(),
|
|
465
|
+
stopReason: 'aborted',
|
|
466
|
+
errorMessage: 'pi stream aborted',
|
|
467
|
+
timestamp: Date.now(),
|
|
468
|
+
};
|
|
469
|
+
out.push({ type: 'error', reason: 'error', error: abortedMsg });
|
|
470
|
+
out.end(abortedMsg);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Tear down a stream iterator on abort/failure so the detached producer cannot
|
|
474
|
+
* keep the underlying transport stream open after the call has ended.
|
|
475
|
+
*
|
|
476
|
+
* Calls the iterator's optional `return()` (the async-iterator cancellation
|
|
477
|
+
* hook) and swallows any error it raises — teardown is best-effort and MUST NOT
|
|
478
|
+
* throw past the never-throw producer boundary.
|
|
479
|
+
*
|
|
480
|
+
* @param iterator - The async iterator driving the transport stream.
|
|
481
|
+
*/
|
|
482
|
+
async function closeIterator(iterator) {
|
|
483
|
+
try {
|
|
484
|
+
await iterator.return?.();
|
|
485
|
+
}
|
|
486
|
+
catch {
|
|
487
|
+
// Best-effort teardown — a transport that throws on early return must not
|
|
488
|
+
// escape the producer (Pi's StreamFn never throws).
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Whether a thrown value represents an abort (a `DOMException`/`Error` whose
|
|
493
|
+
* `name` is `AbortError`).
|
|
494
|
+
*
|
|
495
|
+
* @param err - The thrown value.
|
|
496
|
+
* @returns `true` when `err` is an abort error.
|
|
497
|
+
*/
|
|
498
|
+
function isAbortError(err) {
|
|
499
|
+
return (typeof err === 'object' &&
|
|
500
|
+
err !== null &&
|
|
501
|
+
'name' in err &&
|
|
502
|
+
err.name === 'AbortError');
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=pi-stream-fn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-stream-fn.js","sourceRoot":"","sources":["../../../src/llm/pi/pi-stream-fn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi ↔ dispatch-engine bridge (T1740 · AC6 · epic T11456).
|
|
3
|
+
*
|
|
4
|
+
* Closes the agent tool-call loop for the in-process Pi runner. Pi's agent loop
|
|
5
|
+
* executes a tool the model emits by calling the `execute(toolCallId, params,
|
|
6
|
+
* signal)` method of the matching `AgentTool` it finds on `AgentContext.tools`.
|
|
7
|
+
* Before T1740 the Pi adapter advertised the registry's tool SCHEMAS to the
|
|
8
|
+
* model (`pi-stream-fn.ts` → `SendOptions.tools`) but supplied NO executables —
|
|
9
|
+
* so a model tool-call had nothing to run and the loop could only stream text.
|
|
10
|
+
*
|
|
11
|
+
* {@link buildPiAgentTools} projects the {@link AgentToolRegistry} into the
|
|
12
|
+
* `AgentTool[]` the loop needs, binding each tool's `execute` body to the T1740
|
|
13
|
+
* {@link ToolDispatchEngine}. When the model emits a tool call, Pi invokes the
|
|
14
|
+
* bound `execute`, which runs the call THROUGH the dispatch engine — lookup +
|
|
15
|
+
* Zod-validate + availability + budget + guarded execution + LLM-safe
|
|
16
|
+
* formatting — and returns the classified result as an `AgentToolResult` Pi
|
|
17
|
+
* feeds back to the model as a `tool_result`. That is the closed loop:
|
|
18
|
+
*
|
|
19
|
+
* model tool-call → Pi AgentTool.execute → ToolDispatchEngine.dispatch →
|
|
20
|
+
* GuardedToolSurface side effect → formatted result → back to the model.
|
|
21
|
+
*
|
|
22
|
+
* ## Boundary cleanliness
|
|
23
|
+
*
|
|
24
|
+
* - **Gate-11** — this module defines NO atomic tool primitive; it CONSUMES the
|
|
25
|
+
* frozen registry (`toOpenAITools`-shaped schemas) and the dispatch engine.
|
|
26
|
+
* - **Gate-13** — no LLM resolution / transport / client construction here; the
|
|
27
|
+
* only LLM route stays in {@link createPiStreamFn}. Tool execution is pure
|
|
28
|
+
* side-effect dispatch through the guard.
|
|
29
|
+
* - **Gate-10** — the Pi `AgentTool.parameters` is a TypeBox `TSchema`; the
|
|
30
|
+
* registry carries Zod. We convert via the shared {@link zodSchemaToOpenAITool}
|
|
31
|
+
* generator (Zod v4 native `z.toJSONSchema`) and pass the resulting JSON-Schema
|
|
32
|
+
* object through as the (structurally-compatible) `parameters` WITHOUT a
|
|
33
|
+
* typebox value-import, matching `pi-stream-fn.ts`'s quarantine.
|
|
34
|
+
*
|
|
35
|
+
* @task T1740
|
|
36
|
+
* @epic T11456
|
|
37
|
+
* @see ../../tools/dispatch.js — the dispatch engine this binds the loop to
|
|
38
|
+
* @see ./pi-stream-fn.js — the sibling that advertises the same tools' schemas
|
|
39
|
+
*/
|
|
40
|
+
import type { AgentToolRegistry } from '../../tools/agent-registry.js';
|
|
41
|
+
import type { ToolDispatchEngine, ToolDispatchResult } from '../../tools/dispatch.js';
|
|
42
|
+
/**
|
|
43
|
+
* The minimal `AgentTool` shape `pi-agent-core` requires on
|
|
44
|
+
* `AgentContext.tools`. Declared structurally here (NOT a type-only import of
|
|
45
|
+
* `@earendil-works/pi-agent-core`'s `AgentTool`) so the bridge stays decoupled
|
|
46
|
+
* from the loop package's generic `TSchema`/`TDetails` parameterization and so a
|
|
47
|
+
* `pi-agent-core` minor cannot silently widen the contract we satisfy. The
|
|
48
|
+
* fields mirror `AgentTool` member-for-member; the loop reads exactly these.
|
|
49
|
+
*/
|
|
50
|
+
export interface PiBridgeAgentTool {
|
|
51
|
+
/** Model-visible tool name. */
|
|
52
|
+
readonly name: string;
|
|
53
|
+
/** Human-readable description shown to the model. */
|
|
54
|
+
readonly description: string;
|
|
55
|
+
/** JSON-Schema (TypeBox-structural) parameter schema for the model. */
|
|
56
|
+
readonly parameters: Record<string, unknown>;
|
|
57
|
+
/** UI label (Pi requires it; we reuse the name). */
|
|
58
|
+
readonly label: string;
|
|
59
|
+
/**
|
|
60
|
+
* Execute the tool call. Pi calls this when the model emits a matching
|
|
61
|
+
* tool-call; it routes THROUGH the dispatch engine and returns the formatted
|
|
62
|
+
* result content. Never throws — a dispatch failure becomes an error-flagged
|
|
63
|
+
* `AgentToolResult` so the loop can feed it back and continue.
|
|
64
|
+
*/
|
|
65
|
+
execute(toolCallId: string, params: unknown, signal?: AbortSignal): Promise<PiBridgeToolResult>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The `AgentToolResult` subset the loop reads back from {@link
|
|
69
|
+
* PiBridgeAgentTool.execute}. `content` is the model-facing `tool_result` body;
|
|
70
|
+
* `details` carries the structured {@link ToolDispatchResult} for logs/UI; a
|
|
71
|
+
* dispatch failure is reported via the content + the `isError`-style detail.
|
|
72
|
+
*/
|
|
73
|
+
export interface PiBridgeToolResult {
|
|
74
|
+
/** Text content blocks fed back to the model (one text block in v0). */
|
|
75
|
+
readonly content: readonly {
|
|
76
|
+
readonly type: 'text';
|
|
77
|
+
readonly text: string;
|
|
78
|
+
}[];
|
|
79
|
+
/** Structured dispatch result for logs / UI rendering. */
|
|
80
|
+
readonly details: ToolDispatchResult;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Project an {@link AgentToolRegistry} into the `AgentTool[]` the Pi loop
|
|
84
|
+
* executes, binding every tool's `execute` to the shared {@link
|
|
85
|
+
* ToolDispatchEngine} (AC6).
|
|
86
|
+
*
|
|
87
|
+
* One {@link ToolDispatchEngine} instance is shared across all returned tools so
|
|
88
|
+
* the run-scoped budget (call count / time ceilings) is enforced ACROSS the
|
|
89
|
+
* whole turn, not per tool. Each `execute`:
|
|
90
|
+
* 1. wraps Pi's `(toolCallId, params)` into a {@link ToolCall};
|
|
91
|
+
* 2. dispatches it through the engine (validate → availability → budget →
|
|
92
|
+
* guarded execution → format);
|
|
93
|
+
* 3. returns the formatted content as an `AgentToolResult` Pi feeds back.
|
|
94
|
+
*
|
|
95
|
+
* @param engine - The dispatch engine (carries registry + guard + budget).
|
|
96
|
+
* @returns The `AgentTool[]` to assign to `AgentContext.tools`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function buildPiAgentTools(engine: ToolDispatchEngine, registry: AgentToolRegistry): PiBridgeAgentTool[];
|
|
99
|
+
//# sourceMappingURL=pi-tool-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-tool-bridge.d.ts","sourceRoot":"","sources":["../../../src/llm/pi/pi-tool-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAY,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAKhG;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjG;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9E,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;CACtC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,iBAAiB,GAC1B,iBAAiB,EAAE,CAsCrB"}
|