@ebowwa/coder 0.7.63 → 0.7.64

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 (341) hide show
  1. package/dist/core/__tests__/permissions.test.d.ts +12 -0
  2. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  3. package/dist/core/__tests__/permissions.test.js +851 -0
  4. package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
  5. package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
  6. package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
  7. package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
  8. package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
  9. package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
  10. package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
  11. package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
  12. package/dist/core/agent-loop/__tests__/index.test.js +121 -0
  13. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
  14. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
  15. package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
  16. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
  17. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
  18. package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
  19. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
  20. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
  21. package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
  22. package/dist/core/agent-loop/compaction.d.ts +39 -0
  23. package/dist/core/agent-loop/compaction.d.ts.map +1 -0
  24. package/dist/core/agent-loop/compaction.js +51 -0
  25. package/dist/core/agent-loop/formatters.d.ts +21 -0
  26. package/dist/core/agent-loop/formatters.d.ts.map +1 -0
  27. package/dist/core/agent-loop/formatters.js +42 -0
  28. package/dist/core/agent-loop/index.d.ts +25 -0
  29. package/dist/core/agent-loop/index.d.ts.map +1 -0
  30. package/dist/core/agent-loop/index.js +83 -0
  31. package/dist/core/agent-loop/loop-state.d.ts +74 -0
  32. package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
  33. package/dist/core/agent-loop/loop-state.js +147 -0
  34. package/dist/core/agent-loop/message-builder.d.ts +13 -0
  35. package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
  36. package/dist/core/agent-loop/message-builder.js +49 -0
  37. package/dist/core/agent-loop/tool-executor.d.ts +23 -0
  38. package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
  39. package/dist/core/agent-loop/tool-executor.js +152 -0
  40. package/dist/core/agent-loop/turn-executor.d.ts +57 -0
  41. package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
  42. package/dist/core/agent-loop/turn-executor.js +124 -0
  43. package/dist/core/agent-loop/types.d.ts +141 -0
  44. package/dist/core/agent-loop/types.d.ts.map +1 -0
  45. package/dist/core/agent-loop/types.js +4 -0
  46. package/dist/core/agent-loop.d.ts +17 -0
  47. package/dist/core/agent-loop.d.ts.map +1 -0
  48. package/dist/core/agent-loop.js +16 -0
  49. package/dist/core/api-client-impl.d.ts +62 -0
  50. package/dist/core/api-client-impl.d.ts.map +1 -0
  51. package/dist/core/api-client-impl.js +479 -0
  52. package/dist/core/api-client.d.ts +6 -0
  53. package/dist/core/api-client.d.ts.map +1 -0
  54. package/dist/core/api-client.js +5 -0
  55. package/dist/core/checkpoints.d.ts +128 -0
  56. package/dist/core/checkpoints.d.ts.map +1 -0
  57. package/dist/core/checkpoints.js +438 -0
  58. package/dist/core/claude-md.d.ts +71 -0
  59. package/dist/core/claude-md.d.ts.map +1 -0
  60. package/dist/core/claude-md.js +198 -0
  61. package/dist/core/cognitive-security/hooks.d.ts +138 -0
  62. package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
  63. package/dist/core/cognitive-security/hooks.js +389 -0
  64. package/dist/core/cognitive-security/index.d.ts +751 -0
  65. package/dist/core/cognitive-security/index.d.ts.map +1 -0
  66. package/dist/core/cognitive-security/index.js +1123 -0
  67. package/dist/core/cognitive-security/middleware.d.ts +136 -0
  68. package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
  69. package/dist/core/cognitive-security/middleware.js +376 -0
  70. package/dist/core/config-loader.d.ts +127 -0
  71. package/dist/core/config-loader.d.ts.map +1 -0
  72. package/dist/core/config-loader.js +219 -0
  73. package/dist/core/context-compaction.d.ts +87 -0
  74. package/dist/core/context-compaction.d.ts.map +1 -0
  75. package/dist/core/context-compaction.js +428 -0
  76. package/dist/core/git-status.d.ts +25 -0
  77. package/dist/core/git-status.d.ts.map +1 -0
  78. package/dist/core/git-status.js +204 -0
  79. package/dist/core/image.d.ts +69 -0
  80. package/dist/core/image.d.ts.map +1 -0
  81. package/dist/core/image.js +290 -0
  82. package/dist/core/image.test.d.ts +2 -0
  83. package/dist/core/image.test.d.ts.map +1 -0
  84. package/dist/core/image.test.js +149 -0
  85. package/dist/core/models.d.ts +123 -0
  86. package/dist/core/models.d.ts.map +1 -0
  87. package/dist/core/models.js +325 -0
  88. package/dist/core/permissions.d.ts +81 -0
  89. package/dist/core/permissions.d.ts.map +1 -0
  90. package/dist/core/permissions.js +327 -0
  91. package/dist/core/retry.d.ts +25 -0
  92. package/dist/core/retry.d.ts.map +1 -0
  93. package/dist/core/retry.js +121 -0
  94. package/dist/core/session-store.d.ts +9 -0
  95. package/dist/core/session-store.d.ts.map +1 -0
  96. package/dist/core/session-store.js +10 -0
  97. package/dist/core/sessions/export.d.ts +47 -0
  98. package/dist/core/sessions/export.d.ts.map +1 -0
  99. package/dist/core/sessions/export.js +256 -0
  100. package/dist/core/sessions/index.d.ts +132 -0
  101. package/dist/core/sessions/index.d.ts.map +1 -0
  102. package/dist/core/sessions/index.js +442 -0
  103. package/dist/core/sessions/metadata.d.ts +77 -0
  104. package/dist/core/sessions/metadata.d.ts.map +1 -0
  105. package/dist/core/sessions/metadata.js +233 -0
  106. package/dist/core/sessions/persistence.d.ts +72 -0
  107. package/dist/core/sessions/persistence.d.ts.map +1 -0
  108. package/dist/core/sessions/persistence.js +201 -0
  109. package/dist/core/sessions/types.d.ts +110 -0
  110. package/dist/core/sessions/types.d.ts.map +1 -0
  111. package/dist/core/sessions/types.js +4 -0
  112. package/dist/core/stream-highlighter.d.ts +18 -0
  113. package/dist/core/stream-highlighter.d.ts.map +1 -0
  114. package/dist/core/stream-highlighter.js +916 -0
  115. package/dist/core/system-reminders.d.ts +89 -0
  116. package/dist/core/system-reminders.d.ts.map +1 -0
  117. package/dist/core/system-reminders.js +285 -0
  118. package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
  119. package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
  120. package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
  121. package/dist/ecosystem/hooks/index.d.ts +59 -0
  122. package/dist/ecosystem/hooks/index.d.ts.map +1 -0
  123. package/dist/ecosystem/hooks/index.js +294 -0
  124. package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
  125. package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
  126. package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
  127. package/dist/ecosystem/skills/index.d.ts +55 -0
  128. package/dist/ecosystem/skills/index.d.ts.map +1 -0
  129. package/dist/ecosystem/skills/index.js +258 -0
  130. package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
  131. package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
  132. package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
  133. package/dist/ecosystem/tools/index.d.ts +24 -0
  134. package/dist/ecosystem/tools/index.d.ts.map +1 -0
  135. package/dist/ecosystem/tools/index.js +1709 -0
  136. package/dist/index.d.ts +24 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +32 -52192
  139. package/dist/interfaces/mcp/client.d.ts +40 -0
  140. package/dist/interfaces/mcp/client.d.ts.map +1 -0
  141. package/dist/interfaces/mcp/client.js +309 -0
  142. package/dist/interfaces/ui/index.d.ts +36 -0
  143. package/dist/interfaces/ui/index.d.ts.map +1 -0
  144. package/dist/interfaces/ui/index.js +61 -0
  145. package/dist/interfaces/ui/spinner.d.ts +140 -0
  146. package/dist/interfaces/ui/spinner.d.ts.map +1 -0
  147. package/dist/interfaces/ui/spinner.js +342 -0
  148. package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
  149. package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
  150. package/dist/interfaces/ui/terminal/cli/index.js +159 -52768
  151. package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
  152. package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
  153. package/dist/interfaces/ui/terminal/shared/args.js +176 -0
  154. package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
  155. package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
  156. package/dist/interfaces/ui/terminal/shared/index.js +16 -0
  157. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
  158. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
  159. package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
  160. package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
  161. package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
  162. package/dist/interfaces/ui/terminal/shared/query.js +100 -0
  163. package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
  164. package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
  165. package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
  166. package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
  167. package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
  168. package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
  169. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
  170. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
  171. package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
  172. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
  173. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
  174. package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
  175. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
  176. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
  177. package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
  178. package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
  179. package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
  180. package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
  181. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
  182. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
  183. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
  184. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
  185. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
  186. package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
  187. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
  188. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
  189. package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
  190. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
  191. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
  192. package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
  193. package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
  194. package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
  195. package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
  196. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
  197. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
  198. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
  199. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
  200. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
  201. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
  202. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
  203. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
  204. package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
  205. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
  206. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
  207. package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
  208. package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
  209. package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
  210. package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
  211. package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
  212. package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
  213. package/dist/interfaces/ui/terminal/tui/console.js +46 -0
  214. package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
  215. package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
  216. package/dist/interfaces/ui/terminal/tui/index.js +28 -0
  217. package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
  218. package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
  219. package/dist/interfaces/ui/terminal/tui/run.js +31 -0
  220. package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
  221. package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
  222. package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
  223. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
  224. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
  225. package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
  226. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
  227. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
  228. package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
  229. package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
  230. package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
  231. package/dist/interfaces/ui/terminal/tui/types.js +5 -0
  232. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
  233. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
  234. package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
  235. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
  236. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
  237. package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
  238. package/dist/native/index.d.ts +480 -0
  239. package/dist/native/index.d.ts.map +1 -0
  240. package/dist/native/index.js +1625 -0
  241. package/dist/teammates/index.d.ts +161 -0
  242. package/dist/teammates/index.d.ts.map +1 -0
  243. package/dist/teammates/index.js +827 -0
  244. package/dist/types/index.d.ts +482 -0
  245. package/dist/types/index.d.ts.map +1 -0
  246. package/dist/types/index.js +52 -0
  247. package/package.json +4 -2
  248. package/packages/src/core/__tests__/permissions.test.ts +1091 -0
  249. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +280 -0
  250. package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
  251. package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
  252. package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
  253. package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
  254. package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
  255. package/packages/src/core/agent-loop/compaction.ts +88 -0
  256. package/packages/src/core/agent-loop/formatters.ts +50 -0
  257. package/packages/src/core/agent-loop/index.ts +135 -0
  258. package/packages/src/core/agent-loop/loop-state.ts +187 -0
  259. package/packages/src/core/agent-loop/message-builder.ts +62 -0
  260. package/packages/src/core/agent-loop/tool-executor.ts +211 -0
  261. package/packages/src/core/agent-loop/turn-executor.ts +222 -0
  262. package/packages/src/core/agent-loop/types.ts +148 -0
  263. package/packages/src/core/agent-loop.ts +18 -0
  264. package/packages/src/core/api-client-impl.ts +619 -0
  265. package/packages/src/core/api-client.ts +6 -0
  266. package/packages/src/core/checkpoints.ts +606 -0
  267. package/packages/src/core/claude-md.ts +272 -0
  268. package/packages/src/core/cognitive-security/hooks.ts +590 -0
  269. package/packages/src/core/cognitive-security/index.ts +2041 -0
  270. package/packages/src/core/cognitive-security/middleware.ts +536 -0
  271. package/packages/src/core/config-loader.ts +324 -0
  272. package/packages/src/core/context-compaction.ts +578 -0
  273. package/packages/src/core/git-status.ts +262 -0
  274. package/packages/src/core/image.test.ts +180 -0
  275. package/packages/src/core/image.ts +350 -0
  276. package/packages/src/core/lmdb.db +0 -0
  277. package/packages/src/core/lmdb.db-lock +0 -0
  278. package/packages/src/core/models.ts +430 -0
  279. package/packages/src/core/normalizers/todo +4 -0
  280. package/packages/src/core/permissions.ts +431 -0
  281. package/packages/src/core/retry.ts +170 -0
  282. package/packages/src/core/session-store.ts +36 -0
  283. package/packages/src/core/sessions/export.ts +329 -0
  284. package/packages/src/core/sessions/index.ts +587 -0
  285. package/packages/src/core/sessions/metadata.ts +309 -0
  286. package/packages/src/core/sessions/persistence.ts +244 -0
  287. package/packages/src/core/sessions/types.ts +169 -0
  288. package/packages/src/core/stream-highlighter.ts +1123 -0
  289. package/packages/src/core/system-reminders.ts +402 -0
  290. package/packages/src/core/todo +8 -0
  291. package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
  292. package/packages/src/ecosystem/hooks/index.ts +341 -0
  293. package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
  294. package/packages/src/ecosystem/skills/index.ts +295 -0
  295. package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
  296. package/packages/src/ecosystem/tools/index.ts +1877 -0
  297. package/packages/src/index.ts +120 -0
  298. package/packages/src/interfaces/mcp/client.ts +389 -0
  299. package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
  300. package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
  301. package/packages/src/interfaces/ui/index.ts +161 -0
  302. package/packages/src/interfaces/ui/lmdb.db +0 -0
  303. package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
  304. package/packages/src/interfaces/ui/spinner.ts +451 -0
  305. package/packages/src/interfaces/ui/terminal/cli/index.ts +228 -0
  306. package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
  307. package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
  308. package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
  309. package/packages/src/interfaces/ui/terminal/shared/index.ts +71 -0
  310. package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
  311. package/packages/src/interfaces/ui/terminal/shared/query.ts +146 -0
  312. package/packages/src/interfaces/ui/terminal/shared/setup.ts +295 -0
  313. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +358 -0
  314. package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
  315. package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +262 -0
  316. package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +232 -0
  317. package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +62 -0
  318. package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +537 -0
  319. package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +107 -0
  320. package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +240 -0
  321. package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +54 -0
  322. package/packages/src/interfaces/ui/terminal/tui/commands.ts +438 -0
  323. package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +584 -0
  324. package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +614 -0
  325. package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +333 -0
  326. package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +604 -0
  327. package/packages/src/interfaces/ui/terminal/tui/components/index.ts +118 -0
  328. package/packages/src/interfaces/ui/terminal/tui/console.ts +49 -0
  329. package/packages/src/interfaces/ui/terminal/tui/index.ts +90 -0
  330. package/packages/src/interfaces/ui/terminal/tui/run.tsx +42 -0
  331. package/packages/src/interfaces/ui/terminal/tui/spinner.ts +69 -0
  332. package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +390 -0
  333. package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +422 -0
  334. package/packages/src/interfaces/ui/terminal/tui/types.ts +186 -0
  335. package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +104 -0
  336. package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +239 -0
  337. package/packages/src/lmdb.db +0 -0
  338. package/packages/src/lmdb.db-lock +0 -0
  339. package/packages/src/native/index.ts +2345 -0
  340. package/packages/src/teammates/index.ts +982 -0
  341. package/packages/src/types/index.ts +722 -0
