@ouro.bot/cli 0.1.0-alpha.60 → 0.1.0-alpha.600

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 (420) hide show
  1. package/README.md +127 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +3857 -0
  13. package/dist/arc/attention-types.js +8 -0
  14. package/dist/arc/cares.js +140 -0
  15. package/dist/arc/episodes.js +117 -0
  16. package/dist/arc/intentions.js +133 -0
  17. package/dist/arc/json-store.js +117 -0
  18. package/dist/arc/obligations.js +254 -0
  19. package/dist/arc/packets.js +193 -0
  20. package/dist/arc/presence.js +185 -0
  21. package/dist/arc/task-lifecycle.js +65 -0
  22. package/dist/heart/active-work.js +837 -26
  23. package/dist/heart/agent-entry.js +69 -3
  24. package/dist/heart/attachments/image-normalize.js +194 -0
  25. package/dist/heart/attachments/materialize.js +97 -0
  26. package/dist/heart/attachments/originals.js +88 -0
  27. package/dist/heart/attachments/render.js +29 -0
  28. package/dist/heart/attachments/sources/adapter.js +2 -0
  29. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  30. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  31. package/dist/heart/attachments/sources/index.js +16 -0
  32. package/dist/heart/attachments/store.js +103 -0
  33. package/dist/heart/attachments/types.js +93 -0
  34. package/dist/heart/auth/auth-flow.js +479 -0
  35. package/dist/heart/awaiting/await-alert.js +146 -0
  36. package/dist/heart/awaiting/await-expiry.js +108 -0
  37. package/dist/heart/awaiting/await-loader.js +91 -0
  38. package/dist/heart/awaiting/await-parser.js +141 -0
  39. package/dist/heart/awaiting/await-runtime-state.js +97 -0
  40. package/dist/heart/awaiting/await-scheduler.js +377 -0
  41. package/dist/heart/background-operations.js +281 -0
  42. package/dist/heart/bundle-state.js +168 -0
  43. package/dist/heart/commitments.js +142 -0
  44. package/dist/heart/config-registry.js +322 -0
  45. package/dist/heart/config.js +114 -119
  46. package/dist/heart/core.js +909 -246
  47. package/dist/heart/cross-chat-delivery.js +3 -18
  48. package/dist/heart/daemon/agent-config-check.js +419 -0
  49. package/dist/heart/daemon/agent-discovery.js +102 -3
  50. package/dist/heart/daemon/agent-service.js +522 -0
  51. package/dist/heart/daemon/agentic-repair.js +547 -0
  52. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  53. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  54. package/dist/heart/daemon/cadence.js +70 -0
  55. package/dist/heart/daemon/cli-defaults.js +776 -0
  56. package/dist/heart/daemon/cli-exec.js +7571 -0
  57. package/dist/heart/daemon/cli-help.js +498 -0
  58. package/dist/heart/daemon/cli-parse.js +1599 -0
  59. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  60. package/dist/heart/daemon/cli-render.js +763 -0
  61. package/dist/heart/daemon/cli-types.js +8 -0
  62. package/dist/heart/daemon/connect-bay.js +323 -0
  63. package/dist/heart/daemon/daemon-cli.js +29 -1703
  64. package/dist/heart/daemon/daemon-entry.js +485 -2
  65. package/dist/heart/daemon/daemon-health.js +176 -0
  66. package/dist/heart/daemon/daemon-rollup.js +57 -0
  67. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  68. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  69. package/dist/heart/daemon/daemon.js +842 -69
  70. package/dist/heart/daemon/dns-workflow.js +394 -0
  71. package/dist/heart/daemon/doctor-types.js +8 -0
  72. package/dist/heart/daemon/doctor.js +873 -0
  73. package/dist/heart/daemon/health-monitor.js +122 -1
  74. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  75. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  76. package/dist/heart/daemon/http-health-probe.js +80 -0
  77. package/dist/heart/daemon/human-command-screens.js +234 -0
  78. package/dist/heart/daemon/human-readiness.js +114 -0
  79. package/dist/heart/daemon/inner-status.js +89 -0
  80. package/dist/heart/daemon/interactive-repair.js +394 -0
  81. package/dist/heart/daemon/launchd.js +37 -8
  82. package/dist/heart/daemon/log-tailer.js +78 -9
  83. package/dist/heart/daemon/logs-prune.js +110 -0
  84. package/dist/heart/daemon/mcp-canary.js +297 -0
  85. package/dist/heart/daemon/os-cron-deps.js +135 -0
  86. package/dist/heart/daemon/os-cron.js +14 -12
  87. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  88. package/dist/heart/daemon/ouro-entry.js +3 -1
  89. package/dist/heart/daemon/process-manager.js +375 -33
  90. package/dist/heart/daemon/provider-discovery.js +137 -0
  91. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  92. package/dist/heart/daemon/pulse.js +475 -0
  93. package/dist/heart/daemon/readiness-repair.js +365 -0
  94. package/dist/heart/daemon/run-hooks.js +2 -0
  95. package/dist/heart/daemon/runtime-logging.js +10 -2
  96. package/dist/heart/daemon/runtime-metadata.js +2 -30
  97. package/dist/heart/daemon/safe-mode.js +161 -0
  98. package/dist/heart/daemon/sense-manager.js +462 -38
  99. package/dist/heart/daemon/session-id-resolver.js +131 -0
  100. package/dist/heart/daemon/skill-management-installer.js +94 -0
  101. package/dist/heart/daemon/socket-client.js +158 -11
  102. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  103. package/dist/heart/daemon/startup-tui.js +330 -0
  104. package/dist/heart/daemon/task-scheduler.js +3 -25
  105. package/dist/heart/daemon/terminal-ui.js +499 -0
  106. package/dist/heart/daemon/thoughts.js +162 -17
  107. package/dist/heart/daemon/up-progress.js +366 -0
  108. package/dist/heart/daemon/vault-items.js +56 -0
  109. package/dist/heart/delegation.js +1 -1
  110. package/dist/heart/habits/habit-migration.js +189 -0
  111. package/dist/heart/habits/habit-parser.js +140 -0
  112. package/dist/heart/habits/habit-runtime-state.js +100 -0
  113. package/dist/heart/habits/habit-scheduler.js +372 -0
  114. package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
  115. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  116. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  117. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  118. package/dist/heart/identity.js +166 -55
  119. package/dist/heart/kept-notes.js +357 -0
  120. package/dist/heart/kicks.js +1 -1
  121. package/dist/heart/machine-identity.js +161 -0
  122. package/dist/heart/mail-import-discovery.js +353 -0
  123. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  124. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  125. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  126. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  127. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  128. package/dist/heart/mailbox/mailbox-http.js +99 -0
  129. package/dist/heart/mailbox/mailbox-read.js +31 -0
  130. package/dist/heart/mailbox/mailbox-types.js +27 -0
  131. package/dist/heart/mailbox/mailbox-view.js +195 -0
  132. package/dist/heart/mailbox/readers/agent-machine.js +382 -0
  133. package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
  134. package/dist/heart/mailbox/readers/mail.js +367 -0
  135. package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
  136. package/dist/heart/mailbox/readers/sessions.js +232 -0
  137. package/dist/heart/mailbox/readers/shared.js +111 -0
  138. package/dist/heart/mcp/mcp-server.js +656 -0
  139. package/dist/heart/migrate-config.js +100 -0
  140. package/dist/heart/model-capabilities.js +19 -0
  141. package/dist/heart/platform.js +81 -0
  142. package/dist/heart/provider-attempt.js +134 -0
  143. package/dist/heart/provider-binding-resolver.js +267 -0
  144. package/dist/heart/provider-credentials.js +425 -0
  145. package/dist/heart/provider-failover.js +301 -0
  146. package/dist/heart/provider-models.js +81 -0
  147. package/dist/heart/provider-ping.js +262 -0
  148. package/dist/heart/provider-readiness-cache.js +40 -0
  149. package/dist/heart/provider-visibility.js +188 -0
  150. package/dist/heart/providers/anthropic-token.js +131 -0
  151. package/dist/heart/providers/anthropic.js +139 -52
  152. package/dist/heart/providers/azure.js +23 -11
  153. package/dist/heart/providers/error-classification.js +127 -0
  154. package/dist/heart/providers/github-copilot.js +145 -0
  155. package/dist/heart/providers/minimax-vlm.js +189 -0
  156. package/dist/heart/providers/minimax.js +26 -8
  157. package/dist/heart/providers/openai-codex.js +55 -40
  158. package/dist/heart/runtime-capability-check.js +170 -0
  159. package/dist/heart/runtime-credentials.js +367 -0
  160. package/dist/heart/runtime-cwd.js +87 -0
  161. package/dist/heart/sense-truth.js +13 -4
  162. package/dist/heart/session-activity.js +43 -22
  163. package/dist/heart/session-events.js +1149 -0
  164. package/dist/heart/session-playback-cli-main.js +5 -0
  165. package/dist/heart/session-playback-cli.js +36 -0
  166. package/dist/heart/session-playback.js +231 -0
  167. package/dist/heart/session-stats-cli-main.js +5 -0
  168. package/dist/heart/session-stats.js +182 -0
  169. package/dist/heart/session-transcript.js +243 -0
  170. package/dist/heart/start-of-turn-packet.js +345 -0
  171. package/dist/heart/streaming.js +44 -27
  172. package/dist/heart/sync-classification.js +176 -0
  173. package/dist/heart/sync.js +449 -0
  174. package/dist/heart/target-resolution.js +9 -5
  175. package/dist/heart/tempo.js +93 -0
  176. package/dist/heart/temporal-view.js +41 -0
  177. package/dist/heart/timeouts.js +101 -0
  178. package/dist/heart/tool-activity-callbacks.js +59 -0
  179. package/dist/heart/tool-description.js +143 -0
  180. package/dist/heart/tool-friction.js +55 -0
  181. package/dist/heart/tool-loop.js +200 -0
  182. package/dist/heart/turn-context.js +421 -0
  183. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  184. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  185. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  186. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  187. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  188. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  189. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  190. package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
  191. package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
  192. package/dist/mailbox-ui/index.html +15 -0
  193. package/dist/mailroom/attention.js +167 -0
  194. package/dist/mailroom/autonomy.js +209 -0
  195. package/dist/mailroom/blob-store.js +700 -0
  196. package/dist/mailroom/body-cache.js +61 -0
  197. package/dist/mailroom/core.js +788 -0
  198. package/dist/mailroom/entry.js +160 -0
  199. package/dist/mailroom/file-store.js +457 -0
  200. package/dist/mailroom/mbox-import.js +393 -0
  201. package/dist/mailroom/migration.js +164 -0
  202. package/dist/mailroom/outbound.js +380 -0
  203. package/dist/mailroom/policy.js +263 -0
  204. package/dist/mailroom/reader.js +233 -0
  205. package/dist/mailroom/search-cache.js +268 -0
  206. package/dist/mailroom/search-relevance.js +319 -0
  207. package/dist/mailroom/smtp-ingress.js +176 -0
  208. package/dist/mailroom/source-state.js +176 -0
  209. package/dist/mailroom/thread.js +109 -0
  210. package/dist/mailroom/travel-extract.js +89 -0
  211. package/dist/mind/bundle-manifest.js +7 -1
  212. package/dist/mind/context.js +165 -101
  213. package/dist/mind/diary-integrity.js +60 -0
  214. package/dist/mind/{memory.js → diary.js} +62 -75
  215. package/dist/mind/embedding-provider.js +60 -0
  216. package/dist/mind/file-state.js +179 -0
  217. package/dist/mind/friends/channel.js +39 -0
  218. package/dist/mind/friends/resolver.js +54 -2
  219. package/dist/mind/friends/store-file.js +39 -3
  220. package/dist/mind/friends/types.js +2 -2
  221. package/dist/mind/journal-index.js +161 -0
  222. package/dist/mind/note-search.js +268 -0
  223. package/dist/mind/obligation-steering.js +221 -0
  224. package/dist/mind/pending.js +4 -0
  225. package/dist/mind/prompt-refresh.js +3 -2
  226. package/dist/mind/prompt.js +1050 -135
  227. package/dist/mind/provenance-trust.js +26 -0
  228. package/dist/mind/scrutiny.js +173 -0
  229. package/dist/nerves/cli-logging.js +7 -1
  230. package/dist/nerves/coverage/audit-rules.js +15 -6
  231. package/dist/nerves/coverage/audit.js +28 -2
  232. package/dist/nerves/coverage/cli.js +1 -1
  233. package/dist/nerves/coverage/contract.js +5 -5
  234. package/dist/nerves/coverage/file-completeness.js +129 -5
  235. package/dist/nerves/event-buffer.js +111 -0
  236. package/dist/nerves/index.js +224 -4
  237. package/dist/nerves/observation.js +20 -0
  238. package/dist/nerves/redact.js +79 -0
  239. package/dist/nerves/review/cli-main.js +5 -0
  240. package/dist/nerves/review/cli.js +156 -0
  241. package/dist/nerves/review/core.js +152 -0
  242. package/dist/nerves/runtime.js +5 -1
  243. package/dist/repertoire/ado-client.js +15 -56
  244. package/dist/repertoire/ado-semantic.js +11 -10
  245. package/dist/repertoire/api-client.js +97 -0
  246. package/dist/repertoire/bitwarden-store.js +997 -0
  247. package/dist/repertoire/bundle-templates.js +72 -0
  248. package/dist/repertoire/bw-installer.js +180 -0
  249. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  250. package/dist/repertoire/coding/context-pack.js +330 -0
  251. package/dist/repertoire/coding/feedback.js +197 -30
  252. package/dist/repertoire/coding/manager.js +158 -9
  253. package/dist/repertoire/coding/spawner.js +55 -9
  254. package/dist/repertoire/coding/tools.js +170 -7
  255. package/dist/repertoire/commerce-errors.js +109 -0
  256. package/dist/repertoire/commerce-self-test.js +156 -0
  257. package/dist/repertoire/credential-access.js +178 -0
  258. package/dist/repertoire/duffel-client.js +185 -0
  259. package/dist/repertoire/github-client.js +14 -55
  260. package/dist/repertoire/graph-client.js +11 -52
  261. package/dist/repertoire/guardrails.js +396 -0
  262. package/dist/repertoire/mcp-client.js +295 -0
  263. package/dist/repertoire/mcp-manager.js +362 -0
  264. package/dist/repertoire/mcp-tools.js +63 -0
  265. package/dist/repertoire/shell-sessions.js +133 -0
  266. package/dist/repertoire/skills.js +15 -24
  267. package/dist/repertoire/stripe-client.js +131 -0
  268. package/dist/repertoire/tasks/board.js +31 -5
  269. package/dist/repertoire/tasks/fix.js +182 -0
  270. package/dist/repertoire/tasks/index.js +16 -4
  271. package/dist/repertoire/tasks/lifecycle.js +2 -2
  272. package/dist/repertoire/tasks/parser.js +3 -2
  273. package/dist/repertoire/tasks/scanner.js +194 -37
  274. package/dist/repertoire/tasks/transitions.js +16 -78
  275. package/dist/repertoire/tool-results.js +29 -0
  276. package/dist/repertoire/tools-attachments.js +317 -0
  277. package/dist/repertoire/tools-awaiting.js +360 -0
  278. package/dist/repertoire/tools-base.js +53 -1082
  279. package/dist/repertoire/tools-bluebubbles.js +1 -0
  280. package/dist/repertoire/tools-bridge.js +142 -0
  281. package/dist/repertoire/tools-bundle.js +984 -0
  282. package/dist/repertoire/tools-config.js +185 -0
  283. package/dist/repertoire/tools-continuity.js +248 -0
  284. package/dist/repertoire/tools-credential.js +381 -0
  285. package/dist/repertoire/tools-files.js +342 -0
  286. package/dist/repertoire/tools-flight.js +224 -0
  287. package/dist/repertoire/tools-flow.js +119 -0
  288. package/dist/repertoire/tools-github.js +1 -7
  289. package/dist/repertoire/tools-mail.js +1916 -0
  290. package/dist/repertoire/tools-notes.js +421 -0
  291. package/dist/repertoire/tools-obligations.js +142 -0
  292. package/dist/repertoire/tools-runtime.js +61 -0
  293. package/dist/repertoire/tools-session.js +809 -0
  294. package/dist/repertoire/tools-shell.js +120 -0
  295. package/dist/repertoire/tools-stripe.js +180 -0
  296. package/dist/repertoire/tools-surface.js +345 -0
  297. package/dist/repertoire/tools-teams.js +9 -39
  298. package/dist/repertoire/tools-travel.js +125 -0
  299. package/dist/repertoire/tools-trip.js +604 -0
  300. package/dist/repertoire/tools-user-profile.js +144 -0
  301. package/dist/repertoire/tools-vault.js +40 -0
  302. package/dist/repertoire/tools-voice.js +144 -0
  303. package/dist/repertoire/tools.js +115 -103
  304. package/dist/repertoire/travel-api-client.js +360 -0
  305. package/dist/repertoire/user-profile.js +131 -0
  306. package/dist/repertoire/vault-setup.js +246 -0
  307. package/dist/repertoire/vault-unlock.js +594 -0
  308. package/dist/scripts/claude-code-hook.js +41 -0
  309. package/dist/scripts/claude-code-stop-hook.js +47 -0
  310. package/dist/senses/attention-queue.js +116 -0
  311. package/dist/senses/await-turn-message.js +58 -0
  312. package/dist/senses/bluebubbles/active-turns.js +216 -0
  313. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  314. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  315. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  316. package/dist/senses/bluebubbles/entry.js +77 -0
  317. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  318. package/dist/senses/bluebubbles/index.js +2548 -0
  319. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  320. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  321. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  322. package/dist/senses/bluebubbles/processed-log.js +133 -0
  323. package/dist/senses/bluebubbles/replay.js +137 -0
  324. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  325. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  326. package/dist/senses/bluebubbles-meta-guard.js +40 -0
  327. package/dist/senses/cli/bracketed-paste.js +82 -0
  328. package/dist/senses/cli/image-paste.js +287 -0
  329. package/dist/senses/cli/image-ref-navigation.js +75 -0
  330. package/dist/senses/cli/ink-app.js +156 -0
  331. package/dist/senses/cli/inline-diff.js +64 -0
  332. package/dist/senses/cli/input-keys.js +174 -0
  333. package/dist/senses/cli/kill-ring.js +86 -0
  334. package/dist/senses/cli/message-list.js +51 -0
  335. package/dist/senses/cli/ouro-tui.js +607 -0
  336. package/dist/senses/cli/spinner-imperative.js +135 -0
  337. package/dist/senses/cli/spinner.js +101 -0
  338. package/dist/senses/cli/status-line.js +60 -0
  339. package/dist/senses/cli/streaming-markdown.js +526 -0
  340. package/dist/senses/cli/tool-display.js +85 -0
  341. package/dist/senses/cli/tool-render.js +85 -0
  342. package/dist/senses/cli/tui-store.js +240 -0
  343. package/dist/senses/cli/virtual-list.js +35 -0
  344. package/dist/senses/cli-entry.js +60 -8
  345. package/dist/senses/cli-layout.js +100 -0
  346. package/dist/senses/cli.js +516 -204
  347. package/dist/senses/commands.js +66 -3
  348. package/dist/senses/habit-turn-message.js +108 -0
  349. package/dist/senses/inner-dialog-worker.js +185 -21
  350. package/dist/senses/inner-dialog.js +372 -27
  351. package/dist/senses/mail-entry.js +66 -0
  352. package/dist/senses/mail.js +379 -0
  353. package/dist/senses/pipeline.js +654 -181
  354. package/dist/senses/proactive-content-guard.js +51 -0
  355. package/dist/senses/shared-turn.js +392 -0
  356. package/dist/senses/surface-tool.js +70 -0
  357. package/dist/senses/teams-entry.js +60 -8
  358. package/dist/senses/teams.js +387 -98
  359. package/dist/senses/trust-gate.js +100 -5
  360. package/dist/senses/voice/audio-playback.js +237 -0
  361. package/dist/senses/voice/audio-routing.js +119 -0
  362. package/dist/senses/voice/elevenlabs.js +202 -0
  363. package/dist/senses/voice/floor-control.js +431 -0
  364. package/dist/senses/voice/floor-controller.js +115 -0
  365. package/dist/senses/voice/golden-path.js +116 -0
  366. package/dist/senses/voice/index.js +29 -0
  367. package/dist/senses/voice/meeting.js +113 -0
  368. package/dist/senses/voice/outbound.js +190 -0
  369. package/dist/senses/voice/phone.js +33 -0
  370. package/dist/senses/voice/playback.js +139 -0
  371. package/dist/senses/voice/realtime-eval.js +496 -0
  372. package/dist/senses/voice/realtime-trace.js +531 -0
  373. package/dist/senses/voice/transcript.js +70 -0
  374. package/dist/senses/voice/turn.js +191 -0
  375. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  376. package/dist/senses/voice/twilio-phone.js +5077 -0
  377. package/dist/senses/voice/types.js +2 -0
  378. package/dist/senses/voice/whisper.js +161 -0
  379. package/dist/senses/voice-entry.js +81 -0
  380. package/dist/senses/voice-realtime-eval-command.js +99 -0
  381. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  382. package/dist/senses/voice-twilio-entry.js +87 -0
  383. package/dist/trips/core.js +138 -0
  384. package/dist/trips/store.js +265 -0
  385. package/package.json +41 -7
  386. package/skills/agent-commerce.md +106 -0
  387. package/skills/browser-navigation.md +117 -0
  388. package/skills/commerce-setup-guide.md +116 -0
  389. package/skills/commerce-setup.md +84 -0
  390. package/skills/configure-dev-tools.md +99 -0
  391. package/skills/travel-planning.md +138 -0
  392. package/dist/heart/daemon/auth-flow.js +0 -351
  393. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  394. package/dist/heart/daemon/subagent-installer.js +0 -166
  395. package/dist/heart/safe-workspace.js +0 -228
  396. package/dist/heart/session-recall.js +0 -116
  397. package/dist/mind/associative-recall.js +0 -209
  398. package/dist/senses/bluebubbles-entry.js +0 -13
  399. package/dist/senses/bluebubbles.js +0 -1177
  400. package/dist/senses/debug-activity.js +0 -148
  401. package/subagents/README.md +0 -86
  402. package/subagents/work-doer.md +0 -237
  403. package/subagents/work-merger.md +0 -618
  404. package/subagents/work-planner.md +0 -390
  405. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  406. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  407. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  408. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  409. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  410. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  411. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  412. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  413. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  414. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  415. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  416. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  417. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  418. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  419. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  420. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,531 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parseVoiceRealtimeEvalTraceArtifact = parseVoiceRealtimeEvalTraceArtifact;
