fix(ai): force recovery summary when final tools fail (Fix 6)
This commit is contained in:
@@ -272,6 +272,26 @@ ${projectsText}
|
|||||||
Today's date: ${new Date().toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" })}.`;
|
Today's date: ${new Date().toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" })}.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lastToolResultsHadFailure(messages: ChatMessage[], lookback = 3) {
|
||||||
|
const toolMsgs = messages.filter((m) => m.role === "tool").slice(-lookback);
|
||||||
|
for (const tm of toolMsgs) {
|
||||||
|
const raw = typeof tm.content === "string" ? tm.content : "";
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
|
if (parsed.ok === false) return true;
|
||||||
|
if (typeof parsed.exitCode === "number" && parsed.exitCode !== 0)
|
||||||
|
return true;
|
||||||
|
if (parsed.healthCheck?.status && parsed.healthCheck.status >= 400)
|
||||||
|
return true;
|
||||||
|
if (typeof parsed.error === "string" && parsed.error.length > 0)
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
// non-JSON result, skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
await ensureChatTables();
|
await ensureChatTables();
|
||||||
|
|
||||||
@@ -752,9 +772,14 @@ export async function POST(request: Request) {
|
|||||||
lastTurnHadTools &&
|
lastTurnHadTools &&
|
||||||
(round >= MAX_TOOL_ROUNDS ||
|
(round >= MAX_TOOL_ROUNDS ||
|
||||||
!!loopBreakReason ||
|
!!loopBreakReason ||
|
||||||
assistantText.trim().length === 0);
|
assistantText.trim().length === 0 ||
|
||||||
|
lastToolResultsHadFailure(messages));
|
||||||
|
|
||||||
if (needsRecovery) {
|
if (needsRecovery) {
|
||||||
|
const failureNote = lastToolResultsHadFailure(messages)
|
||||||
|
? "Your last tool calls returned failures or non-2xx health checks. " +
|
||||||
|
"Do NOT claim those operations succeeded. "
|
||||||
|
: "";
|
||||||
const reason = loopBreakReason
|
const reason = loopBreakReason
|
||||||
? `LOOP DETECTED: ${loopBreakReason}. Stop trying that approach. `
|
? `LOOP DETECTED: ${loopBreakReason}. Stop trying that approach. `
|
||||||
: round >= MAX_TOOL_ROUNDS
|
: round >= MAX_TOOL_ROUNDS
|
||||||
@@ -764,7 +789,7 @@ export async function POST(request: Request) {
|
|||||||
const summary = await callVibnChat({
|
const summary = await callVibnChat({
|
||||||
systemPrompt:
|
systemPrompt:
|
||||||
systemPrompt +
|
systemPrompt +
|
||||||
`\n\n[RECOVERY] ${reason}Send the user 1–3 short sentences right now: (a) what you actually accomplished or learned, (b) the specific blocker (last error message verbatim if there is one), (c) what you'll try next OR a question for the user. Do NOT call any tools.`,
|
`\n\n[RECOVERY] ${reason}${failureNote}Send the user 1–3 short sentences right now: (a) what you actually accomplished or learned, (b) the specific blocker (last error message verbatim if there is one), (c) what you'll try next OR a question for the user. Do NOT call any tools.`,
|
||||||
messages,
|
messages,
|
||||||
tools: [],
|
tools: [],
|
||||||
temperature: 0.3,
|
temperature: 0.3,
|
||||||
|
|||||||
Reference in New Issue
Block a user