fix: project model and reasoning_effort into Codex CLI args, stop rewriting .codex/config.toml
- Add model_reasoning_effort field to AgentProfile (domain layer) - Remove model parameter from codex_config_toml, stop rewriting model in TOML - Pass model and model_reasoning_effort via Codex CLI -c overrides on every exec - Update CodexExecSession with new_with_policy_and_overrides factory - Cover new conversation and resume flows with tests
This commit is contained in:
@ -625,6 +625,54 @@ mod tests {
|
||||
let _ = std::fs::remove_file(&argv);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn factory_passes_codex_profile_model_overrides_to_exec_session() {
|
||||
let factory = StructuredSessionFactory::new();
|
||||
let (cmd, argv) = make_recording_fake(&[
|
||||
r#"{"type":"thread.started","thread_id":"cx-new"}"#,
|
||||
r#"{"type":"item.completed","item":{"id":"i0","type":"agent_message","text":"ok"}}"#,
|
||||
]);
|
||||
let codex = structured_profile(StructuredAdapter::Codex, &cmd)
|
||||
.with_model("gpt-5.4")
|
||||
.with_model_reasoning_effort("medium");
|
||||
let ctx = PreparedContext {
|
||||
content: MarkdownDoc::new("# ctx"),
|
||||
relative_path: "AGENTS.md".to_owned(),
|
||||
project_root: "/project/root".to_owned(),
|
||||
};
|
||||
|
||||
let session = factory
|
||||
.start(
|
||||
&codex,
|
||||
&ctx,
|
||||
&cwd(),
|
||||
&SessionPlan::None,
|
||||
None,
|
||||
&[],
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("start Codex ok");
|
||||
let content = drain_final(session.as_ref()).await;
|
||||
assert_eq!(content, "ok");
|
||||
|
||||
let recorded = std::fs::read_to_string(&argv).expect("argv");
|
||||
let args: Vec<&str> = recorded.lines().collect();
|
||||
assert!(
|
||||
args.windows(2).any(|w| w == ["-c", "model=\"gpt-5.4\""]),
|
||||
"factory must relay profile.model to Codex exec overrides, got: {args:?}"
|
||||
);
|
||||
assert!(
|
||||
args.windows(2)
|
||||
.any(|w| w == ["-c", "model_reasoning_effort=\"medium\""]),
|
||||
"factory must relay profile.model_reasoning_effort to Codex exec overrides, got: {args:?}"
|
||||
);
|
||||
|
||||
let _ = std::fs::remove_file(&cmd);
|
||||
let _ = std::fs::remove_file(&argv);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn factory_resume_seeds_conversation_id() {
|
||||
let factory = StructuredSessionFactory::new();
|
||||
@ -1774,6 +1822,101 @@ mod tests {
|
||||
let _ = std::fs::remove_file(&argv);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn codex_new_conversation_command_carries_profile_model_overrides() {
|
||||
let (cmd, argv) = make_recording_fake(&[
|
||||
r#"{"type":"thread.started","thread_id":"cx-new"}"#,
|
||||
r#"{"type":"item.completed","item":{"id":"i0","type":"agent_message","text":"ok"}}"#,
|
||||
]);
|
||||
let session = CodexExecSession::new_with_policy_and_overrides(
|
||||
SessionId::new_random(),
|
||||
cmd.clone(),
|
||||
"/",
|
||||
None,
|
||||
"workspace-write",
|
||||
vec!["/project/root".to_owned()],
|
||||
Some(true),
|
||||
Some("gpt-5.4".to_owned()),
|
||||
Some("medium".to_owned()),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let _ = session.send("salut").await.expect("send ok");
|
||||
let recorded = std::fs::read_to_string(&argv).expect("argv");
|
||||
let args: Vec<&str> = recorded.lines().collect();
|
||||
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"exec",
|
||||
"--json",
|
||||
"--skip-git-repo-check",
|
||||
"--sandbox",
|
||||
"workspace-write",
|
||||
"--add-dir",
|
||||
"/project/root",
|
||||
"-c",
|
||||
"sandbox_workspace_write.network_access=true",
|
||||
"-c",
|
||||
"model=\"gpt-5.4\"",
|
||||
"-c",
|
||||
"model_reasoning_effort=\"medium\"",
|
||||
"salut",
|
||||
],
|
||||
"profile model overrides must be passed before the prompt, got: {args:?}"
|
||||
);
|
||||
let _ = std::fs::remove_file(&cmd);
|
||||
let _ = std::fs::remove_file(&argv);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn codex_resume_command_carries_profile_model_overrides_before_resume() {
|
||||
let (cmd, argv) = make_recording_fake(&[
|
||||
r#"{"type":"item.completed","item":{"id":"i0","type":"agent_message","text":"ok"}}"#,
|
||||
]);
|
||||
let session = CodexExecSession::new_with_policy_and_overrides(
|
||||
SessionId::new_random(),
|
||||
cmd.clone(),
|
||||
"/",
|
||||
Some("cx-id".to_owned()),
|
||||
"workspace-write",
|
||||
vec!["/project/root".to_owned()],
|
||||
None,
|
||||
Some("gpt-5.4".to_owned()),
|
||||
Some("medium".to_owned()),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let _ = session.send("vas-y").await.expect("send ok");
|
||||
let recorded = std::fs::read_to_string(&argv).expect("argv");
|
||||
let args: Vec<&str> = recorded.lines().collect();
|
||||
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"exec",
|
||||
"--json",
|
||||
"--skip-git-repo-check",
|
||||
"--sandbox",
|
||||
"workspace-write",
|
||||
"--add-dir",
|
||||
"/project/root",
|
||||
"-c",
|
||||
"model=\"gpt-5.4\"",
|
||||
"-c",
|
||||
"model_reasoning_effort=\"medium\"",
|
||||
"resume",
|
||||
"cx-id",
|
||||
"vas-y",
|
||||
],
|
||||
"profile model overrides must precede resume, got: {args:?}"
|
||||
);
|
||||
let _ = std::fs::remove_file(&cmd);
|
||||
let _ = std::fs::remove_file(&argv);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn codex_read_only_policy_omits_add_dir_and_approval_flag() {
|
||||
let (cmd, argv) = make_recording_fake(&[
|
||||
|
||||
Reference in New Issue
Block a user