Skip to content

Keep request_user_input direct-model only - #27316

Merged
shijie-oai merged 4 commits into
mainfrom
shijie/request-user-input-active-goal-suppression
Jun 12, 2026
Merged

Keep request_user_input direct-model only#27316
shijie-oai merged 4 commits into
mainfrom
shijie/request-user-input-active-goal-suppression

Conversation

@shijie-oai

@shijie-oai shijie-oai commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

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.

@shijie-oai shijie-oai Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives extensions ability to disable or enable other tools per turn over time. Here we do two things:

  1. disable the tool for the turn.
  2. if the tool itself is still reachable for some reason, it can emit the unavailability reason to the model.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update - we are no long disabling the tool for the turn. We will rely on the fact that when the tool is not available we will emit an error.

Comment on lines 65 to 68
let mode = session.collaboration_mode().await.mode;
if let Some(message) = request_user_input_unavailable_message(mode, &self.available_modes) {
return Err(FunctionCallError::RespondToModel(message));
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be a separate opportunity for us to clean this up.

Comment thread codex-rs/ext/goal/src/extension.rs Outdated
Comment on lines +226 to +236
if goal.status == codex_state::ThreadGoalStatus::Active
&& input.collaboration_mode.mode == ModeKind::Default
{
input
.turn_store
.get_or_init(ToolAvailability::default)
.mark_unavailable(
ToolName::plain(REQUEST_USER_INPUT_TOOL_NAME),
ACTIVE_GOAL_REQUEST_USER_INPUT_UNAVAILABLE_MESSAGE,
);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the turn level we store the tool unavailability status and the reason.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here is that the request user input tool will not be available if there is a goal objective that is currently in active status.

THE ONLY EXCEPTION (which the inline code comment also mentioned) is that if plan collaboration mode is also enabled then we will have request user input tool. BUT technically when plan mode is enabled we actually never reach this point. We early terminate at line 209.

Comment on lines +15 to +17
pub struct ToolAvailability {
unavailability_reason_by_tool_name: Mutex<HashMap<ToolName, String>>,
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should call this ToolUnavailability? cause we are storing tools that are not available but it just feels weird calling it that way.

@shijie-oai
shijie-oai marked this pull request as ready for review June 10, 2026 07:07
@shijie-oai
shijie-oai requested a review from a team as a code owner June 10, 2026 07:07
@shijie-oai
shijie-oai force-pushed the shijie/request-user-input-active-goal-suppression branch 3 times, most recently from 53afbeb to 07c9996 Compare June 10, 2026 17:07
Comment on lines +92 to +113
async fn request_user_input_unavailability_reason_for_turn(
session: &crate::session::session::Session,
turn: &crate::session::turn_context::TurnContext,
available_modes: &[ModeKind],
) -> Option<String> {
if turn.session_source.is_non_root_agent() {
return Some("request_user_input can only be used by the root thread".to_string());
}

if let Some(unavailability_reason) =
turn.extension_data
.get::<ToolUnavailability>()
.and_then(|unavailability| {
unavailability.unavailability_reason(&ToolName::plain(REQUEST_USER_INPUT_TOOL_NAME))
})
{
return Some(unavailability_reason);
}

let mode = session.collaboration_mode().await.mode;
request_user_input_unavailable_message(mode, available_modes)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better organize tool unavailability reasons.

@shijie-oai
shijie-oai force-pushed the shijie/request-user-input-active-goal-suppression branch from 07c9996 to 3f3c5f0 Compare June 10, 2026 22:26
@shijie-oai shijie-oai changed the title Suppress request_user_input during active Default goals Keep request_user_input direct-model only Jun 10, 2026
shijie-oai added a commit that referenced this pull request Jun 10, 2026
shijie-oai added a commit that referenced this pull request Jun 11, 2026
shijie-oai added a commit that referenced this pull request Jun 11, 2026
@openai openai deleted a comment from hlky Jun 11, 2026
Base automatically changed from shijie/request-user-input-auto-resolution-ms to main June 12, 2026 05:30
@shijie-oai
shijie-oai force-pushed the shijie/request-user-input-active-goal-suppression branch from 77a01d3 to e1ca683 Compare June 12, 2026 05:33
@shijie-oai
shijie-oai merged commit 7a19b14 into main Jun 12, 2026
46 of 47 checks passed
@shijie-oai
shijie-oai deleted the shijie/request-user-input-active-goal-suppression branch June 12, 2026 06:23
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants