mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
feat(config) Plan mode instructions
This commit is contained in:
@@ -193,6 +193,7 @@ impl MessageProcessor {
|
||||
.features
|
||||
.enabled(codex_core::features::Feature::DefaultModeRequestUserInput),
|
||||
},
|
||||
config.plan_mode_developer_instructions.clone(),
|
||||
));
|
||||
thread_manager
|
||||
.plugins_manager()
|
||||
|
||||
@@ -521,6 +521,9 @@
|
||||
"personality": {
|
||||
"$ref": "#/definitions/Personality"
|
||||
},
|
||||
"plan_mode_developer_instructions": {
|
||||
"type": "string"
|
||||
},
|
||||
"plan_mode_reasoning_effort": {
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
@@ -2158,6 +2161,9 @@
|
||||
],
|
||||
"description": "Optionally specify a personality for the model"
|
||||
},
|
||||
"plan_mode_developer_instructions": {
|
||||
"type": "string"
|
||||
},
|
||||
"plan_mode_reasoning_effort": {
|
||||
"$ref": "#/definitions/ReasoningEffort"
|
||||
},
|
||||
|
||||
@@ -433,6 +433,10 @@ pub struct Config {
|
||||
/// Plan preset. The `none` value means "no reasoning" (not "inherit the
|
||||
/// global default").
|
||||
pub plan_mode_reasoning_effort: Option<ReasoningEffort>,
|
||||
/// Optional Plan-mode-specific developer instructions override.
|
||||
///
|
||||
/// When unset, Plan mode uses the built-in Plan preset instructions.
|
||||
pub plan_mode_developer_instructions: Option<String>,
|
||||
|
||||
/// Optional value to use for `reasoning.summary` when making a request
|
||||
/// using the Responses API. When unset, the model catalog default is used.
|
||||
@@ -1201,6 +1205,7 @@ pub struct ConfigToml {
|
||||
|
||||
pub model_reasoning_effort: Option<ReasoningEffort>,
|
||||
pub plan_mode_reasoning_effort: Option<ReasoningEffort>,
|
||||
pub plan_mode_developer_instructions: Option<String>,
|
||||
pub model_reasoning_summary: Option<ReasoningSummary>,
|
||||
/// Optional verbosity control for GPT-5 models (Responses API `text.verbosity`).
|
||||
pub model_verbosity: Option<Verbosity>,
|
||||
@@ -2422,6 +2427,9 @@ impl Config {
|
||||
plan_mode_reasoning_effort: config_profile
|
||||
.plan_mode_reasoning_effort
|
||||
.or(cfg.plan_mode_reasoning_effort),
|
||||
plan_mode_developer_instructions: config_profile
|
||||
.plan_mode_developer_instructions
|
||||
.or(cfg.plan_mode_developer_instructions),
|
||||
model_reasoning_summary: config_profile
|
||||
.model_reasoning_summary
|
||||
.or(cfg.model_reasoning_summary),
|
||||
|
||||
@@ -28,6 +28,7 @@ pub struct ConfigProfile {
|
||||
pub sandbox_mode: Option<SandboxMode>,
|
||||
pub model_reasoning_effort: Option<ReasoningEffort>,
|
||||
pub plan_mode_reasoning_effort: Option<ReasoningEffort>,
|
||||
pub plan_mode_developer_instructions: Option<String>,
|
||||
pub model_reasoning_summary: Option<ReasoningSummary>,
|
||||
pub model_verbosity: Option<Verbosity>,
|
||||
/// Optional path to a JSON model catalog (applied on startup only).
|
||||
|
||||
@@ -23,17 +23,25 @@ pub struct CollaborationModesConfig {
|
||||
|
||||
pub(crate) fn builtin_collaboration_mode_presets(
|
||||
collaboration_modes_config: CollaborationModesConfig,
|
||||
plan_mode_developer_instructions: Option<&str>,
|
||||
) -> Vec<CollaborationModeMask> {
|
||||
vec![plan_preset(), default_preset(collaboration_modes_config)]
|
||||
vec![
|
||||
plan_preset(plan_mode_developer_instructions),
|
||||
default_preset(collaboration_modes_config),
|
||||
]
|
||||
}
|
||||
|
||||
fn plan_preset() -> CollaborationModeMask {
|
||||
fn plan_preset(plan_mode_developer_instructions: Option<&str>) -> CollaborationModeMask {
|
||||
CollaborationModeMask {
|
||||
name: ModeKind::Plan.display_name().to_string(),
|
||||
mode: Some(ModeKind::Plan),
|
||||
model: None,
|
||||
reasoning_effort: Some(Some(ReasoningEffort::Medium)),
|
||||
developer_instructions: Some(Some(COLLABORATION_MODE_PLAN.to_string())),
|
||||
developer_instructions: Some(Some(
|
||||
plan_mode_developer_instructions
|
||||
.unwrap_or(COLLABORATION_MODE_PLAN)
|
||||
.to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,17 +117,27 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn preset_names_use_mode_display_names() {
|
||||
assert_eq!(plan_preset().name, ModeKind::Plan.display_name());
|
||||
assert_eq!(plan_preset(None).name, ModeKind::Plan.display_name());
|
||||
assert_eq!(
|
||||
default_preset(CollaborationModesConfig::default()).name,
|
||||
ModeKind::Default.display_name()
|
||||
);
|
||||
assert_eq!(
|
||||
plan_preset().reasoning_effort,
|
||||
plan_preset(None).reasoning_effort,
|
||||
Some(Some(ReasoningEffort::Medium))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plan_preset_uses_configured_developer_instructions_override() {
|
||||
let override_instructions = "Use plan override.";
|
||||
let plan = plan_preset(Some(override_instructions));
|
||||
assert_eq!(
|
||||
plan.developer_instructions,
|
||||
Some(Some(override_instructions.to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_mode_instructions_replace_mode_names_placeholder() {
|
||||
let default_instructions = default_preset(CollaborationModesConfig {
|
||||
|
||||
@@ -61,6 +61,7 @@ pub struct ModelsManager {
|
||||
etag: RwLock<Option<String>>,
|
||||
cache_manager: ModelsCacheManager,
|
||||
provider: ModelProviderInfo,
|
||||
plan_mode_developer_instructions: Option<String>,
|
||||
}
|
||||
|
||||
impl ModelsManager {
|
||||
@@ -74,6 +75,7 @@ impl ModelsManager {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
model_catalog: Option<ModelsResponse>,
|
||||
collaboration_modes_config: CollaborationModesConfig,
|
||||
plan_mode_developer_instructions: Option<String>,
|
||||
) -> Self {
|
||||
let cache_path = codex_home.join(MODEL_CACHE_FILE);
|
||||
let cache_manager = ModelsCacheManager::new(cache_path, DEFAULT_MODEL_CACHE_TTL);
|
||||
@@ -96,6 +98,7 @@ impl ModelsManager {
|
||||
etag: RwLock::new(None),
|
||||
cache_manager,
|
||||
provider: ModelProviderInfo::create_openai_provider(),
|
||||
plan_mode_developer_instructions,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +124,10 @@ impl ModelsManager {
|
||||
&self,
|
||||
collaboration_modes_config: CollaborationModesConfig,
|
||||
) -> Vec<CollaborationModeMask> {
|
||||
builtin_collaboration_mode_presets(collaboration_modes_config)
|
||||
builtin_collaboration_mode_presets(
|
||||
collaboration_modes_config,
|
||||
self.plan_mode_developer_instructions.as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Attempt to list models without blocking, using the current cached state.
|
||||
@@ -394,6 +400,7 @@ impl ModelsManager {
|
||||
etag: RwLock::new(None),
|
||||
cache_manager,
|
||||
provider,
|
||||
plan_mode_developer_instructions: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,6 +529,7 @@ mod tests {
|
||||
auth_manager,
|
||||
None,
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
);
|
||||
let known_slug = manager
|
||||
.get_remote_models()
|
||||
@@ -562,6 +570,7 @@ mod tests {
|
||||
models: vec![overlay],
|
||||
}),
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
let model_info = manager
|
||||
|
||||
@@ -87,5 +87,6 @@ pub fn all_model_presets() -> &'static Vec<ModelPreset> {
|
||||
pub fn builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
|
||||
collaboration_mode_presets::builtin_collaboration_mode_presets(
|
||||
collaboration_mode_presets::CollaborationModesConfig::default(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -150,6 +150,7 @@ impl ThreadManager {
|
||||
session_source: SessionSource,
|
||||
model_catalog: Option<ModelsResponse>,
|
||||
collaboration_modes_config: CollaborationModesConfig,
|
||||
plan_mode_developer_instructions: Option<String>,
|
||||
) -> Self {
|
||||
let (thread_created_tx, _) = broadcast::channel(THREAD_CREATED_CHANNEL_CAPACITY);
|
||||
let plugins_manager = Arc::new(PluginsManager::new(codex_home.clone()));
|
||||
@@ -168,6 +169,7 @@ impl ThreadManager {
|
||||
auth_manager.clone(),
|
||||
model_catalog,
|
||||
collaboration_modes_config,
|
||||
plan_mode_developer_instructions,
|
||||
)),
|
||||
skills_manager,
|
||||
plugins_manager,
|
||||
|
||||
@@ -824,6 +824,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() {
|
||||
.features
|
||||
.enabled(Feature::DefaultModeRequestUserInput),
|
||||
},
|
||||
config.plan_mode_developer_instructions.clone(),
|
||||
);
|
||||
let NewThread { thread: codex, .. } = thread_manager
|
||||
.start_thread(config)
|
||||
|
||||
@@ -18,6 +18,7 @@ async fn offline_model_info_without_tool_output_override() {
|
||||
auth_manager,
|
||||
None,
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
let model_info = manager.get_model_info("gpt-5.1", &config).await;
|
||||
@@ -41,6 +42,7 @@ async fn offline_model_info_with_tool_output_override() {
|
||||
auth_manager,
|
||||
None,
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
);
|
||||
|
||||
let model_info = manager.get_model_info("gpt-5.1-codex", &config).await;
|
||||
|
||||
@@ -484,6 +484,7 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
.features
|
||||
.enabled(codex_core::features::Feature::DefaultModeRequestUserInput),
|
||||
},
|
||||
config.plan_mode_developer_instructions.clone(),
|
||||
));
|
||||
let default_model = thread_manager
|
||||
.get_models_manager()
|
||||
|
||||
@@ -68,6 +68,7 @@ impl MessageProcessor {
|
||||
.features
|
||||
.enabled(codex_core::features::Feature::DefaultModeRequestUserInput),
|
||||
},
|
||||
config.plan_mode_developer_instructions.clone(),
|
||||
));
|
||||
Self {
|
||||
outgoing,
|
||||
|
||||
@@ -1585,6 +1585,7 @@ impl App {
|
||||
.features
|
||||
.enabled(codex_core::features::Feature::DefaultModeRequestUserInput),
|
||||
},
|
||||
config.plan_mode_developer_instructions.clone(),
|
||||
));
|
||||
let mut model = thread_manager
|
||||
.get_models_manager()
|
||||
|
||||
@@ -1754,6 +1754,7 @@ async fn make_chatwidget_manual(
|
||||
auth_manager.clone(),
|
||||
None,
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
));
|
||||
let reasoning_effort = None;
|
||||
let base_mode = CollaborationMode {
|
||||
@@ -1884,6 +1885,7 @@ fn set_chatgpt_auth(chat: &mut ChatWidget) {
|
||||
chat.auth_manager.clone(),
|
||||
None,
|
||||
CollaborationModesConfig::default(),
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user