profclaw 0.0.1-beta.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/.env.example +14 -2
  2. package/CHANGELOG.md +54 -34
  3. package/CONTRIBUTING.md +23 -5
  4. package/Dockerfile +39 -23
  5. package/README.md +271 -72
  6. package/dist/agents/agent-summary.d.ts +44 -0
  7. package/dist/agents/agent-summary.js +176 -0
  8. package/dist/agents/auto-memory.d.ts +59 -0
  9. package/dist/agents/auto-memory.js +310 -0
  10. package/dist/agents/checkpoint-manager.d.ts +76 -0
  11. package/dist/agents/checkpoint-manager.js +156 -0
  12. package/dist/agents/circuit-breaker.d.ts +54 -0
  13. package/dist/agents/circuit-breaker.js +153 -0
  14. package/dist/agents/context-compactor.d.ts +70 -0
  15. package/dist/agents/context-compactor.js +361 -0
  16. package/dist/agents/conversation-branch.d.ts +55 -0
  17. package/dist/agents/conversation-branch.js +115 -0
  18. package/dist/agents/error-recovery.d.ts +44 -0
  19. package/dist/agents/error-recovery.js +197 -0
  20. package/dist/agents/events.d.ts +76 -0
  21. package/dist/agents/events.js +8 -0
  22. package/dist/agents/executor.d.ts +35 -1
  23. package/dist/agents/executor.js +573 -124
  24. package/dist/agents/file-snapshots.d.ts +72 -0
  25. package/dist/agents/file-snapshots.js +182 -0
  26. package/dist/agents/index.d.ts +2 -0
  27. package/dist/agents/orchestrator.d.ts +183 -0
  28. package/dist/agents/orchestrator.js +495 -0
  29. package/dist/agents/permissions.d.ts +63 -0
  30. package/dist/agents/permissions.js +138 -0
  31. package/dist/agents/plan-mode.d.ts +71 -0
  32. package/dist/agents/plan-mode.js +186 -0
  33. package/dist/agents/prompt-suggestions.d.ts +33 -0
  34. package/dist/agents/prompt-suggestions.js +208 -0
  35. package/dist/agents/rate-limit-monitor.d.ts +56 -0
  36. package/dist/agents/rate-limit-monitor.js +224 -0
  37. package/dist/agents/result-store.d.ts +37 -0
  38. package/dist/agents/result-store.js +104 -0
  39. package/dist/agents/session-diff.d.ts +43 -0
  40. package/dist/agents/session-diff.js +258 -0
  41. package/dist/agents/tool-loader.d.ts +65 -0
  42. package/dist/agents/tool-loader.js +273 -0
  43. package/dist/agents/transcript.d.ts +96 -0
  44. package/dist/agents/transcript.js +267 -0
  45. package/dist/agents/worktree-manager.d.ts +80 -0
  46. package/dist/agents/worktree-manager.js +203 -0
  47. package/dist/auth/middleware.js +14 -0
  48. package/dist/chat/agentic-executor.d.ts +7 -0
  49. package/dist/chat/agentic-executor.js +253 -30
  50. package/dist/chat/conversations.d.ts +2 -0
  51. package/dist/chat/conversations.js +8 -0
  52. package/dist/chat/execution/executor.d.ts +8 -0
  53. package/dist/chat/execution/executor.js +157 -103
  54. package/dist/chat/execution/index.js +5 -1
  55. package/dist/chat/execution/tool-router.js +40 -14
  56. package/dist/chat/execution/tools/canvas.d.ts +2 -2
  57. package/dist/chat/execution/tools/code-tools.d.ts +66 -0
  58. package/dist/chat/execution/tools/code-tools.js +353 -0
  59. package/dist/chat/execution/tools/complete-task.d.ts +2 -2
  60. package/dist/chat/execution/tools/cron-tool.d.ts +26 -10
  61. package/dist/chat/execution/tools/cron-tool.js +48 -3
  62. package/dist/chat/execution/tools/decompose-task.d.ts +58 -0
  63. package/dist/chat/execution/tools/decompose-task.js +166 -0
  64. package/dist/chat/execution/tools/exec.d.ts +5 -2
  65. package/dist/chat/execution/tools/exec.js +294 -155
  66. package/dist/chat/execution/tools/feed-tools.d.ts +77 -0
  67. package/dist/chat/execution/tools/feed-tools.js +142 -0
  68. package/dist/chat/execution/tools/file-ops.d.ts +1 -1
  69. package/dist/chat/execution/tools/github.d.ts +2 -2
  70. package/dist/chat/execution/tools/index.d.ts +15 -3
  71. package/dist/chat/execution/tools/index.js +125 -12
  72. package/dist/chat/execution/tools/integrations.d.ts +8 -8
  73. package/dist/chat/execution/tools/multi-patch.d.ts +53 -0
  74. package/dist/chat/execution/tools/multi-patch.js +373 -0
  75. package/dist/chat/execution/tools/openai-image-gen.d.ts +2 -2
  76. package/dist/chat/execution/tools/plan-tools.d.ts +80 -0
  77. package/dist/chat/execution/tools/plan-tools.js +134 -0
  78. package/dist/chat/execution/tools/profclaw-ops.d.ts +6 -6
  79. package/dist/chat/execution/tools/repl-tool.d.ts +46 -0
  80. package/dist/chat/execution/tools/repl-tool.js +207 -0
  81. package/dist/chat/execution/tools/sessions-send.d.ts +2 -2
  82. package/dist/chat/execution/tools/slack-actions.d.ts +2 -2
  83. package/dist/chat/execution/tools/system.d.ts +4 -4
  84. package/dist/chat/execution/tools/todo-tool.d.ts +72 -0
  85. package/dist/chat/execution/tools/todo-tool.js +152 -0
  86. package/dist/chat/execution/tools/tool-search.d.ts +50 -0
  87. package/dist/chat/execution/tools/tool-search.js +155 -0
  88. package/dist/chat/execution/types.d.ts +21 -14
  89. package/dist/chat/execution/workflows/executor.d.ts +11 -0
  90. package/dist/chat/execution/workflows/executor.js +99 -1
  91. package/dist/chat/execution/workflows/types.d.ts +35 -2
  92. package/dist/chat/format/index.d.ts +1 -0
  93. package/dist/chat/format/index.js +1 -0
  94. package/dist/chat/format/markdown-convert.d.ts +23 -0
  95. package/dist/chat/format/markdown-convert.js +149 -0
  96. package/dist/chat/index.d.ts +1 -1
  97. package/dist/chat/index.js +1 -1
  98. package/dist/chat/message-handler.js +58 -6
  99. package/dist/chat/proactive/index.d.ts +62 -0
  100. package/dist/chat/proactive/index.js +147 -0
  101. package/dist/chat/prompt-adapter.js +2 -0
  102. package/dist/chat/providers/irc/index.d.ts +2 -2
  103. package/dist/chat/providers/slack/index.d.ts +2 -2
  104. package/dist/chat/providers/telegram/index.d.ts +2 -0
  105. package/dist/chat/providers/telegram/index.js +21 -2
  106. package/dist/chat/system-prompts.d.ts +3 -3
  107. package/dist/chat/system-prompts.js +116 -61
  108. package/dist/chat/tools.d.ts +6 -6
  109. package/dist/cli/commands/auth.js +64 -1
  110. package/dist/cli/commands/chat.js +1327 -138
  111. package/dist/cli/commands/doctor.js +222 -16
  112. package/dist/cli/commands/history.d.ts +3 -0
  113. package/dist/cli/commands/history.js +138 -0
  114. package/dist/cli/commands/import.d.ts +44 -0
  115. package/dist/cli/commands/import.js +526 -0
  116. package/dist/cli/commands/init.d.ts +13 -0
  117. package/dist/cli/commands/init.js +381 -0
  118. package/dist/cli/commands/models.js +39 -26
  119. package/dist/cli/commands/onboard.js +263 -98
  120. package/dist/cli/commands/plan.d.ts +13 -0
  121. package/dist/cli/commands/plan.js +184 -0
  122. package/dist/cli/commands/serve.d.ts +7 -0
  123. package/dist/cli/commands/serve.js +77 -18
  124. package/dist/cli/commands/setup.js +375 -91
  125. package/dist/cli/commands/status.js +54 -0
  126. package/dist/cli/commands/tools.js +13 -13
  127. package/dist/cli/commands/tui.js +26 -1
  128. package/dist/cli/index.js +19 -6
  129. package/dist/cli/ink/App.d.ts +13 -0
  130. package/dist/cli/ink/App.js +6 -0
  131. package/dist/cli/ink/ChatApp.d.ts +60 -0
  132. package/dist/cli/ink/ChatApp.js +325 -0
  133. package/dist/cli/ink/DashboardApp.d.ts +3 -0
  134. package/dist/cli/ink/DashboardApp.js +143 -0
  135. package/dist/cli/ink/components/AgentStatus.d.ts +17 -0
  136. package/dist/cli/ink/components/AgentStatus.js +33 -0
  137. package/dist/cli/ink/components/ChannelList.d.ts +17 -0
  138. package/dist/cli/ink/components/ChannelList.js +33 -0
  139. package/dist/cli/ink/components/ConnectionStatus.d.ts +19 -0
  140. package/dist/cli/ink/components/ConnectionStatus.js +50 -0
  141. package/dist/cli/ink/components/CostBar.d.ts +19 -0
  142. package/dist/cli/ink/components/CostBar.js +35 -0
  143. package/dist/cli/ink/components/HookStatus.d.ts +15 -0
  144. package/dist/cli/ink/components/HookStatus.js +7 -0
  145. package/dist/cli/ink/components/PermissionPrompt.d.ts +21 -0
  146. package/dist/cli/ink/components/PermissionPrompt.js +51 -0
  147. package/dist/cli/ink/components/PlanView.d.ts +23 -0
  148. package/dist/cli/ink/components/PlanView.js +26 -0
  149. package/dist/cli/ink/components/ProviderList.d.ts +16 -0
  150. package/dist/cli/ink/components/ProviderList.js +16 -0
  151. package/dist/cli/ink/components/SessionHeader.d.ts +15 -0
  152. package/dist/cli/ink/components/SessionHeader.js +15 -0
  153. package/dist/cli/ink/components/StreamingMessage.d.ts +20 -0
  154. package/dist/cli/ink/components/StreamingMessage.js +27 -0
  155. package/dist/cli/ink/components/SuggestionBar.d.ts +15 -0
  156. package/dist/cli/ink/components/SuggestionBar.js +28 -0
  157. package/dist/cli/ink/components/SystemHealth.d.ts +20 -0
  158. package/dist/cli/ink/components/SystemHealth.js +39 -0
  159. package/dist/cli/ink/components/TaskList.d.ts +17 -0
  160. package/dist/cli/ink/components/TaskList.js +59 -0
  161. package/dist/cli/ink/components/ToolCall.d.ts +17 -0
  162. package/dist/cli/ink/components/ToolCall.js +43 -0
  163. package/dist/cli/ink/index.d.ts +23 -0
  164. package/dist/cli/ink/index.js +15 -0
  165. package/dist/cli/ink/keybindings.d.ts +35 -0
  166. package/dist/cli/ink/keybindings.js +105 -0
  167. package/dist/cli/ink/markdown-renderer.d.ts +47 -0
  168. package/dist/cli/ink/markdown-renderer.js +380 -0
  169. package/dist/cli/ink/output-styles.d.ts +39 -0
  170. package/dist/cli/ink/output-styles.js +119 -0
  171. package/dist/cli/interactive/auto-serve.d.ts +38 -0
  172. package/dist/cli/interactive/auto-serve.js +209 -0
  173. package/dist/cli/interactive/index.d.ts +25 -0
  174. package/dist/cli/interactive/index.js +23 -0
  175. package/dist/cli/interactive/picker.d.ts +28 -0
  176. package/dist/cli/interactive/picker.js +153 -0
  177. package/dist/cli/interactive/renderer.d.ts +26 -0
  178. package/dist/cli/interactive/renderer.js +555 -0
  179. package/dist/cli/interactive/repl.d.ts +14 -0
  180. package/dist/cli/interactive/repl.js +1516 -0
  181. package/dist/cli/interactive/stream-client.d.ts +59 -0
  182. package/dist/cli/interactive/stream-client.js +506 -0
  183. package/dist/cli/interactive/types.d.ts +121 -0
  184. package/dist/cli/interactive/types.js +10 -0
  185. package/dist/cli/providers.d.ts +15 -0
  186. package/dist/cli/providers.js +41 -0
  187. package/dist/cli/utils/api.d.ts +9 -0
  188. package/dist/cli/utils/api.js +58 -2
  189. package/dist/core/deployment.js +2 -0
  190. package/dist/cron/natural-language.d.ts +54 -0
  191. package/dist/cron/natural-language.js +569 -0
  192. package/dist/cron/scheduler.d.ts +34 -4
  193. package/dist/cron/scheduler.js +141 -9
  194. package/dist/cron/templates.d.ts +1 -1
  195. package/dist/cron/templates.js +219 -0
  196. package/dist/feeds/feed-engine.d.ts +149 -0
  197. package/dist/feeds/feed-engine.js +600 -0
  198. package/dist/feeds/index.d.ts +9 -0
  199. package/dist/feeds/index.js +8 -0
  200. package/dist/gateway/router.js +6 -1
  201. package/dist/hooks/built-in/audit-log.d.ts +11 -0
  202. package/dist/hooks/built-in/audit-log.js +84 -0
  203. package/dist/hooks/built-in/cost-warning.d.ts +10 -0
  204. package/dist/hooks/built-in/cost-warning.js +59 -0
  205. package/dist/hooks/built-in/dangerous-tool.d.ts +32 -0
  206. package/dist/hooks/built-in/dangerous-tool.js +80 -0
  207. package/dist/hooks/built-in/index.d.ts +14 -0
  208. package/dist/hooks/built-in/index.js +20 -0
  209. package/dist/hooks/index.d.ts +3 -0
  210. package/dist/hooks/index.js +6 -0
  211. package/dist/hooks/loader.d.ts +17 -0
  212. package/dist/hooks/loader.js +142 -0
  213. package/dist/hooks/registry.d.ts +62 -0
  214. package/dist/hooks/registry.js +127 -0
  215. package/dist/integrations/web-search.js +6 -3
  216. package/dist/memory/index.d.ts +1 -0
  217. package/dist/memory/index.js +2 -0
  218. package/dist/memory/memory-service.js +14 -13
  219. package/dist/memory/observational.d.ts +62 -0
  220. package/dist/memory/observational.js +396 -0
  221. package/dist/middleware/content-filter.d.ts +22 -0
  222. package/dist/middleware/content-filter.js +69 -0
  223. package/dist/middleware/request-validator.d.ts +159 -0
  224. package/dist/middleware/request-validator.js +93 -0
  225. package/dist/plugins/sdk.d.ts +22 -0
  226. package/dist/plugins/sdk.js +17 -1
  227. package/dist/projects/types.d.ts +10 -10
  228. package/dist/providers/ai-sdk.d.ts +11 -0
  229. package/dist/providers/ai-sdk.js +97 -18
  230. package/dist/providers/core/models.js +67 -1
  231. package/dist/providers/core/types.d.ts +3 -0
  232. package/dist/providers/index.d.ts +1 -0
  233. package/dist/providers/index.js +1 -0
  234. package/dist/providers/smart-router.d.ts +118 -0
  235. package/dist/providers/smart-router.js +685 -0
  236. package/dist/providers/types.d.ts +16 -16
  237. package/dist/routes/agents.js +50 -0
  238. package/dist/routes/auth.js +8 -1
  239. package/dist/routes/channels.d.ts +12 -0
  240. package/dist/routes/channels.js +166 -0
  241. package/dist/routes/chat.js +259 -14
  242. package/dist/routes/costs.js +32 -0
  243. package/dist/routes/cron.js +80 -5
  244. package/dist/routes/feeds.d.ts +10 -0
  245. package/dist/routes/feeds.js +168 -0
  246. package/dist/routes/mcp.js +21 -0
  247. package/dist/routes/memory.js +130 -0
  248. package/dist/routes/skills.js +129 -0
  249. package/dist/routes/teams.d.ts +9 -0
  250. package/dist/routes/teams.js +210 -0
  251. package/dist/routes/tools.js +14 -0
  252. package/dist/routes/users.js +2 -0
  253. package/dist/server/route-loader.js +4 -1
  254. package/dist/server/stream-bridge.d.ts +19 -0
  255. package/dist/server/stream-bridge.js +38 -0
  256. package/dist/server.js +421 -141
  257. package/dist/skills/marketplace.d.ts +87 -0
  258. package/dist/skills/marketplace.js +268 -0
  259. package/dist/storage/index.d.ts +14 -0
  260. package/dist/storage/index.js +64 -3
  261. package/dist/storage/schema.d.ts +4 -4
  262. package/dist/storage/schema.js +1 -1
  263. package/dist/teams/index.d.ts +110 -0
  264. package/dist/teams/index.js +365 -0
  265. package/dist/tickets/types.d.ts +39 -39
  266. package/dist/types/summary.d.ts +5 -5
  267. package/dist/utils/auto-update.d.ts +23 -0
  268. package/dist/utils/auto-update.js +157 -0
  269. package/dist/utils/offline-detect.d.ts +55 -0
  270. package/dist/utils/offline-detect.js +121 -0
  271. package/dist/utils/pid-file.d.ts +36 -0
  272. package/dist/utils/pid-file.js +125 -0
  273. package/dist/utils/prevent-sleep.d.ts +27 -0
  274. package/dist/utils/prevent-sleep.js +95 -0
  275. package/dist/utils/sanitizer.d.ts +57 -0
  276. package/dist/utils/sanitizer.js +174 -0
  277. package/docker-compose.yml +13 -137
  278. package/package.json +31 -6
  279. package/skills/deploy-cloudflare/SKILL.md +62 -0
  280. package/skills/deploy-vercel/SKILL.md +67 -0
  281. package/skills/docker-deploy/SKILL.md +158 -0
  282. package/skills/full-stack-builder/SKILL.md +92 -0
  283. package/skills/git-workflow/SKILL.md +3 -3
  284. package/skills/humanizer/SKILL.md +488 -0
  285. package/skills/profclaw-assistant/SKILL.md +85 -56
  286. package/ui/dist/assets/ActivityView-Da6HQ8ws.js +1 -0
  287. package/ui/dist/assets/AgentList-H58R0kX3.js +1 -0
  288. package/ui/dist/assets/AnalyticsDashboard-B28AeRsc.js +1 -0
  289. package/ui/dist/assets/AreaChart-DwLzeAQ8.js +1 -0
  290. package/ui/dist/assets/CartesianChart-piKQsTAR.js +36 -0
  291. package/ui/dist/assets/ChatView-Dbj8rxU5.js +10 -0
  292. package/ui/dist/assets/CostsDashboard-C6F5df0F.js +1 -0
  293. package/ui/dist/assets/EstimateSelect-wga0rUKX.js +1 -0
  294. package/ui/dist/assets/FeedDashboard-Ef6FEzEf.js +1 -0
  295. package/ui/dist/assets/FloatingChatbot-0yhkUeCq.js +2 -0
  296. package/ui/dist/assets/InviteCodeManagement-tUXfx4Bc.js +2 -0
  297. package/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  298. package/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  299. package/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  300. package/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  301. package/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  302. package/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  303. package/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  304. package/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  305. package/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  306. package/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  307. package/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  308. package/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  309. package/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  310. package/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  311. package/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  312. package/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  313. package/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  314. package/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  315. package/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  316. package/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  317. package/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  318. package/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  319. package/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  320. package/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  321. package/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  322. package/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  323. package/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  324. package/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  325. package/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  326. package/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  327. package/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  328. package/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  329. package/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  330. package/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  331. package/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  332. package/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  333. package/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  334. package/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  335. package/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  336. package/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  337. package/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  338. package/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  339. package/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  340. package/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  341. package/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  342. package/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  343. package/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  344. package/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  345. package/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  346. package/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  347. package/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  348. package/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  349. package/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  350. package/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  351. package/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  352. package/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  353. package/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  354. package/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  355. package/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  356. package/ui/dist/assets/MarketplacePage-DGrLtolR.js +1 -0
  357. package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail-BgWvA6UP.js} +2 -2
  358. package/ui/dist/assets/ProjectIcon-TDuliqwg.js +1 -0
  359. package/ui/dist/assets/ProjectList-DXgM4187.js +1 -0
  360. package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-xA8Zhi3p.js} +3 -3
  361. package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
  362. package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-eedRfTtF.js} +2 -2
  363. package/ui/dist/assets/SummaryList-CLNX2P84.js +1 -0
  364. package/ui/dist/assets/TaskDetail-BtWclNiR.js +1 -0
  365. package/ui/dist/assets/TaskList-JjODAgSc.js +1 -0
  366. package/ui/dist/assets/TeamsPage-CBK5iAyx.js +1 -0
  367. package/ui/dist/assets/TicketBoard-C9aJNNYp.js +1 -0
  368. package/ui/dist/assets/TicketDetail-CV5JmL31.js +1 -0
  369. package/ui/dist/assets/TicketList-68V4lzUz.js +1 -0
  370. package/ui/dist/assets/UserManagement-DKTb6UpE.js +2 -0
  371. package/ui/dist/assets/ViewSwitcher-BvdQht2Y.js +1 -0
  372. package/ui/dist/assets/alert-dialog-O6qBOv_f.js +1 -0
  373. package/ui/dist/assets/{archive-CGck7gxR.js → archive-CX7UvZpf.js} +1 -1
  374. package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
  375. package/ui/dist/assets/{bug-DqSGPUUE.js → bug-3WX0394-.js} +1 -1
  376. package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-buq77TaS.js} +1 -1
  377. package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-4ymsBJRo.js} +1 -1
  378. package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-ByXtwR6Y.js} +1 -1
  379. package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
  380. package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-CiuoCeDY.js} +1 -1
  381. package/ui/dist/assets/{database-CA2w8Lvt.js → database-BWXSBg5a.js} +1 -1
  382. package/ui/dist/assets/dialog-lDg4NvMV.js +1 -0
  383. package/ui/dist/assets/dollar-sign-Dmijd6DP.js +1 -0
  384. package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-vT-5SVIp.js} +1 -1
  385. package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
  386. package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
  387. package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-ChOWdKXf.js} +1 -1
  388. package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-CkOUbIiP.js} +1 -1
  389. package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-uZkoSPP-.js} +1 -1
  390. package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-CwvUxj7C.js} +1 -1
  391. package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
  392. package/ui/dist/assets/{globe-CQWfr7hT.js → globe-D_WpJdsj.js} +1 -1
  393. package/ui/dist/assets/{hash-nKC9gtLg.js → hash-CA0hJ7vh.js} +1 -1
  394. package/ui/dist/assets/{history-DfFSA9xJ.js → history-CEWMLELs.js} +1 -1
  395. package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
  396. package/ui/dist/assets/{index-a4Fxq0Hb.js → index-C1rhbml4.js} +3 -3
  397. package/ui/dist/assets/index-CR8gfCHv.js +1 -0
  398. package/ui/dist/assets/index-DVXMpWai.js +1 -0
  399. package/ui/dist/assets/index-DaDJMM2v.js +1 -0
  400. package/ui/dist/assets/index-Djdq_0xu.js +1 -0
  401. package/ui/dist/assets/index-M46Gcb8K.css +1 -0
  402. package/ui/dist/assets/index-sEBN7w8J.js +109 -0
  403. package/ui/dist/assets/layers-C6Mhf8Nk.js +1 -0
  404. package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-BRUM0kpT.js} +1 -1
  405. package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-CN2q1O5l.js} +1 -1
  406. package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-CC4E28yJ.js} +1 -1
  407. package/ui/dist/assets/markdown-renderer-C6ENbB0u.js +10 -0
  408. package/ui/dist/assets/markdown-renderer-CfVKi3_s.css +1 -0
  409. package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-Bbb241am.js} +1 -1
  410. package/ui/dist/assets/package-CwT3IzFx.js +1 -0
  411. package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CDmiHzoj.js} +1 -1
  412. package/ui/dist/assets/{play-DVgea_jT.js → play-tjy5jMQX.js} +1 -1
  413. package/ui/dist/assets/popover-CFHZf3pE.js +1 -0
  414. package/ui/dist/assets/progress-BboUHuLf.js +1 -0
  415. package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket--8ZHgdXJ.js} +1 -1
  416. package/ui/dist/assets/select-n108rXny.js +1 -0
  417. package/ui/dist/assets/{send-eYnW_7n-.js → send-Cu7MR2Qh.js} +1 -1
  418. package/ui/dist/assets/server-DmodxZp-.js +1 -0
  419. package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-CkRNqkxj.js} +1 -1
  420. package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
  421. package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-ViI3nMKE.js} +1 -1
  422. package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-DN3tagkn.js} +1 -1
  423. package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
  424. package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-5FghiXpA.js} +1 -1
  425. package/ui/dist/assets/{square-e1yxB2eR.js → square-DiNSx8K7.js} +1 -1
  426. package/ui/dist/assets/star-DhdFVidS.js +1 -0
  427. package/ui/dist/assets/switch-CIgVbZqQ.js +1 -0
  428. package/ui/dist/assets/table-BC56FVMV.js +1 -0
  429. package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-CH_vQliw.js} +1 -1
  430. package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
  431. package/ui/dist/assets/{timer-Vel1N3RP.js → timer-CdGVTb60.js} +1 -1
  432. package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
  433. package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-CucZJL0N.js} +1 -1
  434. package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
  435. package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-C5OYX2k2.js} +1 -1
  436. package/ui/dist/assets/vendor-query-C0p7b53x.js +4 -0
  437. package/ui/dist/assets/vendor-react-Mc5_kfYG.js +12 -0
  438. package/ui/dist/assets/vendor-ui-CXPAUBFv.js +51 -0
  439. package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BaH6pJnc.js} +1 -1
  440. package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-CjxjP6ok.js} +1 -1
  441. package/ui/dist/index.html +5 -2
  442. package/dist/chat/auto-reply.d.ts +0 -90
  443. package/dist/chat/auto-reply.js +0 -272
  444. package/dist/chat/execution/pty.d.ts +0 -92
  445. package/dist/chat/execution/pty.js +0 -285
  446. package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
  447. package/dist/chat/execution/tools/glinr-ops.js +0 -694
  448. package/dist/cli/commands/browser.d.ts +0 -3
  449. package/dist/cli/commands/browser.js +0 -138
  450. package/dist/cli/commands/canvas.d.ts +0 -3
  451. package/dist/cli/commands/canvas.js +0 -155
  452. package/dist/cli/commands/nodes.d.ts +0 -3
  453. package/dist/cli/commands/nodes.js +0 -193
  454. package/dist/diagnostics/exporters.d.ts +0 -21
  455. package/dist/diagnostics/exporters.js +0 -138
  456. package/dist/diagnostics/index.d.ts +0 -10
  457. package/dist/diagnostics/index.js +0 -9
  458. package/dist/diagnostics/middleware.d.ts +0 -12
  459. package/dist/diagnostics/middleware.js +0 -58
  460. package/dist/diagnostics/tracer.d.ts +0 -133
  461. package/dist/diagnostics/tracer.js +0 -257
  462. package/dist/discovery/index.d.ts +0 -8
  463. package/dist/discovery/index.js +0 -7
  464. package/dist/discovery/mdns.d.ts +0 -40
  465. package/dist/discovery/mdns.js +0 -249
  466. package/dist/plugins/registry.d.ts +0 -122
  467. package/dist/plugins/registry.js +0 -352
  468. package/dist/plugins/sandbox.d.ts +0 -77
  469. package/dist/plugins/sandbox.js +0 -287
  470. package/dist/plugins/search/brave.d.ts +0 -9
  471. package/dist/plugins/search/brave.js +0 -157
  472. package/dist/plugins/search/duckduckgo.d.ts +0 -9
  473. package/dist/plugins/search/duckduckgo.js +0 -171
  474. package/dist/plugins/search/index.d.ts +0 -13
  475. package/dist/plugins/search/index.js +0 -23
  476. package/dist/plugins/search/searxng.d.ts +0 -9
  477. package/dist/plugins/search/searxng.js +0 -170
  478. package/dist/plugins/search/serper.d.ts +0 -9
  479. package/dist/plugins/search/serper.js +0 -135
  480. package/dist/plugins/search/tavily.d.ts +0 -9
  481. package/dist/plugins/search/tavily.js +0 -146
  482. package/dist/providers/adapters/anthropic.d.ts +0 -26
  483. package/dist/providers/adapters/anthropic.js +0 -306
  484. package/dist/providers/adapters/base.d.ts +0 -53
  485. package/dist/providers/adapters/base.js +0 -99
  486. package/dist/providers/adapters/ollama.d.ts +0 -30
  487. package/dist/providers/adapters/ollama.js +0 -292
  488. package/dist/utils/ai-cache.d.ts +0 -72
  489. package/dist/utils/ai-cache.js +0 -204
  490. package/dist/utils/file-lock.d.ts +0 -85
  491. package/dist/utils/file-lock.js +0 -204
  492. package/ui/dist/assets/ActivityView-DIPQSJ_d.js +0 -1
  493. package/ui/dist/assets/AgentList-CqyaYrcq.js +0 -1
  494. package/ui/dist/assets/AnalyticsDashboard-C-mjuGHT.js +0 -1
  495. package/ui/dist/assets/AreaChart-CfYWmbtr.js +0 -1
  496. package/ui/dist/assets/CartesianChart-BaQ3It0c.js +0 -36
  497. package/ui/dist/assets/ChatView-DxxQy6pl.js +0 -10
  498. package/ui/dist/assets/CostsDashboard-CDBBcGkg.js +0 -1
  499. package/ui/dist/assets/EstimateSelect-CDjf5qKl.js +0 -1
  500. package/ui/dist/assets/FloatingChatbot-CZHjvJIe.js +0 -2
  501. package/ui/dist/assets/InviteCodeManagement-DTm-IPTm.js +0 -2
  502. package/ui/dist/assets/ProjectIcon-BMRpnM04.js +0 -1
  503. package/ui/dist/assets/ProjectList-D85TN0i0.js +0 -4
  504. package/ui/dist/assets/StatusIndicator-yig0uZEA.js +0 -1
  505. package/ui/dist/assets/SummaryList-BvS5Idnu.js +0 -1
  506. package/ui/dist/assets/TaskDetail-zarC1fOt.js +0 -1
  507. package/ui/dist/assets/TaskList-CyJq3ANE.js +0 -1
  508. package/ui/dist/assets/TicketBoard-BlWr3-iH.js +0 -1
  509. package/ui/dist/assets/TicketDetail-DmqWKj2W.js +0 -1
  510. package/ui/dist/assets/TicketList-Scj4pMWa.js +0 -1
  511. package/ui/dist/assets/UserManagement-BH7uG7dw.js +0 -2
  512. package/ui/dist/assets/ViewSwitcher-3HzZUdWn.js +0 -1
  513. package/ui/dist/assets/alert-dialog-DWPb2IfQ.js +0 -7
  514. package/ui/dist/assets/badge-DEmc3Z_l.js +0 -1
  515. package/ui/dist/assets/brain-CfFdLVqb.js +0 -1
  516. package/ui/dist/assets/constants-DhDjZe4P.js +0 -1
  517. package/ui/dist/assets/dialog-BOdGWhgE.js +0 -1
  518. package/ui/dist/assets/index--JkIxVXb.js +0 -67
  519. package/ui/dist/assets/index-Ca3vk7Gq.js +0 -1
  520. package/ui/dist/assets/index-DHGvP9mp.js +0 -1
  521. package/ui/dist/assets/index-DeI8lKRR.js +0 -1
  522. package/ui/dist/assets/index-WclMPci1.css +0 -1
  523. package/ui/dist/assets/index-Z4-RtZcs.js +0 -1
  524. package/ui/dist/assets/layers-DFeLExSa.js +0 -1
  525. package/ui/dist/assets/markdown-renderer-Croje6Xe.js +0 -36
  526. package/ui/dist/assets/popover-JXecfWG5.js +0 -1
  527. package/ui/dist/assets/progress-C1ghf1Fu.js +0 -1
  528. package/ui/dist/assets/select-MADP8m6Q.js +0 -1
  529. package/ui/dist/assets/server-CPMaysH8.js +0 -1
  530. package/ui/dist/assets/sheet-r6NSOxi-.js +0 -1
  531. package/ui/dist/assets/skeleton-C9oEzNlU.js +0 -1
  532. package/ui/dist/assets/switch-tNs0n-kz.js +0 -1
  533. package/ui/dist/assets/table-CXxtLicg.js +0 -1
  534. package/ui/dist/assets/textarea-BjiEeIWh.js +0 -1
  535. package/ui/dist/assets/tooltip-ZMwtfr1J.js +0 -1
