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