@ouro.bot/cli 0.1.0-alpha.8 → 0.1.0-alpha.800

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.
Files changed (624) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -176
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/SerpentGuide.ouro/agent.json +83 -0
  11. package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
  13. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  14. package/assets/bluebubbles-host +264 -0
  15. package/assets/ouroboros.png +0 -0
  16. package/changelog.json +5563 -0
  17. package/deploy/unraid/Dockerfile +48 -0
  18. package/deploy/unraid/README.txt +3012 -0
  19. package/deploy/unraid/audit-container-spec.sh +4 -0
  20. package/deploy/unraid/container-runtime.json +1 -0
  21. package/deploy/unraid/docker-man-template-transaction.mjs +526 -0
  22. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  23. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  24. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  25. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  26. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  27. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  28. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  29. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  30. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  31. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  32. package/deploy/unraid/sanctuary-deployment-target.mjs +709 -0
  33. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  34. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2030 -0
  35. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  36. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  37. package/deploy/unraid/sanctuary.ouro/agent.json +24 -0
  38. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  39. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  40. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  41. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  42. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  43. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +11 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +11 -0
  47. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  48. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +23 -0
  49. package/deploy/unraid/sanctuary.xml +27 -0
  50. package/dist/a2a/card.js +57 -0
  51. package/dist/a2a/client.js +180 -0
  52. package/dist/a2a/config.js +50 -0
  53. package/dist/a2a/delegation-stores.js +56 -0
  54. package/dist/a2a/did-resolution.js +93 -0
  55. package/dist/a2a/identity.js +170 -0
  56. package/dist/a2a/inbound-share.js +107 -0
  57. package/dist/a2a/mission-result-wire.js +196 -0
  58. package/dist/a2a/onboarding.js +115 -0
  59. package/dist/a2a/pin-store.js +132 -0
  60. package/dist/a2a/seen-ledger.js +120 -0
  61. package/dist/a2a/server.js +604 -0
  62. package/dist/a2a/task-store.js +69 -0
  63. package/dist/a2a/transport.js +45 -0
  64. package/dist/a2a/types.js +3 -0
  65. package/dist/arc/attention-types.js +8 -0
  66. package/dist/arc/cares.js +360 -0
  67. package/dist/arc/episodes.js +118 -0
  68. package/dist/arc/evolution.js +490 -0
  69. package/dist/arc/flight-recorder.js +1034 -0
  70. package/dist/arc/intentions.js +134 -0
  71. package/dist/arc/json-store.js +117 -0
  72. package/dist/arc/obligations.js +386 -0
  73. package/dist/arc/packets.js +336 -0
  74. package/dist/arc/presence.js +185 -0
  75. package/dist/arc/task-lifecycle.js +57 -0
  76. package/dist/commerce/store.js +755 -0
  77. package/dist/commerce/types.js +3 -0
  78. package/dist/heart/active-work.js +1009 -0
  79. package/dist/heart/agent-entry.js +252 -3
  80. package/dist/heart/approval-files.js +113 -0
  81. package/dist/heart/approval-store.js +950 -0
  82. package/dist/heart/attachments/image-normalize.js +194 -0
  83. package/dist/heart/attachments/materialize.js +97 -0
  84. package/dist/heart/attachments/originals.js +88 -0
  85. package/dist/heart/attachments/render.js +29 -0
  86. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  87. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  88. package/dist/heart/attachments/sources/index.js +18 -0
  89. package/dist/heart/attachments/sources/telegram.js +71 -0
  90. package/dist/heart/attachments/store.js +132 -0
  91. package/dist/heart/attachments/types.js +93 -0
  92. package/dist/heart/auth/auth-flow.js +495 -0
  93. package/dist/heart/autonomy-budget.js +478 -0
  94. package/dist/heart/awaiting/await-alert.js +148 -0
  95. package/dist/heart/awaiting/await-expiry.js +143 -0
  96. package/dist/heart/awaiting/await-loader.js +91 -0
  97. package/dist/heart/awaiting/await-parser.js +149 -0
  98. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  99. package/dist/heart/awaiting/await-scheduler.js +382 -0
  100. package/dist/heart/background-operations.js +281 -0
  101. package/dist/heart/bridges/manager.js +478 -0
  102. package/dist/heart/bridges/state-machine.js +135 -0
  103. package/dist/heart/bridges/store.js +135 -0
  104. package/dist/heart/bundle-state.js +168 -0
  105. package/dist/heart/commitments.js +135 -0
  106. package/dist/heart/config-registry.js +331 -0
  107. package/dist/heart/config.js +195 -137
  108. package/dist/heart/context-loss-gauntlet.js +387 -0
  109. package/dist/heart/context-loss-sentinel.js +1157 -0
  110. package/dist/heart/core.js +2257 -338
  111. package/dist/heart/cross-chat-delivery.js +133 -0
  112. package/dist/heart/daemon/agent-config-check.js +451 -0
  113. package/dist/heart/daemon/agent-discovery.js +263 -0
  114. package/dist/heart/daemon/agent-service.js +542 -0
  115. package/dist/heart/daemon/agentic-repair.js +547 -0
  116. package/dist/heart/daemon/await-private-wake.js +59 -0
  117. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  118. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  119. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  120. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  121. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  122. package/dist/heart/daemon/cadence.js +180 -0
  123. package/dist/heart/daemon/cli-defaults.js +836 -0
  124. package/dist/heart/daemon/cli-desk.js +322 -0
  125. package/dist/heart/daemon/cli-exec.js +8730 -0
  126. package/dist/heart/daemon/cli-help.js +710 -0
  127. package/dist/heart/daemon/cli-parse.js +2719 -0
  128. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  129. package/dist/heart/daemon/cli-render.js +777 -0
  130. package/dist/heart/daemon/cli-types.js +8 -0
  131. package/dist/heart/daemon/connect-bay.js +323 -0
  132. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  133. package/dist/heart/daemon/container-healthcheck.js +112 -0
  134. package/dist/heart/daemon/container-runtime.js +97 -0
  135. package/dist/heart/daemon/container-spec-auditor-main.js +170 -0
  136. package/dist/heart/daemon/container-spec-auditor.js +236 -0
  137. package/dist/heart/daemon/daemon-bootstrap-startup.js +107 -0
  138. package/dist/heart/daemon/daemon-cli.js +30 -786
  139. package/dist/heart/daemon/daemon-entry.js +971 -13
  140. package/dist/heart/daemon/daemon-health.js +186 -0
  141. package/dist/heart/daemon/daemon-rollup.js +57 -0
  142. package/dist/heart/daemon/daemon-runtime-sync.js +287 -0
  143. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  144. package/dist/heart/daemon/daemon.js +2156 -28
  145. package/dist/heart/daemon/dns-workflow.js +394 -0
  146. package/dist/heart/daemon/doctor-types.js +8 -0
  147. package/dist/heart/daemon/doctor.js +1755 -0
  148. package/dist/heart/daemon/freshness.js +345 -0
  149. package/dist/heart/daemon/habit-private-wake.js +61 -0
  150. package/dist/heart/daemon/health-monitor.js +142 -11
  151. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  152. package/dist/heart/daemon/hooks/bundle-meta.js +226 -0
  153. package/dist/heart/daemon/http-health-probe.js +80 -0
  154. package/dist/heart/daemon/human-command-screens.js +234 -0
  155. package/dist/heart/daemon/human-readiness.js +114 -0
  156. package/dist/heart/daemon/inner-status.js +78 -0
  157. package/dist/heart/daemon/interactive-repair.js +394 -0
  158. package/dist/heart/daemon/launchd.js +188 -0
  159. package/dist/heart/daemon/log-tailer.js +82 -12
  160. package/dist/heart/daemon/logs-prune.js +132 -0
  161. package/dist/heart/daemon/mcp-canary.js +524 -0
  162. package/dist/heart/daemon/message-router.js +80 -11
  163. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  164. package/dist/heart/daemon/os-cron-deps.js +135 -0
  165. package/dist/heart/daemon/os-cron.js +22 -14
  166. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  167. package/dist/heart/daemon/ouro-entry.js +3 -1
  168. package/dist/heart/daemon/plugin-cli.js +432 -0
  169. package/dist/heart/daemon/process-manager.js +739 -54
  170. package/dist/heart/daemon/provider-discovery.js +137 -0
  171. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  172. package/dist/heart/daemon/prunable-bundle.js +144 -0
  173. package/dist/heart/daemon/pulse.js +511 -0
  174. package/dist/heart/daemon/readiness-repair.js +365 -0
  175. package/dist/heart/daemon/run-hooks.js +39 -0
  176. package/dist/heart/daemon/runtime-logging.js +92 -16
  177. package/dist/heart/daemon/runtime-metadata.js +191 -0
  178. package/dist/{repertoire/tasks/lifecycle.js → heart/daemon/runtime-mode.js} +37 -39
  179. package/dist/heart/daemon/safe-mode.js +161 -0
  180. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2609 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1866 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +976 -0
  184. package/dist/heart/daemon/sanctuary-bundle-migration.js +728 -0
  185. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  186. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  187. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  188. package/dist/heart/daemon/sense-manager.js +948 -0
  189. package/dist/heart/daemon/session-id-resolver.js +131 -0
  190. package/dist/heart/daemon/skill-management-installer.js +94 -0
  191. package/dist/heart/daemon/socket-client.js +370 -0
  192. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  193. package/dist/heart/daemon/startup-tui.js +339 -0
  194. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  195. package/dist/heart/daemon/task-scheduler.js +117 -39
  196. package/dist/heart/daemon/terminal-ui.js +499 -0
  197. package/dist/heart/daemon/thoughts.js +591 -0
  198. package/dist/heart/daemon/up-progress.js +366 -0
  199. package/dist/heart/daemon/vault-items.js +56 -0
  200. package/dist/heart/delegation.js +59 -0
  201. package/dist/heart/external-events/router.js +1414 -0
  202. package/dist/heart/habits/habit-cancel.js +810 -0
  203. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  204. package/dist/heart/habits/habit-migration.js +194 -0
  205. package/dist/heart/habits/habit-parser.js +278 -0
  206. package/dist/heart/habits/habit-runtime-state.js +93 -0
  207. package/dist/heart/habits/habit-scheduler.js +653 -0
  208. package/dist/heart/habits/habit-session-summary.js +318 -0
  209. package/dist/heart/habits/habit-session.js +636 -0
  210. package/dist/heart/{daemon → hatch}/hatch-animation.js +10 -3
  211. package/dist/heart/{daemon → hatch}/hatch-flow.js +57 -139
  212. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  213. package/dist/heart/hatch/specialist-orchestrator.js +129 -0
  214. package/dist/heart/hatch/specialist-prompt.js +102 -0
  215. package/dist/heart/hatch/specialist-tools.js +318 -0
  216. package/dist/heart/identity.js +297 -67
  217. package/dist/heart/kept-notes.js +289 -0
  218. package/dist/heart/kicks.js +2 -20
  219. package/dist/heart/machine-identity.js +161 -0
  220. package/dist/heart/mail-import-discovery.js +353 -0
  221. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  222. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  223. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  224. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  225. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  226. package/dist/heart/mailbox/mailbox-http.js +99 -0
  227. package/dist/heart/mailbox/mailbox-read.js +39 -0
  228. package/dist/heart/mailbox/mailbox-types.js +27 -0
  229. package/dist/heart/mailbox/mailbox-view.js +197 -0
  230. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  231. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  232. package/dist/heart/mailbox/readers/mail.js +375 -0
  233. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  234. package/dist/heart/mailbox/readers/sessions.js +232 -0
  235. package/dist/heart/mailbox/readers/shared.js +111 -0
  236. package/dist/heart/mcp/mcp-server.js +696 -0
  237. package/dist/heart/migrate-config.js +100 -0
  238. package/dist/heart/model-capabilities.js +59 -0
  239. package/dist/heart/orientation-frame.js +345 -0
  240. package/dist/heart/platform.js +81 -0
  241. package/dist/heart/primitives.js +1 -1
  242. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  243. package/dist/heart/private-runtime/index.js +18 -0
  244. package/dist/heart/private-runtime/ledger.js +221 -0
  245. package/dist/heart/private-runtime/policy.js +252 -0
  246. package/dist/heart/private-runtime/types.js +2 -0
  247. package/dist/heart/progress-story.js +42 -0
  248. package/dist/heart/provider-attempt.js +137 -0
  249. package/dist/heart/provider-binding-resolver.js +273 -0
  250. package/dist/heart/provider-credentials.js +449 -0
  251. package/dist/heart/provider-failover.js +311 -0
  252. package/dist/heart/provider-models.js +96 -0
  253. package/dist/heart/provider-ping.js +265 -0
  254. package/dist/heart/provider-readiness-cache.js +119 -0
  255. package/dist/heart/provider-visibility.js +188 -0
  256. package/dist/heart/providers/anthropic-token.js +131 -0
  257. package/dist/heart/providers/anthropic.js +236 -58
  258. package/dist/heart/providers/azure.js +104 -13
  259. package/dist/heart/providers/error-classification.js +127 -0
  260. package/dist/heart/providers/github-copilot.js +145 -0
  261. package/dist/heart/providers/minimax-vlm.js +189 -0
  262. package/dist/heart/providers/minimax.js +29 -7
  263. package/dist/heart/providers/openai-codex-token.js +349 -0
  264. package/dist/heart/providers/openai-codex.js +63 -39
  265. package/dist/heart/providers/openai-compatible.js +177 -0
  266. package/dist/heart/run-ledger.js +247 -0
  267. package/dist/heart/runtime-capability-check.js +170 -0
  268. package/dist/heart/runtime-credentials.js +607 -0
  269. package/dist/heart/runtime-cwd.js +87 -0
  270. package/dist/heart/sense-truth.js +79 -0
  271. package/dist/heart/session-activity.js +235 -0
  272. package/dist/heart/session-events.js +1318 -0
  273. package/dist/heart/session-playback-cli-main.js +5 -0
  274. package/dist/heart/session-playback-cli.js +36 -0
  275. package/dist/heart/session-playback.js +231 -0
  276. package/dist/heart/session-stats-cli-main.js +5 -0
  277. package/dist/heart/session-stats.js +182 -0
  278. package/dist/heart/session-transcript.js +133 -0
  279. package/dist/heart/start-of-turn-packet.js +372 -0
  280. package/dist/heart/steward-policy.js +302 -0
  281. package/dist/heart/streaming.js +682 -207
  282. package/dist/heart/structured-output.js +196 -0
  283. package/dist/heart/sync-classification.js +176 -0
  284. package/dist/heart/sync.js +449 -0
  285. package/dist/heart/target-resolution.js +127 -0
  286. package/dist/heart/tempo.js +93 -0
  287. package/dist/heart/temporal-view.js +41 -0
  288. package/dist/heart/timeouts.js +101 -0
  289. package/dist/heart/tool-activity-callbacks.js +59 -0
  290. package/dist/heart/tool-approval.js +342 -0
  291. package/dist/heart/tool-description.js +155 -0
  292. package/dist/heart/tool-friction.js +55 -0
  293. package/dist/heart/tool-loop.js +200 -0
  294. package/dist/heart/turn-context.js +481 -0
  295. package/dist/heart/turn-coordinator.js +28 -0
  296. package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
  297. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  298. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  299. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  300. package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
  301. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  302. package/dist/heart/versioning/staged-restart.js +146 -0
  303. package/dist/heart/versioning/update-checker.js +116 -0
  304. package/dist/heart/versioning/update-hooks.js +154 -0
  305. package/dist/heart/versioning/version-intent.js +114 -0
  306. package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
  307. package/dist/heart/work-card.js +380 -0
  308. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  309. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  310. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  311. package/dist/mailbox-ui/index.html +16 -0
  312. package/dist/mailroom/attention.js +167 -0
  313. package/dist/mailroom/autonomy.js +209 -0
  314. package/dist/mailroom/blob-store.js +889 -0
  315. package/dist/mailroom/body-cache.js +61 -0
  316. package/dist/mailroom/cache-sync-cli.js +58 -0
  317. package/dist/mailroom/core.js +803 -0
  318. package/dist/mailroom/entry.js +160 -0
  319. package/dist/mailroom/file-store.js +568 -0
  320. package/dist/mailroom/hosted-cache-sync.js +384 -0
  321. package/dist/mailroom/mbox-import.js +393 -0
  322. package/dist/mailroom/migration.js +164 -0
  323. package/dist/mailroom/outbound.js +380 -0
  324. package/dist/mailroom/policy.js +263 -0
  325. package/dist/mailroom/reader.js +292 -0
  326. package/dist/mailroom/search-cache.js +513 -0
  327. package/dist/mailroom/search-relevance.js +319 -0
  328. package/dist/mailroom/smtp-ingress.js +176 -0
  329. package/dist/mailroom/source-state.js +176 -0
  330. package/dist/mailroom/thread.js +109 -0
  331. package/dist/mailroom/travel-extract.js +89 -0
  332. package/dist/mind/bundle-manifest.js +93 -1
  333. package/dist/mind/context.js +287 -104
  334. package/dist/mind/desk-section.js +362 -0
  335. package/dist/mind/diary-integrity.js +60 -0
  336. package/dist/mind/{memory.js → diary.js} +90 -98
  337. package/dist/mind/embedding-provider.js +60 -0
  338. package/dist/mind/file-state.js +179 -0
  339. package/dist/mind/first-impressions.js +16 -2
  340. package/dist/mind/{associative-recall.js → note-search.js} +61 -60
  341. package/dist/mind/obligation-steering.js +227 -0
  342. package/dist/mind/pending.js +102 -9
  343. package/dist/mind/phrases.js +1 -0
  344. package/dist/mind/prompt-budget.js +479 -0
  345. package/dist/mind/prompt-refresh.js +3 -2
  346. package/dist/mind/prompt.js +1377 -140
  347. package/dist/mind/provenance-trust.js +26 -0
  348. package/dist/mind/record-paths.js +312 -0
  349. package/dist/mind/scrutiny.js +173 -0
  350. package/dist/mind/session-transaction.js +415 -0
  351. package/dist/mind/token-estimate.js +8 -12
  352. package/dist/nerves/cli-logging.js +22 -3
  353. package/dist/nerves/coverage/audit-rules.js +15 -6
  354. package/dist/nerves/coverage/audit.js +28 -2
  355. package/dist/nerves/coverage/cli.js +1 -1
  356. package/dist/nerves/coverage/contract.js +5 -5
  357. package/dist/nerves/coverage/file-completeness.js +139 -5
  358. package/dist/nerves/coverage/run-artifacts.js +56 -36
  359. package/dist/nerves/coverage/source-scanner.js +4 -4
  360. package/dist/nerves/event-buffer.js +111 -0
  361. package/dist/nerves/index.js +305 -9
  362. package/dist/nerves/observation.js +20 -0
  363. package/dist/nerves/redact.js +79 -0
  364. package/dist/nerves/review/cli-main.js +5 -0
  365. package/dist/nerves/review/cli.js +156 -0
  366. package/dist/nerves/review/core.js +159 -0
  367. package/dist/nerves/runtime.js +17 -1
  368. package/dist/repertoire/ado-client.js +17 -56
  369. package/dist/repertoire/ado-semantic.js +16 -10
  370. package/dist/repertoire/api-client.js +97 -0
  371. package/dist/repertoire/bitwarden-store.js +1045 -0
  372. package/dist/repertoire/bundle-templates.js +71 -0
  373. package/dist/repertoire/bw-installer.js +180 -0
  374. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  375. package/dist/repertoire/coding/context-pack.js +331 -0
  376. package/dist/repertoire/coding/feedback.js +322 -0
  377. package/dist/repertoire/coding/index.js +18 -3
  378. package/dist/repertoire/coding/manager.js +228 -14
  379. package/dist/repertoire/coding/spawner.js +61 -14
  380. package/dist/repertoire/coding/tools.js +279 -12
  381. package/dist/repertoire/coding/workbench-client.js +272 -0
  382. package/dist/repertoire/coding/workbench-manager.js +346 -0
  383. package/dist/repertoire/commerce-errors.js +109 -0
  384. package/dist/repertoire/commerce-self-test.js +156 -0
  385. package/dist/repertoire/credential-access.js +178 -0
  386. package/dist/repertoire/data/ado-endpoints.json +188 -0
  387. package/dist/repertoire/desk/classifier.js +362 -0
  388. package/dist/repertoire/duffel-client.js +185 -0
  389. package/dist/repertoire/github-client.js +14 -55
  390. package/dist/repertoire/graph-client.js +11 -52
  391. package/dist/repertoire/guardrails.js +1083 -0
  392. package/dist/repertoire/mcp-client.js +295 -0
  393. package/dist/repertoire/mcp-manager.js +434 -0
  394. package/dist/repertoire/mcp-tools.js +83 -0
  395. package/dist/repertoire/plugin-mcp.js +175 -0
  396. package/dist/repertoire/plugins.js +253 -0
  397. package/dist/repertoire/relationship-authorization.js +194 -0
  398. package/dist/repertoire/shell-sessions.js +133 -0
  399. package/dist/repertoire/skills.js +45 -24
  400. package/dist/repertoire/stripe-client.js +131 -0
  401. package/dist/repertoire/tool-arguments.js +148 -0
  402. package/dist/repertoire/tool-results.js +29 -0
  403. package/dist/repertoire/tools-a2a.js +699 -0
  404. package/dist/repertoire/tools-attachments.js +322 -0
  405. package/dist/repertoire/tools-awaiting.js +575 -0
  406. package/dist/repertoire/tools-base.js +85 -707
  407. package/dist/repertoire/tools-bluebubbles.js +95 -0
  408. package/dist/repertoire/tools-bridge.js +144 -0
  409. package/dist/repertoire/tools-bundle.js +993 -0
  410. package/dist/repertoire/tools-commerce.js +253 -0
  411. package/dist/repertoire/tools-config.js +186 -0
  412. package/dist/repertoire/tools-continuity.js +575 -0
  413. package/dist/repertoire/tools-credential.js +383 -0
  414. package/dist/repertoire/tools-evolution.js +527 -0
  415. package/dist/repertoire/tools-files.js +344 -0
  416. package/dist/repertoire/tools-flight.js +290 -0
  417. package/dist/repertoire/tools-flow.js +119 -0
  418. package/dist/repertoire/tools-github.js +3 -8
  419. package/dist/repertoire/tools-habits.js +103 -0
  420. package/dist/repertoire/tools-mail.js +1828 -0
  421. package/dist/repertoire/tools-notes.js +485 -0
  422. package/dist/repertoire/tools-obligations.js +182 -0
  423. package/dist/repertoire/tools-orientation.js +31 -0
  424. package/dist/repertoire/tools-record.js +482 -0
  425. package/dist/repertoire/tools-rsvp.js +139 -0
  426. package/dist/repertoire/tools-runtime.js +150 -0
  427. package/dist/repertoire/tools-session.js +1108 -0
  428. package/dist/repertoire/tools-shell.js +133 -0
  429. package/dist/repertoire/tools-steward-policy.js +95 -0
  430. package/dist/repertoire/tools-stripe.js +224 -0
  431. package/dist/repertoire/tools-surface.js +369 -0
  432. package/dist/repertoire/tools-teams.js +67 -61
  433. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  434. package/dist/repertoire/tools-travel.js +125 -0
  435. package/dist/repertoire/tools-trip.js +982 -0
  436. package/dist/repertoire/tools-unraid.js +484 -0
  437. package/dist/repertoire/tools-user-profile.js +146 -0
  438. package/dist/repertoire/tools-vault.js +40 -0
  439. package/dist/repertoire/tools-voice.js +145 -0
  440. package/dist/repertoire/tools.js +441 -102
  441. package/dist/repertoire/travel-api-client.js +360 -0
  442. package/dist/repertoire/unraid-client.js +155 -0
  443. package/dist/repertoire/unraid-restart.js +212 -0
  444. package/dist/repertoire/user-profile.js +131 -0
  445. package/dist/repertoire/vault-setup.js +246 -0
  446. package/dist/repertoire/vault-unlock.js +628 -0
  447. package/dist/rsvp/aisleplanner-client.js +354 -0
  448. package/dist/rsvp/cli.js +926 -0
  449. package/dist/rsvp/config.js +327 -0
  450. package/dist/rsvp/cutover.js +433 -0
  451. package/dist/rsvp/diagnostics.js +232 -0
  452. package/dist/rsvp/diff-renderer.js +176 -0
  453. package/dist/rsvp/habit-policy.js +110 -0
  454. package/dist/rsvp/habit-stage.js +123 -0
  455. package/dist/rsvp/incident-bundle.js +97 -0
  456. package/dist/rsvp/migration.js +204 -0
  457. package/dist/rsvp/native-habit-runner.js +630 -0
  458. package/dist/rsvp/outbound-state.js +628 -0
  459. package/dist/rsvp/query.js +118 -0
  460. package/dist/rsvp/replay.js +233 -0
  461. package/dist/rsvp/snapshot.js +232 -0
  462. package/dist/rsvp/spend-ledger.js +175 -0
  463. package/dist/scripts/claude-code-hook.js +41 -0
  464. package/dist/scripts/claude-code-stop-hook.js +47 -0
  465. package/dist/senses/a2a-entry.js +115 -0
  466. package/dist/senses/attention-queue.js +186 -0
  467. package/dist/senses/await-turn-message.js +58 -0
  468. package/dist/senses/bluebubbles/active-turns.js +216 -0
  469. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  470. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  471. package/dist/senses/bluebubbles/client.js +799 -0
  472. package/dist/senses/bluebubbles/context-packet.js +207 -0
  473. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  474. package/dist/senses/bluebubbles/entry.js +90 -0
  475. package/dist/senses/bluebubbles/inbound-log.js +127 -0
  476. package/dist/senses/bluebubbles/index.js +3839 -0
  477. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  478. package/dist/senses/bluebubbles/media.js +389 -0
  479. package/dist/senses/bluebubbles/model.js +392 -0
  480. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +57 -6
  481. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  482. package/dist/senses/bluebubbles/processed-log.js +133 -0
  483. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  484. package/dist/senses/bluebubbles/replay.js +284 -0
  485. package/dist/senses/bluebubbles/runtime-state.js +137 -0
  486. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  487. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  488. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  489. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  490. package/dist/senses/cli/bracketed-paste.js +82 -0
  491. package/dist/senses/cli/image-paste.js +287 -0
  492. package/dist/senses/cli/image-ref-navigation.js +75 -0
  493. package/dist/senses/cli/ink-app.js +156 -0
  494. package/dist/senses/cli/inline-diff.js +64 -0
  495. package/dist/senses/cli/input-keys.js +174 -0
  496. package/dist/senses/cli/kill-ring.js +86 -0
  497. package/dist/senses/cli/message-list.js +51 -0
  498. package/dist/senses/cli/ouro-tui.js +607 -0
  499. package/dist/senses/cli/spinner-imperative.js +135 -0
  500. package/dist/senses/cli/spinner.js +101 -0
  501. package/dist/senses/cli/status-line.js +60 -0
  502. package/dist/senses/cli/streaming-markdown.js +526 -0
  503. package/dist/senses/cli/tool-display.js +85 -0
  504. package/dist/senses/cli/tool-render.js +85 -0
  505. package/dist/senses/cli/tui-store.js +241 -0
  506. package/dist/senses/cli/virtual-list.js +35 -0
  507. package/dist/senses/cli-entry.js +60 -8
  508. package/dist/senses/cli-layout.js +187 -0
  509. package/dist/senses/cli.js +813 -281
  510. package/dist/senses/commands.js +66 -3
  511. package/dist/senses/context-packet-ledger.js +371 -0
  512. package/dist/senses/context-packets.js +154 -0
  513. package/dist/senses/continuity.js +94 -0
  514. package/dist/senses/habit-lifecycle-guard.js +24 -0
  515. package/dist/senses/habit-turn-message.js +160 -0
  516. package/dist/senses/ingress-evidence.js +2 -0
  517. package/dist/senses/mail-entry.js +66 -0
  518. package/dist/senses/mail.js +524 -0
  519. package/dist/senses/pipeline.js +1213 -0
  520. package/dist/senses/private-runtime-worker.js +859 -0
  521. package/dist/senses/private-runtime.js +1496 -0
  522. package/dist/senses/proactive-content-guard.js +51 -0
  523. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  524. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  525. package/dist/senses/sanctuary-grounding.js +118 -0
  526. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  527. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  528. package/dist/senses/sanctuary-health-runner.js +101 -0
  529. package/dist/senses/sanctuary-health.js +408 -0
  530. package/dist/senses/sanctuary-interactive-control.js +306 -0
  531. package/dist/senses/sanctuary-media-catalog-contract.js +235 -0
  532. package/dist/senses/sanctuary-media-optimization.js +514 -0
  533. package/dist/senses/sanctuary-runtime.js +338 -0
  534. package/dist/senses/sanctuary-sab.js +85 -0
  535. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  536. package/dist/senses/shared-turn.js +571 -0
  537. package/dist/senses/surface-tool.js +109 -0
  538. package/dist/senses/teams-entry.js +60 -8
  539. package/dist/senses/teams.js +953 -211
  540. package/dist/senses/telegram-admission.js +711 -0
  541. package/dist/senses/telegram-approval-runtime.js +566 -0
  542. package/dist/senses/telegram-attachments.js +182 -0
  543. package/dist/senses/telegram-audit-ledger.js +220 -0
  544. package/dist/senses/telegram-client.js +1677 -0
  545. package/dist/senses/telegram-effect-adapter.js +859 -0
  546. package/dist/senses/telegram-entry.js +83 -0
  547. package/dist/senses/telegram.js +2026 -0
  548. package/dist/senses/trust-gate.js +207 -2
  549. package/dist/senses/voice/audio-playback.js +237 -0
  550. package/dist/senses/voice/audio-routing.js +119 -0
  551. package/dist/senses/voice/elevenlabs.js +202 -0
  552. package/dist/senses/voice/floor-control.js +431 -0
  553. package/dist/senses/voice/floor-controller.js +115 -0
  554. package/dist/senses/voice/golden-path.js +116 -0
  555. package/dist/senses/voice/index.js +29 -0
  556. package/dist/senses/voice/meeting.js +113 -0
  557. package/dist/senses/voice/outbound.js +190 -0
  558. package/dist/senses/voice/phone.js +33 -0
  559. package/dist/senses/voice/playback.js +139 -0
  560. package/dist/senses/voice/realtime-eval.js +496 -0
  561. package/dist/senses/voice/realtime-trace.js +531 -0
  562. package/dist/senses/voice/transcript.js +70 -0
  563. package/dist/senses/voice/turn.js +191 -0
  564. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  565. package/dist/senses/voice/twilio-phone.js +5081 -0
  566. package/dist/senses/voice/types.js +2 -0
  567. package/dist/senses/voice/whisper.js +161 -0
  568. package/dist/senses/voice-entry.js +81 -0
  569. package/dist/senses/voice-realtime-eval-command.js +99 -0
  570. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  571. package/dist/senses/voice-twilio-entry.js +87 -0
  572. package/dist/trips/core.js +138 -0
  573. package/dist/trips/store.js +265 -0
  574. package/dist/util/frontmatter.js +69 -0
  575. package/npm-shrinkwrap.json +8144 -0
  576. package/package.json +82 -12
  577. package/skills/agent-commerce.md +113 -0
  578. package/skills/browser-navigation.md +117 -0
  579. package/skills/commerce-setup-guide.md +116 -0
  580. package/skills/commerce-setup.md +84 -0
  581. package/skills/configure-dev-tools.md +99 -0
  582. package/skills/travel-planning.md +138 -0
  583. package/AdoptionSpecialist.ouro/agent.json +0 -20
  584. package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
  585. package/dist/heart/daemon/specialist-orchestrator.js +0 -160
  586. package/dist/heart/daemon/specialist-prompt.js +0 -47
  587. package/dist/heart/daemon/specialist-session.js +0 -142
  588. package/dist/heart/daemon/specialist-tools.js +0 -132
  589. package/dist/heart/daemon/subagent-installer.js +0 -125
  590. package/dist/inner-worker-entry.js +0 -4
  591. package/dist/mind/friends/channel.js +0 -49
  592. package/dist/mind/friends/resolver.js +0 -84
  593. package/dist/mind/friends/store-file.js +0 -171
  594. package/dist/mind/friends/store.js +0 -4
  595. package/dist/mind/friends/tokens.js +0 -26
  596. package/dist/mind/friends/types.js +0 -21
  597. package/dist/repertoire/tasks/board.js +0 -122
  598. package/dist/repertoire/tasks/index.js +0 -210
  599. package/dist/repertoire/tasks/middleware.js +0 -65
  600. package/dist/repertoire/tasks/parser.js +0 -173
  601. package/dist/repertoire/tasks/scanner.js +0 -132
  602. package/dist/repertoire/tasks/transitions.js +0 -145
  603. package/dist/senses/bluebubbles-client.js +0 -279
  604. package/dist/senses/bluebubbles-entry.js +0 -11
  605. package/dist/senses/bluebubbles-model.js +0 -253
  606. package/dist/senses/bluebubbles.js +0 -332
  607. package/dist/senses/inner-dialog-worker.js +0 -61
  608. package/dist/senses/inner-dialog.js +0 -231
  609. package/subagents/README.md +0 -73
  610. package/subagents/work-doer.md +0 -233
  611. package/subagents/work-merger.md +0 -624
  612. package/subagents/work-planner.md +0 -373
  613. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  614. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  615. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  616. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  617. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  618. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  619. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  620. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  621. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  622. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  623. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  624. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
