talon-agent 1.12.0 → 1.34.0

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 (451) hide show
  1. package/README.md +111 -52
  2. package/package.json +39 -12
  3. package/prompts/README.md +112 -0
  4. package/prompts/base.md +12 -12
  5. package/prompts/discord.md +10 -47
  6. package/prompts/heartbeat.md +23 -8
  7. package/prompts/identity.md +12 -22
  8. package/prompts/native.md +23 -0
  9. package/prompts/system/contract-text-or-tools.md +8 -0
  10. package/prompts/system/contract-text-preferred.md +5 -0
  11. package/prompts/system/contract-tool-only.md +10 -0
  12. package/prompts/system/cron.md +3 -0
  13. package/prompts/system/daily-memory.md +3 -0
  14. package/prompts/system/goals.md +7 -0
  15. package/prompts/system/heartbeat-agent.md +44 -0
  16. package/prompts/system/persistent-memory.md +8 -0
  17. package/prompts/system/skills.md +9 -0
  18. package/prompts/system/triggers.md +5 -0
  19. package/prompts/system/workspace.md +9 -0
  20. package/prompts/teams.md +4 -14
  21. package/prompts/telegram.md +17 -89
  22. package/src/app.ts +278 -0
  23. package/src/backend/claude-sdk/constants.ts +22 -10
  24. package/src/backend/claude-sdk/factory.ts +79 -22
  25. package/src/backend/claude-sdk/handler.ts +431 -160
  26. package/src/backend/claude-sdk/index.ts +6 -2
  27. package/src/backend/claude-sdk/mcp-ready.ts +54 -0
  28. package/src/backend/claude-sdk/model-drift.ts +65 -0
  29. package/src/backend/claude-sdk/model-provider.ts +12 -6
  30. package/src/backend/claude-sdk/models/convert.ts +169 -0
  31. package/src/backend/claude-sdk/models/discovery.ts +203 -0
  32. package/src/backend/claude-sdk/models/index.ts +18 -0
  33. package/src/backend/claude-sdk/models/parsing.ts +264 -0
  34. package/src/backend/claude-sdk/models/static.ts +45 -0
  35. package/src/backend/claude-sdk/one-shot.ts +19 -13
  36. package/src/backend/claude-sdk/options.ts +228 -104
  37. package/src/backend/claude-sdk/state.ts +1 -1
  38. package/src/backend/claude-sdk/stream.ts +153 -45
  39. package/src/backend/claude-sdk/warm.ts +12 -5
  40. package/src/backend/codex/auth.ts +216 -40
  41. package/src/backend/codex/constants.ts +63 -22
  42. package/src/backend/codex/discovery.ts +427 -0
  43. package/src/backend/codex/factory.ts +63 -33
  44. package/src/backend/codex/handler/events.ts +239 -0
  45. package/src/backend/codex/handler/index.ts +15 -0
  46. package/src/backend/codex/handler/message.ts +669 -0
  47. package/src/backend/codex/handler/state.ts +14 -0
  48. package/src/backend/codex/handler/usage.ts +68 -0
  49. package/src/backend/codex/index.ts +2 -2
  50. package/src/backend/codex/init.ts +92 -11
  51. package/src/backend/codex/mcp-config.ts +89 -62
  52. package/src/backend/codex/models.ts +305 -54
  53. package/src/backend/codex/oauth-incompat.ts +302 -0
  54. package/src/backend/codex/one-shot.ts +91 -8
  55. package/src/backend/codex/state.ts +54 -3
  56. package/src/backend/codex/token-usage.ts +434 -0
  57. package/src/backend/kilo/factory.ts +60 -35
  58. package/src/backend/kilo/handler/index.ts +13 -0
  59. package/src/backend/kilo/handler/message.ts +317 -0
  60. package/src/backend/kilo/handler/state.ts +14 -0
  61. package/src/backend/kilo/handler/turn.ts +321 -0
  62. package/src/backend/kilo/index.ts +5 -5
  63. package/src/backend/kilo/model-provider.ts +26 -168
  64. package/src/backend/kilo/models/index.ts +52 -0
  65. package/src/backend/kilo/one-shot.ts +20 -142
  66. package/src/backend/kilo/server.ts +14 -21
  67. package/src/backend/openai-agents/builtins.ts +215 -114
  68. package/src/backend/openai-agents/constants.ts +41 -15
  69. package/src/backend/openai-agents/discovery.ts +332 -0
  70. package/src/backend/openai-agents/factory.ts +66 -28
  71. package/src/backend/openai-agents/handler/events.ts +170 -0
  72. package/src/backend/openai-agents/handler/index.ts +13 -0
  73. package/src/backend/openai-agents/handler/message.ts +527 -0
  74. package/src/backend/openai-agents/handler/state.ts +13 -0
  75. package/src/backend/openai-agents/index.ts +22 -4
  76. package/src/backend/openai-agents/init.ts +51 -88
  77. package/src/backend/openai-agents/mcp-pool.ts +252 -0
  78. package/src/backend/openai-agents/models.ts +118 -11
  79. package/src/backend/openai-agents/session.ts +277 -0
  80. package/src/backend/openai-agents/state.ts +82 -11
  81. package/src/backend/opencode/factory.ts +54 -25
  82. package/src/backend/opencode/handler/index.ts +13 -0
  83. package/src/backend/opencode/handler/message.ts +325 -0
  84. package/src/backend/opencode/handler/state.ts +14 -0
  85. package/src/backend/opencode/handler/turn.ts +304 -0
  86. package/src/backend/opencode/index.ts +2 -2
  87. package/src/backend/opencode/model-provider.ts +26 -168
  88. package/src/backend/opencode/models/index.ts +51 -0
  89. package/src/backend/opencode/one-shot.ts +20 -137
  90. package/src/backend/opencode/server.ts +12 -11
  91. package/src/backend/remote-server/client.ts +13 -6
  92. package/src/backend/remote-server/events.ts +59 -9
  93. package/src/backend/remote-server/lifecycle.ts +3 -1
  94. package/src/backend/remote-server/mcp.ts +52 -19
  95. package/src/backend/remote-server/model-catalog/catalog.ts +270 -0
  96. package/src/backend/remote-server/model-catalog/index.ts +100 -0
  97. package/src/backend/remote-server/model-catalog/presentation.ts +298 -0
  98. package/src/backend/remote-server/model-catalog/provider.ts +193 -0
  99. package/src/backend/remote-server/model-catalog/resolve.ts +225 -0
  100. package/src/backend/remote-server/model-catalog/types.ts +136 -0
  101. package/src/backend/remote-server/one-shot.ts +225 -0
  102. package/src/backend/remote-server/session-helpers.ts +3 -4
  103. package/src/backend/remote-server/state.ts +1 -1
  104. package/src/backend/shared/delivery-contract.ts +161 -0
  105. package/src/backend/shared/delivery.ts +49 -0
  106. package/src/backend/shared/flow-violation.ts +38 -7
  107. package/src/backend/shared/frontends.ts +66 -0
  108. package/src/backend/shared/handle-retry.ts +244 -0
  109. package/src/backend/shared/handler-to-events.ts +186 -0
  110. package/src/backend/shared/handler-types.ts +57 -0
  111. package/src/backend/shared/index.ts +51 -5
  112. package/src/backend/shared/metrics.ts +199 -0
  113. package/src/backend/shared/model-retry.ts +1 -1
  114. package/src/backend/shared/prompt-format.ts +69 -0
  115. package/src/backend/shared/session-name.ts +1 -1
  116. package/src/backend/shared/stream-state.ts +36 -2
  117. package/src/backend/shared/system-prompt.ts +200 -23
  118. package/src/bootstrap.ts +338 -38
  119. package/src/cli/chat.ts +49 -0
  120. package/src/cli/config-view.ts +100 -0
  121. package/src/cli/config.ts +105 -0
  122. package/src/cli/context.ts +23 -0
  123. package/src/cli/daemon.ts +95 -0
  124. package/src/cli/doctor.ts +53 -0
  125. package/src/cli/index.ts +139 -0
  126. package/src/cli/logs.ts +60 -0
  127. package/src/cli/menu.ts +104 -0
  128. package/src/cli/setup.ts +455 -0
  129. package/src/cli/status.ts +75 -0
  130. package/src/cli.ts +20 -1211
  131. package/src/core/agent-runtime/README.md +173 -0
  132. package/src/{backend/registry.ts → core/agent-runtime/backend-registry.ts} +15 -6
  133. package/src/core/agent-runtime/capabilities.ts +330 -0
  134. package/src/core/agent-runtime/contract-tests.ts +378 -0
  135. package/src/core/agent-runtime/events.ts +291 -0
  136. package/src/core/agent-runtime/index.ts +62 -0
  137. package/src/core/agent-runtime/model-ref.ts +130 -0
  138. package/src/core/background/cron.ts +469 -0
  139. package/src/core/{dream.ts → background/dream.ts} +118 -53
  140. package/src/core/background/heartbeat/agent.ts +333 -0
  141. package/src/core/background/heartbeat/index.ts +25 -0
  142. package/src/core/background/heartbeat/scheduler.ts +211 -0
  143. package/src/core/background/heartbeat/state.ts +153 -0
  144. package/src/core/background/index.ts +21 -0
  145. package/src/core/background/isolated-agent.ts +115 -0
  146. package/src/core/background/job-health.ts +140 -0
  147. package/src/core/background/job-oneshot.ts +165 -0
  148. package/src/core/background/job-prompt.ts +54 -0
  149. package/src/core/{pulse.ts → background/pulse.ts} +6 -5
  150. package/src/core/background/triggers/command.ts +60 -0
  151. package/src/core/background/triggers/exit.ts +202 -0
  152. package/src/core/background/triggers/index.ts +38 -0
  153. package/src/core/background/triggers/output.ts +142 -0
  154. package/src/core/background/triggers/resume.ts +127 -0
  155. package/src/core/background/triggers/spawn.ts +282 -0
  156. package/src/core/background/triggers/state.ts +52 -0
  157. package/src/core/constants.ts +57 -28
  158. package/src/core/daemon/control.ts +229 -0
  159. package/src/core/daemon/discovery.ts +169 -0
  160. package/src/core/daemon/pidfile.ts +98 -0
  161. package/src/core/doctor.ts +459 -0
  162. package/src/core/engine/backend-controller/holders.ts +17 -0
  163. package/src/core/engine/backend-controller/index.ts +71 -0
  164. package/src/core/engine/backend-controller/legacy.ts +111 -0
  165. package/src/core/engine/backend-controller/pool.ts +296 -0
  166. package/src/core/engine/backend-controller/rebind.ts +205 -0
  167. package/src/core/engine/backend-controller/state.ts +150 -0
  168. package/src/core/engine/backend-controller/types.ts +51 -0
  169. package/src/core/engine/dispatcher.ts +68 -0
  170. package/src/core/engine/gateway-actions/cron.ts +518 -0
  171. package/src/core/engine/gateway-actions/fetch-url.ts +120 -0
  172. package/src/core/engine/gateway-actions/goals.ts +178 -0
  173. package/src/core/engine/gateway-actions/history.ts +53 -0
  174. package/src/core/engine/gateway-actions/index.ts +60 -0
  175. package/src/core/engine/gateway-actions/models.ts +120 -0
  176. package/src/core/engine/gateway-actions/plugins.ts +83 -0
  177. package/src/core/engine/gateway-actions/scripts.ts +127 -0
  178. package/src/core/engine/gateway-actions/shared.ts +66 -0
  179. package/src/core/engine/gateway-actions/skills.ts +120 -0
  180. package/src/core/engine/gateway-actions/triggers.ts +237 -0
  181. package/src/core/engine/gateway-actions/types.ts +18 -0
  182. package/src/core/{gateway.ts → engine/gateway.ts} +223 -60
  183. package/src/core/engine/index.ts +20 -0
  184. package/src/core/engine/model-audit.ts +121 -0
  185. package/src/core/errors.ts +68 -6
  186. package/src/core/mcp-hub/children.ts +254 -0
  187. package/src/core/mcp-hub/index.ts +335 -0
  188. package/src/core/mcp-hub/proxy-server.ts +45 -0
  189. package/src/core/mcp-hub/talon-server.ts +71 -0
  190. package/src/core/memory/retrieval.ts +90 -0
  191. package/src/core/models/active-model.ts +441 -0
  192. package/src/core/{models.ts → models/catalog.ts} +6 -0
  193. package/src/core/models/index.ts +17 -0
  194. package/src/core/models/reasoning-levels.ts +57 -0
  195. package/src/core/plugin/actions.ts +32 -0
  196. package/src/core/plugin/builtins.ts +162 -0
  197. package/src/core/plugin/index.ts +37 -0
  198. package/src/core/plugin/loader.ts +289 -0
  199. package/src/core/plugin/mcp.ts +86 -0
  200. package/src/core/plugin/registry.ts +124 -0
  201. package/src/core/plugin/types.ts +126 -0
  202. package/src/core/prompt/assemble.ts +273 -0
  203. package/src/core/prompt/disk-prompts.ts +41 -0
  204. package/src/core/prompt/embed.ts +107 -0
  205. package/src/core/prompt/embedded-prompts.ts +85 -0
  206. package/src/core/prompt/index.ts +30 -0
  207. package/src/core/prompt/templates.ts +124 -0
  208. package/src/core/prompt/workspace-listing.ts +91 -0
  209. package/src/core/scripting/lua-runner.ts +210 -0
  210. package/src/core/scripts/runner.ts +125 -0
  211. package/src/core/soul/README.md +110 -0
  212. package/src/core/soul/RESEARCH.md +98 -0
  213. package/src/core/soul/associative.ts +98 -0
  214. package/src/core/soul/centrality.ts +98 -0
  215. package/src/core/soul/cluster.ts +83 -0
  216. package/src/core/soul/compiler.ts +207 -0
  217. package/src/core/soul/consolidate.ts +179 -0
  218. package/src/core/soul/critic.ts +159 -0
  219. package/src/core/soul/dag.ts +265 -0
  220. package/src/core/soul/delta.ts +123 -0
  221. package/src/core/soul/drift.ts +99 -0
  222. package/src/core/soul/embedder.ts +129 -0
  223. package/src/core/soul/emergent-critic.ts +96 -0
  224. package/src/core/soul/forgetting.ts +131 -0
  225. package/src/core/soul/governance.ts +93 -0
  226. package/src/core/soul/hash.ts +97 -0
  227. package/src/core/soul/hdc.ts +154 -0
  228. package/src/core/soul/index.ts +140 -0
  229. package/src/core/soul/kernel.ts +540 -0
  230. package/src/core/soul/lattice.ts +103 -0
  231. package/src/core/soul/lens.ts +110 -0
  232. package/src/core/soul/projector.ts +240 -0
  233. package/src/core/soul/reflect.ts +170 -0
  234. package/src/core/soul/reflex.ts +164 -0
  235. package/src/core/soul/retrieve.ts +146 -0
  236. package/src/core/soul/salience.ts +142 -0
  237. package/src/core/soul/service.ts +204 -0
  238. package/src/core/soul/settings.ts +47 -0
  239. package/src/core/soul/signals.ts +117 -0
  240. package/src/core/soul/talon-embedder.ts +80 -0
  241. package/src/core/soul/taps.ts +199 -0
  242. package/src/core/soul/types.ts +298 -0
  243. package/src/core/soul/valence.ts +83 -0
  244. package/src/core/tools/goals.ts +117 -0
  245. package/src/core/tools/index.ts +10 -0
  246. package/src/core/tools/mcp-env.ts +94 -0
  247. package/src/core/tools/mcp-server.ts +27 -4
  248. package/src/core/tools/messaging.ts +122 -29
  249. package/src/core/tools/models.ts +39 -0
  250. package/src/core/tools/scheduling.ts +133 -14
  251. package/src/core/tools/schemas.ts +16 -4
  252. package/src/core/tools/scripts.ts +78 -0
  253. package/src/core/tools/skills.ts +90 -0
  254. package/src/core/tools/stickers.ts +1 -1
  255. package/src/core/tools/triggers.ts +19 -3
  256. package/src/core/tools/types.ts +6 -6
  257. package/src/core/types.ts +62 -112
  258. package/src/core/update/self-update.ts +269 -0
  259. package/src/core/weaver/index.ts +10 -0
  260. package/src/core/weaver/loom.ts +125 -0
  261. package/src/core/weaver/thread-session.ts +51 -0
  262. package/src/core/weaver/thread.ts +196 -0
  263. package/src/core/weaver/weaver.ts +357 -0
  264. package/src/frontend/discord/actions/chat-info.ts +268 -0
  265. package/src/frontend/discord/actions/index.ts +77 -0
  266. package/src/frontend/discord/actions/media.ts +190 -0
  267. package/src/frontend/discord/actions/messaging.ts +277 -0
  268. package/src/frontend/discord/actions/shared.ts +100 -0
  269. package/src/frontend/discord/actions/types.ts +33 -0
  270. package/src/frontend/discord/admin.ts +13 -23
  271. package/src/frontend/discord/callbacks/autocomplete.ts +55 -0
  272. package/src/frontend/discord/{callbacks.ts → callbacks/components.ts} +150 -190
  273. package/src/frontend/discord/callbacks/index.ts +14 -0
  274. package/src/frontend/discord/callbacks/modals.ts +76 -0
  275. package/src/frontend/discord/callbacks/shared.ts +22 -0
  276. package/src/frontend/discord/commands/admin.ts +88 -0
  277. package/src/frontend/discord/commands/definitions.ts +200 -0
  278. package/src/frontend/discord/commands/index.ts +19 -0
  279. package/src/frontend/discord/commands/info.ts +106 -0
  280. package/src/frontend/discord/commands/router.ts +149 -0
  281. package/src/frontend/discord/commands/session.ts +89 -0
  282. package/src/frontend/discord/commands/settings.ts +405 -0
  283. package/src/frontend/discord/commands/shared.ts +50 -0
  284. package/src/frontend/discord/formatting.ts +8 -34
  285. package/src/frontend/discord/handlers/access.ts +248 -0
  286. package/src/frontend/discord/handlers/context.ts +161 -0
  287. package/src/frontend/discord/handlers/delivery.ts +94 -0
  288. package/src/frontend/discord/handlers/index.ts +34 -0
  289. package/src/frontend/discord/handlers/messages.ts +120 -0
  290. package/src/frontend/discord/handlers/queue.ts +135 -0
  291. package/src/frontend/discord/handlers/registry.ts +29 -0
  292. package/src/frontend/discord/handlers/state.ts +94 -0
  293. package/src/frontend/discord/helpers.ts +46 -57
  294. package/src/frontend/discord/index.ts +10 -7
  295. package/src/frontend/discord/middleware.ts +2 -2
  296. package/src/frontend/native/actions.ts +133 -0
  297. package/src/frontend/native/chats.ts +146 -0
  298. package/src/frontend/native/discovery.ts +50 -0
  299. package/src/frontend/native/index.ts +1227 -0
  300. package/src/frontend/native/logs.ts +95 -0
  301. package/src/frontend/native/protocol.ts +253 -0
  302. package/src/frontend/native/server.ts +612 -0
  303. package/src/frontend/native/settings.ts +205 -0
  304. package/src/frontend/native/turn-meta.ts +43 -0
  305. package/src/frontend/shared/format.ts +51 -0
  306. package/src/frontend/shared/reasoning-levels.ts +46 -0
  307. package/src/frontend/shared/session-status.ts +189 -0
  308. package/src/frontend/shared/status-context.ts +125 -0
  309. package/src/frontend/teams/actions.ts +7 -5
  310. package/src/frontend/teams/formatting.ts +7 -18
  311. package/src/frontend/teams/graph.ts +2 -1
  312. package/src/frontend/teams/index.ts +76 -54
  313. package/src/frontend/telegram/actions/chat-info.ts +323 -0
  314. package/src/frontend/telegram/actions/index.ts +68 -0
  315. package/src/frontend/telegram/actions/media.ts +224 -0
  316. package/src/frontend/telegram/actions/messaging.ts +295 -0
  317. package/src/frontend/telegram/actions/shared.ts +58 -0
  318. package/src/frontend/telegram/actions/types.ts +31 -0
  319. package/src/frontend/telegram/admin.ts +12 -22
  320. package/src/frontend/telegram/callbacks/effort.ts +68 -0
  321. package/src/frontend/telegram/callbacks/index.ts +68 -0
  322. package/src/frontend/telegram/callbacks/model.ts +311 -0
  323. package/src/frontend/telegram/callbacks/pulse.ts +50 -0
  324. package/src/frontend/telegram/callbacks/settings.ts +177 -0
  325. package/src/frontend/telegram/callbacks/shared.ts +71 -0
  326. package/src/frontend/telegram/commands/admin.ts +226 -0
  327. package/src/frontend/telegram/commands/definitions.ts +60 -0
  328. package/src/frontend/telegram/commands/index.ts +39 -0
  329. package/src/frontend/telegram/commands/info.ts +125 -0
  330. package/src/frontend/telegram/commands/session.ts +77 -0
  331. package/src/frontend/telegram/commands/settings.ts +345 -0
  332. package/src/frontend/telegram/commands/state.ts +34 -0
  333. package/src/frontend/telegram/formatting.ts +14 -25
  334. package/src/frontend/telegram/handlers/access.ts +287 -0
  335. package/src/frontend/telegram/handlers/context.ts +210 -0
  336. package/src/frontend/telegram/handlers/delivery.ts +236 -0
  337. package/src/frontend/telegram/handlers/index.ts +39 -0
  338. package/src/frontend/telegram/handlers/messages.ts +477 -0
  339. package/src/frontend/telegram/handlers/queue.ts +241 -0
  340. package/src/frontend/telegram/handlers/state.ts +75 -0
  341. package/src/frontend/telegram/helpers/diagnostics.ts +188 -0
  342. package/src/frontend/telegram/helpers/format.ts +41 -0
  343. package/src/frontend/telegram/helpers/index.ts +13 -0
  344. package/src/frontend/telegram/{helpers.ts → helpers/menu.ts} +209 -210
  345. package/src/frontend/telegram/index.ts +24 -27
  346. package/src/frontend/telegram/middleware.ts +16 -3
  347. package/src/frontend/telegram/model-callbacks.ts +14 -0
  348. package/src/frontend/telegram/model-menu.ts +317 -0
  349. package/src/frontend/telegram/sticker-library.ts +178 -0
  350. package/src/frontend/telegram/userbot.ts +2 -44
  351. package/src/frontend/terminal/commands.ts +47 -41
  352. package/src/frontend/terminal/index.ts +46 -31
  353. package/src/frontend/terminal/input.ts +5 -0
  354. package/src/frontend/terminal/renderer.ts +4 -2
  355. package/src/index.ts +13 -171
  356. package/src/login.ts +3 -2
  357. package/src/native/blake3-wasm-bytes.ts +7 -0
  358. package/src/native/blake3.ts +234 -0
  359. package/src/native/htmlents-wasm-bytes.ts +7 -0
  360. package/src/native/htmlents.ts +56 -0
  361. package/src/native/prelude.d.mts +168 -0
  362. package/src/native/prelude.mjs +1561 -0
  363. package/src/native/registry.ts +142 -0
  364. package/src/native/runtime.ts +164 -0
  365. package/src/native/scheduler-core/gleam.d.mts +2 -0
  366. package/src/native/scheduler-core/gleam.mjs +1 -0
  367. package/src/native/scheduler-core/scheduler_core.d.mts +76 -0
  368. package/src/native/scheduler-core/scheduler_core.mjs +252 -0
  369. package/src/native/scheduler-core.ts +124 -0
  370. package/src/native/sqlguard-wasm-bytes.ts +7 -0
  371. package/src/native/sqlguard.ts +107 -0
  372. package/src/native/strsim-wasm-bytes.ts +7 -0
  373. package/src/native/strsim.ts +98 -0
  374. package/src/native/textops-wasm-bytes.ts +7 -0
  375. package/src/native/textops.ts +83 -0
  376. package/src/native/warden.ts +287 -0
  377. package/src/plugins/github/index.ts +1 -1
  378. package/src/plugins/mempalace/index.ts +1 -1
  379. package/src/plugins/playwright/index.ts +1 -1
  380. package/src/storage/chat-settings.ts +335 -85
  381. package/src/storage/cron-store.ts +266 -109
  382. package/src/storage/daily-log.ts +15 -3
  383. package/src/storage/db.ts +206 -0
  384. package/src/storage/goal-store.ts +186 -0
  385. package/src/storage/history.ts +137 -188
  386. package/src/storage/kv.ts +52 -0
  387. package/src/storage/legacy-import.ts +47 -0
  388. package/src/storage/media-index.ts +118 -61
  389. package/src/storage/repositories/chat-settings-repo.ts +60 -0
  390. package/src/storage/repositories/cron-repo.ts +128 -0
  391. package/src/storage/repositories/goals-repo.ts +122 -0
  392. package/src/storage/repositories/history-repo.ts +207 -0
  393. package/src/storage/repositories/kv-repo.ts +25 -0
  394. package/src/storage/repositories/media-index-repo.ts +147 -0
  395. package/src/storage/repositories/scripts-repo.ts +81 -0
  396. package/src/storage/repositories/sessions-repo.ts +129 -0
  397. package/src/storage/repositories/triggers-repo.ts +158 -0
  398. package/src/storage/repositories/turn-meta-repo.ts +32 -0
  399. package/src/storage/scheduled-store.ts +84 -0
  400. package/src/storage/script-store.ts +198 -0
  401. package/src/storage/sessions.ts +227 -102
  402. package/src/storage/skill-store.ts +325 -0
  403. package/src/storage/sql/README.md +18 -0
  404. package/src/storage/sql/chat-settings.sql +11 -0
  405. package/src/storage/sql/cron.sql +40 -0
  406. package/src/storage/sql/db.sql +11 -0
  407. package/src/storage/sql/embed.ts +118 -0
  408. package/src/storage/sql/goals.sql +41 -0
  409. package/src/storage/sql/history.sql +83 -0
  410. package/src/storage/sql/kv.sql +11 -0
  411. package/src/storage/sql/media-index.sql +45 -0
  412. package/src/storage/sql/schema.sql +233 -0
  413. package/src/storage/sql/scripts.sql +28 -0
  414. package/src/storage/sql/sessions.sql +22 -0
  415. package/src/storage/sql/statements.generated.ts +500 -0
  416. package/src/storage/sql/triggers.sql +69 -0
  417. package/src/storage/sql/turn-meta.sql +24 -0
  418. package/src/storage/sticker-store.ts +141 -0
  419. package/src/storage/trigger-store.ts +104 -126
  420. package/src/storage/turn-meta.ts +118 -0
  421. package/src/util/chat-id.ts +30 -0
  422. package/src/util/config.ts +313 -195
  423. package/src/util/fs-path.ts +32 -0
  424. package/src/util/log.ts +53 -31
  425. package/src/util/mcp-launcher.ts +351 -33
  426. package/src/util/paths.ts +45 -17
  427. package/src/util/tail-file.ts +24 -0
  428. package/src/util/workspace.ts +161 -10
  429. package/tsconfig.json +1 -0
  430. package/src/backend/claude-sdk/models.ts +0 -501
  431. package/src/backend/codex/handler.ts +0 -595
  432. package/src/backend/kilo/handler.ts +0 -707
  433. package/src/backend/kilo/models.ts +0 -762
  434. package/src/backend/openai-agents/handler.ts +0 -539
  435. package/src/backend/openai-agents/mcp.ts +0 -139
  436. package/src/backend/opencode/handler.ts +0 -663
  437. package/src/backend/opencode/models.ts +0 -741
  438. package/src/core/cron.ts +0 -184
  439. package/src/core/dispatcher.ts +0 -144
  440. package/src/core/gateway-actions.ts +0 -603
  441. package/src/core/heartbeat.ts +0 -575
  442. package/src/core/plugin.ts +0 -776
  443. package/src/core/triggers.ts +0 -640
  444. package/src/frontend/discord/actions.ts +0 -729
  445. package/src/frontend/discord/commands.ts +0 -1036
  446. package/src/frontend/discord/handlers.ts +0 -798
  447. package/src/frontend/telegram/actions.ts +0 -731
  448. package/src/frontend/telegram/callbacks.ts +0 -419
  449. package/src/frontend/telegram/commands.ts +0 -642
  450. package/src/frontend/telegram/handlers.ts +0 -1352
  451. package/src/util/mcp-launcher.mjs +0 -140
@@ -5,25 +5,30 @@
5
5
  * MCP servers, system prompt) into the Options shape expected by the SDK.
6
6
  */
7
7
 
8
- import { resolve } from "node:path";
9
- import { pathToFileURL } from "node:url";
8
+ import { SYSTEM_PROMPT_DYNAMIC_BOUNDARY } from "@anthropic-ai/claude-agent-sdk";
10
9
  import type {
11
10
  Options,
12
11
  PostToolBatchHookInput,
12
+ PostToolUseFailureHookInput,
13
13
  NotificationHookInput,
14
14
  StopFailureHookInput,
15
15
  HookCallback,
16
16
  HookJSONOutput,
17
17
  } from "@anthropic-ai/claude-agent-sdk";
18
+ import type { PreparedSystemPrompt } from "../shared/system-prompt.js";
18
19
  import { getSession } from "../../storage/sessions.js";
19
20
  import { getChatSettings } from "../../storage/chat-settings.js";
20
- import { getPluginMcpServers } from "../../core/plugin.js";
21
- import { resolveModelId } from "../../core/models.js";
22
- import { wrapMcpServer } from "../../util/mcp-launcher.js";
21
+ import { resolveModelId } from "../../core/models/catalog.js";
23
22
  import { isTurnTerminator } from "../../core/tools/index.js";
