Skip to content

feat(agent): add Codex-native compaction paths - #54633

Closed
hmirin wants to merge 1 commit into
NousResearch:mainfrom
hmirin:feat/codex-native-compaction
Closed

feat(agent): add Codex-native compaction paths#54633
hmirin wants to merge 1 commit into
NousResearch:mainfrom
hmirin:feat/codex-native-compaction

Conversation

@hmirin

@hmirin hmirin commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds opt-in Codex-native context compaction for Codex-backed Hermes sessions.

By default, Hermes keeps its current summary-based compressor. When users set
compression.codex_native_compaction: true, Codex sessions can compact through
the native Codex mechanisms instead:

  • Codex OAuth / Responses API sessions call the Responses compaction API and
    replay the returned encrypted compaction items on later turns.
  • Codex app-server sessions can send manual compaction to the app server via
    thread/compact/start.
  • Codex app-server automatic compaction can be routed through native Codex
    compaction, Hermes compaction, or disabled with compression.codex_app_server_auto.
  • Native Codex compaction updates replay/state metadata and emits the same
    compaction lifecycle status as existing Hermes compaction.

This is intentionally opt-in to avoid changing existing model behavior or
upgrading existing configs during migration.

Related Issue

Closes #33130

Related: #25253, #40957

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Adds a shared compaction path that can delegate Codex-backed sessions to
    Codex-native compaction when compression.codex_native_compaction is enabled.
  • Adds Responses API compaction support, including replay of encrypted compaction
    items and state persistence for compacted transcripts.
  • Adds Codex app-server thread/compact/start support for manual compaction and
    configurable automatic behavior through compression.codex_app_server_auto.
  • Adds config, desktop settings, example config, cache-key, replay, and docs
    plumbing for the new opt-in settings.
  • Adds focused tests for Codex Responses compaction, Codex app-server compaction,
    state.db compaction persistence, compaction logs, app-server transport
    behavior, config migration, and gateway cache busting.

How to Test

  1. Check the PR diff:

    git diff --check origin/main...HEAD
  2. Run focused tests:

    python -m pytest \
      tests/run_agent/test_codex_app_server_compaction.py \
      tests/run_agent/test_codex_responses_compaction.py \
      tests/agent/test_codex_responses_adapter.py \
      tests/agent/transports/test_codex_app_server_session.py \
      tests/gateway/test_replay_entry_fields.py \
      tests/test_hermes_state.py \
      tests/gateway/test_agent_cache.py \
      tests/hermes_cli/test_config.py::TestCodexNativeCompactionConfig \
      tests/hermes_cli/test_config.py::TestConfigNormalizationDoesNotOverwriteUserValues \
      -q

    A local focused slice covering Codex Responses state/log persistence and
    Codex app-server compaction passed:

    python -m pytest \
      tests/run_agent/test_codex_responses_compaction.py \
      tests/run_agent/test_codex_app_server_compaction.py \
      tests/agent/transports/test_codex_app_server_session.py::TestCompactThread::test_compact_thread_sends_rpc_and_waits_for_completion \
      -q
    # 8 passed
  3. Earlier full fork CI passed before the final rebase:

    https://github.com/hmirin/hermes-agent/actions/runs/28344032245
    
  4. Optional manual Codex OAuth E2E:

    Using an isolated HERMES_HOME, authenticated openai-codex, ran real
    Codex turns, then resumed a long session until native Responses compaction
    triggered. Repro harness and observed result:

    https://gist.github.com/hmirin/b71ee4caa336387e6f38131940b6a713
    

    Logs showed:

    Preflight compression: ~58,902 tokens >= 54,400 threshold
    codex responses compaction started: session=20260629_130538_175999 prefix_messages=8 tail_messages=1 tokens=~58,902
    codex responses compaction done: session=20260629_130538_175999 messages=9->2 compaction_items=1
    

    state.db then had 3 active messages: encrypted compaction item, latest user
    message, and latest assistant reply. The prior 9 rows were inactive and
    marked compacted=1.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS / Darwin with Python 3.11, plus fork GitHub Actions on Ubuntu

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Screenshots / Logs

Earlier fork CI:

https://github.com/hmirin/hermes-agent/actions/runs/28344032245
passed before the final rebase

Current local checks after rebasing onto latest origin/main:

git diff --check origin/main...HEAD
passed

python -m pytest tests/run_agent/test_codex_responses_compaction.py tests/run_agent/test_codex_app_server_compaction.py tests/agent/transports/test_codex_app_server_session.py::TestCompactThread::test_compact_thread_sends_rpc_and_waits_for_completion -q
8 passed

Manual isolated Codex OAuth E2E:
real Codex turns passed; native Responses compaction logged messages=9->2 with compaction_items=1; state.db active transcript contained the encrypted compaction item plus latest turn

@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/openai OpenAI / Codex Responses API sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state P3 Low — cosmetic, nice to have labels Jun 29, 2026
@teknium1

teknium1 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Merged via PR #60114 — your commit was cherry-picked onto current main with your authorship preserved in git log (main @ 87b65e2).

Scope note: after maintainer review, the salvage kept the app-server half of your PR and dropped the Responses-API half. Reasoning:

  • App-server runtime (api_mode: codex_app_server): this is where your work was exactly right — the codex agent owns the real thread context, Hermes' summarizer can only rewrite a local mirror, and thread/compact/start is the only mechanism that actually shrinks it (Codex app-server runtime: long sessions grow unbounded → hard context reset (no proactive compaction) #36801). Your compact_thread(), compaction-notification handling, bookkeeping, and tests all landed. Since it's the only viable mechanism there, it ships as default behavior for that runtime (no opt-in umbrella flag), controlled by your codex_app_server_auto: native|hermes|off knob.
  • Responses API chat route: dropped as a design decision, not a quality one. On that route Hermes owns the message list and the summary compressor works and stays provider-portable; encrypted compaction items would bind the session history to chatgpt.com — a mid-session /model switch or provider failover would lose the compacted prefix entirely, and the handoff becomes unreadable for /recap and session views. The implementation itself (adapter replay, dedup, persistence) was clean.

Thanks for the contribution — the app-server piece closes a real P2 and the code quality made the salvage straightforward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have provider/openai OpenAI / Codex Responses API sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use OpenAI Codex Compaction API instead of internal Compress for context compaction.

3 participants