@@ -9,8 +9,18 @@ import { streamText } from "hono/streaming";
9
9
  import { zValidator } from "@hono/zod-validator";
10
10
  import { z } from "zod";
11
11
  import { randomUUID } from "node:crypto";
12
+ import { routeQuery, recordRoutingDecision, isSmartRouterEnabled, getCostComparison, } from "../providers/smart-router.js";
12
13
  import { logger } from "../utils/logger.js";
14
+ import { rateLimit } from "../middleware/rate-limit.js";
15
+ import { contentFilter } from "../middleware/content-filter.js";
13
16
  const chatRoutes = new Hono();
17
+ // Per-IP sliding-window rate limiter for chat send endpoints
18
+ const chatMaxRequests = parseInt(process.env['CHAT_RATE_LIMIT'] ?? '20', 10);
19
+ const chatRateLimiter = rateLimit({
20
+ maxRequests: chatMaxRequests,
21
+ windowMs: 60_000,
22
+ message: `Chat rate limit exceeded. Maximum ${chatMaxRequests} messages per minute.`,
23
+ });
14
24
  let chatRuntimePromise = null;
15
25
  let ProviderTypeSchema;
16
26
  let aiProvider;
@@ -26,6 +36,7 @@ let listConversations;
26
36
  let deleteConversation;
