indusagi 0.12.18 → 0.12.20

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 (518) hide show
  1. package/README.md +17 -37
  2. package/dist/agent/agent-loop.d.ts +3 -9
  3. package/dist/agent/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/agent-loop.js +19 -58
  5. package/dist/agent/agent-loop.js.map +1 -1
  6. package/dist/agent/agent.d.ts +9 -10
  7. package/dist/agent/agent.d.ts.map +1 -1
  8. package/dist/agent/agent.js +182 -129
  9. package/dist/agent/agent.js.map +1 -1
  10. package/dist/agent/error-handler.d.ts.map +1 -1
  11. package/dist/agent/error-handler.js.map +1 -1
  12. package/dist/agent/event-bus.d.ts.map +1 -1
  13. package/dist/agent/event-bus.js +1 -3
  14. package/dist/agent/event-bus.js.map +1 -1
  15. package/dist/agent/index.d.ts.map +1 -1
  16. package/dist/agent/index.js +0 -6
  17. package/dist/agent/index.js.map +1 -1
  18. package/dist/agent/messages.d.ts +1 -1
  19. package/dist/agent/messages.d.ts.map +1 -1
  20. package/dist/agent/proxy.d.ts +1 -14
  21. package/dist/agent/proxy.d.ts.map +1 -1
  22. package/dist/agent/proxy.js +67 -148
  23. package/dist/agent/proxy.js.map +1 -1
  24. package/dist/agent/session-manager.d.ts +10 -10
  25. package/dist/agent/session-manager.d.ts.map +1 -1
  26. package/dist/agent/session-manager.js +20 -16
  27. package/dist/agent/session-manager.js.map +1 -1
  28. package/dist/agent/state-manager.d.ts +1 -1
  29. package/dist/agent/state-manager.d.ts.map +1 -1
  30. package/dist/agent/state-manager.js +1 -0
  31. package/dist/agent/state-manager.js.map +1 -1
  32. package/dist/agent/telemetry.d.ts.map +1 -1
  33. package/dist/agent/telemetry.js +1 -3
  34. package/dist/agent/telemetry.js.map +1 -1
  35. package/dist/agent/tools/bash.d.ts.map +1 -1
  36. package/dist/agent/tools/bash.js +143 -118
  37. package/dist/agent/tools/bash.js.map +1 -1
  38. package/dist/agent/tools/edit-diff.d.ts +1 -1
  39. package/dist/agent/tools/edit-diff.d.ts.map +1 -1
  40. package/dist/agent/tools/edit-diff.js +189 -175
  41. package/dist/agent/tools/edit-diff.js.map +1 -1
  42. package/dist/agent/tools/edit.d.ts.map +1 -1
  43. package/dist/agent/tools/edit.js +137 -121
  44. package/dist/agent/tools/edit.js.map +1 -1
  45. package/dist/agent/tools/find.d.ts.map +1 -1
  46. package/dist/agent/tools/find.js +100 -65
  47. package/dist/agent/tools/find.js.map +1 -1
  48. package/dist/agent/tools/grep.d.ts.map +1 -1
  49. package/dist/agent/tools/grep.js +126 -97
  50. package/dist/agent/tools/grep.js.map +1 -1
  51. package/dist/agent/tools/index.d.ts +53 -40
  52. package/dist/agent/tools/index.d.ts.map +1 -1
  53. package/dist/agent/tools/index.js +19 -12
  54. package/dist/agent/tools/index.js.map +1 -1
  55. package/dist/agent/tools/ls.d.ts +2 -1
  56. package/dist/agent/tools/ls.d.ts.map +1 -1
  57. package/dist/agent/tools/ls.js +145 -94
  58. package/dist/agent/tools/ls.js.map +1 -1
  59. package/dist/agent/tools/path-utils.d.ts.map +1 -1
  60. package/dist/agent/tools/path-utils.js +48 -29
  61. package/dist/agent/tools/path-utils.js.map +1 -1
  62. package/dist/agent/tools/process-controller.d.ts +15 -0
  63. package/dist/agent/tools/process-controller.d.ts.map +1 -0
  64. package/dist/agent/tools/process-controller.js +39 -0
  65. package/dist/agent/tools/process-controller.js.map +1 -0
  66. package/dist/agent/tools/process-manager.d.ts +60 -0
  67. package/dist/agent/tools/process-manager.d.ts.map +1 -0
  68. package/dist/agent/tools/process-manager.js +485 -0
  69. package/dist/agent/tools/process-manager.js.map +1 -0
  70. package/dist/agent/tools/process-types.d.ts +74 -0
  71. package/dist/agent/tools/process-types.d.ts.map +1 -0
  72. package/dist/agent/tools/process-types.js +7 -0
  73. package/dist/agent/tools/process-types.js.map +1 -0
  74. package/dist/agent/tools/process.d.ts +38 -0
  75. package/dist/agent/tools/process.d.ts.map +1 -0
  76. package/dist/agent/tools/process.js +360 -0
  77. package/dist/agent/tools/process.js.map +1 -0
  78. package/dist/agent/tools/read.d.ts.map +1 -1
  79. package/dist/agent/tools/read.js +157 -135
  80. package/dist/agent/tools/read.js.map +1 -1
  81. package/dist/agent/tools/registry.js +2 -4
  82. package/dist/agent/tools/registry.js.map +1 -1
  83. package/dist/agent/tools/teams/activity-tracker.d.ts +66 -0
  84. package/dist/agent/tools/teams/activity-tracker.d.ts.map +1 -0
  85. package/dist/agent/tools/teams/activity-tracker.js +480 -0
  86. package/dist/agent/tools/teams/activity-tracker.js.map +1 -0
  87. package/dist/agent/tools/teams/cleanup.d.ts +51 -0
  88. package/dist/agent/tools/teams/cleanup.d.ts.map +1 -0
  89. package/dist/agent/tools/teams/cleanup.js +219 -0
  90. package/dist/agent/tools/teams/cleanup.js.map +1 -0
  91. package/dist/agent/tools/teams/fs-lock.d.ts +12 -0
  92. package/dist/agent/tools/teams/fs-lock.d.ts.map +1 -0
  93. package/dist/agent/tools/teams/fs-lock.js +74 -0
  94. package/dist/agent/tools/teams/fs-lock.js.map +1 -0
  95. package/dist/agent/tools/teams/index.d.ts +12 -0
  96. package/dist/agent/tools/teams/index.d.ts.map +1 -0
  97. package/dist/agent/tools/teams/index.js +12 -0
  98. package/dist/agent/tools/teams/index.js.map +1 -0
  99. package/dist/agent/tools/teams/mailbox.d.ts +21 -0
  100. package/dist/agent/tools/teams/mailbox.d.ts.map +1 -0
  101. package/dist/agent/tools/teams/mailbox.js +106 -0
  102. package/dist/agent/tools/teams/mailbox.js.map +1 -0
  103. package/dist/agent/tools/teams/model-policy.d.ts +23 -0
  104. package/dist/agent/tools/teams/model-policy.d.ts.map +1 -0
  105. package/dist/agent/tools/teams/model-policy.js +113 -0
  106. package/dist/agent/tools/teams/model-policy.js.map +1 -0
  107. package/dist/agent/tools/teams/names.d.ts +28 -0
  108. package/dist/agent/tools/teams/names.d.ts.map +1 -0
  109. package/dist/agent/tools/teams/names.js +109 -0
  110. package/dist/agent/tools/teams/names.js.map +1 -0
  111. package/dist/agent/tools/teams/protocol.d.ts +75 -0
  112. package/dist/agent/tools/teams/protocol.d.ts.map +1 -0
  113. package/dist/agent/tools/teams/protocol.js +205 -0
  114. package/dist/agent/tools/teams/protocol.js.map +1 -0
  115. package/dist/agent/tools/teams/task-store.d.ts +89 -0
  116. package/dist/agent/tools/teams/task-store.d.ts.map +1 -0
  117. package/dist/agent/tools/teams/task-store.js +445 -0
  118. package/dist/agent/tools/teams/task-store.js.map +1 -0
  119. package/dist/agent/tools/teams/team-attach-claim.d.ts +36 -0
  120. package/dist/agent/tools/teams/team-attach-claim.d.ts.map +1 -0
  121. package/dist/agent/tools/teams/team-attach-claim.js +144 -0
  122. package/dist/agent/tools/teams/team-attach-claim.js.map +1 -0
  123. package/dist/agent/tools/teams/team-config.d.ts +55 -0
  124. package/dist/agent/tools/teams/team-config.d.ts.map +1 -0
  125. package/dist/agent/tools/teams/team-config.js +252 -0
  126. package/dist/agent/tools/teams/team-config.js.map +1 -0
  127. package/dist/agent/tools/teams/worktree.d.ts +40 -0
  128. package/dist/agent/tools/teams/worktree.d.ts.map +1 -0
  129. package/dist/agent/tools/teams/worktree.js +213 -0
  130. package/dist/agent/tools/teams/worktree.js.map +1 -0
  131. package/dist/agent/tools/todo-store.js +2 -1
  132. package/dist/agent/tools/todo-store.js.map +1 -1
  133. package/dist/agent/tools/todo.d.ts +2 -2
  134. package/dist/agent/tools/todo.js +2 -2
  135. package/dist/agent/tools/truncate.d.ts.map +1 -1
  136. package/dist/agent/tools/truncate.js +150 -134
  137. package/dist/agent/tools/truncate.js.map +1 -1
  138. package/dist/agent/tools/utils/hook-runner.d.ts +9 -10
  139. package/dist/agent/tools/utils/hook-runner.d.ts.map +1 -1
  140. package/dist/agent/tools/utils/hook-runner.js +18 -16
  141. package/dist/agent/tools/utils/hook-runner.js.map +1 -1
  142. package/dist/agent/tools/utils/image-resize.d.ts +1 -14
  143. package/dist/agent/tools/utils/image-resize.d.ts.map +1 -1
  144. package/dist/agent/tools/utils/image-resize.js +80 -34
  145. package/dist/agent/tools/utils/image-resize.js.map +1 -1
  146. package/dist/agent/tools/utils/mime.d.ts +0 -8
  147. package/dist/agent/tools/utils/mime.d.ts.map +1 -1
  148. package/dist/agent/tools/utils/mime.js +43 -32
  149. package/dist/agent/tools/utils/mime.js.map +1 -1
  150. package/dist/agent/tools/utils/shell.d.ts +1 -23
  151. package/dist/agent/tools/utils/shell.d.ts.map +1 -1
  152. package/dist/agent/tools/utils/shell.js +43 -86
  153. package/dist/agent/tools/utils/shell.js.map +1 -1
  154. package/dist/agent/tools/write.d.ts.map +1 -1
  155. package/dist/agent/tools/write.js +105 -62
  156. package/dist/agent/tools/write.js.map +1 -1
  157. package/dist/agent/types.d.ts +69 -64
  158. package/dist/agent/types.d.ts.map +1 -1
  159. package/dist/agent/types.js +38 -23
  160. package/dist/agent/types.js.map +1 -1
  161. package/dist/agent.d.ts +4 -0
  162. package/dist/agent.d.ts.map +1 -1
  163. package/dist/agent.js +4 -0
  164. package/dist/agent.js.map +1 -1
  165. package/dist/ai/api-registry.d.ts.map +1 -1
  166. package/dist/ai/api-registry.js +3 -4
  167. package/dist/ai/api-registry.js.map +1 -1
  168. package/dist/ai/cli.js +62 -82
  169. package/dist/ai/cli.js.map +1 -1
  170. package/dist/ai/env-api-keys.d.ts.map +1 -1
  171. package/dist/ai/env-api-keys.js +78 -81
  172. package/dist/ai/env-api-keys.js.map +1 -1
  173. package/dist/ai/index.d.ts +6 -0
  174. package/dist/ai/index.d.ts.map +1 -1
  175. package/dist/ai/index.js +6 -0
  176. package/dist/ai/index.js.map +1 -1
  177. package/dist/ai/models.d.ts +7 -17
  178. package/dist/ai/models.d.ts.map +1 -1
  179. package/dist/ai/models.generated.d.ts +87 -244
  180. package/dist/ai/models.generated.d.ts.map +1 -1
  181. package/dist/ai/models.generated.js +82 -241
  182. package/dist/ai/models.generated.js.map +1 -1
  183. package/dist/ai/models.js +17 -11
  184. package/dist/ai/models.js.map +1 -1
  185. package/dist/ai/providers/amazon-bedrock.d.ts.map +1 -1
  186. package/dist/ai/providers/amazon-bedrock.js +319 -248
  187. package/dist/ai/providers/amazon-bedrock.js.map +1 -1
  188. package/dist/ai/providers/anthropic.d.ts.map +1 -1
  189. package/dist/ai/providers/anthropic.js +378 -324
  190. package/dist/ai/providers/anthropic.js.map +1 -1
  191. package/dist/ai/providers/azure-openai-responses.d.ts.map +1 -1
  192. package/dist/ai/providers/azure-openai-responses.js +164 -123
  193. package/dist/ai/providers/azure-openai-responses.js.map +1 -1
  194. package/dist/ai/providers/google-shared.d.ts +0 -18
  195. package/dist/ai/providers/google-shared.d.ts.map +1 -1
  196. package/dist/ai/providers/google-shared.js +224 -225
  197. package/dist/ai/providers/google-shared.js.map +1 -1
  198. package/dist/ai/providers/google-vertex.d.ts.map +1 -1
  199. package/dist/ai/providers/google-vertex.js +244 -226
  200. package/dist/ai/providers/google-vertex.js.map +1 -1
  201. package/dist/ai/providers/google.d.ts +3 -0
  202. package/dist/ai/providers/google.d.ts.map +1 -1
  203. package/dist/ai/providers/google.js +232 -210
  204. package/dist/ai/providers/google.js.map +1 -1
  205. package/dist/ai/providers/kimi.js +1 -0
  206. package/dist/ai/providers/kimi.js.map +1 -1
  207. package/dist/ai/providers/mock.d.ts +10 -0
  208. package/dist/ai/providers/mock.d.ts.map +1 -0
  209. package/dist/ai/providers/mock.js +64 -0
  210. package/dist/ai/providers/mock.js.map +1 -0
  211. package/dist/ai/providers/openai-codex-responses.d.ts.map +1 -1
  212. package/dist/ai/providers/openai-codex-responses.js +178 -133
  213. package/dist/ai/providers/openai-codex-responses.js.map +1 -1
  214. package/dist/ai/providers/openai-completions.d.ts.map +1 -1
  215. package/dist/ai/providers/openai-completions.js +468 -387
  216. package/dist/ai/providers/openai-completions.js.map +1 -1
  217. package/dist/ai/providers/openai-responses-shared.d.ts.map +1 -1
  218. package/dist/ai/providers/openai-responses-shared.js +187 -166
  219. package/dist/ai/providers/openai-responses-shared.js.map +1 -1
  220. package/dist/ai/providers/openai-responses.d.ts.map +1 -1
  221. package/dist/ai/providers/openai-responses.js +108 -85
  222. package/dist/ai/providers/openai-responses.js.map +1 -1
  223. package/dist/ai/providers/openai-scaffold.d.ts +4 -0
  224. package/dist/ai/providers/openai-scaffold.d.ts.map +1 -0
  225. package/dist/ai/providers/openai-scaffold.js +33 -0
  226. package/dist/ai/providers/openai-scaffold.js.map +1 -0
  227. package/dist/ai/providers/register-builtins.d.ts.map +1 -1
  228. package/dist/ai/providers/register-builtins.js +109 -42
  229. package/dist/ai/providers/register-builtins.js.map +1 -1
  230. package/dist/ai/providers/simple-options.js +2 -0
  231. package/dist/ai/providers/simple-options.js.map +1 -1
  232. package/dist/ai/providers/transform-messages.js +3 -9
  233. package/dist/ai/providers/transform-messages.js.map +1 -1
  234. package/dist/ai/stream.d.ts +4 -14
  235. package/dist/ai/stream.d.ts.map +1 -1
  236. package/dist/ai/stream.js +0 -36
  237. package/dist/ai/stream.js.map +1 -1
  238. package/dist/ai/types.d.ts +22 -3
  239. package/dist/ai/types.d.ts.map +1 -1
  240. package/dist/ai/types.js +154 -77
  241. package/dist/ai/types.js.map +1 -1
  242. package/dist/ai/utils/base-stream-handler.js +1 -0
  243. package/dist/ai/utils/base-stream-handler.js.map +1 -1
  244. package/dist/ai/utils/event-stream.d.ts +2 -0
  245. package/dist/ai/utils/event-stream.d.ts.map +1 -1
  246. package/dist/ai/utils/event-stream.js +22 -5
  247. package/dist/ai/utils/event-stream.js.map +1 -1
  248. package/dist/ai/utils/json-parse.d.ts +3 -0
  249. package/dist/ai/utils/json-parse.d.ts.map +1 -1
  250. package/dist/ai/utils/json-parse.js +8 -5
  251. package/dist/ai/utils/json-parse.js.map +1 -1
  252. package/dist/ai/utils/oauth/anthropic.d.ts.map +1 -1
  253. package/dist/ai/utils/oauth/anthropic.js +110 -65
  254. package/dist/ai/utils/oauth/anthropic.js.map +1 -1
  255. package/dist/ai/utils/oauth/github-copilot.d.ts +8 -16
  256. package/dist/ai/utils/oauth/github-copilot.d.ts.map +1 -1
  257. package/dist/ai/utils/oauth/github-copilot.js +218 -227
  258. package/dist/ai/utils/oauth/github-copilot.js.map +1 -1
  259. package/dist/ai/utils/oauth/openai-codex.d.ts +4 -2
  260. package/dist/ai/utils/oauth/openai-codex.d.ts.map +1 -1
  261. package/dist/ai/utils/oauth/openai-codex.js +221 -236
  262. package/dist/ai/utils/oauth/openai-codex.js.map +1 -1
  263. package/dist/ai/utils/oauth/pkce.d.ts +6 -5
  264. package/dist/ai/utils/oauth/pkce.d.ts.map +1 -1
  265. package/dist/ai/utils/oauth/pkce.js +24 -21
  266. package/dist/ai/utils/oauth/pkce.js.map +1 -1
  267. package/dist/ai/utils/oauth/types.d.ts +31 -12
  268. package/dist/ai/utils/oauth/types.d.ts.map +1 -1
  269. package/dist/ai/utils/oauth/types.js +10 -1
  270. package/dist/ai/utils/oauth/types.js.map +1 -1
  271. package/dist/ai/utils/overflow.d.ts.map +1 -1
  272. package/dist/ai/utils/overflow.js +49 -21
  273. package/dist/ai/utils/overflow.js.map +1 -1
  274. package/dist/ai/utils/provider-adapter.js +9 -0
  275. package/dist/ai/utils/provider-adapter.js.map +1 -1
  276. package/dist/ai/utils/provider-client-builder.js +1 -1
  277. package/dist/ai/utils/provider-client-builder.js.map +1 -1
  278. package/dist/ai/utils/provider-errors.js +2 -0
  279. package/dist/ai/utils/provider-errors.js.map +1 -1
  280. package/dist/ai/utils/sanitize-unicode.d.ts +0 -20
  281. package/dist/ai/utils/sanitize-unicode.d.ts.map +1 -1
  282. package/dist/ai/utils/sanitize-unicode.js +35 -17
  283. package/dist/ai/utils/sanitize-unicode.js.map +1 -1
  284. package/dist/ai/utils/stream-event-helper.js +3 -0
  285. package/dist/ai/utils/stream-event-helper.js.map +1 -1
  286. package/dist/ai/utils/stream-handler-types.js +5 -0
  287. package/dist/ai/utils/stream-handler-types.js.map +1 -1
  288. package/dist/ai/utils/streaming-state-manager.js +4 -2
  289. package/dist/ai/utils/streaming-state-manager.js.map +1 -1
  290. package/dist/ai/utils/typebox-helpers.d.ts +6 -4
  291. package/dist/ai/utils/typebox-helpers.d.ts.map +1 -1
  292. package/dist/ai/utils/typebox-helpers.js +25 -7
  293. package/dist/ai/utils/typebox-helpers.js.map +1 -1
  294. package/dist/ai/utils/validation.d.ts.map +1 -1
  295. package/dist/ai/utils/validation.js +67 -34
  296. package/dist/ai/utils/validation.js.map +1 -1
  297. package/dist/ai.d.ts +4 -0
  298. package/dist/ai.d.ts.map +1 -1
  299. package/dist/ai.js +4 -0
  300. package/dist/ai.js.map +1 -1
  301. package/dist/cli.d.ts +3 -0
  302. package/dist/cli.d.ts.map +1 -0
  303. package/dist/cli.js +3 -0
  304. package/dist/cli.js.map +1 -0
  305. package/dist/index.d.ts +1 -0
  306. package/dist/index.d.ts.map +1 -1
  307. package/dist/index.js +1 -0
  308. package/dist/index.js.map +1 -1
  309. package/dist/mcp/client-pool.js +3 -2
  310. package/dist/mcp/client-pool.js.map +1 -1
  311. package/dist/mcp/client.js +19 -6
  312. package/dist/mcp/client.js.map +1 -1
  313. package/dist/mcp/config.d.ts +6 -6
  314. package/dist/mcp/config.js +17 -17
  315. package/dist/mcp/config.js.map +1 -1
  316. package/dist/mcp/errors.js +8 -0
  317. package/dist/mcp/errors.js.map +1 -1
  318. package/dist/mcp/index.d.ts +5 -5
  319. package/dist/mcp/index.js +5 -5
  320. package/dist/mcp/schema-converter.d.ts +1 -1
  321. package/dist/mcp/schema-converter.js +1 -1
  322. package/dist/mcp/server.d.ts +4 -4
  323. package/dist/mcp/server.js +12 -7
  324. package/dist/mcp/server.js.map +1 -1
  325. package/dist/mcp/tool-factory.d.ts +2 -2
  326. package/dist/mcp/tool-factory.js +2 -2
  327. package/dist/mcp.d.ts +0 -4
  328. package/dist/mcp.d.ts.map +1 -1
  329. package/dist/mcp.js +0 -4
  330. package/dist/mcp.js.map +1 -1
  331. package/dist/observability.d.ts +2 -0
  332. package/dist/observability.d.ts.map +1 -0
  333. package/dist/observability.js +2 -0
  334. package/dist/observability.js.map +1 -0
  335. package/dist/tui/autocomplete.d.ts +14 -18
  336. package/dist/tui/autocomplete.d.ts.map +1 -1
  337. package/dist/tui/autocomplete.js +290 -402
  338. package/dist/tui/autocomplete.js.map +1 -1
  339. package/dist/tui/components/box.d.ts +1 -6
  340. package/dist/tui/components/box.d.ts.map +1 -1
  341. package/dist/tui/components/box.js +98 -67
  342. package/dist/tui/components/box.js.map +1 -1
  343. package/dist/tui/components/cancellable-loader.d.ts +6 -3
  344. package/dist/tui/components/cancellable-loader.d.ts.map +1 -1
  345. package/dist/tui/components/cancellable-loader.js +8 -9
  346. package/dist/tui/components/cancellable-loader.js.map +1 -1
  347. package/dist/tui/components/editor.d.ts +18 -0
  348. package/dist/tui/components/editor.d.ts.map +1 -1
  349. package/dist/tui/components/editor.js +356 -354
  350. package/dist/tui/components/editor.js.map +1 -1
  351. package/dist/tui/components/image.d.ts +2 -0
  352. package/dist/tui/components/image.d.ts.map +1 -1
  353. package/dist/tui/components/image.js +79 -37
  354. package/dist/tui/components/image.js.map +1 -1
  355. package/dist/tui/components/input.d.ts +4 -8
  356. package/dist/tui/components/input.d.ts.map +1 -1
  357. package/dist/tui/components/input.js +236 -232
  358. package/dist/tui/components/input.js.map +1 -1
  359. package/dist/tui/components/loader.d.ts +5 -5
  360. package/dist/tui/components/loader.d.ts.map +1 -1
  361. package/dist/tui/components/loader.js +22 -19
  362. package/dist/tui/components/loader.js.map +1 -1
  363. package/dist/tui/components/markdown.d.ts +2 -32
  364. package/dist/tui/components/markdown.d.ts.map +1 -1
  365. package/dist/tui/components/markdown.js +338 -357
  366. package/dist/tui/components/markdown.js.map +1 -1
  367. package/dist/tui/components/select-list.d.ts +1 -0
  368. package/dist/tui/components/select-list.d.ts.map +1 -1
  369. package/dist/tui/components/select-list.js +83 -82
  370. package/dist/tui/components/select-list.js.map +1 -1
  371. package/dist/tui/components/settings-list.d.ts +10 -10
  372. package/dist/tui/components/settings-list.d.ts.map +1 -1
  373. package/dist/tui/components/settings-list.js +48 -40
  374. package/dist/tui/components/settings-list.js.map +1 -1
  375. package/dist/tui/components/spacer.d.ts +1 -0
  376. package/dist/tui/components/spacer.d.ts.map +1 -1
  377. package/dist/tui/components/spacer.js +20 -5
  378. package/dist/tui/components/spacer.js.map +1 -1
  379. package/dist/tui/components/text.d.ts.map +1 -1
  380. package/dist/tui/components/text.js +47 -20
  381. package/dist/tui/components/text.js.map +1 -1
  382. package/dist/tui/components/truncated-text.d.ts +8 -4
  383. package/dist/tui/components/truncated-text.d.ts.map +1 -1
  384. package/dist/tui/components/truncated-text.js +15 -12
  385. package/dist/tui/components/truncated-text.js.map +1 -1
  386. package/dist/tui/editor-component.d.ts +87 -23
  387. package/dist/tui/editor-component.d.ts.map +1 -1
  388. package/dist/tui/fuzzy.d.ts.map +1 -1
  389. package/dist/tui/fuzzy.js +101 -50
  390. package/dist/tui/fuzzy.js.map +1 -1
  391. package/dist/tui/keybindings.d.ts +3 -3
  392. package/dist/tui/keybindings.d.ts.map +1 -1
  393. package/dist/tui/keybindings.js +137 -111
  394. package/dist/tui/keybindings.js.map +1 -1
  395. package/dist/tui/keys.d.ts +46 -43
  396. package/dist/tui/keys.d.ts.map +1 -1
  397. package/dist/tui/keys.js +493 -411
  398. package/dist/tui/keys.js.map +1 -1
  399. package/dist/tui/stdin-buffer.d.ts.map +1 -1
  400. package/dist/tui/stdin-buffer.js +162 -159
  401. package/dist/tui/stdin-buffer.js.map +1 -1
  402. package/dist/tui/terminal-image.d.ts +10 -5
  403. package/dist/tui/terminal-image.d.ts.map +1 -1
  404. package/dist/tui/terminal-image.js +53 -51
  405. package/dist/tui/terminal-image.js.map +1 -1
  406. package/dist/tui/terminal.d.ts +4 -27
  407. package/dist/tui/terminal.d.ts.map +1 -1
  408. package/dist/tui/terminal.js +123 -121
  409. package/dist/tui/terminal.js.map +1 -1
  410. package/dist/tui/tui.d.ts +14 -1
  411. package/dist/tui/tui.d.ts.map +1 -1
  412. package/dist/tui/tui.js +185 -145
  413. package/dist/tui/tui.js.map +1 -1
  414. package/dist/tui/utils.d.ts.map +1 -1
  415. package/dist/tui/utils.js +235 -216
  416. package/dist/tui/utils.js.map +1 -1
  417. package/dist/tui.d.ts +4 -0
  418. package/dist/tui.d.ts.map +1 -1
  419. package/dist/tui.js +4 -0
  420. package/dist/tui.js.map +1 -1
  421. package/package.json +23 -43
  422. package/LICENSE.md +0 -22
  423. package/dist/agent/tools/task-types.d.ts +0 -74
  424. package/dist/agent/tools/task-types.d.ts.map +0 -1
  425. package/dist/agent/tools/task-types.js +0 -8
  426. package/dist/agent/tools/task-types.js.map +0 -1
  427. package/dist/agent/tools/task.d.ts +0 -84
  428. package/dist/agent/tools/task.d.ts.map +0 -1
  429. package/dist/agent/tools/task.js +0 -184
  430. package/dist/agent/tools/task.js.map +0 -1
  431. package/dist/memory/embedder/base.d.ts +0 -41
  432. package/dist/memory/embedder/base.d.ts.map +0 -1
  433. package/dist/memory/embedder/base.js +0 -10
  434. package/dist/memory/embedder/base.js.map +0 -1
  435. package/dist/memory/embedder/index.d.ts +0 -8
  436. package/dist/memory/embedder/index.d.ts.map +0 -1
  437. package/dist/memory/embedder/index.js +0 -6
  438. package/dist/memory/embedder/index.js.map +0 -1
  439. package/dist/memory/embedder/openai.d.ts +0 -35
  440. package/dist/memory/embedder/openai.d.ts.map +0 -1
  441. package/dist/memory/embedder/openai.js +0 -103
  442. package/dist/memory/embedder/openai.js.map +0 -1
  443. package/dist/memory/index.d.ts +0 -33
  444. package/dist/memory/index.d.ts.map +0 -1
  445. package/dist/memory/index.js +0 -31
  446. package/dist/memory/index.js.map +0 -1
  447. package/dist/memory/memory.d.ts +0 -126
  448. package/dist/memory/memory.d.ts.map +0 -1
  449. package/dist/memory/memory.js +0 -280
  450. package/dist/memory/memory.js.map +0 -1
  451. package/dist/memory/processors/base.d.ts +0 -42
  452. package/dist/memory/processors/base.d.ts.map +0 -1
  453. package/dist/memory/processors/base.js +0 -6
  454. package/dist/memory/processors/base.js.map +0 -1
  455. package/dist/memory/processors/index.d.ts +0 -16
  456. package/dist/memory/processors/index.d.ts.map +0 -1
  457. package/dist/memory/processors/index.js +0 -18
  458. package/dist/memory/processors/index.js.map +0 -1
  459. package/dist/memory/processors/message-history.d.ts +0 -35
  460. package/dist/memory/processors/message-history.d.ts.map +0 -1
  461. package/dist/memory/processors/message-history.js +0 -51
  462. package/dist/memory/processors/message-history.js.map +0 -1
  463. package/dist/memory/processors/observational-memory/index.d.ts +0 -82
  464. package/dist/memory/processors/observational-memory/index.d.ts.map +0 -1
  465. package/dist/memory/processors/observational-memory/index.js +0 -234
  466. package/dist/memory/processors/observational-memory/index.js.map +0 -1
  467. package/dist/memory/processors/observational-memory/observer-agent.d.ts +0 -64
  468. package/dist/memory/processors/observational-memory/observer-agent.d.ts.map +0 -1
  469. package/dist/memory/processors/observational-memory/observer-agent.js +0 -362
  470. package/dist/memory/processors/observational-memory/observer-agent.js.map +0 -1
  471. package/dist/memory/processors/observational-memory/reflector-agent.d.ts +0 -38
  472. package/dist/memory/processors/observational-memory/reflector-agent.d.ts.map +0 -1
  473. package/dist/memory/processors/observational-memory/reflector-agent.js +0 -213
  474. package/dist/memory/processors/observational-memory/reflector-agent.js.map +0 -1
  475. package/dist/memory/processors/observational-memory/token-counter.d.ts +0 -35
  476. package/dist/memory/processors/observational-memory/token-counter.d.ts.map +0 -1
  477. package/dist/memory/processors/observational-memory/token-counter.js +0 -90
  478. package/dist/memory/processors/observational-memory/token-counter.js.map +0 -1
  479. package/dist/memory/processors/semantic-recall.d.ts +0 -55
  480. package/dist/memory/processors/semantic-recall.d.ts.map +0 -1
  481. package/dist/memory/processors/semantic-recall.js +0 -143
  482. package/dist/memory/processors/semantic-recall.js.map +0 -1
  483. package/dist/memory/processors/working-memory.d.ts +0 -41
  484. package/dist/memory/processors/working-memory.d.ts.map +0 -1
  485. package/dist/memory/processors/working-memory.js +0 -82
  486. package/dist/memory/processors/working-memory.js.map +0 -1
  487. package/dist/memory/storage/base.d.ts +0 -288
  488. package/dist/memory/storage/base.d.ts.map +0 -1
  489. package/dist/memory/storage/base.js +0 -211
  490. package/dist/memory/storage/base.js.map +0 -1
  491. package/dist/memory/storage/index.d.ts +0 -9
  492. package/dist/memory/storage/index.d.ts.map +0 -1
  493. package/dist/memory/storage/index.js +0 -7
  494. package/dist/memory/storage/index.js.map +0 -1
  495. package/dist/memory/storage/inmemory.d.ts +0 -93
  496. package/dist/memory/storage/inmemory.d.ts.map +0 -1
  497. package/dist/memory/storage/inmemory.js +0 -646
  498. package/dist/memory/storage/inmemory.js.map +0 -1
  499. package/dist/memory/tools/working-memory.d.ts +0 -100
  500. package/dist/memory/tools/working-memory.d.ts.map +0 -1
  501. package/dist/memory/tools/working-memory.js +0 -237
  502. package/dist/memory/tools/working-memory.js.map +0 -1
  503. package/dist/memory/types.d.ts +0 -386
  504. package/dist/memory/types.d.ts.map +0 -1
  505. package/dist/memory/types.js +0 -58
  506. package/dist/memory/types.js.map +0 -1
  507. package/dist/memory/vector/base.d.ts +0 -145
  508. package/dist/memory/vector/base.d.ts.map +0 -1
  509. package/dist/memory/vector/base.js +0 -83
  510. package/dist/memory/vector/base.js.map +0 -1
  511. package/dist/memory/vector/index.d.ts +0 -8
  512. package/dist/memory/vector/index.d.ts.map +0 -1
  513. package/dist/memory/vector/index.js +0 -7
  514. package/dist/memory/vector/index.js.map +0 -1
  515. package/dist/memory/vector/inmemory.d.ts +0 -47
  516. package/dist/memory/vector/inmemory.d.ts.map +0 -1
  517. package/dist/memory/vector/inmemory.js +0 -234
  518. package/dist/memory/vector/inmemory.js.map +0 -1
