Add GPT-6-Astra to Amazon Bedrock catalogs (#42619)

## What changed

- Add `openai.gpt-6-astra` to the Amazon Bedrock model catalog.
- Include its global and US cross-region variants in the Bedrock Runtime catalog.
- Preserve the bundled model metadata while applying Bedrock-specific capabilities and identifiers.

## Testing

- Cover catalog ordering, metadata, context-window overrides, and runtime routing variants.
- Add TUI snapshots for the Bedrock model and reasoning pickers.

GitOrigin-RevId: 25895174f00b85a738da5bb94ade82feaacb474c
This commit is contained in:
Celia Chen
2026-09-03 21:21:09 +00:00
committed by copyberry
parent 32c303c197
commit 1f7b99922a
11 changed files with 198 additions and 44 deletions
+1
View File
@@ -45,6 +45,7 @@ pub const AMAZON_BEDROCK_RUNTIME_PROVIDER_ID: &str = "amazon-bedrock-runtime";
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_6_ASTRA_MODEL_ID: &str = "openai.gpt-6-astra";
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_RUNTIME_GLOBAL_GPT_5_6_TERRA_MODEL_ID: &str =
@@ -3,6 +3,7 @@ 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_model_provider_info::AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID;
use codex_models_manager::bundled_models_response;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::openai_models::ModelVisibility;
@@ -15,41 +16,48 @@ const GPT_5_BEDROCK_CONTEXT_WINDOW: i64 = 272_000;
const GPT_5_6_SOL_OPENAI_MODEL_ID: &str = "gpt-5.6-sol";
const GPT_5_6_TERRA_OPENAI_MODEL_ID: &str = "gpt-5.6-terra";
const GPT_5_6_LUNA_OPENAI_MODEL_ID: &str = "gpt-5.6-luna";
const GPT_6_ASTRA_OPENAI_MODEL_ID: &str = "gpt-6-astra";
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 {
normalize_bedrock_catalog(ModelsResponse {
models: vec![
gpt_5_6_bedrock_model(
GPT_5_6_SOL_OPENAI_MODEL_ID,
bedrock_model(
bundled_openai_model(GPT_5_6_SOL_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID,
"GPT-5.6 Sol",
/*priority*/ 0,
),
gpt_5_6_bedrock_model(
GPT_5_6_TERRA_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
"GPT-5.6 Terra",
bedrock_model(
bundled_openai_model(GPT_6_ASTRA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID,
"GPT-6-Astra",
/*priority*/ 1,
),
gpt_5_6_bedrock_model(
GPT_5_6_LUNA_OPENAI_MODEL_ID,
bedrock_model(
bundled_openai_model(GPT_5_6_TERRA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
"GPT-5.6 Terra",
/*priority*/ 2,
),
bedrock_model(
bundled_openai_model(GPT_5_6_LUNA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
"GPT-5.6 Luna",
/*priority*/ 2,
/*priority*/ 3,
),
gpt_5_bedrock_model(
GPT_5_5_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_5_MODEL_ID,
"GPT-5.5",
/*priority*/ 3,
/*priority*/ 4,
),
gpt_5_bedrock_model(
GPT_5_4_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_4_MODEL_ID,
"GPT-5.4",
/*priority*/ 4,
/*priority*/ 5,
),
],
})
@@ -87,13 +95,12 @@ fn gpt_5_bedrock_model(
model
}
fn gpt_5_6_bedrock_model(
openai_slug: &str,
fn bedrock_model(
mut model: ModelInfo,
bedrock_slug: &str,
display_name: &str,
priority: i32,
) -> ModelInfo {
let mut model = bundled_openai_model(openai_slug);
model.slug = bedrock_slug.to_string();
model.display_name = display_name.to_string();
model.priority = priority;
@@ -136,6 +143,7 @@ mod tests {
.collect::<Vec<_>>(),
vec![
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID,
AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
AMAZON_BEDROCK_GPT_5_5_MODEL_ID,
@@ -166,6 +174,12 @@ mod tests {
Some(872_000),
WebSearchToolType::Text,
),
(
AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID,
Some(GPT_5_BEDROCK_CONTEXT_WINDOW),
Some(872_000),
WebSearchToolType::Text,
),
(
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
Some(GPT_5_BEDROCK_CONTEXT_WINDOW),
@@ -233,30 +247,35 @@ mod tests {
}
#[test]
fn gpt_5_6_bedrock_models_use_bundled_metadata_with_bedrock_overrides() {
fn bedrock_models_preserve_source_metadata_with_supported_capabilities() {
let catalog = static_model_catalog();
for (openai_slug, slug, display_name, priority) in [
for (mut expected, slug, display_name, priority) in [
(
GPT_5_6_SOL_OPENAI_MODEL_ID,
bundled_openai_model(GPT_5_6_SOL_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID,
"GPT-5.6 Sol",
0,
),
(
GPT_5_6_TERRA_OPENAI_MODEL_ID,
bundled_openai_model(GPT_5_6_TERRA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID,
"GPT-5.6 Terra",
1,
),
(
GPT_5_6_LUNA_OPENAI_MODEL_ID,
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
"GPT-5.6 Luna",
2,
),
(
bundled_openai_model(GPT_5_6_LUNA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID,
"GPT-5.6 Luna",
3,
),
(
bundled_openai_model(GPT_6_ASTRA_OPENAI_MODEL_ID),
AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID,
"GPT-6-Astra",
1,
),
] {
let mut expected = bundled_openai_model(openai_slug);
expected.slug = slug.to_string();
expected.display_name = display_name.to_string();
expected.priority = priority;
@@ -1,6 +1,7 @@
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_model_provider_info::AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID;
use codex_protocol::openai_models::ModelsResponse;
use super::catalog::static_model_catalog;
@@ -18,6 +19,7 @@ pub(super) fn static_runtime_model_catalog() -> ModelsResponse {
AMAZON_BEDROCK_GPT_5_6_SOL_MODEL_ID
| AMAZON_BEDROCK_GPT_5_6_TERRA_MODEL_ID
| AMAZON_BEDROCK_GPT_5_6_LUNA_MODEL_ID
| AMAZON_BEDROCK_GPT_6_ASTRA_MODEL_ID
)
})
.collect::<Vec<_>>();
@@ -19,18 +19,20 @@ fn runtime_catalog_includes_supported_cross_region_models_in_priority_order() {
.collect::<Vec<_>>(),
vec![
("global.openai.gpt-5.6-sol", "GPT-5.6 Sol (Global)", 0),
("global.openai.gpt-5.6-terra", "GPT-5.6 Terra (Global)", 1),
("global.openai.gpt-5.6-luna", "GPT-5.6 Luna (Global)", 2),
("us.openai.gpt-5.6-sol", "GPT-5.6 Sol (US cross-region)", 3),
("global.openai.gpt-6-astra", "GPT-6-Astra (Global)", 1),
("global.openai.gpt-5.6-terra", "GPT-5.6 Terra (Global)", 2),
("global.openai.gpt-5.6-luna", "GPT-5.6 Luna (Global)", 3),
("us.openai.gpt-5.6-sol", "GPT-5.6 Sol (US cross-region)", 4),
("us.openai.gpt-6-astra", "GPT-6-Astra (US cross-region)", 5),
(
"us.openai.gpt-5.6-terra",
"GPT-5.6 Terra (US cross-region)",
4,
6,
),
(
"us.openai.gpt-5.6-luna",
"GPT-5.6 Luna (US cross-region)",
5
7
),
]
);
@@ -58,6 +60,12 @@ fn runtime_catalog_disables_web_search_without_overriding_review_models() {
false,
Some(MultiAgentVersion::V1),
),
(
"global.openai.gpt-6-astra",
None,
false,
Some(MultiAgentVersion::V1),
),
(
"global.openai.gpt-5.6-terra",
None,
@@ -76,6 +84,12 @@ fn runtime_catalog_disables_web_search_without_overriding_review_models() {
false,
Some(MultiAgentVersion::V1),
),
(
"us.openai.gpt-6-astra",
None,
false,
Some(MultiAgentVersion::V1),
),
(
"us.openai.gpt-5.6-terra",
None,
+18 -14
View File
@@ -1063,20 +1063,22 @@ mod tests {
)
.await;
assert_eq!(uncached_catalog, catalog);
let model_info = manager
.get_model_info(
"openai.gpt-5.6-sol",
&ModelsManagerConfig {
model_context_window: Some(1_000_000),
..Default::default()
},
)
.await;
let mut expected_model_info = manager
.get_model_info("openai.gpt-5.6-sol", &ModelsManagerConfig::default())
.await;
expected_model_info.context_window = Some(872_000);
assert_eq!(model_info, expected_model_info);
for slug in ["openai.gpt-5.6-sol", "openai.gpt-6-astra"] {
let model_info = manager
.get_model_info(
slug,
&ModelsManagerConfig {
model_context_window: Some(1_000_000),
..Default::default()
},
)
.await;
let mut expected_model_info = manager
.get_model_info(slug, &ModelsManagerConfig::default())
.await;
expected_model_info.context_window = Some(872_000);
assert_eq!(model_info, expected_model_info);
}
let models = catalog
.models
@@ -1088,6 +1090,7 @@ mod tests {
models,
vec![
("openai.gpt-5.6-sol", "GPT-5.6 Sol"),
("openai.gpt-6-astra", "GPT-6-Astra"),
("openai.gpt-5.6-terra", "GPT-5.6 Terra"),
("openai.gpt-5.6-luna", "GPT-5.6 Luna"),
("openai.gpt-5.5", "GPT-5.5"),
@@ -1108,6 +1111,7 @@ mod tests {
.collect::<Vec<_>>(),
vec![
"openai.gpt-5.6-sol",
"openai.gpt-6-astra",
"openai.gpt-5.6-terra",
"openai.gpt-5.6-luna",
"openai.gpt-5.5",
@@ -0,0 +1,13 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
expression: "render_bottom_popup(&chat, 100)"
---
Select Reasoning Level for openai.gpt-6-astra
› 1. Low (default) Fast responses with lighter reasoning
2. Medium Balances speed and reasoning depth for everyday tasks
3. High Greater reasoning depth for complex problems
4. Extra high Extra high reasoning depth for complex problems
5. More reasoning… Max consumes usage limits faster
Press enter to confirm or esc to go back
@@ -0,0 +1,16 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
expression: "render_bottom_popup(&chat, 100)"
---
Select Model and Effort
Access legacy models by running codex -m <model_name> or in your config.toml
› 1. openai.gpt-5.6-sol (current) Latest frontier agentic coding model.
2. openai.gpt-6-astra Our most capable model for complex, demanding work.
3. openai.gpt-5.6-terra Balanced agentic coding model for everyday work.
4. openai.gpt-5.6-luna Fast and affordable agentic coding model.
5. openai.gpt-5.5 Frontier model for complex coding, research, and real-world
work.
6. openai.gpt-5.4 Strong model for everyday coding.
Press enter to confirm or esc to go back
@@ -0,0 +1,13 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
expression: "render_bottom_popup(&chat, 100)"
---
Select Reasoning Level for global.openai.gpt-6-astra
› 1. Low (default) Fast responses with lighter reasoning
2. Medium Balances speed and reasoning depth for everyday tasks
3. High Greater reasoning depth for complex problems
4. Extra high Extra high reasoning depth for complex problems
5. More reasoning… Max consumes usage limits faster
Press enter to confirm or esc to go back
@@ -0,0 +1,17 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
expression: "render_bottom_popup(&chat, 100)"
---
Select Model and Effort
Access legacy models by running codex -m <model_name> or in your config.toml
› 1. global.openai.gpt-5.6-sol (current) Latest frontier agentic coding model.
2. global.openai.gpt-6-astra Our most capable model for complex, demanding work.
3. global.openai.gpt-5.6-terra Balanced agentic coding model for everyday work.
4. global.openai.gpt-5.6-luna Fast and affordable agentic coding model.
5. us.openai.gpt-5.6-sol Latest frontier agentic coding model.
6. us.openai.gpt-6-astra Our most capable model for complex, demanding work.
7. us.openai.gpt-5.6-terra Balanced agentic coding model for everyday work.
8. us.openai.gpt-5.6-luna Fast and affordable agentic coding model.
Press enter to confirm or esc to go back
+2
View File
@@ -234,6 +234,8 @@ mod app_server;
mod approval_requests;
#[path = "tests/backend_banners_tests.rs"]
mod backend_banners_tests;
#[path = "tests/bedrock_catalog_tests.rs"]
mod bedrock_catalog_tests;
#[path = "tests/collaboration_catalog_tests.rs"]
mod collaboration_catalog_tests;
#[path = "tests/compaction_tests.rs"]
@@ -0,0 +1,53 @@
//! Renders the provider catalog and Astra reasoning choices without changing the default model.
use super::*;
use codex_http_client::HttpClientFactory;
use codex_http_client::OutboundProxyPolicy;
use codex_model_provider::create_model_provider;
use codex_model_provider_info::ModelProviderInfo;
use codex_models_manager::manager::RefreshStrategy;
#[tokio::test]
async fn bedrock_astra_model_and_reasoning_pickers() {
for (name, provider_info, default_model, astra_model) in [
(
"mantle",
ModelProviderInfo::create_amazon_bedrock_provider(/*aws*/ None),
"openai.gpt-5.6-sol",
"openai.gpt-6-astra",
),
(
"runtime",
ModelProviderInfo::create_amazon_bedrock_runtime_provider(/*aws*/ None),
"global.openai.gpt-5.6-sol",
"global.openai.gpt-6-astra",
),
] {
let presets = create_model_provider(provider_info, /*auth_manager*/ None)
.models_manager_without_cache(/*config_model_catalog*/ None)
.list_models(
RefreshStrategy::Offline,
HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault),
)
.await;
let astra = presets
.iter()
.find(|model| model.model == astra_model)
.expect("Astra preset")
.clone();
let (mut chat, _events, _ops) = make_chatwidget_manual(Some(default_model)).await;
chat.thread_id = Some(ThreadId::new());
chat.model_catalog = Arc::new(ModelCatalog::new(presets));
chat.open_model_popup();
assert_chatwidget_snapshot!(
format!("bedrock_{name}_models"),
render_bottom_popup(&chat, /*width*/ 100)
);
chat.handle_key_event(KeyEvent::from(KeyCode::Esc));
chat.open_reasoning_popup(astra);
assert_chatwidget_snapshot!(
format!("bedrock_{name}_astra_reasoning"),
render_bottom_popup(&chat, /*width*/ 100)
);
}
}