fix(agent): recover when action intent has no tool call

This commit is contained in:
William Valentin
2026-02-22 23:01:52 -08:00
parent 50c4f3de57
commit 7e7685a194
3 changed files with 123 additions and 1 deletions
+26
View File
@@ -259,6 +259,7 @@ export class NativeAgent {
let sameToolStreak = 0;
const maxSameToolStreak = 4; // nudge after 4 calls to the same tool
let nudged = false;
let actionIntentNudged = false;
for (let iteration = 0; iteration < this.maxIterations; iteration++) {
try {
@@ -305,6 +306,16 @@ export class NativeAgent {
const wantsToolUse = toolCalls.length > 0;
if (!wantsToolUse) {
const pseudoToolUse = this.extractPseudoToolUse(response.content);
if (this.shouldNudgeForMissingToolCall(response.content, pseudoToolUse) && !actionIntentNudged) {
actionIntentNudged = true;
const normalized = this.normalizeAssistantContent(response.content);
loopMessages.push({ role: 'assistant', content: normalized });
loopMessages.push({
role: 'user',
content: 'You said you would perform an action now, but no tool call was emitted. If a tool is needed, call it now. If blocked, explain the exact blocker.',
});
continue;
}
const baseContent = pseudoToolUse
? this.buildPseudoToolUseWarning(response.content, pseudoToolUse)
: this.normalizeAssistantContent(response.content);
@@ -472,6 +483,21 @@ export class NativeAgent {
return warningMsg;
}
private shouldNudgeForMissingToolCall(content: string, pseudoToolUse: PseudoToolUse | null): boolean {
if (!content || pseudoToolUse) {
return false;
}
const normalized = content.toLowerCase();
const intentRegex = /\b(i(?:'m| am)? going to|i(?:'ll| will)|let me|proceeding(?: now)?|i can(?: now)?)\b/;
if (!intentRegex.test(normalized)) {
return false;
}
const actionRegex = /\b(create|run|execute|call|use|check|fetch|search|read|write|send|retry|proceed|attempt|apply|delete|update|list)\b/;
return actionRegex.test(normalized);
}
private async chatWithRouter(request: ChatRequest): Promise<ChatResponse> {
const runSignal = this._runAbortController?.signal;
const requestSignal = request.signal;