mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 02:38:26 +00:00
fix(agents): increment compaction counter on overflow-triggered compaction (#39123)
Co-authored-by: MumuTW <clothl47364@gmail.com>
This commit is contained in:
@@ -40,11 +40,17 @@ export function handleAutoCompactionStart(ctx: EmbeddedPiSubscribeContext) {
|
||||
|
||||
export function handleAutoCompactionEnd(
|
||||
ctx: EmbeddedPiSubscribeContext,
|
||||
evt: AgentEvent & { willRetry?: unknown },
|
||||
evt: AgentEvent & { willRetry?: unknown; result?: unknown; aborted?: unknown },
|
||||
) {
|
||||
ctx.state.compactionInFlight = false;
|
||||
const willRetry = Boolean(evt.willRetry);
|
||||
if (!willRetry) {
|
||||
// Increment counter whenever compaction actually produced a result,
|
||||
// regardless of willRetry. Overflow-triggered compaction sets willRetry=true
|
||||
// (the framework retries the LLM request), but the compaction itself succeeded
|
||||
// and context was trimmed — the counter must reflect that. (#38905)
|
||||
const hasResult = evt.result != null;
|
||||
const wasAborted = Boolean(evt.aborted);
|
||||
if (hasResult && !wasAborted) {
|
||||
ctx.incrementCompactionCount?.();
|
||||
}
|
||||
if (willRetry) {
|
||||
|
||||
@@ -38,11 +38,26 @@ describe("subscribeEmbeddedPiSession", () => {
|
||||
emit({ type: "auto_compaction_start" });
|
||||
expect(subscription.getCompactionCount()).toBe(0);
|
||||
|
||||
emit({ type: "auto_compaction_end", willRetry: true });
|
||||
// willRetry with result — counter IS incremented (overflow compaction succeeded)
|
||||
emit({ type: "auto_compaction_end", willRetry: true, result: { summary: "s" } });
|
||||
expect(subscription.getCompactionCount()).toBe(1);
|
||||
|
||||
// willRetry=false with result — counter incremented again
|
||||
emit({ type: "auto_compaction_end", willRetry: false, result: { summary: "s2" } });
|
||||
expect(subscription.getCompactionCount()).toBe(2);
|
||||
});
|
||||
|
||||
it("does not count compaction when result is absent", async () => {
|
||||
const { emit, subscription } = createSubscribedSessionHarness({
|
||||
runId: "run-compaction-no-result",
|
||||
});
|
||||
|
||||
// No result (e.g. aborted or cancelled) — counter stays at 0
|
||||
emit({ type: "auto_compaction_end", willRetry: false, result: undefined });
|
||||
expect(subscription.getCompactionCount()).toBe(0);
|
||||
|
||||
emit({ type: "auto_compaction_end", willRetry: false });
|
||||
expect(subscription.getCompactionCount()).toBe(1);
|
||||
emit({ type: "auto_compaction_end", willRetry: false, aborted: true });
|
||||
expect(subscription.getCompactionCount()).toBe(0);
|
||||
});
|
||||
|
||||
it("emits compaction events on the agent event bus", async () => {
|
||||
|
||||
@@ -100,6 +100,7 @@ describe("compaction hook wiring", () => {
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: false,
|
||||
result: { summary: "compacted" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
@@ -122,7 +123,7 @@ describe("compaction hook wiring", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does not call runAfterCompaction when willRetry is true", () => {
|
||||
it("does not call runAfterCompaction when willRetry is true but still increments counter", () => {
|
||||
hookMocks.runner.hasHooks.mockReturnValue(true);
|
||||
|
||||
const ctx = {
|
||||
@@ -132,7 +133,8 @@ describe("compaction hook wiring", () => {
|
||||
noteCompactionRetry: vi.fn(),
|
||||
resetForCompactionRetry: vi.fn(),
|
||||
maybeResolveCompactionWait: vi.fn(),
|
||||
getCompactionCount: () => 0,
|
||||
incrementCompactionCount: vi.fn(),
|
||||
getCompactionCount: () => 1,
|
||||
};
|
||||
|
||||
handleAutoCompactionEnd(
|
||||
@@ -140,10 +142,13 @@ describe("compaction hook wiring", () => {
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: true,
|
||||
result: { summary: "compacted" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(hookMocks.runner.runAfterCompaction).not.toHaveBeenCalled();
|
||||
// Counter is incremented even with willRetry — compaction succeeded (#38905)
|
||||
expect(ctx.incrementCompactionCount).toHaveBeenCalledTimes(1);
|
||||
expect(ctx.noteCompactionRetry).toHaveBeenCalledTimes(1);
|
||||
expect(ctx.resetForCompactionRetry).toHaveBeenCalledTimes(1);
|
||||
expect(ctx.maybeResolveCompactionWait).not.toHaveBeenCalled();
|
||||
@@ -154,6 +159,75 @@ describe("compaction hook wiring", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does not increment counter when compaction was aborted", () => {
|
||||
const ctx = {
|
||||
params: { runId: "r3b", session: { messages: [] } },
|
||||
state: { compactionInFlight: true },
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
maybeResolveCompactionWait: vi.fn(),
|
||||
incrementCompactionCount: vi.fn(),
|
||||
getCompactionCount: () => 0,
|
||||
};
|
||||
|
||||
handleAutoCompactionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: false,
|
||||
result: undefined,
|
||||
aborted: true,
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(ctx.incrementCompactionCount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not increment counter when compaction has result but was aborted", () => {
|
||||
const ctx = {
|
||||
params: { runId: "r3b2", session: { messages: [] } },
|
||||
state: { compactionInFlight: true },
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
maybeResolveCompactionWait: vi.fn(),
|
||||
incrementCompactionCount: vi.fn(),
|
||||
getCompactionCount: () => 0,
|
||||
};
|
||||
|
||||
handleAutoCompactionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: false,
|
||||
result: { summary: "compacted" },
|
||||
aborted: true,
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(ctx.incrementCompactionCount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not increment counter when result is undefined", () => {
|
||||
const ctx = {
|
||||
params: { runId: "r3c", session: { messages: [] } },
|
||||
state: { compactionInFlight: true },
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
maybeResolveCompactionWait: vi.fn(),
|
||||
incrementCompactionCount: vi.fn(),
|
||||
getCompactionCount: () => 0,
|
||||
};
|
||||
|
||||
handleAutoCompactionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: false,
|
||||
result: undefined,
|
||||
aborted: false,
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(ctx.incrementCompactionCount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("resets stale assistant usage after final compaction", () => {
|
||||
const messages = [
|
||||
{ role: "user", content: "hello" },
|
||||
@@ -183,6 +257,7 @@ describe("compaction hook wiring", () => {
|
||||
{
|
||||
type: "auto_compaction_end",
|
||||
willRetry: false,
|
||||
result: { summary: "compacted" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user