diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index 3349a37e7c..1837b8ed6b 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -12893,8 +12893,11 @@ max_concurrent_threads_per_session = 17 assert!(usage_hints.root.is_none() && usage_hints.subagent.is_none()); } -#[test] -fn multi_agent_v2_model_override_exposure_preserves_configured_usage_hints() { +#[test_case::test_case(false; "native_tools")] +#[test_case::test_case(true; "native_tools_disabled")] +fn multi_agent_v2_model_override_exposure_preserves_configured_usage_hints( + disable_native_tools: bool, +) { let config_toml = toml::from_str( r###"[features.multi_agent_v2] enabled = true @@ -12905,7 +12908,8 @@ expose_spawn_agent_model_overrides = true ) .expect("multi-agent v2 config should parse"); - let config = resolve_multi_agent_v2_config(&config_toml); + let mut config = resolve_multi_agent_v2_config(&config_toml); + config.disable_native_tools = disable_native_tools; assert!(config.expose_spawn_agent_model_overrides); assert_eq!( config.root_agent_usage_hint_text.as_deref(), @@ -12933,6 +12937,23 @@ expose_spawn_agent_model_overrides = true ); } +#[test] +fn multi_agent_v2_disabled_native_tools_omit_default_roles() { + let mut config = resolve_multi_agent_v2_config(&ConfigToml::default()); + config.disable_native_tools = true; + let mut messages = ResolvedModelMessages::bundled().multi_agent(); + for catalog_override in [false, true] { + if catalog_override { + messages.root = ResolvedMessage::Catalog("Catalog root base."); + messages.subagent = ResolvedMessage::Catalog("Catalog subagent base."); + } + let usage_hints = resolve_usage_hints( + &config, messages, /*omit_update_plan_instructions*/ false, + ); + assert_eq!((usage_hints.root, usage_hints.subagent), (None, None)); + } +} + #[test] fn multi_agent_v2_exposes_model_overrides_by_default() { let config_toml = diff --git a/codex-rs/core/src/session/multi_agents.rs b/codex-rs/core/src/session/multi_agents.rs index 9cec8ae35a..02b15e6421 100644 --- a/codex-rs/core/src/session/multi_agents.rs +++ b/codex-rs/core/src/session/multi_agents.rs @@ -52,6 +52,9 @@ pub(crate) fn resolve_usage_hints( if base.is_empty() { return None; } + if config.disable_native_tools { + return None; + } Some(MultiAgentRoleInstructions::Composed { base: base.to_owned(), marked: message.catalog_override().is_some(), diff --git a/codex-rs/core/tests/suite/scenarios.rs b/codex-rs/core/tests/suite/scenarios.rs index 94458eef49..57f8d92265 100644 --- a/codex-rs/core/tests/suite/scenarios.rs +++ b/codex-rs/core/tests/suite/scenarios.rs @@ -2215,7 +2215,7 @@ async fn multi_agent_catalog_parameters(disable_native_tools: bool) -> Result<() let (name, description) = if disable_native_tools { ( "multi_agent_native_tools_hidden", - "Native tools are unavailable while the V2 runtime and its instructions remain enabled.", + "Native tools and native usage guidance are unavailable.", ) } else { ( diff --git a/codex-rs/core/tests/suite/scenarios_reserved_spawn.rs b/codex-rs/core/tests/suite/scenarios_reserved_spawn.rs index 5e2a1125ba..488312e58d 100644 --- a/codex-rs/core/tests/suite/scenarios_reserved_spawn.rs +++ b/codex-rs/core/tests/suite/scenarios_reserved_spawn.rs @@ -300,6 +300,7 @@ async fn same_manager_creation_preserves_live_bindings_and_attachments( )); let child_request = child_request.single_request(); assert!(child_request.body_contains_text(UPDATED_RULE)); + assert!(!child_request.body_contains_text("only as direct tool calls")); assert_eq!( child_request.body_contains_text(parent_message), fork_history diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__scenarios__multi_agent_native_tools_hidden.snap b/codex-rs/core/tests/suite/snapshots/all__suite__scenarios__multi_agent_native_tools_hidden.snap index 66820c3e51..968c8f1729 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__scenarios__multi_agent_native_tools_hidden.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__scenarios__multi_agent_native_tools_hidden.snap @@ -2,7 +2,7 @@ source: core/tests/suite/scenarios.rs expression: "context_snapshot::format_request_history_snapshot(description,\n&mock.requests(),\n&ContextSnapshotOptions::default().include_request_settings(),)" --- -Scenario: Native tools are unavailable while the V2 runtime and its instructions remain enabled. +Scenario: Native tools and native usage guidance are unavailable. ## Window 1 Settings: @@ -64,26 +64,8 @@ Settings: Never use the `request_user_input` tool for permission requests or permission-related escalations. 03:message/developer: - You are `/root`, the primary agent in a team of agents collaborating to fulfill the user's goals. - - At the start of your turn, you are the active agent. - You can spawn sub-agents to handle subtasks, and those sub-agents can spawn their own sub-agents. - All agents in the team, including the agents that you can assign tasks to, are equally intelligent and capable, and have access to the same set of tools. - - You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task an...message to a running agent without triggering a turn. [hash=7d40ff8b58977202] - `send_message` calls may be read by a human, so ensure they are legible. Always put proper spaces between words and/or numbers. - - - All agents use the same current working directory. - - As a result, edits made by one agent are immediately visible to all other agents. - - When calling `wait_agent`, prefer longer waits (minutes) to avoid busy polling. - - There are 4 available concurrency slots, meaning that up to 4 agents can be active at once, including you. - - Full-history forks (`fork_turns` omitted or `"all"`) inherit the parent model and reasoning effort and d... so, set `fork_turns` to `"none"`. [hash=d5928243dc643bcc] -04:message/developer: Any earlier instruction enabling proactive multi-agent delegation no longer applies. D...elegation, or parallel agent work. [hash=2b6e037067b4390c] -05:message/user: +04:message/user: @@ -91,9 +73,9 @@ Settings: <...e="unrestricted" /> [hash=d40b2f45cb028888] -06:message/user: +05:message/user: Check which agents are working under /root before delegating more work. -07:configuration_update:reasoning={"effort":"low"} +06:configuration_update:reasoning={"effort":"low"} -- request 2 (turn) -- -08:function_call/collaboration.list_agents:{"path_prefix":"/root"} -09:function_call_output:unsupported call: collaborationlist_agents +07:function_call/collaboration.list_agents:{"path_prefix":"/root"} +08:function_call_output:unsupported call: collaborationlist_agents