@phuetz/code-buddy 1.0.0 → 1.2.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 (312) hide show
  1. package/README.md +160 -164
  2. package/dist/agent/autonomous/agentic-coding-contract.d.ts +6 -6
  3. package/dist/agent/codebuddy-agent.d.ts +1 -1
  4. package/dist/agent/codebuddy-agent.js +101 -13
  5. package/dist/agent/execution/agent-executor.js +122 -12
  6. package/dist/agent/execution/tool-dependency-graph.js +7 -0
  7. package/dist/agent/execution/tool-hooks.d.ts +6 -0
  8. package/dist/agent/execution/tool-hooks.js +13 -5
  9. package/dist/agent/execution/tool-selection-strategy.d.ts +11 -2
  10. package/dist/agent/execution/tool-selection-strategy.js +67 -10
  11. package/dist/agent/extended-thinking.d.ts +8 -0
  12. package/dist/agent/extended-thinking.js +27 -0
  13. package/dist/agent/hermes-browser-backends.js +151 -11
  14. package/dist/agent/hermes-claw-migrate.d.ts +59 -0
  15. package/dist/agent/hermes-claw-migrate.js +427 -26
  16. package/dist/agent/hermes-parity-manifest.js +78 -71
  17. package/dist/agent/hermes-runtime-lifecycle.d.ts +67 -0
  18. package/dist/agent/hermes-runtime-lifecycle.js +468 -0
  19. package/dist/agent/lesson-auto-proposer.js +10 -0
  20. package/dist/agent/middleware/index.d.ts +1 -0
  21. package/dist/agent/middleware/index.js +1 -0
  22. package/dist/agent/middleware/session-duration.d.ts +36 -0
  23. package/dist/agent/middleware/session-duration.js +78 -0
  24. package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
  25. package/dist/agent/middleware/visual-validation-middleware.js +67 -0
  26. package/dist/agent/model-benchmark.d.ts +77 -0
  27. package/dist/agent/model-benchmark.js +309 -0
  28. package/dist/agent/model-tier.d.ts +14 -0
  29. package/dist/agent/model-tier.js +71 -0
  30. package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
  31. package/dist/agent/multi-agent/multi-agent-system.js +3 -1
  32. package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
  33. package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
  34. package/dist/agent/multi-agent/session-tools.js +22 -5
  35. package/dist/agent/reasoning/mcts.js +20 -6
  36. package/dist/agent/session-end-flush.d.ts +71 -0
  37. package/dist/agent/session-end-flush.js +233 -0
  38. package/dist/agent/streaming/streaming-handler.d.ts +7 -0
  39. package/dist/agent/streaming/streaming-handler.js +8 -1
  40. package/dist/agent/tool-executor.js +1 -0
  41. package/dist/agent/tool-handler.d.ts +5 -0
  42. package/dist/agent/tool-handler.js +130 -4
  43. package/dist/browser-automation/browser-operator-executor.js +15 -0
  44. package/dist/browser-automation/browser-use-runner.d.ts +96 -0
  45. package/dist/browser-automation/browser-use-runner.js +492 -0
  46. package/dist/browser-automation/camofox-runner.d.ts +107 -0
  47. package/dist/browser-automation/camofox-runner.js +287 -0
  48. package/dist/channels/dingtalk/index.js +3 -0
  49. package/dist/channels/discord/client.d.ts +9 -0
  50. package/dist/channels/discord/client.js +12 -0
  51. package/dist/channels/feishu/index.d.ts +167 -1
  52. package/dist/channels/feishu/index.js +432 -7
  53. package/dist/channels/gateway-lifecycle.d.ts +132 -0
  54. package/dist/channels/gateway-lifecycle.js +219 -0
  55. package/dist/channels/google-chat/index.d.ts +5 -1
  56. package/dist/channels/google-chat/index.js +5 -1
  57. package/dist/channels/imessage/index.d.ts +14 -0
  58. package/dist/channels/imessage/index.js +64 -17
  59. package/dist/channels/index.d.ts +4 -0
  60. package/dist/channels/index.js +4 -0
  61. package/dist/channels/irc/index.d.ts +73 -3
  62. package/dist/channels/irc/index.js +446 -11
  63. package/dist/channels/line/index.js +3 -0
  64. package/dist/channels/mattermost/index.d.ts +51 -4
  65. package/dist/channels/mattermost/index.js +303 -20
  66. package/dist/channels/nextcloud-talk/index.d.ts +89 -8
  67. package/dist/channels/nextcloud-talk/index.js +367 -16
  68. package/dist/channels/nostr/index.d.ts +121 -1
  69. package/dist/channels/nostr/index.js +396 -8
  70. package/dist/channels/ntfy/index.js +3 -0
  71. package/dist/channels/qq/index.js +3 -0
  72. package/dist/channels/slash-parity.d.ts +117 -0
  73. package/dist/channels/slash-parity.js +185 -0
  74. package/dist/channels/synology-chat/index.js +3 -0
  75. package/dist/channels/teams/index.d.ts +3 -0
  76. package/dist/channels/teams/index.js +3 -0
  77. package/dist/channels/telegram/client.d.ts +9 -0
  78. package/dist/channels/telegram/client.js +12 -0
  79. package/dist/channels/twilio-voice/index.js +3 -0
  80. package/dist/channels/webchat/index.d.ts +7 -1
  81. package/dist/channels/webchat/index.js +7 -1
  82. package/dist/channels/wecom/index.js +3 -0
  83. package/dist/channels/weixin/index.js +3 -0
  84. package/dist/channels/zalo/index.js +3 -0
  85. package/dist/cli/config-loader.js +1 -1
  86. package/dist/codebuddy/client.d.ts +30 -1
  87. package/dist/codebuddy/client.js +167 -20
  88. package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
  89. package/dist/codebuddy/providers/provider-chatgpt-responses.js +1 -0
  90. package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
  91. package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
  92. package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
  93. package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
  94. package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
  95. package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
  96. package/dist/codebuddy/tool-definitions/index.js +2 -1
  97. package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
  98. package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
  99. package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
  100. package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
  101. package/dist/codebuddy/tools.d.ts +1 -1
  102. package/dist/codebuddy/tools.js +27 -24
  103. package/dist/commands/cli/hermes-commands.js +108 -0
  104. package/dist/commands/cli/native-engine-commands.js +107 -3
  105. package/dist/commands/cli/utility-commands.js +45 -0
  106. package/dist/commands/enhanced-command-handler.js +5 -0
  107. package/dist/commands/goal-cli.d.ts +71 -0
  108. package/dist/commands/goal-cli.js +280 -0
  109. package/dist/commands/handlers/goal-handler.d.ts +34 -0
  110. package/dist/commands/handlers/goal-handler.js +155 -0
  111. package/dist/commands/handlers/index.d.ts +1 -0
  112. package/dist/commands/handlers/index.js +2 -0
  113. package/dist/commands/handlers/infra-handlers.js +36 -0
  114. package/dist/commands/handlers/memory-handlers.js +96 -1
  115. package/dist/commands/headless-slash.d.ts +2 -0
  116. package/dist/commands/headless-slash.js +12 -0
  117. package/dist/commands/llm-provider-resolution.d.ts +5 -3
  118. package/dist/commands/llm-provider-resolution.js +87 -33
  119. package/dist/commands/ollama.d.ts +25 -0
  120. package/dist/commands/ollama.js +100 -0
  121. package/dist/commands/provider.d.ts +5 -0
  122. package/dist/commands/provider.js +106 -55
  123. package/dist/commands/slash/builtin-commands.js +20 -0
  124. package/dist/commands/spec-next.js +2 -1
  125. package/dist/commands/spec-plan.js +5 -16
  126. package/dist/commands/tunnel.d.ts +2 -0
  127. package/dist/commands/tunnel.js +48 -0
  128. package/dist/config/config-resolver.d.ts +2 -1
  129. package/dist/config/config-resolver.js +54 -41
  130. package/dist/config/constants.d.ts +28 -0
  131. package/dist/config/constants.js +7 -0
  132. package/dist/config/env-schema.js +770 -0
  133. package/dist/config/feature-flags.js +7 -0
  134. package/dist/config/model-tools.js +4 -4
  135. package/dist/config/toml-config.d.ts +16 -0
  136. package/dist/config/toml-config.js +3 -0
  137. package/dist/context/context-manager-v2.d.ts +39 -0
  138. package/dist/context/context-manager-v2.js +91 -0
  139. package/dist/daemon/agent-task-executor.js +12 -1
  140. package/dist/daemon/autonomous-daemon.d.ts +1 -1
  141. package/dist/daemon/autonomous-daemon.js +5 -3
  142. package/dist/daemon/autonomous-loop.d.ts +21 -1
  143. package/dist/daemon/autonomous-loop.js +69 -0
  144. package/dist/daemon/colab-goal.d.ts +38 -0
  145. package/dist/daemon/colab-goal.js +81 -0
  146. package/dist/daemon/cron-agent-bridge.d.ts +12 -3
  147. package/dist/daemon/cron-agent-bridge.js +25 -9
  148. package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
  149. package/dist/desktop/codebuddy-engine-adapter.js +257 -80
  150. package/dist/desktop/engine-adapter.d.ts +14 -0
  151. package/dist/desktop-automation/automation-manager.js +16 -0
  152. package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
  153. package/dist/desktop-automation/omniparser-runner.js +115 -0
  154. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  155. package/dist/desktop-automation/smart-snapshot.js +72 -5
  156. package/dist/doctor/index.js +40 -23
  157. package/dist/events/types.d.ts +11 -0
  158. package/dist/fleet/colab-store.d.ts +21 -0
  159. package/dist/fleet/colab-store.js +28 -0
  160. package/dist/fleet/peer-session-bridge.d.ts +1 -1
  161. package/dist/fleet/peer-session-bridge.js +243 -2
  162. package/dist/fleet/peer-session-store.d.ts +3 -0
  163. package/dist/fleet/peer-tool-bridge.js +14 -0
  164. package/dist/fleet/privacy-lint.d.ts +8 -0
  165. package/dist/fleet/privacy-lint.js +22 -0
  166. package/dist/goals/goal-decomposer.d.ts +27 -0
  167. package/dist/goals/goal-decomposer.js +293 -0
  168. package/dist/goals/goal-judge-client.d.ts +15 -0
  169. package/dist/goals/goal-judge-client.js +45 -0
  170. package/dist/goals/goal-judge.d.ts +38 -0
  171. package/dist/goals/goal-judge.js +158 -0
  172. package/dist/goals/goal-loop.d.ts +37 -0
  173. package/dist/goals/goal-loop.js +101 -0
  174. package/dist/goals/goal-manager.d.ts +77 -0
  175. package/dist/goals/goal-manager.js +289 -0
  176. package/dist/goals/goal-state.d.ts +99 -0
  177. package/dist/goals/goal-state.js +315 -0
  178. package/dist/goals/goal-store.d.ts +28 -0
  179. package/dist/goals/goal-store.js +87 -0
  180. package/dist/goals/index.d.ts +5 -0
  181. package/dist/goals/index.js +6 -0
  182. package/dist/hooks/use-input-handler.js +36 -1
  183. package/dist/hooks/user-hooks.js +17 -3
  184. package/dist/index.js +506 -25
  185. package/dist/input/text-to-speech.d.ts +2 -6
  186. package/dist/input/text-to-speech.js +2 -27
  187. package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
  188. package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
  189. package/dist/integrations/tailscale.d.ts +13 -0
  190. package/dist/integrations/tailscale.js +87 -34
  191. package/dist/knowledge/workspace-indexer.js +53 -9
  192. package/dist/mcp/client.js +1 -0
  193. package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
  194. package/dist/mcp/mcp-desktop-tools.js +158 -0
  195. package/dist/mcp/mcp-server.js +2 -0
  196. package/dist/memory/enhanced-memory.d.ts +10 -0
  197. package/dist/memory/enhanced-memory.js +33 -2
  198. package/dist/memory/index.d.ts +3 -1
  199. package/dist/memory/index.js +4 -1
  200. package/dist/memory/memory-auto-proposer.d.ts +23 -0
  201. package/dist/memory/memory-auto-proposer.js +308 -0
  202. package/dist/memory/memory-candidate-queue.d.ts +92 -0
  203. package/dist/memory/memory-candidate-queue.js +261 -0
  204. package/dist/memory/persistent-memory.d.ts +45 -2
  205. package/dist/memory/persistent-memory.js +236 -40
  206. package/dist/ml/bayesian-qualifier.d.ts +1 -1
  207. package/dist/ml/bayesian-qualifier.js +35 -2
  208. package/dist/observability/run-store.d.ts +1 -1
  209. package/dist/openclaw/gateway-bridge.js +5 -0
  210. package/dist/plugins/marketplace.d.ts +1 -0
  211. package/dist/plugins/marketplace.js +7 -0
  212. package/dist/prompts/execution-discipline.d.ts +14 -0
  213. package/dist/prompts/execution-discipline.js +29 -0
  214. package/dist/prompts/variation-injector.js +9 -2
  215. package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
  216. package/dist/protocols/acp/acp-agentic-runner.js +115 -18
  217. package/dist/protocols/acp/acp-session-store.d.ts +23 -0
  218. package/dist/protocols/acp/acp-session-store.js +77 -0
  219. package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
  220. package/dist/protocols/acp/acp-stdio-server.js +71 -16
  221. package/dist/providers/active-llm-registry.d.ts +37 -0
  222. package/dist/providers/active-llm-registry.js +186 -0
  223. package/dist/providers/auxiliary-provider.d.ts +25 -0
  224. package/dist/providers/auxiliary-provider.js +192 -0
  225. package/dist/providers/codex-oauth.d.ts +1 -1
  226. package/dist/providers/codex-oauth.js +27 -4
  227. package/dist/providers/index.d.ts +3 -0
  228. package/dist/providers/index.js +4 -0
  229. package/dist/providers/provider-catalog.d.ts +70 -0
  230. package/dist/providers/provider-catalog.js +738 -0
  231. package/dist/providers/provider-fallback.d.ts +35 -0
  232. package/dist/providers/provider-fallback.js +171 -0
  233. package/dist/providers/xai-oauth.d.ts +128 -0
  234. package/dist/providers/xai-oauth.js +735 -0
  235. package/dist/scheduler/cron-scheduler.d.ts +15 -3
  236. package/dist/scheduler/cron-scheduler.js +53 -7
  237. package/dist/scheduler/script-runner.d.ts +2 -0
  238. package/dist/scheduler/script-runner.js +19 -4
  239. package/dist/scheduler/watchdog-handlers.js +7 -20
  240. package/dist/search/usearch-index.js +7 -2
  241. package/dist/security/tool-policy/tool-groups.js +2 -0
  242. package/dist/server/index.js +17 -2
  243. package/dist/server/routes/mobile.d.ts +12 -4
  244. package/dist/server/routes/mobile.js +116 -1
  245. package/dist/server/tls-config.d.ts +35 -0
  246. package/dist/server/tls-config.js +142 -0
  247. package/dist/server/tunnel-manager.d.ts +20 -0
  248. package/dist/server/tunnel-manager.js +58 -0
  249. package/dist/server/websocket/fleet-bridge.d.ts +13 -1
  250. package/dist/server/websocket/fleet-bridge.js +16 -0
  251. package/dist/services/prompt-builder.d.ts +1 -0
  252. package/dist/services/prompt-builder.js +49 -8
  253. package/dist/shared/engine-types.d.ts +15 -1
  254. package/dist/sidecar/sidecar-bridge.d.ts +1 -0
  255. package/dist/sidecar/sidecar-bridge.js +21 -10
  256. package/dist/spec/spec-store.js +8 -1
  257. package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
  258. package/dist/talk-mode/providers/audioreader-tts.js +8 -8
  259. package/dist/templates/project-scaffolding.js +3 -2
  260. package/dist/themes/theme-schema.d.ts +10 -10
  261. package/dist/tools/application-profiles.js +38 -0
  262. package/dist/tools/bash/bash-tool.d.ts +1 -0
  263. package/dist/tools/bash/bash-tool.js +16 -2
  264. package/dist/tools/bash/command-validator.js +3 -0
  265. package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
  266. package/dist/tools/bash/rtk-rewrite.js +100 -0
  267. package/dist/tools/bash/streaming-executor.js +14 -1
  268. package/dist/tools/computer-control-tool.d.ts +16 -1
  269. package/dist/tools/computer-control-tool.js +317 -5
  270. package/dist/tools/document-generator.d.ts +14 -0
  271. package/dist/tools/document-generator.js +79 -0
  272. package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
  273. package/dist/tools/execute-code-rpc-invoker.js +46 -5
  274. package/dist/tools/metadata.js +28 -0
  275. package/dist/tools/office-macro-tool.d.ts +10 -0
  276. package/dist/tools/office-macro-tool.js +93 -0
  277. package/dist/tools/registry/index.d.ts +2 -1
  278. package/dist/tools/registry/index.js +2 -1
  279. package/dist/tools/registry/memory-tools.d.ts +20 -0
  280. package/dist/tools/registry/memory-tools.js +225 -3
  281. package/dist/tools/registry/multimodal-tools.js +2 -2
  282. package/dist/tools/registry/vision-tools.d.ts +33 -0
  283. package/dist/tools/registry/vision-tools.js +308 -6
  284. package/dist/tools/registry/windows-tools.d.ts +2 -0
  285. package/dist/tools/registry/windows-tools.js +47 -0
  286. package/dist/tools/route-peer-tool.js +14 -0
  287. package/dist/tools/screenshot-tool.js +14 -2
  288. package/dist/tools/text-to-speech-tool.d.ts +1 -1
  289. package/dist/tools/text-to-speech-tool.js +2 -12
  290. package/dist/tools/tool-selector.js +3 -59
  291. package/dist/utils/config-validation/schema.d.ts +40 -7
  292. package/dist/utils/config-validation/schema.js +130 -1
  293. package/dist/utils/cost-tracker.js +21 -1
  294. package/dist/utils/disk-guard.d.ts +180 -0
  295. package/dist/utils/disk-guard.js +404 -0
  296. package/dist/utils/interactive-setup.js +35 -2
  297. package/dist/utils/model-utils.js +11 -2
  298. package/dist/utils/output-sanitizer.js +11 -0
  299. package/dist/utils/provider-detector.d.ts +8 -7
  300. package/dist/utils/provider-detector.js +19 -77
  301. package/dist/utils/settings-manager.d.ts +7 -0
  302. package/dist/utils/token-display.d.ts +3 -3
  303. package/dist/utils/token-display.js +22 -4
  304. package/dist/wizard/onboarding.d.ts +39 -0
  305. package/dist/wizard/onboarding.js +433 -21
  306. package/dist/wizard/provider-onboarding.d.ts +8 -23
  307. package/dist/wizard/provider-onboarding.js +39 -158
  308. package/package.json +4 -2
  309. package/dist/plugins/provider-onboarding.d.ts +0 -23
  310. package/dist/plugins/provider-onboarding.js +0 -116
  311. package/dist/utils/kokoro-tts.d.ts +0 -8
  312. package/dist/utils/kokoro-tts.js +0 -67
