mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Keep request_user_input direct-model only (#27316)
## Why `request_user_input` has direct blocking semantics when invoked by the model. When it is exposed as a nested code-mode tool, the call has to flow through code-mode waiting and continuation behavior instead, which is not the behavior we want for this user-input request surface. ## What changed - Mark `request_user_input` with `ToolExposure::DirectModelOnly` when registering the core utility tool. - Keep `request_user_input` direct-model visible, including in code-mode-only planning. - Add focused `spec_plan_tests` coverage that verifies `request_user_input` remains visible and registered as direct-model-only, while it is omitted from the nested code-mode tool description. No active goal suppression or runtime unavailability behavior is included in this PR. ## Validation - No new build/test run for this housekeeping pass, per maintainer request. - Earlier targeted run, confirmed from session context: `just test -p codex-core request_user_input` passed.
This commit is contained in:
committed by
GitHub
Unverified
parent
a94deb5fa7
commit
7a19b14229
@@ -643,9 +643,12 @@ fn add_core_utility_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut
|
||||
planned_tools.add(PlanHandler);
|
||||
|
||||
if turn_context.config.experimental_request_user_input_enabled {
|
||||
planned_tools.add(RequestUserInputHandler {
|
||||
available_modes: request_user_input_available_modes(features),
|
||||
});
|
||||
planned_tools.add_with_exposure(
|
||||
RequestUserInputHandler {
|
||||
available_modes: request_user_input_available_modes(features),
|
||||
},
|
||||
ToolExposure::DirectModelOnly,
|
||||
);
|
||||
}
|
||||
|
||||
if features.enabled(Feature::RequestPermissionsTool) {
|
||||
|
||||
@@ -431,6 +431,10 @@ async fn request_user_input_tool_respects_experimental_config_gate() {
|
||||
let enabled = probe(|_| {}).await;
|
||||
enabled.assert_visible_contains(&["request_user_input"]);
|
||||
enabled.assert_registered_contains(&["request_user_input"]);
|
||||
assert_eq!(
|
||||
enabled.exposure("request_user_input"),
|
||||
ToolExposure::DirectModelOnly
|
||||
);
|
||||
|
||||
let disabled = probe(|turn| {
|
||||
update_config(turn, |config| {
|
||||
@@ -442,6 +446,30 @@ async fn request_user_input_tool_respects_experimental_config_gate() {
|
||||
disabled.assert_registered_lacks(&["request_user_input"]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn request_user_input_stays_direct_in_code_mode_only() {
|
||||
let plan = probe(|turn| {
|
||||
set_features(turn, &[Feature::CodeMode, Feature::CodeModeOnly]);
|
||||
})
|
||||
.await;
|
||||
|
||||
plan.assert_visible_contains(&[
|
||||
"request_user_input",
|
||||
codex_code_mode::PUBLIC_TOOL_NAME,
|
||||
codex_code_mode::WAIT_TOOL_NAME,
|
||||
]);
|
||||
plan.assert_registered_contains(&["request_user_input"]);
|
||||
assert_eq!(
|
||||
plan.exposure("request_user_input"),
|
||||
ToolExposure::DirectModelOnly
|
||||
);
|
||||
|
||||
let ToolSpec::Freeform(exec) = plan.visible_spec(codex_code_mode::PUBLIC_TOOL_NAME) else {
|
||||
panic!("expected code mode exec tool");
|
||||
};
|
||||
assert!(!exec.description.contains("request_user_input"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn shell_family_registers_visible_unified_exec_and_hidden_legacy_shell() {
|
||||
let plan = probe(|turn| {
|
||||
@@ -1224,6 +1252,7 @@ async fn code_mode_only_can_expose_namespaced_multi_agent_v2_as_normal_tools() {
|
||||
vec![
|
||||
"exec",
|
||||
"wait",
|
||||
"request_user_input",
|
||||
"agents",
|
||||
// Hosted Responses tools.
|
||||
"web_search",
|
||||
@@ -1309,6 +1338,7 @@ async fn hosted_tools_follow_provider_auth_model_and_config_gates() {
|
||||
// Code-mode entrypoints.
|
||||
codex_code_mode::PUBLIC_TOOL_NAME,
|
||||
codex_code_mode::WAIT_TOOL_NAME,
|
||||
"request_user_input",
|
||||
// Multi-agent v2 tools.
|
||||
"spawn_agent",
|
||||
"send_message",
|
||||
|
||||
@@ -502,6 +502,7 @@ async fn code_mode_only_restricts_prompt_tools() -> Result<()> {
|
||||
vec![
|
||||
"exec".to_string(),
|
||||
"wait".to_string(),
|
||||
"request_user_input".to_string(),
|
||||
"web_search".to_string()
|
||||
]
|
||||
);
|
||||
@@ -588,6 +589,7 @@ if (!tool) {
|
||||
vec![
|
||||
"exec".to_string(),
|
||||
"wait".to_string(),
|
||||
"request_user_input".to_string(),
|
||||
"web_search".to_string(),
|
||||
"image_generation".to_string()
|
||||
]
|
||||
|
||||
@@ -173,6 +173,7 @@ async fn remote_tool_mode_selector_overrides_feature_flags() -> Result<()> {
|
||||
// Code-mode entrypoints.
|
||||
codex_code_mode::PUBLIC_TOOL_NAME.to_string(),
|
||||
codex_code_mode::WAIT_TOOL_NAME.to_string(),
|
||||
"request_user_input".to_string(),
|
||||
// Hosted Responses tools.
|
||||
"web_search".to_string(),
|
||||
"image_generation".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user