Configure multi_agent_v2 spawn agent hints (#17071)

Allow multi_agent_v2 features to have its own temporary configuration
under `[features.multi_agent_v2]`

```
[features.multi_agent_v2]
enabled = true
usage_hint_enabled = false
usage_hint_text = "Custom delegation guidance."
hide_spawn_agent_metadata = true
```

Absent `usage_hint_text` means use the default hint.

```
[features]
multi_agent_v2 = true
```

still works as the boolean shorthand.
This commit is contained in:
pakrym-oai
2026-04-08 08:42:18 -07:00
committed by GitHub
parent 2250fdd54a
commit 4c07dd4d25
18 changed files with 501 additions and 62 deletions

View File

@@ -52,7 +52,10 @@ use codex_config::types::WindowsSandboxModeToml;
use codex_features::Feature;
use codex_features::FeatureConfigSource;
use codex_features::FeatureOverrides;
use codex_features::FeatureToml;
use codex_features::Features;
use codex_features::FeaturesToml;
use codex_features::MultiAgentV2ConfigToml;
use codex_login::AuthManagerConfig;
use codex_mcp::McpConfig;
use codex_model_provider_info::LEGACY_OLLAMA_CHAT_PROVIDER_ID;
@@ -520,6 +523,9 @@ pub struct Config {
/// Settings for ghost snapshots (used for undo).
pub ghost_snapshot: GhostSnapshotConfig,
/// Settings specific to the task-path-based multi-agent tool surface.
pub multi_agent_v2: MultiAgentV2Config,
/// Centralized feature flags; source of truth for feature gating.
pub features: ManagedFeatures,
@@ -564,6 +570,23 @@ pub struct Config {
pub otel: codex_config::types::OtelConfig,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MultiAgentV2Config {
pub usage_hint_enabled: bool,
pub usage_hint_text: Option<String>,
pub hide_spawn_agent_metadata: bool,
}
impl Default for MultiAgentV2Config {
fn default() -> Self {
Self {
usage_hint_enabled: true,
usage_hint_text: None,
hide_spawn_agent_metadata: false,
}
}
}
impl AuthManagerConfig for Config {
fn codex_home(&self) -> PathBuf {
self.codex_home.clone()
@@ -1279,6 +1302,42 @@ fn resolve_web_search_config(
}
}
fn resolve_multi_agent_v2_config(
config_toml: &ConfigToml,
config_profile: &ConfigProfile,
) -> MultiAgentV2Config {
let base = multi_agent_v2_toml_config(config_toml.features.as_ref());
let profile = multi_agent_v2_toml_config(config_profile.features.as_ref());
let default = MultiAgentV2Config::default();
let usage_hint_enabled = profile
.and_then(|config| config.usage_hint_enabled)
.or_else(|| base.and_then(|config| config.usage_hint_enabled))
.unwrap_or(default.usage_hint_enabled);
let usage_hint_text = profile
.and_then(|config| config.usage_hint_text.as_ref())
.or_else(|| base.and_then(|config| config.usage_hint_text.as_ref()))
.cloned()
.or(default.usage_hint_text);
let hide_spawn_agent_metadata = profile
.and_then(|config| config.hide_spawn_agent_metadata)
.or_else(|| base.and_then(|config| config.hide_spawn_agent_metadata))
.unwrap_or(default.hide_spawn_agent_metadata);
MultiAgentV2Config {
usage_hint_enabled,
usage_hint_text,
hide_spawn_agent_metadata,
}
}
fn multi_agent_v2_toml_config(features: Option<&FeaturesToml>) -> Option<&MultiAgentV2ConfigToml> {
match features?.multi_agent_v2.as_ref()? {
FeatureToml::Enabled(_) => None,
FeatureToml::Config(config) => Some(config),
}
}
pub(crate) fn resolve_web_search_mode_for_turn(
web_search_mode: &Constrained<WebSearchMode>,
sandbox_policy: &SandboxPolicy,
@@ -1607,6 +1666,7 @@ impl Config {
let web_search_mode = resolve_web_search_mode(&cfg, &config_profile, &features)
.unwrap_or(WebSearchMode::Cached);
let web_search_config = resolve_web_search_config(&cfg, &config_profile);
let multi_agent_v2 = resolve_multi_agent_v2_config(&cfg, &config_profile);
let agent_roles =
agent_roles::load_agent_roles(&cfg, &config_layer_stack, &mut startup_warnings)?;
@@ -2040,6 +2100,7 @@ impl Config {
use_experimental_unified_exec_tool,
background_terminal_max_timeout,
ghost_snapshot,
multi_agent_v2,
features,
suppress_unstable_features_warning: cfg
.suppress_unstable_features_warning