Skip to content

Commit 46fa741

Browse files
committed
Standardize model-visible fragment update assembly
- remove string shim wrappers for model/realtime update fragments\n- push typed developer fragments directly through update builders\n- use fragment path for amendment messages and initial-context assembly\n- add AGENTS.md contextual diffing in steady-state updates\n\nCo-authored-by: Codex <noreply@openai.com>
1 parent 5384a13 commit 46fa741

File tree

4 files changed

+112
-106
lines changed

4 files changed

+112
-106
lines changed

codex-rs/core/src/codex.rs

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,11 @@ use crate::error::CodexErr;
167167
use crate::error::Result as CodexResult;
168168
#[cfg(test)]
169169
use crate::exec::StreamOutput;
170-
use crate::model_visible_context::DeveloperContextRole;
170+
use crate::model_visible_context::ContextualUserTextFragment;
171171
use crate::model_visible_context::DeveloperTextFragment;
172+
use crate::model_visible_context::ModelVisibleContextFragment;
172173
use crate::model_visible_context::TurnContextDiffFragment;
173174
use crate::model_visible_context::TurnContextDiffParams;
174-
use crate::model_visible_context::model_visible_message;
175-
use crate::model_visible_context::model_visible_response_input_item;
176175
use codex_config::CONFIG_TOML_FILE;
177176

