mirror of
https://github.com/openai/codex.git
synced 2026-04-24 06:35:50 +00:00
test(core): cover fork_context defaults for discovered roles
This commit is contained in:
@@ -130,7 +130,7 @@ pub(crate) fn default_fork_context_for_role(config: &Config, role_name: Option<&
|
||||
let role_name = role_name.unwrap_or(DEFAULT_ROLE_NAME);
|
||||
resolve_role_config(config, role_name)
|
||||
.and_then(|role| role.fork_context)
|
||||
.unwrap_or(false)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
fn preservation_policy(config: &Config, role_layer_toml: &TomlValue) -> (bool, bool) {
|
||||
|
||||
@@ -72,6 +72,86 @@ async fn apply_role_returns_error_for_unknown_role() {
|
||||
assert_eq!(err, "unknown agent_type 'missing-role'");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn default_fork_context_for_role_defaults_unspecified_custom_roles_to_true() {
|
||||
let (_home, mut config) = test_config_with_cli_overrides(Vec::new()).await;
|
||||
config.agent_roles.insert(
|
||||
"custom".to_string(),
|
||||
AgentRoleConfig {
|
||||
description: Some("Custom role".to_string()),
|
||||
config_file: None,
|
||||
nickname_candidates: None,
|
||||
fork_context: None,
|
||||
},
|
||||
);
|
||||
|
||||
assert!(default_fork_context_for_role(&config, Some("custom")));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn default_fork_context_for_role_defaults_discovered_role_files_to_true() {
|
||||
let codex_home = TempDir::new().expect("create temp dir");
|
||||
let repo_root = TempDir::new().expect("create temp dir");
|
||||
let nested_cwd = repo_root.path().join("packages").join("app");
|
||||
fs::create_dir_all(repo_root.path().join(".git")).expect("create git dir");
|
||||
fs::create_dir_all(&nested_cwd).expect("create nested cwd");
|
||||
|
||||
let workspace_key = repo_root.path().to_string_lossy().replace('\\', "\\\\");
|
||||
tokio::fs::write(
|
||||
codex_home.path().join(CONFIG_TOML_FILE),
|
||||
format!(
|
||||
r#"[projects."{workspace_key}"]
|
||||
trust_level = "trusted"
|
||||
"#
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("write config");
|
||||
|
||||
let agents_dir = repo_root.path().join(".codex").join("agents");
|
||||
tokio::fs::create_dir_all(&agents_dir)
|
||||
.await
|
||||
.expect("create agents dir");
|
||||
tokio::fs::write(
|
||||
agents_dir.join("custom.toml"),
|
||||
r#"
|
||||
name = "custom"
|
||||
description = "Custom role"
|
||||
developer_instructions = "Stay focused"
|
||||
"#,
|
||||
)
|
||||
.await
|
||||
.expect("write role file");
|
||||
|
||||
let config = ConfigBuilder::default()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
.harness_overrides(ConfigOverrides {
|
||||
cwd: Some(nested_cwd),
|
||||
..Default::default()
|
||||
})
|
||||
.build()
|
||||
.await
|
||||
.expect("load config");
|
||||
|
||||
assert!(default_fork_context_for_role(&config, Some("custom")));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn default_fork_context_for_role_uses_explicit_custom_role_override() {
|
||||
let (_home, mut config) = test_config_with_cli_overrides(Vec::new()).await;
|
||||
config.agent_roles.insert(
|
||||
"custom".to_string(),
|
||||
AgentRoleConfig {
|
||||
description: Some("Custom role".to_string()),
|
||||
config_file: None,
|
||||
nickname_candidates: None,
|
||||
fork_context: Some(false),
|
||||
},
|
||||
);
|
||||
|
||||
assert!(!default_fork_context_for_role(&config, Some("custom")));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "No role requiring it for now"]
|
||||
async fn apply_explorer_role_sets_model_and_adds_session_flags_layer() {
|
||||
|
||||
@@ -601,7 +601,7 @@ fn spawn_agent_common_properties_v1(agent_type_description: &str) -> BTreeMap<St
|
||||
"model".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional model override for the new agent. Replaces the inherited model."
|
||||
"Optional model override for the new agent. Replaces the inherited model only when fork_context is false; forked children always inherit the parent model."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
@@ -610,7 +610,7 @@ fn spawn_agent_common_properties_v1(agent_type_description: &str) -> BTreeMap<St
|
||||
"reasoning_effort".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort."
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort only when fork_context is false; forked children always inherit the parent reasoning effort."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
@@ -645,7 +645,7 @@ fn spawn_agent_common_properties_v2(agent_type_description: &str) -> BTreeMap<St
|
||||
"model".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional model override for the new agent. Replaces the inherited model."
|
||||
"Optional model override for the new agent. Replaces the inherited model only when fork_turns is `none`; forked children always inherit the parent model."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
@@ -654,7 +654,7 @@ fn spawn_agent_common_properties_v2(agent_type_description: &str) -> BTreeMap<St
|
||||
"reasoning_effort".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort."
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort only when fork_turns is `none`; forked children always inherit the parent reasoning effort."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
|
||||
@@ -94,6 +94,58 @@ fn spawn_agent_tool_v1_keeps_legacy_fork_context_field() {
|
||||
|
||||
assert!(properties.contains_key("fork_context"));
|
||||
assert!(!properties.contains_key("fork_turns"));
|
||||
assert_eq!(
|
||||
properties.get("model"),
|
||||
Some(&JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional model override for the new agent. Replaces the inherited model only when fork_context is false; forked children always inherit the parent model."
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
properties.get("reasoning_effort"),
|
||||
Some(&JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort only when fork_context is false; forked children always inherit the parent reasoning effort."
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_tool_v2_documents_that_forked_children_ignore_model_overrides() {
|
||||
let tool = create_spawn_agent_tool_v2(SpawnAgentToolOptions {
|
||||
available_models: &[],
|
||||
agent_type_description: "role help".to_string(),
|
||||
});
|
||||
|
||||
let ToolSpec::Function(ResponsesApiTool { parameters, .. }) = tool else {
|
||||
panic!("spawn_agent should be a function tool");
|
||||
};
|
||||
let JsonSchema::Object { properties, .. } = parameters else {
|
||||
panic!("spawn_agent should use object params");
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
properties.get("model"),
|
||||
Some(&JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional model override for the new agent. Replaces the inherited model only when fork_turns is `none`; forked children always inherit the parent model."
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
properties.get("reasoning_effort"),
|
||||
Some(&JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional reasoning effort override for the new agent. Replaces the inherited reasoning effort only when fork_turns is `none`; forked children always inherit the parent reasoning effort."
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user