mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-20 13:49:07 +02:00
[shared] Identify a Bedrock geography by the vendor that follows it
The cross-region inference-profile prefix was matched against a list of
four — us, eu, apac, global — so a profile issued under any other
geography kept its prefix through normalization. That form matches no
catalog key, which cost more than a blank price column:
- discovery returned those models unpriced, so a real account's listing
came back almost entirely at $0
- the cost meter keys its table by the same normalized id, and operators
are told to register a Bedrock id exactly as AWS issues it, region
prefix included — so the default entry never resolved and every cache
bucket, and any model priced only by catalog defaults, metered free
Identify the geography by what follows it instead: a leading segment is a
geography when a known Bedrock vendor namespace comes next. New
geographies then need no change at all, and a vendor missing from the map
fails safe by keeping the prefix — the behaviour of the list this
replaces. Over-stripping is the direction that must not happen, since the
normalized id also decides which route may claim a model.
Covered at all three seams the id passes through: the normalizer, the cost
meter config the proxy bills from, and the discovery listing the dashboard
renders. Each test fails against the old four-geography list.
This commit is contained in:
+54
-9
@@ -10,9 +10,59 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// bedrockRegionPrefixes are the cross-region inference-profile prefixes that
|
||||
// front a Bedrock model id (e.g. "eu.anthropic.claude-...").
|
||||
var bedrockRegionPrefixes = []string{"us.", "eu.", "apac.", "global."}
|
||||
// bedrockVendorNamespaces are the vendor segments a Bedrock model id is
|
||||
// published under. They identify the geography in front of a cross-region
|
||||
// inference profile without enumerating geographies: in
|
||||
// "eu.anthropic.claude-...", what makes "eu" a geography is that "anthropic"
|
||||
// follows it.
|
||||
//
|
||||
// Listing geographies instead is what this replaced, and it aged badly — the
|
||||
// list held us, eu, apac and global, so every profile issued under jp, au, ca,
|
||||
// sa or us-gov carried its prefix into the pricing key, matched no catalog
|
||||
// entry, and reported the model unpriced.
|
||||
//
|
||||
// A vendor missing from this map fails safe: its id keeps the geography, which
|
||||
// is exactly the behaviour of the list this replaced. Over-stripping is the
|
||||
// dangerous direction, because the result also decides which route may claim a
|
||||
// model.
|
||||
var bedrockVendorNamespaces = map[string]struct{}{
|
||||
"ai21": {},
|
||||
"amazon": {},
|
||||
"anthropic": {},
|
||||
"cohere": {},
|
||||
"deepseek": {},
|
||||
"luma": {},
|
||||
"meta": {},
|
||||
"mistral": {},
|
||||
"openai": {},
|
||||
"qwen": {},
|
||||
"stability": {},
|
||||
"twelvelabs": {},
|
||||
"writer": {},
|
||||
}
|
||||
|
||||
// stripBedrockGeography removes the cross-region inference-profile geography
|
||||
// from a Bedrock model id, leaving the "<vendor>.<model>" form the catalog and
|
||||
// the pricing table key on.
|
||||
//
|
||||
// A leading segment counts as a geography only when a known vendor follows it.
|
||||
// "amazon.nova-pro" is a vendor and a model, not a geography and a model, and
|
||||
// cutting its first segment would strip the vendor away.
|
||||
func stripBedrockGeography(modelID string) string {
|
||||
dot := strings.IndexByte(modelID, '.')
|
||||
if dot <= 0 {
|
||||
return modelID
|
||||
}
|
||||
rest := modelID[dot+1:]
|
||||
vendor, _, found := strings.Cut(rest, ".")
|
||||
if !found {
|
||||
return modelID
|
||||
}
|
||||
if _, ok := bedrockVendorNamespaces[vendor]; !ok {
|
||||
return modelID
|
||||
}
|
||||
return rest
|
||||
}
|
||||
|
||||
// bedrockVersionSuffix matches the trailing "-vN[:N]" or "-YYYYMMDD-vN[:N]"
|
||||
// version/throughput suffix of a Bedrock model id.
|
||||
@@ -37,12 +87,7 @@ func NormalizeBedrockModel(modelID string) string {
|
||||
m = m[i+1:]
|
||||
}
|
||||
}
|
||||
for _, p := range bedrockRegionPrefixes {
|
||||
if strings.HasPrefix(m, p) {
|
||||
m = m[len(p):]
|
||||
break
|
||||
}
|
||||
}
|
||||
m = stripBedrockGeography(m)
|
||||
return bedrockVersionSuffix.ReplaceAllString(m, "")
|
||||
}
|
||||
|
||||
|
||||
@@ -60,3 +60,37 @@ func TestNormalizeAnthropicModel(t *testing.T) {
|
||||
require.Equal(t, want, NormalizeAnthropicModel(in), "normalize %q", in)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNormalizeBedrockModel_GeographiesBeyondTheOriginalFour covers the bug
|
||||
// that made this vendor-anchored: the geography used to be matched against a
|
||||
// list of four, so a profile issued anywhere else kept its prefix, missed the
|
||||
// catalog key it was supposed to match, and reported the model unpriced.
|
||||
func TestNormalizeBedrockModel_GeographiesBeyondTheOriginalFour(t *testing.T) {
|
||||
for _, geo := range []string{"us", "eu", "apac", "global", "jp", "au", "ca", "sa", "us-gov", "il", "mx"} {
|
||||
t.Run(geo, func(t *testing.T) {
|
||||
got := NormalizeBedrockModel(geo + ".anthropic.claude-sonnet-5-20260514-v1:0")
|
||||
require.Equal(t, "anthropic.claude-sonnet-5", got,
|
||||
"a cross-region profile must reduce to the catalog key whatever geography issued it")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestNormalizeBedrockModel_KeepsAVendorItCannotMistakeForAGeography pins the
|
||||
// direction that must never break: a plain "<vendor>.<model>" id has no
|
||||
// geography, and cutting its first segment would strip the vendor away and
|
||||
// hand the id to whichever route claims the bare model name.
|
||||
func TestNormalizeBedrockModel_KeepsAVendorItCannotMistakeForAGeography(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"amazon.nova-pro-v1:0": "amazon.nova-pro",
|
||||
"anthropic.claude-sonnet-5-v1:0": "anthropic.claude-sonnet-5",
|
||||
"meta.llama3-3-70b-instruct-v1:0": "meta.llama3-3-70b-instruct",
|
||||
"cohere.command-r-plus-v1:0": "cohere.command-r-plus",
|
||||
"eu.unknownvendor.some-model-v1:0": "eu.unknownvendor.some-model",
|
||||
"Qwen/Qwen2.5-0.5B-Instruct": "Qwen/Qwen2.5-0.5B-Instruct",
|
||||
}
|
||||
for in, want := range cases {
|
||||
t.Run(in, func(t *testing.T) {
|
||||
require.Equal(t, want, NormalizeBedrockModel(in))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user