File size: 2,065 Bytes
4381a41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
const inferenceClient = require('./inferenceClient');
const toolManager = require('./toolManager');

function stripCodeFences(text) {
  return text
    .trim()
    .replace(/^```[a-zA-Z]*\n?/, '')
    .replace(/```$/, '')
    .trim();
}

// Given a broken tool and the error it threw, ask the model for a corrected
// version and file it as a pending fix. Returns the new pending entry, or
// null if the model failed to produce a usable patch.
async function attemptFix(tool, error) {
  const prompt = [
    `The tool "${tool.name}" threw an error when it ran.`,
    '',
    `Description: ${tool.description}`,
    '',
    'Current code:',
    '---',
    tool.code,
    '---',
    '',
    `Error message: ${error.message}`,
    error.stack ? `Stack: ${error.stack}` : '',
    error.logs && error.logs.length ? `Console output before the error: ${error.logs.join(' | ')}` : '',
    '',
    'Write a corrected full replacement for the tool code, using the exact same convention:',
    'an async function named run(args) that returns a JSON-serializable result.',
    'Reply with ONLY the corrected JavaScript code. No explanation, no markdown fences.',
  ]
    .filter(Boolean)
    .join('\n');

  let message;
  try {
    message = await inferenceClient.chat([
      {
        role: 'system',
        content:
          'You are a careful senior JavaScript engineer patching a broken tool for a self-improving assistant. ' +
          'You fix root causes, keep the same run(args) function signature, and never add explanations outside the code.',
      },
      { role: 'user', content: prompt },
    ]);
  } catch (e) {
    console.error('[errorHealer] fix request failed:', e.message);
    return null;
  }

  const code = stripCodeFences(message.content || '');
  if (!code || !/async\s+function\s+run\s*\(/.test(code)) {
    console.error('[errorHealer] model did not return a usable run(args) function');
    return null;
  }

  return toolManager.proposeFix(tool.id, code, `Auto-fix attempt for error: ${error.message}`);
}

module.exports = { attemptFix };