Skip to content

Commit 1960e2e

Browse files
author
Brendan Gray
committed
fix: stuck greeting ROLLBACK for tiny models overwhelmed by tool injection context
1 parent 7355d29 commit 1960e2e

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

main/agenticChat.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,7 @@ function register(ctx) {
10901090
let sessionJustRotated = false; // Flag to rebuild prompt after rotation
10911091
let overflowResponseBudgetReduced = false; // Flag: already tried reducing response budget on first-turn overflow
10921092
let forcedToolFunctions = null; // Set by PILLAR 3 refusal recovery to force grammar on next iteration
1093+
let forceChatModeForRetry = false; // Set on stuck_greeting ROLLBACK — strips tools and uses chat preamble for retry
10931094
let consecutiveEmptyGrammarRetries = 0; // Track grammar failures for text-mode fallback
10941095

10951096
// ── Execution State Tracking (ported from Pocket Guide) ──
@@ -1384,7 +1385,12 @@ function register(ctx) {
13841385
: modelTier.tier === 'large' ? 5 : 2;
13851386
const useNativeFunctions = (taskType !== 'chat') && iteration <= grammarIterLimit;
13861387
let nativeFunctions = null;
1387-
if (consecutiveEmptyGrammarRetries >= 1) {
1388+
if (forceChatModeForRetry) {
1389+
// stuck_greeting recovery: strip all tools, use plain text with chat preamble
1390+
nativeFunctions = null;
1391+
forcedToolFunctions = null;
1392+
forceChatModeForRetry = false; // One-shot
1393+
} else if (consecutiveEmptyGrammarRetries >= 1) {
13881394
// Grammar-to-text fallback: model can't produce grammar output, degrade gracefully.
13891395
// Threshold lowered to 1 — the second native function call attempt can hang at the
13901396
// C++ level and never return. One failure is enough to switch to text mode safely.
@@ -1703,7 +1709,16 @@ function register(ctx) {
17031709
}
17041710

17051711
// Escalating retry strategy
1706-
if (rollbackRetries === 1) {
1712+
if (responseVerdict.reason === 'stuck_greeting') {
1713+
// Model outputted its trained greeting despite an agentic task.
1714+
// Retry with the simple chat preamble and NO tools — removes all tool pressure.
1715+
currentPrompt = {
1716+
systemContext: buildStaticPrompt('chat'),
1717+
userMessage: message.substring(0, 500),
1718+
};
1719+
forceChatModeForRetry = true;
1720+
console.log('[AI Chat] Stuck greeting detected — retrying in chat mode (tool-free)');
1721+
} else if (rollbackRetries === 1) {
17071722
// First retry: same prompt, slightly lower temperature for focus
17081723
if (context?.params) context.params.temperature = Math.max((context.params.temperature || 0.7) - 0.2, 0.1);
17091724
} else if (rollbackRetries === 2) {

main/agenticChatHelpers.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,14 @@ function evaluateResponse(responseText, functionCalls, taskType, iteration, hasR
563563
return { verdict: 'ROLLBACK', reason: 'described_not_executed' };
564564
}
565565

566+
// ── STUCK GREETING: generic greeting response on an agentic (non-chat) task ──
567+
// Tiny models overwhelmed by tool injection context fall back to their trained greeting.
568+
// Detect the exact pattern and ROLLBACK so the retry can strip tool pressure.
569+
const STUCK_GREETING_RX = /^(Hello!?\s+How\s+can\s+I\s+(assist|help)\s+(you\s+)?(today)?[!?.]*\s*|Hi!?\s+How\s+can\s+I\s+(assist|help)[!?.]*\s*)$/i;
570+
if (taskType !== 'chat' && iteration === 1 && STUCK_GREETING_RX.test(text)) {
571+
return { verdict: 'ROLLBACK', reason: 'stuck_greeting' };
572+
}
573+
566574
// ── DEFAULT: Accept ──
567575
return { verdict: 'COMMIT', reason: 'default' };
568576
}

0 commit comments

Comments
 (0)