mirror of
https://github.com/openai/codex.git
synced 2026-04-30 03:12:20 +03:00
Add models endpoint (#7603)
- Use the codex-api crate to introduce models endpoint. - Add `models` to codex core tests helpers - Add `ModelsInfo` for the endpoint return type
This commit is contained in:
@@ -3,6 +3,7 @@ use std::sync::Mutex;
|
||||
|
||||
use anyhow::Result;
|
||||
use base64::Engine;
|
||||
use codex_protocol::openai_models::ModelsResponse;
|
||||
use serde_json::Value;
|
||||
use wiremock::BodyPrintLimit;
|
||||
use wiremock::Match;
|
||||
@@ -193,6 +194,38 @@ impl ResponsesRequest {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModelsMock {
|
||||
requests: Arc<Mutex<Vec<wiremock::Request>>>,
|
||||
}
|
||||
|
||||
impl ModelsMock {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
requests: Arc::new(Mutex::new(Vec::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn requests(&self) -> Vec<wiremock::Request> {
|
||||
self.requests.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn single_request_path(&self) -> String {
|
||||
let requests = self.requests.lock().unwrap();
|
||||
if requests.len() != 1 {
|
||||
panic!("expected 1 request, got {}", requests.len());
|
||||
}
|
||||
requests.first().unwrap().url.path().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Match for ModelsMock {
|
||||
fn matches(&self, request: &wiremock::Request) -> bool {
|
||||
self.requests.lock().unwrap().push(request.clone());
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Match for ResponseMock {
|
||||
fn matches(&self, request: &wiremock::Request) -> bool {
|
||||
self.requests
|
||||
@@ -560,6 +593,14 @@ fn compact_mock() -> (MockBuilder, ResponseMock) {
|
||||
(mock, response_mock)
|
||||
}
|
||||
|
||||
fn models_mock() -> (MockBuilder, ModelsMock) {
|
||||
let models_mock = ModelsMock::new();
|
||||
let mock = Mock::given(method("GET"))
|
||||
.and(path_regex(".*/models$"))
|
||||
.and(models_mock.clone());
|
||||
(mock, models_mock)
|
||||
}
|
||||
|
||||
pub async fn mount_sse_once_match<M>(server: &MockServer, matcher: M, body: String) -> ResponseMock
|
||||
where
|
||||
M: wiremock::Match + Send + Sync + 'static,
|
||||
@@ -616,11 +657,29 @@ pub async fn mount_compact_json_once(server: &MockServer, body: serde_json::Valu
|
||||
response_mock
|
||||
}
|
||||
|
||||
pub async fn mount_models_once(server: &MockServer, body: ModelsResponse) -> ModelsMock {
|
||||
let (mock, models_mock) = models_mock();
|
||||
mock.respond_with(
|
||||
ResponseTemplate::new(200)
|
||||
.insert_header("content-type", "application/json")
|
||||
.set_body_json(body.clone()),
|
||||
)
|
||||
.up_to_n_times(1)
|
||||
.mount(server)
|
||||
.await;
|
||||
models_mock
|
||||
}
|
||||
|
||||
pub async fn start_mock_server() -> MockServer {
|
||||
MockServer::builder()
|
||||
let server = MockServer::builder()
|
||||
.body_print_limit(BodyPrintLimit::Limited(80_000))
|
||||
.start()
|
||||
.await
|
||||
.await;
|
||||
|
||||
// Provide a default `/models` response so tests remain hermetic when the client queries it.
|
||||
let _ = mount_models_once(&server, ModelsResponse { models: Vec::new() }).await;
|
||||
|
||||
server
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
Reference in New Issue
Block a user