MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / executeToolCall

Method executeToolCall

src/agent/loop.ts:2205–2470  ·  view source on GitHub ↗
(
    tc: ToolCall,
    transaction: Transaction,
    sessionId: string,
    options: AgentOptions,
  )

Source from the content-addressed store, hash-verified

2203 for (const sm of skipped) newMessages.push(sm);
2204 sessionStore.recordTurn(sessionId, skipped, { input: 0, output: 0, costUsd: 0 });
2205 }
2206 newMessages.push(stuckMsg);
2207 sessionStore.recordTurn(sessionId, [stuckMsg], { input: 0, output: 0, costUsd: 0 });
2208 // CRITICAL: also clear recentCalls so the model gets one clean shot after the advice
2209 recentCalls.length = 0;
2210 continue;
2211 }
2212
2213 // Error-guessing loop: same tool, same error kind, different args each time (e.g. reading
2214 // Header.tsx / App.tsx / Navbar.jsx — all FILE_NOT_FOUND — on a .jsx project). detectStuckLoop
2215 // misses this because the args differ. Nudge the model to STOP guessing and learn the real paths.
2216 // Scope guard: if the user never asked to run/install/test and the model is now starting a
2217 // dev server or installing packages on its own, nudge it once to finish the edits and ask
2218 // first. Advisory only (doesn't skip execution); the soft-failure loop detector is the real
2219 // circuit-breaker if the model ignores this and starts thrashing.
2220 if (!userAskedExecution && !scopeNudged) {
2221 const wandering = toolCalls.find(tc =>
2222 isExecutionAction(tc.function.name, tc.function.arguments ?? ''),
2223 );
2224 if (wandering) {
2225 scopeNudged = true;
2226 const smsg: Message = {
2227 role: 'user',
2228 content:
2229 '[SYSTEM] The user asked you to write/redesign code, not to run a dev server or install ' +
2230 'packages. Finish and save the file changes, then report what you changed in a short ' +
2231 'summary. Do NOT start dev servers, install dependencies, or debug the environment unless ' +
2232 'the user explicitly asks — those steps are out of scope and waste time.',
2233 };
2234 newMessages.push(smsg);
2235 sessionStore.recordTurn(sessionId, [smsg], { input: 0, output: 0, costUsd: 0 });
2236 }
2237 }
2238
2239 const errLoop = detectErrorLoop(recentErrors);
2240 if (errLoop) {
2241 let advice = ' Change approach instead of repeating the same kind of call.';
2242 if (errLoop.code === 'FILE_NOT_FOUND') {
2243 advice =
2244 ' STOP guessing file paths. The "did you mean …" suggestions in the errors show the REAL ' +
2245 'names — this project likely uses different extensions than you assume (e.g. .jsx, not .tsx). ' +
2246 'Run `glob` or `ls` to get exact paths, then read those. Do not keep trying filename variations.';
2247 }
2248 const msg: Message = {
2249 role: 'user',
2250 content:
2251 `[SYSTEM] \`${errLoop.name}\` has returned ${errLoop.code} ${errLoop.count} times with different ` +
2252 `arguments.${advice} If you genuinely can't proceed, say so in ONE sentence and stop. Do not loop.`,
2253 };
2254 // Answer the just-emitted tool_calls before skipping execution, or the assistant's
2255 // tool_calls are orphaned and OpenAI-format providers 400 on the next request.
2256 if (toolCalls.length > 0) {
2257 const skipped = skippedToolResults(toolCalls, 'loop guard: same error kind repeated');
2258 for (const sm of skipped) newMessages.push(sm);
2259 sessionStore.recordTurn(sessionId, skipped, { input: 0, output: 0, costUsd: 0 });
2260 }
2261 newMessages.push(msg);
2262 sessionStore.recordTurn(sessionId, [msg], { input: 0, output: 0, costUsd: 0 });

Callers 1

runMethod · 0.95

Calls 15

transformErrorFunction · 0.85
getHooksManagerFunction · 0.85
extractFilePathsFromArgsFunction · 0.85
isPlanningToolCallFunction · 0.85
isGatedMutationToolFunction · 0.85
extractMutationPathsFunction · 0.85
buildGateMessageFunction · 0.85
extractReadPathFunction · 0.85
abortMethod · 0.80
isActiveMethod · 0.80
resolveMethod · 0.80
backtrackMethod · 0.80

Tested by

no test coverage detected