37
+ exports.loadVoiceRealtimeEvalTraceArtifact = loadVoiceRealtimeEvalTraceArtifact;
38
+ exports.resolveVoiceRealtimeEvalTraceExpectation = resolveVoiceRealtimeEvalTraceExpectation;
39
+ exports.traceArtifactToVoiceRealtimeEvalTimeline = traceArtifactToVoiceRealtimeEvalTimeline;
40
+ exports.gradeVoiceRealtimeEvalTrace = gradeVoiceRealtimeEvalTrace;
41
+ exports.formatVoiceRealtimeEvalTraceReport = formatVoiceRealtimeEvalTraceReport;
42
+ const fs = __importStar(require("fs"));
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ const realtime_eval_1 = require("./realtime-eval");
45
+ const transports = new Set([
46
+ "browser-meeting",
47
+ "openai-realtime-control",
48
+ "openai-sip",
49
+ "twilio-media-stream",
50
+ "voice-eval",
51
+ ]);
52
+ const normalizedEvents = new Set([
53
+ "assistant.audio.done",
54
+ "assistant.audio.started",
55
+ "assistant.transcript.done",
56
+ "barge_in.detected",
57
+ "call.connected",
58
+ "call.ended",
59
+ "call.hangup.requested",
60
+ "floor.state.changed",
61
+ "response.requested",
62
+ "response.truncated",
63
+ "session.updated",
64
+ "speech.policy.decision",
65
+ "tool.call.completed",
66
+ "tool.call.started",
67
+ "tool.holding.started",
68
+ "tool.result.ready",
69
+ "tool.result.spoken",
70
+ "transport.playback_cleared",
71
+ "user.transcript.done",
72
+ "voice.context.injected",
73
+ ]);
74
+ const rawEventMap = new Map([
75
+ ["voice.floor.state.changed", "floor.state.changed"],
76
+ ["openai.realtime.call.hangup.sent", "call.hangup.requested"],
77
+ ["openai.realtime.conversation.item.truncate.sent", "response.truncated"],
78
+ ["openai.realtime.input_audio_buffer.speech_started", "barge_in.detected"],
79
+ ["openai.realtime.input_audio_transcription.completed", "user.transcript.done"],
80
+ ["openai.realtime.output_audio.delta", "assistant.audio.started"],
81
+ ["openai.realtime.output_audio.done", "assistant.audio.done"],
82
+ ["openai.realtime.output_audio_transcript.done", "assistant.transcript.done"],
83
+ ["openai.realtime.response.create.sent", "response.requested"],
84
+ ["openai.realtime.response.function_call_arguments.done", "tool.call.started"],
85
+ ["openai.realtime.session.updated", "session.updated"],
86
+ ["openai.realtime.tool.completed", "tool.call.completed"],
87
+ ["openai.sip.call.connected", "call.connected"],
88
+ ["openai.sip.call.ended", "call.ended"],
89
+ ["twilio.call.ended", "call.ended"],
90
+ ["twilio.media.clear.sent", "transport.playback_cleared"],
91
+ ["twilio.media.start", "call.connected"],
92
+ ["voice.hangup.requested", "call.hangup.requested"],
93
+ ["voice.speech.policy.decision", "speech.policy.decision"],
94
+ ["voice.tool_holding.started", "tool.holding.started"],
95
+ ["voice.tool.result.ready", "tool.result.ready"],
96
+ ["voice.tool.result.spoken", "tool.result.spoken"],
97
+ ]);
98
+ const expectedOutcomes = new Set(["expected-fail", "fail", "pass"]);
99
+ const expectationProfiles = new Set(["voice-phone-default"]);
100
+ const floorOwners = new Set(["assistant", "caller", "none", "terminal"]);
101
+ const floorPhases = new Set([
102
+ "caller-speaking",
103
+ "ended",
104
+ "hangup",
105
+ "idle",
106
+ "interrupted",
107
+ "listening",
108
+ "speaking",
109
+ "suppressing",
110
+ "thinking",
111
+ "tool-result-ready",
112
+ "tool-running",
113
+ ]);
114
+ const speechDecisions = new Set(["allow", "cancel", "delay", "suppress"]);
115
+ function objectRecord(value) {
116
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
117
+ }
118
+ function label(prefix, detail) {
119
+ return prefix ? `${prefix}: ${detail}` : detail;
120
+ }
121
+ function requiredString(value, name, sourceLabel) {
122
+ if (typeof value !== "string" || value.trim() === "")
123
+ throw new Error(label(sourceLabel, `${name} must be a non-empty string`));
124
+ return value.trim();
125
+ }
126
+ function optionalString(value, name, sourceLabel) {
127
+ if (value === undefined)
128
+ return undefined;
129
+ if (typeof value !== "string")
130
+ throw new Error(label(sourceLabel, `${name} must be a string`));
131
+ return value;
132
+ }
133
+ function optionalStringArray(value, name, sourceLabel) {
134
+ if (value === undefined)
135
+ return undefined;
136
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
137
+ throw new Error(label(sourceLabel, `${name} must be an array of strings`));
138
+ }
139
+ return [...value];
140
+ }
141
+ function optionalFloorOwner(value, sourceLabel) {
142
+ if (value === undefined)
143
+ return undefined;
144
+ if (typeof value !== "string" || !floorOwners.has(value))
145
+ throw new Error(label(sourceLabel, "floorOwner is unsupported"));
146
+ return value;
147
+ }
148
+ function optionalFloorPhase(value, sourceLabel) {
149
+ if (value === undefined)
150
+ return undefined;
151
+ if (typeof value !== "string" || !floorPhases.has(value))
152
+ throw new Error(label(sourceLabel, "floorPhase is unsupported"));
153
+ return value;
154
+ }
155
+ function optionalSpeechDecision(value, sourceLabel) {
156
+ if (value === undefined)
157
+ return undefined;
158
+ if (typeof value !== "string" || !speechDecisions.has(value))
159
+ throw new Error(label(sourceLabel, "speechDecision is unsupported"));
160
+ return value;
161
+ }
162
+ function parseSource(value, sourceLabel) {
163
+ if (value === undefined)
164
+ return undefined;
165
+ const raw = objectRecord(value);
166
+ if (!raw)
167
+ throw new Error(label(sourceLabel, "source must be an object"));
168
+ const transport = raw.transport;
169
+ if (typeof transport !== "string" || !transports.has(transport)) {
170
+ throw new Error(label(sourceLabel, "source.transport is unsupported"));
171
+ }
172
+ const id = optionalString(raw.id, "source.id", sourceLabel);
173
+ return id === undefined ? { transport: transport } : { transport: transport, id };
174
+ }
175
+ function parseTurnDetection(value, sourceLabel) {
176
+ if (value === undefined)
177
+ return undefined;
178
+ const session = objectRecord(value);
179
+ if (!session)
180
+ throw new Error(label(sourceLabel, "session must be an object"));
181
+ const turnDetection = objectRecord(session.turnDetection);
182
+ if (!turnDetection)
183
+ return {};
184
+ const createResponse = turnDetection.createResponse;
185
+ const interruptResponse = turnDetection.interruptResponse;
186
+ if (createResponse !== undefined && typeof createResponse !== "boolean") {
187
+ throw new Error(label(sourceLabel, "session.turnDetection.createResponse must be boolean"));
188
+ }
189
+ if (interruptResponse !== undefined && typeof interruptResponse !== "boolean") {
190
+ throw new Error(label(sourceLabel, "session.turnDetection.interruptResponse must be boolean"));
191
+ }
192
+ return { turnDetection: { createResponse, interruptResponse } };
193
+ }
194
+ function validateExpectation(expectation, sourceLabel) {
195
+ const budgets = [
196
+ expectation.maxFirstAssistantAudioMs,
197
+ expectation.maxUserTurnResponseMs,
198
+ expectation.maxToolPresenceMs,
199
+ expectation.maxBargeInClearMs,
200
+ expectation.maxBargeInTruncateMs,
201
+ ];
202
+ if (budgets.some((budget) => typeof budget !== "number" || !Number.isFinite(budget) || budget <= 0)) {
203
+ throw new Error(label(sourceLabel, "expectation latency budgets must be positive finite numbers"));
204
+ }
205
+ return expectation;
206
+ }
207
+ function parseExpectation(value, sourceLabel) {
208
+ const raw = objectRecord(value);
209
+ if (!raw)
210
+ throw new Error(label(sourceLabel, "expectation must be an object"));
211
+ return validateExpectation(raw, sourceLabel);
212
+ }
213
+ function parseTraceEvent(value, index, sourceLabel) {
214
+ const eventLabel = `${sourceLabel} event[${index}]`;
215
+ const raw = objectRecord(value);
216
+ if (!raw)
217
+ throw new Error(label(eventLabel, "must be an object"));
218
+ const event = requiredString(raw.event, "event", eventLabel);
219
+ const ignored = raw.ignored === undefined ? undefined : raw.ignored;
220
+ if (ignored !== undefined && typeof ignored !== "boolean")
221
+ throw new Error(label(eventLabel, "ignored must be boolean"));
222
+ if (!ignored && !normalizedEvents.has(event) && !rawEventMap.has(event)) {
223
+ throw new Error(label(eventLabel, `unknown trace event ${event}`));
224
+ }
225
+ const atMs = raw.atMs;
226
+ if (typeof atMs !== "number" || !Number.isFinite(atMs)) {
227
+ throw new Error(label(eventLabel, "atMs must be a finite number"));
228
+ }
229
+ let role;
230
+ if (raw.role !== undefined) {
231
+ if (raw.role !== "assistant" && raw.role !== "user")
232
+ throw new Error(label(eventLabel, "role must be assistant or user"));
233
+ role = raw.role;
234
+ }
235
+ const parsed = {
236
+ atMs,
237
+ event,
238
+ source: parseSource(raw.source, eventLabel),
239
+ correlationId: optionalString(raw.correlationId, "correlationId", eventLabel),
240
+ text: optionalString(raw.text, "text", eventLabel),
241
+ role,
242
+ toolName: optionalString(raw.toolName, "toolName", eventLabel),
243
+ friendId: optionalString(raw.friendId, "friendId", eventLabel),
244
+ sessionKey: optionalString(raw.sessionKey, "sessionKey", eventLabel),
245
+ session: parseTurnDetection(raw.session, eventLabel),
246
+ floorOwner: optionalFloorOwner(raw.floorOwner, eventLabel),
247
+ floorPhase: optionalFloorPhase(raw.floorPhase, eventLabel),
248
+ speechDecision: optionalSpeechDecision(raw.speechDecision, eventLabel),
249
+ decisionReason: optionalString(raw.decisionReason, "decisionReason", eventLabel),
250
+ pendingSpeechId: optionalString(raw.pendingSpeechId, "pendingSpeechId", eventLabel),
251
+ activeAssistantSpeechId: optionalString(raw.activeAssistantSpeechId, "activeAssistantSpeechId", eventLabel),
252
+ pendingToolCallIds: optionalStringArray(raw.pendingToolCallIds, "pendingToolCallIds", eventLabel),
253
+ staleToolCallIds: optionalStringArray(raw.staleToolCallIds, "staleToolCallIds", eventLabel),
254
+ interruptionTurnId: optionalString(raw.interruptionTurnId, "interruptionTurnId", eventLabel),
255
+ ignored: ignored || undefined,
256
+ ignoreReason: optionalString(raw.ignoreReason, "ignoreReason", eventLabel),
257
+ };
258
+ if (parsed.ignored && !parsed.ignoreReason)
259
+ throw new Error(label(eventLabel, "ignored events require ignoreReason"));
260
+ return parsed;
261
+ }
262
+ function parseVoiceRealtimeEvalTraceArtifact(value, sourceLabel = "voice trace artifact") {
263
+ const raw = objectRecord(value);
264
+ if (!raw || raw.schemaVersion !== 1)
265
+ throw new Error(label(sourceLabel, "schemaVersion must be 1"));
266
+ const expectedOutcome = raw.expectedOutcome;
267
+ if (typeof expectedOutcome !== "string" || !expectedOutcomes.has(expectedOutcome)) {
268
+ throw new Error(label(sourceLabel, "expectedOutcome must be pass, fail, or expected-fail"));
269
+ }
270
+ const expectationProfile = raw.expectationProfile;
271
+ if (expectationProfile !== undefined && (typeof expectationProfile !== "string" || !expectationProfiles.has(expectationProfile))) {
272
+ throw new Error(label(sourceLabel, "expectationProfile is unsupported"));
273
+ }
274
+ const hasInlineExpectation = raw.expectation !== undefined;
275
+ if (hasInlineExpectation === (expectationProfile !== undefined)) {
276
+ throw new Error(label(sourceLabel, "provide exactly one of expectation or expectationProfile"));
277
+ }
278
+ if (!Array.isArray(raw.events) || raw.events.length === 0) {
279
+ throw new Error(label(sourceLabel, "events must contain at least one event"));
280
+ }
281
+ const redacted = raw.redacted;
282
+ if (redacted !== undefined && typeof redacted !== "boolean")
283
+ throw new Error(label(sourceLabel, "redacted must be boolean"));
284
+ return {
285
+ schemaVersion: 1,
286
+ traceId: requiredString(raw.traceId, "traceId", sourceLabel),
287
+ scenarioId: requiredString(raw.scenarioId, "scenarioId", sourceLabel),
288
+ expectedOutcome: expectedOutcome,
289
+ expectation: hasInlineExpectation ? parseExpectation(raw.expectation, sourceLabel) : undefined,
290
+ expectationProfile: expectationProfile,
291
+ redacted: redacted || undefined,
292
+ events: raw.events.map((event, index) => parseTraceEvent(event, index, sourceLabel)),
293
+ };
294
+ }
295
+ function loadVoiceRealtimeEvalTraceArtifact(filePath) {
296
+ let raw;
297
+ try {
298
+ raw = fs.readFileSync(filePath, "utf8");
299
+ }
300
+ catch {
301
+ throw new Error(`${filePath}: failed to read trace artifact`);
302
+ }
303
+ try {
304
+ return parseVoiceRealtimeEvalTraceArtifact(JSON.parse(raw), filePath);
305
+ }
306
+ catch (error) {
307
+ if (error instanceof SyntaxError)
308
+ throw new Error(`${filePath}: invalid JSON: ${error.message}`);
309
+ throw error;
310
+ }
311
+ }
312
+ function resolveVoiceRealtimeEvalTraceExpectation(artifact) {
313
+ if (artifact.expectationProfile === "voice-phone-default")
314
+ return (0, realtime_eval_1.buildVoiceRealtimeEvalDefaultExpectation)();
315
+ if (artifact.expectation)
316
+ return artifact.expectation;
317
+ throw new Error(`${artifact.traceId}: trace artifact has no expectation contract`);
318
+ }
319
+ function eventTypeFor(event) {
320
+ if (normalizedEvents.has(event.event))
321
+ return event.event;
322
+ const type = rawEventMap.get(event.event);
323
+ if (!type)
324
+ throw new Error(`unknown trace event ${event.event}`);
325
+ return type;
326
+ }
327
+ function toTimelineEvent(event, redacted) {
328
+ const type = eventTypeFor(event);
329
+ return {
330
+ type,
331
+ atMs: event.atMs,
332
+ source: event.source,
333
+ correlationId: event.correlationId,
334
+ text: redacted ? undefined : event.text,
335
+ role: event.role,
336
+ toolName: event.toolName,
337
+ friendId: event.friendId,
338
+ sessionKey: event.sessionKey,
339
+ session: event.session,
340
+ floorOwner: event.floorOwner,
341
+ floorPhase: event.floorPhase,
342
+ speechDecision: event.speechDecision,
343
+ decisionReason: event.decisionReason,
344
+ pendingSpeechId: event.pendingSpeechId,
345
+ activeAssistantSpeechId: event.activeAssistantSpeechId,
346
+ pendingToolCallIds: event.pendingToolCallIds,
347
+ staleToolCallIds: event.staleToolCallIds,
348
+ interruptionTurnId: event.interruptionTurnId,
349
+ };
350
+ }
351
+ function sortedTimeline(events) {
352
+ return events
353
+ .map((event, index) => ({ event, index }))
354
+ .sort((left, right) => left.event.atMs - right.event.atMs || left.index - right.index)
355
+ .map(({ event }) => event);
356
+ }
357
+ function findFirst(events, type) {
358
+ return events.find((event) => event.type === type);
359
+ }
360
+ function validateCausalTimeline(artifact, timeline) {
361
+ for (let index = 0; index < artifact.events.length; index += 1) {
362
+ const event = artifact.events[index];
363
+ if (event.ignored)
364
+ continue;
365
+ if (event.atMs < 0) {
366
+ throw new Error(`${artifact.traceId} event[${index}] atMs must be a nonnegative finite number`);
367
+ }
368
+ }
369
+ const connected = findFirst(timeline, "call.connected");
370
+ const audio = findFirst(timeline, "assistant.audio.started");
371
+ if (connected && audio && audio.atMs < connected.atMs) {
372
+ throw new Error(`${artifact.traceId}: assistant audio started before call.connected`);
373
+ }
374
+ for (const response of timeline.filter((event) => event.type === "response.requested" && event.correlationId)) {
375
+ const transcript = timeline.find((event) => event.type === "user.transcript.done" && event.correlationId === response.correlationId);
376
+ if (transcript && response.atMs < transcript.atMs) {
377
+ throw new Error(`${artifact.traceId}: response.requested for ${response.correlationId} occurred before user.transcript.done`);
378
+ }
379
+ }
380
+ for (const completed of timeline.filter((event) => event.type === "tool.call.completed" && event.correlationId)) {
381
+ const started = timeline.find((event) => event.type === "tool.call.started" && event.correlationId === completed.correlationId);
382
+ if (started && completed.atMs < started.atMs) {
383
+ throw new Error(`${artifact.traceId}: tool.call.completed for ${completed.correlationId} occurred before tool.call.started`);
384
+ }
385
+ }
386
+ const expectation = resolveVoiceRealtimeEvalTraceExpectation(artifact);
387
+ if (expectation.requireHangup) {
388
+ const ended = findFirst(timeline, "call.ended");
389
+ const hangup = findFirst(timeline, "call.hangup.requested");
390
+ if (ended && hangup && ended.atMs < hangup.atMs) {
391
+ throw new Error(`${artifact.traceId}: call.ended occurred before call.hangup.requested`);
392
+ }
393
+ }
394
+ }
395
+ function traceArtifactToVoiceRealtimeEvalTimeline(artifact) {
396
+ const timeline = sortedTimeline(artifact.events
397
+ .filter((event) => !event.ignored)
398
+ .map((event) => toTimelineEvent(event, Boolean(artifact.redacted))));
399
+ validateCausalTimeline(artifact, timeline);
400
+ return timeline;
401
+ }
402
+ function expectedOutcomeMatched(expectedOutcome, passed) {
403
+ if (expectedOutcome === "pass")
404
+ return passed;
405
+ return !passed;
406
+ }
407
+ function gradeVoiceRealtimeEvalTrace(artifact) {
408
+ (0, runtime_1.emitNervesEvent)({
409
+ component: "senses",
410
+ event: "senses.voice_realtime_trace_replay_start",
411
+ message: "starting Voice realtime trace replay",
412
+ meta: { scenarioId: artifact.scenarioId, events: artifact.events.length },
413
+ });
414
+ const timeline = traceArtifactToVoiceRealtimeEvalTimeline(artifact);
415
+ const report = (0, realtime_eval_1.gradeVoiceRealtimeEvalTimeline)(artifact.scenarioId, timeline, resolveVoiceRealtimeEvalTraceExpectation(artifact));
416
+ const result = {
417
+ artifact,
418
+ traceId: artifact.traceId,
419
+ scenarioId: artifact.scenarioId,
420
+ expectedOutcome: artifact.expectedOutcome,
421
+ outcomeMatched: expectedOutcomeMatched(artifact.expectedOutcome, report.passed),
422
+ report,
423
+ timeline,
424
+ ignoredEvents: artifact.events.filter((event) => event.ignored),
425
+ };
426
+ (0, runtime_1.emitNervesEvent)({
427
+ component: "senses",
428
+ event: "senses.voice_realtime_trace_replay_end",
429
+ message: "finished Voice realtime trace replay",
430
+ meta: { scenarioId: artifact.scenarioId, passed: report.passed, findings: report.findings.length },
431
+ });
432
+ return result;
433
+ }
434
+ function textForSummary(result, event) {
435
+ if (result.artifact.redacted && (event.type === "assistant.transcript.done" ||
436
+ event.type === "user.transcript.done" ||
437
+ event.type === "voice.context.injected")) {
438
+ return " [redacted]";
439
+ }
440
+ if (event.text === undefined)
441
+ return "";
442
+ return ` "${event.text}"`;
443
+ }
444
+ function sourceForSummary(source) {
445
+ if (!source)
446
+ return "";
447
+ return source.id ? ` ${source.transport}/${source.id}` : ` ${source.transport}`;
448
+ }
449
+ function listForSummary(values) {
450
+ return values && values.length > 0 ? values.join(",") : undefined;
451
+ }
452
+ function floorForSummary(floor) {
453
+ const parts = [];
454
+ if (floor.phase)
455
+ parts.push(`phase=${floor.phase}`);
456
+ if (floor.floorOwner)
457
+ parts.push(`floor=${floor.floorOwner}`);
458
+ if (floor.pendingSpeechId)
459
+ parts.push(`pendingSpeech=${floor.pendingSpeechId}`);
460
+ const pendingTools = listForSummary(floor.pendingToolCallIds);
461
+ if (pendingTools)
462
+ parts.push(`pendingTools=${pendingTools}`);
463
+ const staleTools = listForSummary(floor.staleToolCallIds);
464
+ if (staleTools)
465
+ parts.push(`staleTools=${staleTools}`);
466
+ if (floor.interruptionTurnId)
467
+ parts.push(`interruption=${floor.interruptionTurnId}`);
468
+ if (floor.decisionReason)
469
+ parts.push(`reason=${floor.decisionReason}`);
470
+ if (floor.activeAssistantSpeechId)
471
+ parts.push(`activeSpeech=${floor.activeAssistantSpeechId}`);
472
+ if (floor.speechDecision)
473
+ parts.push(`decision=${floor.speechDecision}`);
474
+ if (floor.responseId)
475
+ parts.push(`response=${floor.responseId}`);
476
+ if (floor.toolCallId)
477
+ parts.push(`tool=${floor.toolCallId}`);
478
+ return parts.join(" ") || "none";
479
+ }
480
+ function floorEventForSummary(event) {
481
+ if (event.floorPhase === undefined
482
+ && event.floorOwner === undefined
483
+ && event.speechDecision === undefined
484
+ && event.decisionReason === undefined
485
+ && event.pendingSpeechId === undefined
486
+ && event.activeAssistantSpeechId === undefined
487
+ && event.pendingToolCallIds === undefined
488
+ && event.staleToolCallIds === undefined
489
+ && event.interruptionTurnId === undefined) {
490
+ return "";
491
+ }
492
+ return ` floor(${floorForSummary({
493
+ phase: event.floorPhase,
494
+ floorOwner: event.floorOwner,
495
+ speechDecision: event.speechDecision,
496
+ decisionReason: event.decisionReason,
497
+ responseId: event.type === "response.requested" || event.type === "speech.policy.decision" ? event.correlationId : undefined,
498
+ toolCallId: event.type === "tool.result.ready" || event.type === "tool.result.spoken" ? event.correlationId : undefined,
499
+ pendingSpeechId: event.pendingSpeechId,
500
+ activeAssistantSpeechId: event.activeAssistantSpeechId,
501
+ pendingToolCallIds: event.pendingToolCallIds,
502
+ staleToolCallIds: event.staleToolCallIds,
503
+ interruptionTurnId: event.interruptionTurnId,
504
+ })})`;
505
+ }
506
+ function formatVoiceRealtimeEvalTraceReport(result) {
507
+ const lines = [
508
+ `trace ${result.traceId} scenario ${result.scenarioId}`,
509
+ `expected: ${result.expectedOutcome}; report passed: ${result.report.passed}; outcome matched: ${result.outcomeMatched}`,
510
+ `transports: ${result.report.transportSources.join(", ") || "none"}`,
511
+ `metrics: ${JSON.stringify(result.report.metrics)}`,
512
+ ];
513
+ if (result.report.findings.length > 0) {
514
+ lines.push("findings:");
515
+ for (const finding of result.report.findings) {
516
+ const message = result.artifact.redacted ? "[redacted]" : finding.message;
517
+ lines.push(`- ${finding.code}${finding.atMs === undefined ? "" : ` at ${finding.atMs}ms`}: ${message}`);
518
+ if (finding.floor)
519
+ lines.push(` floor: ${floorForSummary(finding.floor)}`);
520
+ }
521
+ }
522
+ lines.push("events:");
523
+ for (const event of result.timeline) {
524
+ lines.push(`- ${event.atMs}ms ${event.type}${sourceForSummary(event.source)}${textForSummary(result, event)}${floorEventForSummary(event)}`);
525
+ }
526
+ lines.push(`ignored provider events: ${result.ignoredEvents.length}`);
527
+ for (const event of result.ignoredEvents) {
528
+ lines.push(`- ${event.atMs}ms ${event.event}${sourceForSummary(event.source)}: ${event.ignoreReason}`);
529
+ }
530
+ return lines.join("\n");
531
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildVoiceTranscript = buildVoiceTranscript;
4
+ exports.transcriptToPromptText = transcriptToPromptText;
5
+ exports.normalizeVoiceSessionKey = normalizeVoiceSessionKey;
6
+ const runtime_1 = require("../../nerves/runtime");
7
+ function compactSpeechText(text) {
8
+ return text.replace(/\s+/g, " ").trim();
9
+ }
10
+ function buildVoiceTranscript(input) {
11
+ const text = compactSpeechText(input.text);
12
+ if (!text) {
13
+ (0, runtime_1.emitNervesEvent)({
14
+ level: "error",
15
+ component: "senses",
16
+ event: "senses.voice_transcript_error",
17
+ message: "voice transcript text is empty",
18
+ meta: { utteranceId: input.utteranceId },
19
+ });
20
+ throw new Error("voice transcript text is empty");
21
+ }
22
+ const transcript = {
23
+ utteranceId: input.utteranceId,
24
+ text,
25
+ source: input.source,
26
+ audioPath: input.audioPath ?? null,
27
+ language: input.language ?? null,
28
+ startedAt: input.startedAt ?? null,
29
+ endedAt: input.endedAt ?? null,
30
+ };
31
+ (0, runtime_1.emitNervesEvent)({
32
+ component: "senses",
33
+ event: "senses.voice_transcript_built",
34
+ message: "built voice transcript",
35
+ meta: { utteranceId: transcript.utteranceId, source: transcript.source, length: transcript.text.length },
36
+ });
37
+ return transcript;
38
+ }
39
+ function transcriptToPromptText(transcript) {
40
+ const text = compactSpeechText(transcript.text);
41
+ if (!text) {
42
+ (0, runtime_1.emitNervesEvent)({
43
+ level: "error",
44
+ component: "senses",
45
+ event: "senses.voice_transcript_error",
46
+ message: "voice prompt text is empty",
47
+ meta: { utteranceId: transcript.utteranceId },
48
+ });
49
+ throw new Error("voice transcript text is empty");
50
+ }
51
+ return text;
52
+ }
53
+ function normalizeVoiceSessionKey(value) {
54
+ const normalized = value
55
+ .trim()
56
+ .toLowerCase()
57
+ .replace(/[^a-z0-9]+/g, "-")
58
+ .replace(/^-+|-+$/g, "");
59
+ if (!normalized) {
60
+ (0, runtime_1.emitNervesEvent)({
61
+ level: "error",
62
+ component: "senses",
63
+ event: "senses.voice_transcript_error",
64
+ message: "voice session key is empty",
65
+ meta: { inputLength: value.length },
66
+ });
67
+ throw new Error("voice session key is empty");
68
+ }
69
+ return normalized;
70
+ }