mirror of
https://github.com/openai/codex.git
synced 2026-10-24 18:18:41 +00:00
Refine /context user-managed grouping
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -366,7 +366,7 @@ Use `thread/read` to fetch a stored thread by id without resuming it. Pass `incl
|
||||
|
||||
### Example: Read live context-window usage
|
||||
|
||||
Use `thread/context/read` to fetch an approximate, sectioned breakdown of the current model-visible context for a loaded thread. The response groups usage into `Built-in`, `AGENTS.md`, `Skills`, `Runtime context`, and `Conversation`, with token counts derived from Codex's current byte-based estimator.
|
||||
Use `thread/context/read` to fetch an approximate, sectioned breakdown of the current model-visible context for a loaded thread. The response groups usage into `Built-in`, `User`, and `Conversation`, with token counts derived from Codex's current byte-based estimator. The `User` section includes AGENTS, skills, and configurable connector/plugin instructions; runtime scaffolding is folded into `Built-in`.
|
||||
|
||||
```json
|
||||
{ "method": "thread/context/read", "id": 24, "params": { "threadId": "thr_123" } }
|
||||
|
||||
@@ -41,9 +41,7 @@ pub struct ContextWindowDetail {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum ContextSectionKind {
|
||||
BuiltIn,
|
||||
Agents,
|
||||
Skills,
|
||||
Runtime,
|
||||
User,
|
||||
Conversation,
|
||||
}
|
||||
|
||||
@@ -62,9 +60,7 @@ struct SectionAccumulator {
|
||||
#[derive(Debug, Default)]
|
||||
struct BreakdownAccumulator {
|
||||
built_in: SectionAccumulator,
|
||||
agents: SectionAccumulator,
|
||||
skills: SectionAccumulator,
|
||||
runtime: SectionAccumulator,
|
||||
user: SectionAccumulator,
|
||||
conversation: SectionAccumulator,
|
||||
verbose: bool,
|
||||
}
|
||||
@@ -241,9 +237,7 @@ impl BreakdownAccumulator {
|
||||
fn section_accumulator(&mut self, section: ContextSectionKind) -> &mut SectionAccumulator {
|
||||
match section {
|
||||
ContextSectionKind::BuiltIn => &mut self.built_in,
|
||||
ContextSectionKind::Agents => &mut self.agents,
|
||||
ContextSectionKind::Skills => &mut self.skills,
|
||||
ContextSectionKind::Runtime => &mut self.runtime,
|
||||
ContextSectionKind::User => &mut self.user,
|
||||
ContextSectionKind::Conversation => &mut self.conversation,
|
||||
}
|
||||
}
|
||||
@@ -251,9 +245,7 @@ impl BreakdownAccumulator {
|
||||
fn into_sections(self) -> Vec<ContextWindowSection> {
|
||||
let mut sections: Vec<ContextWindowSection> = [
|
||||
self.built_in.section,
|
||||
self.agents.section,
|
||||
self.skills.section,
|
||||
self.runtime.section,
|
||||
self.user.section,
|
||||
self.conversation.section,
|
||||
]
|
||||
.into_iter()
|
||||
@@ -340,7 +332,7 @@ fn classify_developer_text(text: &str) -> (ContextSectionKind, String) {
|
||||
let trimmed = text.trim_start();
|
||||
if starts_with_tag(trimmed, SKILLS_INSTRUCTIONS_OPEN_TAG) {
|
||||
return (
|
||||
ContextSectionKind::Skills,
|
||||
ContextSectionKind::User,
|
||||
format!(
|
||||
"Implicit skills catalog ({} skills)",
|
||||
count_catalog_entries(trimmed)
|
||||
@@ -349,13 +341,13 @@ fn classify_developer_text(text: &str) -> (ContextSectionKind, String) {
|
||||
}
|
||||
if starts_with_tag(trimmed, APPS_INSTRUCTIONS_OPEN_TAG) {
|
||||
return (
|
||||
ContextSectionKind::BuiltIn,
|
||||
ContextSectionKind::User,
|
||||
"Apps connector instructions".to_string(),
|
||||
);
|
||||
}
|
||||
if starts_with_tag(trimmed, PLUGINS_INSTRUCTIONS_OPEN_TAG) {
|
||||
return (
|
||||
ContextSectionKind::BuiltIn,
|
||||
ContextSectionKind::User,
|
||||
format!(
|
||||
"Plugin instructions ({} plugins)",
|
||||
count_catalog_entries(trimmed)
|
||||
@@ -387,7 +379,7 @@ fn classify_developer_text(text: &str) -> (ContextSectionKind, String) {
|
||||
);
|
||||
}
|
||||
if starts_with_tag(trimmed, REALTIME_CONVERSATION_OPEN_TAG) {
|
||||
return (ContextSectionKind::Runtime, "Realtime context".to_string());
|
||||
return (ContextSectionKind::BuiltIn, "Realtime context".to_string());
|
||||
}
|
||||
(
|
||||
ContextSectionKind::BuiltIn,
|
||||
@@ -397,38 +389,38 @@ fn classify_developer_text(text: &str) -> (ContextSectionKind, String) {
|
||||
|
||||
fn classify_user_text(text: &str, phase: Option<&MessagePhase>) -> (ContextSectionKind, String) {
|
||||
if AGENTS_MD_FRAGMENT.matches_text(text) {
|
||||
return (ContextSectionKind::Agents, format_agents_label(text));
|
||||
return (ContextSectionKind::User, format_agents_label(text));
|
||||
}
|
||||
if SKILL_FRAGMENT.matches_text(text) {
|
||||
return (ContextSectionKind::Skills, format_skill_label(text));
|
||||
return (ContextSectionKind::User, format_skill_label(text));
|
||||
}
|
||||
if ENVIRONMENT_CONTEXT_FRAGMENT.matches_text(text) {
|
||||
return (
|
||||
ContextSectionKind::Runtime,
|
||||
ContextSectionKind::BuiltIn,
|
||||
"Environment context".to_string(),
|
||||
);
|
||||
}
|
||||
if USER_SHELL_COMMAND_FRAGMENT.matches_text(text) {
|
||||
return (
|
||||
ContextSectionKind::Runtime,
|
||||
ContextSectionKind::BuiltIn,
|
||||
"User shell command".to_string(),
|
||||
);
|
||||
}
|
||||
if TURN_ABORTED_FRAGMENT.matches_text(text) {
|
||||
return (
|
||||
ContextSectionKind::Runtime,
|
||||
ContextSectionKind::BuiltIn,
|
||||
"Turn aborted marker".to_string(),
|
||||
);
|
||||
}
|
||||
if SUBAGENT_NOTIFICATION_FRAGMENT.matches_text(text) {
|
||||
return (
|
||||
ContextSectionKind::Runtime,
|
||||
ContextSectionKind::BuiltIn,
|
||||
"Subagent notification".to_string(),
|
||||
);
|
||||
}
|
||||
if parse_hook_prompt_fragment(text).is_some() {
|
||||
return (
|
||||
ContextSectionKind::Runtime,
|
||||
ContextSectionKind::BuiltIn,
|
||||
"Hook prompt context".to_string(),
|
||||
);
|
||||
}
|
||||
@@ -568,10 +560,8 @@ fn section_for_message_role(role: &str) -> ContextSectionKind {
|
||||
fn section_order(label: &str) -> usize {
|
||||
match label {
|
||||
"Built-in" => 0,
|
||||
"AGENTS.md" => 1,
|
||||
"Skills" => 2,
|
||||
"Runtime context" => 3,
|
||||
"Conversation" => 4,
|
||||
"User" => 1,
|
||||
"Conversation" => 2,
|
||||
_ => usize::MAX,
|
||||
}
|
||||
}
|
||||
@@ -580,9 +570,7 @@ impl ContextSectionKind {
|
||||
fn label(self) -> &'static str {
|
||||
match self {
|
||||
ContextSectionKind::BuiltIn => "Built-in",
|
||||
ContextSectionKind::Agents => "AGENTS.md",
|
||||
ContextSectionKind::Skills => "Skills",
|
||||
ContextSectionKind::Runtime => "Runtime context",
|
||||
ContextSectionKind::User => "User",
|
||||
ContextSectionKind::Conversation => "Conversation",
|
||||
}
|
||||
}
|
||||
@@ -619,7 +607,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn groups_built_in_agents_skills_runtime_and_conversation_sections() {
|
||||
fn groups_built_in_user_and_conversation_sections() {
|
||||
let base_instructions = BaseInstructions {
|
||||
text: "Base instructions".to_string(),
|
||||
};
|
||||
@@ -658,11 +646,9 @@ mod tests {
|
||||
assert_eq!(
|
||||
section_labels,
|
||||
vec![
|
||||
"AGENTS.md".to_string(),
|
||||
"Built-in".to_string(),
|
||||
"Conversation".to_string(),
|
||||
"Runtime context".to_string(),
|
||||
"Skills".to_string(),
|
||||
"User".to_string(),
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -766,7 +752,7 @@ mod tests {
|
||||
.iter()
|
||||
.map(|(label, _)| label.clone())
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["Built-in".to_string(), "Skills".to_string()]
|
||||
vec!["Built-in".to_string(), "User".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
breakdown.total_tokens,
|
||||
|
||||
@@ -298,9 +298,7 @@ fn section_marker(label: &str) -> Span<'static> {
|
||||
fn section_style(label: &str) -> Style {
|
||||
match label {
|
||||
"Conversation" => Style::new().cyan().bold(),
|
||||
"Skills" => Style::new().green().bold(),
|
||||
"AGENTS.md" => Style::new().magenta().bold(),
|
||||
"Runtime context" => Style::new().red().bold(),
|
||||
"User" => Style::new().green().bold(),
|
||||
"Built-in" => Style::new().fg(ratatui::style::Color::Yellow).bold(),
|
||||
_ => Style::new(),
|
||||
}
|
||||
@@ -402,7 +400,7 @@ mod tests {
|
||||
total_tokens: 20_000,
|
||||
sections: vec![
|
||||
ThreadContextWindowSection {
|
||||
label: "Skills".to_string(),
|
||||
label: "User".to_string(),
|
||||
tokens: 12_000,
|
||||
details: vec![ThreadContextWindowDetail {
|
||||
label: "Implicit skills catalog (42 skills)".to_string(),
|
||||
|
||||
+2
-2
@@ -10,10 +10,10 @@ Context map
|
||||
window▕████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▏
|
||||
used ▕████████████████████████████████████████████▏
|
||||
|
||||
■ Skills 60.0%
|
||||
■ User 60.0%
|
||||
■ Conversation 40.0%
|
||||
|
||||
■ Skills ~12,000 tokens 60.0% of used
|
||||
■ User ~12,000 tokens 60.0% of used
|
||||
██████████ Implicit skills catalog (42 skills) (~12,000 tokens)
|
||||
|
||||
■ Conversation ~8,000 tokens 40.0% of used
|
||||
|
||||
Reference in New Issue
Block a user