chore: add GPT-5.5 to the Amazon Bedrock catalog (#24701)

## Summary

Amazon Bedrock should expose GPT-5.5 alongside GPT-5.4, and the Bedrock
GPT entries should stay aligned with the canonical bundled OpenAI model
metadata instead of carrying a separate hand-written copy that can drift
over time. This change will be merged when the model is online.

This change:

- Adds the Bedrock Mantle model id for `openai.gpt-5.5`.
- Builds the Bedrock GPT-5.5 and GPT-5.4 catalog entries from the
bundled OpenAI model catalog, then overrides the Bedrock-facing slug,
explicit priority, and Bedrock-specific context windows.
- Hardcodes both `context_window` and `max_context_window` to `272000`
for Bedrock GPT-5.5 and GPT-5.4.
- Keeps `openai.gpt-5.5` as the default Bedrock model ahead of
`openai.gpt-5.4` and the Bedrock OSS models.
This commit is contained in:
Celia Chen
2026-05-28 10:29:06 -07:00
committed by GitHub
Unverified
parent 577ec03bf8
commit 489bf38658
3 changed files with 61 additions and 69 deletions
+1
View File
@@ -37,6 +37,7 @@ pub const OPENAI_PROVIDER_ID: &str = "openai";
pub const CHATGPT_CODEX_BASE_URL: &str = "https://chatgpt.com/backend-api/codex";
const AMAZON_BEDROCK_PROVIDER_NAME: &str = "Amazon Bedrock";
pub const AMAZON_BEDROCK_PROVIDER_ID: &str = "amazon-bedrock";
pub const AMAZON_BEDROCK_GPT_5_5_MODEL_ID: &str = "openai.gpt-5.5";
pub const AMAZON_BEDROCK_GPT_5_4_MODEL_ID: &str = "openai.gpt-5.4";
pub const AMAZON_BEDROCK_DEFAULT_BASE_URL: &str =
"https://bedrock-mantle.us-east-1.api.aws/openai/v1";
@@ -1,83 +1,66 @@
use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_4_MODEL_ID;
use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_5_MODEL_ID;
use codex_models_manager::bundled_models_response;
use codex_models_manager::model_info::BASE_INSTRUCTIONS;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::Verbosity;
use codex_protocol::openai_models::ApplyPatchToolType;
use codex_protocol::openai_models::ConfigShellToolType;
use codex_protocol::openai_models::InputModality;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::openai_models::ModelServiceTier;
use codex_protocol::openai_models::ModelVisibility;
use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::openai_models::ReasoningEffortPreset;
use codex_protocol::openai_models::SPEED_TIER_FAST;
use codex_protocol::openai_models::TruncationPolicyConfig;
use codex_protocol::openai_models::WebSearchToolType;
const GPT_OSS_CONTEXT_WINDOW: i64 = 128_000;
const GPT_5_4_CONTEXT_WINDOW: i64 = 272_000;
const GPT_5_4_MAX_CONTEXT_WINDOW: i64 = 1_000_000;
const GPT_5_BEDROCK_CONTEXT_WINDOW: i64 = 272_000;
const GPT_5_5_OPENAI_MODEL_ID: &str = "gpt-5.5";
const GPT_5_4_OPENAI_MODEL_ID: &str = "gpt-5.4";
pub(crate) fn static_model_catalog() -> ModelsResponse {
ModelsResponse {
models: vec![
gpt_5_4_cmb_bedrock_model(/*priority*/ 0),
gpt_5_bedrock_model(
GPT_5_5_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_5_MODEL_ID,
/*priority*/ 0,
),
gpt_5_bedrock_model(
GPT_5_4_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_4_MODEL_ID,
/*priority*/ 1,
),
bedrock_oss_model(
"openai.gpt-oss-120b",
"GPT OSS 120B on Bedrock",
/*priority*/ 1,
/*priority*/ 2,
),
bedrock_oss_model(
"openai.gpt-oss-20b",
"GPT OSS 20B on Bedrock",
/*priority*/ 2,
/*priority*/ 3,
),
],
}
}
fn gpt_5_4_cmb_bedrock_model(priority: i32) -> ModelInfo {
ModelInfo {
slug: AMAZON_BEDROCK_GPT_5_4_MODEL_ID.to_string(),
display_name: "gpt-5.4".to_string(),
description: Some("Strong model for everyday coding.".to_string()),
default_reasoning_level: Some(ReasoningEffort::Medium),
supported_reasoning_levels: gpt_5_4_cmb_reasoning_levels(),
shell_type: ConfigShellToolType::ShellCommand,
visibility: ModelVisibility::List,
supported_in_api: true,
priority,
additional_speed_tiers: Vec::new(),
service_tiers: vec![ModelServiceTier {
id: ServiceTier::Fast.request_value().to_string(),
name: SPEED_TIER_FAST.to_string(),
description: "Fastest inference with increased plan usage".to_string(),
}],
default_service_tier: None,
availability_nux: None,
upgrade: None,
base_instructions: BASE_INSTRUCTIONS.to_string(),
model_messages: None,
supports_reasoning_summaries: true,
default_reasoning_summary: ReasoningSummary::None,
support_verbosity: true,
default_verbosity: Some(Verbosity::Medium),
apply_patch_tool_type: Some(ApplyPatchToolType::Freeform),
web_search_tool_type: WebSearchToolType::TextAndImage,
truncation_policy: TruncationPolicyConfig::tokens(/*limit*/ 10_000),
supports_parallel_tool_calls: true,
supports_image_detail_original: true,
context_window: Some(GPT_5_4_CONTEXT_WINDOW),
max_context_window: Some(GPT_5_4_MAX_CONTEXT_WINDOW),
auto_compact_token_limit: None,
effective_context_window_percent: 95,
experimental_supported_tools: Vec::new(),
input_modalities: vec![InputModality::Text, InputModality::Image],
used_fallback_model_metadata: false,
supports_search_tool: true,
}
fn gpt_5_bedrock_model(openai_slug: &str, bedrock_slug: &str, priority: i32) -> ModelInfo {
let mut model = bundled_openai_model(openai_slug);
model.slug = bedrock_slug.to_string();
model.priority = priority;
model.context_window = Some(GPT_5_BEDROCK_CONTEXT_WINDOW);
model.max_context_window = Some(GPT_5_BEDROCK_CONTEXT_WINDOW);
model
}
fn bundled_openai_model(slug: &str) -> ModelInfo {
bundled_models_response()
.unwrap_or_else(|err| panic!("bundled models.json should parse: {err}"))
.models
.into_iter()
.find(|model| model.slug == slug)
.unwrap_or_else(|| panic!("bundled models.json should include {slug}"))
}
fn bedrock_oss_model(slug: &str, display_name: &str, priority: i32) -> ModelInfo {
@@ -122,15 +105,6 @@ fn bedrock_oss_model(slug: &str, display_name: &str, priority: i32) -> ModelInfo
}
}
fn gpt_5_4_cmb_reasoning_levels() -> Vec<ReasoningEffortPreset> {
vec![
reasoning_effort_preset(ReasoningEffort::Minimal),
reasoning_effort_preset(ReasoningEffort::Low),
reasoning_effort_preset(ReasoningEffort::Medium),
reasoning_effort_preset(ReasoningEffort::High),
]
}
fn reasoning_effort_preset(effort: ReasoningEffort) -> ReasoningEffortPreset {
ReasoningEffortPreset {
effort,
@@ -156,24 +130,40 @@ mod tests {
fn catalog_uses_mantle_model_ids_as_slugs() {
let catalog = static_model_catalog();
assert_eq!(catalog.models.len(), 3);
assert_eq!(catalog.models[0].slug, AMAZON_BEDROCK_GPT_5_4_MODEL_ID);
assert_eq!(catalog.models[1].slug, "openai.gpt-oss-120b");
assert_eq!(catalog.models[2].slug, "openai.gpt-oss-20b");
assert_eq!(catalog.models.len(), 4);
assert_eq!(catalog.models[0].slug, AMAZON_BEDROCK_GPT_5_5_MODEL_ID);
assert_eq!(catalog.models[1].slug, AMAZON_BEDROCK_GPT_5_4_MODEL_ID);
assert_eq!(catalog.models[2].slug, "openai.gpt-oss-120b");
assert_eq!(catalog.models[3].slug, "openai.gpt-oss-20b");
}
#[test]
fn gpt_5_4_cmb_advertises_only_bedrock_supported_reasoning_levels() {
fn gpt_5_bedrock_models_use_bedrock_context_window() {
let catalog = static_model_catalog();
let cmb_model = catalog
let gpt_5_5 = catalog
.models
.iter()
.find(|model| model.slug == AMAZON_BEDROCK_GPT_5_5_MODEL_ID)
.expect("Bedrock catalog should include GPT-5.5");
let gpt_5_4 = catalog
.models
.iter()
.find(|model| model.slug == AMAZON_BEDROCK_GPT_5_4_MODEL_ID)
.expect("Bedrock catalog should include GPT-5.4 CMB");
.expect("Bedrock catalog should include GPT-5.4");
assert_eq!(
cmb_model.supported_reasoning_levels,
gpt_5_4_cmb_reasoning_levels()
(gpt_5_5.context_window, gpt_5_5.max_context_window),
(
Some(GPT_5_BEDROCK_CONTEXT_WINDOW),
Some(GPT_5_BEDROCK_CONTEXT_WINDOW)
)
);
assert_eq!(
(gpt_5_4.context_window, gpt_5_4.max_context_window),
(
Some(GPT_5_BEDROCK_CONTEXT_WINDOW),
Some(GPT_5_BEDROCK_CONTEXT_WINDOW)
)
);
}
}
+2 -1
View File
@@ -510,6 +510,7 @@ mod tests {
assert_eq!(
model_ids,
vec![
"openai.gpt-5.5",
"openai.gpt-5.4",
"openai.gpt-oss-120b",
"openai.gpt-oss-20b"
@@ -523,7 +524,7 @@ mod tests {
.find(|preset| preset.is_default)
.expect("Bedrock catalog should have a default model");
assert_eq!(default_model.model, "openai.gpt-5.4");
assert_eq!(default_model.model, "openai.gpt-5.5");
}
#[tokio::test]