Skip to content

[codex] prototype mcp_history thread hint injection#29259

Merged
pakrym-oai merged 3 commits into
mainfrom
pakrym/token-budget-mcp-prototype
Jun 21, 2026
Merged

[codex] prototype mcp_history thread hint injection#29259
pakrym-oai merged 3 commits into
mainfrom
pakrym/token-budget-mcp-prototype

Conversation

@pakrym-oai

@pakrym-oai pakrym-oai commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Why

Prototype whether the harness can invoke the mcp_history MCP while constructing full initial context and expose its thread hint to the model without requiring a model-issued tool call.

The prototype builds on the context-window lineage added by #29256 and is now based directly on main.

What changed

  • Call mcp_history/thread_hint with no arguments while building the full <token_budget> context.
  • Pass the current threadId through MCP request metadata, matching the normal MCP tool-call path.
  • Serialize only the unstructured content result and append it inside <token_budget> when the call succeeds.
  • Omit the additional context when the MCP call or content serialization fails.

Prototype limitations

  • The direct call bypasses the normal model-initiated MCP approval, lifecycle-event, telemetry, and result-sanitization path.
  • The call has no prototype-specific timeout, result-size cap, or per-window cache.
  • MCP latency is added to full-context construction, including applicable compaction paths.

Validation

  • just test -p codex-core token_budget

Base automatically changed from pakrym/token-budget-window-lineage to main June 20, 2026 20:15
@pakrym-oai
pakrym-oai force-pushed the pakrym/token-budget-mcp-prototype branch from 84f75b3 to ace5d9c Compare June 20, 2026 20:23
@pakrym-oai pakrym-oai changed the title [codex] prototype history MCP injection in token budget [codex] prototype mcp_history thread hint injection Jun 20, 2026
@pakrym-oai
pakrym-oai marked this pull request as ready for review June 20, 2026 21:05
@pakrym-oai
pakrym-oai requested a review from a team as a code owner June 20, 2026 21:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b496dfeca3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3240 to +3241
.collect::<Vec<_>>()
.join("\n");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Cap mcp_history text before injecting it

When a configured mcp_history/thread_hint returns a large hint, this code concatenates every text block and then stores the whole string in the developer context with no token or byte limit. That creates a new injected context fragment that can exceed the 1k-token manual-review threshold, or even the 10k-token hard limit, and can consume or overflow the model context before the turn starts; truncate or reject the hint before adding it to TokenBudgetContext.

AGENTS.md reference: AGENTS.md:L98-L100

Useful? React with 👍 / 👎.

Comment thread codex-rs/core/src/context/token_budget_context.rs
.unwrap_or_default();
format!(
"Thread id {thread_id}.\nFirst context window id {first_window_id}.\nPrevious context window id {previous_window_id}.\nCurrent context window id {window_id}.\nYou have {tokens_left} tokens left in this context window."
"Thread id {thread_id}.\nFirst context window id {first_window_id}.\nPrevious context window id {previous_window_id}.\nCurrent context window id {window_id}.{mcp_result}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the initial token budget in full context

When TokenBudget is enabled, the full-context fragment used to tell the model how many tokens were available at the start of each window; after this replacement it only includes window IDs unless later threshold reminders fire or the model explicitly calls get_context_remaining. On the first request in a fresh window the model no longer has the budget signal this feature is meant to provide, so keep the computed model_context_window text and append the MCP hint separately.

Useful? React with 👍 / 👎.

)
.await
.ok()
.and_then(|result| {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip MCP error results before injecting hints

If mcp_history/thread_hint returns an application-level MCP failure (is_error: true) with text content, call_tool still resolves successfully and this closure injects that error text as a thread hint. In cases like authorization or backend errors, the model receives a failure message inside developer context instead of omitting the optional hint; check result.is_error before reading content.

Useful? React with 👍 / 👎.

"threadId": self.thread_id().to_string(),
})),
)
.await

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound the optional history lookup latency

When a configured mcp_history server is slow or still initializing, this awaits the optional thread_hint call before the first model request for every full-context window; the normal MCP startup/tool timeouts can be many seconds or minutes before .ok() discards the result. That makes user turns and compaction follow-ups appear hung due to an optional hint, so wrap this lookup in a short prototype-specific timeout or avoid blocking context construction on it.

Useful? React with 👍 / 👎.

Comment on lines +3221 to +3224
let mcp_result = self
.call_tool(
"mcp_history",
"thread_hint",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark memory polluted after background MCP hints

When memories.disable_on_external_context is enabled and mcp_history is a configured MCP server, normal MCP tool calls mark the thread's memory mode as polluted before using that external context, but this background call injects MCP-provided context without doing so. That leaves memory writes enabled for a thread that has already consumed external MCP context, so route this through the same pollution check used by model-initiated MCP calls before adding the hint.

Useful? React with 👍 / 👎.

Comment on lines +3226 to +3228
Some(serde_json::json!({
"threadId": self.thread_id().to_string(),
})),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include sandbox metadata in the hidden MCP call

For an mcp_history server that advertises the codex/sandbox-state-meta capability, normal MCP tool calls include the current sandbox cwd and permission state in request metadata, but this direct call sends only threadId. Such a server will see different metadata for this hidden thread_hint invocation and can fail or compute a hint for the wrong environment; build the request meta with the same sandbox-state augmentation used by regular MCP calls.

Useful? React with 👍 / 👎.

@pakrym-oai
pakrym-oai merged commit b6d6be2 into main Jun 21, 2026
31 checks passed
@pakrym-oai
pakrym-oai deleted the pakrym/token-budget-mcp-prototype branch June 21, 2026 01:02
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant