mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
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:
committed by
GitHub
Unverified
parent
2250fdd54a
commit
4c07dd4d25
@@ -964,6 +964,9 @@ impl TurnContext {
|
||||
.with_web_search_config(self.tools_config.web_search_config.clone())
|
||||
.with_allow_login_shell(self.tools_config.allow_login_shell)
|
||||
.with_has_environment(self.tools_config.has_environment)
|
||||
.with_spawn_agent_usage_hint(config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
));
|
||||
@@ -1488,6 +1491,9 @@ impl Session {
|
||||
.with_web_search_config(per_turn_config.web_search_config.clone())
|
||||
.with_allow_login_shell(per_turn_config.permissions.allow_login_shell)
|
||||
.with_has_environment(environment.is_some())
|
||||
.with_spawn_agent_usage_hint(per_turn_config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(per_turn_config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(per_turn_config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&per_turn_config.agent_roles,
|
||||
));
|
||||
@@ -5676,6 +5682,9 @@ async fn spawn_review_thread(
|
||||
.with_web_search_config(/*web_search_config*/ None)
|
||||
.with_allow_login_shell(config.permissions.allow_login_shell)
|
||||
.with_has_environment(parent_turn_context.environment.is_some())
|
||||
.with_spawn_agent_usage_hint(config.multi_agent_v2.usage_hint_enabled)
|
||||
.with_spawn_agent_usage_hint_text(config.multi_agent_v2.usage_hint_text.clone())
|
||||
.with_hide_spawn_agent_metadata(config.multi_agent_v2.hide_spawn_agent_metadata)
|
||||
.with_agent_type_description(crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
));
|
||||
|
||||
@@ -1746,7 +1746,7 @@ fn feature_table_overrides_legacy_flags() -> std::io::Result<()> {
|
||||
let mut entries = BTreeMap::new();
|
||||
entries.insert("apply_patch_freeform".to_string(), false);
|
||||
let cfg = ConfigToml {
|
||||
features: Some(FeaturesToml { entries }),
|
||||
features: Some(FeaturesToml::from(entries)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -1794,7 +1794,7 @@ fn responses_websocket_features_do_not_change_wire_api() -> std::io::Result<()>
|
||||
let mut entries = BTreeMap::new();
|
||||
entries.insert(feature_key.to_string(), true);
|
||||
let cfg = ConfigToml {
|
||||
features: Some(FeaturesToml { entries }),
|
||||
features: Some(FeaturesToml::from(entries)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -3005,14 +3005,14 @@ async fn set_feature_enabled_updates_profile() -> anyhow::Result<()> {
|
||||
profile
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
Some(&true),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
Some(true),
|
||||
);
|
||||
assert_eq!(
|
||||
parsed
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
None,
|
||||
);
|
||||
|
||||
@@ -3047,14 +3047,14 @@ async fn set_feature_enabled_persists_default_false_feature_disable_in_profile()
|
||||
profile
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
Some(&false),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
Some(false),
|
||||
);
|
||||
assert_eq!(
|
||||
parsed
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
None,
|
||||
);
|
||||
|
||||
@@ -3087,15 +3087,15 @@ async fn set_feature_enabled_profile_disable_overrides_root_enable() -> anyhow::
|
||||
parsed
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
Some(&true),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
Some(true),
|
||||
);
|
||||
assert_eq!(
|
||||
profile
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.entries.get("guardian_approval")),
|
||||
Some(&false),
|
||||
.and_then(|features| features.entries().get("guardian_approval").copied()),
|
||||
Some(false),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@@ -4520,6 +4520,7 @@ fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
|
||||
use_experimental_unified_exec_tool: !cfg!(windows),
|
||||
background_terminal_max_timeout: DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS,
|
||||
ghost_snapshot: GhostSnapshotConfig::default(),
|
||||
multi_agent_v2: MultiAgentV2Config::default(),
|
||||
features: Features::with_defaults().into(),
|
||||
suppress_unstable_features_warning: false,
|
||||
active_profile: Some("o3".to_string()),
|
||||
@@ -4665,6 +4666,7 @@ fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
|
||||
use_experimental_unified_exec_tool: !cfg!(windows),
|
||||
background_terminal_max_timeout: DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS,
|
||||
ghost_snapshot: GhostSnapshotConfig::default(),
|
||||
multi_agent_v2: MultiAgentV2Config::default(),
|
||||
features: Features::with_defaults().into(),
|
||||
suppress_unstable_features_warning: false,
|
||||
active_profile: Some("gpt3".to_string()),
|
||||
@@ -4808,6 +4810,7 @@ fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
|
||||
use_experimental_unified_exec_tool: !cfg!(windows),
|
||||
background_terminal_max_timeout: DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS,
|
||||
ghost_snapshot: GhostSnapshotConfig::default(),
|
||||
multi_agent_v2: MultiAgentV2Config::default(),
|
||||
features: Features::with_defaults().into(),
|
||||
suppress_unstable_features_warning: false,
|
||||
active_profile: Some("zdr".to_string()),
|
||||
@@ -4937,6 +4940,7 @@ fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
|
||||
use_experimental_unified_exec_tool: !cfg!(windows),
|
||||
background_terminal_max_timeout: DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS,
|
||||
ghost_snapshot: GhostSnapshotConfig::default(),
|
||||
multi_agent_v2: MultiAgentV2Config::default(),
|
||||
features: Features::with_defaults().into(),
|
||||
suppress_unstable_features_warning: false,
|
||||
active_profile: Some("gpt5".to_string()),
|
||||
@@ -6096,6 +6100,71 @@ smart_approvals = true
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn multi_agent_v2_config_from_feature_table() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
std::fs::write(
|
||||
codex_home.path().join(CONFIG_TOML_FILE),
|
||||
r#"[features.multi_agent_v2]
|
||||
enabled = true
|
||||
usage_hint_enabled = false
|
||||
usage_hint_text = "Custom delegation guidance."
|
||||
hide_spawn_agent_metadata = true
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let config = ConfigBuilder::without_managed_config_for_tests()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
assert!(config.features.enabled(Feature::MultiAgentV2));
|
||||
assert!(!config.multi_agent_v2.usage_hint_enabled);
|
||||
assert_eq!(
|
||||
config.multi_agent_v2.usage_hint_text.as_deref(),
|
||||
Some("Custom delegation guidance.")
|
||||
);
|
||||
assert!(config.multi_agent_v2.hide_spawn_agent_metadata);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn profile_multi_agent_v2_config_overrides_base() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
std::fs::write(
|
||||
codex_home.path().join(CONFIG_TOML_FILE),
|
||||
r#"profile = "no_hint"
|
||||
|
||||
[features.multi_agent_v2]
|
||||
usage_hint_enabled = true
|
||||
usage_hint_text = "base hint"
|
||||
hide_spawn_agent_metadata = true
|
||||
|
||||
[profiles.no_hint.features.multi_agent_v2]
|
||||
usage_hint_enabled = false
|
||||
usage_hint_text = "profile hint"
|
||||
hide_spawn_agent_metadata = false
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let config = ConfigBuilder::without_managed_config_for_tests()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
assert!(!config.multi_agent_v2.usage_hint_enabled);
|
||||
assert_eq!(
|
||||
config.multi_agent_v2.usage_hint_text.as_deref(),
|
||||
Some("profile hint")
|
||||
);
|
||||
assert!(!config.multi_agent_v2.hide_spawn_agent_metadata);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn feature_requirements_normalize_runtime_feature_mutations() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
@@ -202,9 +202,9 @@ fn explicit_feature_settings_in_config(cfg: &ConfigToml) -> Vec<(String, Feature
|
||||
let mut explicit_settings = Vec::new();
|
||||
|
||||
if let Some(features) = cfg.features.as_ref() {
|
||||
for (key, enabled) in &features.entries {
|
||||
if let Some(feature) = feature_for_key(key) {
|
||||
explicit_settings.push((format!("features.{key}"), feature, *enabled));
|
||||
for (key, enabled) in features.entries() {
|
||||
if let Some(feature) = feature_for_key(&key) {
|
||||
explicit_settings.push((format!("features.{key}"), feature, enabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,12 +224,12 @@ fn explicit_feature_settings_in_config(cfg: &ConfigToml) -> Vec<(String, Feature
|
||||
}
|
||||
for (profile_name, profile) in &cfg.profiles {
|
||||
if let Some(features) = profile.features.as_ref() {
|
||||
for (key, enabled) in &features.entries {
|
||||
if let Some(feature) = feature_for_key(key) {
|
||||
for (key, enabled) in features.entries() {
|
||||
if let Some(feature) = feature_for_key(&key) {
|
||||
explicit_settings.push((
|
||||
format!("profiles.{profile_name}.features.{key}"),
|
||||
feature,
|
||||
*enabled,
|
||||
enabled,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::agent::control::render_input_preview;
|
||||
use crate::agent::next_thread_spawn_depth;
|
||||
use crate::agent::role::DEFAULT_ROLE_NAME;
|
||||
use crate::agent::role::apply_role_to_config;
|
||||
use codex_features::Feature;
|
||||
use codex_protocol::AgentPath;
|
||||
use codex_protocol::models::DeveloperInstructions;
|
||||
use codex_protocol::protocol::InterAgentCommunication;
|
||||
@@ -207,10 +206,7 @@ impl ToolHandler for Handler {
|
||||
)
|
||||
})?;
|
||||
|
||||
let hide_agent_metadata = turn
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::DebugHideSpawnAgentMetadata);
|
||||
let hide_agent_metadata = turn.config.multi_agent_v2.hide_spawn_agent_metadata;
|
||||
if hide_agent_metadata {
|
||||
Ok(SpawnAgentResult::HiddenMetadata { task_name })
|
||||
} else {
|
||||
|
||||
@@ -32,6 +32,7 @@ use codex_tools::ZshForkConfig;
|
||||
use codex_tools::mcp_call_tool_result_output_schema;
|
||||
use codex_tools::mcp_tool_to_deferred_responses_api_tool;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use core_test_support::assert_regex_match;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
@@ -158,6 +159,39 @@ fn find_tool<'a>(tools: &'a [ConfiguredToolSpec], expected_name: &str) -> &'a Co
|
||||
.unwrap_or_else(|| panic!("expected tool {expected_name}"))
|
||||
}
|
||||
|
||||
fn multi_agent_v2_tools_config() -> ToolsConfig {
|
||||
let config = test_config();
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Collab);
|
||||
features.enable(Feature::MultiAgentV2);
|
||||
let available_models = Vec::new();
|
||||
ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
available_models: &available_models,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
session_source: SessionSource::Cli,
|
||||
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
||||
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
||||
})
|
||||
}
|
||||
|
||||
fn multi_agent_v2_spawn_agent_description(tools_config: &ToolsConfig) -> String {
|
||||
let (tools, _) = build_specs(
|
||||
tools_config,
|
||||
/*mcp_tools*/ None,
|
||||
/*app_tools*/ None,
|
||||
&[],
|
||||
)
|
||||
.build();
|
||||
let spawn_agent = find_tool(&tools, "spawn_agent");
|
||||
let ToolSpec::Function(ResponsesApiTool { description, .. }) = &spawn_agent.spec else {
|
||||
panic!("spawn_agent should be a function tool");
|
||||
};
|
||||
description.clone()
|
||||
}
|
||||
|
||||
fn model_info_from_models_json(slug: &str) -> ModelInfo {
|
||||
let config = test_config();
|
||||
let response = bundled_models_response()
|
||||
@@ -599,6 +633,44 @@ fn shell_zsh_fork_prefers_shell_command_over_unified_exec() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_description_omits_usage_hint_when_disabled() {
|
||||
let tools_config = multi_agent_v2_tools_config()
|
||||
.with_spawn_agent_usage_hint(/*spawn_agent_usage_hint*/ false);
|
||||
let description = multi_agent_v2_spawn_agent_description(&tools_config);
|
||||
|
||||
assert_regex_match(
|
||||
r#"(?sx)
|
||||
^\s*
|
||||
No\ picker-visible\ models\ are\ currently\ loaded\.
|
||||
\s+Spawn\ a\ sub-agent\ for\ a\ well-scoped\ task\.
|
||||
\s+Returns\ the\ canonical\ task\ name\ for\ the\ spawned\ agent,\ plus\ the\ user-facing\ nickname\ when\ available\.
|
||||
\s*$
|
||||
"#,
|
||||
&description,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_description_uses_configured_usage_hint_text() {
|
||||
let tools_config = multi_agent_v2_tools_config().with_spawn_agent_usage_hint_text(Some(
|
||||
/*spawn_agent_usage_hint_text*/ "Custom delegation guidance only.".to_string(),
|
||||
));
|
||||
let description = multi_agent_v2_spawn_agent_description(&tools_config);
|
||||
|
||||
assert_regex_match(
|
||||
r#"(?sx)
|
||||
^\s*
|
||||
No\ picker-visible\ models\ are\ currently\ loaded\.
|
||||
\s+Spawn\ a\ sub-agent\ for\ a\ well-scoped\ task\.
|
||||
\s+Returns\ the\ canonical\ task\ name\ for\ the\ spawned\ agent,\ plus\ the\ user-facing\ nickname\ when\ available\.
|
||||
\s+Custom\ delegation\ guidance\ only\.
|
||||
\s*$
|
||||
"#,
|
||||
&description,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tool_suggest_requires_apps_and_plugins_features() {
|
||||
let model_info = search_capable_model_info();
|
||||
|
||||
@@ -89,7 +89,7 @@ pub fn resolve_windows_sandbox_private_desktop(cfg: &ConfigToml, profile: &Confi
|
||||
}
|
||||
|
||||
fn legacy_windows_sandbox_keys_present(features: Option<&FeaturesToml>) -> bool {
|
||||
let Some(entries) = features.map(|features| &features.entries) else {
|
||||
let Some(entries) = features.map(FeaturesToml::entries) else {
|
||||
return false;
|
||||
};
|
||||
entries.contains_key(Feature::WindowsSandboxElevated.key())
|
||||
@@ -100,8 +100,8 @@ fn legacy_windows_sandbox_keys_present(features: Option<&FeaturesToml>) -> bool
|
||||
pub fn legacy_windows_sandbox_mode(
|
||||
features: Option<&FeaturesToml>,
|
||||
) -> Option<WindowsSandboxModeToml> {
|
||||
let entries = features.map(|features| &features.entries)?;
|
||||
legacy_windows_sandbox_mode_from_entries(entries)
|
||||
let entries = features.map(FeaturesToml::entries)?;
|
||||
legacy_windows_sandbox_mode_from_entries(&entries)
|
||||
}
|
||||
|
||||
pub fn legacy_windows_sandbox_mode_from_entries(
|
||||
|
||||
@@ -109,7 +109,7 @@ fn resolve_windows_sandbox_mode_falls_back_to_legacy_keys() {
|
||||
/*value*/ true,
|
||||
);
|
||||
let cfg = ConfigToml {
|
||||
features: Some(FeaturesToml { entries }),
|
||||
features: Some(FeaturesToml::from(entries)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -127,9 +127,7 @@ fn resolve_windows_sandbox_mode_profile_legacy_false_blocks_top_level_legacy_tru
|
||||
/*value*/ false,
|
||||
);
|
||||
let profile = ConfigProfile {
|
||||
features: Some(FeaturesToml {
|
||||
entries: profile_entries,
|
||||
}),
|
||||
features: Some(FeaturesToml::from(profile_entries)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -139,9 +137,7 @@ fn resolve_windows_sandbox_mode_profile_legacy_false_blocks_top_level_legacy_tru
|
||||
/*value*/ true,
|
||||
);
|
||||
let cfg = ConfigToml {
|
||||
features: Some(FeaturesToml {
|
||||
entries: cfg_entries,
|
||||
}),
|
||||
features: Some(FeaturesToml::from(cfg_entries)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user