fix: compaction safeguard extension not loading in production builds#22349
Merged
Takhoffman merged 3 commits intoopenclaw:mainfrom Feb 21, 2026
Merged
fix: compaction safeguard extension not loading in production builds#22349Takhoffman merged 3 commits intoopenclaw:mainfrom
Takhoffman merged 3 commits intoopenclaw:mainfrom
Conversation
Contributor
Author
Contributor
|
I was curious when this might have broken so I ask codex to do an analysis and git blame and let's just say I'm gonna leave it at that. |
buildEmbeddedExtensionPaths() computed extension paths (including compaction-safeguard) but the return value was silently discarded in both compact.ts and run/attempt.ts. Only runtime state side effects were used. This meant the session_before_compact event handler was never registered, so pi-coding-agent fell back to its own compact() which sends all messages to generateSummary() without chunking — causing "prompt is too long" errors on sessions with large contexts (e.g. 248k > 200k limit). Now the returned paths are passed to a DefaultResourceLoader which is provided to createAgentSession(), activating the safeguard's chunking, stripToolResultDetails, and progressive fallback logic. When no extension paths are returned (safeguard not configured), the SDK's built-in default resource loader is used unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous fix (83eb996) wired extension paths to DefaultResourceLoader, but those paths resolve to non-existent files in tsdown production bundles. Switch to extensionFactories which passes the extension functions directly as imports, bundled inline at build time. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6a18649 to
525a5fa
Compare
Contributor
|
PR #22349 - fix: compaction safeguard extension not loading in production builds (#22349) Merged via squash.
Thanks @Glucksberg! |
ly85206559
pushed a commit
to ly85206559/openclaw
that referenced
this pull request
Feb 21, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Hansen1018
pushed a commit
to Hansen1018/openclaw
that referenced
this pull request
Feb 21, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
mmyyfirstb
pushed a commit
to mmyyfirstb/openclaw
that referenced
this pull request
Feb 21, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This was referenced Feb 21, 2026
Closed
clickmediapropy
pushed a commit
to clickmediapropy/openclaw
that referenced
this pull request
Feb 22, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
obviyus
pushed a commit
to guirguispierre/openclaw
that referenced
this pull request
Feb 22, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
18 tasks
mreedr
pushed a commit
to mreedr/openclaw-custom
that referenced
this pull request
Feb 24, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2 tasks
6 tasks
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 1, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> (cherry picked from commit 1410d15) # Conflicts: # CHANGELOG.md # src/agents/pi-embedded-runner/compact.ts # src/agents/pi-embedded-runner/extensions.ts
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 3, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> (cherry picked from commit 1410d15) # Conflicts: # CHANGELOG.md # src/agents/pi-embedded-runner/compact.ts # src/agents/pi-embedded-runner/extensions.ts # src/agents/pi-embedded-runner/run/attempt.ts
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…penclaw#22349) thanks @Glucksberg Verified: - pnpm build - pnpm check - pnpm test:macmini (local run had unrelated baseline failures; Tak approved proceed) Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

The bug
When compaction runs, it sends the conversation history to an LLM asking it to generate a summary. For small/medium sessions this works fine — the history fits within the model's context window. But for long-running sessions where the history has grown past the model's 200k token limit, the summarization call itself gets rejected:
448694 prompt tokens > 200000 maximum.That's exactly what the
compaction.mode: "safeguard"extension is supposed to prevent — it hooks intosession_before_compactto truncate the history before the summarization LLM call. The config was set, the extension code existed, but it wasn't doing anything. Compaction on large sessions was guaranteed to fail.Impact
Roughly ~1,000 lines of extension code were sitting idle in production — compaction safeguard (435 lines), context pruning (572 lines), and the path resolution glue (~100 lines). The runtime state was being set correctly, but the extensions that read that state were never loaded. All of it passed tests, shipped, and did nothing.
First fix attempt (83eb996)
Digging into the code, the issue seemed straightforward:
buildEmbeddedExtensionPaths()was being called for its side effects (setting runtime state), but its return value — the actual extension file paths — was being discarded. Neithercompact.tsnorrun/attempt.tswere passing the paths toDefaultResourceLoader, so thesession_before_compacthook never got registered.The fix wired the return value into a
DefaultResourceLoaderwithadditionalExtensionPaths, passed it tocreateAgentSession, and all tests passed. Deployed, tested/compactagain — same error. 248k tokens, rejected.Root cause
resolvePiExtensionPath()computes extension file paths relative toimport.meta.url:In dev (
tsx),import.meta.urlpoints to the actual.tssource file, so the relative path lands onsrc/agents/pi-extensions/compaction-safeguard.ts— which exists. In production,tsdownbundles everything into hashed chunks likedist/pi-embedded-Df4JcLlD.js. The path resolves todist/pi-extensions/compaction-safeguard.js— a file that doesn't exist, because the extension code is already inlined in the bundle. The extension silently fails to load, the safeguard never fires, compaction sends the full history unguarded.Actual fix
DefaultResourceLoadersupports anextensionFactoriesoption that acceptsExtensionFactory[]— functions, not file paths. Instead of resolving paths at runtime for dynamic import, we import the extension functions directly at build time:These get bundled inline by tsdown. No file resolution, no dynamic imports, no runtime path that can break.
buildEmbeddedExtensionPaths→buildEmbeddedExtensionFactories, returnsExtensionFactory[]instead ofstring[]. Both callers (compact.ts,run/attempt.ts) passextensionFactoriestoDefaultResourceLoader. The deadresolvePiExtensionPath()helper and itspath/fileURLToPathimports are removed.After deploying this fix,
/compactworks — compaction completes and the token count drops as expected.Files changed
src/agents/pi-embedded-runner/extensions.ts— core change: imports → factoriessrc/agents/pi-embedded-runner/compact.ts— wireextensionFactoriesto resource loadersrc/agents/pi-embedded-runner/run/attempt.ts— same wiring for the run path🤖 Generated with Claude Code