23
+ import {
24
+ talonHubUrl,
25
+ pluginHubUrl,
26
+ hubPluginServerNames,
27
+ } from "../../core/mcp-hub/index.js";
28
+ import { nonTerminalFrontends, frontendsForChat } from "../shared/frontends.js";
24
29
  import { log, logError } from "../../util/log.js";
25
30
  import { getConfig, getBridgePort } from "./state.js";
26
- import { DISALLOWED_TOOLS_CHAT, EFFORT_MAP } from "./constants.js";
31
+ import { ALLOWED_TOOLS_CHAT, EFFORT_MAP } from "./constants.js";
27
32
 
28
33
  // ── Types ────────────────────────────────────────────────────────────────────
29
34
 
@@ -48,123 +53,189 @@ export type BuildSdkOptionsResult = {
48
53
  * should wrap in try/catch and treat as "no frontends available").
49
54
  */
50
55
  export function getActiveFrontends(): readonly string[] {
51
- const config = getConfig();
52
- const allFrontends = Array.isArray(config.frontend)
53
- ? config.frontend
54
- : [config.frontend];
55
- return allFrontends.filter((f) => f !== "terminal");
56
+ return nonTerminalFrontends(getConfig().frontend);
56
57
  }
57
58
 
59
+ /** Hub-backed MCP server entry — the SDK's `type: "http"` config. */
60
+ export type HubMcpEntry = {
61
+ type: "http";
62
+ url: string;
63
+ alwaysLoad?: boolean;
64
+ };
65
+
58
66
  /**
59
67
  * Build the MCP servers map for a chat query.
60
68
  * Includes frontend-specific tool servers and Brave Search, if configured.
69
+ *
70
+ * Every entry points at the daemon's MCP hub (`core/mcp-hub`) over
71
+ * streamable HTTP: the Talon tool servers run in-process there (zero
72
+ * subprocesses per chat — chat binding travels in the URL, not env),
73
+ * and brave-search is a single hub-managed child shared by all chats.
61
74
  */