178177
mod rollout_reconstruction;
@@ -2596,16 +2595,16 @@ impl Session {
25962595
let text = format!("Approved command prefix saved:\n{prefixes}");
25972596

25982597
if let Some(turn_context) = self.turn_context_for_sub_id(sub_id).await {
2599-
let message = model_visible_message::<DeveloperContextRole>(text.clone());
2598+
let message = DeveloperTextFragment::new(text.clone()).into_message();
26002599
self.record_conversation_items(&turn_context, std::slice::from_ref(&message))
26012600
.await;
26022601
return;
26032602
}
26042603

26052604
if self
2606-
.inject_response_items(vec![model_visible_response_input_item::<
2607-
DeveloperContextRole,
2608-
>(text)])
2605+
.inject_response_items(vec![
2606+
DeveloperTextFragment::new(text).into_response_input_item(),
2607+
])
26092608
.await
26102609
.is_err()
26112610
{
@@ -2692,16 +2691,16 @@ impl Session {
26922691
);
26932692

26942693
if let Some(turn_context) = self.turn_context_for_sub_id(sub_id).await {
2695-
let message = model_visible_message::<DeveloperContextRole>(text.clone());
2694+
let message = DeveloperTextFragment::new(text.clone()).into_message();
26962695
self.record_conversation_items(&turn_context, std::slice::from_ref(&message))
26972696
.await;
26982697
return;
26992698
}
27002699

27012700
if self
2702-
.inject_response_items(vec![model_visible_response_input_item::<
2703-
DeveloperContextRole,
2704-
>(text)])
2701+
.inject_response_items(vec![
2702+
DeveloperTextFragment::new(text).into_response_input_item(),
2703+
])
27052704
.await
27062705
.is_err()
27072706
{
@@ -3268,22 +3267,23 @@ impl Session {
32683267
exec_policy.as_ref(),
32693268
self.features.enabled(Feature::Personality),
32703269
);
3271-
if let Some(model_switch_message) =
3272-
crate::context_manager::updates::build_model_instructions_update_item(
3273-
previous_turn_settings.as_ref(),
3274-
turn_context,
3275-
)
3270+
for fragment in [
3271+
<crate::context_manager::updates::ModelInstructionsUpdateFragment as TurnContextDiffFragment>::from_turn_context(turn_context, &diff_context)
3272+
.map(|fragment| DeveloperTextFragment::new(fragment.render_text())),
3273+
Some(DeveloperTextFragment::new(developer_permissions_text(
3274+
turn_context.sandbox_policy.get(),
3275+
turn_context.approval_policy.value(),
3276+
turn_context.features.enabled(Feature::GuardianApproval),
3277+
exec_policy.as_ref(),
3278+
&turn_context.cwd,
3279+
turn_context.features.enabled(Feature::RequestPermissions),
3280+
))),
3281+
]
3282+
.into_iter()
3283+
.flatten()
32763284
{
3277-
developer_envelope.push(DeveloperTextFragment::new(model_switch_message));
3285+
developer_envelope.push(fragment);
32783286
}
3279-
developer_envelope.push(DeveloperTextFragment::new(developer_permissions_text(
3280-
turn_context.sandbox_policy.get(),
3281-
turn_context.approval_policy.value(),
3282-
turn_context.features.enabled(Feature::GuardianApproval),
3283-
exec_policy.as_ref(),
3284-
&turn_context.cwd,
3285-
turn_context.features.enabled(Feature::RequestPermissions),
3286-
)));
32873287
if let Some(developer_instructions) = turn_context.developer_instructions.as_deref() {
32883288
developer_envelope.push(CustomDeveloperInstructions::new(developer_instructions));
32893289
}
@@ -3308,19 +3308,21 @@ impl Session {
33083308
} else {
33093309
None
33103310
};
3311-
for developer_text in [
3312-
memory_prompt,
3313-
developer_collaboration_mode_text(&collaboration_mode),
3314-
crate::context_manager::updates::build_realtime_update_item(
3315-
reference_context_item.as_ref(),
3316-
previous_turn_settings.as_ref(),
3317-
turn_context,
3318-
),
3319-
personality_message,
3311+
let realtime_message = match reference_context_item.as_ref() {
3312+
Some(previous) => <crate::context_manager::updates::RealtimeUpdateFragment as TurnContextDiffFragment>::diff_from_turn_context_item(previous, turn_context, &diff_context),
3313+
None => <crate::context_manager::updates::RealtimeUpdateFragment as TurnContextDiffFragment>::from_turn_context(turn_context, &diff_context),
3314+
}
3315+
.map(|fragment| DeveloperTextFragment::new(fragment.render_text()));
3316+
for fragment in [
3317+
memory_prompt.map(DeveloperTextFragment::new),
3318+
developer_collaboration_mode_text(&collaboration_mode).map(DeveloperTextFragment::new),
3319+
realtime_message,
3320+
personality_message.map(DeveloperTextFragment::new),
33203321
turn_context
33213322
.features
33223323
.enabled(Feature::Apps)
3323-
.then(render_apps_section),
3324+
.then(render_apps_section)
3325+
.map(DeveloperTextFragment::new),
33243326
turn_context
33253327
.features
33263328
.enabled(Feature::CodexGitCommit)
@@ -3329,43 +3331,42 @@ impl Session {
33293331
turn_context.config.commit_attribution.as_deref(),
33303332
)
33313333
})
3332-
.flatten(),
3334+
.flatten()
3335+
.map(DeveloperTextFragment::new),
33333336
]
33343337
.into_iter()
33353338
.flatten()
33363339
{
3337-
developer_envelope.push(DeveloperTextFragment::new(developer_text));
3338-
}
3339-
if let Some(user_instructions) =
3340-
<AgentsMdInstructions as TurnContextDiffFragment>::from_turn_context(
3341-
turn_context,
3342-
&diff_context,
3343-
)
3344-
{
3345-
contextual_user_envelope.push_fragment(user_instructions);
3340+
developer_envelope.push(fragment);
33463341
}
33473342
let loaded_plugins = self
33483343
.services
33493344
.plugins_manager
33503345
.plugins_for_config(&turn_context.config);
3351-
if let Some(plugin_instructions) =
3346+
for fragment in [
3347+
<AgentsMdInstructions as TurnContextDiffFragment>::from_turn_context(
3348+
turn_context,
3349+
&diff_context,
3350+
)
3351+
.map(|fragment| ContextualUserTextFragment::new(fragment.render_text())),
33523352
render_plugin_instructions(loaded_plugins.capability_summaries())
3353+
.map(|fragment| ContextualUserTextFragment::new(fragment.render_text())),
3354+
<EnvironmentContext as TurnContextDiffFragment>::from_turn_context(
3355+
turn_context,
3356+
&diff_context,
3357+
)
3358+
.map(|fragment| ContextualUserTextFragment::new(fragment.render_text())),
3359+
]
3360+
.into_iter()
3361+
.flatten()
33533362
{
3354-
contextual_user_envelope.push_fragment(plugin_instructions);
3363+
contextual_user_envelope.push_fragment(fragment);
33553364
}
33563365
let subagents = self
33573366
.services
33583367
.agent_control
33593368
.format_environment_context_subagents(self.conversation_id)
33603369
.await;
3361-
if let Some(environment_context) =
3362-
<EnvironmentContext as TurnContextDiffFragment>::from_turn_context(
3363-
turn_context,
3364-
&diff_context,
3365-
)
3366-
{
3367-
contextual_user_envelope.push_fragment(environment_context);
3368-
}
33693370
if let Some(subagent_roster) = crate::session_prefix::SubagentRosterContext::new(subagents)
33703371
{
33713372
developer_envelope.push(subagent_roster);

codex-rs/core/src/context_manager/updates.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ mod developer_update_fragments;
22

33
use crate::codex::TurnContext;
44
use crate::environment_context::EnvironmentContext;
5+
use crate::instructions::AgentsMdInstructions;
56
use crate::model_visible_context::ContextualUserContextRole;
7+
use crate::model_visible_context::ContextualUserTextFragment;
68
use crate::model_visible_context::DeveloperContextRole;
7-
use crate::model_visible_context::DeveloperTextFragment;
89
use crate::model_visible_context::ModelVisibleContextFragment;
910
use crate::model_visible_context::ModelVisibleContextRole;
1011
use crate::model_visible_context::TurnContextDiffFragment;
@@ -17,8 +18,8 @@ use std::marker::PhantomData;
1718
// Keep fragment-specific diff/render logic in
1819
// `updates/developer_update_fragments.rs` so this file can focus on shared
1920
// envelope wiring and message assembly.
20-
pub(crate) use developer_update_fragments::build_model_instructions_update_item;
21-
pub(crate) use developer_update_fragments::build_realtime_update_item;
21+
pub(crate) use developer_update_fragments::ModelInstructionsUpdateFragment;
22+
pub(crate) use developer_update_fragments::RealtimeUpdateFragment;
2223
pub(crate) use developer_update_fragments::personality_message_for;
2324

2425
// Adjacent ContentItems in a single message are effectively concatenated in
@@ -120,17 +121,25 @@ pub(crate) fn build_settings_update_items(
120121
params: &TurnContextDiffParams<'_>,
121122
) -> Vec<ResponseItem> {
122123
let mut developer_envelope = DeveloperEnvelopeBuilder::default();
123-
for fragment in developer_update_fragments::build_developer_update_texts(previous, next, params)
124+
for fragment in
125+
developer_update_fragments::build_developer_update_fragments(previous, next, params)
124126
{
125-
developer_envelope.push(DeveloperTextFragment::new(fragment));
127+
developer_envelope.push(fragment);
126128
}
127129

128130
let mut contextual_user_envelope = ContextualUserEnvelopeBuilder::default();
129131
for fragment in [
130132
// Add new contextual-user diff fragments here.
131-
previous.and_then(|previous| {
132-
EnvironmentContext::diff_from_turn_context_item(previous, next, params)
133-
}),
133+
previous
134+
.and_then(|previous| {
135+
AgentsMdInstructions::diff_from_turn_context_item(previous, next, params)
136+
})
137+
.map(|fragment| ContextualUserTextFragment::new(fragment.render_text())),
138+
previous
139+
.and_then(|previous| {
140+
EnvironmentContext::diff_from_turn_context_item(previous, next, params)
141+
})
142+
.map(|fragment| ContextualUserTextFragment::new(fragment.render_text())),
134143
]
135144
.into_iter()
136145
.flatten()

0 commit comments

Comments
 (0)