Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions codex-rs/model-provider-info/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ 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_GPT_5_6_SOL_MODEL_ID: &str = "openai.gpt-5.6-sol";
pub const AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID: &str = "openai.gpt-5.6-terra";
pub const AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID: &str = "openai.gpt-5.6-luna";
pub const AMAZON_BEDROCK_DEFAULT_BASE_URL: &str =
"https://bedrock-mantle.us-east-1.api.aws/openai/v1";
const AMAZON_BEDROCK_MANTLE_CLIENT_AGENT_HEADER: &str = "x-amzn-mantle-client-agent";
Expand Down
104 changes: 82 additions & 22 deletions codex-rs/model-provider/src/amazon_bedrock/catalog.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
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_model_provider_info::AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID;
use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID;
use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID;
use codex_models_manager::bundled_models_response;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::openai_models::ReasoningEffortPreset;

const GPT_5_BEDROCK_CONTEXT_WINDOW: i64 = 272_000;
const GPT_5_5_OPENAI_MODEL_ID: &str = "gpt-5.5";
Expand All @@ -21,6 +26,21 @@ pub(crate) fn static_model_catalog() -> ModelsResponse {
AMAZON_BEDROCK_GPT_5_4_MODEL_ID,
/*priority*/ 1,
),
gpt_5_6_bedrock_model(
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID,
"Sol",
/*priority*/ 2,
),
gpt_5_6_bedrock_model(
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
"Terra",
/*priority*/ 3,
),
gpt_5_6_bedrock_model(
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
"Luna",
/*priority*/ 4,
),
],
})
}
Expand All @@ -44,6 +64,18 @@ fn gpt_5_bedrock_model(openai_slug: &str, bedrock_slug: &str, priority: i32) ->
model
}

fn gpt_5_6_bedrock_model(bedrock_slug: &str, display_name: &str, priority: i32) -> ModelInfo {
let mut model = gpt_5_bedrock_model(GPT_5_5_OPENAI_MODEL_ID, bedrock_slug, priority);
Comment thread
celia-oai marked this conversation as resolved.
model.display_name = display_name.to_string();
model
.supported_reasoning_levels
.push(ReasoningEffortPreset {
effort: ReasoningEffort::Custom("max".to_string()),
Comment thread
celia-oai marked this conversation as resolved.
description: "Maximum reasoning depth for the hardest problems".to_string(),
});
Comment thread
celia-oai marked this conversation as resolved.
model
}

fn bundled_openai_model(slug: &str) -> ModelInfo {
bundled_models_response()
.unwrap_or_else(|err| panic!("bundled models.json should parse: {err}"))
Expand All @@ -64,39 +96,67 @@ mod tests {
fn catalog_uses_mantle_model_ids_as_slugs() {
let catalog = static_model_catalog();

assert_eq!(catalog.models.len(), 2);
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
.iter()
.map(|model| model.slug.as_str())
.collect::<Vec<_>>(),
vec![
AMAZON_BEDROCK_GPT_5_5_MODEL_ID,
AMAZON_BEDROCK_GPT_5_4_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
]
);
}

#[test]
fn gpt_5_bedrock_models_use_bedrock_context_window() {
let catalog = static_model_catalog();

for model in catalog.models {
assert_eq!(
(model.context_window, model.max_context_window),
(
Some(GPT_5_BEDROCK_CONTEXT_WINDOW),
Some(GPT_5_BEDROCK_CONTEXT_WINDOW)
)
);
}
}

#[test]
fn gpt_5_6_bedrock_models_clone_gpt_5_5_config_with_max_reasoning_effort() {
let catalog = static_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");

assert_eq!(
(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)
)
);
for (slug, display_name, priority) in [
(AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID, "Sol", 2),
(AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID, "Terra", 3),
(AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID, "Luna", 4),
] {
let mut expected = gpt_5_5.clone();
expected.slug = slug.to_string();
expected.display_name = display_name.to_string();
expected.priority = priority;
expected
.supported_reasoning_levels
.push(ReasoningEffortPreset {
effort: ReasoningEffort::Custom("max".to_string()),
description: "Maximum reasoning depth for the hardest problems".to_string(),
});

assert_eq!(
catalog.models.iter().find(|model| model.slug == slug),
Some(&expected)
);
}
}

#[test]
Expand Down
11 changes: 10 additions & 1 deletion codex-rs/model-provider/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,16 @@ mod tests {
.map(|model| model.slug.as_str())
.collect::<Vec<_>>();

assert_eq!(model_ids, vec!["openai.gpt-5.5", "openai.gpt-5.4"]);
assert_eq!(
model_ids,
vec![
"openai.gpt-5.5",
"openai.gpt-5.4",
"openai.gpt-5.6-sol",
"openai.gpt-5.6-terra",
"openai.gpt-5.6-luna",
]
);

let default_model = manager
.list_models(RefreshStrategy::Online)
Expand Down
Loading