feat(aws_bedrock): route OpenAI GPT-5.6 (sol/terra/luna) via Bedrock … (#10502)

Signed-off-by: kbennett15 <75271761+kbennett15@users.noreply.github.com>
This commit is contained in:
kbennett15
2026-08-19 21:32:40 +00:00
committed by GitHub
parent c509e2fa34
commit e31f2f4292
+67
View File
@@ -48,6 +48,9 @@ pub const BEDROCK_KNOWN_MODELS: &[&str] = &[
"us.anthropic.claude-opus-4-1-20250805-v1:0",
"openai.gpt-5.5",
"openai.gpt-5.4",
"openai.gpt-5.6-sol",
"openai.gpt-5.6-terra",
"openai.gpt-5.6-luna",
];
pub const BEDROCK_DEFAULT_MAX_RETRIES: usize = 6;
@@ -1212,6 +1215,70 @@ mod tests {
assert_eq!(body["model"].as_str().unwrap(), "openai.gpt-5.5");
}
#[tokio::test]
async fn test_mantle_stream_returns_text_message_gpt_5_6() {
use futures::StreamExt;
use wiremock::matchers::{header, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
let sse_body = [
r#"data: {"type":"response.output_text.delta","sequence_number":1,"item_id":"msg_1","output_index":0,"content_index":0,"delta":"Hello"}"#,
r#"data: {"type":"response.output_text.delta","sequence_number":2,"item_id":"msg_1","output_index":0,"content_index":0,"delta":" world"}"#,
"data: [DONE]",
]
.join("\n");
Mock::given(method("POST"))
.and(path("/openai/v1/responses"))
.and(header("authorization", "Bearer test-token"))
.respond_with(ResponseTemplate::new(200).set_body_raw(sse_body, "text/event-stream"))
.mount(&server)
.await;
let sdk_config = aws_config::SdkConfig::builder()
.behavior_version(aws_config::BehaviorVersion::latest())
.region(aws_config::Region::new("us-east-1"))
.build();
let model = ModelConfig::new("openai.gpt-5.6-terra");
let provider = BedrockProvider {
client: Client::new(&sdk_config),
retry_config: RetryConfig::default(),
name: "aws_bedrock".to_string(),
region: Some("us-east-1".to_string()),
bearer_token: Some("test-token".to_string()),
http_client: reqwest::Client::new(),
mantle_base_url: Some(format!("{}/openai/v1/responses", server.uri())),
};
let messages = vec![crate::conversation::message::Message::user().with_text("hi")];
let mut stream = provider
.stream(&model.clone(), "", &messages, &[])
.await
.unwrap();
let mut text = String::new();
while let Some(item) = stream.next().await {
let (msg, _usage) = item.unwrap();
if let Some(m) = msg {
for c in m.content {
if let MessageContent::Text(t) = c {
text.push_str(&t.text);
}
}
}
}
assert_eq!(text, "Hello world");
let received = server.received_requests().await.unwrap();
assert_eq!(received.len(), 1);
let body: serde_json::Value = serde_json::from_slice(&received[0].body).unwrap();
assert_eq!(body["model"].as_str().unwrap(), "openai.gpt-5.6-terra");
}
// ── ConverseStream event processing ──────────────────────────────────
use crate::conversation::message::MessageContent;