mirror of
https://github.com/openai/codex.git
synced 2026-11-03 08:22:30 +00:00
Finalize model-specific tool plans in ToolRouter (#41195)
## Why Planning tools for a candidate model must not change the selected model or its Responses Lite tool inventory. Otherwise, preparing a fallback can overwrite metadata before the current model's request is sent. ## What changed - Build tool registries and visible specs from an explicit `ModelInfo`. - Store the finalized tool mode, code-mode names, namespace inventory, and terminal and child-management capabilities on `ToolRouter`. - Publish namespace inventory only after selecting the step's router, and use that router's mode when dispatching and recording tool calls. ## Testing Added coverage for candidate-model isolation, fallback compaction metadata, code-mode worker selection, normalized tool names, and router capabilities. GitOrigin-RevId: 56df2de8f42c7e93a4c4dcd117720e40a0cca3db
This commit is contained in:
1 parent
8aea62b2d8
commit
0182ff3480
13 files changed
+532
-127
No files matched your search
@@ -34,7 +34,6 @@ use crate::tools::ExecutedToolCallRecorder;
|
||||
use crate::tools::context::FunctionToolOutput;
|
||||
use crate::tools::context::SharedTurnDiffTracker;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::effective_tool_mode;
|
||||
use crate::tools::parallel::ToolCallRuntime;
|
||||
use crate::tools::router::ToolCall;
|
||||
use crate::tools::router::ToolCallSource;
|
||||
@@ -205,8 +204,7 @@ impl CodeModeService {
|
||||
tracker: SharedTurnDiffTracker,
|
||||
) -> Option<CodeModeDispatchWorker> {
|
||||
let turn = &step_context.turn;
|
||||
let tool_mode = effective_tool_mode(turn);
|
||||
if !matches!(tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly) {
|
||||
if !step_context.tool_router.requires_code_mode_worker() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -442,14 +440,52 @@ fn build_freeform_tool_payload(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::build_nested_tool_payload;
|
||||
use super::truncate_code_mode_result;
|
||||
use crate::session::step_context::StepContext;
|
||||
use crate::session::tests::make_session_and_context;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::registry::ToolRegistry;
|
||||
use crate::tools::router::ToolRouter;
|
||||
use crate::turn_diff_tracker::TurnDiffTracker;
|
||||
use codex_code_mode::CodeModeToolKind;
|
||||
use codex_protocol::models::FunctionCallOutputContentItem;
|
||||
use codex_protocol::openai_models::ToolMode;
|
||||
use codex_tools::ToolName;
|
||||
use serde_json::json;
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_worker_uses_step_router_mode_instead_of_admitted_turn() {
|
||||
let (session, turn) = make_session_and_context().await;
|
||||
assert_eq!(
|
||||
crate::tools::effective_tool_mode(&turn, turn.model_info()),
|
||||
ToolMode::Direct
|
||||
);
|
||||
let session = Arc::new(session);
|
||||
let step_context = StepContext::for_test(Arc::new(turn));
|
||||
let router = Arc::new(ToolRouter::from_parts(
|
||||
ToolRegistry::empty_for_test(),
|
||||
Vec::new(),
|
||||
ToolMode::CodeModeOnly,
|
||||
BTreeMap::new(),
|
||||
/*tool_namespaces_info*/ None,
|
||||
&[],
|
||||
));
|
||||
let step_context = step_context.with_tool_router_for_test(router);
|
||||
let tracker = Arc::new(tokio::sync::Mutex::new(TurnDiffTracker::new()));
|
||||
|
||||
let worker =
|
||||
session
|
||||
.services
|
||||
.code_mode_service
|
||||
.start_turn_worker(&session, step_context, tracker);
|
||||
|
||||
assert!(worker.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_nested_tool_payload_uses_function_kind() {
|
||||
let payload = build_nested_tool_payload(
|
||||
|
||||
Reference in new issue
Block a user