mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Allow session configuration with codex agents (#39870)
## Why `codex agents` rejected invocation-specific configuration, preventing the dashboard from applying settings when starting a shared thread. ## What changed - Accept interactive options such as model, approval, sandbox, search, working directory, and configuration overrides when opening the agents dashboard. - Forward supported session-flag configuration into threads started through an embedded or remote app server, while excluding unrelated values. - Continue to reject initial prompts and images, along with local provider and additional-directory settings that cannot be applied to a remote server. ## Testing - Cover accepted dashboard options and rejected incompatible inputs. - Verify that explicit feature and sandbox overrides reach shared threads in both embedded and remote modes. GitOrigin-RevId: f10aa1e16ff62b49d55679e987d9e458438ba3f8
This commit is contained in:
@@ -1092,25 +1092,31 @@ async fn cli_main(
|
||||
let open_agents_overview = matches!(&subcommand, Some(Subcommand::Agents(_)));
|
||||
match subcommand {
|
||||
None | Some(Subcommand::Agents(_)) => {
|
||||
prepend_config_flags(
|
||||
&mut interactive.config_overrides,
|
||||
root_config_overrides.clone(),
|
||||
);
|
||||
if open_agents_overview {
|
||||
if !root_config_overrides.raw_overrides.is_empty()
|
||||
|| root_strict_config
|
||||
|| interactive.prompt.is_some()
|
||||
|| !interactive.images.is_empty()
|
||||
|| interactive.model.is_some()
|
||||
|| interactive.oss
|
||||
|| interactive.oss_provider.is_some()
|
||||
|| interactive.config_profile_v2.is_some()
|
||||
|| interactive.sandbox_mode.is_some()
|
||||
|| interactive.dangerously_bypass_approvals_and_sandbox
|
||||
|| interactive.bypass_hook_trust
|
||||
|| interactive.cwd.is_some() && root_remote.is_none()
|
||||
|| !interactive.add_dir.is_empty()
|
||||
|| interactive.approval_policy.is_some()
|
||||
|| interactive.web_search
|
||||
if interactive.prompt.is_some() || !interactive.images.is_empty() {
|
||||
anyhow::bail!("`codex agents` does not accept an initial prompt or images");
|
||||
}
|
||||
if root_remote.is_some()
|
||||
&& (interactive.oss
|
||||
|| interactive.oss_provider.is_some()
|
||||
|| !interactive.add_dir.is_empty()
|
||||
|| interactive
|
||||
.config_overrides
|
||||
.parse_overrides()
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.iter()
|
||||
.any(|(key, value)| {
|
||||
key == "sandbox_workspace_write.writable_roots"
|
||||
|| (key == "sandbox_workspace_write"
|
||||
&& value.get("writable_roots").is_some())
|
||||
}))
|
||||
{
|
||||
anyhow::bail!(
|
||||
"`codex agents` cannot attach to shared sessions with invocation-specific configuration overrides"
|
||||
"`codex agents` cannot apply local provider or additional-directory overrides to a remote server"
|
||||
);
|
||||
}
|
||||
if is_workload_identity_selected() {
|
||||
@@ -1128,10 +1134,6 @@ async fn cli_main(
|
||||
}
|
||||
interactive.agents_overview = true;
|
||||
}
|
||||
prepend_config_flags(
|
||||
&mut interactive.config_overrides,
|
||||
root_config_overrides.clone(),
|
||||
);
|
||||
let exit_info = run_interactive_tui(
|
||||
interactive,
|
||||
root_remote.clone(),
|
||||
|
||||
@@ -33,19 +33,72 @@ foo = "bar"
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agents_reject_session_overrides_before_starting_the_daemon() -> Result<()> {
|
||||
fn agents_accept_interactive_configuration_overrides() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
for args in [
|
||||
["-c", "features.multi_agent_mode=true", "agents"].as_slice(),
|
||||
["--enable", "multi_agent_mode", "agents"].as_slice(),
|
||||
["--yolo", "agents"].as_slice(),
|
||||
["--search", "agents"].as_slice(),
|
||||
["--model", "gpt-5", "agents"].as_slice(),
|
||||
["--approve-for-me", "agents"].as_slice(),
|
||||
["--cd", ".", "agents"].as_slice(),
|
||||
] {
|
||||
let mut cmd = codex_command(codex_home.path())?;
|
||||
cmd.env("TERM", "xterm-256color").args(args);
|
||||
#[cfg(not(unix))]
|
||||
cmd.args(["--remote", "ws://127.0.0.1:4512"]);
|
||||
|
||||
cmd.assert()
|
||||
.failure()
|
||||
.stderr(contains("stdin is not a terminal"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agents_reject_inputs_that_cannot_be_applied() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
for (args, expected_error) in [
|
||||
(
|
||||
["--image=image.png", "agents"].as_slice(),
|
||||
"does not accept an initial prompt or images",
|
||||
),
|
||||
(
|
||||
["--oss", "agents", "--remote", "ws://127.0.0.1:4512"].as_slice(),
|
||||
"cannot apply local provider or additional-directory overrides",
|
||||
),
|
||||
(
|
||||
[
|
||||
"--add-dir",
|
||||
".",
|
||||
"agents",
|
||||
"--remote",
|
||||
"ws://127.0.0.1:4512",
|
||||
]
|
||||
.as_slice(),
|
||||
"cannot apply local provider or additional-directory overrides",
|
||||
),
|
||||
(
|
||||
[
|
||||
"-c",
|
||||
"sandbox_workspace_write.writable_roots=[\"../shared\"]",
|
||||
"agents",
|
||||
"--remote",
|
||||
"ws://127.0.0.1:4512",
|
||||
]
|
||||
.as_slice(),
|
||||
"cannot apply local provider or additional-directory overrides",
|
||||
),
|
||||
] {
|
||||
let mut cmd = codex_command(codex_home.path())?;
|
||||
cmd.args(args)
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(contains("invocation-specific configuration overrides"));
|
||||
.stderr(contains(expected_error));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user