mirror of
https://github.com/openai/codex.git
synced 2026-04-28 02:11:08 +03:00
feat: mutli agents persist config overrides (#12667)
Fix propagation of runtime config changes and `--yolo`
This commit is contained in:
@@ -153,6 +153,7 @@ mod spawn {
|
||||
apply_role_to_config(&mut config, role_name)
|
||||
.await
|
||||
.map_err(FunctionCallError::RespondToModel)?;
|
||||
apply_spawn_agent_runtime_overrides(&mut config, turn.as_ref())?;
|
||||
apply_spawn_agent_overrides(&mut config, child_depth);
|
||||
|
||||
let result = session
|
||||
@@ -922,6 +923,16 @@ fn build_agent_shared_config(
|
||||
config.model_reasoning_summary = turn.reasoning_summary;
|
||||
config.developer_instructions = turn.developer_instructions.clone();
|
||||
config.compact_prompt = turn.compact_prompt.clone();
|
||||
apply_spawn_agent_runtime_overrides(&mut config, turn)?;
|
||||
apply_spawn_agent_overrides(&mut config, child_depth);
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
fn apply_spawn_agent_runtime_overrides(
|
||||
config: &mut Config,
|
||||
turn: &TurnContext,
|
||||
) -> Result<(), FunctionCallError> {
|
||||
config.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
|
||||
config.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
|
||||
config.cwd = turn.cwd.clone();
|
||||
@@ -932,9 +943,7 @@ fn build_agent_shared_config(
|
||||
.map_err(|err| {
|
||||
FunctionCallError::RespondToModel(format!("sandbox_policy is invalid: {err}"))
|
||||
})?;
|
||||
apply_spawn_agent_overrides(&mut config, child_depth);
|
||||
|
||||
Ok(config)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply_spawn_agent_overrides(config: &mut Config, child_depth: i32) {
|
||||
@@ -1165,6 +1174,85 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_reapplies_runtime_sandbox_after_role_config() {
|
||||
fn pick_allowed_sandbox_policy(
|
||||
constraint: &crate::config::Constrained<SandboxPolicy>,
|
||||
base: SandboxPolicy,
|
||||
) -> SandboxPolicy {
|
||||
let candidates = [
|
||||
SandboxPolicy::DangerFullAccess,
|
||||
SandboxPolicy::new_workspace_write_policy(),
|
||||
SandboxPolicy::new_read_only_policy(),
|
||||
];
|
||||
candidates
|
||||
.into_iter()
|
||||
.find(|candidate| *candidate != base && constraint.can_set(candidate).is_ok())
|
||||
.unwrap_or(base)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct SpawnAgentResult {
|
||||
agent_id: String,
|
||||
nickname: Option<String>,
|
||||
}
|
||||
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let expected_sandbox = pick_allowed_sandbox_policy(
|
||||
&turn.config.permissions.sandbox_policy,
|
||||
turn.config.permissions.sandbox_policy.get().clone(),
|
||||
);
|
||||
turn.sandbox_policy
|
||||
.set(expected_sandbox.clone())
|
||||
.expect("sandbox policy should be set");
|
||||
assert_ne!(
|
||||
expected_sandbox,
|
||||
turn.config.permissions.sandbox_policy.get().clone(),
|
||||
"test requires a runtime sandbox override that differs from base config"
|
||||
);
|
||||
|
||||
let invocation = invocation(
|
||||
Arc::new(session),
|
||||
Arc::new(turn),
|
||||
"spawn_agent",
|
||||
function_payload(json!({
|
||||
"message": "await this command",
|
||||
"agent_type": "awaiter"
|
||||
})),
|
||||
);
|
||||
let output = MultiAgentHandler
|
||||
.handle(invocation)
|
||||
.await
|
||||
.expect("spawn_agent should succeed");
|
||||
let ToolOutput::Function {
|
||||
body: FunctionCallOutputBody::Text(content),
|
||||
..
|
||||
} = output
|
||||
else {
|
||||
panic!("expected function output");
|
||||
};
|
||||
let result: SpawnAgentResult =
|
||||
serde_json::from_str(&content).expect("spawn_agent result should be json");
|
||||
let agent_id = agent_id(&result.agent_id).expect("agent_id should be valid");
|
||||
assert!(
|
||||
result
|
||||
.nickname
|
||||
.as_deref()
|
||||
.is_some_and(|nickname| !nickname.is_empty())
|
||||
);
|
||||
|
||||
let snapshot = manager
|
||||
.get_thread(agent_id)
|
||||
.await
|
||||
.expect("spawned agent thread should exist")
|
||||
.config_snapshot()
|
||||
.await;
|
||||
assert_eq!(snapshot.sandbox_policy, expected_sandbox);
|
||||
assert_eq!(snapshot.approval_policy, AskForApproval::Never);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_rejects_when_depth_limit_exceeded() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
|
||||
Reference in New Issue
Block a user