mirror of
https://github.com/openai/codex.git
synced 2026-04-30 03:12:20 +03:00
make model optional in config (#7769)
- Make Config.model optional and centralize default-selection logic in ModelsManager, including a default_model helper (with codex-auto-balanced when available) so sessions now carry an explicit chosen model separate from the base config. - Resolve `model` once in `core` and `tui` from config. Then store the state of it on other structs. - Move refreshing models to be before resolving the default model
This commit is contained in:
@@ -689,6 +689,33 @@ pub async fn start_mock_server() -> MockServer {
|
||||
server
|
||||
}
|
||||
|
||||
// todo(aibrahim): remove this and use our search matching patterns directly
|
||||
/// Get all POST requests to `/responses` endpoints from the mock server.
|
||||
/// Filters out GET requests (e.g., `/models`) .
|
||||
pub async fn get_responses_requests(server: &MockServer) -> Vec<wiremock::Request> {
|
||||
server
|
||||
.received_requests()
|
||||
.await
|
||||
.expect("mock server should not fail")
|
||||
.into_iter()
|
||||
.filter(|req| req.method == "POST" && req.url.path().ends_with("/responses"))
|
||||
.collect()
|
||||
}
|
||||
|
||||
// todo(aibrahim): remove this and use our search matching patterns directly
|
||||
/// Get request bodies as JSON values from POST requests to `/responses` endpoints.
|
||||
/// Filters out GET requests (e.g., `/models`) .
|
||||
pub async fn get_responses_request_bodies(server: &MockServer) -> Vec<Value> {
|
||||
get_responses_requests(server)
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|req| {
|
||||
req.body_json::<Value>()
|
||||
.expect("request body to be valid JSON")
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FunctionCallResponseMocks {
|
||||
pub function_call: ResponseMock,
|
||||
@@ -769,6 +796,10 @@ pub async fn mount_sse_sequence(server: &MockServer, bodies: Vec<String>) -> Res
|
||||
/// - Additionally, enforce symmetry: every `function_call`/`custom_tool_call`
|
||||
/// in the `input` must have a matching output entry.
|
||||
fn validate_request_body_invariants(request: &wiremock::Request) {
|
||||
// Skip GET requests (e.g., /models)
|
||||
if request.method != "POST" || !request.url.path().ends_with("/responses") {
|
||||
return;
|
||||
}
|
||||
let Ok(body): Result<Value, _> = request.body_json() else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ use tempfile::TempDir;
|
||||
use wiremock::MockServer;
|
||||
|
||||
use crate::load_default_config_for_test;
|
||||
use crate::responses::get_responses_request_bodies;
|
||||
use crate::responses::start_mock_server;
|
||||
use crate::wait_for_event;
|
||||
|
||||
@@ -69,7 +70,7 @@ impl TestCodexBuilder {
|
||||
pub fn with_model(self, model: &str) -> Self {
|
||||
let new_model = model.to_string();
|
||||
self.with_config(move |config| {
|
||||
config.model = new_model.clone();
|
||||
config.model = Some(new_model.clone());
|
||||
})
|
||||
}
|
||||
|
||||
@@ -96,7 +97,8 @@ impl TestCodexBuilder {
|
||||
let (config, cwd) = self.prepare_config(server, &home).await?;
|
||||
|
||||
let auth = self.auth.clone();
|
||||
let conversation_manager = ConversationManager::with_auth(auth.clone());
|
||||
let conversation_manager =
|
||||
ConversationManager::with_models_provider(auth.clone(), config.model_provider.clone());
|
||||
|
||||
let new_conversation = match resume_from {
|
||||
Some(path) => {
|
||||
@@ -272,13 +274,7 @@ impl TestCodexHarness {
|
||||
}
|
||||
|
||||
pub async fn request_bodies(&self) -> Vec<Value> {
|
||||
self.server
|
||||
.received_requests()
|
||||
.await
|
||||
.expect("requests")
|
||||
.into_iter()
|
||||
.map(|req| serde_json::from_slice(&req.body).expect("request body json"))
|
||||
.collect()
|
||||
get_responses_request_bodies(&self.server).await
|
||||
}
|
||||
|
||||
pub async fn function_call_output_value(&self, call_id: &str) -> Value {
|
||||
|
||||
Reference in New Issue
Block a user