@phuetz/code-buddy 1.1.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 (291) hide show
  1. package/README.md +160 -165
  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 +69 -14
  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/middleware/index.d.ts +1 -0
  20. package/dist/agent/middleware/index.js +1 -0
  21. package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
  22. package/dist/agent/middleware/visual-validation-middleware.js +67 -0
  23. package/dist/agent/model-benchmark.d.ts +77 -0
  24. package/dist/agent/model-benchmark.js +309 -0
  25. package/dist/agent/model-tier.d.ts +14 -0
  26. package/dist/agent/model-tier.js +71 -0
  27. package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
  28. package/dist/agent/multi-agent/multi-agent-system.js +3 -1
  29. package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
  30. package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
  31. package/dist/agent/multi-agent/session-tools.js +22 -5
  32. package/dist/agent/reasoning/mcts.js +20 -6
  33. package/dist/agent/session-end-flush.d.ts +6 -1
  34. package/dist/agent/session-end-flush.js +20 -4
  35. package/dist/agent/streaming/streaming-handler.d.ts +7 -0
  36. package/dist/agent/streaming/streaming-handler.js +8 -1
  37. package/dist/agent/tool-executor.js +1 -0
  38. package/dist/agent/tool-handler.d.ts +5 -0
  39. package/dist/agent/tool-handler.js +130 -4
  40. package/dist/browser-automation/browser-operator-executor.js +15 -0
  41. package/dist/browser-automation/browser-use-runner.d.ts +96 -0
  42. package/dist/browser-automation/browser-use-runner.js +492 -0
  43. package/dist/browser-automation/camofox-runner.d.ts +107 -0
  44. package/dist/browser-automation/camofox-runner.js +287 -0
  45. package/dist/channels/dingtalk/index.js +3 -0
  46. package/dist/channels/discord/client.d.ts +9 -0
  47. package/dist/channels/discord/client.js +12 -0
  48. package/dist/channels/feishu/index.d.ts +167 -1
  49. package/dist/channels/feishu/index.js +432 -7
  50. package/dist/channels/gateway-lifecycle.d.ts +132 -0
  51. package/dist/channels/gateway-lifecycle.js +219 -0
  52. package/dist/channels/google-chat/index.d.ts +5 -1
  53. package/dist/channels/google-chat/index.js +5 -1
  54. package/dist/channels/imessage/index.d.ts +14 -0
  55. package/dist/channels/imessage/index.js +64 -17
  56. package/dist/channels/index.d.ts +4 -0
  57. package/dist/channels/index.js +4 -0
  58. package/dist/channels/irc/index.d.ts +73 -3
  59. package/dist/channels/irc/index.js +446 -11
  60. package/dist/channels/line/index.js +3 -0
  61. package/dist/channels/mattermost/index.d.ts +51 -4
  62. package/dist/channels/mattermost/index.js +303 -20
  63. package/dist/channels/nextcloud-talk/index.d.ts +89 -8
  64. package/dist/channels/nextcloud-talk/index.js +367 -16
  65. package/dist/channels/nostr/index.d.ts +121 -1
  66. package/dist/channels/nostr/index.js +396 -8
  67. package/dist/channels/ntfy/index.js +3 -0
  68. package/dist/channels/qq/index.js +3 -0
  69. package/dist/channels/slash-parity.d.ts +117 -0
  70. package/dist/channels/slash-parity.js +185 -0
  71. package/dist/channels/synology-chat/index.js +3 -0
  72. package/dist/channels/teams/index.d.ts +3 -0
  73. package/dist/channels/teams/index.js +3 -0
  74. package/dist/channels/telegram/client.d.ts +9 -0
  75. package/dist/channels/telegram/client.js +12 -0
  76. package/dist/channels/twilio-voice/index.js +3 -0
  77. package/dist/channels/webchat/index.d.ts +7 -1
  78. package/dist/channels/webchat/index.js +7 -1
  79. package/dist/channels/wecom/index.js +3 -0
  80. package/dist/channels/weixin/index.js +3 -0
  81. package/dist/channels/zalo/index.js +3 -0
  82. package/dist/cli/config-loader.js +1 -1
  83. package/dist/codebuddy/client.d.ts +30 -1
  84. package/dist/codebuddy/client.js +167 -20
  85. package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
  86. package/dist/codebuddy/providers/provider-chatgpt-responses.js +1 -0
  87. package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
  88. package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
  89. package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
  90. package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
  91. package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
  92. package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
  93. package/dist/codebuddy/tool-definitions/index.js +2 -1
  94. package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
  95. package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
  96. package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
  97. package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
  98. package/dist/codebuddy/tools.d.ts +1 -1
  99. package/dist/codebuddy/tools.js +27 -24
  100. package/dist/commands/cli/hermes-commands.js +108 -0
  101. package/dist/commands/cli/native-engine-commands.js +102 -3
  102. package/dist/commands/cli/utility-commands.js +45 -0
  103. package/dist/commands/enhanced-command-handler.js +1 -1
  104. package/dist/commands/goal-cli.d.ts +30 -0
  105. package/dist/commands/goal-cli.js +210 -27
  106. package/dist/commands/handlers/goal-handler.d.ts +9 -2
  107. package/dist/commands/handlers/goal-handler.js +36 -9
  108. package/dist/commands/handlers/infra-handlers.js +36 -0
  109. package/dist/commands/handlers/memory-handlers.js +96 -1
  110. package/dist/commands/headless-slash.d.ts +2 -0
  111. package/dist/commands/headless-slash.js +12 -0
  112. package/dist/commands/llm-provider-resolution.d.ts +5 -3
  113. package/dist/commands/llm-provider-resolution.js +87 -33
  114. package/dist/commands/ollama.d.ts +25 -0
  115. package/dist/commands/ollama.js +100 -0
  116. package/dist/commands/provider.d.ts +5 -0
  117. package/dist/commands/provider.js +106 -55
  118. package/dist/commands/spec-next.js +2 -1
  119. package/dist/commands/spec-plan.js +5 -16
  120. package/dist/commands/tunnel.d.ts +2 -0
  121. package/dist/commands/tunnel.js +48 -0
  122. package/dist/config/config-resolver.d.ts +2 -1
  123. package/dist/config/config-resolver.js +54 -41
  124. package/dist/config/constants.d.ts +28 -0
  125. package/dist/config/constants.js +7 -0
  126. package/dist/config/env-schema.js +756 -0
  127. package/dist/config/model-tools.js +4 -4
  128. package/dist/config/toml-config.d.ts +16 -0
  129. package/dist/config/toml-config.js +3 -0
  130. package/dist/context/context-manager-v2.js +1 -0
  131. package/dist/daemon/autonomous-daemon.d.ts +1 -1
  132. package/dist/daemon/autonomous-daemon.js +3 -3
  133. package/dist/daemon/autonomous-loop.js +11 -2
  134. package/dist/daemon/colab-goal.js +9 -1
  135. package/dist/daemon/cron-agent-bridge.d.ts +12 -3
  136. package/dist/daemon/cron-agent-bridge.js +25 -9
  137. package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
  138. package/dist/desktop/codebuddy-engine-adapter.js +257 -80
  139. package/dist/desktop/engine-adapter.d.ts +14 -0
  140. package/dist/desktop-automation/automation-manager.js +16 -0
  141. package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
  142. package/dist/desktop-automation/omniparser-runner.js +115 -0
  143. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  144. package/dist/desktop-automation/smart-snapshot.js +72 -5
  145. package/dist/doctor/index.js +40 -23
  146. package/dist/events/types.d.ts +11 -0
  147. package/dist/fleet/colab-store.js +14 -2
  148. package/dist/fleet/peer-session-bridge.js +50 -12
  149. package/dist/fleet/peer-tool-bridge.js +14 -0
  150. package/dist/goals/goal-decomposer.d.ts +27 -0
  151. package/dist/goals/goal-decomposer.js +293 -0
  152. package/dist/goals/goal-judge-client.d.ts +15 -0
  153. package/dist/goals/goal-judge-client.js +45 -0
  154. package/dist/goals/goal-judge.d.ts +2 -0
  155. package/dist/goals/goal-judge.js +35 -6
  156. package/dist/goals/goal-loop.d.ts +14 -0
  157. package/dist/goals/goal-loop.js +47 -2
  158. package/dist/goals/goal-manager.d.ts +6 -0
  159. package/dist/goals/goal-manager.js +67 -14
  160. package/dist/goals/goal-state.d.ts +13 -0
  161. package/dist/goals/goal-state.js +83 -13
  162. package/dist/goals/goal-store.d.ts +3 -0
  163. package/dist/goals/goal-store.js +31 -15
  164. package/dist/hooks/user-hooks.js +17 -3
  165. package/dist/index.js +464 -25
  166. package/dist/input/text-to-speech.d.ts +2 -6
  167. package/dist/input/text-to-speech.js +2 -27
  168. package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
  169. package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
  170. package/dist/integrations/tailscale.d.ts +13 -0
  171. package/dist/integrations/tailscale.js +87 -34
  172. package/dist/knowledge/workspace-indexer.js +53 -9
  173. package/dist/mcp/client.js +1 -0
  174. package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
  175. package/dist/mcp/mcp-desktop-tools.js +158 -0
  176. package/dist/mcp/mcp-server.js +2 -0
  177. package/dist/memory/enhanced-memory.d.ts +10 -0
  178. package/dist/memory/enhanced-memory.js +33 -2
  179. package/dist/memory/index.d.ts +3 -1
  180. package/dist/memory/index.js +4 -1
  181. package/dist/memory/memory-auto-proposer.d.ts +23 -0
  182. package/dist/memory/memory-auto-proposer.js +308 -0
  183. package/dist/memory/memory-candidate-queue.d.ts +92 -0
  184. package/dist/memory/memory-candidate-queue.js +261 -0
  185. package/dist/memory/persistent-memory.d.ts +45 -2
  186. package/dist/memory/persistent-memory.js +236 -40
  187. package/dist/ml/bayesian-qualifier.d.ts +1 -1
  188. package/dist/ml/bayesian-qualifier.js +35 -2
  189. package/dist/openclaw/gateway-bridge.js +5 -0
  190. package/dist/plugins/marketplace.d.ts +1 -0
  191. package/dist/plugins/marketplace.js +7 -0
  192. package/dist/prompts/execution-discipline.d.ts +14 -0
  193. package/dist/prompts/execution-discipline.js +29 -0
  194. package/dist/prompts/variation-injector.js +9 -2
  195. package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
  196. package/dist/protocols/acp/acp-agentic-runner.js +115 -18
  197. package/dist/protocols/acp/acp-session-store.d.ts +23 -0
  198. package/dist/protocols/acp/acp-session-store.js +77 -0
  199. package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
  200. package/dist/protocols/acp/acp-stdio-server.js +71 -16
  201. package/dist/providers/active-llm-registry.d.ts +37 -0
  202. package/dist/providers/active-llm-registry.js +186 -0
  203. package/dist/providers/auxiliary-provider.d.ts +25 -0
  204. package/dist/providers/auxiliary-provider.js +192 -0
  205. package/dist/providers/codex-oauth.d.ts +1 -1
  206. package/dist/providers/codex-oauth.js +27 -4
  207. package/dist/providers/index.d.ts +3 -0
  208. package/dist/providers/index.js +4 -0
  209. package/dist/providers/provider-catalog.d.ts +70 -0
  210. package/dist/providers/provider-catalog.js +738 -0
  211. package/dist/providers/provider-fallback.d.ts +35 -0
  212. package/dist/providers/provider-fallback.js +171 -0
  213. package/dist/providers/xai-oauth.d.ts +128 -0
  214. package/dist/providers/xai-oauth.js +735 -0
  215. package/dist/scheduler/cron-scheduler.d.ts +15 -3
  216. package/dist/scheduler/cron-scheduler.js +53 -7
  217. package/dist/scheduler/script-runner.d.ts +2 -0
  218. package/dist/scheduler/script-runner.js +19 -4
  219. package/dist/scheduler/watchdog-handlers.js +7 -20
  220. package/dist/search/usearch-index.js +7 -2
  221. package/dist/security/tool-policy/tool-groups.js +2 -0
  222. package/dist/server/index.js +17 -2
  223. package/dist/server/routes/mobile.d.ts +12 -4
  224. package/dist/server/routes/mobile.js +116 -1
  225. package/dist/server/tls-config.d.ts +35 -0
  226. package/dist/server/tls-config.js +142 -0
  227. package/dist/server/tunnel-manager.d.ts +20 -0
  228. package/dist/server/tunnel-manager.js +58 -0
  229. package/dist/server/websocket/fleet-bridge.js +5 -0
  230. package/dist/services/prompt-builder.d.ts +1 -0
  231. package/dist/services/prompt-builder.js +49 -8
  232. package/dist/shared/engine-types.d.ts +15 -1
  233. package/dist/sidecar/sidecar-bridge.d.ts +1 -0
  234. package/dist/sidecar/sidecar-bridge.js +21 -10
  235. package/dist/spec/spec-store.js +8 -1
  236. package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
  237. package/dist/talk-mode/providers/audioreader-tts.js +8 -8
  238. package/dist/templates/project-scaffolding.js +3 -2
  239. package/dist/themes/theme-schema.d.ts +10 -10
  240. package/dist/tools/application-profiles.js +38 -0
  241. package/dist/tools/bash/bash-tool.d.ts +1 -0
  242. package/dist/tools/bash/bash-tool.js +16 -2
  243. package/dist/tools/bash/command-validator.js +3 -0
  244. package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
  245. package/dist/tools/bash/rtk-rewrite.js +100 -0
  246. package/dist/tools/bash/streaming-executor.js +14 -1
  247. package/dist/tools/computer-control-tool.d.ts +16 -1
  248. package/dist/tools/computer-control-tool.js +317 -5
  249. package/dist/tools/document-generator.d.ts +14 -0
  250. package/dist/tools/document-generator.js +79 -0
  251. package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
  252. package/dist/tools/execute-code-rpc-invoker.js +46 -5
  253. package/dist/tools/metadata.js +28 -0
  254. package/dist/tools/office-macro-tool.d.ts +10 -0
  255. package/dist/tools/office-macro-tool.js +93 -0
  256. package/dist/tools/registry/index.d.ts +2 -1
  257. package/dist/tools/registry/index.js +2 -1
  258. package/dist/tools/registry/memory-tools.d.ts +20 -0
  259. package/dist/tools/registry/memory-tools.js +225 -3
  260. package/dist/tools/registry/multimodal-tools.js +2 -2
  261. package/dist/tools/registry/vision-tools.d.ts +33 -0
  262. package/dist/tools/registry/vision-tools.js +308 -6
  263. package/dist/tools/registry/windows-tools.d.ts +2 -0
  264. package/dist/tools/registry/windows-tools.js +47 -0
  265. package/dist/tools/route-peer-tool.js +14 -0
  266. package/dist/tools/screenshot-tool.js +14 -2
  267. package/dist/tools/text-to-speech-tool.d.ts +1 -1
  268. package/dist/tools/text-to-speech-tool.js +2 -12
  269. package/dist/tools/tool-selector.js +3 -59
  270. package/dist/utils/config-validation/schema.d.ts +40 -7
  271. package/dist/utils/config-validation/schema.js +130 -1
  272. package/dist/utils/cost-tracker.js +21 -1
  273. package/dist/utils/disk-guard.d.ts +180 -0
  274. package/dist/utils/disk-guard.js +404 -0
  275. package/dist/utils/interactive-setup.js +35 -2
  276. package/dist/utils/model-utils.js +11 -2
  277. package/dist/utils/output-sanitizer.js +11 -0
  278. package/dist/utils/provider-detector.d.ts +8 -7
  279. package/dist/utils/provider-detector.js +19 -77
  280. package/dist/utils/settings-manager.d.ts +7 -0
  281. package/dist/utils/token-display.d.ts +3 -3
  282. package/dist/utils/token-display.js +22 -4
  283. package/dist/wizard/onboarding.d.ts +39 -0
  284. package/dist/wizard/onboarding.js +433 -21
  285. package/dist/wizard/provider-onboarding.d.ts +8 -23
  286. package/dist/wizard/provider-onboarding.js +39 -158
  287. package/package.json +4 -2
  288. package/dist/plugins/provider-onboarding.d.ts +0 -23
  289. package/dist/plugins/provider-onboarding.js +0 -116
  290. package/dist/utils/kokoro-tts.d.ts +0 -8
  291. package/dist/utils/kokoro-tts.js +0 -67
