Tighten plugin-guidance input plumbing

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Charles Cunningham
2026-03-24 21:06:50 -07:00
co-authored by Codex
parent 4bd0c33fee
commit fac2f41559
2 changed files with 35 additions and 76 deletions
+22 -26
View File
@@ -2570,13 +2570,12 @@ impl Session {
.await
}
/// `maybe_user_input` is only consulted for explicit plugin mentions on this turn.
/// Pass `None` when no raw current-turn user input is available.
/// `user_input` is only consulted for explicit plugin mentions on this turn.
async fn build_settings_update_items(
&self,
reference_context_item: Option<&TurnContextItem>,
current_context: &TurnContext,
maybe_user_input: Option<&[UserInput]>,
user_input: &[UserInput],
) -> Vec<ResponseItem> {
// TODO: Make context updates a pure diff of persisted previous/current TurnContextItem
// state so replay/backtracking is deterministic. Runtime inputs that affect model-visible
@@ -2589,7 +2588,7 @@ impl Session {
let shell = self.user_shell();
let exec_policy = self.services.exec_policy.current();
let additional_developer_sections = self
.build_explicit_plugin_developer_sections(current_context, maybe_user_input)
.build_explicit_plugin_developer_sections(current_context, user_input)
.await;
crate::context_manager::updates::build_settings_update_items(
reference_context_item,
@@ -2602,17 +2601,14 @@ impl Session {
)
}
/// `maybe_user_input` is only used to derive explicit plugin-mention guidance for this turn.
/// When the raw user input is unavailable, pass `None` and no turn-local plugin guidance will
/// be added to the canonical developer envelope.
async fn build_explicit_plugin_developer_sections(
&self,
turn_context: &TurnContext,
maybe_user_input: Option<&[UserInput]>,
user_input: &[UserInput],
) -> Vec<String> {
let Some(user_input) = maybe_user_input else {
if user_input.is_empty() {
return Vec::new();
};
}
let loaded_plugins = self
.services
@@ -3480,7 +3476,8 @@ impl Session {
}
/// `maybe_user_input` is only consulted for explicit plugin mentions on this turn.
/// Pass `None` when no raw current-turn user input is available.
/// Pass `None` when no raw current-turn user input is available, such as compaction callers
/// that are rebuilding prompt context from flattened history alone.
pub(crate) async fn build_initial_context(
&self,
turn_context: &TurnContext,
@@ -3605,10 +3602,12 @@ impl Session {
{
developer_sections.push(plugin_section);
}
developer_sections.extend(
self.build_explicit_plugin_developer_sections(turn_context, maybe_user_input)
.await,
);
if let Some(user_input) = maybe_user_input {
developer_sections.extend(
self.build_explicit_plugin_developer_sections(turn_context, user_input)
.await,
);
}
if turn_context.features.enabled(Feature::CodexGitCommit)
&& let Some(commit_message_instruction) = commit_message_trailer_instruction(
turn_context.config.commit_attribution.as_deref(),
@@ -3697,26 +3696,26 @@ impl Session {
/// reinjects full initial context into replacement history. Other non-regular tasks
/// intentionally do not update the baseline.
///
/// `maybe_user_input` is only used to derive explicit plugin-mention guidance for the
/// canonical developer envelope on this turn.
/// `user_input` is only used to derive explicit plugin-mention guidance for the canonical
/// developer envelope on this turn.
pub(crate) async fn record_context_updates_and_set_reference_context_item(
&self,
turn_context: &TurnContext,
maybe_user_input: Option<&[UserInput]>,
user_input: &[UserInput],
) {
let reference_context_item = {
let state = self.state.lock().await;
state.reference_context_item()
};
let context_items = if reference_context_item.is_none() {
self.build_initial_context(turn_context, maybe_user_input)
self.build_initial_context(turn_context, Some(user_input))
.await
} else {
// Steady-state path: append only context diffs to minimize token overhead.
self.build_settings_update_items(
reference_context_item.as_ref(),
turn_context,
maybe_user_input,
user_input,
)
.await
};
@@ -5597,7 +5596,7 @@ pub(crate) async fn run_turn(
.plugins_for_config(&turn_context.config);
// Structured plugin:// mentions are resolved from the current session's
// enabled plugins here for telemetry/tool selection; the canonical context
// builders derive any explicit plugin guidance from `maybe_user_input`.
// builders derive any explicit plugin guidance from this turn's user input.
let mentioned_plugins =
collect_explicit_plugin_mentions(&input, loaded_plugins.capability_summaries());
let mcp_tools = if turn_context.apps_enabled() || !mentioned_plugins.is_empty() {
@@ -5688,11 +5687,8 @@ pub(crate) async fn run_turn(
.filter_map(crate::plugins::PluginCapabilitySummary::telemetry_metadata)
.collect::<Vec<_>>();
sess.record_context_updates_and_set_reference_context_item(
turn_context.as_ref(),
/*maybe_user_input*/ Some(&input),
)
.await;
sess.record_context_updates_and_set_reference_context_item(turn_context.as_ref(), &input)
.await;
let mut explicitly_enabled_connectors = collect_explicit_app_ids(&input);
explicitly_enabled_connectors.extend(collect_explicit_app_ids_from_skill_items(
+13 -50
View File
@@ -957,10 +957,7 @@ async fn resumed_history_injects_initial_context_on_first_context_update_only()
assert_eq!(expected, history_before_seed.raw_items());
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
expected.extend(
session
@@ -971,10 +968,7 @@ async fn resumed_history_injects_initial_context_on_first_context_update_only()
assert_eq!(expected, history_after_seed.raw_items());
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
let history_after_second_seed = session.clone_history().await;
assert_eq!(
@@ -3719,11 +3713,7 @@ async fn build_settings_update_items_emits_environment_item_for_network_changes(
let reference_context_item = previous_context.to_turn_context_item();
let update_items = session
.build_settings_update_items(
Some(&reference_context_item),
&current_context,
/*maybe_user_input*/ None,
)
.build_settings_update_items(Some(&reference_context_item), &current_context, &[])
.await;
let environment_update = update_items
@@ -3758,11 +3748,7 @@ async fn build_settings_update_items_emits_environment_item_for_time_changes() {
let reference_context_item = previous_context.to_turn_context_item();
let update_items = session
.build_settings_update_items(
Some(&reference_context_item),
&current_context,
/*maybe_user_input*/ None,
)
.build_settings_update_items(Some(&reference_context_item), &current_context, &[])
.await;
let environment_update = update_items
@@ -3797,7 +3783,7 @@ async fn build_settings_update_items_emits_realtime_start_when_session_becomes_l
.build_settings_update_items(
Some(&previous_context.to_turn_context_item()),
&current_context,
/*maybe_user_input*/ None,
&[],
)
.await;
@@ -3826,7 +3812,7 @@ async fn build_settings_update_items_emits_realtime_end_when_session_stops_being
.build_settings_update_items(
Some(&previous_context.to_turn_context_item()),
&current_context,
/*maybe_user_input*/ None,
&[],
)
.await;
@@ -3860,11 +3846,7 @@ async fn build_settings_update_items_uses_previous_turn_settings_for_realtime_en
.set_previous_turn_settings(Some(previous_turn_settings))
.await;
let update_items = session
.build_settings_update_items(
Some(&previous_context_item),
&current_context,
/*maybe_user_input*/ None,
)
.build_settings_update_items(Some(&previous_context_item), &current_context, &[])
.await;
let developer_texts = developer_input_texts(&update_items);
@@ -4096,10 +4078,7 @@ async fn record_context_updates_and_set_reference_context_item_injects_full_cont
{
let (session, turn_context) = make_session_and_context().await;
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
let history = session.clone_history().await;
let initial_context = session
@@ -4132,10 +4111,7 @@ async fn record_context_updates_and_set_reference_context_item_reinjects_full_co
.record_into_history(std::slice::from_ref(&compacted_summary), &turn_context)
.await;
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
{
let mut state = session.state.lock().await;
@@ -4146,10 +4122,7 @@ async fn record_context_updates_and_set_reference_context_item_reinjects_full_co
.await;
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
let history = session.clone_history().await;
@@ -4202,19 +4175,12 @@ async fn record_context_updates_and_set_reference_context_item_persists_baseline
}
let update_items = session
.build_settings_update_items(
Some(&previous_context_item),
&turn_context,
/*maybe_user_input*/ None,
)
.build_settings_update_items(Some(&previous_context_item), &turn_context, &[])
.await;
assert_eq!(update_items, Vec::new());
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
assert_eq!(
@@ -4329,10 +4295,7 @@ async fn record_context_updates_and_set_reference_context_item_persists_full_rei
}))
.await;
session
.record_context_updates_and_set_reference_context_item(
&turn_context,
/*maybe_user_input*/ None,
)
.record_context_updates_and_set_reference_context_item(&turn_context, &[])
.await;
session.ensure_rollout_materialized().await;
session.flush_rollout().await;