codex - 💡(How to fix) Fix Suggestion: improve local compaction handoff

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

I could not open a PR against openai/codex from this account because PR creation is restricted, but I pushed a working implementation branch here:

Code Example

let user_messages = collect_user_messages(&pre_compaction_history_items);
let recent_tail = collect_recent_context_tail(&pre_compaction_history_items);

let mut new_history = build_compacted_history_with_recent_tail(
    Vec::new(),
    &user_messages,
    &summary_text,
    recent_tail,
);

---

const COMPACT_RECENT_OUTPUT_ITEMS_MAX: usize = 16;
const COMPACT_RECENT_OUTPUT_MAX_TOKENS: i64 = 20_000;

fn collect_recent_context_tail(items: &[ResponseItem]) -> Vec<ResponseItem> {
    let Some(last_user_index) = items
        .iter()
        .enumerate()
        .rev()
        .find_map(|(index, item)| real_user_message_text(item).is_some().then_some(index))
    else {
        return Vec::new();
    };

    let mut selected_outputs = Vec::new();
    let mut remaining_tokens = COMPACT_RECENT_OUTPUT_MAX_TOKENS;
    for item in items[last_user_index + 1..].iter().rev() {
        if !is_recent_output_item(item) {
            continue;
        }
        if selected_outputs.len() >= COMPACT_RECENT_OUTPUT_ITEMS_MAX {
            break;
        }

        let item_tokens =
            approx_tokens_from_byte_count_i64(estimate_response_item_model_visible_bytes(item));
        if item_tokens > remaining_tokens {
            break;
        }
        remaining_tokens = remaining_tokens.saturating_sub(item_tokens.max(0));
        selected_outputs.push(item.clone());
    }
    selected_outputs.reverse();
    let selected_outputs = retain_complete_tool_pairs(selected_outputs);

    let mut recent_tail = Vec::with_capacity(selected_outputs.len() + 1);
    recent_tail.push(items[last_user_index].clone());
    recent_tail.extend(selected_outputs);
    recent_tail
}

---

just fmt
just fix -p codex-core
RUST_MIN_STACK=8388608 cargo test -p codex-core compact::tests
RUST_MIN_STACK=8388608 cargo test -p codex-core --test all suite::compact::
cargo build -p codex-cli
RAW_BUFFERClick to expand / collapse

Suggestion

Local compaction should hand off enough state for the next model to continue the active task without re-discovering recent context.

This is related to the prompt-adjustment discussion here: https://github.com/openai/codex/discussions/17330

I could not open a PR against openai/codex from this account because PR creation is restricted, but I pushed a working implementation branch here:

Proposed behavior

  • Make the local compaction prompt explicitly produce a CONTEXT CHECKPOINT SUMMARY handoff.
  • Preserve the latest real user turn plus a bounded recent assistant/reasoning/tool tail.
  • Keep only complete tool call/output pairs when retaining tool context.
  • Emit the generated compact summary as an agent message, while preserving the existing compact warning event.
  • Keep existing remote compaction routing and configured compact_prompt overrides intact.

Representative implementation

The branch adds bounded recent-tail retention before building replacement history:

let user_messages = collect_user_messages(&pre_compaction_history_items);
let recent_tail = collect_recent_context_tail(&pre_compaction_history_items);

let mut new_history = build_compacted_history_with_recent_tail(
    Vec::new(),
    &user_messages,
    &summary_text,
    recent_tail,
);

The retained tail starts from the last real user message, then walks recent model-visible output backward under item/token caps, and drops orphaned tool calls or outputs:

const COMPACT_RECENT_OUTPUT_ITEMS_MAX: usize = 16;
const COMPACT_RECENT_OUTPUT_MAX_TOKENS: i64 = 20_000;

fn collect_recent_context_tail(items: &[ResponseItem]) -> Vec<ResponseItem> {
    let Some(last_user_index) = items
        .iter()
        .enumerate()
        .rev()
        .find_map(|(index, item)| real_user_message_text(item).is_some().then_some(index))
    else {
        return Vec::new();
    };

    let mut selected_outputs = Vec::new();
    let mut remaining_tokens = COMPACT_RECENT_OUTPUT_MAX_TOKENS;
    for item in items[last_user_index + 1..].iter().rev() {
        if !is_recent_output_item(item) {
            continue;
        }
        if selected_outputs.len() >= COMPACT_RECENT_OUTPUT_ITEMS_MAX {
            break;
        }

        let item_tokens =
            approx_tokens_from_byte_count_i64(estimate_response_item_model_visible_bytes(item));
        if item_tokens > remaining_tokens {
            break;
        }
        remaining_tokens = remaining_tokens.saturating_sub(item_tokens.max(0));
        selected_outputs.push(item.clone());
    }
    selected_outputs.reverse();
    let selected_outputs = retain_complete_tool_pairs(selected_outputs);

    let mut recent_tail = Vec::with_capacity(selected_outputs.len() + 1);
    recent_tail.push(items[last_user_index].clone());
    recent_tail.extend(selected_outputs);
    recent_tail
}

The prompt text is changed to request a dense handoff with explicit PREVIOUSLY, PARKED TASKS, and CURRENT TASK sections, and to copy delicate runtime state such as pending jobs, subagents, plans, exact command outputs, and immediate next validation checks.

Validation run on the branch

just fmt
just fix -p codex-core
RUST_MIN_STACK=8388608 cargo test -p codex-core compact::tests
RUST_MIN_STACK=8388608 cargo test -p codex-core --test all suite::compact::
cargo build -p codex-cli

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING