@visorcraft/idlehands 2.1.4 → 2.2.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.
@@ -54,20 +54,61 @@ export function approvalSetCommand(managed, arg) {
54
54
  managed.approvalMode = arg;
55
55
  return { success: `✅ Approval mode set to ${arg}` };
56
56
  }
57
+ // Routing modes for Phase 2 - Fast/Heavy/Auto Routing
58
+ const ROUTING_MODES = ['auto', 'fast', 'heavy'];
57
59
  export function modeShowCommand(managed) {
58
- return { kv: [['Mode', managed.config.mode ?? 'code', true]] };
60
+ const mode = managed.config.mode ?? 'code';
61
+ return {
62
+ kv: [['Mode', mode, true]],
63
+ lines: mode === 'auto' || mode === 'fast' || mode === 'heavy'
64
+ ? [`Routing mode: ${mode}`]
65
+ : undefined
66
+ };
59
67
  }
60
68
  export function modeSetCommand(managed, arg) {
61
- if (arg !== 'code' && arg !== 'sys') {
62
- return { error: 'Invalid mode. Options: code, sys' };
69
+ // Check if it's a routing mode
70
+ if (ROUTING_MODES.includes(arg)) {
71
+ managed.config.mode = arg;
72
+ return { success: `✅ Routing mode set to ${arg}` };
63
73
  }
64
- managed.config.mode = arg;
65
- if (arg === 'sys' && managed.config.approval_mode === 'auto-edit') {
66
- managed.config.approval_mode = 'default';
67
- if ('approvalMode' in managed)
68
- managed.approvalMode = 'default';
74
+ // Check if it's a legacy mode (code/sys)
75
+ if (arg === 'code' || arg === 'sys') {
76
+ managed.config.mode = arg;
77
+ if (arg === 'sys' && managed.config.approval_mode === 'auto-edit') {
78
+ managed.config.approval_mode = 'default';
79
+ if ('approvalMode' in managed)
80
+ managed.approvalMode = 'default';
81
+ }
82
+ return { success: `✅ Mode set to ${arg}` };
69
83
  }
70
- return { success: `✅ Mode set to ${arg}` };
84
+ // Invalid mode
85
+ return {
86
+ error: `Invalid mode. Options: code, sys, ${ROUTING_MODES.join(', ')}`
87
+ };
88
+ }
89
+ export function modeStatusCommand(managed) {
90
+ const mode = managed.config.mode ?? 'code';
91
+ const lines = [];
92
+ if (mode === 'auto' || mode === 'fast' || mode === 'heavy') {
93
+ lines.push(`Current routing mode: ${mode}`);
94
+ }
95
+ else {
96
+ lines.push(`Current mode: ${mode}`);
97
+ }
98
+ // Show routing config if available
99
+ const routing = managed.config.routing;
100
+ if (routing) {
101
+ lines.push(`Default mode: ${routing.defaultMode ?? 'auto'}`);
102
+ lines.push(`Fast model: ${routing.fastModel ?? 'not configured'}`);
103
+ lines.push(`Heavy model: ${routing.heavyModel ?? 'not configured'}`);
104
+ }
105
+ else {
106
+ lines.push('Routing not configured');
107
+ }
108
+ return {
109
+ title: 'Routing Mode Status',
110
+ lines
111
+ };
71
112
  }
72
113
  export function subagentsShowCommand(managed) {
73
114
  const current = managed.config.sub_agents?.enabled !== false;
@@ -1 +1 @@
1
- {"version":3,"file":"session-settings.js","sourceRoot":"","sources":["../../src/bot/session-settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-settings.js","sourceRoot":"","sources":["../../src/bot/session-settings.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  * Handles /hosts, /backends, /models, /rtstatus, /switch and the
4
4
  * model-selection callback query.
5
5
  */
6
+ import path from 'node:path';
6
7
  /**
7
8
  * Register runtime-related command handlers on the bot instance.
8
9
  */
@@ -118,6 +119,82 @@ export function registerRuntimeCommands(bot) {
118
119
  await ctx.reply(`❌ Upgrade failed: ${e?.message ?? String(e)}`);
119
120
  }
120
121
  });
122
+ bot.command('check_template', async (ctx) => {
123
+ try {
124
+ const modelId = ctx.match?.toString().trim();
125
+ const { loadRuntimes, saveRuntimes } = await import('../runtime/store.js');
126
+ const { checkTemplate, checkAndFixTemplate } = await import('../runtime/template-check.js');
127
+ const rtConfig = await loadRuntimes();
128
+ if (!modelId) {
129
+ // Check all enabled models
130
+ await ctx.reply('🔍 Checking templates for all models...');
131
+ const results = [];
132
+ for (const model of rtConfig.models.filter((m) => m.enabled)) {
133
+ const r = await checkTemplate(model, rtConfig);
134
+ const runIcon = r.runningTemplate === 'passed-in' ? '🟢' :
135
+ r.runningTemplate === 'embedded' ? '🔴' : '⚫';
136
+ const runLabel = r.runningTemplate === 'passed-in' ? 'passed-in' :
137
+ r.runningTemplate === 'embedded' ? 'embedded' : 'not running';
138
+ if (r.error) {
139
+ results.push(`⚠️ *${model.id}* [${runIcon} ${runLabel}]: ${r.error}`);
140
+ }
141
+ else if (r.match === true) {
142
+ results.push(`✅ *${model.id}* [${runIcon} ${runLabel}]: GGUF matches HF`);
143
+ }
144
+ else {
145
+ results.push(`❌ *${model.id}* [${runIcon} ${runLabel}]: MISMATCH`);
146
+ }
147
+ }
148
+ await ctx.reply(results.join('\n'), { parse_mode: 'Markdown' });
149
+ return;
150
+ }
151
+ const model = rtConfig.models.find((m) => m.id === modelId);
152
+ if (!model) {
153
+ await ctx.reply(`❌ Model not found: ${modelId}`);
154
+ return;
155
+ }
156
+ await ctx.reply(`🔍 Checking template for *${modelId}*...`, { parse_mode: 'Markdown' });
157
+ const result = await checkAndFixTemplate(model, rtConfig);
158
+ const lines = [];
159
+ lines.push(`📋 *Template Check: ${modelId}*`);
160
+ lines.push(`Source: \`${path.basename(model.source)}\``);
161
+ lines.push(`HF Repo: ${result.hfRepoUrl || 'unknown'}`);
162
+ lines.push(`GGUF template: ${result.ggufTemplate ? `${result.ggufTemplate.length} chars` : 'not found'}`);
163
+ lines.push(`HF template: ${result.hfTemplate ? `${result.hfTemplate.length} chars` : 'not found'}`);
164
+ const runIcon = result.runningTemplate === 'passed-in' ? '🟢' :
165
+ result.runningTemplate === 'embedded' ? '🔴' : '⚫';
166
+ if (result.runningTemplate === 'passed-in') {
167
+ lines.push(`Running: ${runIcon} Using passed-in template: \`${result.runningTemplatePath}\``);
168
+ }
169
+ else if (result.runningTemplate === 'embedded') {
170
+ lines.push(`Running: ${runIcon} Using embedded GGUF template (may be incorrect)`);
171
+ }
172
+ else if (result.runningTemplate === 'not-running') {
173
+ lines.push(`Running: ${runIcon} Not running`);
174
+ }
175
+ if (result.error) {
176
+ lines.push(`\n⚠️ ${result.error}`);
177
+ }
178
+ else if (result.match === true) {
179
+ lines.push('\n✅ Templates match — no action needed');
180
+ }
181
+ else if (result.fixed) {
182
+ lines.push(`\n❌ MISMATCH detected`);
183
+ lines.push(`✅ Fixed: saved correct template to \`${result.templatePath}\``);
184
+ lines.push(`Updated model config with \`chat_template: "${model.chat_template}"\``);
185
+ // Save the updated config
186
+ await saveRuntimes(rtConfig);
187
+ lines.push('💾 runtimes.json saved');
188
+ }
189
+ else {
190
+ lines.push('\n❌ MISMATCH detected but could not auto-fix');
191
+ }
192
+ await ctx.reply(lines.join('\n'), { parse_mode: 'Markdown' });
193
+ }
194
+ catch (e) {
195
+ await ctx.reply(`❌ check_template error: ${e?.message ?? String(e)}`);
196
+ }
197
+ });
121
198
  bot.command('switch', async (ctx) => {
122
199
  try {
123
200
  const modelId = ctx.match?.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"telegram-commands.js","sourceRoot":"","sources":["../../src/bot/telegram-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telegram-commands.js","sourceRoot":"","sources":["../../src/bot/telegram-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Routing policy module for IdleHands.
3
+ *
4
+ * Determines whether to use "fast" or "heavy" mode based on input characteristics.
5
+ * Outputs: `fast | heavy | auto-selected-fast | auto-selected-heavy`.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Core Routing Logic
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Analyze prompt and compute complexity heuristics.
12
+ */
13
+ export function analyzeComplexity(prompt) {
14
+ const promptLength = prompt.length;
15
+ const words = prompt.trim().split(/\s+/).filter(w => w.length > 0);
16
+ const wordCount = words.length;
17
+ const estimatedTokens = Math.ceil(wordCount * 1.3);
18
+ // Detect code blocks (``` or inline `code`)
19
+ const codeBlockCount = (prompt.match(/```[\s\S]*?```/g) || []).length;
20
+ const inlineCodeCount = (prompt.match(/`[^`]+`/g) || []).length;
21
+ const hasCodeBlocks = codeBlockCount > 0 || inlineCodeCount > 5;
22
+ // Detect complex instructions (numbered lists, bullet points, multi-step)
23
+ const hasComplexInstructions = /(?:^|\n)(?:\d+\.|\-|\*|\+)\s+/m.test(prompt) &&
24
+ prompt.split(/\n/).filter(l => l.trim().length > 0).length >= 3;
25
+ // Detect file references (paths like src/, /home/, .ts, etc.) - more specific regex
26
+ const hasFileReferences = /(?:^|\/)[\w\-]+(?:\/[\w\-]+)*(?:\.[a-zA-Z]{2,})|https?:\/\/[^\s]+/i.test(prompt);
27
+ // Detect technical terms
28
+ const technicalTerms = ['import', 'export', 'function', 'const', 'let', 'var', 'class', 'interface',
29
+ 'type', 'interface', 'async', 'await', 'return', 'if', 'else', 'for', 'while',
30
+ 'try', 'catch', 'throw', 'new', 'this', 'public', 'private', 'protected',
31
+ 'static', 'async', 'interface', 'implements', 'extends', 'abstract',
32
+ 'namespace', 'module', 'import', 'export', 'from', 'require'];
33
+ const promptLower = prompt.toLowerCase();
34
+ const technicalCount = technicalTerms.reduce((count, term) => count + (promptLower.split(new RegExp(`\\b${term}\\b`, 'g')).length - 1), 0);
35
+ const isTechnical = technicalCount >= 3;
36
+ return {
37
+ promptLength,
38
+ wordCount,
39
+ estimatedTokens,
40
+ hasCodeBlocks,
41
+ hasComplexInstructions,
42
+ hasFileReferences,
43
+ isTechnical
44
+ };
45
+ }
46
+ /**
47
+ * Classify command category from prompt.
48
+ */
49
+ export function classifyCommand(prompt) {
50
+ const promptLower = prompt.toLowerCase();
51
+ // Check for analysis-related keywords first (more specific)
52
+ const analysisKeywords = ['analyze', 'review', 'explain', 'document', 'describe', 'summarize',
53
+ 'evaluate', 'compare', 'discuss', 'interpret'];
54
+ if (analysisKeywords.some(k => promptLower.includes(k))) {
55
+ return 'analysis';
56
+ }
57
+ // Check for code-related keywords
58
+ const codeKeywords = ['implement', 'create', 'build', 'write', 'fix', 'debug', 'refactor',
59
+ 'modify', 'add', 'remove', 'update', 'change', 'function', 'class'];
60
+ if (codeKeywords.some(k => promptLower.includes(k))) {
61
+ return 'code';
62
+ }
63
+ // Check for file-related keywords
64
+ const fileKeywords = ['read', 'delete', 'move', 'copy', 'list', 'directory', 'folder', 'path'];
65
+ if (fileKeywords.some(k => promptLower.includes(k))) {
66
+ return 'file';
67
+ }
68
+ // Check for system-related keywords
69
+ const systemKeywords = ['config', 'setup', 'install', 'run', 'build', 'test', 'deploy',
70
+ 'server', 'docker', 'kubernetes', 'k8s'];
71
+ if (systemKeywords.some(k => promptLower.includes(k))) {
72
+ return 'system';
73
+ }
74
+ // Default to query for general questions
75
+ return 'query';
76
+ }
77
+ /**
78
+ * Determine routing decision based on inputs.
79
+ *
80
+ * @param prompt - The user's input prompt
81
+ * @param complexity - Pre-computed complexity heuristics (optional, will be computed if not provided)
82
+ * @param commandCategory - Command category (optional, will be classified if not provided)
83
+ * @param requestedMode - User-requested mode (auto/fast/heavy)
84
+ * @param modelHealth - Current model availability and health
85
+ * @param config - Routing configuration
86
+ * @returns Routing decision
87
+ */
88
+ export function determineRouting(prompt, complexity, commandCategory, requestedMode, modelHealth, config) {
89
+ // Compute defaults if not provided
90
+ const computedComplexity = complexity ?? analyzeComplexity(prompt);
91
+ const computedCommandCategory = commandCategory ?? classifyCommand(prompt);
92
+ const effectiveMode = requestedMode ?? 'auto';
93
+ // Default configuration
94
+ const defaultConfig = {
95
+ defaultMode: 'auto',
96
+ fastModel: 'default-fast',
97
+ heavyModel: 'default-heavy',
98
+ thresholds: {
99
+ maxPromptLength: 500,
100
+ maxTokens: 100,
101
+ maxWords: 80
102
+ },
103
+ autoEscalationRules: {
104
+ codeBlocksThreshold: 1,
105
+ fileReferencesThreshold: 3,
106
+ complexInstructionsThreshold: 1
107
+ }
108
+ };
109
+ const finalConfig = { ...defaultConfig, ...config };
110
+ // Check model health
111
+ const fastAvailable = modelHealth?.fastAvailable ?? true;
112
+ const heavyAvailable = modelHealth?.heavyAvailable ?? true;
113
+ // If only one model is available, use it
114
+ if (!fastAvailable && heavyAvailable) {
115
+ return 'heavy';
116
+ }
117
+ if (fastAvailable && !heavyAvailable) {
118
+ return 'fast';
119
+ }
120
+ if (!fastAvailable && !heavyAvailable) {
121
+ // Both unavailable - this is an error case, default to heavy
122
+ return 'heavy';
123
+ }
124
+ // Handle explicit mode requests
125
+ if (effectiveMode === 'fast') {
126
+ return 'fast';
127
+ }
128
+ if (effectiveMode === 'heavy') {
129
+ return 'heavy';
130
+ }
131
+ // Auto mode - use heuristics
132
+ const { thresholds, autoEscalationRules } = finalConfig;
133
+ // Check for auto-escalation triggers
134
+ let shouldEscalate = false;
135
+ if (computedComplexity.hasCodeBlocks) {
136
+ shouldEscalate = true;
137
+ }
138
+ if (computedComplexity.hasFileReferences) {
139
+ shouldEscalate = true;
140
+ }
141
+ if (computedComplexity.hasComplexInstructions) {
142
+ shouldEscalate = true;
143
+ }
144
+ // Check thresholds
145
+ if (computedComplexity.promptLength > thresholds.maxPromptLength ||
146
+ computedComplexity.estimatedTokens > thresholds.maxTokens ||
147
+ computedComplexity.wordCount > thresholds.maxWords) {
148
+ shouldEscalate = true;
149
+ }
150
+ // Command category-based escalation
151
+ if (computedCommandCategory === 'code' || computedCommandCategory === 'analysis') {
152
+ shouldEscalate = true;
153
+ }
154
+ return shouldEscalate ? 'auto-selected-heavy' : 'auto-selected-fast';
155
+ }
156
+ /**
157
+ * Get model identifier for a routing decision.
158
+ */
159
+ export function getModelForDecision(decision, config) {
160
+ switch (decision) {
161
+ case 'fast':
162
+ case 'auto-selected-fast':
163
+ return config.fastModel;
164
+ case 'heavy':
165
+ case 'auto-selected-heavy':
166
+ return config.heavyModel;
167
+ }
168
+ }
169
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/routing/policy.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
2
3
  import fs from 'node:fs/promises';
3
4
  import path from 'node:path';
4
5
  import { sleep } from '../shared/async.js';
@@ -350,6 +351,121 @@ async function teardownPartialStart(plan, outcomes) {
350
351
  /**
351
352
  * Execute a runtime plan.
352
353
  */
354
+ /**
355
+ * Build SSH args common to sync operations (BatchMode, key, port).
356
+ */
357
+ function buildSshArgs(host, keyPath) {
358
+ const args = ['-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10'];
359
+ if (keyPath)
360
+ args.push('-i', keyPath);
361
+ if (host.connection.port && host.connection.port !== 22)
362
+ args.push('-p', String(host.connection.port));
363
+ return args;
364
+ }
365
+ /**
366
+ * Resolve the SSH key path for a host, handling secret refs.
367
+ */
368
+ async function resolveHostKeyPath(host) {
369
+ if (!host.connection.key_path)
370
+ return undefined;
371
+ try {
372
+ const store = new SecretsStore(process.env.IDLEHANDS_SECRETS_PASSPHRASE || null);
373
+ await store.load();
374
+ return resolveSecretRef(host.connection.key_path, store);
375
+ }
376
+ catch {
377
+ return host.connection.key_path;
378
+ }
379
+ }
380
+ /**
381
+ * Get the remote user's home directory via SSH.
382
+ */
383
+ async function getRemoteHomeDir(host, keyPath) {
384
+ const target = host.connection.user
385
+ ? `${host.connection.user}@${host.connection.host}`
386
+ : host.connection.host;
387
+ const args = buildSshArgs(host, keyPath);
388
+ args.push(target, 'echo', '$HOME');
389
+ return new Promise((resolve) => {
390
+ const child = spawn('ssh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
391
+ let stdout = '';
392
+ child.stdout?.on('data', (d) => { stdout += d.toString(); });
393
+ child.on('close', (code) => {
394
+ const home = stdout.trim();
395
+ resolve(home || `/home/${host.connection.user ?? 'root'}`);
396
+ });
397
+ child.on('error', () => resolve(`/home/${host.connection.user ?? 'root'}`));
398
+ setTimeout(() => { try {
399
+ child.kill();
400
+ }
401
+ catch { } }, 10000);
402
+ });
403
+ }
404
+ /**
405
+ * Sync chat template files to remote hosts before starting a model.
406
+ * Copies from the local project repo to <home>/.idlehands/templates/ on each remote host.
407
+ * Returns a map of host_id → absolute remote template path for command rewriting.
408
+ */
409
+ async function syncTemplatesToHosts(plan) {
410
+ const remoteTemplatePaths = new Map();
411
+ const chatTemplate = plan.model.chat_template;
412
+ if (!chatTemplate)
413
+ return remoteTemplatePaths;
414
+ // Only sync file paths (not built-in names like "chatml")
415
+ if (!/\.jinja\b|[/\\]/.test(chatTemplate))
416
+ return remoteTemplatePaths;
417
+ // Resolve local path: try absolute, then relative to cwd
418
+ const localPath = path.isAbsolute(chatTemplate) ? chatTemplate : path.resolve(chatTemplate);
419
+ if (!existsSync(localPath)) {
420
+ console.error(`[runtime] chat_template file not found locally: ${localPath}`);
421
+ return remoteTemplatePaths;
422
+ }
423
+ const remoteFilename = path.basename(localPath);
424
+ for (const host of plan.hosts) {
425
+ if (host.transport === 'local') {
426
+ // Local: use absolute path directly
427
+ remoteTemplatePaths.set(host.id, localPath);
428
+ continue;
429
+ }
430
+ const targetHost = host.connection.host;
431
+ if (!targetHost)
432
+ continue;
433
+ const target = host.connection.user ? `${host.connection.user}@${targetHost}` : targetHost;
434
+ const keyPath = await resolveHostKeyPath(host);
435
+ try {
436
+ // Resolve actual home directory
437
+ const homeDir = await getRemoteHomeDir(host, keyPath);
438
+ const remoteDir = `${homeDir}/.idlehands/templates`;
439
+ const remotePath = `${remoteDir}/${remoteFilename}`;
440
+ // Create remote directory
441
+ const mkdirArgs = buildSshArgs(host, keyPath);
442
+ mkdirArgs.push(target, `mkdir -p ${remoteDir}`);
443
+ await new Promise((resolve, reject) => {
444
+ const child = spawn('ssh', mkdirArgs, { stdio: 'ignore' });
445
+ child.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`mkdir exit ${code}`))));
446
+ child.on('error', reject);
447
+ });
448
+ // SCP the template file
449
+ const scpArgs = ['-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10'];
450
+ if (keyPath)
451
+ scpArgs.push('-i', keyPath);
452
+ if (host.connection.port && host.connection.port !== 22)
453
+ scpArgs.push('-P', String(host.connection.port));
454
+ scpArgs.push(localPath, `${target}:${remotePath}`);
455
+ await new Promise((resolve, reject) => {
456
+ const child = spawn('scp', scpArgs, { stdio: 'ignore' });
457
+ child.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`scp exit ${code}`))));
458
+ child.on('error', reject);
459
+ });
460
+ remoteTemplatePaths.set(host.id, remotePath);
461
+ console.error(`[runtime] synced template ${remoteFilename} → ${host.id}:${remotePath}`);
462
+ }
463
+ catch (e) {
464
+ console.error(`[runtime] failed to sync template to ${host.id}: ${e?.message ?? e}`);
465
+ }
466
+ }
467
+ return remoteTemplatePaths;
468
+ }
353
469
  export async function execute(plan, opts = {}) {
354
470
  const lock = await acquireRuntimeLock(plan, opts);
355
471
  if (!lock.ok) {
@@ -419,6 +535,8 @@ export async function execute(plan, opts = {}) {
419
535
  }
420
536
  return { ok: true, reused: true, steps: outcomes };
421
537
  }
538
+ // Sync template files to remote hosts before starting, get resolved remote paths
539
+ const remoteTemplatePaths = await syncTemplatesToHosts(plan);
422
540
  for (const step of plan.steps) {
423
541
  if (opts.signal?.aborted) {
424
542
  await teardownPartialStart(plan, outcomes);
@@ -426,6 +544,14 @@ export async function execute(plan, opts = {}) {
426
544
  return { ok: false, reused: false, steps: outcomes, error: 'Execution aborted' };
427
545
  }
428
546
  const host = plan.hosts.find((h) => h.id === step.host_id);
547
+ // Rewrite start_model command to use resolved remote template path
548
+ let activeStep = step;
549
+ if (step.kind === 'start_model' && remoteTemplatePaths.size > 0) {
550
+ const remotePath = remoteTemplatePaths.get(step.host_id);
551
+ if (remotePath) {
552
+ activeStep = { ...step, command: step.command.replace(/--chat-template-file\s+'[^']*'/, `--chat-template-file '${remotePath}'`) };
553
+ }
554
+ }
429
555
  if (!host) {
430
556
  const failed = {
431
557
  step,
@@ -442,7 +568,7 @@ export async function execute(plan, opts = {}) {
442
568
  }
443
569
  opts.onStep?.(step, 'start');
444
570
  const stepStarted = Date.now();
445
- const result = await runStepWithRetry(step, host);
571
+ const result = await runStepWithRetry(activeStep, host);
446
572
  const duration = Date.now() - stepStarted;
447
573
  if (result.exitCode === 0) {
448
574
  outcomes.push({