Skip to content

Commit 9be2868

Browse files
authored
fix: Claude 4.x compatibility and security updates (#711)
This commit addresses multiple issues related to model compatibility and security: 1. Claude 4.x Models Support: - Fix single sampling parameter requirement for Claude 4.x models - Claude 4.x only accepts 'temperature' parameter, not both temperature and top_p - Add version detection and conditional parameter handling 2. CRIS Model Listing Fix: - Resolve dictionary collision when listing models via CRIS integration - Prevent duplicate model entries from overwriting each other 3. Security Updates: - Upgrade pdfminer.six to version 20251107 to address known vulnerabilities - Complete pip-audit vulnerability suppression for GHSA-f83h-ghpp-7wcc across all requirements files - Add --ignore-vuln flag to file-import-batch-job pip-audit (was missing) References: - pdfminer.six vulnerability: pdfminer/pdfminer.six#1175 - The GHSA-f83h-ghpp-7wcc vulnerability remains unpatched in the latest version
1 parent 03b4682 commit 9be2868

File tree

5 files changed

+72
-22
lines changed

5 files changed

+72
-22
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
bandit -c bandit.yaml -r .
3838
pip-audit -r pytest_requirements.txt --ignore-vuln GHSA-f83h-ghpp-7wcc
3939
pip-audit -r lib/shared/web-crawler-batch-job/requirements.txt --ignore-vuln GHSA-f83h-ghpp-7wcc
40-
pip-audit -r lib/shared/file-import-batch-job/requirements.txt
40+
pip-audit -r lib/shared/file-import-batch-job/requirements.txt --ignore-vuln GHSA-f83h-ghpp-7wcc
4141
pytest tests/
4242
- name: Frontend
4343
working-directory: ./lib/user-interface/react-app

lib/model-interfaces/langchain/functions/request-handler/adapters/bedrock/base.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,36 @@ def should_call_apply_bedrock_guardrails(self) -> bool:
3939
else:
4040
return False
4141

42+
def _requires_single_sampling_param(self) -> bool:
43+
"""
44+
Some newer Claude models only allow one sampling parameter at a time.
45+
Returns True if the model requires choosing between temperature OR
46+
top_p.
47+
48+
Claude 4.x models (Sonnet 4, Opus 4, Haiku 4) require only one
49+
sampling parameter. Handles regional prefixes (us., global., eu.).
50+
Reference: https://docs.aws.amazon.com/bedrock/latest/userguide/
51+
model-parameters-anthropic-claude-messages.html
52+
"""
53+
# Models that only support one sampling parameter
54+
# Pattern matches any regional prefix (us., global., eu., etc.)
55+
single_param_model_patterns = [
56+
"anthropic.claude-sonnet-4", # Claude Sonnet 4.x (any region)
57+
"anthropic.claude-opus-4", # Claude Opus 4.x (any region)
58+
"anthropic.claude-haiku-4", # Claude Haiku 4.x (any region)
59+
]
60+
61+
model_lower = self.model_id.lower()
62+
return any(pattern in model_lower for pattern in single_param_model_patterns)
63+
4264
def add_files_to_message_history(self, images=[], documents=[], videos=[]):
4365
for image in images:
4466
filename, file_extension = os.path.splitext(image["key"])
4567
file_extension = file_extension.lower().replace(".", "")
4668
if file_extension == "jpg" or file_extension == "jpeg":
4769
file_extension = "jpeg"
4870
elif file_extension != "png":
49-
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ImageBlock.html
71+
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ImageBlock.html # noqa
5072
raise Exception("Unsupported format " + file_extension)
5173

5274
self.chat_history.add_temporary_message(
@@ -84,7 +106,7 @@ def add_files_to_message_history(self, images=[], documents=[], videos=[]):
84106
"md",
85107
]
86108
if file_extension not in supported:
87-
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_DocumentBlock.html
109+
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_DocumentBlock.html # noqa
88110
raise Exception("Unsupported format " + file_extension)
89111
self.chat_history.add_temporary_message(
90112
HumanMessage(
@@ -111,7 +133,7 @@ def add_files_to_message_history(self, images=[], documents=[], videos=[]):
111133
filename, file_extension = os.path.splitext(video["key"])
112134
file_extension = file_extension.lower().replace(".", "")
113135
if file_extension != "mp4":
114-
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_VideoBlock.html
136+
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_VideoBlock.html # noqa
115137
raise Exception("Unsupported format " + file_extension)
116138
self.chat_history.add_temporary_message(
117139
HumanMessage(
@@ -243,10 +265,21 @@ def get_llm(self, model_kwargs={}, extra={}):
243265
top_p = model_kwargs.get("topP")
244266
max_tokens = model_kwargs.get("maxTokens")
245267

246-
if temperature is not None:
247-
params["temperature"] = temperature
248-
if top_p:
249-
params["top_p"] = top_p
268+
# Handle sampling parameters based on model requirements
269+
if self._requires_single_sampling_param():
270+
# For Claude 4.x+ models: only set temperature OR top_p, not both
271+
# Prioritize temperature if both are provided
272+
if temperature is not None:
273+
params["temperature"] = temperature
274+
elif top_p:
275+
params["top_p"] = top_p
276+
else:
277+
# For older models (Claude 3.x, etc.): allow both parameters
278+
if temperature is not None:
279+
params["temperature"] = temperature
280+
if top_p:
281+
params["top_p"] = top_p
282+
250283
if max_tokens:
251284
params["max_tokens"] = max_tokens
252285

lib/shared/file-import-batch-job/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ beautifulsoup4==4.12.2
1515
requests==2.32.5
1616
attrs==23.1.0
1717
feedparser==6.0.11
18-
PyJWT==2.9.0
18+
PyJWT==2.9.0
19+
pdfminer-six==20251107

lib/shared/layers/python-sdk/python/genai_core/model_providers/direct/provider.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ def _list_azure_openai_models():
145145

146146

147147
# Based on the table (Need to support both document and sytem prompt)
148-
# https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html
148+
# https://docs.aws.amazon.com/bedrock/latest/userguide/
149+
# conversation-inference-supported-models-features.html
149150
def _does_model_support_documents(model_name):
150151
return (
151152
not re.match(r"^ai21.jamba*", model_name)
@@ -182,32 +183,47 @@ def _list_cross_region_inference_profiles():
182183
bedrock = genai_core.clients.get_bedrock_client(service_name="bedrock")
183184
response = bedrock.list_inference_profiles()
184185

185-
return {
186-
inference_profile["models"][0]["modelArn"].split("/")[1]: inference_profile[
187-
"inferenceProfileId"
188-
]
186+
# Return list of profiles instead of dict to avoid collisions
187+
# (multiple regional variants can have the same base model ID)
188+
return [
189+
inference_profile
189190
for inference_profile in response.get("inferenceProfileSummaries", [])
190191
if (
191192
inference_profile.get("status") == "ACTIVE"
192193
and inference_profile.get("type") == "SYSTEM_DEFINED"
193194
)
194-
}
195+
]
195196

196197

197198
def _list_bedrock_cris_models():
198199
try:
199-
cross_region_profiles = _list_cross_region_inference_profiles()
200+
inference_profiles = _list_cross_region_inference_profiles()
200201
bedrock_client = genai_core.clients.get_bedrock_client(service_name="bedrock")
201202
all_models = bedrock_client.list_foundation_models()["modelSummaries"]
202203

203-
return [
204-
_create_bedrock_model_profile(
205-
model, cross_region_profiles[model["modelId"]]
206-
)
204+
# Create dict of base models for lookup
205+
models_by_id = {
206+
model["modelId"]: model
207207
for model in all_models
208208
if genai_core.types.InferenceType.INFERENCE_PROFILE.value
209209
in model["inferenceTypesSupported"]
210-
]
210+
}
211+
212+
# Return all inference profiles (including multiple regional variants)
213+
result = []
214+
for profile in inference_profiles:
215+
base_model_id = profile["models"][0]["modelArn"].split("/")[1]
216+
profile_id = profile["inferenceProfileId"]
217+
218+
if base_model_id in models_by_id:
219+
result.append(
220+
_create_bedrock_model_profile(
221+
models_by_id[base_model_id],
222+
profile_id
223+
)
224+
)
225+
226+
return result
211227
except Exception as e:
212228
logger.error(f"Error listing cross region inference profiles models: {e}")
213229
return None

lib/shared/web-crawler-batch-job/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ feedparser==6.0.11
1717
aws_xray_sdk==2.14.0
1818
defusedxml==0.7.1
1919
pdfplumber==0.11.8
20-
pdfminer.six==20251107
20+
pdfminer.six==20251107

0 commit comments

Comments
 (0)