[codex] Add token budget context feature (#27438)

## Why

The model should be able to see bounded context-window budget metadata
when the `token_budget` feature is enabled. The full-window message is
only injected with full context, while normal turns get a smaller
follow-up only when reported usage first crosses a budget threshold.

## What changed

- Added the `TokenBudget` feature flag.
- Added `<token_budget>` developer fragments for full context-window
metadata and current-window remaining tokens.
- Inserted the threshold message during normal turn handling by
comparing token usage before and after sampling, avoiding persistent
threshold bookkeeping.
- Added core integration coverage for full-context-only metadata and
25/50/75 percent threshold messages.

## Verification

- `just test -p codex-core token_budget`
- `git diff --check`
This commit is contained in:
pakrym-oai
2026-06-10 20:07:06 -07:00
committed by GitHub
parent ab4ce40042
commit 658af936fd
14 changed files with 399 additions and 7 deletions
+3
View File
@@ -23,6 +23,7 @@ mod realtime_end_instructions;
mod realtime_start_instructions;
mod realtime_start_with_instructions;
mod subagent_notification;
mod token_budget_context;
mod turn_aborted;
mod user_instructions;
mod user_shell_command;
@@ -60,6 +61,8 @@ pub(crate) use realtime_end_instructions::RealtimeEndInstructions;
pub(crate) use realtime_start_instructions::RealtimeStartInstructions;
pub(crate) use realtime_start_with_instructions::RealtimeStartWithInstructions;
pub(crate) use subagent_notification::SubagentNotification;
pub(crate) use token_budget_context::TokenBudgetContext;
pub(crate) use token_budget_context::TokenBudgetRemainingContext;
pub(crate) use turn_aborted::TurnAborted;
pub(crate) use user_instructions::UserInstructions;
pub(crate) use user_shell_command::UserShellCommand;
@@ -0,0 +1,68 @@
use super::ContextualUserFragment;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct TokenBudgetContext {
window_id: u64,
tokens_left: i64,
}
impl TokenBudgetContext {
pub(crate) fn new(window_id: u64, tokens_left: i64) -> Self {
Self {
window_id,
tokens_left,
}
}
}
impl ContextualUserFragment for TokenBudgetContext {
fn role(&self) -> &'static str {
"developer"
}
fn markers(&self) -> (&'static str, &'static str) {
Self::type_markers()
}
fn type_markers() -> (&'static str, &'static str) {
("<token_budget>\n", "\n</token_budget>")
}
fn body(&self) -> String {
let window_id = self.window_id;
let tokens_left = self.tokens_left;
format!(
"Current context window {window_id}.\nYou have {tokens_left} tokens left in this context window."
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct TokenBudgetRemainingContext {
tokens_left: i64,
}
impl TokenBudgetRemainingContext {
pub(crate) fn new(tokens_left: i64) -> Self {
Self { tokens_left }
}
}
impl ContextualUserFragment for TokenBudgetRemainingContext {
fn role(&self) -> &'static str {
"developer"
}
fn markers(&self) -> (&'static str, &'static str) {
Self::type_markers()
}
fn type_markers() -> (&'static str, &'static str) {
("<token_budget>\n", "\n</token_budget>")
}
fn body(&self) -> String {
let tokens_left = self.tokens_left;
format!("You have {tokens_left} tokens left in this context window.")
}
}