Skip to content

Commit b30c17a

Browse files
committed
fix(recovery): more aggressive truncation, remove revert fallback
- Change charsPerToken from 4 to 2 for more aggressive truncation calculation - Remove revert fallback (PHASE 2.5) - Always try Continue after truncation if anything was truncated 🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
1 parent a5983f1 commit b30c17a

File tree

2 files changed

+13
-107
lines changed

2 files changed

+13
-107
lines changed

src/hooks/anthropic-context-window-limit-recovery/executor.ts

Lines changed: 12 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,7 @@ export async function getLastAssistant(
158158
}
159159
}
160160

161-
async function getLastMessageId(
162-
sessionID: string,
163-
client: Client,
164-
directory: string,
165-
): Promise<string | null> {
166-
try {
167-
const resp = await client.session.messages({
168-
path: { id: sessionID },
169-
query: { directory },
170-
});
171161

172-
const data = (resp as { data?: unknown[] }).data;
173-
if (!Array.isArray(data) || data.length === 0) return null;
174-
175-
const lastMsg = data[data.length - 1] as Record<string, unknown>;
176-
const info = lastMsg.info as Record<string, unknown> | undefined;
177-
return (info?.id as string) ?? null;
178-
} catch {
179-
return null;
180-
}
181-
}
182162

183163
function clearSessionState(
184164
autoCompactState: AutoCompactState,
@@ -421,95 +401,21 @@ export async function executeCompact(
421401

422402
log("[auto-compact] aggressive truncation completed", aggressiveResult);
423403

424-
if (aggressiveResult.sufficient) {
425-
clearSessionState(autoCompactState, sessionID);
426-
setTimeout(async () => {
427-
try {
428-
await (client as Client).session.prompt_async({
429-
path: { sessionID },
430-
body: { parts: [{ type: "text", text: "Continue" }] },
431-
query: { directory },
432-
});
433-
} catch {}
434-
}, 500);
435-
return;
436-
}
437-
} else {
438-
log("[auto-compact] no tool outputs found to truncate", { sessionID });
439-
}
440-
441-
// PHASE 2.5: Revert fallback - if still over limit, remove last message
442-
log("[auto-compact] PHASE 2.5: revert fallback - still over limit after truncation", {
443-
sessionID,
444-
currentTokens: errorData.currentTokens,
445-
maxTokens: errorData.maxTokens,
446-
});
447-
448-
const lastMessageId = await getLastMessageId(
449-
sessionID,
450-
client as Client,
451-
directory,
452-
);
453-
454-
if (lastMessageId) {
455-
try {
456-
await (client as Client).session.revert({
457-
path: { id: sessionID },
458-
body: { messageID: lastMessageId },
459-
query: { directory },
460-
});
461-
462-
await (client as Client).tui
463-
.showToast({
464-
body: {
465-
title: "Message Reverted",
466-
message: "Removed last message to reduce context. Retrying...",
467-
variant: "warning",
468-
duration: 3000,
469-
},
470-
})
471-
.catch(() => {});
472-
473-
clearSessionState(autoCompactState, sessionID);
474-
setTimeout(async () => {
475-
try {
476-
await (client as Client).session.prompt_async({
477-
path: { sessionID },
478-
body: { parts: [{ type: "text", text: "Continue" }] },
479-
query: { directory },
480-
});
481-
} catch {}
482-
}, 500);
483-
return;
484-
} catch (revertError) {
485-
log("[auto-compact] revert failed", { error: String(revertError) });
486-
}
404+
clearSessionState(autoCompactState, sessionID);
405+
setTimeout(async () => {
406+
try {
407+
await (client as Client).session.prompt_async({
408+
path: { sessionID },
409+
body: { parts: [{ type: "text", text: "Continue" }] },
410+
query: { directory },
411+
});
412+
} catch {}
413+
}, 500);
414+
return;
487415
}
488416
}
489417

490-
// PHASE 3: Summarize - only when under limit (otherwise it will also fail)
491-
if (isOverLimit) {
492-
log("[auto-compact] skipping summarize - still over token limit", {
493-
sessionID,
494-
currentTokens: errorData?.currentTokens,
495-
maxTokens: errorData?.maxTokens,
496-
});
497-
498-
clearSessionState(autoCompactState, sessionID);
499-
500-
await (client as Client).tui
501-
.showToast({
502-
body: {
503-
title: "Recovery Failed",
504-
message: `Still over token limit (${errorData?.currentTokens}/${errorData?.maxTokens}). Please start a new session or manually compact.`,
505-
variant: "error",
506-
duration: 10000,
507-
},
508-
})
509-
.catch(() => {});
510-
return;
511-
}
512-
418+
// PHASE 3: Summarize - fallback when no tool outputs to truncate
513419
const retryState = getOrCreateRetryState(autoCompactState, sessionID);
514420

515421
if (errorData?.errorType?.includes("non-empty content")) {

src/hooks/anthropic-context-window-limit-recovery/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ export const TRUNCATE_CONFIG = {
4444
maxTruncateAttempts: 20,
4545
minOutputSizeToTruncate: 500,
4646
targetTokenRatio: 0.5,
47-
charsPerToken: 4,
47+
charsPerToken: 2,
4848
} as const

0 commit comments

Comments
 (0)