@@ -0,0 +1,619 @@
1
+ /**
2
+ * API Client - SSE streaming for LLM APIs
3
+ */
4
+
5
+ import type {
6
+ Message,
7
+ ContentBlock,
8
+ ToolUseBlock,
9
+ UsageMetrics,
10
+ APIRequest,
11
+ APIResponse,
12
+ APITool,
13
+ JSONSchema,
14
+ CacheConfig,
15
+ CacheControl,
16
+ CacheMetrics,
17
+ SystemBlock,
18
+ ThinkingConfig,
19
+ ExtendedThinkingConfig,
20
+ EffortLevel,
21
+ RedactedThinkingBlock,
22
+ StopReason,
23
+ } from "../types/index.js";
24
+ import {
25
+ DEFAULT_CACHE_CONFIG,
26
+ calculateBudgetTokens,
27
+ supportsExtendedThinking as supportsThinkingType,
28
+ EFFORT_TO_BUDGET,
29
+ } from "../types/index.js";
30
+ import { withRetry, parseRetryAfter, type RetryOptions } from "./retry.js";
31
+ import {
32
+ calculateCost as calculateModelCost,
33
+ DEFAULT_MODEL,
34
+ supportsExtendedThinking,
35
+ } from "./models.js";
36
+
37
+ export interface StreamOptions {
38
+ apiKey: string;
39
+ model?: string;
40
+ maxTokens?: number;
41
+ tools?: APITool[];
42
+ systemPrompt?: string | SystemBlock[];
43
+ cacheConfig?: CacheConfig;
44
+ /** Legacy thinking config (budget_tokens) */
45
+ thinking?: ThinkingConfig;
46
+ /** Extended thinking config (effort levels) */
47
+ extendedThinking?: ExtendedThinkingConfig;
48
+ onToken?: (text: string) => void;
49
+ onThinking?: (thinking: string) => void;
50
+ /** Called when redacted thinking is received (data is base64) */
51
+ onRedactedThinking?: (data: string) => void;
52
+ onToolUse?: (toolUse: { id: string; name: string; input: unknown }) => void;
53
+ signal?: AbortSignal;
54
+ }
55
+
56
+ export interface StreamResult {
57
+ message: APIResponse;
58
+ usage: UsageMetrics;
59
+ cacheMetrics?: CacheMetrics;
60
+ costUSD: number;
61
+ durationMs: number;
62
+ ttftMs: number;
63
+ /** Thinking tokens used (if extended thinking was enabled) */
64
+ thinkingTokens?: number;
65
+ }
66
+
67
+ /**
68
+ * Calculate cost for API usage including cache metrics
69
+ * Delegates to models.ts for centralized pricing
70
+ */
71
+ export function calculateCost(
72
+ model: string,
73
+ usage: UsageMetrics
74
+ ): { costUSD: number; estimatedSavingsUSD: number } {
75
+ return calculateModelCost(model, usage);
76
+ }
77
+
78
+ /**
79
+ * Build system prompt with cache control
80
+ */
81
+ export function buildSystemPrompt(
82
+ systemPrompt: string | SystemBlock[] | undefined,
83
+ cacheConfig: CacheConfig
84
+ ): string | SystemBlock[] | undefined {
85
+ if (!systemPrompt || !cacheConfig.enabled || !cacheConfig.cacheSystemPrompt) {
86
+ return typeof systemPrompt === "string" ? systemPrompt : undefined;
87
+ }
88
+
89
+ // If already in block format, add cache_control to the last block
90
+ if (Array.isArray(systemPrompt)) {
91
+ const blocks = [...systemPrompt];
92
+ if (blocks.length > 0) {
93
+ const lastBlock = blocks[blocks.length - 1];
94
+ if (lastBlock && lastBlock.type === "text") {
95
+ blocks[blocks.length - 1] = {
96
+ type: "text" as const,
97
+ text: lastBlock.text,
98
+ cache_control: { type: "ephemeral" as const, ttl: cacheConfig.ttl },
99
+ };
100
+ }
101
+ }
102
+ return blocks;
103
+ }
104
+
105
+ // Convert string to block format with cache_control
106
+ return [
107
+ {
108
+ type: "text",
109
+ text: systemPrompt,
110
+ cache_control: { type: "ephemeral", ttl: cacheConfig.ttl },
111
+ },
112
+ ];
113
+ }
114
+
115
+ /**
116
+ * Build messages with cache control for long context blocks
117
+ */
118
+ export function buildCachedMessages(
119
+ messages: Message[],
120
+ cacheConfig: CacheConfig
121
+ ): Message[] {
122
+ if (!cacheConfig.enabled) {
123
+ return messages;
124
+ }
125
+
126
+ const result: Message[] = [];
127
+
128
+ for (let i = 0; i < messages.length; i++) {
129
+ const msg = messages[i]!;
130
+
131
+ // Convert string content to content blocks array
132
+ const contentBlocks: ContentBlock[] = typeof msg.content === "string"
133
+ ? [{ type: "text", text: msg.content }]
134
+ : msg.content;
135
+
136
+ const cachedContent: ContentBlock[] = [];
137
+
138
+ for (let j = 0; j < contentBlocks.length; j++) {
139
+ const block = contentBlocks[j]!;
140
+ const isLastBlock = j === contentBlocks.length - 1;
141
+ const isLastMessage = i === messages.length - 1;
142
+
143
+ // Add cache_control to large text blocks (especially in user messages)
144
+ if (
145
+ block.type === "text" &&
146
+ block.text.length >= cacheConfig.minTokensForCache * 4 && // Approximate chars per token
147
+ !block.cache_control &&
148
+ (isLastBlock || isLastMessage)
149
+ ) {
150
+ cachedContent.push({
151
+ ...block,
152
+ cache_control: { type: "ephemeral", ttl: cacheConfig.ttl },
153
+ });
154
+ } else {
155
+ cachedContent.push(block);
156
+ }
157
+ }
158
+
159
+ result.push({ ...msg, content: cachedContent });
160
+ }
161
+
162
+ // Ensure the last message has cache_control on its last content block
163
+ if (result.length > 0 && cacheConfig.enabled) {
164
+ const lastMsg = result[result.length - 1]!;
165
+ const lastBlock = lastMsg.content[lastMsg.content.length - 1];
166
+ if (lastBlock && !("cache_control" in lastBlock)) {
167
+ lastMsg.content[lastMsg.content.length - 1] = {
168
+ ...lastBlock,
169
+ cache_control: { type: "ephemeral", ttl: cacheConfig.ttl },
170
+ } as ContentBlock;
171
+ }
172
+ }
173
+
174
+ return result;
175
+ }
176
+
177
+ /**
178
+ * Calculate cache metrics from usage
179
+ */
180
+ export function calculateCacheMetrics(usage: UsageMetrics): CacheMetrics {
181
+ const cacheReadTokens = usage.cache_read_input_tokens ?? 0;
182
+ const cacheWriteTokens = usage.cache_creation_input_tokens ?? 0;
183
+ const totalCacheTokens = cacheReadTokens + cacheWriteTokens;
184
+
185
+ const cacheHits = cacheReadTokens > 0 ? 1 : 0;
186
+ const cacheMisses = cacheWriteTokens > 0 ? 1 : 0;
187
+ const total = cacheHits + cacheMisses;
188
+
189
+ return {
190
+ cacheHits,
191
+ cacheMisses,
192
+ totalCacheReadTokens: cacheReadTokens,
193
+ totalCacheWriteTokens: cacheWriteTokens,
194
+ cacheHitRate: total > 0 ? cacheHits / total : 0,
195
+ estimatedSavingsUSD: 0, // Will be calculated after pricing lookup
196
+ };
197
+ }
198
+
199
+ /**
200
+ * Create a streaming message request to Anthropic API
201
+ */
202
+ export async function createMessageStream(
203
+ messages: Message[],
204
+ options: StreamOptions
205
+ ): Promise<StreamResult> {
206
+ const {
207
+ apiKey,
208
+ model = "claude-sonnet-4-6",
209
+ maxTokens = 4096,
210
+ tools,
211
+ systemPrompt,
212
+ cacheConfig = DEFAULT_CACHE_CONFIG,
213
+ thinking,
214
+ extendedThinking,
215
+ onToken,
216
+ onThinking,
217
+ onRedactedThinking,
218
+ onToolUse,
219
+ signal,
220
+ } = options;
221
+
222
+ const startTime = Date.now();
223
+ let ttft = 0;
224
+ let firstToken = true;
225
+ let totalThinkingTokens = 0;
226
+
227
+ // Build cached messages
228
+ const cachedMessages = buildCachedMessages(messages, cacheConfig);
229
+
230
+ // Build system prompt with cache control
231
+ const cachedSystemPrompt = buildSystemPrompt(systemPrompt, cacheConfig);
232
+
233
+ // Build request
234
+ const request: APIRequest = {
235
+ model,
236
+ max_tokens: maxTokens,
237
+ messages: cachedMessages.map((m) => ({
238
+ role: m.role,
239
+ content: m.content,
240
+ })),
241
+ stream: true,
242
+ };
243
+
244
+ // Add system prompt if provided
245
+ if (cachedSystemPrompt) {
246
+ request.system = cachedSystemPrompt;
247
+ }
248
+
249
+ // Add tools if provided (with optional caching)
250
+ if (tools && tools.length > 0) {
251
+ request.tools = tools;
252
+ }
253
+
254
+ // Determine API endpoint (support custom base URL for GLM, etc.)
255
+ const baseUrl = process.env.ANTHROPIC_BASE_URL || "https://api.anthropic.com";
256
+ const apiEndpoint = `${baseUrl}/v1/messages`;
257
+
258
+ // Build headers
259
+ const headers: Record<string, string> = {
260
+ "Content-Type": "application/json",
261
+ "x-api-key": apiKey,
262
+ "anthropic-version": "2023-06-01",
263
+ };
264
+
265
+ // Determine thinking configuration
266
+ const shouldUseExtendedThinking =
267
+ (extendedThinking?.enabled ?? false) ||
268
+ (thinking && thinking.type !== "disabled");
269
+
270
+ if (shouldUseExtendedThinking && supportsExtendedThinking(model)) {
271
+ // Calculate budget tokens
272
+ let budgetTokens: number;
273
+
274
+ if (extendedThinking?.budgetTokens) {
275
+ budgetTokens = extendedThinking.budgetTokens;
276
+ } else if (thinking?.type === "enabled") {
277
+ budgetTokens = thinking.budget_tokens;
278
+ } else {
279
+ // Use effort level to determine budget
280
+ const effort = extendedThinking?.effort || "medium";
281
+ budgetTokens = calculateBudgetTokens(
282
+ {
283
+ enabled: true,
284
+ effort,
285
+ modelMultiplier: model.includes("opus") ? 2 : 1,
286
+ },
287
+ model
288
+ );
289
+ }
290
+
291
+ // Clamp budget to valid range
292
+ budgetTokens = Math.max(1024, Math.min(budgetTokens, 100000));
293
+
294
+ request.thinking = {
295
+ type: "enabled",
296
+ budget_tokens: budgetTokens,
297
+ };
298
+
299
+ // Add beta headers for extended thinking features
300
+ const betaFeatures: string[] = ["extended-thinking-2025-01-24"];
301
+
302
+ // Add interleaved thinking support if enabled
303
+ if (extendedThinking?.interleaved !== false) {
304
+ betaFeatures.push("interleaved-thinking-2025-01-24");
305
+ }
306
+
307
+ headers["anthropic-beta"] = betaFeatures.join(",");
308
+ } else {
309
+ // Default beta header
310
+ headers["anthropic-beta"] = "max-tokens-3-5-sonnet-2024-07-15";
311
+ }
312
+
313
+ // Make API request with retry logic
314
+ const retryOptions: RetryOptions = {
315
+ maxRetries: 3,
316
+ baseDelayMs: 1000,
317
+ maxDelayMs: 30000,
318
+ retryableStatusCodes: [429, 500, 502, 503, 504, 529],
319
+ onRetry: (attempt, error, delayMs) => {
320
+ console.log(`\x1b[33mAPI retry ${attempt}/3 after ${delayMs}ms: ${error.message}\x1b[0m`);
321
+ },
322
+ };
323
+
324
+ const response = await withRetry(
325
+ async () => {
326
+ const res = await fetch(apiEndpoint, {
327
+ method: "POST",
328
+ headers,
329
+ body: JSON.stringify(request),
330
+ signal,
331
+ });
332
+
333
+ // Throw for retryable status codes so withRetry can handle them
334
+ if (!res.ok && retryOptions.retryableStatusCodes?.includes(res.status)) {
335
+ const errorText = await res.text();
336
+ throw new Error(`API error: ${res.status} - ${errorText}`);
337
+ }
338
+
339
+ return res;
340
+ },
341
+ retryOptions
342
+ );
343
+
344
+ if (!response.ok) {
345
+ const error = await response.text();
346
+ throw new Error(`API error: ${response.status} - ${error}`);
347
+ }
348
+
349
+ if (!response.body) {
350
+ throw new Error("No response body");
351
+ }
352
+
353
+ // Parse SSE stream
354
+ const reader = response.body.getReader();
355
+ const decoder = new TextDecoder();
356
+
357
+ let message: APIResponse | null = null;
358
+ let currentContent: ContentBlock[] = [];
359
+ let usage: UsageMetrics = { input_tokens: 0, output_tokens: 0 };
360
+ let currentTextBlock: { type: "text"; text: string } | null = null;
361
+ let currentThinkingBlock: { type: "thinking"; thinking: string } | null = null;
362
+ let currentRedactedThinkingBlock: { type: "redacted_thinking"; data: string } | null = null;
363
+ let currentToolUseBlock: ToolUseBlock | null = null;
364
+ let toolUseInput = "";
365
+
366
+ const buffer = "";
367
+
368
+ try {
369
+ let buffer = "";
370
+
371
+ while (true) {
372
+ const { done, value } = await reader.read();
373
+ if (done) break;
374
+
375
+ buffer += decoder.decode(value, { stream: true });
376
+ const lines = buffer.split("\n");
377
+ buffer = lines.pop() || "";
378
+
379
+ for (const line of lines) {
380
+ if (!line.startsWith("data: ")) continue;
381
+
382
+ const data = line.slice(6);
383
+ if (!data) continue;
384
+
385
+ // Debug: Log all SSE data when debug enabled
386
+ if (process.env.DEBUG_API === '1') {
387
+ console.log('\x1b[90m[DEBUG] SSE data:\x1b[0m', data.substring(0, 200));
388
+ }
389
+
390
+ try {
391
+ const event = JSON.parse(data) as Record<string, unknown>;
392
+
393
+ // Debug: Log event types
394
+ if (process.env.DEBUG_API === '1' && event.type) {
395
+ console.log('\x1b[90m[DEBUG] SSE event type:\x1b[0m', event.type);
396
+ }
397
+
398
+ switch (event.type) {
399
+ case "error": {
400
+ // API returned an error - surface it
401
+ const errorEvent = event as { error?: { type?: string; message?: string } };
402
+ const errorMsg = errorEvent.error?.message || errorEvent.error?.type || "Unknown API error";
403
+ console.error(`API error: ${errorMsg}`);
404
+ // Include more details in debug mode
405
+ if (process.env.DEBUG_API === '1') {
406
+ console.log('\x1b[91m[DEBUG] API error event:', JSON.stringify(errorEvent, null, 255));
407
+ }
408
+ throw new Error(`API error: ${errorMsg}`);
409
+ }
410
+
411
+ case "message_start": {
412
+ const msg = event.message as APIResponse;
413
+ message = msg;
414
+ usage = msg.usage;
415
+ break;
416
+ }
417
+
418
+ case "content_block_start": {
419
+ const block = (event as { content_block: Record<string, unknown> }).content_block;
420
+ if (block.type === "text") {
421
+ currentTextBlock = { type: "text", text: "" };
422
+ } else if (block.type === "thinking") {
423
+ currentThinkingBlock = { type: "thinking", thinking: "" };
424
+ } else if (block.type === "redacted_thinking") {
425
+ currentRedactedThinkingBlock = { type: "redacted_thinking", data: "" };
426
+ } else if (block.type === "tool_use") {
427
+ currentToolUseBlock = {
428
+ type: "tool_use",
429
+ id: block.id as string,
430
+ name: block.name as string,
431
+ input: {},
432
+ };
433
+ toolUseInput = "";
434
+ }
435
+ break;
436
+ }
437
+
438
+ case "content_block_delta": {
439
+ const delta = (event as { delta: Record<string, unknown> }).delta;
440
+ if (delta.type === "text_delta" && currentTextBlock) {
441
+ const text = delta.text as string;
442
+ currentTextBlock.text += text;
443
+ onToken?.(text);
444
+
445
+ if (firstToken) {
446
+ ttft = Date.now() - startTime;
447
+ firstToken = false;
448
+ }
449
+ } else if (delta.type === "thinking_delta" && currentThinkingBlock) {
450
+ const thinking = delta.thinking as string;
451
+ currentThinkingBlock.thinking += thinking;
452
+ onThinking?.(thinking);
453
+ totalThinkingTokens += Math.ceil(thinking.length / 4); // Rough estimate
454
+ } else if (delta.type === "redacted_thinking_delta" && currentRedactedThinkingBlock) {
455
+ // Handle redacted thinking deltas
456
+ const redactedData = delta.data as string;
457
+ currentRedactedThinkingBlock.data += redactedData;
458
+ onRedactedThinking?.(redactedData);
459
+ totalThinkingTokens += Math.ceil(redactedData.length / 4); // Rough estimate
460
+ } else if (delta.type === "input_json_delta" && currentToolUseBlock) {
461
+ toolUseInput += delta.partial_json as string;
462
+ }
463
+ break;
464
+ }
465
+
466
+ case "content_block_stop": {
467
+ // content_block_stop event has { index: number }, not the block itself
468
+ // We need to check which current block is active and push it
469
+ if (currentTextBlock !== null) {
470
+ currentContent.push(currentTextBlock);
471
+ currentTextBlock = null;
472
+ } else if (currentThinkingBlock !== null) {
473
+ currentContent.push(currentThinkingBlock);
474
+ currentThinkingBlock = null;
475
+ } else if (currentRedactedThinkingBlock !== null) {
476
+ currentContent.push(currentRedactedThinkingBlock);
477
+ onRedactedThinking?.(currentRedactedThinkingBlock.data);
478
+ currentRedactedThinkingBlock = null;
479
+ } else if (currentToolUseBlock !== null) {
480
+ try {
481
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
482
+ } catch {
483
+ currentToolUseBlock.input = {};
484
+ }
485
+ currentContent.push(currentToolUseBlock);
486
+ onToolUse?.({
487
+ id: currentToolUseBlock.id,
488
+ name: currentToolUseBlock.name,
489
+ input: currentToolUseBlock.input,
490
+ });
491
+ currentToolUseBlock = null;
492
+ toolUseInput = "";
493
+ }
494
+ break;
495
+ }
496
+
497
+ case "message_delta": {
498
+ const evt = event as { usage?: { output_tokens: number }; delta?: { stop_reason: string } };
499
+ if (evt.usage) {
500
+ usage.output_tokens = evt.usage.output_tokens;
501
+ }
502
+ if (message && evt.delta?.stop_reason) {
503
+ message.stop_reason = evt.delta.stop_reason as "end_turn" | "max_tokens" | "stop_sequence" | "tool_use";
504
+ }
505
+ break;
506
+ }
507
+
508
+ case "message_stop":
509
+ // Message complete
510
+ break;
511
+
512
+ // OpenAI/Z.AI compatible format (for GLM-5, etc.)
513
+ // OpenAI streaming sends chunks with choices array
514
+ default: {
515
+ // Check for OpenAI format: { choices: [{ delta: { content: "..." } }], usage: {...} }
516
+ if (event.choices && Array.isArray(event.choices)) {
517
+ const choice = event.choices[0] as { delta?: { content?: string }; finish_reason?: string } | undefined;
518
+ if (choice?.delta?.content) {
519
+ const text = choice.delta.content;
520
+ if (currentTextBlock) {
521
+ currentTextBlock.text += text;
522
+ } else {
523
+ currentTextBlock = { type: "text", text };
524
+ }
525
+ onToken?.(text);
526
+ if (firstToken) {
527
+ ttft = Date.now() - startTime;
528
+ firstToken = false;
529
+ }
530
+ }
531
+ // Check for finish
532
+ if (choice?.finish_reason) {
533
+ if (currentTextBlock) {
534
+ currentContent.push(currentTextBlock);
535
+ currentTextBlock = null;
536
+ }
537
+ if (!message) {
538
+ message = {
539
+ id: `msg-${Date.now()}`,
540
+ type: "message",
541
+ role: "assistant",
542
+ content: currentContent,
543
+ model: model,
544
+ stop_reason: (choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn") as StopReason,
545
+ stop_sequence: null,
546
+ usage: { input_tokens: 0, output_tokens: 0 },
547
+ };
548
+ } else {
549
+ message.stop_reason = (choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn") as StopReason;
550
+ }
551
+ }
552
+ }
553
+ // OpenAI usage format (often in final chunk)
554
+ if (event.usage) {
555
+ const openaiUsage = event.usage as { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };
556
+ usage.input_tokens = openaiUsage.prompt_tokens || 0;
557
+ usage.output_tokens = openaiUsage.completion_tokens || 0;
558
+ }
559
+ break;
560
+ }
561
+ }
562
+ } catch (err: unknown) {
563
+ // Log the parse error with more detail
564
+ if (process.env.DEBUG_API === '1') {
565
+ console.error('\x1b[91m[DEBUG] JSON parse error:', err);
566
+ console.error('\x1b[91m[DEBUG] Error parsing SSE data:', data.substring(0, 200));
567
+ console.error('\x1b[91m[DEBUG] Original buffer:', buffer.substring(0, 500));
568
+ }
569
+ }
570
+ }
571
+ }
572
+ } finally {
573
+ reader.releaseLock();
574
+ }
575
+
576
+ if (!message) {
577
+ // If we received content via OpenAI format but no message_start, create a message
578
+ if (currentContent.length > 0) {
579
+ message = {
580
+ id: `msg-${Date.now()}`,
581
+ type: "message",
582
+ role: "assistant",
583
+ content: currentContent,
584
+ model: model,
585
+ stop_reason: "end_turn",
586
+ stop_sequence: null,
587
+ usage: { input_tokens: 0, output_tokens: 0 },
588
+ };
589
+ } else {
590
+ // Debug: Log what we did receive
591
+ if (process.env.DEBUG_API === '1') {
592
+ console.log('\x1b[91m[DEBUG] No message_start event received. Buffer:\x1b[0m', buffer.substring(0, 500));
593
+ }
594
+ throw new Error("No message received from API");
595
+ }
596
+ }
597
+
598
+ message.content = currentContent;
599
+
600
+ // Calculate cost and cache metrics
601
+ const { costUSD, estimatedSavingsUSD } = calculateCost(model, usage);
602
+ const cacheMetrics = calculateCacheMetrics(usage);
603
+ cacheMetrics.estimatedSavingsUSD = estimatedSavingsUSD;
604
+
605
+ const durationMs = Date.now() - startTime;
606
+
607
+ return {
608
+ message,
609
+ usage,
610
+ cacheMetrics,
611
+ costUSD,
612
+ durationMs,
613
+ ttftMs: ttft || durationMs,
614
+ thinkingTokens: totalThinkingTokens,
615
+ };
616
+ }
617
+
618
+ // Re-export types
619
+ export type { StreamOptions as StreamOptionsType, StreamResult as StreamResultType };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * API Client exports
3
+ */
4
+
5
+ export * from "./api-client-impl.js";
6
+ export * from "./agent-loop.js";