62
- export function buildMcpServers(
63
- chatId: string,
64
- ): Record<
65
- string,
66
- { command: string; args: string[]; env: Record<string, string> }
67
- > {
75
+ export function buildMcpServers(chatId: string): Record<string, HubMcpEntry> {
68
76
  const config = getConfig();
69
77
  const bridgeUrl = `http://127.0.0.1:${getBridgePort()}`;
70
78
 
71
- // tsx as a Node loader is passed via `--import <url>`. Node accepts URLs
72
- // or absolute paths, but on Windows a raw backslash path (`D:\…\tsx`) is
73
- // ambiguous between path and URL — the loader hook fails to register and
74
- // every subsequent `import` of a .ts file throws. `pathToFileURL` produces
75
- // a cross-platform `file://` URL that Node always treats as a loader URL.
76
- const tsxImport = pathToFileURL(
77
- resolve(
78
- import.meta.dirname ?? ".",
79
- "../../../node_modules/tsx/dist/esm/index.mjs",
80
- ),
81
- ).href;
82
- const mcpServerPath = resolve(
83
- import.meta.dirname ?? ".",
84
- "../../core/tools/mcp-server.ts",
85
- );
86
-
87
- // Frontend-specific MCP tool servers (one per non-terminal frontend)
88
- const frontends = getActiveFrontends();
79
+ const servers: Record<string, HubMcpEntry> = {};
89
80
 
90
- const servers: Record<
91
- string,
92
- { command: string; args: string[]; env: Record<string, string> }
93
- > = {};
94
-
95
- for (const frontend of frontends) {
96
- const serverName = `${frontend}-tools`;
97
- const mcpEnv = {
98
- TALON_BRIDGE_URL: bridgeUrl,
99
- TALON_CHAT_ID: chatId,
100
- TALON_FRONTEND: frontend,
81
+ // Scope to the chat's owning frontend: a native-app chat gets
82
+ // native-tools only, not every configured frontend's server (stray
83
+ // mcp__telegram-tools__* in a native chat is confusing UI and a
84
+ // wrong-surface delivery hazard). Cross-surface contexts (heartbeat,
85
+ // one-shots) keep the full set.
86
+ for (const frontend of frontendsForChat(chatId, getActiveFrontends())) {
87
+ servers[`${frontend}-tools`] = {
88
+ type: "http",
89
+ url: talonHubUrl(bridgeUrl, frontend, chatId),
90
+ // Always include the frontend's tools in the turn-1 prompt instead of
91
+ // deferring them behind the SDK's tool search. These are the bot's
92
+ // primary surface — it needs `end_turn`/`send`/`react` on EVERY turn to
93
+ // reply at all. When deferred, the SDK evicts their schemas between
94
+ // turns, so a bare `end_turn` fails with "no such tool" and the user's
95
+ // reply silently doesn't send (the model has to burn a round-trip
96
+ // re-fetching the schema via tool_search first). `alwaysLoad` also
97
+ // blocks startup until this server is connected (capped at the 5s MCP
98
+ // connect timeout) so the tools are present when the first prompt is
99
+ // built — fixing the post-restart race where turn-1 ran before the
100
+ // server finished connecting. Per-tool `_meta['anthropic/alwaysLoad']`
101
+ // does NOT add that blocking, which is why server-level is the correct
102
+ // lever here. Cost: ~50 frontend tool schemas loaded every turn (~10k
103
+ // tokens, cached, negligible on the 1M-context models Talon runs).
104
+ alwaysLoad: true,
101
105
  };
102
- // `node --import <tsx-loader>` everywhere — tsx as a Node loader works
103
- // identically on Windows and POSIX, and avoids spawning `npx.cmd` (which
104
- // Node 20.19+ refuses to execute via child_process.spawn without
105
- // shell:true; CVE-2024-27980 mitigation). The wrapping launcher would
106
- // hit the same .cmd ban when calling its child.
107
- servers[serverName] = wrapMcpServer({
108
- command: "node",
109
- args: ["--import", tsxImport, mcpServerPath],
110
- env: mcpEnv,
111
- });
112
106
  }
113
107
 
114
108
  // Brave Search MCP server (if configured)
115
109
  if (config.braveApiKey) {
116
- servers["brave-search"] = wrapMcpServer({
117
- command: resolve(
118
- import.meta.dirname ?? ".",
119
- "../../../node_modules/.bin/brave-search-mcp-server",
120
- ),
121
- args: [],
122
- env: { BRAVE_API_KEY: config.braveApiKey },
123
- });
110
+ servers["brave-search"] = {
111
+ type: "http",
112
+ url: pluginHubUrl(bridgeUrl, "brave-search", chatId),
113
+ };
124
114
  }
125
115
 
126
116
  return servers;
127
117
  }
128
118
 
119
+ /**
120
+ * Build the plugin MCP server map for a chat query — hub URLs for every
121
+ * registry-provided plugin server, optionally filtered to `only` plugin
122
+ * names (heartbeat/dream tiers restrict their tool surface this way).
123
+ */
124
+ export function buildPluginMcpServers(
125
+ chatId: string,
126
+ only?: string[],
127
+ ): Record<string, HubMcpEntry> {
128
+ const bridgeUrl = `http://127.0.0.1:${getBridgePort()}`;
129
+ const servers: Record<string, HubMcpEntry> = {};
130
+ for (const name of hubPluginServerNames(only)) {
131
+ servers[name] = {
132
+ type: "http",
133
+ url: pluginHubUrl(bridgeUrl, name, chatId),
134
+ };
135
+ }
136
+ return servers;
137
+ }
138
+
129
139
  // ── Hooks ───────────────────────────────────────────────────────────────────
130
140
 
131
141
  /**
132
- * PostToolBatch hook: terminate the SDK query loop the moment a turn-terminator
133
- * tool (e.g. `end_turn`) resolves in the assistant's tool batch.
142
+ * Build the turn-terminator hook pair (PostToolUseFailure + PostToolBatch).
143
+ *
144
+ * These two hooks coordinate through a per-session `Set<tool_use_id>` of
145
+ * terminator tools whose `execute()` threw. The set is shared by closure —
146
+ * one Set per `buildSdkOptions` call, so concurrent chat sessions never
147
+ * leak failure flags into each other.
134
148
  *
135
- * Why PostToolBatch and not PostToolUse:
136
- * - PostToolUse fires per-tool and may run concurrently for parallel tool
137
- * calls. Returning `continue: false` from there can race with sibling MCP
138
- * tools whose AbortControllers haven't yet completed — the same race that
139
- * killed the previous `qi.interrupt()` approach (see handler.ts comment
140
- * and commit `d5ce30f`).
141
- * - PostToolBatch fires exactly ONCE after every tool in the batch has
142
- * resolved. By definition there are no in-flight siblings to race with.
149
+ * Design choices:
143
150
  *
144
- * What this saves:
145
- * - The ~2-3s "phantom typing" round-trip the SDK makes after `end_turn`
146
- * returns (the model has nothing to say, generates a stop_turn anyway).
147
- * - Trailing prose that gets generated during that round-trip and was
148
- * previously suppressed only at the delivery layer (real tokens spent).
151
+ * - **Why PostToolBatch for the terminate decision** (vs PostToolUse): batch
152
+ * fires exactly once after every tool in the batch has resolved, so there
153
+ * are no in-flight siblings to race with. PostToolUse fires per-tool and
154
+ * can race with sibling MCP tools whose AbortControllers haven't completed
155
+ * the same race that killed the earlier `qi.interrupt()` approach (commit
156
+ * `d5ce30f`).
149
157
  *
150
- * Returns `{ continue: false, stopReason: ... }` SDK exits with TerminalReason
151
- * `'hook_stopped'`, no further model generation.
158
+ * - **Why also PostToolUseFailure**: when a terminator tool's `execute()`
159
+ * throws (e.g. `end_turn` throws because the bridge returned `{ok:false}`),
160
+ * the SDK fires PostToolUseFailure with `{tool_name, error, is_interrupt}`.
161
+ * That's a typed, content-free signal that the call failed — vastly more
162
+ * robust than sniffing `tool_response` bodies for `"ok":false` substrings.
163
+ * The hook records the failed `tool_use_id`; PostToolBatch consults the
164
+ * set when deciding whether to terminate.
165
+ *
166
+ * - **Why `is_interrupt: true` is ignored**: an interrupted tool isn't a
167
+ * delivery failure — it's the user (or the harness) cancelling the call
168
+ * mid-flight. Treating that as "preserve the loop" would leak interrupted
169
+ * sessions into zombie state.
170
+ *
171
+ * What this preserves:
172
+ *
173
+ * - Happy path: terminator succeeds → loop terminates → no phantom-typing
174
+ * round-trip (the ~2-3s perf win from PR #122).
175
+ * - Failure path: terminator's execute() threw → loop stays alive → model
176
+ * sees the error in the next assistant turn and can retry / message the
177
+ * user. The bug fixed: prior to this hook pair, a failed terminator
178
+ * terminated the loop silently and the user saw nothing (canonical
179
+ * incident: 2026-05-13 13:11Z 4096-char overflow).
152
180
  */
153
- const turnTerminatorHook: HookCallback = async (
154
- input,
155
- ): Promise<HookJSONOutput> => {
156
- if (input.hook_event_name !== "PostToolBatch") {
181
+ function buildTurnTerminatorHooks(): {
182
+ postToolUseFailureHook: HookCallback;
183
+ postToolBatchHook: HookCallback;
184
+ } {
185
+ const failedTerminatorIds = new Set<string>();
186
+
187
+ const postToolUseFailureHook: HookCallback = async (
188
+ input,
189
+ ): Promise<HookJSONOutput> => {
190
+ if (input.hook_event_name !== "PostToolUseFailure") {
191
+ return { continue: true };
192
+ }
193
+ const failure = input as PostToolUseFailureHookInput;
194
+ // Interrupts are not delivery failures — don't treat them as recoverable.
195
+ if (failure.is_interrupt) return { continue: true };
196
+
197
+ // Pass tool_input so soft-terminator react (`end_turn: false`) doesn't
198
+ // get tracked here. If the call wasn't acting as a terminator, the
199
+ // PostToolBatch path would have continued the loop anyway.
200
+ if (!isTurnTerminator(failure.tool_name, failure.tool_input)) {
201
+ return { continue: true };
202
+ }
203
+
204
+ failedTerminatorIds.add(failure.tool_use_id);
205
+ log(
206
+ "agent",
207
+ `PostToolUseFailure: ${failure.tool_name} (${failure.tool_use_id}) ` +
208
+ `failed — flagging for loop preservation. error: ${failure.error}`,
209
+ );
157
210
  return { continue: true };
158
- }
159
- const batch = input as PostToolBatchHookInput;
160
- // Pass `tool_input` so the soft-terminator opt-out (e.g. react with
161
- // `end_turn: false`) can keep the loop alive. Without the input, the
162
- // check is name-only and reacts that meant to keep going would still
163
- // terminate.
164
- const terminator = batch.tool_calls.find((tc) =>
165
- isTurnTerminator(tc.tool_name, tc.tool_input),
166
- );
167
- if (terminator) {
211
+ };
212
+
213
+ const postToolBatchHook: HookCallback = async (
214
+ input,
215
+ ): Promise<HookJSONOutput> => {
216
+ if (input.hook_event_name !== "PostToolBatch") {
217
+ return { continue: true };
218
+ }
219
+ const batch = input as PostToolBatchHookInput;
220
+ const terminator = batch.tool_calls.find((tc) =>
221
+ isTurnTerminator(tc.tool_name, tc.tool_input),
222
+ );
223
+ if (!terminator) {
224
+ return { continue: true };
225
+ }
226
+
227
+ // If the terminator failed, the failure hook flagged its tool_use_id.
228
+ // Preserve the loop so the model can react to the error.
229
+ if (failedTerminatorIds.has(terminator.tool_use_id)) {
230
+ failedTerminatorIds.delete(terminator.tool_use_id);
231
+ log(
232
+ "agent",
233
+ `PostToolBatch: ${terminator.tool_name} failed — keeping SDK loop ` +
234
+ `alive so the model can read the error and retry`,
235
+ );
236
+ return { continue: true };
237
+ }
238
+
168
239
  log(
169
240
  "agent",
170
241
  `PostToolBatch: terminating SDK loop on ${terminator.tool_name} ` +
@@ -174,9 +245,10 @@ const turnTerminatorHook: HookCallback = async (
174
245
  continue: false,
175
246
  stopReason: "turn terminated by end_turn / send",
176
247
  };
177
- }
178
- return { continue: true };
179
- };
248
+ };
249
+
250
+ return { postToolUseFailureHook, postToolBatchHook };
251
+ }
180
252
 
181
253
  /**
182
254
  * Notification hook: log SDK-generated notifications (e.g. context compaction,
@@ -234,10 +306,33 @@ const stopFailureHook: HookCallback = async (
234
306
 
235
307
  // ── Options builder ─────────────────────────────────────────────────────────
236
308
 
237
- export function buildSdkOptions(chatId: string): BuildSdkOptionsResult {
309
+ /**
310
+ * Build the SDK `systemPrompt` option from a prepared prompt.
311
+ *
312
+ * When a dynamic part exists, the prompt is sent as blocks split by
313
+ * `SYSTEM_PROMPT_DYNAMIC_BOUNDARY`: everything before the marker is the
314
+ * static prefix the API can cache across sessions; everything after is
315
+ * the volatile tail (workspace listing, daily-memory pointer) that
316
+ * changes between rebuilds without invalidating the prefix.
317
+ */
318
+ function toSdkSystemPrompt(prepared: PreparedSystemPrompt): string | string[] {
319
+ if (!prepared.dynamicText) return prepared.staticText;
320
+ return [
321
+ prepared.staticText,
322
+ SYSTEM_PROMPT_DYNAMIC_BOUNDARY,
323
+ prepared.dynamicText,
324
+ ];
325
+ }
326
+
327
+ export function buildSdkOptions(
328
+ chatId: string,
329
+ abortController?: AbortController,
330
+ modelOverride?: string,
331
+ preparedPrompt?: PreparedSystemPrompt,
332
+ ): BuildSdkOptionsResult {
238
333
  const config = getConfig();
239
334
  const chatSettings = getChatSettings(chatId);
240
- const activeModel = chatSettings.model ?? config.model;
335
+ const activeModel = modelOverride ?? chatSettings.model ?? config.model;
241
336
  const activeEffort = chatSettings.effort ?? "adaptive";
242
337
  const resolvedActiveModel = resolveModelId(activeModel);
243
338
 
@@ -247,9 +342,26 @@ export function buildSdkOptions(chatId: string): BuildSdkOptionsResult {
247
342
 
248
343
  const session = getSession(chatId);
249
344
 
345
+ // Per-session closure-shared state for the terminator hook pair (see
346
+ // buildTurnTerminatorHooks docstring). Each chat gets its own failure set
347
+ // so concurrent sessions never leak flags into each other.
348
+ const { postToolUseFailureHook, postToolBatchHook } =
349
+ buildTurnTerminatorHooks();
350
+
250
351
  const options: Options = {
251
352
  model: resolvedActiveModel,
252
- systemPrompt: config.systemPrompt,
353
+ // Prefer the caller's frozen per-session prompt; fall back to the
354
+ // global config split (warm-up and legacy callers), then to the
355
+ // plain string for configs built without parts (tests).
356
+ systemPrompt: preparedPrompt
357
+ ? toSdkSystemPrompt(preparedPrompt)
358
+ : config.systemPromptParts
359
+ ? toSdkSystemPrompt({
360
+ text: config.systemPrompt,
361
+ staticText: config.systemPromptParts.staticText,
362
+ dynamicText: config.systemPromptParts.dynamicText,
363
+ })
364
+ : config.systemPrompt,
253
365
  cwd: config.workspace,
254
366
  // The SDK's permission system is designed for an interactive Claude
255
367
  // Code IDE session where a human approves each tool call. Talon runs
@@ -262,17 +374,29 @@ export function buildSdkOptions(chatId: string): BuildSdkOptionsResult {
262
374
  // these as a unit — flipping either alone is a configuration bug.
263
375
  permissionMode: "bypassPermissions",
264
376
  allowDangerouslySkipPermissions: true,
377
+ // Cancellation signal — when aborted, the SDK tears down the spawned
378
+ // subprocess and stops streaming. The chat handler uses this both as a
379
+ // shutdown hook for the daemon and as the kill-switch for a watchdog
380
+ // that fires if the SDK iterator hangs after emitting `result`. The
381
+ // happy-path SDK exit is owned by the PostToolBatch hook below; this
382
+ // is defence in depth, not the primary terminator.
383
+ ...(abortController ? { abortController } : {}),
265
384
  ...(config.claudeBinary
266
385
  ? { pathToClaudeCodeExecutable: config.claudeBinary }
267
386
  : {}),
268
- disallowedTools: [...DISALLOWED_TOOLS_CHAT],
387
+ // Whitelist of SDK built-in tools. Anything not listed (e.g. WebSearch,
388
+ // WebFetch, Monitor, PushNotification, RemoteTrigger, Plan/Worktree/Todo
389
+ // helpers, AskUserQuestion, ScheduleWakeup) is unavailable to the model.
390
+ // MCP tools are governed independently via `mcpServers` below.
391
+ tools: [...ALLOWED_TOOLS_CHAT],
269
392
  ...thinkingConfig,
270
393
  mcpServers: {
271
394
  ...buildMcpServers(chatId),
272
- ...getPluginMcpServers(`http://127.0.0.1:${getBridgePort()}`, chatId),
395
+ ...buildPluginMcpServers(chatId),
273
396
  },
274
397
  hooks: {
275
- PostToolBatch: [{ hooks: [turnTerminatorHook] }],
398
+ PostToolUseFailure: [{ hooks: [postToolUseFailureHook] }],
399
+ PostToolBatch: [{ hooks: [postToolBatchHook] }],
276
400
  Notification: [{ hooks: [notificationHook] }],
277
401
  StopFailure: [{ hooks: [stopFailureHook] }],
278
402
  },
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { TalonConfig } from "../../util/config.js";
9
- import { registerClaudeModels } from "./models.js";
9
+ import { registerClaudeModels } from "./models/index.js";
10
10
 
11
11
  // ── State ────────────────────────────────────────────────────────────────────
12
12