@@ -0,0 +1,100 @@
1
+ import { spawn } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { resolve } from 'path';
4
+ export function normalizeOllamaBaseUrl(rawUrl) {
5
+ const value = (rawUrl || 'http://localhost:11434').trim();
6
+ const withoutV1 = value.replace(/\/v1\/?$/, '');
7
+ return withoutV1.replace(/\/+$/, '');
8
+ }
9
+ export async function fetchOllamaStatus(baseUrl) {
10
+ const normalizedBaseUrl = normalizeOllamaBaseUrl(baseUrl);
11
+ const apiBase = `${normalizedBaseUrl}/api`;
12
+ try {
13
+ const [versionResponse, tagsResponse] = await Promise.all([
14
+ fetch(`${apiBase}/version`, { signal: AbortSignal.timeout(5000) }),
15
+ fetch(`${apiBase}/tags`, { signal: AbortSignal.timeout(5000) }),
16
+ ]);
17
+ const versionJson = (await versionResponse.json());
18
+ const tagsJson = (await tagsResponse.json());
19
+ return {
20
+ baseUrl: normalizedBaseUrl,
21
+ reachable: versionResponse.ok && tagsResponse.ok,
22
+ version: typeof versionJson.version === 'string' ? versionJson.version : null,
23
+ models: Array.isArray(tagsJson.models)
24
+ ? tagsJson.models
25
+ .map((model) => (typeof model.name === 'string' ? model.name : null))
26
+ .filter((name) => Boolean(name))
27
+ : [],
28
+ error: versionResponse.ok && tagsResponse.ok ? null : `HTTP ${versionResponse.status}/${tagsResponse.status}`,
29
+ };
30
+ }
31
+ catch (error) {
32
+ return {
33
+ baseUrl: normalizedBaseUrl,
34
+ reachable: false,
35
+ version: null,
36
+ models: [],
37
+ error: error instanceof Error ? error.message : String(error),
38
+ };
39
+ }
40
+ }
41
+ export function buildOllamaUpdatePlan(options) {
42
+ const platform = options.platform ?? process.platform;
43
+ const repoRoot = resolve(options.repoRoot);
44
+ const scriptPath = resolve(repoRoot, 'scripts', 'update-ollama-windows.ps1');
45
+ const scriptUrl = options.scriptUrl ?? 'https://ollama.com/install.ps1';
46
+ const supported = platform === 'win32';
47
+ if (!supported) {
48
+ return {
49
+ supported,
50
+ platform,
51
+ repoRoot,
52
+ scriptPath,
53
+ scriptUrl,
54
+ message: 'Ollama update automation is implemented for Windows. Use the official install script on this platform.',
55
+ };
56
+ }
57
+ const command = 'powershell';
58
+ const args = [
59
+ '-ExecutionPolicy',
60
+ 'Bypass',
61
+ '-File',
62
+ scriptPath,
63
+ '-InstallerScriptUrl',
64
+ scriptUrl,
65
+ ];
66
+ return {
67
+ supported,
68
+ platform,
69
+ repoRoot,
70
+ scriptPath,
71
+ scriptUrl,
72
+ command,
73
+ args,
74
+ message: `Windows update script ready: ${scriptPath}`,
75
+ };
76
+ }
77
+ export async function runOllamaUpdatePlan(plan) {
78
+ if (!plan.supported || !plan.command || !plan.args) {
79
+ throw new Error(plan.message);
80
+ }
81
+ if (!existsSync(plan.scriptPath)) {
82
+ throw new Error(`Missing Ollama update script: ${plan.scriptPath}`);
83
+ }
84
+ await new Promise((resolvePromise, rejectPromise) => {
85
+ const child = spawn(plan.command, plan.args, {
86
+ stdio: 'inherit',
87
+ cwd: plan.repoRoot,
88
+ shell: false,
89
+ });
90
+ child.once('error', rejectPromise);
91
+ child.once('exit', (code) => {
92
+ if (code === 0) {
93
+ resolvePromise();
94
+ return;
95
+ }
96
+ rejectPromise(new Error(`Ollama update script exited with code ${code ?? 'unknown'}`));
97
+ });
98
+ });
99
+ }
100
+ //# sourceMappingURL=ollama.js.map
@@ -4,13 +4,18 @@
4
4
  * CLI commands for managing AI providers (Claude, ChatGPT, Grok, Gemini)
