From 743508e3f6bed2fcc6df0d2d0d2e4664dd6d6fb4 Mon Sep 17 00:00:00 2001 From: kimnamu Date: Wed, 23 Sep 2026 19:42:18 +0900 Subject: [PATCH] fix(bedrock): keep dotted model names in cross-region profile IDs (us.openai.gpt-5.6-sol) _cross_region_check split geo-prefixed IDs on every dot and kept only the piece after the vendor, so us.openai.gpt-5.6-sol (and its inference-profile ARN) resolved to model "gpt-5" in the span name and gen_ai.request.model. The prefix-less branch already uses split(".", 1); limit the prefixed split to the prefix and vendor the same way. Co-Authored-By: Claude --- .../instrumentation/bedrock/__init__.py | 2 +- .../tests/test_model_id_parsing.py | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/opentelemetry-instrumentation-bedrock/tests/test_model_id_parsing.py diff --git a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/__init__.py b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/__init__.py index 6ad6cdc291..4b380bab1f 100644 --- a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/__init__.py +++ b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/__init__.py @@ -1009,7 +1009,7 @@ def _get_vendor_model(modelId): def _cross_region_check(value): prefixes = ["us", "us-gov", "eu", "apac"] if any(value.startswith(prefix + ".") for prefix in prefixes): - parts = value.split(".") + parts = value.split(".", 2) if len(parts) > 2: parts.pop(0) return parts[0], parts[1] diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/test_model_id_parsing.py b/packages/opentelemetry-instrumentation-bedrock/tests/test_model_id_parsing.py new file mode 100644 index 0000000000..a36fde1986 --- /dev/null +++ b/packages/opentelemetry-instrumentation-bedrock/tests/test_model_id_parsing.py @@ -0,0 +1,24 @@ +"""Model IDs whose model name contains a dot (openai.gpt-5.6-sol) must survive +the cross-region prefix strip, the same way the prefix-less form does.""" + +from opentelemetry.instrumentation.bedrock import _get_vendor_model + + +class TestDottedModelName: + def test_regional_profile_keeps_full_model_name(self): + assert _get_vendor_model("us.openai.gpt-5.6-sol") == ("aws.bedrock", "openai", "gpt-5.6-sol") + + def test_regional_profile_arn_keeps_full_model_name(self): + arn = "arn:aws:bedrock:us-east-1:111122223333:inference-profile/us.openai.gpt-5.6-sol" + assert _get_vendor_model(arn) == ("aws.bedrock", "openai", "gpt-5.6-sol") + + def test_prefixless_id_unchanged(self): + assert _get_vendor_model("openai.gpt-5.6-sol") == ("aws.bedrock", "openai", "gpt-5.6-sol") + + def test_undotted_profile_unchanged(self): + assert _get_vendor_model("us.openai.gpt-6-sol") == ("aws.bedrock", "openai", "gpt-6-sol") + assert _get_vendor_model("eu.anthropic.claude-3-7-sonnet-20250219-v1:0") == ( + "aws.bedrock", + "anthropic", + "claude-3-7-sonnet-20250219-v1:0", + )