@@ -405,13 +405,13 @@ const DEFAULT_MODEL_CONFIGS = [
405
405
  patchFormat: 'full_file',
406
406
  promptProfile: 'lite',
407
407
  },
408
- // Gemma 4 (Ollama, e2b/e4b) — local lightweight model. Same lite
409
- // profile as qwen/llama: minimal SP, no tool_calls advertised,
410
- // chat-only base prompt to avoid JSON hallucination on small models.
408
+ // Gemma 4 (Ollama, e2b/e4b) — local model with tool support. Keep the
409
+ // lite prompt/tool profile, but do not gate off tool calls: real `buddy goal`
410
+ // smoke with gemma4:12b only succeeds when the selected tools are preserved.
411
411
  {
412
412
  model: 'gemma4*',
413
413
  supportsReasoning: false,
414
- supportsToolCalls: false,
414
+ supportsToolCalls: true,
415
415
  supportsVision: false,
416
416
  contextWindow: 8192,
417
417
  maxOutputTokens: 2048,
@@ -122,6 +122,20 @@ export interface ModelPairsConfig {
122
122
  /** Model used for code edits and execution (the "doer") */
123
123
  editor?: string;
124
124
  }
125
+ /** Active-LLM registry: auto-failover across the user's live logins + "together". */
126
+ export interface LlmFailoverConfig {
127
+ /** Master gate. OFF by default — single-provider behavior is unchanged. */
128
+ enabled?: boolean;
129
+ /** Fallback ordering: 'resilience' (capable/subscription first, local last),
130
+ * 'free-first' (cheapest first), or 'manual' (explicit `manualOrder`). */
131
+ order?: 'resilience' | 'free-first' | 'manual';
132
+ /** Provider ids in preferred order when `order: 'manual'`. */
133
+ manualOrder?: string[];
134
+ /** Restrict the active set to local runtimes (privacy). */
135
+ local_only?: boolean;
136
+ /** Default strategy for `/llm ensemble` (Phase 2). */
137
+ together_strategy?: 'ensemble' | 'consensus' | 'fastest' | 'cascade';
138
+ }
125
139
  /**
126
140
  * External integrations configuration
127
141
  */
@@ -497,6 +511,8 @@ export interface CodeBuddyConfig {
497
511
  integrations: IntegrationsConfig;
498
512
  /** Model pairs for architect/editor split */
499
513
  model_pairs?: ModelPairsConfig;
514
+ /** Active-LLM registry: auto-failover across live logins + "together" */
515
+ llm?: LlmFailoverConfig;
500
516
  /** Agent defaults (model preferences) — Native Engine v2026.3.14 */
501
517
  agent_defaults?: AgentDefaultsConfig;
502
518
  /** Advisor tool settings (second opinion model) — V4.1 */
@@ -540,6 +540,9 @@ class ConfigManager {
540
540
  if (partial.model_pairs) {
541
541
  this.config.model_pairs = { ...this.config.model_pairs, ...partial.model_pairs };
542
542
  }
543
+ if (partial.llm) {
544
+ this.config.llm = { ...this.config.llm, ...partial.llm };
545
+ }
543
546
  }
544
547
  /**
545
548
  * Get current config
@@ -699,6 +699,7 @@ export class ContextManagerV2 {
699
699
  * Clean up resources
700
700
  */
701
701
  dispose() {
702
+ this.stopPeriodicSnapshot();
702
703
  this.tokenCounter.dispose();
703
704
  this.summaries = [];
704
705
  this.triggeredWarnings.clear();
@@ -89,7 +89,7 @@ export interface DefaultAutonomousLoopOptions {
89
89
  * local/network executor. The CLI uses this so the same config drives one-shot
90
90
  * and continuous runs.
91
91
  */
92
- export declare function createDefaultAutonomousLoop(opts?: DefaultAutonomousLoopOptions): FleetAutonomousLoop;
92
+ export declare function createDefaultAutonomousLoop(opts?: DefaultAutonomousLoopOptions): Promise<FleetAutonomousLoop>;
93
93
  /**
94
94
  * Event source for {@link AutonomousDaemonConfig.eventSourceFactory}: watches the
95
95
  * fleet queue file (`colab-tasks.json`) and calls `onChange` when it changes —
@@ -13,7 +13,7 @@
13
13
  * (see {@link createAgentTaskExecutor}).
14
14
  */
15
15
  import { FleetColabStore } from '../fleet/colab-store.js';
16
- import { resolveModelTierConfig } from '../agent/model-tier.js';
16
+ import { resolveLiveModelTierConfig, } from '../agent/model-tier.js';
17
17
  import { FileWatcherTrigger } from '../agent/file-watcher-trigger.js';
18
18
  import { FleetAutonomousLoop } from './autonomous-loop.js';
19
19
  import { createLocalModelTaskExecutor } from './ollama-task-executor.js';
@@ -116,12 +116,12 @@ export class FleetAutonomousDaemon {
116
116
  * local/network executor. The CLI uses this so the same config drives one-shot
117
117
  * and continuous runs.
118
118
  */
119
- export function createDefaultAutonomousLoop(opts = {}) {
119
+ export async function createDefaultAutonomousLoop(opts = {}) {
120
120
  const store = new FleetColabStore({
121
121
  ...(opts.dir ? { dir: opts.dir } : {}),
122
122
  ...(opts.agentId ? { agentId: opts.agentId } : {}),
123
123
  });
124
- const tierConfig = resolveModelTierConfig();
124
+ const tierConfig = await resolveLiveModelTierConfig();
125
125
  const executorMode = opts.executorMode ?? (process.env['CODEBUDDY_AUTONOMY_EXECUTOR'] === 'agent' ? 'agent' : 'artifact');
126
126
  const executor = executorMode === 'agent'
127
127
  ? createAgentTaskExecutor({ ...(opts.workspaceRoot ? { workspaceRoot: opts.workspaceRoot } : {}) })
@@ -23,6 +23,14 @@
23
23
  import { chooseAutonomousModel, } from '../agent/model-tier.js';
24
24
  import { beginFleetWork, isFleetSaturated } from '../fleet/fleet-load.js';
25
25
  import { DEFAULT_COLAB_GOAL_MAX_TURNS } from './colab-goal.js';
26
+ function resolveGoalMaxTurns(raw) {
27
+ return typeof raw === 'number' && Number.isSafeInteger(raw) && raw > 0
28
+ ? raw
29
+ : DEFAULT_COLAB_GOAL_MAX_TURNS;
30
+ }
31
+ function resolveGoalTurnsUsed(raw) {
32
+ return typeof raw === 'number' && Number.isSafeInteger(raw) && raw >= 0 ? raw : 0;
33
+ }
26
34
  export class FleetAutonomousLoop {
27
35
  store;
28
36
  tierConfig;
@@ -145,11 +153,12 @@ export class FleetAutonomousLoop {
145
153
  }
146
154
  if (verdict.verdict !== 'continue')
147
155
  return null;
148
- const maxTurns = task.goalMaxTurns ?? DEFAULT_COLAB_GOAL_MAX_TURNS;
149
- const turnsUsed = (task.goalTurnsUsed ?? 0) + 1;
156
+ const maxTurns = resolveGoalMaxTurns(task.goalMaxTurns);
157
+ const turnsUsed = resolveGoalTurnsUsed(task.goalTurnsUsed) + 1;
150
158
  if (turnsUsed >= maxTurns) {
151
159
  // Hermes rule: block for human review instead of spinning forever.
152
160
  const reason = `goal budget exhausted (${turnsUsed}/${maxTurns}) — judge: ${verdict.reason}`;
161
+ this.store.recordGoalTurn(task.id, verdict.reason);
153
162
  this.store.blockTask(task.id, reason);
154
163
  this.store.appendWorklog({
155
164
  agent: this.store.agentId,
@@ -12,6 +12,7 @@
12
12
  * "continue", and the turn budget is the backstop.
13
13
  */
14
14
  import { CodeBuddyClient } from '../codebuddy/client.js';
15
+ import { resolveGoalJudgeClient } from '../goals/goal-judge-client.js';
15
16
  import { judgeGoal } from '../goals/goal-judge.js';
16
17
  import { resolveGoalsConfig } from '../goals/goal-manager.js';
17
18
  import { logger } from '../utils/logger.js';
@@ -54,12 +55,19 @@ export function createColabGoalJudge() {
54
55
  return async (task, result, model) => {
55
56
  try {
56
57
  const config = resolveGoalsConfig();
57
- const client = new CodeBuddyClient(process.env.GROK_API_KEY || process.env.OPENAI_API_KEY || 'local', config.judgeModel || model.model, model.baseUrl);
58
+ const apiKey = process.env.GROK_API_KEY || process.env.OPENAI_API_KEY || 'local';
59
+ const baseClient = new CodeBuddyClient(apiKey, model.model, model.baseUrl);
60
+ const client = await resolveGoalJudgeClient(baseClient, config.judgeModel, {
61
+ apiKey,
62
+ ...(model.baseUrl ? { baseURL: model.baseUrl } : {}),
63
+ providerLabel: model.baseUrl?.includes(':11434') ? 'ollama' : model.tier,
64
+ });
58
65
  return await judgeGoal(client, {
59
66
  goal: goalTextForTask(task),
60
67
  lastResponse: result.output || result.summary,
61
68
  ...(task.acceptanceCriteria?.length ? { subgoals: task.acceptanceCriteria } : {}),
62
69
  ...(config.judgeModel ? { model: config.judgeModel } : {}),
70
+ maxTokens: config.judgeMaxTokens,
63
71
  timeoutMs: config.judgeTimeoutMs,
64
72
  });
65
73
  }
@@ -40,6 +40,12 @@ export interface JobExecutionResult {
40
40
  skipReason?: string;
41
41
  /** For watchdog jobs: false when any check produced an alert/error. */
42
42
  watchdogOk?: boolean;
43
+ /**
44
+ * Structured output data for cross-job data passing. When this job is part
45
+ * of a chain (`then`), its outputData is forwarded as the next job's
46
+ * inputData.
47
+ */
48
+ outputData?: string;
43
49
  }
44
50
  export declare class CronAgentBridge extends EventEmitter {
45
51
  private config;
@@ -48,11 +54,11 @@ export declare class CronAgentBridge extends EventEmitter {
48
54
  /**
49
55
  * Create a task executor function for the CronScheduler
50
56
  */
51
- createTaskExecutor(): (job: CronJob) => Promise<unknown>;
57
+ createTaskExecutor(): (job: CronJob, inputData?: string) => Promise<unknown>;
52
58
  /**
53
59
  * Execute a cron job by creating an agent instance
54
60
  */
55
- executeJob(job: CronJob): Promise<JobExecutionResult>;
61
+ executeJob(job: CronJob, inputData?: string): Promise<JobExecutionResult>;
56
62
  /**
57
63
  * Start a durable run record for a job execution, when an observability store
58
64
  * is configured. Returns the run id, or undefined when recording is disabled
@@ -86,8 +92,11 @@ export declare class CronAgentBridge extends EventEmitter {
86
92
  * WITHOUT instantiating a CodeBuddyAgent or calling any model provider.
87
93
  * A non-zero exit (or timeout) throws so the run is recorded as failed and
88
94
  * any chained `then` job does not fire.
95
+ *
96
+ * Returns both the combined output (for logging/delivery) and the separate
97
+ * stdout (for cross-job data passing, capped at 64KB by the script runner).
89
98
  */
90
- private executeScriptTask;
99
+ private executeScriptTaskFull;
91
100
  /**
92
101
  * Execute a skill-type task — resolves a named skill from the SkillRegistry
93
102
  * and runs it via the SkillExecutor. Without a configured tool executor the
@@ -28,14 +28,14 @@ export class CronAgentBridge extends EventEmitter {
28
28
  * Create a task executor function for the CronScheduler
29
29
  */
30
30
  createTaskExecutor() {
31
- return async (job) => {
32
- return this.executeJob(job);
31
+ return async (job, inputData) => {
32
+ return this.executeJob(job, inputData);
33
33
  };
34
34
  }
35
35
  /**
36
36
  * Execute a cron job by creating an agent instance
37
37
  */
38
- async executeJob(job) {
38
+ async executeJob(job, inputData) {
39
39
  const startTime = Date.now();
40
40
  const abortController = new AbortController();
41
41
  this.activeJobs.set(job.id, abortController);
@@ -80,9 +80,10 @@ export class CronAgentBridge extends EventEmitter {
80
80
  }
81
81
  let output;
82
82
  let watchdogOk;
83
+ let scriptStdout;
83
84
  switch (job.task.type) {
84
85
  case 'message': {
85
- output = await this.executeMessageTask(job);
86
+ output = await this.executeMessageTask(job, inputData);
86
87
  break;
87
88
  }
88
89
  case 'tool': {
@@ -100,7 +101,9 @@ export class CronAgentBridge extends EventEmitter {
100
101
  break;
101
102
  }
102
103
  case 'script': {
103
- output = await this.executeScriptTask(job);
104
+ const scriptResult = await this.executeScriptTaskFull(job);
105
+ output = scriptResult.output;
106
+ scriptStdout = scriptResult.stdout;
104
107
  break;
105
108
  }
106
109
  case 'skill': {
@@ -132,6 +135,10 @@ export class CronAgentBridge extends EventEmitter {
132
135
  deliveryChannel,
133
136
  ...(watchdogOk !== undefined ? { watchdogOk } : {}),
134
137
  });
138
+ // For script jobs, outputData is the captured stdout only (structured
139
+ // data channel, capped at 64KB in the script runner). For all other
140
+ // task types, the full output serves as outputData.
141
+ const outputData = job.task.type === 'script' ? scriptStdout : output;
135
142
  const result = {
136
143
  jobId: job.id,
137
144
  runId: recordedRunId ?? `run-${Date.now()}`,
@@ -140,6 +147,7 @@ export class CronAgentBridge extends EventEmitter {
140
147
  duration,
141
148
  delivered,
142
149
  deliveryChannel,
150
+ outputData,
143
151
  ...(watchdogOk !== undefined ? { watchdogOk } : {}),
144
152
  };
145
153
  this.emit('job:complete', result);
@@ -223,7 +231,7 @@ export class CronAgentBridge extends EventEmitter {
223
231
  /**
224
232
  * Execute a message-type task
225
233
  */
226
- async executeMessageTask(job) {
234
+ async executeMessageTask(job, inputData) {
227
235
  if (!job.task.message) {
228
236
  throw new Error('Message task requires a message');
229
237
  }
@@ -245,7 +253,12 @@ export class CronAgentBridge extends EventEmitter {
245
253
  logger.debug(`Cron job ${job.id}: could not load session ${job.resolvedSessionId}, starting fresh`);
246
254
  }
247
255
  }
248
- const entries = await agent.processUserMessage(job.task.message);
256
+ // Prepend inputData from parent chained job if available
257
+ let message = job.task.message;
258
+ if (inputData) {
259
+ message = `[Chained job context — output from parent job]:\n${inputData}\n\n[Task]:\n${message}`;
260
+ }
261
+ const entries = await agent.processUserMessage(message);
249
262
  const assistantEntries = entries.filter(e => e.type === 'assistant');
250
263
  return assistantEntries.map(e => e.content).join('\n') || 'No response';
251
264
  }
@@ -292,8 +305,11 @@ export class CronAgentBridge extends EventEmitter {
292
305
  * WITHOUT instantiating a CodeBuddyAgent or calling any model provider.
293
306
  * A non-zero exit (or timeout) throws so the run is recorded as failed and
294
307
  * any chained `then` job does not fire.
308
+ *
309
+ * Returns both the combined output (for logging/delivery) and the separate
310
+ * stdout (for cross-job data passing, capped at 64KB by the script runner).
295
311
  */
296
- async executeScriptTask(job) {
312
+ async executeScriptTaskFull(job) {
297
313
  const command = job.task.command;
298
314
  if (!command || typeof command.executable !== 'string' || command.executable.length === 0) {
299
315
  throw new Error('Script task requires a command with an executable');
@@ -312,7 +328,7 @@ export class CronAgentBridge extends EventEmitter {
312
328
  if (result.exitCode !== 0) {
313
329
  throw new Error(`script failed: ${command.executable} (exit ${result.exitCode})\n${result.output}`.trim());
314
330
  }
315
- return result.output;
331
+ return { output: result.output, stdout: result.stdout };
316
332
  }
317
333
  /**
318
334
  * Execute a skill-type task — resolves a named skill from the SkillRegistry
@@ -40,6 +40,12 @@ export declare class CodeBuddyEngineAdapter implements EngineAdapter {
40
40
  * effect on the next turn (Phase 8).
41
41
  */
42
42
  private agentIdentities;
43
+ /**
44
+ * Configured reasoning/thinking level (`off | minimal | … | xhigh`), set via
45
+ * {@link setThinkingLevel}. Re-applied to each freshly-created agent so a
46
+ * model swap / new session keeps the user's chosen level.
47
+ */
48
+ private thinkingLevel?;
43
49
  /**
44
50
  * Hard cap on cached agents — matches the pi-runner's
45
51
  * `MAX_CACHED_SESSIONS` (50) so memory pressure is comparable
@@ -50,6 +56,7 @@ export declare class CodeBuddyEngineAdapter implements EngineAdapter {
50
56
  constructor(config: EngineSessionConfig);
51
57
  runSession(sessionId: string, messages: EngineMessage[], onEvent: EngineStreamCallback, options?: Partial<EngineSessionConfig>): Promise<EngineSessionResult>;
52
58
  cancel(sessionId: string): void;
59
+ steer(sessionId: string, prompt: string): boolean;
53
60
  clearSession(sessionId: string): void;
54
61
  /**
55
62
  * Drop oldest cached agents until `agents.size <= maxRetained`.
@@ -70,6 +77,21 @@ export declare class CodeBuddyEngineAdapter implements EngineAdapter {
70
77
  * returns whatever survived the previous load.
71
78
  */
72
79
  reloadSkills(): Promise<void>;
80
+ /**
81
+ * Hot-swap the reasoning/thinking level for live sessions. Updates the global
82
+ * extended-thinking budget (read per-turn by the OpenAI-compat / Grok / Ollama
83
+ * providers → effective next turn, no rebuild) and the Gemini-native default on
84
+ * every cached agent. The level is remembered so future agents inherit it.
85
+ */
86
+ setThinkingLevel(level: string): Promise<void>;
87
+ /**
88
+ * Map a UI level to the Gemini-native default thinking level on a single
89
+ * agent's client. `GeminiThinkingLevel` is `minimal|low|medium|high`, so
90
+ * `xhigh` clamps to `high` and `off`/unknown leaves the Gemini default
91
+ * untouched (the global extended-thinking switch already disables it for the
92
+ * OpenAI-compat path). Best-effort; never throws.
93
+ */
94
+ private applyGeminiThinkingLevel;
73
95
  /**
74
96
  * Synchronise the core MCPManager singleton with the host's view of
75
97
  * the MCP servers. Called by Cowork at boot and after any
@@ -97,3 +119,13 @@ export declare class CodeBuddyEngineAdapter implements EngineAdapter {
97
119
  */
98
120
  updateConfig(config: Partial<EngineSessionConfig>): void;
99
121
  }
122
+ /** Cap a single failure detail so the footer stays compact for the judge. */
123
+ export declare function truncateFailureDetail(detail: string, max?: number): string;
124
+ /**
125
+ * Build a prominent, NON-bracketed footer listing failed tool actions. The goal
126
+ * judge prompt (goal-state.ts) treats `[tool:…]` bracketed lines as ignorable
127
+ * metadata, so failures must be surfaced as a plain instruction line or the
128
+ * judge discounts them. Returns '' when there are no failures.
129
+ */
130
+ export declare function buildToolFailureFooter(failures: string[]): string;
131
+ export declare function buildGoalJudgeResponse(content: string, toolEvidence: string[], toolFailures?: string[]): string;