Skip to content

Commit af26d7e

Browse files
authored
Add GPT-5.6 Luna routing coverage (#1213)
1 parent a92821f commit af26d7e

2 files changed

Lines changed: 70 additions & 17 deletions

File tree

crates/providers/src/openai/provider/core.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -674,19 +674,26 @@ mod tests {
674674
}
675675

676676
#[test]
677-
fn openai_reasoning_with_tools_uses_responses_api() {
678-
let mut provider = OpenAiProvider::new(
679-
secrecy::Secret::new("test-key".to_string()),
680-
"gpt-5.6-sol".to_string(),
681-
"https://api.openai.com/v1".to_string(),
682-
);
683-
provider.reasoning_effort = Some(ReasoningEffort::High);
684-
685-
assert_eq!(provider.wire_api_for_request(true), WireApi::Responses);
686-
assert_eq!(
687-
provider.wire_api_for_request(false),
688-
WireApi::ChatCompletions
689-
);
677+
fn openai_gpt_5_6_reasoning_with_tools_uses_responses_api() {
678+
for model in ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"] {
679+
let mut provider = OpenAiProvider::new(
680+
secrecy::Secret::new("test-key".to_string()),
681+
model.to_string(),
682+
"https://api.openai.com/v1".to_string(),
683+
);
684+
provider.reasoning_effort = Some(ReasoningEffort::High);
685+
686+
assert_eq!(
687+
provider.wire_api_for_request(true),
688+
WireApi::Responses,
689+
"{model}",
690+
);
691+
assert_eq!(
692+
provider.wire_api_for_request(false),
693+
WireApi::ChatCompletions,
694+
"{model}",
695+
);
696+
}
690697
}
691698

692699
#[test]

crates/providers/tests/openai_integration.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,29 @@
88
99
#![allow(clippy::unwrap_used, clippy::expect_used)]
1010

11-
use std::collections::HashSet;
11+
use std::{collections::HashSet, sync::Arc};
1212

1313
use {
1414
futures::StreamExt,
15-
moltis_agents::model::{ChatMessage, LlmProvider, StreamEvent, ToolCall},
15+
moltis_agents::model::{ChatMessage, LlmProvider, ReasoningEffort, StreamEvent, ToolCall},
1616
moltis_providers::openai::OpenAiProvider,
1717
secrecy::{ExposeSecret, Secret},
1818
};
1919

2020
const OPENAI_BASE_URL: &str = "https://api.openai.com/v1";
2121
const TEST_MODEL: &str = "gpt-5-mini";
22+
const LUNA_MODEL: &str = "gpt-5.6-luna";
2223

2324
/// Known OpenAI models we catalog. Keep in sync with `DEFAULT_OPENAI_MODELS`
24-
/// in `crates/providers/src/openai.rs`.
25-
const KNOWN_MODELS: &[&str] = &["gpt-5.2", "gpt-5.2-chat-latest", "gpt-5-mini"];
25+
/// in `crates/providers/src/openai/catalog.rs`.
26+
const KNOWN_MODELS: &[&str] = &[
27+
"gpt-5.6-sol",
28+
"gpt-5.6-terra",
29+
LUNA_MODEL,
30+
"gpt-5.2",
31+
"gpt-5.2-chat-latest",
32+
TEST_MODEL,
33+
];
2634

2735
fn api_key() -> Secret<String> {
2836
let key =
@@ -34,6 +42,12 @@ fn make_provider(model: &str) -> OpenAiProvider {
3442
OpenAiProvider::new(api_key(), model.to_string(), OPENAI_BASE_URL.to_string())
3543
}
3644

45+
fn make_provider_with_reasoning(model: &str, effort: ReasoningEffort) -> Arc<dyn LlmProvider> {
46+
Arc::new(make_provider(model))
47+
.with_reasoning_effort(effort)
48+
.expect("OpenAI provider should support reasoning_effort")
49+
}
50+
3751
fn weather_tool() -> serde_json::Value {
3852
serde_json::json!({
3953
"name": "get_weather",
@@ -170,6 +184,37 @@ async fn tool_call_round_trip_streaming() {
170184
assert_eq!(tool_name, "get_weather");
171185
}
172186

187+
#[tokio::test]
188+
#[ignore]
189+
async fn luna_reasoning_tool_call_uses_responses_api() {
190+
let p = make_provider_with_reasoning(LUNA_MODEL, ReasoningEffort::High);
191+
let messages = vec![ChatMessage::user(
192+
"What's the weather in Paris? Use the get_weather tool.",
193+
)];
194+
195+
let mut stream = p.stream_with_tools(messages, vec![weather_tool()]);
196+
let mut saw_tool_start = false;
197+
let mut saw_done = false;
198+
199+
while let Some(event) = stream.next().await {
200+
match event {
201+
StreamEvent::ToolCallStart { name, .. } => {
202+
assert_eq!(name, "get_weather");
203+
saw_tool_start = true;
204+
},
205+
StreamEvent::Done(_) => {
206+
saw_done = true;
207+
break;
208+
},
209+
StreamEvent::Error(err) => panic!("stream error: {err}"),
210+
_ => {},
211+
}
212+
}
213+
214+
assert!(saw_done, "Luna reasoning tool stream must emit Done");
215+
assert!(saw_tool_start, "Luna should call get_weather");
216+
}
217+
173218
#[tokio::test]
174219
#[ignore]
175220
async fn multi_turn_tool_use() {
@@ -261,6 +306,7 @@ async fn catalog_models_are_live() {
261306
eprintln!("==================================\n");
262307

263308
assert!(alive.contains(&TEST_MODEL), "{TEST_MODEL} should be live");
309+
assert!(alive.contains(&LUNA_MODEL), "{LUNA_MODEL} should be live");
264310
}
265311

266312
#[tokio::test]

0 commit comments

Comments
 (0)