This is an automated email from the ASF dual-hosted git repository.
vincbeck pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 140c13dc96c Skip legacy models when selecting a Bedrock inference
profile (#72521)
140c13dc96c is described below
commit 140c13dc96c229bf6af9f4f2bcc12ca2b410930e
Author: Vincent <[email protected]>
AuthorDate: Thu Sep 10 12:35:50 2026 -0400
Skip legacy models when selecting a Bedrock inference profile (#72521)
get_text_inference_profile_arn() returns the first "sonnet" inference
profile
in list_inference_profiles order. That order is not stable, and when it
changed
the helper started returning a profile backed by a model its provider had
marked as legacy. Bedrock then rejects the request:
ValidationException: This Model is marked by provider as Legacy and you
have not been actively using the model in the last 30 days. Please
upgrade
to an active model on Amazon Bedrock.
example_bedrock_batch_inference and example_bedrock_retrieve_and_generate
both
use this helper, so both fail for as long as a legacy model sits first in
the
listing.
The inference profile summaries do not expose a lifecycle status, so look
the
legacy models up with list_foundation_models and skip any profile that
resolves to one of them. Foundation model IDs are compared rather than ARNs
because a global profile resolves to the same model in several regions.
* Pick a stable inference profile for Bedrock system tests
Requiring an ACTIVE lifecycle status keeps the selection correct if Bedrock
ever
reports a status beyond today's ACTIVE/LEGACY pair, and preferring the
oldest
release makes each run pick the same model instead of drifting onto a fresh
one
that batch inference or RAG may not support yet.
---
.../tests/system/amazon/aws/utils/bedrock.py | 60 +++++++++++++++++-----
1 file changed, 48 insertions(+), 12 deletions(-)
diff --git a/providers/amazon/tests/system/amazon/aws/utils/bedrock.py
b/providers/amazon/tests/system/amazon/aws/utils/bedrock.py
index 4b833b7438f..358848c9983 100644
--- a/providers/amazon/tests/system/amazon/aws/utils/bedrock.py
+++ b/providers/amazon/tests/system/amazon/aws/utils/bedrock.py
@@ -17,6 +17,7 @@
from __future__ import annotations
import logging
+import re
log = logging.getLogger(__name__)
@@ -26,6 +27,21 @@ except ImportError:
from airflow.decorators import task # type: ignore[attr-defined, no-redef]
+def _foundation_model_id(model_arn: str) -> str:
+ """Return the model ID part of a foundation model ARN, which is identical
in every region."""
+ return model_arn.rpartition("/")[2]
+
+
+def _release_date(inference_profile_id: str) -> str:
+ """
+ Return the ``YYYYMMDD`` release date model providers embed in their
version, e.g.
+ ``global.anthropic.claude-sonnet-4-5-20250929-v1:0``. An ID without one
sorts last, so an
+ unrecognised naming scheme is treated as the newest rather than silently
preferred.
+ """
+ match = re.search(r"\d{8}", inference_profile_id)
+ return match.group() if match else "99999999"
+
+
@task
def get_text_inference_profile_arn() -> str:
"""
@@ -37,17 +53,37 @@ def get_text_inference_profile_arn() -> str:
from airflow.providers.amazon.aws.hooks.bedrock import BedrockHook
client = BedrockHook().conn
+
+ # Bedrock only accepts a model whose lifecycle status is ACTIVE, so
requiring that status keeps this
+ # working if a provider ever reports something other than today's
ACTIVE/LEGACY pair. The inference
+ # profile summaries do not carry the lifecycle status, only the foundation
models a profile resolves to.
+ active_model_ids = {
+ model["modelId"]
+ for model in client.list_foundation_models()["modelSummaries"]
+ if model.get("modelLifecycle", {}).get("status") == "ACTIVE"
+ }
+
profiles =
client.list_inference_profiles(typeEquals="SYSTEM_DEFINED")["inferenceProfileSummaries"]
- arns = [
- profile["inferenceProfileArn"]
- for profile in profiles
- if profile.get("status") == "ACTIVE" and
profile["inferenceProfileId"].startswith("global.anthropic.")
- ]
- log.info("Valid text inference profile ARNs: %s", arns)
-
- for arn in arns:
+ # Oldest release first, so a run picks a mature model rather than a fresh
one that batch inference or
+ # RAG may not support yet, and picks the same one on every run.
+ candidates = sorted(
+ (
+ profile
+ for profile in profiles
+ if profile.get("status") == "ACTIVE"
+ and profile["inferenceProfileId"].startswith("global.anthropic.")
+ and all(
+ _foundation_model_id(model["modelArn"]) in active_model_ids
for model in profile["models"]
+ )
+ ),
+ key=lambda profile: (_release_date(profile["inferenceProfileId"]),
profile["inferenceProfileId"]),
+ )
+ profile_ids = [profile["inferenceProfileId"] for profile in candidates]
+ log.info("Valid text inference profiles, oldest first: %s", profile_ids)
+
+ for profile in candidates:
# Haiku has some version dependency issues: RAG only supports 3.5 but
batch only supports 4.5
- if "sonnet" in arn:
- log.info("Selected inference profile ARN: %s", arn)
- return arn
- raise RuntimeError("No valid inference profiles found")
+ if "sonnet" in profile["inferenceProfileId"]:
+ log.info("Selected inference profile ARN: %s",
profile["inferenceProfileArn"])
+ return profile["inferenceProfileArn"]
+ raise RuntimeError(f"No valid inference profiles found. Active candidates
were: {profile_ids}")