27
37
  let addMessage;
28
38
  let getConversationMessages;
39
+ let deleteMessage;
29
40
  let getRecentConversationsWithPreview;
30
41
  let compactMessages;
31
42
  let getMemoryStats;
@@ -65,6 +76,7 @@ async function ensureChatRuntime() {
65
76
  deleteConversation = chatModule.deleteConversation;
66
77
  addMessage = chatModule.addMessage;
67
78
  getConversationMessages = chatModule.getConversationMessages;
79
+ deleteMessage = chatModule.deleteMessage;
68
80
  getRecentConversationsWithPreview =
69
81
  chatModule.getRecentConversationsWithPreview;
70
82
  compactMessages = chatModule.compactMessages;
@@ -168,6 +180,84 @@ chatRoutes.get("/model-capability", async (c) => {
168
180
  const resolved = MODEL_ALIASES[model.toLowerCase()]?.model ?? model;
169
181
  return c.json(getModelRouting(resolved));
170
182
  });
183
+ /**
184
+ * POST /api/chat/send
185
+ * Simple one-shot chat - send a message and get a response
186
+ */
187
+ chatRoutes.post("/send", chatRateLimiter, contentFilter(), zValidator("json", z.object({
188
+ message: z.string(),
189
+ model: z.string().optional(),
190
+ systemPrompt: z.string().optional(),
191
+ temperature: z.number().min(0).max(2).optional(),
192
+ maxTokens: z.number().positive().optional(),
193
+ })), async (c) => {
194
+ const body = c.req.valid("json");
195
+ try {
196
+ const messages = [
197
+ {
198
+ id: randomUUID(),
199
+ role: "user",
200
+ content: body.message,
201
+ timestamp: new Date().toISOString(),
202
+ },
203
+ ];
204
+ // Smart routing: auto-select model if none specified
205
+ let routing;
206
+ let modelToUse = body.model;
207
+ if (!body.model && isSmartRouterEnabled()) {
208
+ const providers = new Set(aiProvider.getConfiguredProviders());
209
+ routing = routeQuery(body.message, providers);
210
+ modelToUse = routing.selectedModel.id;
211
+ recordRoutingDecision(routing);
212
+ }
213
+ const response = await aiProvider.chat({
214
+ messages,
215
+ model: modelToUse,
216
+ systemPrompt: body.systemPrompt,
217
+ temperature: body.temperature,
218
+ maxTokens: body.maxTokens,
219
+ });
220
+ // Track token usage for cost dashboard
221
+ if (response.usage?.totalTokens && response.model) {
222
+ await ensureChatRuntime();
223
+ trackChatUsage(response.model, response.usage.totalTokens, response.usage.promptTokens, response.usage.completionTokens);
224
+ }
225
+ return c.json({
226
+ id: response.id,
227
+ provider: response.provider,
228
+ model: response.model,
229
+ reply: response.content,
230
+ finishReason: response.finishReason,
231
+ usage: response.usage,
232
+ duration: response.duration,
233
+ ...(routing && {
234
+ routing: {
235
+ smartRouted: true,
236
+ complexity: routing.complexity.tier,
237
+ confidence: Math.round(routing.complexity.confidence * 100),
238
+ reasoning: routing.complexity.reasoning,
239
+ savings: `${routing.savingsPercent}%`,
240
+ estimatedCost: `$${routing.estimatedCost.toFixed(4)}`,
241
+ summary: getCostComparison(routing),
242
+ ...(routing.missingProviderHint && {
243
+ tip: {
244
+ addProvider: routing.missingProviderHint.provider,
245
+ reason: routing.missingProviderHint.reason,
246
+ savings: routing.missingProviderHint.estimatedSavings,
247
+ signupUrl: routing.missingProviderHint.signupUrl,
248
+ },
249
+ }),
250
+ },
251
+ }),
252
+ });
253
+ }
254
+ catch (error) {
255
+ logger.error("[Chat] Send error:", error instanceof Error ? error : undefined);
256
+ return c.json({
257
+ error: error instanceof Error ? error.message : "Chat send failed",
258
+ }, 500);
259
+ }
260
+ });
171
261
  /**
172
262
  * POST /api/chat/completions
173
263
  * Generate a chat completion
@@ -183,11 +273,37 @@ chatRoutes.post("/completions", zValidator("json", ChatCompletionSchema), async
183
273
  }));
184
274
  // Handle streaming
185
275
  if (body.stream) {
276
+ // Smart route for streaming too
277
+ let streamRouting;
278
+ let streamModel = body.model;
279
+ if (!body.model && isSmartRouterEnabled()) {
280
+ const lastUserMsg = [...body.messages].reverse().find((m) => m.role === "user");
281
+ if (lastUserMsg) {
282
+ const providers = new Set(aiProvider.getConfiguredProviders());
283
+ streamRouting = routeQuery(lastUserMsg.content, providers, {
284
+ conversationLength: body.messages.length,
285
+ });
286
+ streamModel = streamRouting.selectedModel.id;
287
+ recordRoutingDecision(streamRouting);
288
+ }
289
+ }
186
290
  return streamText(c, async (stream) => {
187
291
  try {
292
+ // Send routing info as first event in stream
293
+ if (streamRouting) {
294
+ await stream.write(`data: ${JSON.stringify({
295
+ routing: {
296
+ smartRouted: true,
297
+ complexity: streamRouting.complexity.tier,
298
+ savings: `${streamRouting.savingsPercent}%`,
299
+ model: streamRouting.selectedModel.id,
300
+ provider: streamRouting.selectedModel.provider,
301
+ },
302
+ })}\n\n`);
303
+ }
188
304
  const response = await aiProvider.chatStream({
189
305
  messages,
190
- model: body.model,
306
+ model: streamModel,
191
307
  systemPrompt: body.systemPrompt,
192
308
  temperature: body.temperature,
193
309
  maxTokens: body.maxTokens,
@@ -216,9 +332,23 @@ chatRoutes.post("/completions", zValidator("json", ChatCompletionSchema), async
216
332
  }
217
333
  // Non-streaming
218
334
  try {
335
+ // Smart routing for completions
336
+ let routing;
337
+ let modelToUse = body.model;
338
+ if (!body.model && isSmartRouterEnabled()) {
339
+ const lastUserMsg = [...body.messages].reverse().find((m) => m.role === "user");
340
+ if (lastUserMsg) {
341
+ const providers = new Set(aiProvider.getConfiguredProviders());
342
+ routing = routeQuery(lastUserMsg.content, providers, {
343
+ conversationLength: body.messages.length,
344
+ });
345
+ modelToUse = routing.selectedModel.id;
346
+ recordRoutingDecision(routing);
347
+ }
348
+ }
219
349
  const response = await aiProvider.chat({
220
350
  messages,
221
- model: body.model,
351
+ model: modelToUse,
222
352
  systemPrompt: body.systemPrompt,
223
353
  temperature: body.temperature,
224
354
  maxTokens: body.maxTokens,
@@ -234,6 +364,15 @@ chatRoutes.post("/completions", zValidator("json", ChatCompletionSchema), async
234
364
  finishReason: response.finishReason,
235
365
  usage: response.usage,
236
366
  duration: response.duration,
367
+ ...(routing && {
368
+ routing: {
369
+ smartRouted: true,
370
+ complexity: routing.complexity.tier,
371
+ savings: `${routing.savingsPercent}%`,
372
+ estimatedCost: `$${routing.estimatedCost.toFixed(4)}`,
373
+ summary: getCostComparison(routing),
374
+ },
375
+ }),
237
376
  });
238
377
  }
239
378
  catch (error) {
@@ -751,14 +890,62 @@ chatRoutes.post("/conversations/:id/compact", async (c) => {
751
890
  return c.json({ error: "Failed to compact conversation" }, 500);
752
891
  }
753
892
  });
893
+ /**
894
+ * DELETE /api/chat/conversations/:id/messages/:messageId
895
+ * Delete a single message from a conversation
896
+ */
897
+ chatRoutes.delete("/conversations/:id/messages/:messageId", async (c) => {
898
+ const conversationId = c.req.param("id");
899
+ const messageId = c.req.param("messageId");
900
+ try {
901
+ const conversation = await getConversation(conversationId);
902
+ if (!conversation) {
903
+ return c.json({ error: "Conversation not found" }, 404);
904
+ }
905
+ await deleteMessage(conversationId, messageId);
906
+ return c.json({ success: true });
907
+ }
908
+ catch (error) {
909
+ logger.error("[Chat] Delete message error:", error instanceof Error ? error : undefined);
910
+ return c.json({ error: "Failed to delete message" }, 500);
911
+ }
912
+ });
913
+ /**
914
+ * GET /api/chat/conversations/:id/export
915
+ * Export a conversation as JSON
916
+ */
917
+ chatRoutes.get("/conversations/:id/export", async (c) => {
918
+ const conversationId = c.req.param("id");
919
+ try {
920
+ const conversation = await getConversation(conversationId);
921
+ if (!conversation) {
922
+ return c.json({ error: "Conversation not found" }, 404);
923
+ }
924
+ const messages = await getConversationMessages(conversationId);
925
+ return c.json({
926
+ conversation: {
927
+ id: conversation.id,
928
+ title: conversation.title,
929
+ createdAt: conversation.createdAt,
930
+ },
931
+ messages,
932
+ exportedAt: new Date().toISOString(),
933
+ });
934
+ }
935
+ catch (error) {
936
+ logger.error("[Chat] Export conversation error:", error instanceof Error ? error : undefined);
937
+ return c.json({ error: "Failed to export conversation" }, 500);
938
+ }
939
+ });
754
940
  /**
755
941
  * POST /api/chat/conversations/:id/messages
756
942
  * Send a message in a conversation (with context and history)
757
943
  */
758
- chatRoutes.post("/conversations/:id/messages", zValidator("json", z.object({
944
+ chatRoutes.post("/conversations/:id/messages", chatRateLimiter, contentFilter(), zValidator("json", z.object({
759
945
  content: z.string(),
760
946
  model: z.string().optional(),
761
947
  temperature: z.number().min(0).max(2).optional(),
948
+ stream: z.boolean().optional(),
762
949
  })), async (c) => {
763
950
  const conversationId = c.req.param("id");
764
951
  const body = c.req.valid("json");
@@ -870,7 +1057,56 @@ chatRoutes.post("/conversations/:id/messages", zValidator("json", z.object({
870
1057
  content: m.content,
871
1058
  timestamp: m.createdAt,
872
1059
  }));
873
- // Send to AI
1060
+ // Streaming branch
1061
+ if (body.stream) {
1062
+ return streamText(c, async (stream) => {
1063
+ try {
1064
+ let fullContent = "";
1065
+ const response = await aiProvider.chatStream({
1066
+ messages: chatMessages,
1067
+ model: body.model,
1068
+ systemPrompt,
1069
+ temperature: body.temperature,
1070
+ }, (chunk) => {
1071
+ fullContent += chunk;
1072
+ stream
1073
+ .write(`data: ${JSON.stringify({ content: chunk })}\n\n`)
1074
+ .catch((err) => {
1075
+ logger.error("[Chat] Stream write error:", err instanceof Error ? err : undefined);
1076
+ });
1077
+ });
1078
+ // Save assistant response after streaming completes
1079
+ const assistantMessage = await addMessage({
1080
+ conversationId,
1081
+ role: "assistant",
1082
+ content: fullContent || response.content,
1083
+ model: response.model,
1084
+ provider: response.provider,
1085
+ tokenUsage: response.usage
1086
+ ? {
1087
+ prompt: response.usage.promptTokens,
1088
+ completion: response.usage.completionTokens,
1089
+ total: response.usage.totalTokens,
1090
+ }
1091
+ : undefined,
1092
+ cost: response.usage?.cost,
1093
+ });
1094
+ await stream.write(`data: ${JSON.stringify({
1095
+ done: true,
1096
+ usage: response.usage,
1097
+ messageId: assistantMessage.id,
1098
+ compaction: compactionInfo,
1099
+ })}\n\n`);
1100
+ }
1101
+ catch (error) {
1102
+ logger.error("[Chat] Conversation stream error:", error instanceof Error ? error : undefined);
1103
+ await stream.write(`data: ${JSON.stringify({
1104
+ error: error instanceof Error ? error.message : "Failed to send message",
1105
+ })}\n\n`);
1106
+ }
1107
+ });
1108
+ }
1109
+ // Send to AI (non-streaming)
874
1110
  const response = await aiProvider.chat({
875
1111
  messages: chatMessages,
876
1112
  model: body.model,
@@ -915,7 +1151,7 @@ chatRoutes.post("/conversations/:id/messages", zValidator("json", z.object({
915
1151
  * POST /api/chat/conversations/:id/messages/with-tools
916
1152
  * Send a message in a conversation with native tool calling enabled
917
1153
  */
918
- chatRoutes.post("/conversations/:id/messages/with-tools", zValidator("json", z.object({
1154
+ chatRoutes.post("/conversations/:id/messages/with-tools", chatRateLimiter, contentFilter(), zValidator("json", z.object({
919
1155
  content: z.string(),
920
1156
  model: z.string().optional(),
921
1157
  temperature: z.number().min(0).max(2).optional(),
@@ -993,6 +1229,10 @@ chatRoutes.post("/conversations/:id/messages/with-tools", zValidator("json", z.o
993
1229
  const tools = enableTools
994
1230
  ? getChatToolsForModel(modelId, { conversationId })
995
1231
  : [];
1232
+ logger.info(`[Chat] Tools for ${modelId}: ${tools.length} (enableTools=${enableTools})`, {
1233
+ component: 'Chat',
1234
+ toolNames: tools.map(t => t.name).join(', '),
1235
+ });
996
1236
  // Build system prompt with context and tool mode
997
1237
  const systemPrompt = await buildSystemPrompt(conversation.presetId, context, {
998
1238
  enableTools: enableTools && tools.length > 0,
@@ -1322,7 +1562,7 @@ chatRoutes.post("/with-tools", zValidator("json", z.object({
1322
1562
  * - complete - Session complete
1323
1563
  * - error - Error occurred
1324
1564
  */
1325
- chatRoutes.post("/conversations/:id/messages/agentic", zValidator("json", z.object({
1565
+ chatRoutes.post("/conversations/:id/messages/agentic", chatRateLimiter, contentFilter(), zValidator("json", z.object({
1326
1566
  content: z.string(),
1327
1567
  model: z.string().optional(),
1328
1568
  provider: z.string().optional(),
@@ -1385,8 +1625,6 @@ chatRoutes.post("/conversations/:id/messages/agentic", zValidator("json", z.obje
1385
1625
  conversationId,
1386
1626
  sessionOverride,
1387
1627
  };
1388
- // Get tools - agentic mode uses model-aware filtering
1389
- const tools = getChatToolsForModel(resolvedRef.model, { conversationId, includeAll: true });
1390
1628
  // Build system prompt with agent mode (uses AGENT_MODE_SUFFIX)
1391
1629
  const systemPrompt = await buildSystemPrompt(conversation.presetId, context, {
1392
1630
  agentMode: true,
@@ -1429,11 +1667,14 @@ chatRoutes.post("/conversations/:id/messages/agentic", zValidator("json", z.obje
1429
1667
  content: m.content,
1430
1668
  timestamp: m.createdAt,
1431
1669
  }));
1432
- // Create tool handler
1670
+ // Create tool handler (triggers tool registration if first call)
1433
1671
  const toolHandler = await createChatToolHandler({
1434
1672
  conversationId,
1435
1673
  securityMode: "full", // Full access in agentic mode (tools are pre-approved)
1436
1674
  });
1675
+ // Get tools AFTER handler init (registry is now populated)
1676
+ const tools = getChatToolsForModel(resolvedRef.model, { conversationId });
1677
+ logger.info(`[Chat/Agentic] Tools for model ${resolvedRef.model}: ${tools.length}`);
1437
1678
  // Set up SSE streaming response
1438
1679
  c.header("Content-Type", "text/event-stream");
1439
1680
  c.header("Cache-Control", "no-cache");
@@ -1491,11 +1732,15 @@ chatRoutes.post("/conversations/:id/messages/agentic", zValidator("json", z.obje
1491
1732
  provider: body.provider,
1492
1733
  temperature: body.temperature,
1493
1734
  toolHandler,
1494
- tools: tools.map((t) => ({
1495
- name: t.name,
1496
- description: t.description,
1497
- parameters: t.parameters,
1498
- })),
1735
+ tools: (() => {
1736
+ const mapped = tools.map((t) => ({
1737
+ name: t.name,
1738
+ description: t.description,
1739
+ parameters: t.parameters,
1740
+ }));
1741
+ logger.info(`[Chat/Agentic] Sending ${mapped.length} tools: [${mapped.map(t => t.name).join(', ')}]`);
1742
+ return mapped;
1743
+ })(),
1499
1744
  showThinking: body.showThinking,
1500
1745
  maxSteps: body.maxSteps,
1501
1746
  maxBudget: body.maxBudget,
@@ -2,6 +2,7 @@ import { Hono } from 'hono';
2
2
  import { getUsageSummary } from '../costs/token-tracker.js';
3
3
  import { getBudgetStatus } from '../costs/budget.js';
4
4
  import { getStorage } from '../storage/index.js';
5
+ import { getRoutingStats, getCostOptimizationAdvice } from '../providers/smart-router.js';
5
6
  const costs = new Hono();
6
7
  // Get usage summary
7
8
  costs.get('/summary', (c) => {
@@ -19,6 +20,37 @@ costs.get('/analytics', async (c) => {
19
20
  const analytics = await storage.getCostAnalytics();
20
21
  return c.json(analytics);
21
22
  });
23
+ // Get smart routing stats (savings from auto-routing)
24
+ costs.get('/routing', (_c) => {
25
+ const stats = getRoutingStats();
26
+ return _c.json({
27
+ success: true,
28
+ data: {
29
+ ...stats,
30
+ totalSaved: `$${stats.totalSaved.toFixed(4)}`,
31
+ avgSavingsPercent: `${Math.round(stats.avgSavingsPercent)}%`,
32
+ message: stats.totalRouted > 0
33
+ ? `Smart routing saved $${stats.totalSaved.toFixed(2)} across ${stats.totalRouted} requests (avg ${Math.round(stats.avgSavingsPercent)}% savings)`
34
+ : 'No queries routed yet. Smart routing will show savings as you use profClaw.',
35
+ },
36
+ });
37
+ });
38
+ // Get cost optimization advice
39
+ costs.get('/optimize', async (c) => {
40
+ // Get configured providers dynamically
41
+ const { aiProvider } = await import('../providers/ai-sdk.js');
42
+ const providers = new Set(aiProvider.getConfiguredProviders());
43
+ const advice = getCostOptimizationAdvice(providers);
44
+ return c.json({
45
+ success: true,
46
+ data: {
47
+ configuredProviders: [...providers],
48
+ providerCount: providers.size,
49
+ recommendations: advice,
50
+ optimalSetup: advice.some(a => a.action.includes('cost-optimal')),
51
+ },
52
+ });
53
+ });
22
54
  // Export cost report as CSV
23
55
  costs.get('/export', async (c) => {
24
56
  const format = c.req.query('format') || 'csv';
@@ -9,6 +9,7 @@ import { zValidator } from '@hono/zod-validator';
9
9
  import { z } from 'zod';
10
10
  import { createScheduledJob, getScheduledJob, listScheduledJobs, updateScheduledJob, pauseScheduledJob, resumeScheduledJob, deleteScheduledJob, archiveScheduledJob, restoreScheduledJob, triggerScheduledJob, getJobRunHistory, getScheduler, } from '../cron/scheduler.js';
11
11
  import { listJobTemplates, getJobTemplate, createJobTemplate, deleteJobTemplate, applyJobTemplate, initBuiltInTemplates, } from '../cron/templates.js';
12
+ import { parseNaturalLanguage, cronToHuman } from '../cron/natural-language.js';
12
13
  import { createContextualLogger } from '../utils/logger.js';
13
14
  const log = createContextualLogger('CronRoutes');
14
15
  const app = new Hono();
@@ -34,7 +35,7 @@ app.use('*', async (_c, next) => {
34
35
  });
35
36
  // Schemas
36
37
  const deliveryChannelSchema = z.object({
37
- type: z.enum(['slack', 'webhook', 'email']),
38
+ type: z.enum(['slack', 'webhook', 'email', 'telegram', 'discord']),
38
39
  target: z.string(),
39
40
  onSuccess: z.boolean().optional(),
40
41
  onFailure: z.boolean().optional(),
@@ -64,7 +65,7 @@ const createJobSchema = z.object({
64
65
  // Event trigger (alternative to schedule)
65
66
  eventTrigger: eventTriggerSchema.optional(),
66
67
  // Execution
67
- jobType: z.enum(['http', 'tool', 'script', 'message']),
68
+ jobType: z.enum(['http', 'tool', 'script', 'message', 'agent_session']),
68
69
  payload: z.record(z.any()),
69
70
  templateId: z.string().optional(),
70
71
  // Delivery
@@ -98,7 +99,7 @@ const updateJobSchema = z.object({
98
99
  });
99
100
  const listQuerySchema = z.object({
100
101
  status: z.enum(['active', 'paused', 'completed', 'failed', 'archived']).optional(),
101
- jobType: z.enum(['http', 'tool', 'script', 'message']).optional(),
102
+ jobType: z.enum(['http', 'tool', 'script', 'message', 'agent_session']).optional(),
102
103
  projectId: z.string().optional(),
103
104
  userId: z.string().optional(),
104
105
  limit: z.coerce.number().min(1).max(100).optional().default(50),
@@ -107,8 +108,8 @@ const createTemplateSchema = z.object({
107
108
  name: z.string().min(1).max(100),
108
109
  description: z.string().max(500).optional(),
109
110
  icon: z.string().max(10).optional(),
110
- category: z.enum(['sync', 'report', 'cleanup', 'notification', 'monitoring', 'custom']).optional(),
111
- jobType: z.enum(['http', 'tool', 'script', 'message']),
111
+ category: z.enum(['sync', 'report', 'cleanup', 'notification', 'monitoring', 'automation', 'custom']).optional(),
112
+ jobType: z.enum(['http', 'tool', 'script', 'message', 'agent_session']),
112
113
  payloadTemplate: z.record(z.any()),
113
114
  suggestedCron: z.string().optional(),
114
115
  suggestedIntervalMs: z.number().min(1000).optional(),
@@ -166,6 +167,79 @@ app.get('/jobs', zValidator('query', listQuerySchema), async (c) => {
166
167
  }, 500);
167
168
  }
168
169
  });
170
+ /**
171
+ * POST /api/cron/automate - Create a job from natural language
172
+ *
173
+ * Example: { "input": "every morning at 8am summarize my GitHub notifications and send to telegram" }
174
+ *
175
+ * Returns the parsed schedule, intent, and delivery - then creates the job.
176
+ * Use ?dryRun=true to preview without creating.
177
+ */
178
+ app.post('/automate', zValidator('json', z.object({
179
+ input: z.string().min(5).max(500),
180
+ })), async (c) => {
181
+ try {
182
+ const { input } = c.req.valid('json');
183
+ const dryRun = c.req.query('dryRun') === 'true';
184
+ const result = parseNaturalLanguage(input);
185
+ if (!result.success || !result.jobParams) {
186
+ return c.json({
187
+ success: false,
188
+ error: result.error ?? 'Could not understand the request',
189
+ parsed: {
190
+ schedule: result.schedule,
191
+ intent: result.intent,
192
+ delivery: result.delivery,
193
+ },
194
+ hint: 'Try: "every morning at 8am summarize GitHub notifications and send to telegram"',
195
+ }, 400);
196
+ }
197
+ // Dry run: return what would be created
198
+ if (dryRun) {
199
+ return c.json({
200
+ success: true,
201
+ dryRun: true,
202
+ parsed: {
203
+ schedule: result.schedule,
204
+ intent: result.intent,
205
+ delivery: result.delivery,
206
+ humanReadable: result.schedule?.humanReadable,
207
+ cronExpression: result.jobParams.cronExpression,
208
+ cronExplained: result.jobParams.cronExpression
209
+ ? cronToHuman(result.jobParams.cronExpression)
210
+ : undefined,
211
+ },
212
+ jobParams: result.jobParams,
213
+ message: `Would create: "${result.jobParams.name}" running ${result.schedule?.humanReadable ?? 'on schedule'}`,
214
+ });
215
+ }
216
+ // Create the job
217
+ const job = await createScheduledJob(result.jobParams);
218
+ log.info(`Created job from natural language: ${job.name} (${job.id})`, {
219
+ input: input.slice(0, 80),
220
+ cron: result.jobParams.cronExpression,
221
+ schedule: result.schedule?.humanReadable,
222
+ });
223
+ return c.json({
224
+ success: true,
225
+ job,
226
+ parsed: {
227
+ schedule: result.schedule?.humanReadable,
228
+ cronExpression: result.jobParams.cronExpression,
229
+ intent: result.intent?.action,
230
+ delivery: result.delivery?.channel,
231
+ },
232
+ message: `Created "${job.name}" - ${result.schedule?.humanReadable ?? 'scheduled'}`,
233
+ }, 201);
234
+ }
235
+ catch (error) {
236
+ log.error('Failed to create job from natural language:', error instanceof Error ? error : new Error(String(error)));
237
+ return c.json({
238
+ success: false,
239
+ error: error instanceof Error ? error.message : 'Failed to create automation',
240
+ }, 500);
241
+ }
242
+ });
169
243
  /**
170
244
  * POST /api/cron/jobs - Create a scheduled job
171
245
  * Supports: cron, interval, one-shot (runAt), or event-triggered
@@ -534,6 +608,7 @@ app.get('/stats', async (c) => {
534
608
  tool: activeJobs.filter((j) => j.jobType === 'tool').length,
535
609
  script: activeJobs.filter((j) => j.jobType === 'script').length,
536
610
  message: activeJobs.filter((j) => j.jobType === 'message').length,
611
+ agent_session: activeJobs.filter((j) => j.jobType === 'agent_session').length,
537
612
  },
538
613
  byScheduleType: {
539
614
  cron: activeJobs.filter((j) => j.cronExpression).length,
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Feed Routes
3
+ *
4
+ * REST API for managing RSS/Atom feeds and article digests.
5
+ * All endpoints are under /api/feeds.
6
+ */
7
+ import { Hono } from 'hono';
8
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
9
+ export default app;
10
+ //# sourceMappingURL=feeds.d.ts.map