@@ -1,96 +1,514 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FinalAnswerParser = void 0;
3
+ exports.RESPONSES_FUNCTION_CALL_OUTPUT_CAP = exports.ProviderTextOutput = exports.SettleStreamer = exports.SettleParser = exports.SettleFinalizationCallbackError = void 0;
4
+ exports.finalizeSettleStream = finalizeSettleStream;
5
+ exports.truncateResponsesFunctionCallOutput = truncateResponsesFunctionCallOutput;
4
6
  exports.toResponsesInput = toResponsesInput;
5
7
  exports.toResponsesTools = toResponsesTools;
6
8
  exports.streamChatCompletion = streamChatCompletion;
7
9
  exports.streamResponsesApi = streamResponsesApi;
8
10
  const runtime_1 = require("../nerves/runtime");
9
- // Character-level state machine that extracts the answer value from
10
- // `final_answer` tool call JSON arguments as they stream in.
11
- // Scans for prefix `"answer":"` or `"answer": "` in the character stream,
12
- // then emits text handling JSON escapes, stopping at unescaped closing `"`.
13
- class FinalAnswerParser {
14
- // Possible prefixes to match (with and without space after colon)
15
- static PREFIXES = ['"answer":"', '"answer": "'];
16
- // Buffer of characters seen so far (pre-activation only)
17
- buf = "";
11
+ class SettleFinalizationCallbackError extends Error {
12
+ retryable = false;
13
+ cause;
14
+ constructor(cause) {
15
+ const normalized = cause instanceof Error ? cause : new Error(String(cause));
16
+ super(`settle finalization callback failed: ${normalized.message}`);
17
+ this.name = "SettleFinalizationCallbackError";
18
+ this.cause = normalized;
19
+ }
20
+ }
21
+ exports.SettleFinalizationCallbackError = SettleFinalizationCallbackError;
22
+ function isJsonWhitespace(character) {
23
+ return character === " " || character === "\t" || character === "\n" || character === "\r";
24
+ }
25
+ function isHighSurrogate(character) {
26
+ const code = character.charCodeAt(0);
27
+ return code >= 0xD800 && code <= 0xDBFF;
28
+ }
29
+ function isLowSurrogate(character) {
30
+ const code = character.charCodeAt(0);
31
+ return code >= 0xDC00 && code <= 0xDFFF;
32
+ }
33
+ // Incremental JSON string decoder for the top-level `answer` property in
34
+ // streamed settle arguments. JSON.parse remains the terminal authority; this
35
+ // state machine exists only to emit validated string units before EOF.
36
+ class SettleParser {
37
+ rawArguments = "";
18
38
  _active = false;
19
39
  _complete = false;
20
- inEscape = false;
40
+ invalid = false;
41
+ terminalResult;
42
+ containers = [];
43
+ rootLastSignificant = "";
44
+ scanInString = false;
45
+ scanEscape = false;
46
+ scanStringRaw = "";
47
+ scanStringIsRootKey = false;
48
+ answerKeyState = "none";
49
+ decodeState = "normal";
50
+ unicodeDigits = "";
51
+ pendingHighSurrogate = "";
52
+ decodedAnswer = "";
21
53
  get active() { return this._active; }
22
54
  get complete() { return this._complete; }
23
55
  process(delta) {
24
- if (this._complete)
56
+ if (this.terminalResult)
57
+ return "";
58
+ this.rawArguments += delta;
59
+ if (this._complete || this.invalid)
25
60
  return "";
26
61
  let out = "";
27
62
  for (let i = 0; i < delta.length; i++) {
28
63
  const ch = delta[i];
29
- if (!this._active) {
30
- this.buf += ch;
31
- // Check if any prefix has been fully matched in the buffer
32
- for (const prefix of FinalAnswerParser.PREFIXES) {
33
- if (this.buf.endsWith(prefix)) {
34
- this._active = true;
35
- break;
36
- }
37
- }
64
+ if (this._active) {
65
+ out += this.processAnswerCharacter(ch);
38
66
  }
39
67
  else {
40
- // Active: emit characters, handling JSON escapes
41
- if (this.inEscape) {
42
- this.inEscape = false;
43
- switch (ch) {
44
- case '"':
45
- out += '"';
46
- break;
47
- case '\\':
48
- out += '\\';
49
- break;
50
- case 'n':
51
- out += '\n';
52
- break;
53
- case 't':
54
- out += '\t';
55
- break;
56
- case '/':
57
- out += '/';
58
- break;
59
- default:
60
- out += ch;
61
- break; // unknown escape: pass through character
68
+ this.scanForTopLevelAnswer(ch);
69
+ }
70
+ if (this._complete || this.invalid)
71
+ break;
72
+ }
73
+ return out;
74
+ }
75
+ finish() {
76
+ if (this.terminalResult)
77
+ return this.terminalResult;
78
+ if (this.invalid) {
79
+ return this.setTerminalFailure("invalid_settle_arguments");
80
+ }
81
+ let parsed;
82
+ try {
83
+ parsed = JSON.parse(this.rawArguments);
84
+ }
85
+ catch (error) {
86
+ const errorCode = this.isIncompleteAtEof(error)
87
+ ? "incomplete_settle_arguments"
88
+ : "invalid_settle_arguments";
89
+ return this.setTerminalFailure(errorCode);
90
+ }
91
+ if (typeof parsed !== "object"
92
+ || parsed === null
93
+ || Array.isArray(parsed)
94
+ || typeof parsed.answer !== "string"
95
+ || !this._active
96
+ || !this._complete) {
97
+ return this.setTerminalFailure("invalid_settle_arguments");
98
+ }
99
+ const answer = parsed.answer;
100
+ if (answer !== this.decodedAnswer) {
101
+ return this.setTerminalFailure("invalid_settle_arguments");
102
+ }
103
+ this.terminalResult = { ok: true, answer };
104
+ return this.terminalResult;
105
+ }
106
+ scanForTopLevelAnswer(character) {
107
+ if (this.scanInString) {
108
+ if (this.scanEscape) {
109
+ this.scanStringRaw += character;
110
+ this.scanEscape = false;
111
+ return;
112
+ }
113
+ if (character === "\\") {
114
+ this.scanStringRaw += character;
115
+ this.scanEscape = true;
116
+ return;
117
+ }
118
+ if (character !== '"') {
119
+ this.scanStringRaw += character;
120
+ return;
121
+ }
122
+ this.scanInString = false;
123
+ this.rootLastSignificant = '"';
124
+ if (this.scanStringIsRootKey) {
125
+ try {
126
+ if (JSON.parse(`"${this.scanStringRaw}"`) === "answer") {
127
+ this.answerKeyState = "after_key";
62
128
  }
63
129
  }
64
- else if (ch === '\\') {
65
- this.inEscape = true;
66
- }
67
- else if (ch === '"') {
68
- this._complete = true;
69
- return out; // stop processing, closing quote found
70
- }
71
- else {
72
- out += ch;
130
+ catch {
131
+ this.invalid = true;
73
132
  }
74
133
  }
134
+ this.scanStringRaw = "";
135
+ this.scanStringIsRootKey = false;
136
+ return;
75
137
  }
76
- return out;
138
+ if (this.answerKeyState === "after_key") {
139
+ if (isJsonWhitespace(character))
140
+ return;
141
+ if (character === ":") {
142
+ this.answerKeyState = "after_colon";
143
+ this.rootLastSignificant = character;
144
+ return;
145
+ }
146
+ this.invalid = true;
147
+ return;
148
+ }
149
+ if (this.answerKeyState === "after_colon") {
150
+ if (isJsonWhitespace(character))
151
+ return;
152
+ this.answerKeyState = "none";
153
+ if (character === '"') {
154
+ this._active = true;
155
+ this.rootLastSignificant = "value";
156
+ return;
157
+ }
158
+ }
159
+ if (isJsonWhitespace(character))
160
+ return;
161
+ const atRootObject = this.containers.length === 1 && this.containers[0] === "object";
162
+ if (character === '"') {
163
+ this.scanInString = true;
164
+ this.scanEscape = false;
165
+ this.scanStringRaw = "";
166
+ this.scanStringIsRootKey = atRootObject
167
+ && (this.rootLastSignificant === "{" || this.rootLastSignificant === ",");
168
+ return;
169
+ }
170
+ if (character === "{" || character === "[") {
171
+ if (atRootObject)
172
+ this.rootLastSignificant = "value";
173
+ this.containers.push(character === "{" ? "object" : "array");
174
+ if (this.containers.length === 1 && character === "{") {
175
+ this.rootLastSignificant = character;
176
+ }
177
+ return;
178
+ }
179
+ if (character === "}" || character === "]") {
180
+ const expected = character === "}" ? "object" : "array";
181
+ if (this.containers.at(-1) !== expected) {
182
+ this.invalid = true;
183
+ return;
184
+ }
185
+ this.containers.pop();
186
+ if (this.containers.length === 1 && this.containers[0] === "object") {
187
+ this.rootLastSignificant = "value";
188
+ }
189
+ return;
190
+ }
191
+ if (atRootObject)
192
+ this.rootLastSignificant = character;
193
+ }
194
+ processAnswerCharacter(character) {
195
+ if (this.decodeState === "unicode") {
196
+ if (!/^[0-9A-Fa-f]$/.test(character)) {
197
+ this.invalid = true;
198
+ return "";
199
+ }
200
+ this.unicodeDigits += character;
201
+ if (this.unicodeDigits.length < 4)
202
+ return "";
203
+ const decoded = String.fromCharCode(Number.parseInt(this.unicodeDigits, 16));
204
+ this.unicodeDigits = "";
205
+ this.decodeState = "normal";
206
+ return this.appendDecodedUnit(decoded);
207
+ }
208
+ if (this.decodeState === "escape") {
209
+ this.decodeState = "normal";
210
+ switch (character) {
211
+ case '"': return this.appendDecodedUnit('"');
212
+ case "\\": return this.appendDecodedUnit("\\");
213
+ case "/": return this.appendDecodedUnit("/");
214
+ case "b": return this.appendDecodedUnit("\b");
215
+ case "f": return this.appendDecodedUnit("\f");
216
+ case "n": return this.appendDecodedUnit("\n");
217
+ case "r": return this.appendDecodedUnit("\r");
218
+ case "t": return this.appendDecodedUnit("\t");
219
+ case "u":
220
+ this.decodeState = "unicode";
221
+ return "";
222
+ default:
223
+ this.invalid = true;
224
+ return "";
225
+ }
226
+ }
227
+ if (character === "\\") {
228
+ this.decodeState = "escape";
229
+ return "";
230
+ }
231
+ if (character === '"') {
232
+ const trailing = this.flushPendingHighSurrogate();
233
+ this._complete = true;
234
+ return trailing;
235
+ }
236
+ if (character.charCodeAt(0) <= 0x1F) {
237
+ this.invalid = true;
238
+ return "";
239
+ }
240
+ return this.appendDecodedUnit(character);
241
+ }
242
+ appendDecodedUnit(character) {
243
+ let out = "";
244
+ if (this.pendingHighSurrogate) {
245
+ if (isLowSurrogate(character)) {
246
+ const pair = this.pendingHighSurrogate + character;
247
+ this.pendingHighSurrogate = "";
248
+ this.decodedAnswer += pair;
249
+ return pair;
250
+ }
251
+ out = this.flushPendingHighSurrogate();
252
+ }
253
+ if (isHighSurrogate(character)) {
254
+ this.pendingHighSurrogate = character;
255
+ return out;
256
+ }
257
+ this.decodedAnswer += character;
258
+ return out + character;
259
+ }
260
+ flushPendingHighSurrogate() {
261
+ if (!this.pendingHighSurrogate)
262
+ return "";
263
+ const pending = this.pendingHighSurrogate;
264
+ this.pendingHighSurrogate = "";
265
+ this.decodedAnswer += pending;
266
+ return pending;
267
+ }
268
+ isIncompleteAtEof(error) {
269
+ if (this._active && !this._complete)
270
+ return true;
271
+ if (this.rawArguments.length === 0)
272
+ return true;
273
+ if (!(error instanceof SyntaxError))
274
+ return false;
275
+ if (/Unexpected end|Unterminated string/i.test(error.message))
276
+ return true;
277
+ const position = /position (\d+)/i.exec(error.message);
278
+ return position ? Number(position[1]) >= this.rawArguments.length : false;
279
+ }
280
+ setTerminalFailure(errorCode) {
281
+ this.terminalResult = { ok: false, errorCode };
282
+ return this.terminalResult;
77
283
  }
78
284
  }
79
- exports.FinalAnswerParser = FinalAnswerParser;
285
+ exports.SettleParser = SettleParser;
286
+ // Shared helper: wraps SettleParser with onClearText + onTextChunk wiring.
287
+ // Used by all streaming providers (Chat Completions, Responses API, Anthropic)
288
+ // so the eager-match settle streaming pattern lives in one place.
289
+ class SettleStreamer {
290
+ parser = new SettleParser();
291
+ _detected = false;
292
+ _streamed = false;
293
+ callbacks;
294
+ enabled;
295
+ mode;
296
+ observedArguments = "";
297
+ eagerAnswer = "";
298
+ terminalResult;
299
+ cancelled = false;
300
+ constructor(callbacks, enabled = true) {
301
+ this.callbacks = callbacks;
302
+ this.enabled = enabled;
303
+ // Production callback owners declare their mode explicitly. Retain the
304
+ // historical retractable default for third-party/in-test callback objects.
305
+ this.mode = callbacks.settleOutputMode ?? "retractable_buffer";
306
+ }
307
+ get detected() { return this._detected; }
308
+ get streamed() { return this._streamed; }
309
+ /** Mark settle as detected. Calls onClearText on the callbacks. */
310
+ activate() {
311
+ if (!this.enabled)
312
+ return;
313
+ if (this._detected)
314
+ return;
315
+ this._detected = true;
316
+ if (this.mode === "retractable_buffer")
317
+ this.callbacks.onClearText?.();
318
+ }
319
+ /** Feed an argument delta through the parser. Emits text via onTextChunk. */
320
+ processDelta(delta) {
321
+ if (!this.enabled)
322
+ return;
323
+ if (!this._detected)
324
+ return;
325
+ if (this.cancelled || this.terminalResult)
326
+ return;
327
+ this.observedArguments += delta;
328
+ const text = this.parser.process(delta);
329
+ if (text && this.mode === "retractable_buffer") {
330
+ this.callbacks.onTextChunk(text);
331
+ this.eagerAnswer += text;
332
+ }
333
+ }
334
+ /** Validate the completed provider arguments exactly once, then commit or
335
+ * retract callback-visible output according to the callback owner's mode. */
336
+ finish(completedArguments) {
337
+ if (!this.enabled || !this._detected || this.cancelled)
338
+ return undefined;
339
+ if (this.terminalResult)
340
+ return this.terminalResult;
341
+ let finalSuffix = "";
342
+ let replacedObservedArguments = false;
343
+ if (completedArguments.startsWith(this.observedArguments)) {
344
+ const suffix = completedArguments.slice(this.observedArguments.length);
345
+ this.observedArguments = completedArguments;
346
+ finalSuffix = this.parser.process(suffix);
347
+ }
348
+ else {
349
+ // A provider may normalize or replace its streamed argument fragments in
350
+ // the completed tool call. Re-parse that one authoritative final value;
351
+ // any eager output from the divergent fragment is retracted below.
352
+ replacedObservedArguments = true;
353
+ this.parser = new SettleParser();
354
+ this.observedArguments = completedArguments;
355
+ finalSuffix = this.parser.process(completedArguments);
356
+ }
357
+ const result = this.parser.finish();
358
+ // Cache before invoking callbacks: a callback failure must never make a
359
+ // repeated finish parse or commit the answer again.
360
+ this.terminalResult = result;
361
+ if (!result.ok) {
362
+ if (this.mode === "retractable_buffer")
363
+ this.callbacks.onClearText?.();
364
+ return result;
365
+ }
366
+ if (this.mode === "retractable_buffer") {
367
+ if (replacedObservedArguments) {
368
+ this.callbacks.onClearText?.();
369
+ this.callbacks.onTextChunk(result.answer);
370
+ }
371
+ else if (finalSuffix) {
372
+ this.callbacks.onTextChunk(finalSuffix);
373
+ }
374
+ this._streamed = true;
375
+ }
376
+ return result;
377
+ }
378
+ /** Cancel a partial provider stream without terminal parsing or commit. */
379
+ cancel() {
380
+ if (!this.enabled || !this._detected || this.cancelled || this.terminalResult)
381
+ return;
382
+ this.cancelled = true;
383
+ if (this.mode === "retractable_buffer" && this.eagerAnswer) {
384
+ this.callbacks.onClearText?.();
385
+ }
386
+ }
387
+ }
388
+ exports.SettleStreamer = SettleStreamer;
389
+ function finalizeSettleStream(streamer, completedArguments) {
390
+ try {
391
+ return streamer.finish(completedArguments);
392
+ }
393
+ catch (error) {
394
+ throw new SettleFinalizationCallbackError(error);
395
+ }
396
+ }
397
+ /** Holds ordinary provider text until a final-only response is known not to be
398
+ * an invalid settle. Retractable callback owners continue receiving deltas. */
399
+ class ProviderTextOutput {
400
+ callbacks;
401
+ bufferedText = "";
402
+ deferred;
403
+ suppressed = false;
404
+ constructor(callbacks) {
405
+ this.callbacks = callbacks;
406
+ this.deferred = callbacks.settleOutputMode === "final_only";
407
+ }
408
+ emit(text) {
409
+ if (this.suppressed)
410
+ return;
411
+ if (this.deferred) {
412
+ this.bufferedText += text;
413
+ }
414
+ else {
415
+ this.callbacks.onTextChunk(text);
416
+ }
417
+ }
418
+ suppress() {
419
+ this.bufferedText = "";
420
+ this.suppressed = true;
421
+ }
422
+ discard() {
423
+ this.bufferedText = "";
424
+ }
425
+ flush() {
426
+ if (!this.bufferedText)
427
+ return;
428
+ const text = this.bufferedText;
429
+ this.bufferedText = "";
430
+ this.callbacks.onTextChunk(text);
431
+ }
432
+ }
433
+ exports.ProviderTextOutput = ProviderTextOutput;
434
+ exports.RESPONSES_FUNCTION_CALL_OUTPUT_CAP = 200_000;
435
+ function truncateResponsesFunctionCallOutput(output, maxChars = exports.RESPONSES_FUNCTION_CALL_OUTPUT_CAP) {
436
+ if (output.length <= maxChars)
437
+ return output;
438
+ const marker = `\n\n[truncated — function_call_output exceeded ${maxChars} chars; original length ${output.length} chars]\n\n`;
439
+ const remainingBudget = Math.max(0, maxChars - marker.length);
440
+ const headLength = Math.ceil(remainingBudget * 0.75);
441
+ const tailLength = Math.max(0, remainingBudget - headLength);
442
+ return `${output.slice(0, headLength)}${marker}${output.slice(-tailLength)}`;
443
+ }
444
+ function toResponsesUserContent(content) {
445
+ if (typeof content === "string") {
446
+ return content;
447
+ }
448
+ if (!Array.isArray(content)) {
449
+ return "";
450
+ }
451
+ const parts = [];
452
+ for (const part of content) {
453
+ if (!part || typeof part !== "object") {
454
+ continue;
455
+ }
456
+ if (part.type === "text" && typeof part.text === "string") {
457
+ parts.push({ type: "input_text", text: part.text });
458
+ continue;
459
+ }
460
+ if (part.type === "image_url") {
461
+ const imageUrl = typeof part.image_url?.url === "string" ? part.image_url.url : "";
462
+ if (!imageUrl)
463
+ continue;
464
+ parts.push({
465
+ type: "input_image",
466
+ image_url: imageUrl,
467
+ detail: part.image_url?.detail ?? "auto",
468
+ });
469
+ continue;
470
+ }
471
+ if (part.type === "input_audio" &&
472
+ typeof part.input_audio?.data === "string" &&
473
+ (part.input_audio.format === "mp3" || part.input_audio.format === "wav")) {
474
+ parts.push({
475
+ type: "input_audio",
476
+ input_audio: {
477
+ data: part.input_audio.data,
478
+ format: part.input_audio.format,
479
+ },
480
+ });
481
+ continue;
482
+ }
483
+ if (part.type === "file") {
484
+ const fileRecord = { type: "input_file" };
485
+ if (typeof part.file?.file_data === "string")
486
+ fileRecord.file_data = part.file.file_data;
487
+ if (typeof part.file?.file_id === "string")
488
+ fileRecord.file_id = part.file.file_id;
489
+ if (typeof part.file?.filename === "string")
490
+ fileRecord.filename = part.file.filename;
491
+ if (typeof part.file?.file_data === "string" || typeof part.file?.file_id === "string") {
492
+ parts.push(fileRecord);
493
+ }
494
+ }
495
+ }
496
+ return parts.length > 0 ? parts : "";
497
+ }
80
498
  function toResponsesInput(messages) {
81
- let instructions = "";
499
+ const instructionParts = [];
82
500
  const input = [];
83
501
  for (const msg of messages) {
84
502
  if (msg.role === "system") {
85
- if (!instructions) {
86
- const sys = msg;
87
- instructions = (typeof sys.content === "string" ? sys.content : "") || "";
88
- }
503
+ const sys = msg;
504
+ const content = (typeof sys.content === "string" ? sys.content : "").trim();
505
+ if (content)
506
+ instructionParts.push(content);
89
507
  continue;
90
508
  }
91
509
  if (msg.role === "user") {
92
510
  const u = msg;
93
- input.push({ role: "user", content: typeof u.content === "string" ? u.content : "" });
511
+ input.push({ role: "user", content: toResponsesUserContent(u.content) });
94
512
  continue;
95
513
  }
96
514
  if (msg.role === "assistant") {
@@ -102,7 +520,10 @@ function toResponsesInput(messages) {
102
520
  }
103
521
  }
104
522
  if (a.content) {
105
- input.push({ role: "assistant", content: typeof a.content === "string" ? a.content : "" });
523
+ const assistantItem = { role: "assistant", content: typeof a.content === "string" ? a.content : "" };
524
+ if (a.phase)
525
+ assistantItem.phase = a.phase;
526
+ input.push(assistantItem);
106
527
  }
107
528
  if (a.tool_calls) {
108
529
  for (const tc of a.tool_calls) {
@@ -125,12 +546,12 @@ function toResponsesInput(messages) {
125
546
  input.push({
126
547
  type: "function_call_output",
127
548
  call_id: t.tool_call_id,
128
- output: typeof t.content === "string" ? t.content : "",
549
+ output: truncateResponsesFunctionCallOutput(typeof t.content === "string" ? t.content : ""),
129
550
  });
130
551
  continue;
131
552
  }
132
553
  }
133
- return { instructions, input };
554
+ return { instructions: instructionParts.join("\n\n"), input };
134
555
  }
135
556
  function toResponsesTools(ccTools) {
136
557
  return ccTools.map((t) => ({
@@ -141,7 +562,7 @@ function toResponsesTools(ccTools) {
141
562
  strict: false,
142
563
  }));
143
564
  }
144
- async function streamChatCompletion(client, createParams, callbacks, signal) {
565
+ async function streamChatCompletion(client, createParams, callbacks, signal, eagerSettleStreaming = true) {
145
566
  (0, runtime_1.emitNervesEvent)({
146
567
  component: "engine",
147
568
  event: "engine.stream_start",
@@ -155,8 +576,8 @@ async function streamChatCompletion(client, createParams, callbacks, signal) {
155
576
  let toolCalls = {};
156
577
  let streamStarted = false;
157
578
  let usage;
158
- const answerParser = new FinalAnswerParser();
159
- let finalAnswerDetected = false;
579
+ const answerStreamer = new SettleStreamer(callbacks, eagerSettleStreaming);
580
+ const textOutput = new ProviderTextOutput(callbacks);
160
581
  // State machine for parsing inline <think> tags (MiniMax pattern)
161
582
  let contentBuf = "";
162
583
  let inThinkTag = false;
@@ -199,7 +620,7 @@ async function streamChatCompletion(client, createParams, callbacks, signal) {
199
620
  if (start !== -1) {
200
621
  const text = contentBuf.slice(0, start);
201
622
  if (text)
202
- callbacks.onTextChunk(text);
623
+ textOutput.emit(text);
203
624
  contentBuf = contentBuf.slice(start + OPEN_TAG.length);
204
625
  inThinkTag = true;
205
626
  }
@@ -214,98 +635,120 @@ async function streamChatCompletion(client, createParams, callbacks, signal) {
214
635
  if (retain > 0) {
215
636
  const text = contentBuf.slice(0, -retain);
216
637
  if (text)
217
- callbacks.onTextChunk(text);
638
+ textOutput.emit(text);
218
639
  contentBuf = contentBuf.slice(-retain);
219
640
  return;
220
641
  }
221
642
  }
222
643
  // All content, flush it
223
- callbacks.onTextChunk(contentBuf);
644
+ textOutput.emit(contentBuf);
224
645
  contentBuf = "";
225
646
  }
226
647
  }
227
648
  }
228
649
  }
229
- for await (const chunk of response) {
230
- if (signal?.aborted)
231
- break;
232
- // Capture usage from final chunk (sent when stream_options.include_usage is true)
233
- if (chunk.usage) {
234
- const u = chunk.usage;
235
- usage = {
236
- input_tokens: u.prompt_tokens,
237
- output_tokens: u.completion_tokens,
238
- reasoning_tokens: u.completion_tokens_details?.reasoning_tokens ?? 0,
239
- total_tokens: u.total_tokens,
240
- };
241
- }
242
- const d = chunk.choices[0]?.delta;
243
- if (!d)
244
- continue;
245
- // Handle reasoning_content (Azure AI models like DeepSeek-R1)
246
- if (d.reasoning_content) {
247
- if (!streamStarted) {
248
- callbacks.onModelStreamStart();
249
- streamStarted = true;
650
+ try {
651
+ for await (const chunk of response) {
652
+ if (signal?.aborted)
653
+ break;
654
+ // Capture usage from final chunk (sent when stream_options.include_usage is true)
655
+ if (chunk.usage) {
656
+ const u = chunk.usage;
657
+ usage = {
658
+ input_tokens: u.prompt_tokens,
659
+ output_tokens: u.completion_tokens,
660
+ reasoning_tokens: u.completion_tokens_details?.reasoning_tokens ?? 0,
661
+ total_tokens: u.total_tokens,
662
+ };
250
663
  }
251
- callbacks.onReasoningChunk(d.reasoning_content);
252
- }
253
- if (d.content) {
254
- if (!streamStarted) {
255
- callbacks.onModelStreamStart();
256
- streamStarted = true;
664
+ const d = chunk.choices[0]?.delta;
665
+ if (!d)
666
+ continue;
667
+ // Handle reasoning_content (Azure AI models like DeepSeek-R1)
668
+ if (d.reasoning_content) {
669
+ if (!streamStarted) {
670
+ callbacks.onModelStreamStart();
671
+ streamStarted = true;
672
+ }
673
+ callbacks.onReasoningChunk(d.reasoning_content);
257
674
  }
258
- content += d.content;
259
- contentBuf += d.content;
260
- processContentBuf(false);
261
- }
262
- if (d.tool_calls) {
263
- for (const tc of d.tool_calls) {
264
- if (!toolCalls[tc.index])
265
- toolCalls[tc.index] = {
266
- id: tc.id ?? "",
267
- name: tc.function?.name ?? "",
268
- arguments: "",
269
- };
270
- if (tc.id)
271
- toolCalls[tc.index].id = tc.id;
272
- if (tc.function?.name) {
273
- toolCalls[tc.index].name = tc.function.name;
274
- // Detect final_answer tool call on first name delta.
275
- // Only activate streaming if this is the sole tool call (index 0
276
- // and no other indices seen). Mixed calls are rejected by core.ts.
277
- if (tc.function.name === "final_answer" && !finalAnswerDetected
278
- && tc.index === 0 && Object.keys(toolCalls).length === 1) {
279
- finalAnswerDetected = true;
280
- callbacks.onClearText?.();
281
- }
675
+ if (d.content) {
676
+ if (!streamStarted) {
677
+ callbacks.onModelStreamStart();
678
+ streamStarted = true;
282
679
  }
283
- if (tc.function?.arguments) {
284
- toolCalls[tc.index].arguments += tc.function.arguments;
285
- // Feed final_answer argument deltas to the parser for progressive
286
- // streaming, but only when it appears to be the sole tool call.
287
- if (finalAnswerDetected && toolCalls[tc.index].name === "final_answer"
288
- && Object.keys(toolCalls).length === 1) {
289
- const text = answerParser.process(tc.function.arguments);
290
- if (text)
291
- callbacks.onTextChunk(text);
680
+ content += d.content;
681
+ contentBuf += d.content;
682
+ processContentBuf(false);
683
+ }
684
+ if (d.tool_calls) {
685
+ for (const tc of d.tool_calls) {
686
+ if (!toolCalls[tc.index])
687
+ toolCalls[tc.index] = {
688
+ id: tc.id ?? "",
689
+ name: tc.function?.name ?? "",
690
+ arguments: "",
691
+ };
692
+ if (tc.id)
693
+ toolCalls[tc.index].id = tc.id;
694
+ if (tc.function?.name) {
695
+ toolCalls[tc.index].name = tc.function.name;
696
+ // Detect settle tool call on first name delta.
697
+ // Only activate streaming if this is the sole tool call (index 0
698
+ // and no other indices seen). Mixed calls are rejected by core.ts.
699
+ if (tc.function.name === "settle" && !answerStreamer.detected
700
+ && tc.index === 0 && Object.keys(toolCalls).length === 1) {
701
+ answerStreamer.activate();
702
+ textOutput.suppress();
703
+ }
704
+ }
705
+ if (tc.function?.arguments) {
706
+ toolCalls[tc.index].arguments += tc.function.arguments;
707
+ // Feed settle argument deltas to the parser for progressive
708
+ // streaming, but only when it appears to be the sole tool call.
709
+ if (answerStreamer.detected && toolCalls[tc.index].name === "settle"
710
+ && Object.keys(toolCalls).length === 1) {
711
+ answerStreamer.processDelta(tc.function.arguments);
712
+ }
292
713
  }
293
714
  }
294
715
  }
295
716
  }
296
717
  }
718
+ catch (error) {
719
+ textOutput.discard();
720
+ answerStreamer.cancel();
721
+ throw error;
722
+ }
297
723
  // Flush any remaining buffer at end of stream
298
724
  if (contentBuf)
299
725
  processContentBuf(true);
726
+ const completedToolCalls = Object.values(toolCalls);
727
+ let settleFinalization;
728
+ if (signal?.aborted) {
729
+ textOutput.discard();
730
+ answerStreamer.cancel();
731
+ }
732
+ else if (completedToolCalls.length === 1
733
+ && completedToolCalls[0].name === "settle"
734
+ && answerStreamer.detected) {
735
+ textOutput.discard();
736
+ settleFinalization = finalizeSettleStream(answerStreamer, completedToolCalls[0].arguments);
737
+ }
738
+ else {
739
+ answerStreamer.cancel();
740
+ textOutput.flush();
741
+ }
300
742
  return {
301
743
  content,
302
- toolCalls: Object.values(toolCalls),
744
+ toolCalls: completedToolCalls,
303
745
  outputItems: [],
304
746
  usage,
305
- finalAnswerStreamed: answerParser.active,
747
+ settleStreamed: answerStreamer.streamed,
748
+ ...(settleFinalization ? { settleFinalization } : {}),
306
749
  };
307
750
  }
308
- async function streamResponsesApi(client, createParams, callbacks, signal) {
751
+ async function streamResponsesApi(client, createParams, callbacks, signal, eagerSettleStreaming = true) {
309
752
  (0, runtime_1.emitNervesEvent)({
310
753
  component: "engine",
311
754
  event: "engine.stream_start",
@@ -320,89 +763,120 @@ async function streamResponsesApi(client, createParams, callbacks, signal) {
320
763
  const outputItems = [];
321
764
  let currentToolCall = null;
322
765
  let usage;
323
- const answerParser = new FinalAnswerParser();
766
+ const answerStreamer = new SettleStreamer(callbacks, eagerSettleStreaming);
767
+ const textOutput = new ProviderTextOutput(callbacks);
324
768
  let functionCallCount = 0;
325
- let finalAnswerDetected = false;
326
- for await (const event of response) {
327
- if (signal?.aborted)
328
- break;
329
- switch (event.type) {
330
- case "response.output_text.delta":
331
- case "response.reasoning_summary_text.delta": {
332
- if (!streamStarted) {
333
- callbacks.onModelStreamStart();
334
- streamStarted = true;
335
- }
336
- const delta = String(event.delta);
337
- if (event.type === "response.output_text.delta") {
338
- callbacks.onTextChunk(delta);
339
- content += delta;
340
- }
341
- else {
342
- callbacks.onReasoningChunk(delta);
343
- }
769
+ try {
770
+ for await (const event of response) {
771
+ if (signal?.aborted)
344
772
  break;
345
- }
346
- case "response.output_item.added": {
347
- if (event.item?.type === "function_call") {
348
- functionCallCount++;
349
- currentToolCall = {
350
- call_id: String(event.item.call_id),
351
- name: String(event.item.name),
352
- arguments: "",
353
- };
354
- // Detect final_answer function call -- clear any streamed noise.
355
- // Only activate when this is the first (and so far only) function call.
356
- // Mixed calls are rejected by core.ts; no need to stream their args.
357
- if (String(event.item.name) === "final_answer" && functionCallCount === 1) {
358
- finalAnswerDetected = true;
359
- callbacks.onClearText?.();
773
+ switch (event.type) {
774
+ case "response.output_text.delta":
775
+ case "response.reasoning_summary_text.delta": {
776
+ if (!streamStarted) {
777
+ callbacks.onModelStreamStart();
778
+ streamStarted = true;
779
+ }
780
+ const delta = String(event.delta);
781
+ if (event.type === "response.output_text.delta") {
782
+ textOutput.emit(delta);
783
+ content += delta;
784
+ }
785
+ else {
786
+ callbacks.onReasoningChunk(delta);
360
787
  }
788
+ break;
361
789
  }
362
- break;
363
- }
364
- case "response.function_call_arguments.delta": {
365
- if (currentToolCall) {
366
- currentToolCall.arguments += event.delta;
367
- // Feed final_answer argument deltas to the parser for progressive
368
- // streaming, but only when it appears to be the sole function call.
369
- if (finalAnswerDetected && currentToolCall.name === "final_answer"
370
- && functionCallCount === 1) {
371
- const text = answerParser.process(String(event.delta));
372
- if (text)
373
- callbacks.onTextChunk(text);
790
+ case "response.output_item.added": {
791
+ if (event.item?.type === "function_call") {
792
+ functionCallCount++;
793
+ currentToolCall = {
794
+ call_id: String(event.item.call_id),
795
+ name: String(event.item.name),
796
+ arguments: "",
797
+ };
798
+ // Detect settle function call -- clear any streamed noise.
799
+ // Only activate when this is the first (and so far only) function call.
800
+ // Mixed calls are rejected by core.ts; no need to stream their args.
801
+ if (String(event.item.name) === "settle" && functionCallCount === 1) {
802
+ answerStreamer.activate();
803
+ textOutput.suppress();
804
+ }
374
805
  }
806
+ break;
375
807
  }
376
- break;
377
- }
378
- case "response.output_item.done": {
379
- outputItems.push(event.item);
380
- if (event.item?.type === "function_call") {
381
- toolCalls.push({
382
- id: String(event.item.call_id),
383
- name: String(event.item.name),
384
- arguments: String(event.item.arguments),
385
- });
386
- currentToolCall = null;
808
+ case "response.function_call_arguments.delta": {
809
+ if (currentToolCall) {
810
+ currentToolCall.arguments += event.delta;
811
+ // Feed settle argument deltas to the parser for progressive
812
+ // streaming, but only when it appears to be the sole function call.
813
+ if (answerStreamer.detected && currentToolCall.name === "settle"
814
+ && functionCallCount === 1) {
815
+ answerStreamer.processDelta(String(event.delta));
816
+ }
817
+ }
818
+ break;
387
819
  }
388
- break;
389
- }
390
- case "response.completed":
391
- case "response.done": {
392
- const u = event.response?.usage;
393
- if (u) {
394
- usage = {
395
- input_tokens: u.input_tokens,
396
- output_tokens: u.output_tokens,
397
- reasoning_tokens: u.output_tokens_details?.reasoning_tokens ?? 0,
398
- total_tokens: u.total_tokens,
399
- };
820
+ case "response.output_item.done": {
821
+ outputItems.push(event.item);
822
+ if (event.item?.type === "function_call") {
823
+ toolCalls.push({
824
+ id: String(event.item.call_id),
825
+ name: String(event.item.name),
826
+ arguments: String(event.item.arguments),
827
+ });
828
+ currentToolCall = null;
829
+ }
830
+ break;
400
831
  }
401
- break;
832
+ case "response.completed":
833
+ case "response.done": {
834
+ const u = event.response?.usage;
835
+ if (u) {
836
+ usage = {
837
+ input_tokens: u.input_tokens,
838
+ output_tokens: u.output_tokens,
839
+ reasoning_tokens: u.output_tokens_details?.reasoning_tokens ?? 0,
840
+ total_tokens: u.total_tokens,
841
+ };
842
+ }
843
+ break;
844
+ }
845
+ default:
846
+ // Unknown/unhandled events silently ignored
847
+ break;
402
848
  }
403
- default:
404
- // Unknown/unhandled events silently ignored
405
- break;
849
+ }
850
+ }
851
+ catch (error) {
852
+ textOutput.discard();
853
+ answerStreamer.cancel();
854
+ throw error;
855
+ }
856
+ let settleFinalization;
857
+ if (signal?.aborted) {
858
+ textOutput.discard();
859
+ answerStreamer.cancel();
860
+ }
861
+ else {
862
+ if (toolCalls.length === 0 && functionCallCount === 1 && currentToolCall?.name === "settle") {
863
+ toolCalls.push({
864
+ id: currentToolCall.call_id,
865
+ name: currentToolCall.name,
866
+ arguments: currentToolCall.arguments,
867
+ });
868
+ currentToolCall = null;
869
+ }
870
+ const completedSettle = toolCalls.length === 1 && toolCalls[0].name === "settle"
871
+ ? toolCalls[0]
872
+ : undefined;
873
+ if (completedSettle && answerStreamer.detected) {
874
+ textOutput.discard();
875
+ settleFinalization = finalizeSettleStream(answerStreamer, completedSettle.arguments);
876
+ }
877
+ else {
878
+ answerStreamer.cancel();
879
+ textOutput.flush();
406
880
  }
407
881
  }
408
882
  return {
@@ -410,6 +884,7 @@ async function streamResponsesApi(client, createParams, callbacks, signal) {
410
884
  toolCalls,
411
885
  outputItems,
412
886
  usage,
413
- finalAnswerStreamed: answerParser.active,
887
+ settleStreamed: answerStreamer.streamed,
888
+ ...(settleFinalization ? { settleFinalization } : {}),
414
889
  };
415
890
  }