mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
feat(core): remove spawn_mode from agent roles
This commit is contained in:
@@ -2527,7 +2527,6 @@ mod tests {
|
||||
prompt: "inspect the repo".into(),
|
||||
model: "gpt-5.4-mini".into(),
|
||||
reasoning_effort: codex_protocol::openai_models::ReasoningEffort::Medium,
|
||||
spawn_mode: codex_protocol::protocol::AgentSpawnMode::Spawn,
|
||||
status: AgentStatus::Running,
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
},
|
||||
"AgentRoleSpawnMode": {
|
||||
"enum": [
|
||||
"spawn",
|
||||
"fork"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentRoleToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -43,14 +36,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"spawn_mode": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentRoleSpawnMode"
|
||||
}
|
||||
],
|
||||
"description": "Optional default spawn mode when `spawn_agent` omits `spawn_mode`."
|
||||
},
|
||||
"watchdog_interval_s": {
|
||||
"description": "Optional watchdog interval in seconds for roles that should behave as watchdogs.",
|
||||
"format": "int64",
|
||||
@@ -2625,4 +2610,4 @@
|
||||
},
|
||||
"title": "ConfigToml",
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# You are the Root Agent
|
||||
|
||||
You are the **root agent** in a multi-agent Codex session. Until you see `# You are a Subagent`, these instructions define your role. If this thread was created from the root thread with `spawn_mode = "fork"` (a forked child), you may see both sets of instructions; apply subagent instructions as local role guidance while root instructions remain governing system-level rules.
|
||||
You are the **root agent** in a multi-agent Codex session. Until you see `# You are a Subagent`, these instructions define your role. If this thread was created from the root thread with `fork_context = true` (a forked child), you may see both sets of instructions; apply subagent instructions as local role guidance while root instructions remain governing system-level rules.
|
||||
|
||||
## Root Agent Responsibilities
|
||||
|
||||
@@ -36,23 +36,23 @@ Create a subagent and give it an initial task.
|
||||
Parameters:
|
||||
- `message` (required): the task description.
|
||||
- `agent_type` (optional): the role to assign (`default`, `explorer`, `fast-worker`, or `worker`).
|
||||
- `spawn_mode` (optional): one of `spawn` or `fork`.
|
||||
- `fork_context` (optional): when `true`, the child receives the current thread history.
|
||||
|
||||
Guidance:
|
||||
- When `spawn_mode` is omitted, the default is `fork` unless the selected role overrides it.
|
||||
- When `fork_context` is omitted, the default comes from the selected role and otherwise falls back to `true`.
|
||||
- Use `agent_type = "explorer"` for specific codebase questions; it defaults to context-free `spawn`.
|
||||
- Use `agent_type = "fast-worker"` for tightly constrained execution work that can run from a self-contained prompt; it also defaults to context-free `spawn`.
|
||||
- Use `agent_type = "worker"` for broader implementation work that should inherit current-thread context; it defaults to `fork`.
|
||||
- Choose `fork` vs `spawn` by context requirements first (not by task shape).
|
||||
- Use `spawn_mode = "fork"` when the child should preserve your current conversation history and rely on current-thread context, including:
|
||||
- Choose `fork_context = true` vs `false` by context requirements first (not by task shape).
|
||||
- Use `fork_context = true` when the child should preserve your current conversation history and rely on current-thread context, including:
|
||||
- current debugging-thread relevance (for example, "summarize only failures relevant to this investigation")
|
||||
- active plan / ExecPlan branch continuation
|
||||
- recent user decisions, tradeoffs, or rejected approaches
|
||||
- parallel review work that should inherit the same context automatically
|
||||
- Use `spawn_mode = "spawn"` only when the child can do the task correctly from a fresh prompt you provide now, without needing current-thread context.
|
||||
- For `spawn`, make the task, inputs, and expected output explicit (especially for independent, output-heavy work where you want the child to distill results and keep the root thread context clean).
|
||||
- Needle-in-a-haystack searches are strong `spawn` candidates when the child can search from a precise prompt without current-thread context.
|
||||
- Do not choose `spawn` solely because work is output-heavy or command-heavy if it still depends on current-thread context.
|
||||
- Use `fork_context = false` only when the child can do the task correctly from a fresh prompt you provide now, without needing current-thread context.
|
||||
- For `fork_context = false`, make the task, inputs, and expected output explicit (especially for independent, output-heavy work where you want the child to distill results and keep the root thread context clean).
|
||||
- Needle-in-a-haystack searches are strong `fork_context = false` candidates when the child can search from a precise prompt without current-thread context.
|
||||
- Do not choose `fork_context = false` solely because work is output-heavy or command-heavy if it still depends on current-thread context.
|
||||
|
||||
### 2) `send_input`
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ use crate::agent::role::default_fork_context_for_role;
|
||||
use crate::agent::role::watchdog_interval_for_role;
|
||||
use crate::config::Config;
|
||||
use codex_features::Feature;
|
||||
use codex_protocol::protocol::AgentSpawnMode;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use std::collections::HashSet;
|
||||
|
||||
@@ -198,13 +197,6 @@ impl ToolHandler for Handler {
|
||||
prompt,
|
||||
model: effective_model,
|
||||
reasoning_effort: effective_reasoning_effort,
|
||||
spawn_mode: if is_watchdog {
|
||||
AgentSpawnMode::Watchdog
|
||||
} else if fork_context {
|
||||
AgentSpawnMode::Fork
|
||||
} else {
|
||||
AgentSpawnMode::Spawn
|
||||
},
|
||||
status,
|
||||
}
|
||||
.into(),
|
||||
|
||||
@@ -449,7 +449,7 @@ async fn multi_agent_v2_spawn_fork_context_ignores_child_model_overrides() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_watchdog_role_returns_handle_without_spawn_mode() {
|
||||
async fn spawn_agent_watchdog_role_returns_handle_with_role_defaults() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
session.services.agent_control = manager.agent_control();
|
||||
|
||||
@@ -6,7 +6,6 @@ use crate::agent::role::DEFAULT_ROLE_NAME;
|
||||
use crate::agent::role::apply_role_to_config;
|
||||
use crate::agent::role::default_fork_context_for_role;
|
||||
use codex_protocol::AgentPath;
|
||||
use codex_protocol::protocol::AgentSpawnMode;
|
||||
use codex_protocol::protocol::InterAgentCommunication;
|
||||
use codex_protocol::protocol::Op;
|
||||
|
||||
@@ -178,11 +177,6 @@ impl ToolHandler for Handler {
|
||||
prompt,
|
||||
model: effective_model,
|
||||
reasoning_effort: effective_reasoning_effort,
|
||||
spawn_mode: if fork_context {
|
||||
AgentSpawnMode::Fork
|
||||
} else {
|
||||
AgentSpawnMode::Spawn
|
||||
},
|
||||
status,
|
||||
}
|
||||
.into(),
|
||||
|
||||
@@ -52,7 +52,7 @@ When you detect these, prescribe the corrective action explicitly.
|
||||
|
||||
Use only the multi-agent tools that exist here:
|
||||
|
||||
- `spawn_agent` (prefer `spawn_mode = "fork"` when shared context matters).
|
||||
- `spawn_agent` (prefer `fork_context = true` when shared context matters).
|
||||
- `send_input`.
|
||||
- `compact_parent_context` (watchdog-only recovery tool; see below).
|
||||
- `watchdog_self_close` (watchdog-only immediate exit tool; see below).
|
||||
|
||||
@@ -3420,16 +3420,6 @@ pub struct CollabAgentSpawnBeginEvent {
|
||||
pub reasoning_effort: ReasoningEffortConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum AgentSpawnMode {
|
||||
#[default]
|
||||
Spawn,
|
||||
Fork,
|
||||
Watchdog,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct CollabAgentRef {
|
||||
/// Thread ID of the receiver/new agent.
|
||||
@@ -3477,9 +3467,6 @@ pub struct CollabAgentSpawnEndEvent {
|
||||
pub model: String,
|
||||
/// Effective reasoning effort used by the spawned agent after inheritance and role overrides.
|
||||
pub reasoning_effort: ReasoningEffortConfig,
|
||||
/// Spawn mode used for this agent.
|
||||
#[serde(default)]
|
||||
pub spawn_mode: AgentSpawnMode,
|
||||
/// Last known status of the new agent reported to the sender agent.
|
||||
pub status: AgentStatus,
|
||||
}
|
||||
|
||||
@@ -139,7 +139,6 @@ use codex_protocol::protocol::AgentReasoningEvent;
|
||||
use codex_protocol::protocol::AgentReasoningRawContentDeltaEvent;
|
||||
#[cfg(test)]
|
||||
use codex_protocol::protocol::AgentReasoningRawContentEvent;
|
||||
use codex_protocol::protocol::AgentSpawnMode;
|
||||
use codex_protocol::protocol::AgentStatus;
|
||||
use codex_protocol::protocol::ApplyPatchApprovalRequestEvent;
|
||||
#[cfg(test)]
|
||||
@@ -3666,10 +3665,6 @@ impl ChatWidget {
|
||||
prompt: prompt.unwrap_or_default(),
|
||||
model: String::new(),
|
||||
reasoning_effort: ReasoningEffortConfig::Medium,
|
||||
// Thread history items do not carry spawn_mode yet, so the
|
||||
// replay path must choose an explicit fallback for reconstructed
|
||||
// spawn rows. Plain spawn is the least surprising default.
|
||||
spawn_mode: AgentSpawnMode::Spawn,
|
||||
status: first_receiver
|
||||
.as_ref()
|
||||
.and_then(|thread_id| agents_states.get(&thread_id.to_string()))
|
||||
|
||||
@@ -2341,7 +2341,6 @@ async fn collab_spawn_end_shows_requested_model_and_effort() {
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: "Explore the repo".to_string(),
|
||||
spawn_mode: codex_protocol::protocol::AgentSpawnMode::Spawn,
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
|
||||
@@ -583,7 +583,6 @@ fn status_summary_spans(status: &AgentStatus) -> Vec<Span<'static>> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::history_cell::HistoryCell;
|
||||
use codex_protocol::protocol::AgentSpawnMode;
|
||||
#[cfg(target_os = "macos")]
|
||||
use crossterm::event::KeyEvent;
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -610,7 +609,6 @@ mod tests {
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: "Compute 11! and reply with just the integer result.".to_string(),
|
||||
spawn_mode: AgentSpawnMode::Spawn,
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
@@ -749,7 +747,6 @@ mod tests {
|
||||
new_agent_nickname: Some("Robie".to_string()),
|
||||
new_agent_role: Some("explorer".to_string()),
|
||||
prompt: String::new(),
|
||||
spawn_mode: AgentSpawnMode::Spawn,
|
||||
model: "gpt-5".to_string(),
|
||||
reasoning_effort: ReasoningEffortConfig::High,
|
||||
status: AgentStatus::PendingInit,
|
||||
|
||||
Reference in New Issue
Block a user