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

@@ -1,6 +1,7 @@
use crate::Feature;
use crate::FeatureConfigSource;
use crate::FeatureOverrides;
use crate::FeatureToml;
use crate::Features;
use crate::FeaturesToml;
use crate::Stage;
@@ -211,12 +212,14 @@ fn from_sources_applies_base_profile_and_overrides() {
base_entries.insert("plugins".to_string(), true);
let base_features = FeaturesToml {
entries: base_entries,
..Default::default()
};
let mut profile_entries = BTreeMap::new();
profile_entries.insert("code_mode_only".to_string(), true);
let profile_features = FeaturesToml {
entries: profile_entries,
..Default::default()
};
let features = Features::from_sources(
@@ -242,6 +245,81 @@ fn from_sources_applies_base_profile_and_overrides() {
assert_eq!(features.enabled(Feature::WebSearchRequest), false);
}
#[test]
fn multi_agent_v2_feature_config_deserializes_boolean_toggle() {
let features: FeaturesToml = toml::from_str(
r#"
multi_agent_v2 = true
"#,
)
.expect("features table should deserialize");
assert_eq!(
features.entries(),
BTreeMap::from([("multi_agent_v2".to_string(), true)])
);
assert_eq!(features.multi_agent_v2, Some(FeatureToml::Enabled(true)));
}
#[test]
fn multi_agent_v2_feature_config_deserializes_table() {
let features: FeaturesToml = toml::from_str(
r#"
[multi_agent_v2]
enabled = true
usage_hint_enabled = false
usage_hint_text = "Custom delegation guidance."
hide_spawn_agent_metadata = true
"#,
)
.expect("features table should deserialize");
assert_eq!(
features.entries(),
BTreeMap::from([("multi_agent_v2".to_string(), true)])
);
assert_eq!(
features.multi_agent_v2,
Some(crate::FeatureToml::Config(crate::MultiAgentV2ConfigToml {
enabled: Some(true),
usage_hint_enabled: Some(false),
usage_hint_text: Some("Custom delegation guidance.".to_string()),
hide_spawn_agent_metadata: Some(true),
}))
);
}
#[test]
fn multi_agent_v2_feature_config_usage_hint_enabled_does_not_enable_feature() {
let features_toml: FeaturesToml = toml::from_str(
r#"
[multi_agent_v2]
usage_hint_enabled = false
"#,
)
.expect("features table should deserialize");
let features = Features::from_sources(
FeatureConfigSource {
features: Some(&features_toml),
..Default::default()
},
FeatureConfigSource::default(),
FeatureOverrides::default(),
);
assert_eq!(features.enabled(Feature::MultiAgentV2), false);
assert_eq!(features_toml.entries(), BTreeMap::new());
assert_eq!(
features_toml.multi_agent_v2,
Some(crate::FeatureToml::Config(crate::MultiAgentV2ConfigToml {
enabled: None,
usage_hint_enabled: Some(false),
usage_hint_text: None,
hide_spawn_agent_metadata: None,
}))
);
}
#[test]
fn unstable_warning_event_only_mentions_enabled_under_development_features() {
let mut configured_features = Table::new();