mirror of
https://github.com/openai/codex.git
synced 2026-11-02 00:18:52 +00:00
feat: add post-compaction sub-agent infos (#12774)
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -14,6 +14,7 @@ pub(crate) struct EnvironmentContext {
|
||||
pub cwd: Option<PathBuf>,
|
||||
pub shell: Shell,
|
||||
pub network: Option<NetworkContext>,
|
||||
pub subagents: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||
@@ -23,11 +24,17 @@ pub(crate) struct NetworkContext {
|
||||
}
|
||||
|
||||
impl EnvironmentContext {
|
||||
pub fn new(cwd: Option<PathBuf>, shell: Shell, network: Option<NetworkContext>) -> Self {
|
||||
pub fn new(
|
||||
cwd: Option<PathBuf>,
|
||||
shell: Shell,
|
||||
network: Option<NetworkContext>,
|
||||
subagents: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
cwd,
|
||||
shell,
|
||||
network,
|
||||
subagents,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +45,10 @@ impl EnvironmentContext {
|
||||
let EnvironmentContext {
|
||||
cwd,
|
||||
network,
|
||||
subagents,
|
||||
shell: _,
|
||||
} = other;
|
||||
self.cwd == *cwd && self.network == *network
|
||||
self.cwd == *cwd && self.network == *network && self.subagents == *subagents
|
||||
}
|
||||
|
||||
pub fn diff_from_turn_context_item(
|
||||
@@ -60,7 +68,7 @@ impl EnvironmentContext {
|
||||
} else {
|
||||
before_network
|
||||
};
|
||||
EnvironmentContext::new(cwd, shell.clone(), network)
|
||||
EnvironmentContext::new(cwd, shell.clone(), network, None)
|
||||
}
|
||||
|
||||
pub fn from_turn_context(turn_context: &TurnContext, shell: &Shell) -> Self {
|
||||
@@ -68,6 +76,7 @@ impl EnvironmentContext {
|
||||
Some(turn_context.cwd.clone()),
|
||||
shell.clone(),
|
||||
Self::network_from_turn_context(turn_context),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -76,9 +85,17 @@ impl EnvironmentContext {
|
||||
Some(turn_context_item.cwd.clone()),
|
||||
shell.clone(),
|
||||
Self::network_from_turn_context_item(turn_context_item),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn with_subagents(mut self, subagents: String) -> Self {
|
||||
if !subagents.is_empty() {
|
||||
self.subagents = Some(subagents);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn network_from_turn_context(turn_context: &TurnContext) -> Option<NetworkContext> {
|
||||
let network = turn_context
|
||||
.config
|
||||
@@ -142,6 +159,11 @@ impl EnvironmentContext {
|
||||
// lines.push(" <network enabled=\"false\" />".to_string());
|
||||
}
|
||||
}
|
||||
if let Some(subagents) = self.subagents {
|
||||
lines.push(" <subagents>".to_string());
|
||||
lines.extend(subagents.lines().map(|line| format!(" {line}")));
|
||||
lines.push(" </subagents>".to_string());
|
||||
}
|
||||
ENVIRONMENT_CONTEXT_FRAGMENT.wrap(lines.join("\n"))
|
||||
}
|
||||
}
|
||||
@@ -171,7 +193,7 @@ mod tests {
|
||||
#[test]
|
||||
fn serialize_workspace_write_environment_context() {
|
||||
let cwd = test_path_buf("/repo");
|
||||
let context = EnvironmentContext::new(Some(cwd.clone()), fake_shell(), None);
|
||||
let context = EnvironmentContext::new(Some(cwd.clone()), fake_shell(), None, None);
|
||||
|
||||
let expected = format!(
|
||||
r#"<environment_context>
|
||||
@@ -190,8 +212,12 @@ mod tests {
|
||||
allowed_domains: vec!["api.example.com".to_string(), "*.openai.com".to_string()],
|
||||
denied_domains: vec!["blocked.example.com".to_string()],
|
||||
};
|
||||
let context =
|
||||
EnvironmentContext::new(Some(test_path_buf("/repo")), fake_shell(), Some(network));
|
||||
let context = EnvironmentContext::new(
|
||||
Some(test_path_buf("/repo")),
|
||||
fake_shell(),
|
||||
Some(network),
|
||||
None,
|
||||
);
|
||||
|
||||
let expected = format!(
|
||||
r#"<environment_context>
|
||||
@@ -211,7 +237,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn serialize_read_only_environment_context() {
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None);
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None, None);
|
||||
|
||||
let expected = r#"<environment_context>
|
||||
<shell>bash</shell>
|
||||
@@ -222,7 +248,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn serialize_external_sandbox_environment_context() {
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None);
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None, None);
|
||||
|
||||
let expected = r#"<environment_context>
|
||||
<shell>bash</shell>
|
||||
@@ -233,7 +259,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn serialize_external_sandbox_with_restricted_network_environment_context() {
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None);
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None, None);
|
||||
|
||||
let expected = r#"<environment_context>
|
||||
<shell>bash</shell>
|
||||
@@ -244,7 +270,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn serialize_full_access_environment_context() {
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None);
|
||||
let context = EnvironmentContext::new(None, fake_shell(), None, None);
|
||||
|
||||
let expected = r#"<environment_context>
|
||||
<shell>bash</shell>
|
||||
@@ -255,23 +281,29 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn equals_except_shell_compares_cwd() {
|
||||
let context1 = EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None);
|
||||
let context2 = EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None);
|
||||
let context1 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None, None);
|
||||
let context2 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None, None);
|
||||
assert!(context1.equals_except_shell(&context2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equals_except_shell_ignores_sandbox_policy() {
|
||||
let context1 = EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None);
|
||||
let context2 = EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None);
|
||||
let context1 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None, None);
|
||||
let context2 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo")), fake_shell(), None, None);
|
||||
|
||||
assert!(context1.equals_except_shell(&context2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equals_except_shell_compares_cwd_differences() {
|
||||
let context1 = EnvironmentContext::new(Some(PathBuf::from("/repo1")), fake_shell(), None);
|
||||
let context2 = EnvironmentContext::new(Some(PathBuf::from("/repo2")), fake_shell(), None);
|
||||
let context1 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo1")), fake_shell(), None, None);
|
||||
let context2 =
|
||||
EnvironmentContext::new(Some(PathBuf::from("/repo2")), fake_shell(), None, None);
|
||||
|
||||
assert!(!context1.equals_except_shell(&context2));
|
||||
}
|
||||
@@ -286,6 +318,7 @@ mod tests {
|
||||
shell_snapshot: crate::shell::empty_shell_snapshot_receiver(),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let context2 = EnvironmentContext::new(
|
||||
Some(PathBuf::from("/repo")),
|
||||
@@ -295,8 +328,33 @@ mod tests {
|
||||
shell_snapshot: crate::shell::empty_shell_snapshot_receiver(),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(context1.equals_except_shell(&context2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_environment_context_with_subagents() {
|
||||
let context = EnvironmentContext::new(
|
||||
Some(test_path_buf("/repo")),
|
||||
fake_shell(),
|
||||
None,
|
||||
Some("- agent-1: atlas\n- agent-2".to_string()),
|
||||
);
|
||||
|
||||
let expected = format!(
|
||||
r#"<environment_context>
|
||||
<cwd>{}</cwd>
|
||||
<shell>bash</shell>
|
||||
<subagents>
|
||||
- agent-1: atlas
|
||||
- agent-2
|
||||
</subagents>
|
||||
</environment_context>"#,
|
||||
test_path_buf("/repo").display()
|
||||
);
|
||||
|
||||
assert_eq!(context.serialize_to_xml(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user