diff --git a/e2e/agentnetwork/chat_test.go b/e2e/agentnetwork/chat_test.go index ba45e7f91..a07ca9cff 100644 --- a/e2e/agentnetwork/chat_test.go +++ b/e2e/agentnetwork/chat_test.go @@ -95,17 +95,36 @@ func availableProviders() []providerCase { } // Bedrock: path-routed, bearer auth. Model is a cross-region inference - // profile id (distinct string from the first-party Anthropic case). + // profile id (distinct string from the first-party Anthropic case). The + // profile's region prefix must match the endpoint's region family — an + // eu.* profile against a us-east endpoint (or vice versa) makes Bedrock + // reject the request with "The provided model identifier is invalid". + // Defaults pair eu-central-1 with the eu.* profile; AWS_REGION overrides + // the region and the prefix follows its family. if k := os.Getenv("AWS_BEARER_TOKEN_BEDROCK"); k != "" { region := os.Getenv("AWS_REGION") if region == "" { - region = "us-east-1" + region = "eu-central-1" } - ps = append(ps, providerCase{name: "bedrock", catalogID: "bedrock_api", upstream: "https://bedrock-runtime." + region + ".amazonaws.com", apiKey: k, model: "us.anthropic.claude-haiku-4-5", kind: harness.WireBedrock}) + ps = append(ps, providerCase{name: "bedrock", catalogID: "bedrock_api", upstream: "https://bedrock-runtime." + region + ".amazonaws.com", apiKey: k, model: bedrockProfilePrefix(region) + ".anthropic.claude-haiku-4-5", kind: harness.WireBedrock}) } return ps } +// bedrockProfilePrefix maps an AWS region to its cross-region inference +// profile prefix: us-east-1 -> us, eu-central-1 -> eu, ap-southeast-1 -> apac, +// us-gov-west-1 -> us-gov. +func bedrockProfilePrefix(region string) string { + switch { + case strings.HasPrefix(region, "us-gov-"): + return "us-gov" + case strings.HasPrefix(region, "ap-"): + return "apac" + default: + return strings.SplitN(region, "-", 2)[0] + } +} + // providerRequest builds a create request for a matrix provider: enabled, with // a uniquely-priced model for body-routed providers and none for the // path-routed Vertex (whose model lives in the request path). diff --git a/e2e/agentnetwork/guardrail_test.go b/e2e/agentnetwork/guardrail_test.go index bb952044f..1461ca093 100644 --- a/e2e/agentnetwork/guardrail_test.go +++ b/e2e/agentnetwork/guardrail_test.go @@ -21,7 +21,14 @@ import ( func catalogModel(pc providerCase) string { switch pc.kind { case harness.WireBedrock: - return strings.TrimPrefix(pc.model, "us.") + // Strip whichever cross-region inference-profile prefix the matrix + // picked for the configured AWS region (us., eu., apac., us-gov.). + for _, p := range []string{"us-gov.", "apac.", "us.", "eu."} { + if strings.HasPrefix(pc.model, p) { + return strings.TrimPrefix(pc.model, p) + } + } + return pc.model case harness.WireVertex: return strings.SplitN(pc.model, "@", 2)[0] default: @@ -35,7 +42,9 @@ func catalogModel(pc providerCase) string { func disallowedModel(pc providerCase) string { switch pc.kind { case harness.WireBedrock: - return "us.anthropic.claude-opus-4-8" + // Same profile prefix as the allowed model so only the model name + // differs; the guardrail must deny it before it reaches AWS. + return strings.SplitN(pc.model, ".", 2)[0] + ".anthropic.claude-opus-4-8" case harness.WireVertex: return "claude-opus-4-8@20250101" default: