Split DeveloperInstructions into individual fragments. (#18813)

Split DeveloperInstructions into individual fragments.
This commit is contained in:
pakrym-oai
2026-04-21 10:22:36 -07:00
committed by GitHub
Unverified
parent 5fe767e8e1
commit 2a226096f6
55 changed files with 1410 additions and 1058 deletions
+36 -33
View File
@@ -14,19 +14,26 @@ use crate::agent::MailboxReceiver;
use crate::agent::agent_status_from_event;
use crate::agent::status::is_final;
use crate::agent_identity::AgentIdentityManager;
use crate::apps::render_apps_section;
use crate::build_available_skills;
use crate::commit_attribution::commit_message_trailer_instruction;
use crate::compact;
use crate::config::ManagedFeatures;
use crate::connectors;
use crate::context::ApprovedCommandPrefixSaved;
use crate::context::AppsInstructions;
use crate::context::AvailablePluginsInstructions;
use crate::context::AvailableSkillsInstructions;
use crate::context::CollaborationModeInstructions;
use crate::context::ContextualUserFragment;
use crate::context::NetworkRuleSaved;
use crate::context::PermissionsInstructions;
use crate::context::PersonalitySpecInstructions;
use crate::default_skill_metadata_budget;
use crate::exec_policy::ExecPolicyManager;
use crate::installation_id::resolve_installation_id;
use crate::parse_turn_item;
use crate::path_utils::normalize_for_native_workdir;
use crate::realtime_conversation::RealtimeConversationManager;
use crate::render_skills_section;
use crate::rollout::find_thread_name_by_id;
use crate::session_prefix::format_subagent_notification_message;
use crate::skills::SkillRenderSideEffects;
@@ -256,7 +263,6 @@ use crate::mcp::McpManager;
use crate::memories;
use crate::network_policy_decision::execpolicy_network_rule_amendment;
use crate::plugins::PluginsManager;
use crate::plugins::render_plugins_section;
use crate::rollout::RolloutRecorder;
use crate::rollout::RolloutRecorderParams;
use crate::rollout::map_session_init_error;
@@ -303,7 +309,6 @@ use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::ContentItem;
use codex_protocol::models::DeveloperInstructions;
use codex_protocol::models::ResponseInputItem;
use codex_protocol::models::ResponseItem;
use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
@@ -1652,8 +1657,9 @@ impl Session {
warn!("execpolicy amendment for {sub_id} had no command prefix");
return;
};
let text = format!("Approved command prefix saved:\n{prefixes}");
let message: ResponseItem = DeveloperInstructions::new(text.clone()).into();
let fragment = ApprovedCommandPrefixSaved::new(prefixes);
let text = fragment.render();
let message: ResponseItem = ContextualUserFragment::into(fragment);
if let Some(turn_context) = self.turn_context_for_sub_id(sub_id).await {
self.record_conversation_items(&turn_context, std::slice::from_ref(&message))
@@ -1747,15 +1753,9 @@ impl Session {
sub_id: &str,
amendment: &NetworkPolicyAmendment,
) {
let (action, list_name) = match amendment.action {
NetworkPolicyRuleAction::Allow => ("Allowed", "allowlist"),
NetworkPolicyRuleAction::Deny => ("Denied", "denylist"),
};
let text = format!(
"{action} network rule saved in execpolicy ({list_name}): {}",
amendment.host
);
let message: ResponseItem = DeveloperInstructions::new(text.clone()).into();
let fragment = NetworkRuleSaved::new(amendment);
let text = fragment.render();
let message: ResponseItem = ContextualUserFragment::into(fragment);
if let Some(turn_context) = self.turn_context_for_sub_id(sub_id).await {
self.record_conversation_items(&turn_context, std::slice::from_ref(&message))
@@ -2398,11 +2398,11 @@ impl Session {
turn_context,
)
{
developer_sections.push(model_switch_message.into_text());
developer_sections.push(model_switch_message);
}
if turn_context.config.include_permissions_instructions {
developer_sections.push(
DeveloperInstructions::from_policy(
PermissionsInstructions::from_policy(
turn_context.sandbox_policy.get(),
turn_context.approval_policy.value(),
turn_context.config.approvals_reviewer,
@@ -2415,7 +2415,7 @@ impl Session {
.features
.enabled(Feature::RequestPermissionsTool),
)
.into_text(),
.render(),
);
}
let separate_guardian_developer_message =
@@ -2438,16 +2438,16 @@ impl Session {
}
// Add developer instructions from collaboration_mode if they exist and are non-empty
if let Some(collab_instructions) =
DeveloperInstructions::from_collaboration_mode(&collaboration_mode)
CollaborationModeInstructions::from_collaboration_mode(&collaboration_mode)
{
developer_sections.push(collab_instructions.into_text());
developer_sections.push(collab_instructions.render());
}
if let Some(realtime_update) = crate::context_manager::updates::build_initial_realtime_item(
reference_context_item.as_ref(),
previous_turn_settings.as_ref(),
turn_context,
) {
developer_sections.push(realtime_update.into_text());
developer_sections.push(realtime_update);
}
if self.features.enabled(Feature::Personality)
&& let Some(personality) = turn_context.personality
@@ -2462,10 +2462,8 @@ impl Session {
personality,
)
{
developer_sections.push(
DeveloperInstructions::personality_spec_message(personality_message)
.into_text(),
);
developer_sections
.push(PersonalitySpecInstructions::new(personality_message).render());
}
}
if turn_context.config.include_apps_instructions && turn_context.apps_enabled() {
@@ -2476,8 +2474,10 @@ impl Session {
&turn_context.config,
)
.await;
if let Some(apps_section) = render_apps_section(&accessible_and_enabled_connectors) {
developer_sections.push(apps_section);
if let Some(apps_instructions) =
AppsInstructions::from_connectors(&accessible_and_enabled_connectors)
{
developer_sections.push(apps_instructions.render());
}
}
if turn_context.config.include_skill_instructions {
@@ -2485,15 +2485,17 @@ impl Session {
.turn_skills
.outcome
.allowed_skills_for_implicit_invocation();
let rendered_skills = render_skills_section(
let available_skills = build_available_skills(
&implicit_skills,
default_skill_metadata_budget(turn_context.model_info.context_window),
SkillRenderSideEffects::ThreadStart {
session_telemetry: &self.services.session_telemetry,
},
);
if let Some(rendered_skills) = rendered_skills {
if rendered_skills.emit_warning {
if let Some(available_skills) = available_skills {
let emit_warning = available_skills.emit_warning;
let skills_instructions = AvailableSkillsInstructions::from(available_skills);
if emit_warning {
self.send_event_raw(Event {
id: String::new(),
msg: EventMsg::Warning(WarningEvent {
@@ -2502,7 +2504,7 @@ impl Session {
})
.await;
}
developer_sections.push(rendered_skills.text);
developer_sections.push(skills_instructions.render());
}
}
let loaded_plugins = self
@@ -2510,9 +2512,10 @@ impl Session {
.plugins_manager
.plugins_for_config(&turn_context.config)
.await;
if let Some(plugin_section) = render_plugins_section(loaded_plugins.capability_summaries())
if let Some(plugin_instructions) =
AvailablePluginsInstructions::from_plugins(loaded_plugins.capability_summaries())
{
developer_sections.push(plugin_section);
developer_sections.push(plugin_instructions.render());
}
if turn_context.features.enabled(Feature::CodexGitCommit)
&& let Some(commit_message_instruction) = commit_message_trailer_instruction(