* Run a single prompt through the agent loop. * Returns structured results with response, tool calls, and file changes.
(prompt)
| 47 | * Returns structured results with response, tool calls, and file changes. |
| 48 | */ |
| 49 | async run(prompt) { |
| 50 | const startTime = Date.now(); |
| 51 | this.earlyStop.newTurn(); |
| 52 | this._history = []; |
| 53 | |
| 54 | const result = { |
| 55 | response: '', |
| 56 | toolCalls: [], |
| 57 | filesCreated: [], |
| 58 | filesEdited: [], |
| 59 | tokensUsed: { input: 0, output: 0, total: 0 }, |
| 60 | duration: 0, |
| 61 | success: false, |
| 62 | error: null, |
| 63 | }; |
| 64 | |
| 65 | try { |
| 66 | const messages = [ |
| 67 | { role: 'system', content: this._buildSystemPrompt() }, |
| 68 | { role: 'user', content: prompt }, |
| 69 | ]; |
| 70 | |
| 71 | let toolCallCount = 0; |
| 72 | |
| 73 | while (toolCallCount < this.config.maxToolCalls) { |
| 74 | const response = await this._chatCompletion(messages); |
| 75 | if (!response) { |
| 76 | result.error = 'No response from model'; |
| 77 | break; |
| 78 | } |
| 79 | |
| 80 | const message = response.choices?.[0]?.message; |
| 81 | if (!message) break; |
| 82 | |
| 83 | // Recover tool calls embedded in text content (qwen2.5-coder etc.) |
| 84 | // See src/tools/tool_call_extractor.js + issue #36. |
| 85 | try { |
| 86 | const { extractFromMessage } = require('../tools/tool_call_extractor'); |
| 87 | extractFromMessage(message, this._getTools()); |
| 88 | } catch {} |
| 89 | |
| 90 | // Track token usage |
| 91 | if (response.usage) { |
| 92 | result.tokensUsed.input += response.usage.prompt_tokens || 0; |
| 93 | result.tokensUsed.output += response.usage.completion_tokens || 0; |
| 94 | result.tokensUsed.total = result.tokensUsed.input + result.tokensUsed.output; |
| 95 | } |
| 96 | |
| 97 | // Tool calls |
| 98 | if (message.tool_calls && message.tool_calls.length > 0) { |
| 99 | messages.push(message); |
| 100 | |
| 101 | for (const tc of message.tool_calls) { |
| 102 | toolCallCount++; |
| 103 | const toolName = tc.function.name; |
| 104 | let toolArgs; |
| 105 | try { toolArgs = JSON.parse(tc.function.arguments); } catch { toolArgs = {}; } |
| 106 |
no test coverage detected