@calliopelabs/cli 0.8.20 → 2.0.2

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 (402) hide show
  1. package/dist/agents/agent-config-loader.d.ts +60 -0
  2. package/dist/agents/agent-config-loader.d.ts.map +1 -0
  3. package/dist/agents/agent-config-loader.js +402 -0
  4. package/dist/agents/agent-config-loader.js.map +1 -0
  5. package/dist/agents/agent-config-presets.d.ts +10 -0
  6. package/dist/agents/agent-config-presets.d.ts.map +1 -0
  7. package/dist/agents/agent-config-presets.js +940 -0
  8. package/dist/agents/agent-config-presets.js.map +1 -0
  9. package/dist/agents/agent-config-types.d.ts +145 -0
  10. package/dist/agents/agent-config-types.d.ts.map +1 -0
  11. package/dist/agents/agent-config-types.js +12 -0
  12. package/dist/agents/agent-config-types.js.map +1 -0
  13. package/dist/{agterm → agents}/agent-detection.d.ts +1 -1
  14. package/dist/{agterm → agents}/agent-detection.d.ts.map +1 -1
  15. package/dist/{agterm → agents}/agent-detection.js +21 -5
  16. package/dist/agents/agent-detection.js.map +1 -0
  17. package/dist/agents/aggregator.d.ts +19 -0
  18. package/dist/agents/aggregator.d.ts.map +1 -0
  19. package/dist/agents/aggregator.js +141 -0
  20. package/dist/agents/aggregator.js.map +1 -0
  21. package/dist/{agterm → agents}/cli-backend.d.ts +1 -1
  22. package/dist/{agterm → agents}/cli-backend.d.ts.map +1 -1
  23. package/dist/{agterm → agents}/cli-backend.js +90 -12
  24. package/dist/agents/cli-backend.js.map +1 -0
  25. package/dist/agents/council-types.d.ts +113 -0
  26. package/dist/agents/council-types.d.ts.map +1 -0
  27. package/dist/agents/council-types.js +81 -0
  28. package/dist/agents/council-types.js.map +1 -0
  29. package/dist/agents/council.d.ts +107 -0
  30. package/dist/agents/council.d.ts.map +1 -0
  31. package/dist/agents/council.js +586 -0
  32. package/dist/agents/council.js.map +1 -0
  33. package/dist/agents/decomposer.d.ts +33 -0
  34. package/dist/agents/decomposer.d.ts.map +1 -0
  35. package/dist/agents/decomposer.js +138 -0
  36. package/dist/agents/decomposer.js.map +1 -0
  37. package/dist/agents/dynamic-tools.d.ts +52 -0
  38. package/dist/agents/dynamic-tools.d.ts.map +1 -0
  39. package/dist/agents/dynamic-tools.js +395 -0
  40. package/dist/agents/dynamic-tools.js.map +1 -0
  41. package/dist/agents/index.d.ts +29 -0
  42. package/dist/agents/index.d.ts.map +1 -0
  43. package/dist/agents/index.js +29 -0
  44. package/dist/agents/index.js.map +1 -0
  45. package/dist/agents/installer.d.ts +39 -0
  46. package/dist/agents/installer.d.ts.map +1 -0
  47. package/dist/agents/installer.js +205 -0
  48. package/dist/agents/installer.js.map +1 -0
  49. package/dist/{agterm → agents}/orchestrator.d.ts +7 -2
  50. package/dist/agents/orchestrator.d.ts.map +1 -0
  51. package/dist/{agterm → agents}/orchestrator.js +22 -2
  52. package/dist/agents/orchestrator.js.map +1 -0
  53. package/dist/agents/sdk-backend.d.ts +63 -0
  54. package/dist/agents/sdk-backend.d.ts.map +1 -0
  55. package/dist/agents/sdk-backend.js +489 -0
  56. package/dist/agents/sdk-backend.js.map +1 -0
  57. package/dist/agents/swarm-types.d.ts +83 -0
  58. package/dist/agents/swarm-types.d.ts.map +1 -0
  59. package/dist/agents/swarm-types.js +20 -0
  60. package/dist/agents/swarm-types.js.map +1 -0
  61. package/dist/agents/swarm.d.ts +74 -0
  62. package/dist/agents/swarm.d.ts.map +1 -0
  63. package/dist/agents/swarm.js +307 -0
  64. package/dist/agents/swarm.js.map +1 -0
  65. package/dist/{agterm → agents}/tools.d.ts +7 -5
  66. package/dist/agents/tools.d.ts.map +1 -0
  67. package/dist/agents/tools.js +776 -0
  68. package/dist/agents/tools.js.map +1 -0
  69. package/dist/{agterm → agents}/types.d.ts +14 -2
  70. package/dist/agents/types.d.ts.map +1 -0
  71. package/dist/{agterm → agents}/types.js +2 -2
  72. package/dist/agents/types.js.map +1 -0
  73. package/dist/api-server.d.ts +26 -0
  74. package/dist/api-server.d.ts.map +1 -0
  75. package/dist/api-server.js +230 -0
  76. package/dist/api-server.js.map +1 -0
  77. package/dist/auto-checkpoint.d.ts +35 -0
  78. package/dist/auto-checkpoint.d.ts.map +1 -0
  79. package/dist/auto-checkpoint.js +143 -0
  80. package/dist/auto-checkpoint.js.map +1 -0
  81. package/dist/auto-compressor.d.ts +44 -0
  82. package/dist/auto-compressor.d.ts.map +1 -0
  83. package/dist/auto-compressor.js +145 -0
  84. package/dist/auto-compressor.js.map +1 -0
  85. package/dist/background-jobs.d.ts +45 -0
  86. package/dist/background-jobs.d.ts.map +1 -0
  87. package/dist/background-jobs.js +122 -0
  88. package/dist/background-jobs.js.map +1 -0
  89. package/dist/bin.d.ts +6 -2
  90. package/dist/bin.d.ts.map +1 -1
  91. package/dist/bin.js +127 -24
  92. package/dist/bin.js.map +1 -1
  93. package/dist/checkpoint.d.ts +49 -0
  94. package/dist/checkpoint.d.ts.map +1 -0
  95. package/dist/checkpoint.js +219 -0
  96. package/dist/checkpoint.js.map +1 -0
  97. package/dist/circuit-breaker/breaker.d.ts +80 -0
  98. package/dist/circuit-breaker/breaker.d.ts.map +1 -0
  99. package/dist/circuit-breaker/breaker.js +408 -0
  100. package/dist/circuit-breaker/breaker.js.map +1 -0
  101. package/dist/circuit-breaker/defaults.d.ts +8 -0
  102. package/dist/circuit-breaker/defaults.d.ts.map +1 -0
  103. package/dist/circuit-breaker/defaults.js +35 -0
  104. package/dist/circuit-breaker/defaults.js.map +1 -0
  105. package/dist/circuit-breaker/index.d.ts +9 -0
  106. package/dist/circuit-breaker/index.d.ts.map +1 -0
  107. package/dist/circuit-breaker/index.js +8 -0
  108. package/dist/circuit-breaker/index.js.map +1 -0
  109. package/dist/circuit-breaker/types.d.ts +77 -0
  110. package/dist/circuit-breaker/types.d.ts.map +1 -0
  111. package/dist/circuit-breaker/types.js +8 -0
  112. package/dist/circuit-breaker/types.js.map +1 -0
  113. package/dist/circuit-breaker.d.ts +8 -0
  114. package/dist/circuit-breaker.d.ts.map +1 -0
  115. package/dist/circuit-breaker.js +7 -0
  116. package/dist/circuit-breaker.js.map +1 -0
  117. package/dist/cli/agent.d.ts +9 -0
  118. package/dist/cli/agent.d.ts.map +1 -0
  119. package/dist/cli/agent.js +262 -0
  120. package/dist/cli/agent.js.map +1 -0
  121. package/dist/cli/commands.d.ts +12 -0
  122. package/dist/cli/commands.d.ts.map +1 -0
  123. package/dist/{cli.js → cli/commands.js} +285 -422
  124. package/dist/cli/commands.js.map +1 -0
  125. package/dist/cli/index.d.ts +8 -0
  126. package/dist/cli/index.d.ts.map +1 -0
  127. package/dist/cli/index.js +222 -0
  128. package/dist/cli/index.js.map +1 -0
  129. package/dist/cli/types.d.ts +30 -0
  130. package/dist/cli/types.d.ts.map +1 -0
  131. package/dist/cli/types.js +20 -0
  132. package/dist/cli/types.js.map +1 -0
  133. package/dist/companions.d.ts +54 -0
  134. package/dist/companions.d.ts.map +1 -0
  135. package/dist/companions.js +440 -0
  136. package/dist/companions.js.map +1 -0
  137. package/dist/config.d.ts +23 -1
  138. package/dist/config.d.ts.map +1 -1
  139. package/dist/config.js +95 -22
  140. package/dist/config.js.map +1 -1
  141. package/dist/diff.d.ts +27 -0
  142. package/dist/diff.d.ts.map +1 -1
  143. package/dist/diff.js +415 -10
  144. package/dist/diff.js.map +1 -1
  145. package/dist/errors.d.ts.map +1 -1
  146. package/dist/errors.js +20 -11
  147. package/dist/errors.js.map +1 -1
  148. package/dist/git-status.d.ts +23 -0
  149. package/dist/git-status.d.ts.map +1 -0
  150. package/dist/git-status.js +92 -0
  151. package/dist/git-status.js.map +1 -0
  152. package/dist/headless.d.ts +25 -0
  153. package/dist/headless.d.ts.map +1 -0
  154. package/dist/headless.js +182 -0
  155. package/dist/headless.js.map +1 -0
  156. package/dist/hud/api.d.ts +35 -0
  157. package/dist/hud/api.d.ts.map +1 -0
  158. package/dist/hud/api.js +448 -0
  159. package/dist/hud/api.js.map +1 -0
  160. package/dist/hud/palettes.d.ts +9 -0
  161. package/dist/hud/palettes.d.ts.map +1 -0
  162. package/dist/hud/palettes.js +280 -0
  163. package/dist/hud/palettes.js.map +1 -0
  164. package/dist/hud/skins.d.ts +12 -0
  165. package/dist/hud/skins.d.ts.map +1 -0
  166. package/dist/hud/skins.js +365 -0
  167. package/dist/hud/skins.js.map +1 -0
  168. package/dist/hud/theme-packs/api.d.ts +51 -0
  169. package/dist/hud/theme-packs/api.d.ts.map +1 -0
  170. package/dist/hud/theme-packs/api.js +145 -0
  171. package/dist/hud/theme-packs/api.js.map +1 -0
  172. package/dist/hud/theme-packs/index.d.ts +18 -0
  173. package/dist/hud/theme-packs/index.d.ts.map +1 -0
  174. package/dist/hud/theme-packs/index.js +38 -0
  175. package/dist/hud/theme-packs/index.js.map +1 -0
  176. package/dist/hud/theme-packs/types.d.ts +29 -0
  177. package/dist/hud/theme-packs/types.d.ts.map +1 -0
  178. package/dist/hud/theme-packs/types.js +9 -0
  179. package/dist/hud/theme-packs/types.js.map +1 -0
  180. package/dist/hud/types.d.ts +182 -0
  181. package/dist/hud/types.d.ts.map +1 -0
  182. package/dist/hud/types.js +7 -0
  183. package/dist/hud/types.js.map +1 -0
  184. package/dist/idle-eviction.d.ts +34 -0
  185. package/dist/idle-eviction.d.ts.map +1 -0
  186. package/dist/idle-eviction.js +78 -0
  187. package/dist/idle-eviction.js.map +1 -0
  188. package/dist/index.d.ts +9 -3
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +9 -3
  191. package/dist/index.js.map +1 -1
  192. package/dist/iteration-ledger.d.ts +105 -0
  193. package/dist/iteration-ledger.d.ts.map +1 -0
  194. package/dist/iteration-ledger.js +237 -0
  195. package/dist/iteration-ledger.js.map +1 -0
  196. package/dist/markdown.d.ts.map +1 -1
  197. package/dist/markdown.js +1 -27
  198. package/dist/markdown.js.map +1 -1
  199. package/dist/mcp.d.ts +35 -0
  200. package/dist/mcp.d.ts.map +1 -1
  201. package/dist/mcp.js +291 -7
  202. package/dist/mcp.js.map +1 -1
  203. package/dist/memory.d.ts.map +1 -1
  204. package/dist/memory.js +12 -2
  205. package/dist/memory.js.map +1 -1
  206. package/dist/model-detection.d.ts +5 -0
  207. package/dist/model-detection.d.ts.map +1 -1
  208. package/dist/model-detection.js +278 -10
  209. package/dist/model-detection.js.map +1 -1
  210. package/dist/model-router.d.ts.map +1 -1
  211. package/dist/model-router.js +33 -11
  212. package/dist/model-router.js.map +1 -1
  213. package/dist/plugins.d.ts +8 -0
  214. package/dist/plugins.d.ts.map +1 -1
  215. package/dist/plugins.js +97 -6
  216. package/dist/plugins.js.map +1 -1
  217. package/dist/providers/anthropic.d.ts +10 -0
  218. package/dist/providers/anthropic.d.ts.map +1 -0
  219. package/dist/providers/anthropic.js +221 -0
  220. package/dist/providers/anthropic.js.map +1 -0
  221. package/dist/providers/bedrock.d.ts +17 -0
  222. package/dist/providers/bedrock.d.ts.map +1 -0
  223. package/dist/providers/bedrock.js +574 -0
  224. package/dist/providers/bedrock.js.map +1 -0
  225. package/dist/providers/compat.d.ts +13 -0
  226. package/dist/providers/compat.d.ts.map +1 -0
  227. package/dist/providers/compat.js +202 -0
  228. package/dist/providers/compat.js.map +1 -0
  229. package/dist/providers/google.d.ts +10 -0
  230. package/dist/providers/google.d.ts.map +1 -0
  231. package/dist/providers/google.js +203 -0
  232. package/dist/providers/google.js.map +1 -0
  233. package/dist/providers/index.d.ts +23 -0
  234. package/dist/providers/index.d.ts.map +1 -0
  235. package/dist/providers/index.js +145 -0
  236. package/dist/providers/index.js.map +1 -0
  237. package/dist/providers/ollama.d.ts +17 -0
  238. package/dist/providers/ollama.d.ts.map +1 -0
  239. package/dist/providers/ollama.js +289 -0
  240. package/dist/providers/ollama.js.map +1 -0
  241. package/dist/providers/openai.d.ts +121 -0
  242. package/dist/providers/openai.d.ts.map +1 -0
  243. package/dist/providers/openai.js +485 -0
  244. package/dist/providers/openai.js.map +1 -0
  245. package/dist/providers/types.d.ts +63 -0
  246. package/dist/providers/types.d.ts.map +1 -0
  247. package/dist/providers/types.js +164 -0
  248. package/dist/providers/types.js.map +1 -0
  249. package/dist/sandbox-native.d.ts +59 -0
  250. package/dist/sandbox-native.d.ts.map +1 -0
  251. package/dist/sandbox-native.js +292 -0
  252. package/dist/sandbox-native.js.map +1 -0
  253. package/dist/sandbox.d.ts +2 -2
  254. package/dist/sandbox.d.ts.map +1 -1
  255. package/dist/sandbox.js +59 -13
  256. package/dist/sandbox.js.map +1 -1
  257. package/dist/scope.d.ts +3 -1
  258. package/dist/scope.d.ts.map +1 -1
  259. package/dist/scope.js +13 -1
  260. package/dist/scope.js.map +1 -1
  261. package/dist/session-timeout.d.ts +31 -0
  262. package/dist/session-timeout.d.ts.map +1 -0
  263. package/dist/session-timeout.js +100 -0
  264. package/dist/session-timeout.js.map +1 -0
  265. package/dist/setup.d.ts.map +1 -1
  266. package/dist/setup.js +29 -17
  267. package/dist/setup.js.map +1 -1
  268. package/dist/smart-router.d.ts +73 -0
  269. package/dist/smart-router.d.ts.map +1 -0
  270. package/dist/smart-router.js +332 -0
  271. package/dist/smart-router.js.map +1 -0
  272. package/dist/storage.d.ts +19 -0
  273. package/dist/storage.d.ts.map +1 -1
  274. package/dist/storage.js +164 -1
  275. package/dist/storage.js.map +1 -1
  276. package/dist/streaming.d.ts +4 -0
  277. package/dist/streaming.d.ts.map +1 -1
  278. package/dist/streaming.js +12 -0
  279. package/dist/streaming.js.map +1 -1
  280. package/dist/styles.d.ts +32 -0
  281. package/dist/styles.d.ts.map +1 -1
  282. package/dist/styles.js +91 -0
  283. package/dist/styles.js.map +1 -1
  284. package/dist/summarization.d.ts +1 -1
  285. package/dist/summarization.js +4 -4
  286. package/dist/summarization.js.map +1 -1
  287. package/dist/terminal-image.d.ts +115 -0
  288. package/dist/terminal-image.d.ts.map +1 -0
  289. package/dist/terminal-image.js +766 -0
  290. package/dist/terminal-image.js.map +1 -0
  291. package/dist/terminal-recording.d.ts +55 -0
  292. package/dist/terminal-recording.d.ts.map +1 -0
  293. package/dist/terminal-recording.js +182 -0
  294. package/dist/terminal-recording.js.map +1 -0
  295. package/dist/themes.d.ts +19 -35
  296. package/dist/themes.d.ts.map +1 -1
  297. package/dist/themes.js +101 -210
  298. package/dist/themes.js.map +1 -1
  299. package/dist/tmux.d.ts +35 -0
  300. package/dist/tmux.d.ts.map +1 -0
  301. package/dist/tmux.js +106 -0
  302. package/dist/tmux.js.map +1 -0
  303. package/dist/tools.d.ts +3 -3
  304. package/dist/tools.d.ts.map +1 -1
  305. package/dist/tools.js +587 -45
  306. package/dist/tools.js.map +1 -1
  307. package/dist/trust.d.ts +53 -0
  308. package/dist/trust.d.ts.map +1 -0
  309. package/dist/trust.js +154 -0
  310. package/dist/trust.js.map +1 -0
  311. package/dist/types.d.ts +7 -3
  312. package/dist/types.d.ts.map +1 -1
  313. package/dist/types.js +70 -32
  314. package/dist/types.js.map +1 -1
  315. package/dist/ui/agent.d.ts +61 -0
  316. package/dist/ui/agent.d.ts.map +1 -0
  317. package/dist/ui/agent.js +768 -0
  318. package/dist/ui/agent.js.map +1 -0
  319. package/dist/ui/chat-input.d.ts +32 -0
  320. package/dist/ui/chat-input.d.ts.map +1 -0
  321. package/dist/ui/chat-input.js +355 -0
  322. package/dist/ui/chat-input.js.map +1 -0
  323. package/dist/ui/commands.d.ts +92 -0
  324. package/dist/ui/commands.d.ts.map +1 -0
  325. package/dist/ui/commands.js +3006 -0
  326. package/dist/ui/commands.js.map +1 -0
  327. package/dist/ui/completions.d.ts +22 -0
  328. package/dist/ui/completions.d.ts.map +1 -0
  329. package/dist/ui/completions.js +215 -0
  330. package/dist/ui/completions.js.map +1 -0
  331. package/dist/ui/components.d.ts +38 -0
  332. package/dist/ui/components.d.ts.map +1 -0
  333. package/dist/ui/components.js +422 -0
  334. package/dist/ui/components.js.map +1 -0
  335. package/dist/ui/context.d.ts +12 -0
  336. package/dist/ui/context.d.ts.map +1 -0
  337. package/dist/ui/context.js +102 -0
  338. package/dist/ui/context.js.map +1 -0
  339. package/dist/ui/error-boundary.d.ts +33 -0
  340. package/dist/ui/error-boundary.d.ts.map +1 -0
  341. package/dist/ui/error-boundary.js +94 -0
  342. package/dist/ui/error-boundary.js.map +1 -0
  343. package/dist/ui/frame.d.ts +13 -0
  344. package/dist/ui/frame.d.ts.map +1 -0
  345. package/dist/ui/frame.js +89 -0
  346. package/dist/ui/frame.js.map +1 -0
  347. package/dist/ui/index.d.ts +12 -0
  348. package/dist/ui/index.d.ts.map +1 -0
  349. package/dist/ui/index.js +928 -0
  350. package/dist/ui/index.js.map +1 -0
  351. package/dist/ui/messages.d.ts +19 -0
  352. package/dist/ui/messages.d.ts.map +1 -0
  353. package/dist/ui/messages.js +181 -0
  354. package/dist/ui/messages.js.map +1 -0
  355. package/dist/ui/modals.d.ts +52 -0
  356. package/dist/ui/modals.d.ts.map +1 -0
  357. package/dist/ui/modals.js +204 -0
  358. package/dist/ui/modals.js.map +1 -0
  359. package/dist/ui/pack-picker.d.ts +12 -0
  360. package/dist/ui/pack-picker.d.ts.map +1 -0
  361. package/dist/ui/pack-picker.js +101 -0
  362. package/dist/ui/pack-picker.js.map +1 -0
  363. package/dist/ui/status-bar.d.ts +20 -0
  364. package/dist/ui/status-bar.d.ts.map +1 -0
  365. package/dist/ui/status-bar.js +41 -0
  366. package/dist/ui/status-bar.js.map +1 -0
  367. package/dist/ui/theme-picker.d.ts +24 -0
  368. package/dist/ui/theme-picker.d.ts.map +1 -0
  369. package/dist/ui/theme-picker.js +190 -0
  370. package/dist/ui/theme-picker.js.map +1 -0
  371. package/dist/ui/types.d.ts +62 -0
  372. package/dist/ui/types.d.ts.map +1 -0
  373. package/dist/ui/types.js +7 -0
  374. package/dist/ui/types.js.map +1 -0
  375. package/dist/version-check.d.ts.map +1 -1
  376. package/dist/version-check.js +1 -9
  377. package/dist/version-check.js.map +1 -1
  378. package/package.json +8 -3
  379. package/dist/agterm/agent-detection.js.map +0 -1
  380. package/dist/agterm/cli-backend.js.map +0 -1
  381. package/dist/agterm/index.d.ts +0 -12
  382. package/dist/agterm/index.d.ts.map +0 -1
  383. package/dist/agterm/index.js +0 -15
  384. package/dist/agterm/index.js.map +0 -1
  385. package/dist/agterm/orchestrator.d.ts.map +0 -1
  386. package/dist/agterm/orchestrator.js.map +0 -1
  387. package/dist/agterm/tools.d.ts.map +0 -1
  388. package/dist/agterm/tools.js +0 -278
  389. package/dist/agterm/tools.js.map +0 -1
  390. package/dist/agterm/types.d.ts.map +0 -1
  391. package/dist/agterm/types.js.map +0 -1
  392. package/dist/cli.d.ts +0 -14
  393. package/dist/cli.d.ts.map +0 -1
  394. package/dist/cli.js.map +0 -1
  395. package/dist/providers.d.ts +0 -51
  396. package/dist/providers.d.ts.map +0 -1
  397. package/dist/providers.js +0 -1146
  398. package/dist/providers.js.map +0 -1
  399. package/dist/ui-cli.d.ts +0 -17
  400. package/dist/ui-cli.d.ts.map +0 -1
  401. package/dist/ui-cli.js +0 -3730
  402. package/dist/ui-cli.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Smart Router - Cross-Provider Model Selection
