fix: show correct Bedrock runtime endpoint in /status (#20275)

## Why

`/status` was showing the configured `ModelProviderInfo.base_url` for
Amazon Bedrock, which can be stale or misleading because the actual
Bedrock Mantle endpoint is derived at runtime from the resolved AWS
region. This made sessions report the wrong provider endpoint even
though requests used the correct runtime URL.

## What changed

- Added `ModelProvider::runtime_base_url()` so provider implementations
can expose the request-time base URL through the shared runtime provider
abstraction.
- Moved Bedrock region-to-Mantle URL resolution into
`amazon_bedrock::mantle::runtime_base_url()`, keeping region resolution
private to the Mantle module.
- Overrode `runtime_base_url()` for Amazon Bedrock so it returns the
resolved Mantle endpoint instead of the configured default.
- Resolved and cached the runtime provider base URL during TUI startup,
then used that cached value when rendering `/status`.
- Added status coverage that verifies Bedrock displays the runtime URL
and ignores the configured Bedrock `base_url` when they differ.

## Verification
model provider is resolved correctly in local build:
<img width="696" height="245" alt="Screenshot 2026-04-29 at 5 01 36 PM"
src="https://github.com/user-attachments/assets/a13c10a5-3720-41ab-8ace-3c4bc573f971"
/>
This commit is contained in:
Celia Chen authored and GitHub committed 2026-04-30 19:02:34 +00:00
1 parent 93d53f655b
commit 31f8813e3e
15 files changed
+149 -17

No files matched your search

@@ -22,12 +22,14 @@ use super::mantle::region_from_config;
const AWS_BEARER_TOKEN_BEDROCK_ENV_VAR: &str = "AWS_BEARER_TOKEN_BEDROCK";
const LEGACY_SESSION_ID_HEADER: &str = "session_id";
enum BedrockAuthMethod {
pub(super) enum BedrockAuthMethod {
EnvBearerToken { token: String, region: String },
AwsSdkAuth { context: AwsAuthContext },
}
async fn resolve_auth_method(aws: &ModelProviderAwsAuthInfo) -> Result<BedrockAuthMethod> {
pub(super) async fn resolve_auth_method(
aws: &ModelProviderAwsAuthInfo,
) -> Result<BedrockAuthMethod> {
if let Some(token) = bearer_token_from_env() {
let region = bearer_token_region_from_config(aws)?;
return Ok(BedrockAuthMethod::EnvBearerToken { token, region });
@@ -55,13 +57,6 @@ pub(super) async fn resolve_provider_auth(
}
}
pub(super) async fn resolve_region(aws: &ModelProviderAwsAuthInfo) -> Result<String> {
match resolve_auth_method(aws).await? {
BedrockAuthMethod::EnvBearerToken { region, .. } => Ok(region),
BedrockAuthMethod::AwsSdkAuth { context, .. } => Ok(context.region().to_string()),
}
}
fn bearer_token_from_env() -> Option<String> {
std::env::var(AWS_BEARER_TOKEN_BEDROCK_ENV_VAR)
.ok()
@@ -3,6 +3,9 @@ use codex_model_provider_info::ModelProviderAwsAuthInfo;
use codex_protocol::error::CodexErr;
use codex_protocol::error::Result;
use super::auth::BedrockAuthMethod;
use super::auth::resolve_auth_method;
const BEDROCK_MANTLE_SERVICE_NAME: &str = "bedrock-mantle";
const BEDROCK_MANTLE_SUPPORTED_REGIONS: [&str; 12] = [
"us-east-2",
@@ -45,6 +48,18 @@ pub(super) fn base_url(region: &str) -> Result<String> {
}
}
pub(super) async fn runtime_base_url(aws: &ModelProviderAwsAuthInfo) -> Result<String> {
let region = resolve_region(aws).await?;
base_url(&region)
}
async fn resolve_region(aws: &ModelProviderAwsAuthInfo) -> Result<String> {
match resolve_auth_method(aws).await? {
BedrockAuthMethod::EnvBearerToken { region, .. } => Ok(region),
BedrockAuthMethod::AwsSdkAuth { context } => Ok(context.region().to_string()),
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
@@ -22,9 +22,8 @@ use crate::provider::ProviderAccountResult;
use crate::provider::ProviderAccountState;
use crate::provider::ProviderCapabilities;
use auth::resolve_provider_auth;
use auth::resolve_region;
pub(crate) use catalog::static_model_catalog;
use mantle::base_url;
use mantle::runtime_base_url;
/// Runtime provider for Amazon Bedrock's OpenAI-compatible Mantle endpoint.
#[derive(Clone, Debug)]
@@ -79,12 +78,15 @@ impl ModelProvider for AmazonBedrockModelProvider {
}
async fn api_provider(&self) -> Result<Provider> {
let region = resolve_region(&self.aws).await?;
let mut api_provider_info = self.info.clone();
api_provider_info.base_url = Some(base_url(&region)?);
api_provider_info.base_url = Some(runtime_base_url(&self.aws).await?);
api_provider_info.to_api_provider(/*auth_mode*/ None)
}
async fn runtime_base_url(&self) -> Result<Option<String>> {
Ok(Some(runtime_base_url(&self.aws).await?))
}
async fn api_auth(&self) -> Result<SharedAuthProvider> {
resolve_provider_auth(&self.aws).await
}
@@ -112,7 +114,7 @@ mod tests {
let region = "eu-central-1";
let mut api_provider_info =
ModelProviderInfo::create_amazon_bedrock_provider(/*aws*/ None);
api_provider_info.base_url = Some(base_url(region).expect("supported region"));
api_provider_info.base_url = Some(mantle::base_url(region).expect("supported region"));
let api_provider = api_provider_info
.to_api_provider(/*auth_mode*/ None)
.expect("api provider should build");