5
5
  */
6
6
  import { Command } from 'commander';
7
+ import { type RuntimeProviderCatalogEntry, type RuntimeProviderId } from '../providers/provider-catalog.js';
7
8
  interface ProviderInfo {
8
9
  name: string;
9
10
  envVar: string;
11
+ envVars: string[];
10
12
  models: string[];
11
13
  defaultModel: string;
12
14
  baseURL?: string;
15
+ providerId: RuntimeProviderId;
16
+ authMode: RuntimeProviderCatalogEntry['authMode'];
13
17
  }
14
18
  export declare const PROVIDERS: Record<string, ProviderInfo>;
15
19
  export declare function createProviderCommand(): Command;
20
+ export declare function resolveProviderCommandKey(provider: string): string | null;
16
21
  export default createProviderCommand;
@@ -7,61 +7,85 @@ import { Command } from 'commander';
7
7
  import { logger } from "../utils/logger.js";
8
8
  import { getSettingsManager } from '../utils/settings-manager.js';
9
9
  import { hasCodexCredentials } from '../providers/codex-oauth.js';
10
- export const PROVIDERS = {
11
- grok: {
12
- name: 'Grok (xAI)',
13
- envVar: 'GROK_API_KEY',
14
- models: ['grok-4-1-fast', 'grok-4-latest', 'grok-4-fast', 'grok-code-fast-1', 'grok-3-latest', 'grok-3-fast', 'grok-3-mini'],
15
- defaultModel: 'grok-3-fast',
16
- baseURL: 'https://api.x.ai/v1',
17
- },
18
- claude: {
19
- name: 'Claude (Anthropic)',
20
- envVar: 'ANTHROPIC_API_KEY',
21
- models: [
22
- 'claude-sonnet-4-20250514',
23
- 'claude-opus-4-20250514',
24
- 'claude-3-5-sonnet-latest',
25
- 'claude-3-5-haiku-latest',
26
- 'claude-3-opus-latest',
27
- ],
28
- defaultModel: 'claude-sonnet-4-20250514',
29
- },
30
- openai: {
31
- name: 'ChatGPT (OpenAI)',
32
- envVar: 'OPENAI_API_KEY',
33
- models: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1', 'o1-mini', 'o3-mini'],
34
- defaultModel: 'gpt-4o',
35
- baseURL: 'https://api.openai.com/v1',
36
- },
37
- chatgpt: {
38
- name: 'ChatGPT (OAuth)',
39
- envVar: 'CODEBUDDY_CHATGPT_OAUTH',
40
- models: ['gpt-5.5'],
41
- defaultModel: 'gpt-5.5',
42
- baseURL: 'https://chatgpt.com/backend-api/codex',
43
- },
44
- gemini: {
45
- name: 'Gemini (Google)',
46
- envVar: 'GOOGLE_API_KEY',
47
- models: ['gemini-2.5-flash', 'gemini-2.5-pro', 'gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
48
- defaultModel: 'gemini-2.5-flash',
49
- baseURL: 'https://generativelanguage.googleapis.com/v1beta',
50
- },
10
+ import { findRuntimeProvider, getPluginNativeRuntimeProviderCatalog, getProviderEnvSummary, getRuntimeProviderCatalog, isProviderConfigured, resolvePluginRuntimeProvider, } from '../providers/provider-catalog.js';
11
+ const PROVIDER_COMMAND_KEYS = {
12
+ chatgpt: 'chatgpt',
13
+ ollama: 'ollama',
14
+ 'ollama-cloud': 'ollama-cloud',
15
+ lmstudio: 'lmstudio',
16
+ grok: 'grok',
17
+ gemini: 'gemini',
18
+ openai: 'openai',
19
+ anthropic: 'claude',
20
+ mistral: 'mistral',
21
+ groq: 'groq',
22
+ together: 'together',
23
+ fireworks: 'fireworks',
24
+ openrouter: 'openrouter',
25
+ novita: 'novita',
26
+ zai: 'zai',
27
+ 'kimi-coding': 'kimi-coding',
28
+ 'kimi-coding-cn': 'kimi-coding-cn',
29
+ arcee: 'arcee',
30
+ gmi: 'gmi',
31
+ minimax: 'minimax',
32
+ 'minimax-cn': 'minimax-cn',
33
+ alibaba: 'alibaba',
34
+ 'alibaba-coding-plan': 'alibaba-coding-plan',
35
+ kilocode: 'kilocode',
36
+ xiaomi: 'xiaomi',
37
+ 'tencent-tokenhub': 'tencent-tokenhub',
38
+ 'opencode-zen': 'opencode-zen',
39
+ 'opencode-go': 'opencode-go',
40
+ deepseek: 'deepseek',
41
+ huggingface: 'huggingface',
42
+ nvidia: 'nvidia',
43
+ stepfun: 'stepfun',
44
+ vllm: 'vllm',
45
+ custom: 'custom',
46
+ azure: 'azure',
47
+ bedrock: 'bedrock',
48
+ copilot: 'copilot',
51
49
  };
50
+ export const PROVIDERS = Object.fromEntries(getRuntimeProviderCatalog()
51
+ .filter((entry) => entry.runtimeSupport === 'direct')
52
+ .map((entry) => {
53
+ const key = PROVIDER_COMMAND_KEYS[entry.id];
54
+ return [
55
+ key,
56
+ {
57
+ name: entry.label,
58
+ envVar: getProviderEnvSummary(entry),
59
+ envVars: entry.id === 'chatgpt'
60
+ ? ['CODEBUDDY_CHATGPT_OAUTH']
61
+ : [...entry.apiKeyEnvKeys, ...entry.baseUrlEnvKeys],
62
+ models: entry.models,
63
+ defaultModel: entry.defaultModel,
64
+ baseURL: entry.defaultBaseURL,
65
+ providerId: entry.id,
66
+ authMode: entry.authMode,
67
+ },
68
+ ];
69
+ }));
52
70
  function getConfiguredProviders() {
53
71
  const configured = [];
54
72
  for (const [key, info] of Object.entries(PROVIDERS)) {
55
- const hasKey = process.env[info.envVar] ||
56
- (key === 'grok' && process.env.XAI_API_KEY) ||
57
- (key === 'gemini' && process.env.GEMINI_API_KEY) ||
58
- (key === 'chatgpt' && hasCodexCredentials());
59
- if (hasKey) {
73
+ const entry = findRuntimeProvider(info.providerId);
74
+ if (entry && isProviderConfigured(entry, process.env, hasCodexCredentials())) {
60
75
  configured.push(key);
61
76
  }
62
77
  }
63
78
  return configured;
64
79
  }
80
+ function getConfiguredPluginNativeProviders() {
81
+ const configured = [];
82
+ for (const entry of getPluginNativeRuntimeProviderCatalog()) {
83
+ if (isProviderConfigured(entry, process.env, hasCodexCredentials())) {
84
+ configured.push(entry.id);
85
+ }
86
+ }
87
+ return configured;
88
+ }
65
89
  function getCurrentProvider() {
66
90
  const manager = getSettingsManager();
67
91
  const settings = manager.loadUserSettings();
@@ -90,7 +114,7 @@ function setCurrentModel(model) {
90
114
  }
91
115
  export function createProviderCommand() {
92
116
  const provider = new Command('provider')
93
- .description('Manage AI providers (Claude, ChatGPT, Grok, Gemini)');
117
+ .description('Manage AI providers');
94
118
  // List providers
95
119
  provider
96
120
  .command('list')
@@ -98,7 +122,8 @@ export function createProviderCommand() {
98
122
  .description('List available AI providers')
99
123
  .action(() => {
100
124
  const configured = getConfiguredProviders();
101
- const current = getCurrentProvider();
125
+ const configuredPluginProviders = getConfiguredPluginNativeProviders();
126
+ const current = resolveProviderCommandKey(getCurrentProvider()) || getCurrentProvider();
102
127
  console.log('\nAvailable AI Providers:\n');
103
128
  for (const [key, info] of Object.entries(PROVIDERS)) {
104
129
  const isConfigured = configured.includes(key);
@@ -111,7 +136,21 @@ export function createProviderCommand() {
111
136
  console.log(` Models: ${info.models.slice(0, 3).join(', ')}${info.models.length > 3 ? '...' : ''}`);
112
137
  console.log('');
113
138
  }
114
- if (configured.length === 0) {
139
+ const pluginProviders = getPluginNativeRuntimeProviderCatalog();
140
+ if (pluginProviders.length > 0) {
141
+ console.log('Plugin-native providers (available through bundled transports):\n');
142
+ for (const entry of pluginProviders) {
143
+ const status = configuredPluginProviders.includes(entry.id) ? '✅' : '❌';
144
+ const runtime = resolvePluginRuntimeProvider(entry.id);
145
+ console.log(` ${status} ${entry.label}`);
146
+ console.log(` Key: ${PROVIDER_COMMAND_KEYS[entry.id]}`);
147
+ console.log(` Env: ${getProviderEnvSummary(entry)}`);
148
+ console.log(` Transport: ${runtime?.pluginId ?? 'bundled plugin'}`);
149
+ console.log(` Models: ${entry.models.slice(0, 3).join(', ')}${entry.models.length > 3 ? '...' : ''}`);
150
+ console.log('');
151
+ }
152
+ }
153
+ if (configured.length === 0 && configuredPluginProviders.length === 0) {
115
154
  console.log('⚠️ No providers configured. Set an API key environment variable.');
116
155
  console.log(' Example: export ANTHROPIC_API_KEY="your-key"');
117
156
  }
@@ -124,11 +163,12 @@ export function createProviderCommand() {
124
163
  .action(() => {
125
164
  const current = getCurrentProvider();
126
165
  const model = getCurrentModel();
127
- const info = PROVIDERS[current];
166
+ const key = resolveProviderCommandKey(current) || current;
167
+ const info = PROVIDERS[key];
128
168
  console.log(`\nActive Provider: ${info?.name || current}`);
129
169
  console.log(`Model: ${model || info?.defaultModel || 'default'}`);
130
170
  const configured = getConfiguredProviders();
131
- if (!configured.includes(current)) {
171
+ if (!configured.includes(key)) {
132
172
  console.log(`\n⚠️ Warning: ${info?.envVar || 'API key'} not set`);
133
173
  }
134
174
  });
@@ -139,8 +179,8 @@ export function createProviderCommand() {
139
179
  .description('Set the active AI provider')
140
180
  .option('-m, --model <model>', 'Also set the model')
141
181
  .action((providerKey, options) => {
142
- const key = providerKey.toLowerCase();
143
- if (!PROVIDERS[key]) {
182
+ const key = resolveProviderCommandKey(providerKey);
183
+ if (!key || !PROVIDERS[key]) {
144
184
  logger.error(`❌ Unknown provider: ${providerKey}`);
145
185
  logger.error(` Available: ${Object.keys(PROVIDERS).join(', ')}`);
146
186
  process.exit(1);
@@ -167,8 +207,8 @@ export function createProviderCommand() {
167
207
  .command('models [provider]')
168
208
  .description('List available models for a provider')
169
209
  .action((providerKey) => {
170
- const key = (providerKey || getCurrentProvider()).toLowerCase();
171
- if (!PROVIDERS[key]) {
210
+ const key = resolveProviderCommandKey(providerKey || getCurrentProvider());
211
+ if (!key || !PROVIDERS[key]) {
172
212
  logger.error(`❌ Unknown provider: ${providerKey}`);
173
213
  process.exit(1);
174
214
  }
@@ -197,5 +237,16 @@ export function createProviderCommand() {
197
237
  });
198
238
  return provider;
199
239
  }
240
+ export function resolveProviderCommandKey(provider) {
241
+ const normalized = provider.toLowerCase();
242
+ if (PROVIDERS[normalized])
243
+ return normalized;
244
+ const entry = findRuntimeProvider(normalized);
245
+ if (!entry)
246
+ return null;
247
+ if (entry.runtimeSupport !== 'direct')
248
+ return null;
249
+ return PROVIDER_COMMAND_KEYS[entry.id] ?? null;
250
+ }
200
251
  export default createProviderCommand;
201
252
  //# sourceMappingURL=provider.js.map
@@ -808,6 +808,26 @@ const personaCommands = [
808
808
  // Autonomy & Permissions Commands
809
809
  // ============================================================================
810
810
  const autonomyCommands = [
811
+ {
812
+ name: 'goal',
813
+ description: 'Standing goal with judge + auto-continue loop (Ralph loop): /goal <text> | status | pause | resume | clear',
814
+ prompt: '__GOAL__',
815
+ filePath: '',
816
+ isBuiltin: true,
817
+ arguments: [
818
+ { name: 'action', description: '<text> to set a goal, or status, pause, resume, clear', required: false }
819
+ ]
820
+ },
821
+ {
822
+ name: 'subgoal',
823
+ description: 'Add acceptance criteria to the active goal: /subgoal <text> | remove <n> | clear',
824
+ prompt: '__SUBGOAL__',
825
+ filePath: '',
826
+ isBuiltin: true,
827
+ arguments: [
828
+ { name: 'action', description: '<text> to add a criterion, remove <n>, clear, or empty to list', required: false }
829
+ ]
830
+ },
811
831
  {
812
832
  name: 'yolo',
813
833
  description: 'Toggle YOLO mode (full auto-execution with guardrails)',
@@ -163,7 +163,8 @@ function pickStory(store, projectId, explicitId) {
163
163
  }
164
164
  return story;
165
165
  }
166
- const approved = store.listStories(projectId, 'approved'); // oldest first (createdAt)
166
+ const approved = store.listStories(projectId, 'approved')
167
+ .sort((a, b) => a.createdAt - b.createdAt || a.id.localeCompare(b.id));
167
168
  const first = approved[0];
168
169
  if (!first) {
169
170
  console.log('No approved stories. Approve one with: buddy spec story approve <id> --by <name>');
@@ -18,7 +18,7 @@ import { Command } from 'commander';
18
18
  import { getSpecStore } from '../spec/spec-store.js';
19
19
  import { startSpecPlan, advanceSpecPlan, runSpecPlanToCompletion, } from '../spec/spec-plan-runner.js';
20
20
  import { getSettingsManager } from '../utils/settings-manager.js';
21
- import { PROVIDERS } from './provider.js';
21
+ import { resolveCommandProvider } from './llm-provider-resolution.js';
22
22
  /**
23
23
  * Build the `plan` sub-command group.
24
24
  * @param llmProvider override for tests; defaults to a real CodeBuddyClient.
@@ -150,23 +150,12 @@ function printAdvanceResult(store, projectId, result) {
150
150
  // ============================================================================
151
151
  async function defaultLlmProvider() {
152
152
  const settingsManager = getSettingsManager();
153
- const userSettings = settingsManager.loadUserSettings();
154
- const providerKey = userSettings.provider || 'grok';
155
- const providerInfo = PROVIDERS[providerKey];
156
- let apiKey = process.env[providerInfo?.envVar || ''] || '';
157
- if (!apiKey) {
158
- apiKey =
159
- process.env.GROK_API_KEY ||
160
- process.env.ANTHROPIC_API_KEY ||
161
- process.env.OPENAI_API_KEY ||
162
- process.env.GEMINI_API_KEY ||
163
- '';
164
- }
165
- if (!apiKey)
153
+ const resolved = resolveCommandProvider();
154
+ if (!resolved)
166
155
  throw new Error('No API key configured. Run: buddy onboard');
167
156
  const { CodeBuddyClient } = await import('../codebuddy/client.js');
168
- const model = settingsManager.getCurrentModel() || providerInfo?.defaultModel;
169
- const client = new CodeBuddyClient(apiKey, model, providerInfo?.baseURL);
157
+ const model = settingsManager.getCurrentModel() || resolved.model;
158
+ const client = new CodeBuddyClient(resolved.apiKey, model, resolved.baseURL);
170
159
  return async (system, user) => {
171
160
  const response = await client.chat([
172
161
  { role: 'system', content: system },
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createTunnelCommand(): Command;
@@ -0,0 +1,48 @@
1
+ import { Command } from 'commander';
2
+ import { TunnelManager } from '../server/tunnel-manager.js';
3
+ import { logger } from '../utils/logger.js';
4
+ export function createTunnelCommand() {
5
+ const cmd = new Command('tunnel')
6
+ .description('Manage ngrok tunnels for the Code Buddy remote gateway');
7
+ cmd.command('start')
8
+ .description('Start an ngrok tunnel')
9
+ .option('-p, --port <number>', 'Port to tunnel to', '3000')
10
+ .option('--domain <string>', 'Custom ngrok domain')
11
+ .option('--authtoken <string>', 'ngrok authtoken (or set NGROK_AUTHTOKEN env var)')
12
+ .option('--server', 'Start the local HTTP server along with the tunnel')
13
+ .action(async (opts) => {
14
+ const port = parseInt(opts.port, 10);
15
+ if (opts.server) {
16
+ // dynamically import server to start it
17
+ try {
18
+ const { startServer } = await import('../server/index.js');
19
+ await startServer({ port });
20
+ logger.info(`Local server started on port ${port}`);
21
+ }
22
+ catch (error) {
23
+ logger.error('Failed to start local server', { error });
24
+ process.exit(1);
25
+ }
26
+ }
27
+ try {
28
+ const url = await TunnelManager.startTunnel({
29
+ port,
30
+ domain: opts.domain,
31
+ authtoken: opts.authtoken,
32
+ });
33
+ console.log(`\nTunnel started successfully!`);
34
+ console.log(`Forwarding: ${url} -> http://localhost:${port}\n`);
35
+ // Keep process alive if just tunneling
36
+ process.on('SIGINT', async () => {
37
+ await TunnelManager.stopTunnel();
38
+ process.exit(0);
39
+ });
40
+ }
41
+ catch (error) {
42
+ console.error('Failed to start tunnel:', error instanceof Error ? error.message : String(error));
43
+ process.exit(1);
44
+ }
45
+ });
46
+ return cmd;
47
+ }
48
+ //# sourceMappingURL=tunnel.js.map
@@ -44,9 +44,10 @@ export declare class ConfigResolver extends EventEmitter {
44
44
  private resolveFromProfile;
45
45
  /**
46
46
  * Resolve from environment variables
47
- * Priority: Gemini > Grok > OpenAI > Anthropic
47
+ * Priority comes from the runtime provider catalog.
48
48
  */
49
49
  private resolveFromEnv;
50
+ private normalizeDetectedProvider;
50
51
  /**
51
52
  * Get built-in default configuration
52
53
  */
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { EventEmitter } from 'events';
13
13
  import { logger } from '../utils/logger.js';
14
+ import { detectProviderFromEnv } from '../utils/provider-detector.js';
14
15
  import { DEFAULT_PROFILES, DEFAULT_CONNECTION_CONFIG, } from './types.js';
15
16
  // ============================================================================
16
17
  // Config Resolver
@@ -121,49 +122,16 @@ export class ConfigResolver extends EventEmitter {
121
122
  }
122
123
  /**
123
124
  * Resolve from environment variables
124
- * Priority: Gemini > Grok > OpenAI > Anthropic
125
+ * Priority comes from the runtime provider catalog.
125
126
  */
126
127
  resolveFromEnv() {
127
- // Check Gemini first (preferred)
128
- const geminiKey = process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
129
- if (geminiKey) {
128
+ const detected = detectProviderFromEnv();
129
+ if (detected) {
130
130
  return {
131
- baseURL: 'https://generativelanguage.googleapis.com/v1beta',
132
- apiKey: geminiKey,
133
- model: process.env.GEMINI_MODEL || 'gemini-2.5-flash',
134
- provider: 'gemini',
135
- source: 'environment',
136
- };
137
- }
138
- // Check Grok
139
- const grokKey = process.env.GROK_API_KEY || process.env.XAI_API_KEY;
140
- if (grokKey) {
141
- const baseURL = process.env.GROK_BASE_URL || 'https://api.x.ai/v1';
142
- return {
143
- baseURL,
144
- apiKey: grokKey,
145
- model: process.env.GROK_MODEL || 'grok-code-fast-1',
146
- provider: 'grok',
147
- source: 'environment',
148
- };
149
- }
150
- // Check OpenAI
151
- if (process.env.OPENAI_API_KEY) {
152
- return {
153
- baseURL: 'https://api.openai.com/v1',
154
- apiKey: process.env.OPENAI_API_KEY,
155
- model: process.env.OPENAI_MODEL || 'gpt-4o',
156
- provider: 'openai',
157
- source: 'environment',
158
- };
159
- }
160
- // Check Anthropic
161
- if (process.env.ANTHROPIC_API_KEY) {
162
- return {
163
- baseURL: 'https://api.anthropic.com/v1',
164
- apiKey: process.env.ANTHROPIC_API_KEY,
165
- model: process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-20250514',
166
- provider: 'claude',
131
+ baseURL: detected.baseURL,
132
+ apiKey: detected.apiKey,
133
+ model: detected.defaultModel,
134
+ provider: this.normalizeDetectedProvider(detected.provider),
167
135
  source: 'environment',
168
136
  };
169
137
  }
@@ -177,6 +145,13 @@ export class ConfigResolver extends EventEmitter {
177
145
  source: 'environment',
178
146
  };
179
147
  }
148
+ normalizeDetectedProvider(provider) {
149
+ if (provider === 'anthropic')
150
+ return 'claude';
151
+ if (provider === 'unknown')
152
+ return 'grok';
153
+ return provider;
154
+ }
180
155
  /**
181
156
  * Get built-in default configuration
182
157
  */
@@ -215,6 +190,44 @@ export class ConfigResolver extends EventEmitter {
215
190
  return 'together';
216
191
  if (urlLower.includes('fireworks.ai'))
217
192
  return 'fireworks';
193
+ if (urlLower.includes('openrouter.ai'))
194
+ return 'openrouter';
195
+ if (urlLower.includes('novita.ai'))
196
+ return 'novita';
197
+ if (urlLower.includes('z.ai') || urlLower.includes('bigmodel'))
198
+ return 'zai';
199
+ if (urlLower.includes('moonshot.ai'))
200
+ return 'kimi-coding';
201
+ if (urlLower.includes('moonshot.cn'))
202
+ return 'kimi-coding-cn';
203
+ if (urlLower.includes('arcee.ai'))
204
+ return 'arcee';
205
+ if (urlLower.includes('gmi-serving.com'))
206
+ return 'gmi';
207
+ if (urlLower.includes('minimax.io'))
208
+ return 'minimax';
209
+ if (urlLower.includes('minimaxi.com'))
210
+ return 'minimax-cn';
211
+ if (urlLower.includes('dashscope') || urlLower.includes('aliyuncs.com'))
212
+ return 'alibaba';
213
+ if (urlLower.includes('kilo.ai'))
214
+ return 'kilocode';
215
+ if (urlLower.includes('xiaomimimo.com'))
216
+ return 'xiaomi';
217
+ if (urlLower.includes('tencentmaas.com'))
218
+ return 'tencent-tokenhub';
219
+ if (urlLower.includes('opencode.ai/zen/go'))
220
+ return 'opencode-go';
221
+ if (urlLower.includes('opencode.ai/zen'))
222
+ return 'opencode-zen';
223
+ if (urlLower.includes('router.huggingface.co') || urlLower.includes('huggingface.co'))
224
+ return 'huggingface';
225
+ if (urlLower.includes('api.nvidia.com'))
226
+ return 'nvidia';
227
+ if (urlLower.includes('ollama.com'))
228
+ return 'ollama-cloud';
229
+ if (urlLower.includes('stepfun.ai'))
230
+ return 'stepfun';
218
231
  // Local providers (by port)
219
232
  if (urlLower.includes(':1234'))
220
233
  return 'lmstudio';
@@ -393,7 +406,7 @@ export class ConfigResolver extends EventEmitter {
393
406
  };
394
407
  }
395
408
  }
396
- catch (error) {
409
+ catch (_error) {
397
410
  // Server not available on this port, try next
398
411
  continue;
399
412
  }
@@ -282,10 +282,38 @@ export declare const SUPPORTED_MODELS: {
282
282
  readonly maxTokens: 32768;
283
283
  readonly provider: "ollama";
284
284
  };
285
+ readonly 'qwen3.5-ctx32k': {
286
+ readonly maxTokens: 32768;
287
+ readonly provider: "ollama";
288
+ };
289
+ readonly 'qwen3.5:35b': {
290
+ readonly maxTokens: 32768;
291
+ readonly provider: "ollama";
292
+ };
293
+ readonly 'qwen3.6:27b': {
294
+ readonly maxTokens: 32768;
295
+ readonly provider: "ollama";
296
+ };
297
+ readonly 'qwen3.6:35b-a3b-q4_K_M': {
298
+ readonly maxTokens: 32768;
299
+ readonly provider: "ollama";
300
+ };
301
+ readonly 'devstral-small-2': {
302
+ readonly maxTokens: 131072;
303
+ readonly provider: "ollama";
304
+ };
305
+ readonly 'devstral-small-2:24b-instruct-2512-q4_K_M': {
306
+ readonly maxTokens: 131072;
307
+ readonly provider: "ollama";
308
+ };
285
309
  readonly phi3: {
286
310
  readonly maxTokens: 4096;
287
311
  readonly provider: "ollama";
288
312
  };
313
+ readonly 'gemma4:12b': {
314
+ readonly maxTokens: 8192;
315
+ readonly provider: "ollama";
316
+ };
289
317
  readonly gemma2: {
290
318
  readonly maxTokens: 8192;
291
319
  readonly provider: "ollama";