Skip to content

fix(codex): reuse shared recall compressor - #4445

Open
fancyboi999 wants to merge 1 commit into
volcengine:mainfrom
fancyboi999:fix/4444-codex-recall-compress-core
Open

fix(codex): reuse shared recall compressor#4445
fancyboi999 wants to merge 1 commit into
volcengine:mainfrom
fancyboi999:fix/4444-codex-recall-compress-core

Conversation

@fancyboi999

Copy link
Copy Markdown
Contributor

Description

Codex auto-recall maintained a private compression path instead of using the repository's shared recall-compression core. It therefore launched nested codex exec compression for every non-empty result, including bounded context, and could not reuse an identical digest.

This change routes Codex's injection-ready context through compressRecallContext(). The Codex adapter continues to own model/profile selection, process launch, timeouts, provider overrides, and runtime_failed recovery; the shared core owns admission, cache identity, prompt/output validation, and served-URI repair.

The resulting behavior is:

  • context below recallCompressMinInputChars (default 1500) is injected without a nested model call;
  • an identical query/context/URI set reuses the Codex-local digest cache;
  • eligible cache misses lazily resolve the configured Codex compressor profile and launch codex exec;
  • compressor failures preserve the existing deterministic fallback, including the legacy /recall path fixed by fix(codex): compress type-quota recall results #3248;
  • recallCompressMinInputChars=0 preserves always-compress behavior.

Human Involvement

  • A human participated in the implementation or review loop
  • This PR was generated entirely by AI agents without human participation in the loop

Related Issue

Fixes #4444

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • Replaced the Codex-only compression prompt/normalizer with the generated shared compression core while preserving the Codex profile and subprocess adapter.
  • Added the persistent OPENVIKING_RECALL_COMPRESS_MIN_INPUT_CHARS / plugin.codex.recallCompressMinInputChars setting and documented the default/cache behavior.
  • Hardened the shared owner so header-only cached digests and repair results with no surviving cited bullet fail open to caller fallback instead of injecting an empty digest.
  • Preserved served URIs containing spaces and decoded escaped citations before provenance comparison; synchronized the generated shared-module copies.
  • Added production-entrypoint regressions for short-input admission, repeated-request cache reuse, forced compression, provider override, NO_RELEVANT_MEMORY, and failure fallback.

Root Cause

#3248 restored compression on the Codex endpoint success path, but its item-based compressor predated the shared core. #3534 later introduced recall-compress-core.mjs and wired Claude Code through it; the generated file was copied into the Codex bundle without being imported by Codex auto-recall.mjs.

The first real smoke through the shared path also exposed two shared validation gaps: a fully rejected URI-repair result retained the digest header, and the URI scanner truncated legal served paths containing spaces. Both fixes live in the shared owner rather than adding Codex-specific exceptions.

Compatibility and Trade-offs

No server, REST, MCP, identity, or persisted-memory format changes. Small recalled blocks are now injected directly by default instead of paying a second model call for semantic filtering; the server context assembler has already applied retrieval, ranking, budgeting, and cross-turn dedup. Operators that prefer model filtering for every non-empty result can set the minimum to 0.

The digest cache lives under OPENVIKING_CODEX_STATE_DIR, separate from Claude Code state. Legacy servers and compressor failures retain bounded deterministic injection.

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Commands and results:

  • Baseline reproduction on current main: Codex auto-recall test file 10 passed, 2 failed (short: 1 != 0 nested calls; repeat: 2 != 1).
  • npx --yes node@24 --test examples/codex-memory-plugin/scripts/auto-recall.test.mjs examples/memory-plugin-shared/recall-compress-core.test.mjs examples/memory-plugin-shared/sync.test.mjs: 20 passed, 0 failed.
  • Full memory-plugin matrix from .github/workflows/pr.yml on Node 24: 374 passed, 0 failed, 1 skipped out of 375. The skipped test is the existing environment-gated live DSH recall test.
  • All six installer scripts checked by the memory-plugin CI job pass bash -n.
  • git diff --check: passed.
  • Real macOS smoke against OpenViking 0.4.16 with a configured gpt-5.6-luna/low compressor: first eligible request produced a valid cited digest; the identical second request completed in about one second with no compressor profile resolution, confirming a cache hit. No Spark request was used for this verification.

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Not applicable; this changes hook control flow and generated context.

Additional Notes

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

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

[Bug]: Codex recall compressor bypasses shared minimum-input gate and digest cache

1 participant