Please give us a hook for custom compaction
Open 💬 9 comments Opened Feb 16, 2026 by thom-heinrich
What variant of Codex are you using?
CLI
What feature would you like to see?
Please give us a hook to add custom compaction solutions to codex.. like:
Token amount xxx is reached —> fires —> my custom compaction does its job —> injects and uses as context for continuation..
This is already possible if you build custom interfaces, but it would be a huge QoL for the vanilla CLI…
Additional information
_No response_
9 Comments
<img width="895" height="323" alt="Image" src="https://github.com/user-attachments/assets/c8ef47f0-e342-47a3-a3f6-ed2f7e1f99a2" />
https://developers.openai.com/codex/config-reference/
Maybe some of this will help you. Perhaps by instructions?
I have the same need, and the concrete blocker is a structured
persistworkflow.My setup:
.agent-doc/SessionStartandStoppersistskill that writes findings, next actions, decisions, and state snapshots to diskWhat is still missing is a deterministic hook immediately before compaction.
Why
Stopis not enough:Stoponly runs on clean session endThe exact feature that would solve this for me is something like a
PreCompacthook with payload fields such as:cwdsession_idthread_idreason(autovsmanual)Then I could run something like:
or a more general
persistcommand that checkpoints.agent-doc/before Codex summarizes the context.This would make a big difference for:
So +1 from a real workflow perspective: this is not just "more hooks would be nice", it is the missing piece that makes durable custom memory and structured persistence reliable in Codex.
+1 PLEASE give us better compaction options
I routinely run into compaction error loops where I have to discard my whole thread.
Follow-up after tightening the fork patch:
hookSpecificOutput.hookEventName = "Stop"together withaction = "compact".CodexErr::Interruptedis treated as a real turn abort; interrupted compaction no longer falls through into continuation scheduling.block + compactStop-hook continuations in the same turn are now guarded by a turn-scoped latch, so compaction still runs at most once per turn.So the current contract is:
block + compactcontinuation preserves the normal mid-turn context baselineAdding an implementation-oriented field report from Codex CLI 0.124.0 and the current
mainbranch source.Codex already has a solid hook runtime shape for this feature. The current hook engine discovers handlers from
hooks.jsonand[hooks]inconfig.toml, supports command handlers, matcher groups, timeouts, hook start/completion events, and event-specific parsers for:SessionStartUserPromptSubmitPreToolUsePermissionRequestPostToolUseStopThe gap is that none of those events is tied directly to the compaction lifecycle.
SessionStartandUserPromptSubmitcan inject context, andStopcan ask Codex to continue, but there is no stable event that says either:Without that lifecycle event, external memory systems have to infer compaction by watching rollout logs, token usage, or other internal artifacts. That is workable for experiments but brittle as a plugin or long-running workflow contract.
A minimal design that seems to fit the existing hook architecture:
PreCompactRun before compaction starts. The input could mirror the common hook fields already used elsewhere:
session_idturn_idcwdtranscript_pathmodelpermission_modetrigger:manualorautoUseful output semantics:
hookSpecificOutput.additionalContextcan be included in the compaction input.PostCompactorContextCompactedRun after compaction succeeds. The input could include:
triggercompact_summaryor a stable summary referenceUseful output semantics:
additionalContextshould be recorded as model context for the next turn exactly once, similar to the existingSessionStart/UserPromptSubmitcontext injection path.Implementation-wise, this looks like an incremental extension rather than a new subsystem:
HookEventsTomlincodex-rs/config/src/hook_config.rs.codex-rs/hooks/schema/generated.session_start.rs,user_prompt_submit.rs, andstop.rs.codex-rs/core/src/hook_runtime.rsaround the existing compaction flow.codex-rs/core/tests/suite/hooks.rsthat verify no-hook behavior is unchanged, configured hooks receive stable stdin JSON, and additional context reaches the next model request once.The main product value is not only custom summaries. It gives users a supported persistence boundary for long-running threads: save important state before compaction, observe the compacted state after compaction, and reinject durable context without relying on internal log formats.
Happy to help refine the contract or test cases if maintainers think this direction matches the intended hook model.
+1 for explicit
PreCompact/PostCompactlifecycle hooks. My main use case is deterministic project-state persistence before Codex rewrites context: save decisions, current plan, changed files, and next steps to a project memory/doc, then optionally reinject a short durable summary after compaction.Stop/UserPromptSubmithooks are not a reliable substitute because compaction can happen mid-session, before the user is ready to stop or manually persist state.Indexed this hook ticket in the umbrella tracker: #21753
Goal: collect the scattered Codex hook requests and bugs into one parity matrix for Full Claude Code Hook Parity (29+), while preserving this issue as the detailed thread for its specific behavior.
Is this being prioritized / on the roadmap?
Concrete use case: a companion hook that preserves external task-tracker context across compaction. Today
PreCompact/PostCompactare lifecycle-only (no injection channel), andSessionStart(compact)only fires on resume — so after an in-place auto-compaction there's no first-class way to re-inject saved context into the continuing session. The current options are the rollout-log-scraping + next-UserPromptSubmitreinjection pattern (#19061) or aPostToolUseadditionalContextshim — both best-effort and coupled to internal log shapes.A deterministic post-compaction injection point (as requested here) would remove the need for those workarounds. Any maintainer signal on whether this is planned? Happy to help test.
Ideally so that something like https://github.com/Opencode-DCP/opencode-dynamic-context-pruning is possible. In opencode I hardly ever hit compaction thanks to it.