fix: reset session after compaction overflow

This commit is contained in:
Peter Steinberger
2026-01-12 00:28:02 +00:00
parent 32df2ef7bd
commit 67743325ee
6 changed files with 485 additions and 320 deletions

View File

@@ -7,6 +7,7 @@ import {
formatAssistantErrorText,
isBillingErrorMessage,
isCloudCodeAssistFormatError,
isCompactionFailureError,
isContextOverflowError,
isFailoverErrorMessage,
isMessagingToolDuplicate,
@@ -208,6 +209,8 @@ describe("isContextOverflowError", () => {
"Request exceeds the maximum size",
"context length exceeded",
"Maximum context length",
"prompt is too long: 208423 tokens > 200000 maximum",
"Context overflow: Summarization failed",
"413 Request Entity Too Large",
];
for (const sample of samples) {
@@ -220,6 +223,26 @@ describe("isContextOverflowError", () => {
});
});
describe("isCompactionFailureError", () => {
it("matches compaction overflow failures", () => {
const samples = [
"Context overflow: Summarization failed: 400 {\"message\":\"prompt is too long\"}",
"auto-compaction failed due to context overflow",
"Compaction failed: prompt is too long",
];
for (const sample of samples) {
expect(isCompactionFailureError(sample)).toBe(true);
}
});
it("ignores non-compaction overflow errors", () => {
expect(
isCompactionFailureError("Context overflow: prompt too large"),
).toBe(false);
expect(isCompactionFailureError("rate limit exceeded")).toBe(false);
});
});
describe("isBillingErrorMessage", () => {
it("matches credit / payment failures", () => {
const samples = [

View File

@@ -244,10 +244,24 @@ export function isContextOverflowError(errorMessage?: string): boolean {
lower.includes("request exceeds the maximum size") ||
lower.includes("context length exceeded") ||
lower.includes("maximum context length") ||
lower.includes("prompt is too long") ||
lower.includes("context overflow") ||
(lower.includes("413") && lower.includes("too large"))
);
}
export function isCompactionFailureError(errorMessage?: string): boolean {
if (!errorMessage) return false;
if (!isContextOverflowError(errorMessage)) return false;
const lower = errorMessage.toLowerCase();
return (
lower.includes("summarization failed") ||
lower.includes("auto-compaction") ||
lower.includes("compaction failed") ||
lower.includes("compaction")
);
}
export function formatAssistantErrorText(
msg: AssistantMessage,
opts?: { cfg?: ClawdbotConfig; sessionKey?: string },

View File

@@ -36,6 +36,7 @@ import { isCacheEnabled, resolveCacheTtlMs } from "../config/cache-utils.js";
import type { ClawdbotConfig } from "../config/config.js";
import { resolveProviderCapabilities } from "../config/provider-capabilities.js";
import { getMachineDisplayName } from "../infra/machine-name.js";
import { registerUnhandledRejectionHandler } from "../infra/unhandled-rejections.js";
import { createSubsystemLogger } from "../logging.js";
import {
type enqueueCommand,
@@ -85,6 +86,7 @@ import {
formatAssistantErrorText,
isAuthAssistantError,
isCloudCodeAssistFormatError,
isCompactionFailureError,
isContextOverflowError,
isFailoverAssistantError,
isFailoverErrorMessage,
@@ -408,6 +410,13 @@ type EmbeddedPiQueueHandle = {
const log = createSubsystemLogger("agent/embedded");
const GOOGLE_TURN_ORDERING_CUSTOM_TYPE = "google-turn-ordering-bootstrap";
registerUnhandledRejectionHandler((reason) => {
const message = describeUnknownError(reason);
if (!isCompactionFailureError(message)) return false;
log.error(`Auto-compaction failed (unhandled): ${message}`);
return true;
});
type CustomEntryLike = { type?: unknown; customType?: unknown };
function hasGoogleTurnOrderingMarker(sessionManager: SessionManager): boolean {