mirror of
https://github.com/openai/codex.git
synced 2026-10-28 08:04:55 +00:00
Restore agent roles when reloading v2 sub-agents (#33657)
## Why Durable v2 sub-agents can be lazily reloaded after their root session resumes. The reload path restored the agent identity but did not reapply the agent's selected role configuration. ## What changed - Recover the agent role from the resumed session source and apply it before reloading the sub-agent. - Preserve the runtime approval policy, approval reviewer, working directory, and permission profile while applying the role. ## Testing Extend the cold-resume integration test to verify that the reloaded worker retains its role-defined instructions, model, provider, reasoning effort, and permission profile. GitOrigin-RevId: a26dbbd2599838ca317326a1223a6a0a9cb2a2ed
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use super::residency::is_v2_resident_session_source;
|
||||
use super::*;
|
||||
use crate::agent::role::apply_role_to_config;
|
||||
use crate::config::PermissionProfileSnapshot;
|
||||
use codex_extension_api::ExtensionDataInit;
|
||||
|
||||
const AGENT_NAMES: &str = include_str!("../agent_names.txt");
|
||||
@@ -247,7 +249,7 @@ impl AgentControl {
|
||||
|
||||
pub(crate) async fn ensure_v2_agent_loaded(
|
||||
&self,
|
||||
config: Config,
|
||||
mut config: Config,
|
||||
thread_id: ThreadId,
|
||||
) -> CodexResult<()> {
|
||||
let state = self.upgrade()?;
|
||||
@@ -279,13 +281,49 @@ impl AgentControl {
|
||||
if initial_history.get_multi_agent_version() != Some(MultiAgentVersion::V2) {
|
||||
return Err(CodexErr::ThreadNotFound(thread_id));
|
||||
}
|
||||
let (session_source, _) = initial_history
|
||||
.get_resumed_session_sources()
|
||||
.unwrap_or((stored_source, None));
|
||||
if let Some(role_name) = session_source.get_agent_role() {
|
||||
let runtime_approval_policy = config.permissions.approval_policy.value();
|
||||
let runtime_approvals_reviewer = config.approvals_reviewer;
|
||||
let runtime_cwd = config.cwd.clone();
|
||||
let runtime_permission_profile = match config.permissions.active_permission_profile() {
|
||||
Some(active_permission_profile) => {
|
||||
PermissionProfileSnapshot::active_with_profile_workspace_roots(
|
||||
config.permissions.permission_profile().clone(),
|
||||
active_permission_profile,
|
||||
config.permissions.profile_workspace_roots().to_vec(),
|
||||
)
|
||||
}
|
||||
None => PermissionProfileSnapshot::legacy(
|
||||
config.permissions.permission_profile().clone(),
|
||||
),
|
||||
};
|
||||
|
||||
apply_role_to_config(&mut config, Some(&role_name))
|
||||
.await
|
||||
.map_err(CodexErr::InvalidRequest)?;
|
||||
config
|
||||
.permissions
|
||||
.approval_policy
|
||||
.set(runtime_approval_policy)
|
||||
.map_err(|err| {
|
||||
CodexErr::InvalidRequest(format!("approval_policy is invalid: {err}"))
|
||||
})?;
|
||||
config.approvals_reviewer = runtime_approvals_reviewer;
|
||||
config.cwd = runtime_cwd;
|
||||
config
|
||||
.permissions
|
||||
.set_permission_profile_from_session_snapshot(runtime_permission_profile)
|
||||
.map_err(|err| {
|
||||
CodexErr::InvalidRequest(format!("permission_profile is invalid: {err}"))
|
||||
})?;
|
||||
}
|
||||
let residency_slot = self
|
||||
.reserve_v2_residency_slot(&state, &config, Some(thread_id))
|
||||
.await?;
|
||||
|
||||
let (session_source, _) = initial_history
|
||||
.get_resumed_session_sources()
|
||||
.unwrap_or((stored_source, None));
|
||||
let parent_thread_id = initial_history
|
||||
.get_resumed_parent_thread_id()
|
||||
.or(stored_parent_thread_id);
|
||||
|
||||
Reference in New Issue
Block a user