3
+ *
4
+ * Analyzes each prompt's task type and routes to the best model
5
+ * across all configured providers. Unlike autoRoute (single-provider
6
+ * tier selection), smart routing considers strength matrices across
7
+ * provider boundaries.
8
+ *
9
+ * Pure functions, no API calls - easy to test.
10
+ */
11
+ import type { LLMProvider } from './types.js';
12
+ import { type TaskComplexity } from './model-router.js';
13
+ export type TaskType = 'code' | 'research' | 'creative' | 'analysis' | 'simple-qa' | 'general';
14
+ export interface SmartRouteCandidate {
15
+ provider: LLMProvider;
16
+ model: string;
17
+ tier: 'fast' | 'balanced' | 'smart';
18
+ score: number;
19
+ reason: string;
20
+ }
21
+ export interface SmartRouteDecision {
22
+ selected: SmartRouteCandidate;
23
+ alternatives: SmartRouteCandidate[];
24
+ taskType: TaskType;
25
+ complexity: TaskComplexity;
26
+ confidence: number;
27
+ }
28
+ export interface SmartRoutingConfig {
29
+ enabled: boolean;
30
+ providerPool: LLMProvider[];
31
+ costSensitivity: number;
32
+ preferredProviders: LLMProvider[];
33
+ }
34
+ interface ModelInfo {
35
+ model: string;
36
+ costPer1kInput: number;
37
+ costPer1kOutput: number;
38
+ }
39
+ interface ProviderStrengths {
40
+ tiers: Record<'fast' | 'balanced' | 'smart', ModelInfo>;
41
+ strengths: Record<TaskType, number>;
42
+ }
43
+ export declare const MODEL_STRENGTHS: Partial<Record<LLMProvider, ProviderStrengths>>;
44
+ /**
45
+ * Detect the task type from a user message.
46
+ */
47
+ export declare function detectTaskType(message: string): {
48
+ taskType: TaskType;
49
+ confidence: number;
50
+ signals: string[];
51
+ };
52
+ /**
53
+ * Route to the best model across all configured providers.
54
+ *
55
+ * Algorithm:
56
+ * 1. analyzeComplexity() → tier (fast/balanced/smart)
57
+ * 2. detectTaskType() → task type
58
+ * 3. Score each (provider, tier) pair:
59
+ * score = strength * (1 - costWeight) + costEfficiency * costWeight
60
+ * 4. Return best candidate + alternatives
61
+ */
62
+ export declare function smartRoute(message: string, routingConfig: SmartRoutingConfig, context?: {
63
+ messageCount?: number;
64
+ hasCode?: boolean;
65
+ fileCount?: number;
66
+ toolsUsed?: string[];
67
+ }): SmartRouteDecision;
68
+ /**
69
+ * Get default smart routing config.
70
+ */
71
+ export declare function getDefaultSmartRoutingConfig(): SmartRoutingConfig;
72
+ export {};
73
+ //# sourceMappingURL=smart-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-router.d.ts","sourceRoot":"","sources":["../src/smart-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAO3E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/F,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,cAAc,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,WAAW,EAAE,CAAC;CACnC;AAMD,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,GAAG,OAAO,EAAE,SAAS,CAAC,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAwI3E,CAAC;AAsCF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA0C7G;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,kBAAkB,EACjC,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GACA,kBAAkB,CA+EpB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,kBAAkB,CAOjE"}
@@ -0,0 +1,332 @@
1
+ /**
2
+ * Smart Router - Cross-Provider Model Selection
3
+ *
4
+ * Analyzes each prompt's task type and routes to the best model
5
+ * across all configured providers. Unlike autoRoute (single-provider
6
+ * tier selection), smart routing considers strength matrices across
7
+ * provider boundaries.
8
+ *
9
+ * Pure functions, no API calls - easy to test.
10
+ */
11
+ import { analyzeComplexity } from './model-router.js';
12
+ import { getConfiguredProviders } from './config.js';
13
+ export const MODEL_STRENGTHS = {
14
+ anthropic: {
15
+ tiers: {
16
+ fast: { model: 'claude-3-5-haiku-20241022', costPer1kInput: 0.00025, costPer1kOutput: 0.00125 },
17
+ balanced: { model: 'claude-sonnet-4-20250514', costPer1kInput: 0.003, costPer1kOutput: 0.015 },
18
+ smart: { model: 'claude-opus-4-20250514', costPer1kInput: 0.015, costPer1kOutput: 0.075 },
19
+ },
20
+ strengths: {
21
+ 'code': 0.95,
22
+ 'research': 0.85,
23
+ 'creative': 0.90,
24
+ 'analysis': 0.90,
25
+ 'simple-qa': 0.80,
26
+ 'general': 0.90,
27
+ },
28
+ },
29
+ openai: {
30
+ tiers: {
31
+ fast: { model: 'gpt-4o-mini', costPer1kInput: 0.00015, costPer1kOutput: 0.0006 },
32
+ balanced: { model: 'gpt-4o', costPer1kInput: 0.0025, costPer1kOutput: 0.01 },
33
+ smart: { model: 'o1', costPer1kInput: 0.015, costPer1kOutput: 0.06 },
34
+ },
35
+ strengths: {
36
+ 'code': 0.90,
37
+ 'research': 0.85,
38
+ 'creative': 0.85,
39
+ 'analysis': 0.90,
40
+ 'simple-qa': 0.85,
41
+ 'general': 0.88,
42
+ },
43
+ },
44
+ google: {
45
+ tiers: {
46
+ fast: { model: 'gemini-2.0-flash', costPer1kInput: 0.000075, costPer1kOutput: 0.0003 },
47
+ balanced: { model: 'gemini-1.5-pro', costPer1kInput: 0.00125, costPer1kOutput: 0.005 },
48
+ smart: { model: 'gemini-1.5-pro', costPer1kInput: 0.00125, costPer1kOutput: 0.005 },
49
+ },
50
+ strengths: {
51
+ 'code': 0.80,
52
+ 'research': 0.90,
53
+ 'creative': 0.80,
54
+ 'analysis': 0.85,
55
+ 'simple-qa': 0.90,
56
+ 'general': 0.85,
57
+ },
58
+ },
59
+ groq: {
60
+ tiers: {
61
+ fast: { model: 'llama-3.1-8b-instant', costPer1kInput: 0.00005, costPer1kOutput: 0.00008 },
62
+ balanced: { model: 'llama-3.3-70b-versatile', costPer1kInput: 0.00059, costPer1kOutput: 0.00079 },
63
+ smart: { model: 'llama-3.3-70b-versatile', costPer1kInput: 0.00059, costPer1kOutput: 0.00079 },
64
+ },
65
+ strengths: {
66
+ 'code': 0.70,
67
+ 'research': 0.65,
68
+ 'creative': 0.65,
69
+ 'analysis': 0.65,
70
+ 'simple-qa': 0.80,
71
+ 'general': 0.70,
72
+ },
73
+ },
74
+ together: {
75
+ tiers: {
76
+ fast: { model: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', costPer1kInput: 0.00018, costPer1kOutput: 0.00018 },
77
+ balanced: { model: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', costPer1kInput: 0.00088, costPer1kOutput: 0.00088 },
78
+ smart: { model: 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo', costPer1kInput: 0.003, costPer1kOutput: 0.003 },
79
+ },
80
+ strengths: {
81
+ 'code': 0.75,
82
+ 'research': 0.70,
83
+ 'creative': 0.70,
84
+ 'analysis': 0.70,
85
+ 'simple-qa': 0.80,
86
+ 'general': 0.72,
87
+ },
88
+ },
89
+ openrouter: {
90
+ tiers: {
91
+ fast: { model: 'anthropic/claude-3.5-haiku', costPer1kInput: 0.0008, costPer1kOutput: 0.004 },
92
+ balanced: { model: 'anthropic/claude-sonnet-4', costPer1kInput: 0.003, costPer1kOutput: 0.015 },
93
+ smart: { model: 'anthropic/claude-opus-4', costPer1kInput: 0.015, costPer1kOutput: 0.075 },
94
+ },
95
+ strengths: {
96
+ 'code': 0.93,
97
+ 'research': 0.83,
98
+ 'creative': 0.88,
99
+ 'analysis': 0.88,
100
+ 'simple-qa': 0.78,
101
+ 'general': 0.88,
102
+ },
103
+ },
104
+ fireworks: {
105
+ tiers: {
106
+ fast: { model: 'accounts/fireworks/models/llama-v3p1-8b-instruct', costPer1kInput: 0.0002, costPer1kOutput: 0.0002 },
107
+ balanced: { model: 'accounts/fireworks/models/llama-v3p1-70b-instruct', costPer1kInput: 0.0009, costPer1kOutput: 0.0009 },
108
+ smart: { model: 'accounts/fireworks/models/llama-v3p1-405b-instruct', costPer1kInput: 0.003, costPer1kOutput: 0.003 },
109
+ },
110
+ strengths: {
111
+ 'code': 0.73,
112
+ 'research': 0.68,
113
+ 'creative': 0.68,
114
+ 'analysis': 0.68,
115
+ 'simple-qa': 0.78,
116
+ 'general': 0.70,
117
+ },
118
+ },
119
+ mistral: {
120
+ tiers: {
121
+ fast: { model: 'mistral-small-latest', costPer1kInput: 0.001, costPer1kOutput: 0.003 },
122
+ balanced: { model: 'mistral-large-latest', costPer1kInput: 0.003, costPer1kOutput: 0.009 },
123
+ smart: { model: 'mistral-large-latest', costPer1kInput: 0.003, costPer1kOutput: 0.009 },
124
+ },
125
+ strengths: {
126
+ 'code': 0.78,
127
+ 'research': 0.75,
128
+ 'creative': 0.75,
129
+ 'analysis': 0.78,
130
+ 'simple-qa': 0.82,
131
+ 'general': 0.78,
132
+ },
133
+ },
134
+ ollama: {
135
+ tiers: {
136
+ fast: { model: 'llama3.1:8b', costPer1kInput: 0, costPer1kOutput: 0 },
137
+ balanced: { model: 'llama3.3', costPer1kInput: 0, costPer1kOutput: 0 },
138
+ smart: { model: 'llama3.3', costPer1kInput: 0, costPer1kOutput: 0 },
139
+ },
140
+ strengths: {
141
+ 'code': 0.65,
142
+ 'research': 0.60,
143
+ 'creative': 0.60,
144
+ 'analysis': 0.60,
145
+ 'simple-qa': 0.75,
146
+ 'general': 0.65,
147
+ },
148
+ },
149
+ };
150
+ // ============================================================================
151
+ // Task Type Detection
152
+ // ============================================================================
153
+ const TASK_TYPE_PATTERNS = {
154
+ 'code': [
155
+ /\b(implement|refactor|bug|fix|debug|code|function|class|method|module)\b/i,
156
+ /\b(typescript|javascript|python|rust|java|go|ruby|c\+\+)\b/i,
157
+ /\.(ts|js|tsx|jsx|py|rs|go|java|rb|cpp|c|h|css|html|sql)\b/,
158
+ /```[\s\S]*```/,
159
+ /\b(npm|pip|cargo|maven|yarn|pnpm|git)\b/i,
160
+ /\b(compile|build|test|lint|deploy)\b/i,
161
+ ],
162
+ 'research': [
163
+ /\b(explain|compare|documentation|how\s+does|what\s+is|describe|overview)\b/i,
164
+ /\b(research|investigate|look\s+into|find\s+out|summarize)\b/i,
165
+ /\b(pros\s+and\s+cons|tradeoffs?|trade-offs?|differences?\s+between)\b/i,
166
+ ],
167
+ 'creative': [
168
+ /\b(write|story|brainstorm|imagine|creative|poem|narrative)\b/i,
169
+ /\b(generate|compose|craft|design|invent|create\s+a)\b/i,
170
+ /\b(naming|tagline|slogan|pitch|headline)\b/i,
171
+ ],
172
+ 'analysis': [
173
+ /\b(analyze|review|audit|evaluate|assess|inspect)\b/i,
174
+ /\b(metrics|performance|benchmark|profil|optimize)\b/i,
175
+ /\b(security|vulnerability|risk|compliance)\b/i,
176
+ /\b(data|statistics|trends|patterns|correlat)\b/i,
177
+ ],
178
+ 'simple-qa': [
179
+ /^.{0,80}$/, // Very short messages
180
+ /^(what|who|when|where|why|how|is|are|do|does|can|could|will|would)\b/i,
181
+ /\?$/,
182
+ ],
183
+ };
184
+ /**
185
+ * Detect the task type from a user message.
186
+ */
187
+ export function detectTaskType(message) {
188
+ const scores = {
189
+ 'code': 0,
190
+ 'research': 0,
191
+ 'creative': 0,
192
+ 'analysis': 0,
193
+ 'simple-qa': 0,
194
+ 'general': 0,
195
+ };
196
+ const signals = [];
197
+ for (const [type, patterns] of Object.entries(TASK_TYPE_PATTERNS)) {
198
+ if (!patterns)
199
+ continue;
200
+ for (const pattern of patterns) {
201
+ if (pattern.test(message)) {
202
+ scores[type] += 1;
203
+ if (scores[type] === 1) {
204
+ signals.push(type);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ // Find highest scoring type
210
+ let bestType = 'general';
211
+ let bestScore = 0;
212
+ for (const [type, score] of Object.entries(scores)) {
213
+ if (score > bestScore) {
214
+ bestScore = score;
215
+ bestType = type;
216
+ }
217
+ }
218
+ // If simple-qa is the only match but it's a short question, keep it
219
+ // If code or analysis also matches, those take priority
220
+ if (bestType === 'simple-qa' && scores['code'] > 0)
221
+ bestType = 'code';
222
+ if (bestType === 'simple-qa' && scores['analysis'] > 0)
223
+ bestType = 'analysis';
224
+ if (bestType === 'simple-qa' && scores['research'] > 0)
225
+ bestType = 'research';
226
+ const confidence = bestScore > 0 ? Math.min(0.95, 0.5 + bestScore * 0.15) : 0.3;
227
+ return { taskType: bestType, confidence, signals };
228
+ }
229
+ // ============================================================================
230
+ // Cost Efficiency
231
+ // ============================================================================
232
+ function costEfficiency(info) {
233
+ const avgCost = (info.costPer1kInput + info.costPer1kOutput) / 2;
234
+ if (avgCost === 0)
235
+ return 1.0; // Free (local) = max efficiency
236
+ // Normalize: lower cost = higher efficiency. Cap at 1.0
237
+ return Math.min(1.0, 0.01 / avgCost);
238
+ }
239
+ // ============================================================================
240
+ // Smart Routing
241
+ // ============================================================================
242
+ /**
243
+ * Route to the best model across all configured providers.
244
+ *
245
+ * Algorithm:
246
+ * 1. analyzeComplexity() → tier (fast/balanced/smart)
247
+ * 2. detectTaskType() → task type
248
+ * 3. Score each (provider, tier) pair:
249
+ * score = strength * (1 - costWeight) + costEfficiency * costWeight
250
+ * 4. Return best candidate + alternatives
251
+ */
252
+ export function smartRoute(message, routingConfig, context) {
253
+ // Step 1: Determine complexity → tier
254
+ const { complexity, confidence: complexityConfidence } = analyzeComplexity(message, context);
255
+ let tier;
256
+ switch (complexity) {
257
+ case 'trivial':
258
+ case 'simple':
259
+ tier = 'fast';
260
+ break;
261
+ case 'moderate':
262
+ tier = 'balanced';
263
+ break;
264
+ case 'complex':
265
+ case 'expert':
266
+ tier = 'smart';
267
+ break;
268
+ }
269
+ // Step 2: Detect task type
270
+ const { taskType, confidence: typeConfidence } = detectTaskType(message);
271
+ // Step 3: Score each (provider, tier) pair
272
+ const pool = routingConfig.providerPool.length > 0
273
+ ? routingConfig.providerPool
274
+ : getConfiguredProviders();
275
+ const costWeight = routingConfig.costSensitivity;
276
+ const candidates = [];
277
+ for (const provider of pool) {
278
+ const strengths = MODEL_STRENGTHS[provider];
279
+ if (!strengths)
280
+ continue;
281
+ const modelInfo = strengths.tiers[tier];
282
+ const taskStrength = strengths.strengths[taskType] ?? 0.5;
283
+ const efficiency = costEfficiency(modelInfo);
284
+ const score = taskStrength * (1 - costWeight) + efficiency * costWeight;
285
+ // Preference bonus for preferred providers (small tie-breaker)
286
+ const preferenceBonus = routingConfig.preferredProviders.includes(provider) ? 0.01 : 0;
287
+ candidates.push({
288
+ provider,
289
+ model: modelInfo.model,
290
+ tier,
291
+ score: score + preferenceBonus,
292
+ reason: `${taskType}/${complexity} - strength ${(taskStrength * 100).toFixed(0)}%, cost efficiency ${(efficiency * 100).toFixed(0)}%`,
293
+ });
294
+ }
295
+ // Sort by score descending
296
+ candidates.sort((a, b) => b.score - a.score);
297
+ // If no candidates found, return a fallback
298
+ if (candidates.length === 0) {
299
+ return {
300
+ selected: {
301
+ provider: 'anthropic',
302
+ model: 'claude-sonnet-4-20250514',
303
+ tier,
304
+ score: 0.5,
305
+ reason: 'fallback - no providers available',
306
+ },
307
+ alternatives: [],
308
+ taskType,
309
+ complexity,
310
+ confidence: Math.min(complexityConfidence, typeConfidence),
311
+ };
312
+ }
313
+ return {
314
+ selected: candidates[0],
315
+ alternatives: candidates.slice(1),
316
+ taskType,
317
+ complexity,
318
+ confidence: Math.min(complexityConfidence, typeConfidence),
319
+ };
320
+ }
321
+ /**
322
+ * Get default smart routing config.
323
+ */
324
+ export function getDefaultSmartRoutingConfig() {
325
+ return {
326
+ enabled: false,
327
+ providerPool: [],
328
+ costSensitivity: 0.3,
329
+ preferredProviders: [],
330
+ };
331
+ }
332
+ //# sourceMappingURL=smart-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-router.js","sourceRoot":"","sources":["../src/smart-router.ts"],"names":[],"mappings":"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"}
package/dist/storage.d.ts CHANGED
@@ -84,6 +84,25 @@ export declare function addChatMessage(message: Omit<ChatMessage, 'id' | 'timest
84
84
  * Get chat history for current session
85
85
  */
86
86
  export declare function getChatHistory(limit?: number): ChatMessage[];
87
+ /**
88
+ * Find a session directory by session ID
89
+ */
90
+ export declare function getSessionDirById(sessionId: string): string | null;
91
+ /**
92
+ * Save the full LLM message array to the current session directory as messages.json.
93
+ * This preserves tool calls, tool results, and all message metadata for perfect resume.
94
+ */
95
+ export declare function saveMessageHistory(messages: unknown[]): void;
96
+ /**
97
+ * Load saved LLM messages from a session.
98
+ * If sessionId is provided, loads from that session; otherwise loads from current session.
99
+ */
100
+ export declare function loadMessageHistory(sessionId?: string): unknown[] | null;
101
+ /**
102
+ * Fork the current session: creates a new session with the current messages copied.
103
+ * Returns the new session, or null on failure.
104
+ */
105
+ export declare function forkSession(projectPath: string): Session | null;
87
106
  /**
88
107
  * Search chat history
89
108
  */
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAChD,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;CAC1E;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;CAC7D;AAQD,eAAO,MAAM,KAAK;;;;;;;;;;;;;CAajB,CAAC;AAMF;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAuBlC;AA8KD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA2C/D;AAgBD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,GAAG,IAAI,CAUlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,SAAK,GAAG,OAAO,EAAE,CA0BlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAaxD;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI,CAoBnF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAQ5D;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBlE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAgB5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,GAAG,IAAI,CAuBvE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAkD/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAO9D;AAMD;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,EAAE,CAGxC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,EAAE,CAGvC;AAED;;GAEG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CACb,GACL,IAAI,CAuBN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC,EACxE,MAAM,UAAQ,GACb,IAAI,GAAG,IAAI,CAkBb;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAY9D;AAMD;;GAEG;AACH,wBAAgB,QAAQ,IAAI,IAAI,EAAE,CAiBjC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAQzC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,GAAG,IAAI,CAG3C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAOrD;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,SAAM,GAAG,MAAM,EAAE,CAUvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAK5D;AAMD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AASD;;GAEG;AACH,wBAAgB,QAAQ,IAAI,UAAU,CAwBrC;AA4CD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAsBnF;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAwBvC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAMD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AASD;;GAEG;AACH,wBAAgB,YAAY,IAAI,cAAc,EAAE,CAG/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAgBzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQpD;AAaD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAOzD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,GAAG,IAAI,CAa3C"}
package/dist/storage.js CHANGED
@@ -165,7 +165,8 @@ function formatTodo(todo) {
165
165
  return `${todo.id}|${todo.status}|${todo.priority}|${tags}|${todo.createdAt}|${completed}|${content}`;
166
166
  }
167
167
  function parseTodoLine(line) {
168
- const parts = line.split('|');
168
+ // Split on unescaped pipes only (pipes not preceded by backslash)
169
+ const parts = line.split(/(?<!\\)\|/);
169
170
  if (parts.length < 7)
170
171
  return null;
171
172
  const [id, status, priority, tags, createdAt, completedAt, ...contentParts] = parts;
@@ -365,6 +366,127 @@ export function getChatHistory(limit) {
365
366
  }
366
367
  return history;
367
368
  }
369
+ // ============================================================================
370
+ // Session Persistence (Full LLM Message History)
371
+ // ============================================================================
372
+ /**
373
+ * Find a session directory by session ID
374
+ */
375
+ export function getSessionDirById(sessionId) {
376
+ initStorage();
377
+ try {
378
+ const entries = fs.readdirSync(paths.sessions, { withFileTypes: true });
379
+ for (const entry of entries) {
380
+ if (entry.isDirectory() && entry.name !== 'current') {
381
+ const sessionFile = path.join(paths.sessions, entry.name, 'session.json');
382
+ const session = readJSON(sessionFile, null);
383
+ if (session && session.id === sessionId) {
384
+ return path.join(paths.sessions, entry.name);
385
+ }
386
+ }
387
+ }
388
+ }
389
+ catch {
390
+ // Ignore errors
391
+ }
392
+ return null;
393
+ }
394
+ /**
395
+ * Save the full LLM message array to the current session directory as messages.json.
396
+ * This preserves tool calls, tool results, and all message metadata for perfect resume.
397
+ */
398
+ export function saveMessageHistory(messages) {
399
+ const session = getCurrentSession();
400
+ if (!session)
401
+ return;
402
+ try {
403
+ const messagesFile = path.join(paths.currentSession, 'messages.json');
404
+ writeJSON(messagesFile, messages);
405
+ // Update session metadata
406
+ const sessionFile = path.join(paths.currentSession, 'session.json');
407
+ session.messageCount = messages.length;
408
+ session.lastAccessedAt = new Date().toISOString();
409
+ writeJSON(sessionFile, session);
410
+ }
411
+ catch {
412
+ // Silently fail - don't break the agent loop
413
+ }
414
+ }
415
+ /**
416
+ * Load saved LLM messages from a session.
417
+ * If sessionId is provided, loads from that session; otherwise loads from current session.
418
+ */
419
+ export function loadMessageHistory(sessionId) {
420
+ try {
421
+ let messagesFile;
422
+ if (sessionId) {
423
+ const sessionDir = getSessionDirById(sessionId);
424
+ if (!sessionDir)
425
+ return null;
426
+ messagesFile = path.join(sessionDir, 'messages.json');
427
+ }
428
+ else {
429
+ messagesFile = path.join(paths.currentSession, 'messages.json');
430
+ }
431
+ if (!fs.existsSync(messagesFile))
432
+ return null;
433
+ const content = fs.readFileSync(messagesFile, 'utf-8');
434
+ const messages = JSON.parse(content);
435
+ if (Array.isArray(messages)) {
436
+ return messages;
437
+ }
438
+ }
439
+ catch {
440
+ // Ignore parse errors
441
+ }
442
+ return null;
443
+ }
444
+ /**
445
+ * Fork the current session: creates a new session with the current messages copied.
446
+ * Returns the new session, or null on failure.
447
+ */
448
+ export function forkSession(projectPath) {
449
+ initStorage();
450
+ // Load current messages
451
+ const currentMessages = loadMessageHistory();
452
+ if (!currentMessages || currentMessages.length === 0) {
453
+ return null;
454
+ }
455
+ const currentSession = getCurrentSession();
456
+ // Create a unique fork directory name
457
+ const projectName = path.basename(projectPath) || 'unnamed';
458
+ const date = getTodayString();
459
+ const forkSuffix = `_fork_${Date.now()}`;
460
+ const forkDirName = `${date}_${projectName}${forkSuffix}`;
461
+ const forkDir = path.join(paths.sessions, forkDirName);
462
+ try {
463
+ fs.mkdirSync(forkDir, { recursive: true });
464
+ fs.mkdirSync(path.join(forkDir, 'plans'), { recursive: true });
465
+ const newSession = {
466
+ id: `session_${Date.now()}`,
467
+ projectPath,
468
+ projectName,
469
+ createdAt: new Date().toISOString(),
470
+ lastAccessedAt: new Date().toISOString(),
471
+ messageCount: currentMessages.length,
472
+ provider: currentSession?.provider || '',
473
+ model: currentSession?.model || '',
474
+ };
475
+ // Write session metadata
476
+ writeJSON(path.join(forkDir, 'session.json'), newSession);
477
+ // Copy messages to fork
478
+ writeJSON(path.join(forkDir, 'messages.json'), currentMessages);
479
+ // Create empty chat log and todos
480
+ fs.writeFileSync(path.join(forkDir, 'chat.log'), '');
481
+ fs.writeFileSync(path.join(forkDir, 'todos.txt'), '');
482
+ // Point current symlink to fork
483
+ updateCurrentSymlink(forkDir);
484
+ return newSession;
485
+ }
486
+ catch {
487
+ return null;
488
+ }
489
+ }
368
490
  /**
369
491
  * Search chat history
370
492
  */
@@ -568,6 +690,41 @@ export function getCosts() {
568
690
  lastUpdated: new Date().toISOString(),
569
691
  };
570
692
  }
693
+ /** Maximum number of days to retain in costByDay */
694
+ const COST_PRUNE_DAYS = 90;
695
+ /** Maximum number of sessions to retain in costBySession */
696
+ const COST_PRUNE_MAX_SESSIONS = 100;
697
+ /** Minimum interval between cost pruning runs (1 hour in ms) */
698
+ const COST_PRUNE_INTERVAL = 60 * 60 * 1000;
699
+ /** Timestamp of last cost pruning run */
700
+ let lastCostPrune = 0;
701
+ /**
702
+ * Prune old entries from cost data to prevent unbounded growth.
703
+ * Removes costByDay entries older than COST_PRUNE_DAYS and trims
704
+ * costBySession to the most recent COST_PRUNE_MAX_SESSIONS entries.
705
+ */
706
+ function pruneCosts(costs) {
707
+ // Prune costByDay: remove entries older than 90 days
708
+ const cutoffDate = new Date();
709
+ cutoffDate.setDate(cutoffDate.getDate() - COST_PRUNE_DAYS);
710
+ const cutoffStr = getTodayString(cutoffDate);
711
+ const dayKeys = Object.keys(costs.costByDay);
712
+ for (const day of dayKeys) {
713
+ if (day < cutoffStr) {
714
+ delete costs.costByDay[day];
715
+ }
716
+ }
717
+ // Prune costBySession: keep only the most recent N sessions (by key, which contains timestamp)
718
+ const sessionKeys = Object.keys(costs.costBySession);
719
+ if (sessionKeys.length > COST_PRUNE_MAX_SESSIONS) {
720
+ // Session IDs are formatted as session_<timestamp>, so sorting works chronologically
721
+ sessionKeys.sort();
722
+ const toRemove = sessionKeys.slice(0, sessionKeys.length - COST_PRUNE_MAX_SESSIONS);
723
+ for (const key of toRemove) {
724
+ delete costs.costBySession[key];
725
+ }
726
+ }
727
+ }
571
728
  /**
572
729
  * Record a cost
573
730
  */
@@ -581,6 +738,12 @@ export function recordCost(cost, provider, sessionId) {
581
738
  if (sessionId) {
582
739
  costs.costBySession[sessionId] = (costs.costBySession[sessionId] || 0) + cost;
583
740
  }
741
+ // Periodically prune old entries (at most once per hour)
742
+ const now = Date.now();
743
+ if (now - lastCostPrune > COST_PRUNE_INTERVAL) {
744
+ lastCostPrune = now;
745
+ pruneCosts(costs);
746
+ }
584
747
  costs.lastUpdated = new Date().toISOString();
585
748
  writeJSON(getCostFilePath(), costs);
586
749
  }