From 02d89c1ce1e29848e2cfb85d4ee1e3d37bb7f7fb Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Tue, 21 Jul 2026 11:49:42 +0000 Subject: [PATCH] Use the full Bedrock inference-profile id in the e2e matrix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The region-prefix fix wasn't sufficient: Bedrock ids also carry a date/version suffix (…-20251001-v1:0), and AWS rejects the bare form with 'The provided model identifier is invalid' regardless of region. Send the id exactly as AWS issues it and mirror the proxy's NormalizeBedrockModel (prefix + version-suffix strip, not importable from here) when deriving the guardrail allowlist entry — which is also precisely the round-trip the normalization change in 82fdfa8 exists to handle. --- e2e/agentnetwork/chat_test.go | 13 +++++++------ e2e/agentnetwork/guardrail_test.go | 22 ++++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/e2e/agentnetwork/chat_test.go b/e2e/agentnetwork/chat_test.go index a07ca9cff..cac670210 100644 --- a/e2e/agentnetwork/chat_test.go +++ b/e2e/agentnetwork/chat_test.go @@ -94,11 +94,12 @@ func availableProviders() []providerCase { } } - // Bedrock: path-routed, bearer auth. Model is a cross-region inference - // 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". + // Bedrock: path-routed, bearer auth. Model is the FULL cross-region + // inference-profile id exactly as AWS issues it — region-family prefix + // plus the date/version suffix. A bare or wrong-region id makes Bedrock + // reject the request with "The provided model identifier is invalid" + // before any inference runs. The proxy normalizes this id to the catalog + // key (anthropic.claude-haiku-4-5) for routing/pricing/allowlists. // 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 != "" { @@ -106,7 +107,7 @@ func availableProviders() []providerCase { if region == "" { region = "eu-central-1" } - 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}) + 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-20251001-v1:0", kind: harness.WireBedrock}) } return ps } diff --git a/e2e/agentnetwork/guardrail_test.go b/e2e/agentnetwork/guardrail_test.go index 1461ca093..c522f55bd 100644 --- a/e2e/agentnetwork/guardrail_test.go +++ b/e2e/agentnetwork/guardrail_test.go @@ -4,6 +4,7 @@ package agentnetwork import ( "context" + "regexp" "strings" "testing" "time" @@ -15,20 +16,29 @@ import ( "github.com/netbirdio/netbird/shared/management/http/api" ) +// bedrockVersionSuffix mirrors the proxy's normalizer: the trailing +// "-vN[:N]" or "-YYYYMMDD-vN[:N]" version/throughput suffix of a Bedrock +// model id. +var bedrockVersionSuffix = regexp.MustCompile(`-(\d{8}-)?v\d+(:\d+)?$`) + // catalogModel returns the normalized catalog id the proxy stamps for a // path-routed provider's configured model — the form the guardrail allowlist is // compared against (region prefix / @version stripped). func catalogModel(pc providerCase) string { switch pc.kind { case harness.WireBedrock: - // 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) + // Mirror the proxy's llm.NormalizeBedrockModel (not importable from + // here — proxy/internal): strip the region-family prefix and the + // date/version suffix so the allowlist carries the catalog key the + // guardrail compares against. + m := pc.model + for _, p := range []string{"us.", "eu.", "apac.", "global."} { + if strings.HasPrefix(m, p) { + m = strings.TrimPrefix(m, p) + break } } - return pc.model + return bedrockVersionSuffix.ReplaceAllString(m, "") case harness.WireVertex: return strings.SplitN(pc.model, "@", 2)[0] default: