Skip to content

Bug: context-engine auto-compaction does not persist session compactionCount #42628

@uf-hy

Description

@uf-hy

Summary

When auto-compaction happens through a custom context engine (for example lossless-claw / LCM with ownsCompaction: true), the session-level compactionCount in sessions.json does not get incremented.

Repro

  1. Enable a context engine plugin that owns compaction (contextEngineInfo.ownsCompaction === true).
  2. Trigger overflow recovery so runEmbeddedPiAgent() calls contextEngine.compact(...).
  3. Let the compaction succeed and observe that the next request retries successfully.
  4. Inspect the session entry / status output.

Actual

  • The compaction succeeds.
  • runEmbeddedPiAgent() reports meta.agentMeta.compactionCount.
  • But persisted sessionEntry.compactionCount stays unchanged, so status/UI still shows 0.

Expected

A successful auto-compaction should increment the persisted session compactionCount, regardless of whether the compaction came from the legacy embedded Pi path or from a context engine plugin.

Root cause

The current session accounting path in:

  • src/auto-reply/reply/agent-runner-execution.ts
  • src/auto-reply/reply/followup-runner.ts

marks autoCompactionCompleted = true only when a streamed compaction event is observed.

That works for the legacy embedded compaction flow, because pi-embedded-subscribe.handlers.compaction.ts emits those events.

However, the explicit overflow path in src/agents/pi-embedded-runner/run.ts can increment agentMeta.compactionCount without necessarily producing that same event path when a context engine owns compaction.

So downstream accounting never calls incrementRunCompactionCount(...), even though the result metadata already says compaction happened.

Suggested fix

In the callers that already receive the final embedded result, treat result.meta?.agentMeta?.compactionCount > 0 as a fallback signal that auto-compaction completed.

That fixes both:

  • the main reply path (agent-runner-execution.ts / agent-runner.ts)
  • the followup path (followup-runner.ts)

and avoids depending entirely on a streamed event that some context-engine-owned compaction paths can bypass.

Notes

I have a local patch + tests for this approach if you'd like it as a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions