@ouro.bot/cli 0.1.0-alpha.66 → 0.1.0-alpha.660

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 (449) 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 +4209 -13
  13. package/dist/a2a/card.js +56 -0
  14. package/dist/a2a/client.js +143 -0
  15. package/dist/a2a/config.js +50 -0
  16. package/dist/a2a/onboarding.js +111 -0
  17. package/dist/a2a/server.js +498 -0
  18. package/dist/a2a/task-store.js +69 -0
  19. package/dist/a2a/types.js +3 -0
  20. package/dist/arc/attention-types.js +8 -0
  21. package/dist/arc/cares.js +144 -0
  22. package/dist/arc/episodes.js +118 -0
  23. package/dist/arc/evolution.js +487 -0
  24. package/dist/arc/flight-recorder.js +369 -0
  25. package/dist/arc/intentions.js +134 -0
  26. package/dist/arc/json-store.js +117 -0
  27. package/dist/arc/obligations.js +292 -0
  28. package/dist/arc/packets.js +288 -0
  29. package/dist/arc/presence.js +185 -0
  30. package/dist/arc/task-lifecycle.js +57 -0
  31. package/dist/commerce/store.js +755 -0
  32. package/dist/commerce/types.js +3 -0
  33. package/dist/heart/active-work.js +860 -43
  34. package/dist/heart/agent-entry.js +69 -3
  35. package/dist/heart/attachments/image-normalize.js +194 -0
  36. package/dist/heart/attachments/materialize.js +97 -0
  37. package/dist/heart/attachments/originals.js +88 -0
  38. package/dist/heart/attachments/render.js +29 -0
  39. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  40. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  41. package/dist/heart/attachments/sources/index.js +16 -0
  42. package/dist/heart/attachments/store.js +103 -0
  43. package/dist/heart/attachments/types.js +93 -0
  44. package/dist/heart/auth/auth-flow.js +479 -0
  45. package/dist/heart/awaiting/await-alert.js +146 -0
  46. package/dist/heart/awaiting/await-expiry.js +108 -0
  47. package/dist/heart/awaiting/await-loader.js +91 -0
  48. package/dist/heart/awaiting/await-parser.js +141 -0
  49. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  50. package/dist/heart/awaiting/await-scheduler.js +377 -0
  51. package/dist/heart/background-operations.js +281 -0
  52. package/dist/heart/bridges/manager.js +137 -17
  53. package/dist/heart/bridges/store.js +14 -2
  54. package/dist/heart/bundle-state.js +168 -0
  55. package/dist/heart/commitments.js +135 -0
  56. package/dist/heart/config-registry.js +331 -0
  57. package/dist/heart/config.js +118 -119
  58. package/dist/heart/context-loss-gauntlet.js +354 -0
  59. package/dist/heart/core.js +1123 -247
  60. package/dist/heart/cross-chat-delivery.js +3 -18
  61. package/dist/heart/daemon/agent-config-check.js +419 -0
  62. package/dist/heart/daemon/agent-discovery.js +102 -3
  63. package/dist/heart/daemon/agent-service.js +523 -0
  64. package/dist/heart/daemon/agentic-repair.js +547 -0
  65. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  66. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  67. package/dist/heart/daemon/cadence.js +70 -0
  68. package/dist/heart/daemon/cli-defaults.js +780 -0
  69. package/dist/heart/daemon/cli-desk.js +322 -0
  70. package/dist/heart/daemon/cli-exec.js +7767 -0
  71. package/dist/heart/daemon/cli-help.js +558 -0
  72. package/dist/heart/daemon/cli-parse.js +1688 -0
  73. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  74. package/dist/heart/daemon/cli-render.js +763 -0
  75. package/dist/heart/daemon/cli-types.js +8 -0
  76. package/dist/heart/daemon/connect-bay.js +323 -0
  77. package/dist/heart/daemon/daemon-cli.js +29 -1750
  78. package/dist/heart/daemon/daemon-entry.js +485 -2
  79. package/dist/heart/daemon/daemon-health.js +176 -0
  80. package/dist/heart/daemon/daemon-rollup.js +57 -0
  81. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  82. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  83. package/dist/heart/daemon/daemon.js +937 -74
  84. package/dist/heart/daemon/dns-workflow.js +394 -0
  85. package/dist/heart/daemon/doctor-types.js +8 -0
  86. package/dist/heart/daemon/doctor.js +873 -0
  87. package/dist/heart/daemon/health-monitor.js +122 -1
  88. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  89. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  90. package/dist/heart/daemon/http-health-probe.js +80 -0
  91. package/dist/heart/daemon/human-command-screens.js +234 -0
  92. package/dist/heart/daemon/human-readiness.js +114 -0
  93. package/dist/heart/daemon/inner-status.js +78 -0
  94. package/dist/heart/daemon/interactive-repair.js +394 -0
  95. package/dist/heart/daemon/launchd.js +37 -8
  96. package/dist/heart/daemon/log-tailer.js +79 -10
  97. package/dist/heart/daemon/logs-prune.js +110 -0
  98. package/dist/heart/daemon/mcp-canary.js +297 -0
  99. package/dist/heart/daemon/message-router.js +6 -2
  100. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  101. package/dist/heart/daemon/os-cron-deps.js +135 -0
  102. package/dist/heart/daemon/os-cron.js +14 -12
  103. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  104. package/dist/heart/daemon/ouro-entry.js +3 -1
  105. package/dist/heart/daemon/plugin-cli.js +432 -0
  106. package/dist/heart/daemon/process-manager.js +511 -40
  107. package/dist/heart/daemon/provider-discovery.js +137 -0
  108. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  109. package/dist/heart/daemon/pulse.js +475 -0
  110. package/dist/heart/daemon/readiness-repair.js +365 -0
  111. package/dist/heart/daemon/run-hooks.js +2 -0
  112. package/dist/heart/daemon/runtime-logging.js +35 -14
  113. package/dist/heart/daemon/runtime-metadata.js +2 -30
  114. package/dist/heart/daemon/safe-mode.js +161 -0
  115. package/dist/heart/daemon/sense-manager.js +564 -38
  116. package/dist/heart/daemon/session-id-resolver.js +131 -0
  117. package/dist/heart/daemon/skill-management-installer.js +1 -1
  118. package/dist/heart/daemon/socket-client.js +158 -11
  119. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  120. package/dist/heart/daemon/startup-tui.js +330 -0
  121. package/dist/heart/daemon/task-scheduler.js +117 -39
  122. package/dist/heart/daemon/terminal-ui.js +499 -0
  123. package/dist/heart/daemon/thoughts.js +229 -17
  124. package/dist/heart/daemon/up-progress.js +366 -0
  125. package/dist/heart/daemon/vault-items.js +56 -0
  126. package/dist/heart/delegation.js +1 -4
  127. package/dist/heart/habits/habit-migration.js +189 -0
  128. package/dist/heart/habits/habit-parser.js +203 -0
  129. package/dist/heart/habits/habit-runtime-state.js +100 -0
  130. package/dist/heart/habits/habit-scheduler.js +372 -0
  131. package/dist/heart/{daemon → hatch}/hatch-flow.js +40 -56
  132. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  133. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  134. package/dist/heart/{daemon → hatch}/specialist-tools.js +45 -18
  135. package/dist/heart/identity.js +174 -57
  136. package/dist/heart/kept-notes.js +289 -0
  137. package/dist/heart/kicks.js +1 -1
  138. package/dist/heart/machine-identity.js +161 -0
  139. package/dist/heart/mail-import-discovery.js +353 -0
  140. package/dist/heart/mailbox/mailbox-http-hooks.js +67 -0
  141. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  142. package/dist/heart/mailbox/mailbox-http-routes.js +250 -0
  143. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  144. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  145. package/dist/heart/mailbox/mailbox-http.js +99 -0
  146. package/dist/heart/mailbox/mailbox-read.js +32 -0
  147. package/dist/heart/mailbox/mailbox-types.js +27 -0
  148. package/dist/heart/mailbox/mailbox-view.js +197 -0
  149. package/dist/heart/mailbox/readers/agent-machine.js +418 -0
  150. package/dist/heart/mailbox/readers/continuity-readers.js +324 -0
  151. package/dist/heart/mailbox/readers/mail.js +375 -0
  152. package/dist/heart/mailbox/readers/runtime-readers.js +728 -0
  153. package/dist/heart/mailbox/readers/sessions.js +232 -0
  154. package/dist/heart/mailbox/readers/shared.js +111 -0
  155. package/dist/heart/mcp/mcp-server.js +696 -0
  156. package/dist/heart/migrate-config.js +100 -0
  157. package/dist/heart/model-capabilities.js +19 -0
  158. package/dist/heart/orientation-frame.js +217 -0
  159. package/dist/heart/platform.js +81 -0
  160. package/dist/heart/provider-attempt.js +134 -0
  161. package/dist/heart/provider-binding-resolver.js +272 -0
  162. package/dist/heart/provider-credentials.js +425 -0
  163. package/dist/heart/provider-failover.js +311 -0
  164. package/dist/heart/provider-models.js +81 -0
  165. package/dist/heart/provider-ping.js +262 -0
  166. package/dist/heart/provider-readiness-cache.js +40 -0
  167. package/dist/heart/provider-visibility.js +188 -0
  168. package/dist/heart/providers/anthropic-token.js +131 -0
  169. package/dist/heart/providers/anthropic.js +139 -52
  170. package/dist/heart/providers/azure.js +23 -11
  171. package/dist/heart/providers/error-classification.js +127 -0
  172. package/dist/heart/providers/github-copilot.js +145 -0
  173. package/dist/heart/providers/minimax-vlm.js +189 -0
  174. package/dist/heart/providers/minimax.js +26 -8
  175. package/dist/heart/providers/openai-codex-token.js +349 -0
  176. package/dist/heart/providers/openai-codex.js +55 -40
  177. package/dist/heart/runtime-capability-check.js +170 -0
  178. package/dist/heart/runtime-credentials.js +367 -0
  179. package/dist/heart/runtime-cwd.js +87 -0
  180. package/dist/heart/sense-truth.js +17 -4
  181. package/dist/heart/session-activity.js +48 -24
  182. package/dist/heart/session-events.js +1133 -0
  183. package/dist/heart/session-playback-cli-main.js +5 -0
  184. package/dist/heart/session-playback-cli.js +36 -0
  185. package/dist/heart/session-playback.js +231 -0
  186. package/dist/heart/session-stats-cli-main.js +5 -0
  187. package/dist/heart/session-stats.js +182 -0
  188. package/dist/heart/session-transcript.js +133 -0
  189. package/dist/heart/start-of-turn-packet.js +351 -0
  190. package/dist/heart/streaming.js +44 -27
  191. package/dist/heart/structured-output.js +196 -0
  192. package/dist/heart/sync-classification.js +176 -0
  193. package/dist/heart/sync.js +449 -0
  194. package/dist/heart/target-resolution.js +9 -5
  195. package/dist/heart/tempo.js +93 -0
  196. package/dist/heart/temporal-view.js +41 -0
  197. package/dist/heart/timeouts.js +101 -0
  198. package/dist/heart/tool-activity-callbacks.js +59 -0
  199. package/dist/heart/tool-description.js +155 -0
  200. package/dist/heart/tool-friction.js +55 -0
  201. package/dist/heart/tool-loop.js +200 -0
  202. package/dist/heart/turn-context.js +430 -0
  203. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  204. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  205. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  206. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  207. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  208. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  209. package/dist/heart/versioning/update-hooks.js +154 -0
  210. package/dist/heart/work-card.js +386 -0
  211. package/dist/mailbox-ui/assets/index-B-V9vRQ0.js +61 -0
  212. package/dist/mailbox-ui/assets/index-BOZbGbkL.css +1 -0
  213. package/dist/mailbox-ui/index.html +15 -0
  214. package/dist/mailroom/attention.js +167 -0
  215. package/dist/mailroom/autonomy.js +209 -0
  216. package/dist/mailroom/blob-store.js +715 -0
  217. package/dist/mailroom/body-cache.js +61 -0
  218. package/dist/mailroom/core.js +788 -0
  219. package/dist/mailroom/entry.js +160 -0
  220. package/dist/mailroom/file-store.js +568 -0
  221. package/dist/mailroom/mbox-import.js +393 -0
  222. package/dist/mailroom/migration.js +164 -0
  223. package/dist/mailroom/outbound.js +380 -0
  224. package/dist/mailroom/policy.js +263 -0
  225. package/dist/mailroom/reader.js +233 -0
  226. package/dist/mailroom/search-cache.js +334 -0
  227. package/dist/mailroom/search-relevance.js +319 -0
  228. package/dist/mailroom/smtp-ingress.js +176 -0
  229. package/dist/mailroom/source-state.js +176 -0
  230. package/dist/mailroom/thread.js +109 -0
  231. package/dist/mailroom/travel-extract.js +89 -0
  232. package/dist/mind/bundle-manifest.js +21 -2
  233. package/dist/mind/context.js +250 -101
  234. package/dist/mind/desk-section.js +362 -0
  235. package/dist/mind/diary-integrity.js +60 -0
  236. package/dist/mind/{memory.js → diary.js} +68 -77
  237. package/dist/mind/embedding-provider.js +60 -0
  238. package/dist/mind/file-state.js +179 -0
  239. package/dist/mind/friends/channel.js +48 -0
  240. package/dist/mind/friends/resolver.js +67 -4
  241. package/dist/mind/friends/store-file.js +61 -4
  242. package/dist/mind/friends/types.js +2 -2
  243. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  244. package/dist/mind/obligation-steering.js +221 -0
  245. package/dist/mind/pending.js +6 -1
  246. package/dist/mind/prompt-refresh.js +3 -2
  247. package/dist/mind/prompt.js +1015 -140
  248. package/dist/mind/provenance-trust.js +26 -0
  249. package/dist/mind/record-paths.js +312 -0
  250. package/dist/mind/scrutiny.js +173 -0
  251. package/dist/nerves/cli-logging.js +7 -1
  252. package/dist/nerves/coverage/audit-rules.js +15 -6
  253. package/dist/nerves/coverage/audit.js +28 -2
  254. package/dist/nerves/coverage/cli.js +1 -1
  255. package/dist/nerves/coverage/contract.js +5 -5
  256. package/dist/nerves/coverage/file-completeness.js +139 -5
  257. package/dist/nerves/event-buffer.js +111 -0
  258. package/dist/nerves/index.js +224 -4
  259. package/dist/nerves/observation.js +20 -0
  260. package/dist/nerves/redact.js +79 -0
  261. package/dist/nerves/review/cli-main.js +5 -0
  262. package/dist/nerves/review/cli.js +156 -0
  263. package/dist/nerves/review/core.js +152 -0
  264. package/dist/nerves/runtime.js +5 -1
  265. package/dist/repertoire/ado-client.js +15 -56
  266. package/dist/repertoire/ado-semantic.js +16 -10
  267. package/dist/repertoire/api-client.js +97 -0
  268. package/dist/repertoire/bitwarden-store.js +1041 -0
  269. package/dist/repertoire/bundle-templates.js +71 -0
  270. package/dist/repertoire/bw-installer.js +180 -0
  271. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  272. package/dist/repertoire/coding/context-pack.js +331 -0
  273. package/dist/repertoire/coding/feedback.js +197 -30
  274. package/dist/repertoire/coding/manager.js +166 -10
  275. package/dist/repertoire/coding/spawner.js +55 -9
  276. package/dist/repertoire/coding/tools.js +219 -7
  277. package/dist/repertoire/commerce-errors.js +109 -0
  278. package/dist/repertoire/commerce-self-test.js +156 -0
  279. package/dist/repertoire/credential-access.js +178 -0
  280. package/dist/repertoire/desk/classifier.js +362 -0
  281. package/dist/repertoire/duffel-client.js +185 -0
  282. package/dist/repertoire/github-client.js +14 -55
  283. package/dist/repertoire/graph-client.js +11 -52
  284. package/dist/repertoire/guardrails.js +159 -25
  285. package/dist/repertoire/mcp-client.js +295 -0
  286. package/dist/repertoire/mcp-manager.js +434 -0
  287. package/dist/repertoire/mcp-tools.js +83 -0
  288. package/dist/repertoire/plugin-mcp.js +175 -0
  289. package/dist/repertoire/plugins.js +253 -0
  290. package/dist/repertoire/shell-sessions.js +133 -0
  291. package/dist/repertoire/skills.js +48 -4
  292. package/dist/repertoire/stripe-client.js +131 -0
  293. package/dist/repertoire/tool-results.js +29 -0
  294. package/dist/repertoire/tools-a2a.js +283 -0
  295. package/dist/repertoire/tools-attachments.js +317 -0
  296. package/dist/repertoire/tools-awaiting.js +372 -0
  297. package/dist/repertoire/tools-base.js +63 -1082
  298. package/dist/repertoire/tools-bluebubbles.js +2 -0
  299. package/dist/repertoire/tools-bridge.js +144 -0
  300. package/dist/repertoire/tools-bundle.js +993 -0
  301. package/dist/repertoire/tools-commerce.js +253 -0
  302. package/dist/repertoire/tools-config.js +186 -0
  303. package/dist/repertoire/tools-continuity.js +252 -0
  304. package/dist/repertoire/tools-credential.js +383 -0
  305. package/dist/repertoire/tools-evolution.js +527 -0
  306. package/dist/repertoire/tools-files.js +344 -0
  307. package/dist/repertoire/tools-flight.js +290 -0
  308. package/dist/repertoire/tools-flow.js +119 -0
  309. package/dist/repertoire/tools-github.js +3 -8
  310. package/dist/repertoire/tools-mail.js +1975 -0
  311. package/dist/repertoire/tools-notes.js +418 -0
  312. package/dist/repertoire/tools-obligations.js +143 -0
  313. package/dist/repertoire/tools-orientation.js +31 -0
  314. package/dist/repertoire/tools-record.js +469 -0
  315. package/dist/repertoire/tools-runtime.js +150 -0
  316. package/dist/repertoire/tools-session.js +766 -0
  317. package/dist/repertoire/tools-shell.js +120 -0
  318. package/dist/repertoire/tools-stripe.js +224 -0
  319. package/dist/repertoire/tools-surface.js +344 -0
  320. package/dist/repertoire/tools-teams.js +12 -39
  321. package/dist/repertoire/tools-travel.js +125 -0
  322. package/dist/repertoire/tools-trip.js +982 -0
  323. package/dist/repertoire/tools-user-profile.js +146 -0
  324. package/dist/repertoire/tools-vault.js +40 -0
  325. package/dist/repertoire/tools-voice.js +145 -0
  326. package/dist/repertoire/tools.js +243 -79
  327. package/dist/repertoire/travel-api-client.js +360 -0
  328. package/dist/repertoire/user-profile.js +131 -0
  329. package/dist/repertoire/vault-setup.js +246 -0
  330. package/dist/repertoire/vault-unlock.js +594 -0
  331. package/dist/scripts/claude-code-hook.js +41 -0
  332. package/dist/scripts/claude-code-stop-hook.js +47 -0
  333. package/dist/senses/a2a-entry.js +78 -0
  334. package/dist/senses/attention-queue.js +186 -0
  335. package/dist/senses/await-turn-message.js +58 -0
  336. package/dist/senses/bluebubbles/active-turns.js +216 -0
  337. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  338. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  339. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  340. package/dist/senses/bluebubbles/entry.js +77 -0
  341. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  342. package/dist/senses/bluebubbles/index.js +2737 -0
  343. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  344. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  345. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  346. package/dist/senses/bluebubbles/processed-log.js +133 -0
  347. package/dist/senses/bluebubbles/replay.js +137 -0
  348. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  349. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  350. package/dist/senses/bluebubbles-meta-guard.js +40 -0
  351. package/dist/senses/cli/bracketed-paste.js +82 -0
  352. package/dist/senses/cli/image-paste.js +287 -0
  353. package/dist/senses/cli/image-ref-navigation.js +75 -0
  354. package/dist/senses/cli/ink-app.js +156 -0
  355. package/dist/senses/cli/inline-diff.js +64 -0
  356. package/dist/senses/cli/input-keys.js +174 -0
  357. package/dist/senses/cli/kill-ring.js +86 -0
  358. package/dist/senses/cli/message-list.js +51 -0
  359. package/dist/senses/cli/ouro-tui.js +607 -0
  360. package/dist/senses/cli/spinner-imperative.js +135 -0
  361. package/dist/senses/cli/spinner.js +101 -0
  362. package/dist/senses/cli/status-line.js +60 -0
  363. package/dist/senses/cli/streaming-markdown.js +526 -0
  364. package/dist/senses/cli/tool-display.js +85 -0
  365. package/dist/senses/cli/tool-render.js +85 -0
  366. package/dist/senses/cli/tui-store.js +240 -0
  367. package/dist/senses/cli/virtual-list.js +35 -0
  368. package/dist/senses/cli-entry.js +60 -8
  369. package/dist/senses/cli-layout.js +100 -0
  370. package/dist/senses/cli.js +517 -204
  371. package/dist/senses/commands.js +66 -3
  372. package/dist/senses/habit-turn-message.js +122 -0
  373. package/dist/senses/inner-dialog-worker.js +303 -22
  374. package/dist/senses/inner-dialog.js +525 -41
  375. package/dist/senses/mail-entry.js +66 -0
  376. package/dist/senses/mail.js +379 -0
  377. package/dist/senses/pipeline.js +857 -180
  378. package/dist/senses/proactive-content-guard.js +51 -0
  379. package/dist/senses/shared-turn.js +419 -0
  380. package/dist/senses/surface-tool.js +108 -0
  381. package/dist/senses/teams-entry.js +60 -8
  382. package/dist/senses/teams.js +390 -98
  383. package/dist/senses/trust-gate.js +100 -5
  384. package/dist/senses/voice/audio-playback.js +237 -0
  385. package/dist/senses/voice/audio-routing.js +119 -0
  386. package/dist/senses/voice/elevenlabs.js +202 -0
  387. package/dist/senses/voice/floor-control.js +431 -0
  388. package/dist/senses/voice/floor-controller.js +115 -0
  389. package/dist/senses/voice/golden-path.js +116 -0
  390. package/dist/senses/voice/index.js +29 -0
  391. package/dist/senses/voice/meeting.js +113 -0
  392. package/dist/senses/voice/outbound.js +190 -0
  393. package/dist/senses/voice/phone.js +33 -0
  394. package/dist/senses/voice/playback.js +139 -0
  395. package/dist/senses/voice/realtime-eval.js +496 -0
  396. package/dist/senses/voice/realtime-trace.js +531 -0
  397. package/dist/senses/voice/transcript.js +70 -0
  398. package/dist/senses/voice/turn.js +191 -0
  399. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  400. package/dist/senses/voice/twilio-phone.js +5079 -0
  401. package/dist/senses/voice/types.js +2 -0
  402. package/dist/senses/voice/whisper.js +161 -0
  403. package/dist/senses/voice-entry.js +81 -0
  404. package/dist/senses/voice-realtime-eval-command.js +99 -0
  405. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  406. package/dist/senses/voice-twilio-entry.js +87 -0
  407. package/dist/trips/core.js +138 -0
  408. package/dist/trips/store.js +265 -0
  409. package/dist/util/frontmatter.js +69 -0
  410. package/package.json +55 -12
  411. package/skills/agent-commerce.md +113 -0
  412. package/skills/browser-navigation.md +117 -0
  413. package/skills/commerce-setup-guide.md +116 -0
  414. package/skills/commerce-setup.md +84 -0
  415. package/skills/configure-dev-tools.md +99 -0
  416. package/skills/travel-planning.md +138 -0
  417. package/dist/heart/daemon/auth-flow.js +0 -351
  418. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  419. package/dist/heart/daemon/update-hooks.js +0 -138
  420. package/dist/heart/safe-workspace.js +0 -228
  421. package/dist/heart/session-recall.js +0 -116
  422. package/dist/repertoire/tasks/board.js +0 -134
  423. package/dist/repertoire/tasks/index.js +0 -224
  424. package/dist/repertoire/tasks/lifecycle.js +0 -80
  425. package/dist/repertoire/tasks/middleware.js +0 -65
  426. package/dist/repertoire/tasks/parser.js +0 -173
  427. package/dist/repertoire/tasks/scanner.js +0 -132
  428. package/dist/repertoire/tasks/transitions.js +0 -144
  429. package/dist/senses/bluebubbles-entry.js +0 -13
  430. package/dist/senses/bluebubbles.js +0 -1177
  431. package/dist/senses/debug-activity.js +0 -148
  432. package/subagents/README.md +0 -7
  433. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  434. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  435. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  436. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  437. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  438. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  439. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  440. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  441. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  442. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  443. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  444. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  445. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  446. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  447. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  448. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  449. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,283 @@
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.a2aToolDefinitions = void 0;
37
+ const path = __importStar(require("node:path"));
38
+ const identity_1 = require("../heart/identity");
39
+ const runtime_credentials_1 = require("../heart/runtime-credentials");
40
+ const types_1 = require("../mind/friends/types");
41
+ const store_file_1 = require("../mind/friends/store-file");
42
+ const runtime_1 = require("../nerves/runtime");
43
+ const client_1 = require("../a2a/client");
44
+ const outboundTaskTokens = new Map();
45
+ function tokenKey(ctx, friendId, taskId) {
46
+ return `${ctx?.agentRoot ?? "ambient"}\n${friendId}\n${taskId}`;
47
+ }
48
+ function rememberTaskToken(ctx, friendId, task) {
49
+ /* v8 ignore next -- defensive metadata-shape guard; protocol tasks from Ouro servers always use object metadata @preserve */
50
+ const token = task.metadata?.a2a && typeof task.metadata.a2a === "object" && !Array.isArray(task.metadata.a2a)
51
+ ? task.metadata.a2a.accessToken
52
+ : undefined;
53
+ if (typeof token === "string" && token.trim()) {
54
+ outboundTaskTokens.set(tokenKey(ctx, friendId, task.id), token.trim());
55
+ }
56
+ }
57
+ function rememberedTaskToken(ctx, friendId, taskId) {
58
+ return outboundTaskTokens.get(tokenKey(ctx, friendId, taskId));
59
+ }
60
+ function redactTaskToken(task) {
61
+ const a2a = task.metadata?.a2a;
62
+ if (!a2a || typeof a2a !== "object" || Array.isArray(a2a) || !("accessToken" in a2a))
63
+ return task;
64
+ const { accessToken: _accessToken, ...safeA2A } = a2a;
65
+ return {
66
+ ...task,
67
+ metadata: {
68
+ ...task.metadata,
69
+ a2a: safeA2A,
70
+ },
71
+ };
72
+ }
73
+ function storeFor(ctx) {
74
+ if (ctx?.friendStore)
75
+ return ctx.friendStore;
76
+ /* v8 ignore next -- no-agentRoot fallback depends on process argv; normal tool calls inject agentRoot @preserve */
77
+ if (ctx?.agentRoot)
78
+ return new store_file_1.FileFriendStore(path.join(ctx.agentRoot, "friends"));
79
+ return new store_file_1.FileFriendStore(path.join((0, identity_1.getAgentRoot)(), "friends"));
80
+ }
81
+ function requireTrustedRequester(ctx) {
82
+ if (!ctx?.context?.friend?.id)
83
+ return "no friend context — cannot use A2A tools.";
84
+ if (!(0, types_1.isTrustedLevel)(ctx.context.friend.trustLevel))
85
+ return "A2A tools require friend or family trust.";
86
+ return null;
87
+ }
88
+ function isA2APeer(friend) {
89
+ return friend.kind === "agent" && friend.externalIds.some((id) => id.provider === "a2a-agent");
90
+ }
91
+ function agentNameFromRoot(agentRoot) {
92
+ if (!agentRoot)
93
+ return undefined;
94
+ const base = path.basename(agentRoot);
95
+ return base.endsWith(".ouro") ? base.slice(0, -".ouro".length) : undefined;
96
+ }
97
+ function textField(record, key) {
98
+ const value = record?.[key];
99
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
100
+ }
101
+ function localA2ACardUrl(agentRoot) {
102
+ const agentName = agentNameFromRoot(agentRoot);
103
+ if (!agentName)
104
+ return undefined;
105
+ const result = (0, runtime_credentials_1.readMachineRuntimeCredentialConfig)(agentName);
106
+ if (!result.ok)
107
+ return undefined;
108
+ const a2a = result.config.a2a;
109
+ if (!a2a || typeof a2a !== "object" || Array.isArray(a2a))
110
+ return undefined;
111
+ const publicUrl = textField(a2a, "publicUrl");
112
+ return publicUrl ? `${publicUrl.replace(/\/+$/, "")}/.well-known/agent-card.json` : undefined;
113
+ }
114
+ async function resolveA2AEndpoint(friend) {
115
+ const metadata = friend.agentMeta?.a2a;
116
+ if (metadata?.endpointUrl) {
117
+ return { endpointUrl: metadata.endpointUrl, agentId: metadata.agentId, peerName: friend.name };
118
+ }
119
+ if (metadata?.cardUrl) {
120
+ const card = await (0, client_1.fetchA2AAgentCard)(metadata.cardUrl);
121
+ const endpointUrl = (0, client_1.endpointForCard)(card);
122
+ /* v8 ignore next -- fetchA2AAgentCard rejects cards without a usable endpoint before tools see them @preserve */
123
+ if (!endpointUrl)
124
+ throw new Error("A2A card has no JSONRPC endpoint");
125
+ /* v8 ignore next -- empty card names are invalid in practice; friend-name fallback is defensive @preserve */
126
+ const peerName = card.name || friend.name;
127
+ return { endpointUrl, agentId: metadata.agentId ?? endpointUrl, peerName };
128
+ }
129
+ const external = friend.externalIds.find((id) => id.provider === "a2a-agent");
130
+ if (external?.externalId?.startsWith("http")) {
131
+ const card = await (0, client_1.fetchA2AAgentCard)(external.externalId);
132
+ const endpointUrl = (0, client_1.endpointForCard)(card);
133
+ /* v8 ignore next -- fetchA2AAgentCard rejects cards without a usable endpoint before tools see them @preserve */
134
+ if (!endpointUrl)
135
+ throw new Error("A2A card has no JSONRPC endpoint");
136
+ /* v8 ignore next -- empty card names are invalid in practice; friend-name fallback is defensive @preserve */
137
+ const peerName = card.name || friend.name;
138
+ return { endpointUrl, agentId: external.externalId, peerName };
139
+ }
140
+ throw new Error("A2A peer has no endpointUrl or cardUrl in agentMeta.a2a");
141
+ }
142
+ exports.a2aToolDefinitions = [
143
+ {
144
+ tool: {
145
+ type: "function",
146
+ function: {
147
+ name: "a2a_list_peers",
148
+ description: "List onboarded A2A agent peers from the friend model. Requires friend or family trust.",
149
+ parameters: {
150
+ type: "object",
151
+ properties: {},
152
+ },
153
+ },
154
+ },
155
+ handler: async (_args, ctx) => {
156
+ (0, runtime_1.emitNervesEvent)({
157
+ component: "repertoire",
158
+ event: "repertoire.tool_a2a_list_peers",
159
+ message: "a2a_list_peers invoked",
160
+ meta: { tool: "a2a_list_peers" },
161
+ });
162
+ const guard = requireTrustedRequester(ctx);
163
+ if (guard)
164
+ return guard;
165
+ const store = storeFor(ctx);
166
+ const listAll = store.listAll;
167
+ if (!listAll)
168
+ return "friend store does not support listing.";
169
+ const peers = (await listAll.call(store)).filter(isA2APeer);
170
+ return JSON.stringify(peers.map((peer) => ({
171
+ id: peer.id,
172
+ name: peer.name,
173
+ trustLevel: peer.trustLevel ?? "friend",
174
+ endpointUrl: peer.agentMeta?.a2a?.endpointUrl,
175
+ cardUrl: peer.agentMeta?.a2a?.cardUrl,
176
+ })), null, 2);
177
+ },
178
+ summaryKeys: [],
179
+ },
180
+ {
181
+ tool: {
182
+ type: "function",
183
+ function: {
184
+ name: "a2a_send_message",
185
+ description: "Send a message to a trusted A2A agent peer. The target peer must be an agent friend at friend/family trust.",
186
+ parameters: {
187
+ type: "object",
188
+ properties: {
189
+ friend_id: { type: "string", description: "Friend record ID for the A2A agent peer." },
190
+ message: { type: "string", description: "Message or task request to send." },
191
+ session_key: { type: "string", description: "Optional A2A context/session key." },
192
+ },
193
+ required: ["friend_id", "message"],
194
+ },
195
+ },
196
+ },
197
+ handler: async (args, ctx) => {
198
+ (0, runtime_1.emitNervesEvent)({
199
+ component: "repertoire",
200
+ event: "repertoire.tool_a2a_send_message",
201
+ message: "a2a_send_message invoked",
202
+ meta: { tool: "a2a_send_message", friendId: args.friend_id },
203
+ });
204
+ const guard = requireTrustedRequester(ctx);
205
+ if (guard)
206
+ return guard;
207
+ const peer = await storeFor(ctx).get(args.friend_id);
208
+ if (!peer || !isA2APeer(peer))
209
+ return `A2A peer not found: ${args.friend_id}`;
210
+ if (!(0, types_1.isTrustedLevel)(peer.trustLevel))
211
+ return "target A2A peer must be friend or family trust before outbound messages.";
212
+ try {
213
+ const endpoint = await resolveA2AEndpoint(peer);
214
+ const task = await (0, client_1.sendA2AMessage)({
215
+ endpointUrl: endpoint.endpointUrl,
216
+ message: args.message,
217
+ senderAgentId: agentNameFromRoot(ctx?.agentRoot) ?? "ouro-agent",
218
+ senderName: agentNameFromRoot(ctx?.agentRoot) ?? "Ouro agent",
219
+ senderCardUrl: localA2ACardUrl(ctx?.agentRoot),
220
+ sessionKey: args.session_key,
221
+ });
222
+ rememberTaskToken(ctx, peer.id, task);
223
+ return JSON.stringify(redactTaskToken(task), null, 2);
224
+ }
225
+ catch (error) {
226
+ return `A2A send error: ${error instanceof Error ? error.message : /* v8 ignore next -- defensive non-Error transport failures */ String(error)}`;
227
+ }
228
+ },
229
+ summaryKeys: ["friend_id", "session_key"],
230
+ riskProfile: { mutates: "external_side_effect", risk: "high", reason: "sends a message to a remote agent peer" },
231
+ },
232
+ {
233
+ tool: {
234
+ type: "function",
235
+ function: {
236
+ name: "a2a_get_task",
237
+ description: "Fetch a task from a trusted A2A agent peer.",
238
+ parameters: {
239
+ type: "object",
240
+ properties: {
241
+ friend_id: { type: "string", description: "Friend record ID for the A2A agent peer." },
242
+ task_id: { type: "string", description: "Remote A2A task ID." },
243
+ access_token: { type: "string", description: "Optional task access token from an external A2A response; omitted for tasks sent through a2a_send_message because Ouro stores it out of transcript." },
244
+ },
245
+ required: ["friend_id", "task_id"],
246
+ },
247
+ },
248
+ },
249
+ handler: async (args, ctx) => {
250
+ (0, runtime_1.emitNervesEvent)({
251
+ component: "repertoire",
252
+ event: "repertoire.tool_a2a_get_task",
253
+ message: "a2a_get_task invoked",
254
+ meta: { tool: "a2a_get_task", friendId: args.friend_id, taskId: args.task_id },
255
+ });
256
+ const guard = requireTrustedRequester(ctx);
257
+ if (guard)
258
+ return guard;
259
+ const peer = await storeFor(ctx).get(args.friend_id);
260
+ if (!peer || !isA2APeer(peer))
261
+ return `A2A peer not found: ${args.friend_id}`;
262
+ if (!(0, types_1.isTrustedLevel)(peer.trustLevel))
263
+ return "target A2A peer must be friend or family trust before task lookup.";
264
+ try {
265
+ const endpoint = await resolveA2AEndpoint(peer);
266
+ const task = await (0, client_1.getA2ATask)({
267
+ endpointUrl: endpoint.endpointUrl,
268
+ taskId: args.task_id,
269
+ accessToken: args.access_token ?? rememberedTaskToken(ctx, peer.id, args.task_id),
270
+ senderAgentId: agentNameFromRoot(ctx?.agentRoot) ?? "ouro-agent",
271
+ senderName: agentNameFromRoot(ctx?.agentRoot) ?? "Ouro agent",
272
+ senderCardUrl: localA2ACardUrl(ctx?.agentRoot),
273
+ });
274
+ rememberTaskToken(ctx, peer.id, task);
275
+ return JSON.stringify(redactTaskToken(task), null, 2);
276
+ }
277
+ catch (error) {
278
+ return `A2A task error: ${error instanceof Error ? error.message : /* v8 ignore next -- defensive non-Error transport failures */ String(error)}`;
279
+ }
280
+ },
281
+ summaryKeys: ["friend_id", "task_id"],
282
+ },
283
+ ];
@@ -0,0 +1,317 @@
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.attachmentToolDefinitions = void 0;
37
+ const fs = __importStar(require("node:fs/promises"));
38
+ const identity_1 = require("../heart/identity");
39
+ const provider_credentials_1 = require("../heart/provider-credentials");
40
+ const minimax_1 = require("../heart/providers/minimax");
41
+ const minimax_vlm_1 = require("../heart/providers/minimax-vlm");
42
+ const store_1 = require("../heart/attachments/store");
43
+ const materialize_1 = require("../heart/attachments/materialize");
44
+ const runtime_1 = require("../nerves/runtime");
45
+ const tool_results_1 = require("./tool-results");
46
+ const LIST_ATTACHMENTS_DESCRIPTION = "List the most recent attachments the harness preserved across senses. Use this when you need a stable attachment_id, " +
47
+ "when a repair flow says an attachment could not be found, or when you want to inspect what artifacts are currently on hand " +
48
+ "before asking the user to resend anything.";
49
+ const MATERIALIZE_ATTACHMENT_DESCRIPTION = "Materialize an attachment into a concrete file path the harness can inspect or hand to other tools. " +
50
+ "Use variant=original when you want the raw file. Use variant=vision_safe for images when you want the harness to normalize " +
51
+ "size and format into a VLM-safe image before retrying.";
52
+ const DESCRIBE_IMAGE_DESCRIPTION = "Use this to inspect an image attachment with a targeted question, or to re-interrogate an image after a wrong first answer. " +
53
+ "The harness materializes the original attachment, normalizes it into a VLM-safe image when needed, and sends it through the vision-language model. " +
54
+ "Prefer specific prompts like 'what is the confirmation number?' over 'describe this image'. " +
55
+ "Pass attachment_id when you have it; attachment_guid is accepted as a compatibility alias.";
56
+ function trimArg(value) {
57
+ return value?.trim() ?? "";
58
+ }
59
+ function resolveAttachmentId(args) {
60
+ return trimArg(args.attachment_id) || trimArg(args.attachment_guid);
61
+ }
62
+ function parseLimit(raw) {
63
+ if (!raw)
64
+ return undefined;
65
+ const parsed = Number.parseInt(raw, 10);
66
+ if (!Number.isFinite(parsed) || parsed <= 0)
67
+ return undefined;
68
+ return parsed;
69
+ }
70
+ function normalizeThrownReason(error) {
71
+ const rendered = String(error);
72
+ return rendered.startsWith("Error: ") ? rendered.slice(7) : rendered;
73
+ }
74
+ function attachmentNotFound(tool, attachmentId) {
75
+ const friction = {
76
+ kind: "local_repair",
77
+ recoverability: "transformable",
78
+ summary: `Attachment ${attachmentId} is not in the recent attachment store anymore.`,
79
+ signature: `${tool}:attachment-not-found`,
80
+ suggested_next_actions: [
81
+ {
82
+ kind: "tool",
83
+ tool: "list_recent_attachments",
84
+ reason: "Find the current attachment_id for the artifact you want to inspect before retrying.",
85
+ },
86
+ ],
87
+ };
88
+ return (0, tool_results_1.frictionToolResult)(tool, friction);
89
+ }
90
+ function missingAttachmentId(tool) {
91
+ return (0, tool_results_1.frictionToolResult)(tool, {
92
+ kind: "input_error",
93
+ recoverability: "transformable",
94
+ summary: "An attachment id is required for this tool call.",
95
+ signature: `${tool}:missing-attachment-id`,
96
+ suggested_next_actions: [
97
+ {
98
+ kind: "tool",
99
+ tool: "list_recent_attachments",
100
+ reason: "Inspect the current recent attachments and retry with attachment_id.",
101
+ },
102
+ ],
103
+ });
104
+ }
105
+ function missingPrompt() {
106
+ return (0, tool_results_1.frictionToolResult)("describe_image", {
107
+ kind: "input_error",
108
+ recoverability: "transformable",
109
+ summary: "describe_image needs a targeted prompt before retrying.",
110
+ signature: "describe_image:missing-prompt",
111
+ suggested_next_actions: [
112
+ {
113
+ kind: "message",
114
+ message: "Retry with a specific question like 'what is the confirmation number?' or 'what date is shown?'",
115
+ },
116
+ ],
117
+ });
118
+ }
119
+ function normalizeMaterializeError(tool, attachmentId, reason) {
120
+ if (reason.startsWith("Attachment not found:")) {
121
+ return attachmentNotFound(tool, attachmentId);
122
+ }
123
+ if (reason.includes("is not an image")) {
124
+ return (0, tool_results_1.frictionToolResult)(tool, {
125
+ kind: "input_error",
126
+ recoverability: "transformable",
127
+ summary: `Attachment ${attachmentId} is not an image, so it cannot produce a vision_safe variant.`,
128
+ signature: `${tool}:not-image`,
129
+ suggested_next_actions: [
130
+ {
131
+ kind: "tool",
132
+ tool: "materialize_attachment",
133
+ reason: "Retry with variant=original if you need the raw file instead.",
134
+ args: { attachment_id: attachmentId, variant: "original" },
135
+ },
136
+ ],
137
+ });
138
+ }
139
+ return (0, tool_results_1.frictionToolResult)(tool, {
140
+ kind: "local_repair",
141
+ recoverability: "retryable",
142
+ summary: reason,
143
+ signature: `${tool}:materialize-failed`,
144
+ suggested_next_actions: [
145
+ {
146
+ kind: "tool",
147
+ tool: "materialize_attachment",
148
+ reason: "Retry materialization once more in case the file path or normalization target changed.",
149
+ args: { attachment_id: attachmentId, variant: "vision_safe" },
150
+ },
151
+ ],
152
+ });
153
+ }
154
+ async function buildImageDataUrl(filePath, mimeType) {
155
+ const buffer = await fs.readFile(filePath);
156
+ const encoded = buffer.toString("base64");
157
+ const normalizedMime = mimeType?.trim().toLowerCase() || "image/jpeg";
158
+ return `data:${normalizedMime};base64,${encoded}`;
159
+ }
160
+ exports.attachmentToolDefinitions = [
161
+ {
162
+ tool: {
163
+ type: "function",
164
+ function: {
165
+ name: "list_recent_attachments",
166
+ description: LIST_ATTACHMENTS_DESCRIPTION,
167
+ parameters: {
168
+ type: "object",
169
+ properties: {
170
+ kind: {
171
+ type: "string",
172
+ enum: ["image", "audio", "document", "binary", "unknown"],
173
+ description: "Optional attachment kind filter.",
174
+ },
175
+ limit: {
176
+ type: "string",
177
+ description: "Optional numeric limit for how many attachments to return.",
178
+ },
179
+ },
180
+ },
181
+ },
182
+ },
183
+ handler: async (args) => {
184
+ const agentName = (0, identity_1.getAgentName)();
185
+ const kind = trimArg(args.kind);
186
+ const attachments = (0, store_1.listRecentAttachments)(agentName, {
187
+ kind: kind ? kind : undefined,
188
+ limit: parseLimit(args.limit),
189
+ });
190
+ return (0, tool_results_1.okToolResult)("list_recent_attachments", attachments);
191
+ },
192
+ summaryKeys: ["kind", "limit"],
193
+ },
194
+ {
195
+ tool: {
196
+ type: "function",
197
+ function: {
198
+ name: "materialize_attachment",
199
+ description: MATERIALIZE_ATTACHMENT_DESCRIPTION,
200
+ parameters: {
201
+ type: "object",
202
+ properties: {
203
+ attachment_id: {
204
+ type: "string",
205
+ description: "Stable attachment id such as attachment:cli-local-file:... or attachment:bluebubbles:...",
206
+ },
207
+ attachment_guid: {
208
+ type: "string",
209
+ description: "Compatibility alias for older callers. Prefer attachment_id.",
210
+ },
211
+ variant: {
212
+ type: "string",
213
+ enum: ["original", "vision_safe"],
214
+ description: "Which attachment variant to materialize.",
215
+ },
216
+ },
217
+ required: ["variant"],
218
+ },
219
+ },
220
+ },
221
+ handler: async (args) => {
222
+ const attachmentId = resolveAttachmentId(args);
223
+ if (!attachmentId) {
224
+ return missingAttachmentId("materialize_attachment");
225
+ }
226
+ const agentName = (0, identity_1.getAgentName)();
227
+ const variant = trimArg(args.variant) === "vision_safe" ? "vision_safe" : "original";
228
+ try {
229
+ const materialized = await (0, materialize_1.materializeAttachment)(agentName, attachmentId, { variant });
230
+ return (0, tool_results_1.okToolResult)("materialize_attachment", materialized);
231
+ }
232
+ catch (error) {
233
+ const reason = normalizeThrownReason(error);
234
+ return normalizeMaterializeError("materialize_attachment", attachmentId, reason);
235
+ }
236
+ },
237
+ summaryKeys: ["attachment_id", "attachment_guid", "variant"],
238
+ },
239
+ {
240
+ tool: {
241
+ type: "function",
242
+ function: {
243
+ name: "describe_image",
244
+ description: DESCRIBE_IMAGE_DESCRIPTION,
245
+ parameters: {
246
+ type: "object",
247
+ properties: {
248
+ attachment_id: {
249
+ type: "string",
250
+ description: "Stable attachment id for the image you want to inspect.",
251
+ },
252
+ attachment_guid: {
253
+ type: "string",
254
+ description: "Compatibility alias for older callers. Prefer attachment_id.",
255
+ },
256
+ prompt: {
257
+ type: "string",
258
+ description: "A targeted question about the image.",
259
+ },
260
+ },
261
+ required: ["prompt"],
262
+ },
263
+ },
264
+ },
265
+ handler: async (args) => {
266
+ const attachmentId = resolveAttachmentId(args);
267
+ if (!attachmentId) {
268
+ return missingAttachmentId("describe_image");
269
+ }
270
+ const prompt = trimArg(args.prompt);
271
+ if (!prompt) {
272
+ return missingPrompt();
273
+ }
274
+ const agentName = (0, identity_1.getAgentName)();
275
+ try {
276
+ const materialized = await (0, materialize_1.materializeAttachment)(agentName, attachmentId, { variant: "vision_safe" });
277
+ const imageDataUrl = await buildImageDataUrl(materialized.path, materialized.mimeType);
278
+ const credential = await (0, provider_credentials_1.readProviderCredentialRecord)(agentName, "minimax");
279
+ const apiKey = credential.ok ? credential.record.credentials.apiKey : undefined;
280
+ if (!apiKey) {
281
+ return (0, tool_results_1.frictionToolResult)("describe_image", {
282
+ kind: "external_blocker",
283
+ recoverability: "blocked",
284
+ summary: "MiniMax credentials are missing, so image understanding is unavailable until credentials are fixed.",
285
+ signature: "describe_image:minimax-missing-key",
286
+ suggested_next_actions: [
287
+ {
288
+ kind: "message",
289
+ message: "Run `ouro auth --agent <agent> --provider minimax`, then retry describe_image.",
290
+ },
291
+ ],
292
+ });
293
+ }
294
+ const description = await (0, minimax_vlm_1.minimaxVlmDescribe)({
295
+ apiKey: String(apiKey),
296
+ prompt,
297
+ imageDataUrl,
298
+ baseURL: minimax_1.MINIMAX_PROVIDER_BASE_URL,
299
+ attachmentGuid: attachmentId,
300
+ mimeType: materialized.mimeType,
301
+ });
302
+ (0, runtime_1.emitNervesEvent)({
303
+ component: "tools",
304
+ event: "tool.describe_image_success",
305
+ message: "describe_image returned a description",
306
+ meta: { attachmentId },
307
+ });
308
+ return description;
309
+ }
310
+ catch (error) {
311
+ const reason = normalizeThrownReason(error);
312
+ return normalizeMaterializeError("describe_image", attachmentId, reason);
313
+ }
314
+ },
315
+ summaryKeys: ["attachment_id", "attachment_guid", "prompt"],
316
+ },
317
+ ];