@@ -47,6 +47,7 @@ function hasToolHistory(messages) {
47
47
  return false;
48
48
  }
49
49
  export class OpenAICompatibilityAdapter {
50
+ model;
50
51
  constructor(model) {
51
52
  this.model = model;
52
53
  }
@@ -65,6 +66,7 @@ export class OpenAICompatibilityAdapter {
65
66
  * standardized assistant events.
66
67
  */
67
68
  class OpenAICompletionsStreamHandler extends BaseStreamHandler {
69
+ executeFn;
68
70
  constructor(executeFn) {
69
71
  super();
70
72
  this.executeFn = executeFn;
@@ -76,6 +78,209 @@ class OpenAICompletionsStreamHandler extends BaseStreamHandler {
76
78
  await this.executeFn();
77
79
  }
78
80
  }
81
+ class CompletionsBlockLifecycle {
82
+ output;
83
+ stream;
84
+ activeBlock = null;
85
+ constructor(output, stream) {
86
+ this.output = output;
87
+ this.stream = stream;
88
+ }
89
+ finalizeCurrent() {
90
+ if (!this.activeBlock)
91
+ return;
92
+ const currentIndex = this.output.content.length - 1;
93
+ if (this.activeBlock.type === "text") {
94
+ this.stream.push({
95
+ type: "text_end",
96
+ contentIndex: currentIndex,
97
+ content: this.activeBlock.text,
98
+ partial: this.output,
99
+ });
100
+ }
101
+ else if (this.activeBlock.type === "thinking") {
102
+ this.stream.push({
103
+ type: "thinking_end",
104
+ contentIndex: currentIndex,
105
+ content: this.activeBlock.thinking,
106
+ partial: this.output,
107
+ });
108
+ }
109
+ else {
110
+ this.activeBlock.arguments = JSON.parse(this.activeBlock.partialArgs || "{}");
111
+ delete this.activeBlock.partialArgs;
112
+ this.stream.push({
113
+ type: "toolcall_end",
114
+ contentIndex: currentIndex,
115
+ toolCall: this.activeBlock,
116
+ partial: this.output,
117
+ });
118
+ }
119
+ }
120
+ applyTextDelta(deltaText) {
121
+ if (!deltaText)
122
+ return;
123
+ if (!this.activeBlock || this.activeBlock.type !== "text") {
124
+ this.finalizeCurrent();
125
+ this.activeBlock = { type: "text", text: "" };
126
+ this.output.content.push(this.activeBlock);
127
+ this.stream.push({ type: "text_start", contentIndex: this.output.content.length - 1, partial: this.output });
128
+ }
129
+ if (this.activeBlock.type === "text") {
130
+ this.activeBlock.text += deltaText;
131
+ this.stream.push({
132
+ type: "text_delta",
133
+ contentIndex: this.output.content.length - 1,
134
+ delta: deltaText,
135
+ partial: this.output,
136
+ });
137
+ }
138
+ }
139
+ applyThinkingDelta(reasoningField, deltaText) {
140
+ if (!deltaText)
141
+ return;
142
+ if (!this.activeBlock || this.activeBlock.type !== "thinking") {
143
+ this.finalizeCurrent();
144
+ this.activeBlock = {
145
+ type: "thinking",
146
+ thinking: "",
147
+ thinkingSignature: reasoningField,
148
+ };
149
+ this.output.content.push(this.activeBlock);
150
+ this.stream.push({
151
+ type: "thinking_start",
152
+ contentIndex: this.output.content.length - 1,
153
+ partial: this.output,
154
+ });
155
+ }
156
+ if (this.activeBlock.type === "thinking") {
157
+ this.activeBlock.thinking += deltaText;
158
+ this.stream.push({
159
+ type: "thinking_delta",
160
+ contentIndex: this.output.content.length - 1,
161
+ delta: deltaText,
162
+ partial: this.output,
163
+ });
164
+ }
165
+ }
166
+ applyToolCallDelta(toolCall) {
167
+ if (!this.activeBlock ||
168
+ this.activeBlock.type !== "toolCall" ||
169
+ (toolCall.id && this.activeBlock.id !== toolCall.id)) {
170
+ this.finalizeCurrent();
171
+ this.activeBlock = {
172
+ type: "toolCall",
173
+ id: toolCall.id || "",
174
+ name: toolCall.function?.name || "",
175
+ arguments: {},
176
+ partialArgs: "",
177
+ };
178
+ this.output.content.push(this.activeBlock);
179
+ this.stream.push({
180
+ type: "toolcall_start",
181
+ contentIndex: this.output.content.length - 1,
182
+ partial: this.output,
183
+ });
184
+ }
185
+ if (this.activeBlock.type === "toolCall") {
186
+ if (toolCall.id)
187
+ this.activeBlock.id = toolCall.id;
188
+ if (toolCall.function?.name)
189
+ this.activeBlock.name = toolCall.function.name;
190
+ let argumentDelta = "";
191
+ if (toolCall.function?.arguments) {
192
+ argumentDelta = toolCall.function.arguments;
193
+ this.activeBlock.partialArgs += toolCall.function.arguments;
194
+ this.activeBlock.arguments = parseStreamingJson(this.activeBlock.partialArgs);
195
+ }
196
+ this.stream.push({
197
+ type: "toolcall_delta",
198
+ contentIndex: this.output.content.length - 1,
199
+ delta: argumentDelta,
200
+ partial: this.output,
201
+ });
202
+ }
203
+ }
204
+ attachReasoningDetails(reasoningDetails) {
205
+ if (!Array.isArray(reasoningDetails))
206
+ return;
207
+ for (const detail of reasoningDetails) {
208
+ if (detail?.type === "reasoning.encrypted" && detail?.id && detail?.data) {
209
+ const matchingToolCall = this.output.content.find((b) => b.type === "toolCall" && b.id === detail.id);
210
+ if (matchingToolCall) {
211
+ matchingToolCall.thoughtSignature = JSON.stringify(detail);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+ class CompletionsChunkRouter {
218
+ model;
219
+ output;
220
+ lifecycle;
221
+ static REASONING_FIELDS = ["reasoning_content", "reasoning", "reasoning_text"];
222
+ constructor(model, output, lifecycle) {
223
+ this.model = model;
224
+ this.output = output;
225
+ this.lifecycle = lifecycle;
226
+ }
227
+ applyUsage(chunk) {
228
+ if (!chunk.usage)
229
+ return;
230
+ const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens || 0;
231
+ const reasoningTokens = chunk.usage.completion_tokens_details?.reasoning_tokens || 0;
232
+ const input = (chunk.usage.prompt_tokens || 0) - cachedTokens;
233
+ const outputTokens = (chunk.usage.completion_tokens || 0) + reasoningTokens;
234
+ this.output.usage = {
235
+ input,
236
+ output: outputTokens,
237
+ cacheRead: cachedTokens,
238
+ cacheWrite: 0,
239
+ totalTokens: input + outputTokens + cachedTokens,
240
+ cost: {
241
+ input: 0,
242
+ output: 0,
243
+ cacheRead: 0,
244
+ cacheWrite: 0,
245
+ total: 0,
246
+ },
247
+ };
248
+ calculateCost(this.model, this.output.usage);
249
+ }
250
+ applyFinishReason(choice) {
251
+ if (choice.finish_reason) {
252
+ this.output.stopReason = mapProviderStopReason(choice.finish_reason, "openai-completions");
253
+ }
254
+ }
255
+ applyChoiceDelta(choice) {
256
+ const delta = choice.delta;
257
+ if (!delta)
258
+ return;
259
+ if (delta.content) {
260
+ this.lifecycle.applyTextDelta(delta.content);
261
+ }
262
+ const reasoningField = this.resolveReasoningField(delta);
263
+ if (reasoningField) {
264
+ const reasoningDelta = delta[reasoningField];
265
+ this.lifecycle.applyThinkingDelta(reasoningField, reasoningDelta);
266
+ }
267
+ if (delta.tool_calls) {
268
+ for (const toolCall of delta.tool_calls) {
269
+ this.lifecycle.applyToolCallDelta(toolCall);
270
+ }
271
+ }
272
+ this.lifecycle.attachReasoningDetails(delta.reasoning_details);
273
+ }
274
+ resolveReasoningField(delta) {
275
+ for (const field of CompletionsChunkRouter.REASONING_FIELDS) {
276
+ const value = delta[field];
277
+ if (value !== null && value !== undefined && value.length > 0) {
278
+ return field;
279
+ }
280
+ }
281
+ return null;
282
+ }
283
+ }
79
284
  export const streamOpenAICompletions = (model, context, options) => {
80
285
  const stream = new AssistantMessageEventStream();
81
286
  const output = createAssistantMessageOutput(model);
@@ -93,178 +298,17 @@ export const streamOpenAICompletions = (model, context, options) => {
93
298
  baseDelayMs: options?.retryPolicy?.baseDelayMs ?? 250,
94
299
  });
95
300
  events.start();
96
- let currentBlock = null;
97
- const blocks = output.content;
98
- const blockIndex = () => blocks.length - 1;
99
- const finishCurrentBlock = (block) => {
100
- if (block) {
101
- if (block.type === "text") {
102
- stream.push({
103
- type: "text_end",
104
- contentIndex: blockIndex(),
105
- content: block.text,
106
- partial: output,
107
- });
108
- }
109
- else if (block.type === "thinking") {
110
- stream.push({
111
- type: "thinking_end",
112
- contentIndex: blockIndex(),
113
- content: block.thinking,
114
- partial: output,
115
- });
116
- }
117
- else if (block.type === "toolCall") {
118
- block.arguments = JSON.parse(block.partialArgs || "{}");
119
- delete block.partialArgs;
120
- stream.push({
121
- type: "toolcall_end",
122
- contentIndex: blockIndex(),
123
- toolCall: block,
124
- partial: output,
125
- });
126
- }
127
- }
128
- };
301
+ const lifecycle = new CompletionsBlockLifecycle(output, stream);
302
+ const chunkRouter = new CompletionsChunkRouter(model, output, lifecycle);
129
303
  for await (const chunk of openaiStream) {
130
- if (chunk.usage) {
131
- const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens || 0;
132
- const reasoningTokens = chunk.usage.completion_tokens_details?.reasoning_tokens || 0;
133
- const input = (chunk.usage.prompt_tokens || 0) - cachedTokens;
134
- const outputTokens = (chunk.usage.completion_tokens || 0) + reasoningTokens;
135
- output.usage = {
136
- // OpenAI includes cached tokens in prompt_tokens, so subtract to get non-cached input
137
- input,
138
- output: outputTokens,
139
- cacheRead: cachedTokens,
140
- cacheWrite: 0,
141
- // Compute totalTokens ourselves since we add reasoning_tokens to output
142
- // and some providers (e.g., Groq) don't include them in total_tokens
143
- totalTokens: input + outputTokens + cachedTokens,
144
- cost: {
145
- input: 0,
146
- output: 0,
147
- cacheRead: 0,
148
- cacheWrite: 0,
149
- total: 0,
150
- },
151
- };
152
- calculateCost(model, output.usage);
153
- }
304
+ chunkRouter.applyUsage(chunk);
154
305
  const choice = chunk.choices[0];
155
306
  if (!choice)
156
307
  continue;
157
- if (choice.finish_reason) {
158
- output.stopReason = mapProviderStopReason(choice.finish_reason, "openai-completions");
159
- }
160
- if (choice.delta) {
161
- if (choice.delta.content !== null &&
162
- choice.delta.content !== undefined &&
163
- choice.delta.content.length > 0) {
164
- if (!currentBlock || currentBlock.type !== "text") {
165
- finishCurrentBlock(currentBlock);
166
- currentBlock = { type: "text", text: "" };
167
- output.content.push(currentBlock);
168
- stream.push({ type: "text_start", contentIndex: blockIndex(), partial: output });
169
- }
170
- if (currentBlock.type === "text") {
171
- currentBlock.text += choice.delta.content;
172
- stream.push({
173
- type: "text_delta",
174
- contentIndex: blockIndex(),
175
- delta: choice.delta.content,
176
- partial: output,
177
- });
178
- }
179
- }
180
- // Some endpoints return reasoning in reasoning_content (llama.cpp),
181
- // or reasoning (other openai compatible endpoints)
182
- // Use the first non-empty reasoning field to avoid duplication
183
- // (e.g., chutes.ai returns both reasoning_content and reasoning with same content)
184
- const reasoningFields = ["reasoning_content", "reasoning", "reasoning_text"];
185
- let foundReasoningField = null;
186
- for (const field of reasoningFields) {
187
- if (choice.delta[field] !== null &&
188
- choice.delta[field] !== undefined &&
189
- choice.delta[field].length > 0) {
190
- if (!foundReasoningField) {
191
- foundReasoningField = field;
192
- break;
193
- }
194
- }
195
- }
196
- if (foundReasoningField) {
197
- if (!currentBlock || currentBlock.type !== "thinking") {
198
- finishCurrentBlock(currentBlock);
199
- currentBlock = {
200
- type: "thinking",
201
- thinking: "",
202
- thinkingSignature: foundReasoningField,
203
- };
204
- output.content.push(currentBlock);
205
- stream.push({ type: "thinking_start", contentIndex: blockIndex(), partial: output });
206
- }
207
- if (currentBlock.type === "thinking") {
208
- const delta = choice.delta[foundReasoningField];
209
- currentBlock.thinking += delta;
210
- stream.push({
211
- type: "thinking_delta",
212
- contentIndex: blockIndex(),
213
- delta,
214
- partial: output,
215
- });
216
- }
217
- }
218
- if (choice?.delta?.tool_calls) {
219
- for (const toolCall of choice.delta.tool_calls) {
220
- if (!currentBlock ||
221
- currentBlock.type !== "toolCall" ||
222
- (toolCall.id && currentBlock.id !== toolCall.id)) {
223
- finishCurrentBlock(currentBlock);
224
- currentBlock = {
225
- type: "toolCall",
226
- id: toolCall.id || "",
227
- name: toolCall.function?.name || "",
228
- arguments: {},
229
- partialArgs: "",
230
- };
231
- output.content.push(currentBlock);
232
- stream.push({ type: "toolcall_start", contentIndex: blockIndex(), partial: output });
233
- }
234
- if (currentBlock.type === "toolCall") {
235
- if (toolCall.id)
236
- currentBlock.id = toolCall.id;
237
- if (toolCall.function?.name)
238
- currentBlock.name = toolCall.function.name;
239
- let delta = "";
240
- if (toolCall.function?.arguments) {
241
- delta = toolCall.function.arguments;
242
- currentBlock.partialArgs += toolCall.function.arguments;
243
- currentBlock.arguments = parseStreamingJson(currentBlock.partialArgs);
244
- }
245
- stream.push({
246
- type: "toolcall_delta",
247
- contentIndex: blockIndex(),
248
- delta,
249
- partial: output,
250
- });
251
- }
252
- }
253
- }
254
- const reasoningDetails = choice.delta.reasoning_details;
255
- if (reasoningDetails && Array.isArray(reasoningDetails)) {
256
- for (const detail of reasoningDetails) {
257
- if (detail.type === "reasoning.encrypted" && detail.id && detail.data) {
258
- const matchingToolCall = output.content.find((b) => b.type === "toolCall" && b.id === detail.id);
259
- if (matchingToolCall) {
260
- matchingToolCall.thoughtSignature = JSON.stringify(detail);
261
- }
262
- }
263
- }
264
- }
265
- }
308
+ chunkRouter.applyFinishReason(choice);
309
+ chunkRouter.applyChoiceDelta(choice);
266
310
  }
267
- finishCurrentBlock(currentBlock);
311
+ lifecycle.finalizeCurrent();
268
312
  if (options?.signal?.aborted) {
269
313
  throw new Error("Request was aborted");
270
314
  }
@@ -423,218 +467,253 @@ function maybeAddOpenRouterAnthropicCacheControl(model, messages) {
423
467
  }
424
468
  }
425
469
  }
426
- export function convertMessages(model, context, compat) {
427
- const params = [];
428
- const normalizeToolCallId = (id) => {
429
- if (compat.requiresMistralToolIds)
430
- return normalizeMistralToolId(id);
431
- if (model.provider === "openai")
432
- return id.length > 40 ? id.slice(0, 40) : id;
433
- // Copilot Claude models route to Claude backend which requires Anthropic ID format
434
- if (model.provider === "github-copilot" && model.id.toLowerCase().includes("claude")) {
435
- return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
470
+ class UserMessageTransformer {
471
+ model;
472
+ constructor(model) {
473
+ this.model = model;
474
+ }
475
+ transform(message) {
476
+ if (typeof message.content === "string") {
477
+ return {
478
+ role: "user",
479
+ content: sanitizeSurrogates(message.content),
480
+ };
436
481
  }
437
- return id;
438
- };
439
- const transformedMessages = transformMessages(context.messages, model, (id) => normalizeToolCallId(id));
440
- if (context.systemPrompt) {
441
- const useDeveloperRole = model.reasoning && compat.supportsDeveloperRole;
442
- const role = useDeveloperRole ? "developer" : "system";
443
- params.push({ role: role, content: sanitizeSurrogates(context.systemPrompt) });
444
- }
445
- let lastRole = null;
446
- for (let i = 0; i < transformedMessages.length; i++) {
447
- const msg = transformedMessages[i];
448
- // Some providers (e.g. Mistral/Devstral) don't allow user messages directly after tool results
449
- // Insert a synthetic assistant message to bridge the gap
450
- if (compat.requiresAssistantAfterToolResult && lastRole === "toolResult" && msg.role === "user") {
451
- params.push({
452
- role: "assistant",
453
- content: "I have processed the tool results.",
454
- });
482
+ const contentParts = message.content.map((item) => {
483
+ if (item.type === "text") {
484
+ return {
485
+ type: "text",
486
+ text: sanitizeSurrogates(item.text),
487
+ };
488
+ }
489
+ return {
490
+ type: "image_url",
491
+ image_url: {
492
+ url: `data:${item.mimeType};base64,${item.data}`,
493
+ },
494
+ };
495
+ });
496
+ const filteredParts = !this.model.input.includes("image")
497
+ ? contentParts.filter((part) => part.type !== "image_url")
498
+ : contentParts;
499
+ if (filteredParts.length === 0) {
500
+ return undefined;
455
501
  }
456
- if (msg.role === "user") {
457
- if (typeof msg.content === "string") {
458
- params.push({
459
- role: "user",
460
- content: sanitizeSurrogates(msg.content),
461
- });
502
+ return {
503
+ role: "user",
504
+ content: filteredParts,
505
+ };
506
+ }
507
+ }
508
+ class AssistantMessageTransformer {
509
+ model;
510
+ compat;
511
+ constructor(model, compat) {
512
+ this.model = model;
513
+ this.compat = compat;
514
+ }
515
+ transform(message) {
516
+ const assistantMessage = {
517
+ role: "assistant",
518
+ content: this.compat.requiresAssistantAfterToolResult ? "" : null,
519
+ };
520
+ const textBlocks = message.content.filter((block) => block.type === "text");
521
+ const nonEmptyTextBlocks = textBlocks.filter((block) => block.text && block.text.trim().length > 0);
522
+ if (nonEmptyTextBlocks.length > 0) {
523
+ if (this.model.provider === "github-copilot") {
524
+ assistantMessage.content = nonEmptyTextBlocks.map((block) => sanitizeSurrogates(block.text)).join("");
462
525
  }
463
526
  else {
464
- const content = msg.content.map((item) => {
465
- if (item.type === "text") {
466
- return {
467
- type: "text",
468
- text: sanitizeSurrogates(item.text),
469
- };
470
- }
471
- else {
472
- return {
473
- type: "image_url",
474
- image_url: {
475
- url: `data:${item.mimeType};base64,${item.data}`,
476
- },
477
- };
478
- }
479
- });
480
- const filteredContent = !model.input.includes("image")
481
- ? content.filter((c) => c.type !== "image_url")
482
- : content;
483
- if (filteredContent.length === 0)
484
- continue;
485
- params.push({
486
- role: "user",
487
- content: filteredContent,
488
- });
527
+ assistantMessage.content = nonEmptyTextBlocks.map((block) => ({
528
+ type: "text",
529
+ text: sanitizeSurrogates(block.text),
530
+ }));
489
531
  }
490
532
  }
491
- else if (msg.role === "assistant") {
492
- // Some providers (e.g. Mistral) don't accept null content, use empty string instead
493
- const assistantMsg = {
494
- role: "assistant",
495
- content: compat.requiresAssistantAfterToolResult ? "" : null,
496
- };
497
- const textBlocks = msg.content.filter((b) => b.type === "text");
498
- // Filter out empty text blocks to avoid API validation errors
499
- const nonEmptyTextBlocks = textBlocks.filter((b) => b.text && b.text.trim().length > 0);
500
- if (nonEmptyTextBlocks.length > 0) {
501
- // GitHub Copilot requires assistant content as a string, not an array.
502
- // Sending as array causes Claude models to re-answer all previous prompts.
503
- if (model.provider === "github-copilot") {
504
- assistantMsg.content = nonEmptyTextBlocks.map((b) => sanitizeSurrogates(b.text)).join("");
533
+ const thinkingBlocks = message.content.filter((block) => block.type === "thinking");
534
+ const nonEmptyThinkingBlocks = thinkingBlocks.filter((block) => block.thinking && block.thinking.trim().length > 0);
535
+ if (nonEmptyThinkingBlocks.length > 0) {
536
+ this.applyThinkingBlocks(assistantMessage, nonEmptyThinkingBlocks);
537
+ }
538
+ const toolCalls = message.content.filter((block) => block.type === "toolCall");
539
+ if (toolCalls.length > 0) {
540
+ assistantMessage.tool_calls = toolCalls.map((toolCall) => ({
541
+ id: toolCall.id,
542
+ type: "function",
543
+ function: {
544
+ name: toolCall.name,
545
+ arguments: JSON.stringify(toolCall.arguments),
546
+ },
547
+ }));
548
+ const reasoningDetails = toolCalls
549
+ .filter((toolCall) => toolCall.thoughtSignature)
550
+ .map((toolCall) => {
551
+ try {
552
+ return JSON.parse(toolCall.thoughtSignature);
505
553
  }
506
- else {
507
- assistantMsg.content = nonEmptyTextBlocks.map((b) => {
508
- return { type: "text", text: sanitizeSurrogates(b.text) };
509
- });
554
+ catch {
555
+ return null;
510
556
  }
557
+ })
558
+ .filter(Boolean);
559
+ if (reasoningDetails.length > 0) {
560
+ assistantMessage.reasoning_details = reasoningDetails;
511
561
  }
512
- // Handle thinking blocks
513
- const thinkingBlocks = msg.content.filter((b) => b.type === "thinking");
514
- // Filter out empty thinking blocks to avoid API validation errors
515
- const nonEmptyThinkingBlocks = thinkingBlocks.filter((b) => b.thinking && b.thinking.trim().length > 0);
516
- if (nonEmptyThinkingBlocks.length > 0) {
517
- if (compat.requiresThinkingAsText) {
518
- // Convert thinking blocks to plain text (no tags to avoid model mimicking them)
519
- const thinkingText = nonEmptyThinkingBlocks.map((b) => b.thinking).join("\n\n");
520
- const textContent = assistantMsg.content;
521
- if (textContent) {
522
- textContent.unshift({ type: "text", text: thinkingText });
523
- }
524
- else {
525
- assistantMsg.content = [{ type: "text", text: thinkingText }];
526
- }
527
- }
528
- else {
529
- // Use the signature from the first thinking block if available (for llama.cpp server + gpt-oss)
530
- const signature = nonEmptyThinkingBlocks[0].thinkingSignature;
531
- if (signature && signature.length > 0) {
532
- assistantMsg[signature] = nonEmptyThinkingBlocks.map((b) => b.thinking).join("\n");
533
- }
534
- }
562
+ }
563
+ const content = assistantMessage.content;
564
+ const hasContent = content !== null &&
565
+ content !== undefined &&
566
+ (typeof content === "string" ? content.length > 0 : content.length > 0);
567
+ if (!hasContent && !assistantMessage.tool_calls) {
568
+ return undefined;
569
+ }
570
+ return assistantMessage;
571
+ }
572
+ applyThinkingBlocks(assistantMessage, nonEmptyThinkingBlocks) {
573
+ if (this.compat.requiresThinkingAsText) {
574
+ const thinkingText = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n\n");
575
+ const textContent = assistantMessage.content;
576
+ if (textContent) {
577
+ textContent.unshift({ type: "text", text: thinkingText });
535
578
  }
536
- const toolCalls = msg.content.filter((b) => b.type === "toolCall");
537
- if (toolCalls.length > 0) {
538
- assistantMsg.tool_calls = toolCalls.map((tc) => ({
539
- id: tc.id,
540
- type: "function",
541
- function: {
542
- name: tc.name,
543
- arguments: JSON.stringify(tc.arguments),
544
- },
545
- }));
546
- const reasoningDetails = toolCalls
547
- .filter((tc) => tc.thoughtSignature)
548
- .map((tc) => {
549
- try {
550
- return JSON.parse(tc.thoughtSignature);
551
- }
552
- catch {
553
- return null;
554
- }
555
- })
556
- .filter(Boolean);
557
- if (reasoningDetails.length > 0) {
558
- assistantMsg.reasoning_details = reasoningDetails;
559
- }
579
+ else {
580
+ assistantMessage.content = [{ type: "text", text: thinkingText }];
560
581
  }
561
- // Skip assistant messages that have no content and no tool calls.
562
- // Mistral explicitly requires "either content or tool_calls, but not none".
563
- // Other providers also don't accept empty assistant messages.
564
- // This handles aborted assistant responses that got no content.
565
- const content = assistantMsg.content;
566
- const hasContent = content !== null &&
567
- content !== undefined &&
568
- (typeof content === "string" ? content.length > 0 : content.length > 0);
569
- if (!hasContent && !assistantMsg.tool_calls) {
570
- continue;
582
+ return;
583
+ }
584
+ const signature = nonEmptyThinkingBlocks[0].thinkingSignature;
585
+ if (signature && signature.length > 0) {
586
+ assistantMessage[signature] = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n");
587
+ }
588
+ }
589
+ }
590
+ class ToolResultTransformer {
591
+ model;
592
+ compat;
593
+ constructor(model, compat) {
594
+ this.model = model;
595
+ this.compat = compat;
596
+ }
597
+ transform(messages, startIndex) {
598
+ const params = [];
599
+ const imageBlocks = [];
600
+ let cursor = startIndex;
601
+ for (; cursor < messages.length && messages[cursor].role === "toolResult"; cursor++) {
602
+ const toolMessage = messages[cursor];
603
+ const textResult = toolMessage.content
604
+ .filter((entry) => entry.type === "text")
605
+ .map((entry) => entry.text)
606
+ .join("\n");
607
+ const hasImages = toolMessage.content.some((entry) => entry.type === "image");
608
+ const hasText = textResult.length > 0;
609
+ const toolResultMessage = {
610
+ role: "tool",
611
+ content: sanitizeSurrogates(hasText ? textResult : "(see attached image)"),
612
+ tool_call_id: toolMessage.toolCallId,
613
+ };
614
+ if (this.compat.requiresToolResultName && toolMessage.toolName) {
615
+ toolResultMessage.name = toolMessage.toolName;
571
616
  }
572
- params.push(assistantMsg);
573
- }
574
- else if (msg.role === "toolResult") {
575
- const imageBlocks = [];
576
- let j = i;
577
- for (; j < transformedMessages.length && transformedMessages[j].role === "toolResult"; j++) {
578
- const toolMsg = transformedMessages[j];
579
- // Extract text and image content
580
- const textResult = toolMsg.content
581
- .filter((c) => c.type === "text")
582
- .map((c) => c.text)
583
- .join("\n");
584
- const hasImages = toolMsg.content.some((c) => c.type === "image");
585
- // Always send tool result with text (or placeholder if only images)
586
- const hasText = textResult.length > 0;
587
- // Some providers (e.g. Mistral) require the 'name' field in tool results
588
- const toolResultMsg = {
589
- role: "tool",
590
- content: sanitizeSurrogates(hasText ? textResult : "(see attached image)"),
591
- tool_call_id: toolMsg.toolCallId,
592
- };
593
- if (compat.requiresToolResultName && toolMsg.toolName) {
594
- toolResultMsg.name = toolMsg.toolName;
595
- }
596
- params.push(toolResultMsg);
597
- if (hasImages && model.input.includes("image")) {
598
- for (const block of toolMsg.content) {
599
- if (block.type === "image") {
600
- imageBlocks.push({
601
- type: "image_url",
602
- image_url: {
603
- url: `data:${block.mimeType};base64,${block.data}`,
604
- },
605
- });
606
- }
617
+ params.push(toolResultMessage);
618
+ if (hasImages && this.model.input.includes("image")) {
619
+ for (const block of toolMessage.content) {
620
+ if (block.type === "image") {
621
+ imageBlocks.push({
622
+ type: "image_url",
623
+ image_url: {
624
+ url: `data:${block.mimeType};base64,${block.data}`,
625
+ },
626
+ });
607
627
  }
608
628
  }
609
629
  }
610
- i = j - 1;
611
- if (imageBlocks.length > 0) {
612
- if (compat.requiresAssistantAfterToolResult) {
613
- params.push({
614
- role: "assistant",
615
- content: "I have processed the tool results.",
616
- });
630
+ }
631
+ if (imageBlocks.length === 0) {
632
+ return { params, nextIndex: cursor - 1, lastRole: "toolResult" };
633
+ }
634
+ if (this.compat.requiresAssistantAfterToolResult) {
635
+ params.push({
636
+ role: "assistant",
637
+ content: "I have processed the tool results.",
638
+ });
639
+ }
640
+ params.push({
641
+ role: "user",
642
+ content: [
643
+ {
644
+ type: "text",
645
+ text: "Attached image(s) from tool result:",
646
+ },
647
+ ...imageBlocks,
648
+ ],
649
+ });
650
+ return { params, nextIndex: cursor - 1, lastRole: "user" };
651
+ }
652
+ }
653
+ class OpenAIMessageTransformer {
654
+ model;
655
+ context;
656
+ compat;
657
+ userTransformer;
658
+ assistantTransformer;
659
+ toolResultTransformer;
660
+ constructor(model, context, compat) {
661
+ this.model = model;
662
+ this.context = context;
663
+ this.compat = compat;
664
+ this.userTransformer = new UserMessageTransformer(model);
665
+ this.assistantTransformer = new AssistantMessageTransformer(model, compat);
666
+ this.toolResultTransformer = new ToolResultTransformer(model, compat);
667
+ }
668
+ transform() {
669
+ const params = [];
670
+ const transformedMessages = transformMessages(this.context.messages, this.model, (id) => this.normalizeToolCallId(id));
671
+ if (this.context.systemPrompt) {
672
+ const role = this.model.reasoning && this.compat.supportsDeveloperRole ? "developer" : "system";
673
+ params.push({ role, content: sanitizeSurrogates(this.context.systemPrompt) });
674
+ }
675
+ let lastRole = null;
676
+ for (let i = 0; i < transformedMessages.length; i++) {
677
+ const message = transformedMessages[i];
678
+ if (this.compat.requiresAssistantAfterToolResult && lastRole === "toolResult" && message.role === "user") {
679
+ params.push({ role: "assistant", content: "I have processed the tool results." });
680
+ }
681
+ if (message.role === "user") {
682
+ const transformed = this.userTransformer.transform(message);
683
+ if (transformed) {
684
+ params.push(transformed);
685
+ lastRole = "user";
617
686
  }
618
- params.push({
619
- role: "user",
620
- content: [
621
- {
622
- type: "text",
623
- text: "Attached image(s) from tool result:",
624
- },
625
- ...imageBlocks,
626
- ],
627
- });
628
- lastRole = "user";
687
+ continue;
629
688
  }
630
- else {
631
- lastRole = "toolResult";
689
+ if (message.role === "assistant") {
690
+ const transformed = this.assistantTransformer.transform(message);
691
+ if (transformed) {
692
+ params.push(transformed);
693
+ lastRole = "assistant";
694
+ }
695
+ continue;
632
696
  }
633
- continue;
697
+ const toolResultBatch = this.toolResultTransformer.transform(transformedMessages, i);
698
+ params.push(...toolResultBatch.params);
699
+ i = toolResultBatch.nextIndex;
700
+ lastRole = toolResultBatch.lastRole;
634
701
  }
635
- lastRole = msg.role;
702
+ return params;
636
703
  }
637
- return params;
704
+ normalizeToolCallId(id) {
705
+ if (this.compat.requiresMistralToolIds)
706
+ return normalizeMistralToolId(id);
707
+ if (this.model.provider === "openai")
708
+ return id.length > 40 ? id.slice(0, 40) : id;
709
+ if (this.model.provider === "github-copilot" && this.model.id.toLowerCase().includes("claude")) {
710
+ return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
711
+ }
712
+ return id;
713
+ }
714
+ }
715
+ export function convertMessages(model, context, compat) {
716
+ return new OpenAIMessageTransformer(model, context, compat).transform();
638
717
  }
639
718
  function convertTools(tools) {
640
719
  return tools.map((tool) => ({
@@ -669,59 +748,61 @@ function mapStopReason(reason) {
669
748
  /**
670
749
  * Detect compatibility settings from provider and baseUrl for known providers.
671
750
  * Provider takes precedence over URL-based detection since it's explicitly configured.
672
- * Returns a fully resolved OpenAICompletionsCompat object with all fields set.
673
751
  */
674
- function detectCompat(model) {
752
+ function deriveCompatFromProvider(model) {
675
753
  const provider = model.provider;
676
754
  const baseUrl = model.baseUrl;
677
755
  const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
678
- const isNonStandard = provider === "cerebras" ||
756
+ const isMistral = provider === "mistral" || baseUrl.includes("mistral.ai");
757
+ const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
758
+ const isNonStandardProvider = provider === "cerebras" ||
679
759
  baseUrl.includes("cerebras.ai") ||
680
760
  provider === "xai" ||
681
761
  baseUrl.includes("api.x.ai") ||
682
- provider === "mistral" ||
683
- baseUrl.includes("mistral.ai") ||
762
+ isMistral ||
684
763
  baseUrl.includes("chutes.ai") ||
685
764
  isZai ||
686
765
  provider === "opencode" ||
687
766
  baseUrl.includes("opencode.ai");
688
- const useMaxTokens = provider === "mistral" || baseUrl.includes("mistral.ai") || baseUrl.includes("chutes.ai");
689
- const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
690
- const isMistral = provider === "mistral" || baseUrl.includes("mistral.ai");
767
+ const useLegacyMaxTokensField = isMistral || baseUrl.includes("chutes.ai");
691
768
  return {
692
- supportsStore: !isNonStandard,
693
- supportsDeveloperRole: !isNonStandard,
769
+ supportsStore: !isNonStandardProvider,
770
+ supportsDeveloperRole: !isNonStandardProvider,
694
771
  supportsReasoningEffort: !isGrok && !isZai,
695
772
  supportsUsageInStreaming: true,
696
- maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
773
+ maxTokensField: useLegacyMaxTokensField ? "max_tokens" : "max_completion_tokens",
697
774
  requiresToolResultName: isMistral,
698
- requiresAssistantAfterToolResult: false, // Mistral no longer requires this as of Dec 2024
775
+ requiresAssistantAfterToolResult: false,
699
776
  requiresThinkingAsText: isMistral,
700
777
  requiresMistralToolIds: isMistral,
701
778
  thinkingFormat: isZai ? "zai" : "openai",
702
779
  openRouterRouting: {},
703
780
  };
704
781
  }
782
+ function overlayCompatOverrides(base, overrides) {
783
+ if (!overrides) {
784
+ return base;
785
+ }
786
+ return {
787
+ supportsStore: overrides.supportsStore ?? base.supportsStore,
788
+ supportsDeveloperRole: overrides.supportsDeveloperRole ?? base.supportsDeveloperRole,
789
+ supportsReasoningEffort: overrides.supportsReasoningEffort ?? base.supportsReasoningEffort,
790
+ supportsUsageInStreaming: overrides.supportsUsageInStreaming ?? base.supportsUsageInStreaming,
791
+ maxTokensField: overrides.maxTokensField ?? base.maxTokensField,
792
+ requiresToolResultName: overrides.requiresToolResultName ?? base.requiresToolResultName,
793
+ requiresAssistantAfterToolResult: overrides.requiresAssistantAfterToolResult ?? base.requiresAssistantAfterToolResult,
794
+ requiresThinkingAsText: overrides.requiresThinkingAsText ?? base.requiresThinkingAsText,
795
+ requiresMistralToolIds: overrides.requiresMistralToolIds ?? base.requiresMistralToolIds,
796
+ thinkingFormat: overrides.thinkingFormat ?? base.thinkingFormat,
797
+ openRouterRouting: overrides.openRouterRouting ?? {},
798
+ };
799
+ }
705
800
  /**
706
801
  * Get resolved compatibility settings for a model.
707
802
  * Uses explicit model.compat if provided, otherwise auto-detects from provider/URL.
708
803
  */
709
804
  function getCompat(model) {
710
- const detected = detectCompat(model);
711
- if (!model.compat)
712
- return detected;
713
- return {
714
- supportsStore: model.compat.supportsStore ?? detected.supportsStore,
715
- supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
716
- supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
717
- supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
718
- maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
719
- requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
720
- requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
721
- requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
722
- requiresMistralToolIds: model.compat.requiresMistralToolIds ?? detected.requiresMistralToolIds,
723
- thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
724
- openRouterRouting: model.compat.openRouterRouting ?? {},
725
- };
805
+ const derived = deriveCompatFromProvider(model);
806
+ return overlayCompatOverrides(derived, model.compat);
726
807
  }
727
808
  //# sourceMappingURL=openai-completions.js.map