@pheem49/mint 1.5.5 → 1.6.1

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 (222) hide show
  1. package/.codex +0 -0
  2. package/.github/FUNDING.yml +2 -0
  3. package/.github/workflows/ci.yml +45 -0
  4. package/.github/workflows/release.yml +79 -0
  5. package/Cargo.lock +5792 -0
  6. package/Cargo.toml +32 -0
  7. package/README.md +387 -353
  8. package/assets/icon.png +0 -0
  9. package/bin/mint +0 -0
  10. package/crates/mint-cli/Cargo.toml +23 -0
  11. package/crates/mint-cli/src/agent.rs +851 -0
  12. package/crates/mint-cli/src/gmail.rs +216 -0
  13. package/crates/mint-cli/src/image.rs +142 -0
  14. package/crates/mint-cli/src/main.rs +2837 -0
  15. package/crates/mint-cli/src/mcp.rs +63 -0
  16. package/crates/mint-cli/src/onboard.rs +1149 -0
  17. package/crates/mint-cli/src/setup.rs +390 -0
  18. package/crates/mint-cli/src/skills.rs +8 -0
  19. package/crates/mint-cli/src/updater.rs +279 -0
  20. package/crates/mint-core/Cargo.toml +22 -0
  21. package/crates/mint-core/src/agent_loop.rs +94 -0
  22. package/crates/mint-core/src/api_server.rs +991 -0
  23. package/crates/mint-core/src/channels.rs +248 -0
  24. package/crates/mint-core/src/chat.rs +895 -0
  25. package/crates/mint-core/src/code_tools.rs +729 -0
  26. package/crates/mint-core/src/config.rs +368 -0
  27. package/crates/mint-core/src/files.rs +159 -0
  28. package/crates/mint-core/src/knowledge.rs +541 -0
  29. package/crates/mint-core/src/lib.rs +84 -0
  30. package/crates/mint-core/src/mcp.rs +273 -0
  31. package/crates/mint-core/src/memory.rs +673 -0
  32. package/crates/mint-core/src/orchestration.rs +2157 -0
  33. package/crates/mint-core/src/pictures.rs +314 -0
  34. package/crates/mint-core/src/plugins.rs +727 -0
  35. package/crates/mint-core/src/safety.rs +416 -0
  36. package/crates/mint-core/src/semantic.rs +254 -0
  37. package/crates/mint-core/src/shell.rs +317 -0
  38. package/crates/mint-core/src/skills.rs +71 -0
  39. package/crates/mint-core/src/symbols.rs +157 -0
  40. package/crates/mint-core/src/tasks.rs +308 -0
  41. package/crates/mint-core/src/tts.rs +92 -0
  42. package/crates/mint-core/src/weather.rs +93 -0
  43. package/crates/mint-core/src/web_search.rs +200 -0
  44. package/crates/mint-core/src/workflows.rs +81 -0
  45. package/crates/mint-core/tests/mcp_stdio.rs +45 -0
  46. package/crates/mint-core/tests/memory_persistence.rs +172 -0
  47. package/crates/mint-core/tests/pictures_storage.rs +14 -0
  48. package/crates/mint-core/tests/task_lifecycle.rs +87 -0
  49. package/package.json +35 -99
  50. package/src/bin/index.js +16 -0
  51. package/src/renderer/index-web.html +17 -0
  52. package/src/renderer/index.html +17 -0
  53. package/src/renderer/public/Live2DCubismCore.js +9 -0
  54. package/src/renderer/public/assets/icon.png +0 -0
  55. package/src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.model3.json +36 -0
  56. package/src/renderer/src/App.tsx +33 -0
  57. package/src/renderer/src/calculator.ts +47 -0
  58. package/src/renderer/src/components/ChatPanel.tsx +1598 -0
  59. package/src/renderer/src/components/DashboardSidebar.tsx +358 -0
  60. package/src/renderer/src/components/Live2DStage.tsx +374 -0
  61. package/src/renderer/src/components/MintDashboard.tsx +950 -0
  62. package/src/renderer/src/components/ModelPanel.tsx +154 -0
  63. package/src/renderer/src/components/PicturesLibrary.tsx +46 -0
  64. package/src/renderer/src/components/ProactiveGlow.tsx +19 -0
  65. package/src/renderer/src/components/ScreenPicker.tsx +579 -0
  66. package/src/renderer/src/components/SettingsWindow.tsx +1467 -0
  67. package/src/renderer/src/components/SpotlightWindow.tsx +280 -0
  68. package/src/renderer/src/components/WidgetWindow.tsx +36 -0
  69. package/src/renderer/src/components/WorkspacePanel.tsx +268 -0
  70. package/src/{UI → renderer/src/css}/settings.css +69 -16
  71. package/src/renderer/src/css/spotlight.css +113 -0
  72. package/src/renderer/src/css/styles.css +3722 -0
  73. package/src/renderer/src/css/widget.css +185 -0
  74. package/src/renderer/src/env.d.ts +116 -0
  75. package/src/renderer/src/index.css +379 -0
  76. package/src/renderer/src/main.tsx +13 -0
  77. package/src/renderer/src/tauri.ts +996 -0
  78. package/src/renderer/src-web/App.tsx +25 -0
  79. package/src/renderer/src-web/calculator.ts +47 -0
  80. package/src/renderer/src-web/components/ChatPanel.tsx +1662 -0
  81. package/src/renderer/src-web/components/DashboardSidebar.tsx +242 -0
  82. package/src/renderer/src-web/components/MintDashboard.tsx +763 -0
  83. package/src/renderer/src-web/components/PicturesLibrary.tsx +73 -0
  84. package/src/renderer/src-web/components/SettingsWindow.tsx +1500 -0
  85. package/src/renderer/src-web/css/settings.css +1100 -0
  86. package/src/{UI → renderer/src-web/css}/spotlight.css +4 -4
  87. package/src/{UI → renderer/src-web/css}/styles.css +1055 -159
  88. package/src/{UI → renderer/src-web/css}/widget.css +2 -2
  89. package/src/renderer/src-web/env.d.ts +107 -0
  90. package/src/renderer/src-web/index.css +379 -0
  91. package/src/renderer/src-web/main.tsx +13 -0
  92. package/src/renderer/src-web/tauri.ts +983 -0
  93. package/tsconfig.json +30 -0
  94. package/vite.config.ts +33 -0
  95. package/vite.config.web.ts +51 -0
  96. package/GUIDE_TH.md +0 -125
  97. package/assets/Agent_Mint.png +0 -0
  98. package/assets/CLI_Screen.png +0 -0
  99. package/assets/Settings.png +0 -0
  100. package/benchmark_ai.js +0 -71
  101. package/install.ps1 +0 -64
  102. package/install.sh +0 -54
  103. package/main.js +0 -139
  104. package/mint-cli-logic.js +0 -3
  105. package/mint-cli.js +0 -410
  106. package/models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.model3.json +0 -47
  107. package/models/Shiroko_Model/Shiroko//342/232/241/351/253/230/344/272/256/342/232/241/344/275/277/347/224/250/346/225/231/347/250/213/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.txt +0 -23
  108. package/preload-picker.js +0 -11
  109. package/preload-settings.js +0 -11
  110. package/preload.js +0 -41
  111. package/scripts/install_linux_desktop_entry.js +0 -48
  112. package/src/AI_Brain/Gemini_API.js +0 -813
  113. package/src/AI_Brain/agent_orchestrator.js +0 -73
  114. package/src/AI_Brain/autonomous_brain.js +0 -179
  115. package/src/AI_Brain/behavior_memory.js +0 -135
  116. package/src/AI_Brain/headless_agent.js +0 -143
  117. package/src/AI_Brain/knowledge_base.js +0 -349
  118. package/src/AI_Brain/memory_store.js +0 -662
  119. package/src/AI_Brain/proactive_engine.js +0 -172
  120. package/src/AI_Brain/provider_adapter.js +0 -365
  121. package/src/Automation_Layer/browser_automation.js +0 -149
  122. package/src/Automation_Layer/file_operations.js +0 -286
  123. package/src/Automation_Layer/open_app.js +0 -85
  124. package/src/Automation_Layer/open_website.js +0 -38
  125. package/src/CLI/approval_handler.js +0 -47
  126. package/src/CLI/chat_router.js +0 -247
  127. package/src/CLI/chat_ui.js +0 -1159
  128. package/src/CLI/cli_colors.js +0 -115
  129. package/src/CLI/cli_formatters.js +0 -94
  130. package/src/CLI/code_agent.js +0 -1667
  131. package/src/CLI/code_session_memory.js +0 -62
  132. package/src/CLI/gmail_auth.js +0 -210
  133. package/src/CLI/image_input.js +0 -90
  134. package/src/CLI/intent_detectors.js +0 -181
  135. package/src/CLI/interactive_chat.js +0 -658
  136. package/src/CLI/list_features.js +0 -64
  137. package/src/CLI/onboarding.js +0 -416
  138. package/src/CLI/repo_summarizer.js +0 -282
  139. package/src/CLI/semantic_code_search.js +0 -312
  140. package/src/CLI/skill_manager.js +0 -41
  141. package/src/CLI/slash_command_handler.js +0 -418
  142. package/src/CLI/symbol_indexer.js +0 -231
  143. package/src/CLI/updater.js +0 -230
  144. package/src/CLI/workspace_manager.js +0 -90
  145. package/src/Channels/brave_search_bridge.js +0 -35
  146. package/src/Channels/discord_bridge.js +0 -66
  147. package/src/Channels/google_search_bridge.js +0 -38
  148. package/src/Channels/line_bridge.js +0 -60
  149. package/src/Channels/slack_bridge.js +0 -48
  150. package/src/Channels/telegram_bridge.js +0 -41
  151. package/src/Channels/whatsapp_bridge.js +0 -57
  152. package/src/Command_Parser/parser.js +0 -45
  153. package/src/Plugins/dev_tools.js +0 -41
  154. package/src/Plugins/discord.js +0 -20
  155. package/src/Plugins/docker.js +0 -47
  156. package/src/Plugins/gmail.js +0 -251
  157. package/src/Plugins/google_calendar.js +0 -252
  158. package/src/Plugins/mcp_manager.js +0 -95
  159. package/src/Plugins/notion.js +0 -256
  160. package/src/Plugins/obsidian.js +0 -54
  161. package/src/Plugins/plugin_manager.js +0 -81
  162. package/src/Plugins/spotify.js +0 -173
  163. package/src/Plugins/system_metrics.js +0 -31
  164. package/src/Plugins/system_monitor.js +0 -72
  165. package/src/System/action_executor.js +0 -178
  166. package/src/System/bridge_manager.js +0 -76
  167. package/src/System/chat_history_manager.js +0 -83
  168. package/src/System/config_manager.js +0 -194
  169. package/src/System/custom_workflows.js +0 -163
  170. package/src/System/daemon_manager.js +0 -67
  171. package/src/System/google_tts_urls.js +0 -51
  172. package/src/System/granular_automation.js +0 -157
  173. package/src/System/ipc_handlers.js +0 -332
  174. package/src/System/notifications.js +0 -23
  175. package/src/System/optional_require.js +0 -23
  176. package/src/System/picture_store.js +0 -109
  177. package/src/System/proactive_loop.js +0 -153
  178. package/src/System/safety_manager.js +0 -273
  179. package/src/System/sandbox_runner.js +0 -182
  180. package/src/System/screen_capture.js +0 -175
  181. package/src/System/smart_context.js +0 -227
  182. package/src/System/system_automation.js +0 -162
  183. package/src/System/system_events.js +0 -79
  184. package/src/System/system_info.js +0 -125
  185. package/src/System/task_manager.js +0 -222
  186. package/src/System/tool_registry.js +0 -293
  187. package/src/System/window_manager.js +0 -220
  188. package/src/UI/floating.css +0 -80
  189. package/src/UI/floating.html +0 -17
  190. package/src/UI/floating.js +0 -67
  191. package/src/UI/live2d_manager.js +0 -600
  192. package/src/UI/preload-floating.js +0 -7
  193. package/src/UI/preload-spotlight.js +0 -11
  194. package/src/UI/preload-widget.js +0 -5
  195. package/src/UI/proactive-glow.html +0 -42
  196. package/src/UI/renderer.js +0 -2127
  197. package/src/UI/screenPicker.html +0 -214
  198. package/src/UI/screenPicker.js +0 -262
  199. package/src/UI/settings.html +0 -577
  200. package/src/UI/settings.js +0 -770
  201. package/src/UI/spotlight.html +0 -23
  202. package/src/UI/spotlight.js +0 -185
  203. package/src/UI/widget.html +0 -29
  204. package/src/UI/widget.js +0 -10
  205. /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/72d86db84cfa9730b894c241fd24c0db.png +0 -0
  206. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//345/233/264/350/243/231.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/apron.exp3.json} +0 -0
  207. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/214/253/345/222/252/346/273/244/351/225/234.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/catfilter.exp3.json} +0 -0
  208. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/202/271/344/270/200/344/270/213.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/click.exp3.json} +0 -0
  209. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/dazed.exp3.json} +0 -0
  210. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253/347/234/274/347/217/240/346/221/207/346/231/203.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/dazedeyes.exp3.json} +0 -0
  211. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//347/234/274/351/225/234.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/glasses.exp3.json} +0 -0
  212. /package/{models → src/renderer/public/models}/Shiroko_Model/Shiroko/Shiroko_Core/items_pinned_to_model.json +0 -0
  213. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/277/347/254/224.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/pen.exp3.json} +0 -0
  214. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//346/213/215/347/205/247.exp3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/photo.exp3.json} +0 -0
  215. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_00.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_00.png} +0 -0
  216. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_01.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_01.png} +0 -0
  217. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_02.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_02.png} +0 -0
  218. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.4096/texture_03.png" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.4096/texture_03.png} +0 -0
  219. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.cdi3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.cdi3.json} +0 -0
  220. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.moc3" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.moc3} +0 -0
  221. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.physics3.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.physics3.json} +0 -0
  222. /package/{models/Shiroko_Model/Shiroko/Shiroko_Core//351/235/242/351/245/2740.vtube.json" → src/renderer/public/models/Shiroko_Model/Shiroko/Shiroko_Core/shiroko.vtube.json} +0 -0
@@ -1,247 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { GoogleGenAI } = require('@google/genai');
4
- const { executeCodeTask, _helpers: codeAgentHelpers } = require('./code_agent');
5
- const { readConfig, getAvailableProviders } = require('../System/config_manager');
6
-
7
- const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash';
8
-
9
- const CODE_KEYWORDS = [
10
- 'code', 'repo', 'repository', 'project', 'workspace', 'file', 'files', 'readme',
11
- 'package.json', 'bug', 'fix', 'refactor', 'test', 'tests', 'build', 'lint',
12
- 'implement', 'feature', 'cli', 'function', 'module', 'component', 'diff',
13
- 'list', 'show', 'ls', 'dir', 'directory', 'folders' // เพิ่มคำเหล่านี้ค่ะ
14
- ];
15
-
16
-
17
- const THAI_CODE_KEYWORDS = [
18
- 'โค้ด', 'โปรเจค', 'โปรเจ็กต์', 'ไฟล์', 'รีโป', 'บั๊ก', 'แก้', 'ทดสอบ', 'เทสต์',
19
- 'รีแฟกเตอร์', 'ฟีเจอร์', 'คอมโพเนนต์', 'ฟังก์ชัน', 'อ่าน', 'สำรวจ', 'โครงสร้าง',
20
- 'ไดเรกทอรี', 'โฟลเดอร์'
21
- ];
22
-
23
- const ROUTER_PROMPT = `You classify whether a chat message should be routed to a coding agent for the current local workspace.
24
-
25
- Return JSON only:
26
- {
27
- "route": "code" | "chat",
28
- "reason": "short explanation"
29
- }
30
-
31
- Choose "code" when the user is asking to inspect, edit, review, debug, explain, refactor, verify, or otherwise operate on the current project/workspace/codebase/files.
32
- Choose "chat" for general conversation, factual Q&A, small/simple requests, non-code assistant tasks, or direct file-system actions like finding/opening a folder or file by name.
33
- Only choose "code" for substantial coding work that likely needs multiple steps, workspace inspection, edits, verification, or project-wide reasoning.`;
34
-
35
- function isDirectFilesystemActionRequest(text) {
36
- const input = (text || '').trim().toLowerCase();
37
- if (!input) return false;
38
-
39
- const filesystemActionPattern = /(open|find|locate|search for|look for|หา|ค้นหา|เปิด)/;
40
- const filesystemTargetPattern = /(folder|directory|dir|file|โฟลเดอร์|ไฟล์|ไดเรกทอรี)/;
41
- const codeOperationPattern = /(inspect|review|refactor|debug|implement|edit|change|fix|explain|analyze|สำรวจ|รีวิว|รีแฟกเตอร์|แก้|อธิบาย|วิเคราะห์)/;
42
-
43
- return filesystemActionPattern.test(input) && filesystemTargetPattern.test(input) && !codeOperationPattern.test(input);
44
- }
45
-
46
- function workspaceLooksLikeCodebase(workspaceRoot) {
47
- const markers = [
48
- 'package.json',
49
- '.git',
50
- 'src',
51
- 'README.md',
52
- 'tsconfig.json',
53
- 'Cargo.toml',
54
- 'pyproject.toml'
55
- ];
56
- return markers.some(marker => fs.existsSync(path.join(workspaceRoot, marker)));
57
- }
58
-
59
- function detectCodeIntentHeuristic(text, workspaceRoot = process.cwd()) {
60
- const input = (text || '').trim().toLowerCase();
61
- if (!input) return false;
62
- if (input.startsWith('/code ')) return true;
63
- if (isDirectFilesystemActionRequest(input)) return false;
64
-
65
- return isLargeCodeTaskRequest(input, workspaceRoot);
66
- }
67
-
68
- function isLargeCodeTaskRequest(text, workspaceRoot = process.cwd()) {
69
- const input = (text || '').trim().toLowerCase();
70
- if (!input) return false;
71
- if (!workspaceLooksLikeCodebase(workspaceRoot)) return false;
72
-
73
- const hasCodeKeyword = CODE_KEYWORDS.some(keyword => input.includes(keyword));
74
- const hasThaiCodeKeyword = THAI_CODE_KEYWORDS.some(keyword => input.includes(keyword));
75
- const referencesProject = /โปรเจคนี้|โปรเจ็กต์นี้|this project|this repo|this repository|codebase|workspace|โฟลเดอร์นี้|ในนี้/.test(input);
76
- const asksForAction = /สำรวจ|ดู|แก้|เพิ่ม|ลบ|ปรับ|ตรวจ|วิเคราะห์|ลิสต์|โชว์|แสดง|มี|implement|inspect|explore|fix|update|change|refactor|review|explain|debug|list|show/.test(input);
77
- const strongTaskSignal = /failing tests?|run tests?|verify|verification|bug|issue|error|refactor|implement|feature|patch|edit|modify|analyze the project|แก้บั๊ก|รันเทสต์|ทดสอบ|ตรวจสอบ|ยืนยันผล|รีแฟกเตอร์|เพิ่มฟีเจอร์|แก้โค้ด|วิเคราะห์โปรเจค/.test(input);
78
- const multiStepSignal = /and|then|พร้อม|แล้ว|จากนั้น|ทั้ง|ทั่วทั้ง|ทั้งโปรเจค|project-wide|entire project|whole project/.test(input);
79
-
80
- // If they ask for files/folder content specifically, it's a code task because Chat can't do it accurately
81
- const isListFilesRequest = (hasCodeKeyword || hasThaiCodeKeyword) && /มี|โชว์|แสดง|ลิสต์|list|show|what|anything|อะไรบ้าง/.test(input) && /ไฟล์|file|folder|dir|โฟลเดอร์/.test(input);
82
-
83
- if (isListFilesRequest) return true;
84
- if (referencesProject && strongTaskSignal) return true;
85
- if ((hasCodeKeyword || hasThaiCodeKeyword) && asksForAction && strongTaskSignal) return true;
86
- if ((hasCodeKeyword || hasThaiCodeKeyword) && multiStepSignal && asksForAction) return true;
87
- return false;
88
- }
89
-
90
- function getRouterClient() {
91
- const config = readConfig();
92
- const apiKey = (config.apiKey || process.env.GEMINI_API_KEY || '').trim();
93
- if (!apiKey) return null;
94
- return {
95
- ai: new GoogleGenAI({ apiKey }),
96
- model: (config.geminiModel || DEFAULT_GEMINI_MODEL).trim() || DEFAULT_GEMINI_MODEL
97
- };
98
- }
99
-
100
- function summarizeWorkspace(workspaceRoot) {
101
- const candidates = ['package.json', 'README.md', 'src', '.git'];
102
- return candidates
103
- .filter(item => fs.existsSync(path.join(workspaceRoot, item)))
104
- .join(', ') || '(no obvious code markers)';
105
- }
106
-
107
- async function detectCodeIntent(text, workspaceRoot = process.cwd(), history = []) {
108
- const input = (text || '').trim();
109
- if (!input) {
110
- return { route: 'chat', reason: 'Empty input.' };
111
- }
112
-
113
- if (input.startsWith('/code ')) {
114
- return { route: 'code', reason: 'Explicit /code command.' };
115
- }
116
-
117
- if (isDirectFilesystemActionRequest(input)) {
118
- return { route: 'chat', reason: 'Direct file-system action request.' };
119
- }
120
-
121
- const heuristicRoute = detectCodeIntentHeuristic(input, workspaceRoot);
122
- if (!heuristicRoute) {
123
- return {
124
- route: 'chat',
125
- reason: 'No substantial code intent detected.'
126
- };
127
- }
128
-
129
- const routerClient = getRouterClient();
130
- if (!routerClient) {
131
- return {
132
- route: heuristicRoute ? 'code' : 'chat',
133
- reason: heuristicRoute ? 'Heuristic code intent match.' : 'Heuristic chat fallback.'
134
- };
135
- }
136
-
137
- try {
138
- const response = await routerClient.ai.models.generateContent({
139
- model: routerClient.model,
140
- config: {
141
- systemInstruction: ROUTER_PROMPT,
142
- responseMimeType: 'application/json'
143
- },
144
- contents: [{
145
- role: 'user',
146
- parts: [{
147
- text: [
148
- `Workspace: ${workspaceRoot}`,
149
- `Workspace markers: ${summarizeWorkspace(workspaceRoot)}`,
150
- `Context (Last 5 turns): ${history.slice(-10).map(m => `${m.sender}: ${m.text}`).join('\n')}`,
151
- `Current Message: ${input}`
152
- ].join('\n')
153
- }]
154
- }]
155
- });
156
-
157
- const textOutput = typeof response.text === 'function' ? response.text() : response.text;
158
- const parsed = JSON.parse(textOutput);
159
- const route = parsed.route === 'code' ? 'code' : 'chat';
160
- if (route === 'code' && !isLargeCodeTaskRequest(input, workspaceRoot)) {
161
- return {
162
- route: 'chat',
163
- reason: 'Request looks small enough for normal chat.'
164
- };
165
- }
166
- return {
167
- route,
168
- reason: parsed.reason || (route === 'code' ? 'Model classified as code.' : 'Model classified as chat.')
169
- };
170
- } catch (error) {
171
- return {
172
- route: heuristicRoute ? 'code' : 'chat',
173
- reason: heuristicRoute ? 'Heuristic fallback after router error.' : 'Chat fallback after router error.'
174
- };
175
- }
176
- }
177
-
178
- async function runChatRoutedTask(input, context) {
179
- const text = input.startsWith('/code ') ? input.slice('/code '.length).trim() : input;
180
- const { appendMessage, setThinking, requestApproval, askUser, setMode, history } = context;
181
-
182
- const config = readConfig();
183
- const availableProviders = getAvailableProviders(config);
184
- const preferredProvider = codeAgentHelpers.selectSupportedCodeProvider(config, availableProviders);
185
-
186
- appendMessage('system', `Routing this request to Code Mode for workspace: ${process.cwd()} using [${preferredProvider}]`);
187
- if (setMode) setMode('Code');
188
-
189
- let seconds = 0;
190
- setThinking(true, seconds);
191
- const timer = setInterval(() => {
192
- seconds++;
193
- setThinking(true, seconds);
194
- }, 1000);
195
-
196
- try {
197
- let streamedFinalSummary = false;
198
- const result = await executeCodeTask(text, {
199
- cwd: process.cwd(),
200
- requestApproval,
201
- askUser,
202
- provider: preferredProvider,
203
- history: history,
204
- onProgress: (info) => {
205
- if (context.appendCodeStep) {
206
- context.appendCodeStep(info);
207
- } else {
208
- appendMessage('system', `[Code] ${typeof info === 'string' ? info : (info.action || info.phase)}`);
209
- }
210
- },
211
- onFinalSummary: async (info) => {
212
- if (typeof context.streamAssistantSentences !== 'function') {
213
- return;
214
- }
215
- clearInterval(timer);
216
- setThinking(false);
217
- streamedFinalSummary = true;
218
- await context.streamAssistantSentences(info.summary, appendMessage, { providerInfo: info.providerInfo }, context.streamMessage);
219
- }
220
- });
221
- clearInterval(timer);
222
- setThinking(false);
223
- if (!streamedFinalSummary) {
224
- appendMessage('assistant', [
225
- `Code Mode finished.`,
226
- result.summary,
227
- `Verification: ${result.verification}`
228
- ].join('\n'), { providerInfo: result.providerInfo });
229
- }
230
- } catch (error) {
231
- clearInterval(timer);
232
- setThinking(false);
233
- appendMessage('error', error.message);
234
- } finally {
235
- if (setMode) setMode('Agent');
236
- }
237
- }
238
-
239
- module.exports = {
240
- detectCodeIntent,
241
- runChatRoutedTask,
242
- _helpers: {
243
- detectCodeIntentHeuristic,
244
- isDirectFilesystemActionRequest,
245
- isLargeCodeTaskRequest
246
- }
247
- };