amazon-bedrock-haystack 6.3.0__tar.gz → 6.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/CHANGELOG.md +13 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/PKG-INFO +1 -1
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/downloaders/s3/s3_downloader.py +6 -10
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/embedders/amazon_bedrock/document_embedder.py +6 -10
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/embedders/amazon_bedrock/document_image_embedder.py +6 -17
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/embedders/amazon_bedrock/text_embedder.py +6 -10
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/chat/chat_generator.py +24 -11
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/chat/utils.py +61 -12
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/generator.py +6 -10
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/rankers/amazon_bedrock/ranker.py +6 -10
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_chat_generator.py +28 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_chat_generator_utils.py +177 -15
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/.gitignore +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/LICENSE.txt +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/README.md +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/bedrock_ranker_example.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/chatgenerator_example.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/embedders_generator_with_rag_example.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/s3_downloader_example.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/pydoc/config_docusaurus.yml +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/pyproject.toml +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/amazon_bedrock/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/amazon_bedrock/errors.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/amazon_bedrock/utils.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/py.typed +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/s3/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/s3/errors.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/common/s3/utils.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/downloaders/py.typed +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/downloaders/s3/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/embedders/amazon_bedrock/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/embedders/py.typed +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/adapters.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/amazon_bedrock/chat/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/generators/py.typed +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/rankers/amazon_bedrock/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/src/haystack_integrations/components/rankers/py.typed +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/__init__.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/conftest.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_document_embedder.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_document_image_embedder.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_files/apple.jpg +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_files/haystack-logo.png +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_files/sample_pdf_1.pdf +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_generator.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_ranker.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_s3_downloader.py +0 -0
- {amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_text_embedder.py +0 -0
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/amazon_bedrock-v6.3.0] - 2026-01-28
|
|
4
|
+
|
|
5
|
+
### 🌀 Miscellaneous
|
|
6
|
+
|
|
7
|
+
- Feat: Bedrock - support images in tool results (#2783)
|
|
8
|
+
|
|
9
|
+
## [integrations/amazon_bedrock-v6.2.1] - 2026-01-15
|
|
10
|
+
|
|
11
|
+
### 🐛 Bug Fixes
|
|
12
|
+
|
|
13
|
+
- None value handling of flattened generation kwargs for AmazonBedrockChatGenerator (#2752)
|
|
14
|
+
|
|
15
|
+
|
|
3
16
|
## [integrations/amazon_bedrock-v6.2.0] - 2026-01-13
|
|
4
17
|
|
|
5
18
|
### 🚀 Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amazon-bedrock-haystack
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.4.0
|
|
4
4
|
Summary: An integration of AWS S3 and Bedrock as a Downloader and Generator components.
|
|
5
5
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/amazon_bedrock#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
@@ -11,7 +11,7 @@ from typing import Any
|
|
|
11
11
|
from botocore.config import Config
|
|
12
12
|
from haystack import component, default_from_dict, default_to_dict, logging
|
|
13
13
|
from haystack.dataclasses import Document
|
|
14
|
-
from haystack.utils.auth import Secret
|
|
14
|
+
from haystack.utils.auth import Secret
|
|
15
15
|
from haystack.utils.callable_serialization import deserialize_callable, serialize_callable
|
|
16
16
|
|
|
17
17
|
from haystack_integrations.common.amazon_bedrock.utils import get_aws_session
|
|
@@ -233,11 +233,11 @@ class S3Downloader:
|
|
|
233
233
|
|
|
234
234
|
return default_to_dict(
|
|
235
235
|
self,
|
|
236
|
-
aws_access_key_id=self.aws_access_key_id
|
|
237
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
238
|
-
aws_session_token=self.aws_session_token
|
|
239
|
-
aws_region_name=self.aws_region_name
|
|
240
|
-
aws_profile_name=self.aws_profile_name
|
|
236
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
237
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
238
|
+
aws_session_token=self.aws_session_token,
|
|
239
|
+
aws_region_name=self.aws_region_name,
|
|
240
|
+
aws_profile_name=self.aws_profile_name,
|
|
241
241
|
file_root_path=str(self.file_root_path),
|
|
242
242
|
max_workers=self.max_workers,
|
|
243
243
|
max_cache_size=self.max_cache_size,
|
|
@@ -260,8 +260,4 @@ class S3Downloader:
|
|
|
260
260
|
data["init_parameters"]["s3_key_generation_function"] = deserialize_callable(
|
|
261
261
|
s3_key_generation_function_name
|
|
262
262
|
)
|
|
263
|
-
deserialize_secrets_inplace(
|
|
264
|
-
data["init_parameters"],
|
|
265
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
266
|
-
)
|
|
267
263
|
return default_from_dict(cls, data)
|
|
@@ -6,7 +6,7 @@ from botocore.config import Config
|
|
|
6
6
|
from botocore.exceptions import ClientError
|
|
7
7
|
from haystack import component, default_from_dict, default_to_dict, logging
|
|
8
8
|
from haystack.dataclasses import Document
|
|
9
|
-
from haystack.utils.auth import Secret
|
|
9
|
+
from haystack.utils.auth import Secret
|
|
10
10
|
from tqdm import tqdm
|
|
11
11
|
|
|
12
12
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
@@ -257,11 +257,11 @@ class AmazonBedrockDocumentEmbedder:
|
|
|
257
257
|
"""
|
|
258
258
|
return default_to_dict(
|
|
259
259
|
self,
|
|
260
|
-
aws_access_key_id=self.aws_access_key_id
|
|
261
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
262
|
-
aws_session_token=self.aws_session_token
|
|
263
|
-
aws_region_name=self.aws_region_name
|
|
264
|
-
aws_profile_name=self.aws_profile_name
|
|
260
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
261
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
262
|
+
aws_session_token=self.aws_session_token,
|
|
263
|
+
aws_region_name=self.aws_region_name,
|
|
264
|
+
aws_profile_name=self.aws_profile_name,
|
|
265
265
|
model=self.model,
|
|
266
266
|
batch_size=self.batch_size,
|
|
267
267
|
progress_bar=self.progress_bar,
|
|
@@ -281,8 +281,4 @@ class AmazonBedrockDocumentEmbedder:
|
|
|
281
281
|
:returns:
|
|
282
282
|
Deserialized component.
|
|
283
283
|
"""
|
|
284
|
-
deserialize_secrets_inplace(
|
|
285
|
-
data["init_parameters"],
|
|
286
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
287
|
-
)
|
|
288
284
|
return default_from_dict(cls, data)
|
|
@@ -16,7 +16,7 @@ from haystack.components.converters.image.image_utils import (
|
|
|
16
16
|
_PDFPageInfo,
|
|
17
17
|
)
|
|
18
18
|
from haystack.dataclasses import ByteStream
|
|
19
|
-
from haystack.utils.auth import Secret
|
|
19
|
+
from haystack.utils.auth import Secret
|
|
20
20
|
from tqdm import tqdm
|
|
21
21
|
|
|
22
22
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
@@ -178,11 +178,11 @@ class AmazonBedrockDocumentImageEmbedder:
|
|
|
178
178
|
file_path_meta_field=self.file_path_meta_field,
|
|
179
179
|
root_path=self.root_path,
|
|
180
180
|
model=self.model,
|
|
181
|
-
aws_access_key_id=self.aws_access_key_id
|
|
182
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
183
|
-
aws_session_token=self.aws_session_token
|
|
184
|
-
aws_region_name=self.aws_region_name
|
|
185
|
-
aws_profile_name=self.aws_profile_name
|
|
181
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
182
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
183
|
+
aws_session_token=self.aws_session_token,
|
|
184
|
+
aws_region_name=self.aws_region_name,
|
|
185
|
+
aws_profile_name=self.aws_profile_name,
|
|
186
186
|
progress_bar=self.progress_bar,
|
|
187
187
|
boto3_config=self.boto3_config,
|
|
188
188
|
image_size=self.image_size,
|
|
@@ -200,17 +200,6 @@ class AmazonBedrockDocumentImageEmbedder:
|
|
|
200
200
|
:returns:
|
|
201
201
|
Deserialized component.
|
|
202
202
|
"""
|
|
203
|
-
init_params = data["init_parameters"]
|
|
204
|
-
deserialize_secrets_inplace(
|
|
205
|
-
init_params,
|
|
206
|
-
keys=[
|
|
207
|
-
"aws_access_key_id",
|
|
208
|
-
"aws_secret_access_key",
|
|
209
|
-
"aws_session_token",
|
|
210
|
-
"aws_region_name",
|
|
211
|
-
"aws_profile_name",
|
|
212
|
-
],
|
|
213
|
-
)
|
|
214
203
|
return default_from_dict(cls, data)
|
|
215
204
|
|
|
216
205
|
@component.output_types(documents=list[Document])
|
|
@@ -4,7 +4,7 @@ from typing import Any
|
|
|
4
4
|
from botocore.config import Config
|
|
5
5
|
from botocore.exceptions import ClientError
|
|
6
6
|
from haystack import component, default_from_dict, default_to_dict, logging
|
|
7
|
-
from haystack.utils.auth import Secret
|
|
7
|
+
from haystack.utils.auth import Secret
|
|
8
8
|
|
|
9
9
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
10
10
|
AmazonBedrockConfigurationError,
|
|
@@ -180,11 +180,11 @@ class AmazonBedrockTextEmbedder:
|
|
|
180
180
|
"""
|
|
181
181
|
return default_to_dict(
|
|
182
182
|
self,
|
|
183
|
-
aws_access_key_id=self.aws_access_key_id
|
|
184
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
185
|
-
aws_session_token=self.aws_session_token
|
|
186
|
-
aws_region_name=self.aws_region_name
|
|
187
|
-
aws_profile_name=self.aws_profile_name
|
|
183
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
184
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
185
|
+
aws_session_token=self.aws_session_token,
|
|
186
|
+
aws_region_name=self.aws_region_name,
|
|
187
|
+
aws_profile_name=self.aws_profile_name,
|
|
188
188
|
model=self.model,
|
|
189
189
|
boto3_config=self.boto3_config,
|
|
190
190
|
**self.kwargs,
|
|
@@ -200,8 +200,4 @@ class AmazonBedrockTextEmbedder:
|
|
|
200
200
|
:returns:
|
|
201
201
|
Deserialized component.
|
|
202
202
|
"""
|
|
203
|
-
deserialize_secrets_inplace(
|
|
204
|
-
data["init_parameters"],
|
|
205
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
206
|
-
)
|
|
207
203
|
return default_from_dict(cls, data)
|
|
@@ -13,7 +13,7 @@ from haystack.tools import (
|
|
|
13
13
|
flatten_tools_or_toolsets,
|
|
14
14
|
serialize_tools_or_toolset,
|
|
15
15
|
)
|
|
16
|
-
from haystack.utils.auth import Secret
|
|
16
|
+
from haystack.utils.auth import Secret
|
|
17
17
|
from haystack.utils.callable_serialization import deserialize_callable, serialize_callable
|
|
18
18
|
|
|
19
19
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
@@ -27,6 +27,7 @@ from haystack_integrations.components.generators.amazon_bedrock.chat.utils impor
|
|
|
27
27
|
_parse_completion_response,
|
|
28
28
|
_parse_streaming_response,
|
|
29
29
|
_parse_streaming_response_async,
|
|
30
|
+
_validate_and_format_cache_point,
|
|
30
31
|
_validate_guardrail_config,
|
|
31
32
|
)
|
|
32
33
|
|
|
@@ -142,6 +143,12 @@ class AmazonBedrockChatGenerator:
|
|
|
142
143
|
and `aws_region_name` as environment variables or pass them as
|
|
143
144
|
[Secret](https://docs.haystack.deepset.ai/docs/secret-management) arguments. Make sure the region you set
|
|
144
145
|
supports Amazon Bedrock.
|
|
146
|
+
|
|
147
|
+
This component supports prompt caching. You can use the `tools_cachepoint_config` parameter to configure the cache
|
|
148
|
+
point for tools.
|
|
149
|
+
To cache messages, you can use the `cachePoint` key in `ChatMessage.meta` attribute.
|
|
150
|
+
Example: `ChatMessage.from_user("Long message...", meta={"cachePoint": {"type": "default"}})`
|
|
151
|
+
For more information, see the [Amazon Bedrock documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html).
|
|
145
152
|
"""
|
|
146
153
|
|
|
147
154
|
def __init__(
|
|
@@ -160,6 +167,7 @@ class AmazonBedrockChatGenerator:
|
|
|
160
167
|
tools: ToolsType | None = None,
|
|
161
168
|
*,
|
|
162
169
|
guardrail_config: dict[str, str] | None = None,
|
|
170
|
+
tools_cachepoint_config: dict[str, str] | None = None,
|
|
163
171
|
) -> None:
|
|
164
172
|
"""
|
|
165
173
|
Initializes the `AmazonBedrockChatGenerator` with the provided parameters. The parameters are passed to the
|
|
@@ -201,6 +209,10 @@ class AmazonBedrockChatGenerator:
|
|
|
201
209
|
See the
|
|
202
210
|
[Guardrails Streaming documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-streaming.html)
|
|
203
211
|
for more information.
|
|
212
|
+
:param tools_cachepoint_config: Optional configuration to use prompt caching for tools.
|
|
213
|
+
The dictionary must match the
|
|
214
|
+
[CachePointBlock schema](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_CachePointBlock.html).
|
|
215
|
+
Example: `{"type": "default", "ttl": "5m"}`
|
|
204
216
|
|
|
205
217
|
|
|
206
218
|
:raises ValueError: If the model name is empty or None.
|
|
@@ -225,6 +237,10 @@ class AmazonBedrockChatGenerator:
|
|
|
225
237
|
_validate_guardrail_config(guardrail_config=guardrail_config, streaming=streaming_callback is not None)
|
|
226
238
|
self.guardrail_config = guardrail_config
|
|
227
239
|
|
|
240
|
+
self.tools_cachepoint_config = (
|
|
241
|
+
_validate_and_format_cache_point(tools_cachepoint_config) if tools_cachepoint_config else None
|
|
242
|
+
)
|
|
243
|
+
|
|
228
244
|
def resolve_secret(secret: Secret | None) -> str | None:
|
|
229
245
|
return secret.resolve_value() if secret else None
|
|
230
246
|
|
|
@@ -299,17 +315,18 @@ class AmazonBedrockChatGenerator:
|
|
|
299
315
|
callback_name = serialize_callable(self.streaming_callback) if self.streaming_callback else None
|
|
300
316
|
return default_to_dict(
|
|
301
317
|
self,
|
|
302
|
-
aws_access_key_id=self.aws_access_key_id
|
|
303
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
304
|
-
aws_session_token=self.aws_session_token
|
|
305
|
-
aws_region_name=self.aws_region_name
|
|
306
|
-
aws_profile_name=self.aws_profile_name
|
|
318
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
319
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
320
|
+
aws_session_token=self.aws_session_token,
|
|
321
|
+
aws_region_name=self.aws_region_name,
|
|
322
|
+
aws_profile_name=self.aws_profile_name,
|
|
307
323
|
model=self.model,
|
|
308
324
|
generation_kwargs=self.generation_kwargs,
|
|
309
325
|
streaming_callback=callback_name,
|
|
310
326
|
boto3_config=self.boto3_config,
|
|
311
327
|
tools=serialize_tools_or_toolset(self.tools),
|
|
312
328
|
guardrail_config=self.guardrail_config,
|
|
329
|
+
tools_cachepoint_config=self.tools_cachepoint_config,
|
|
313
330
|
)
|
|
314
331
|
|
|
315
332
|
@classmethod
|
|
@@ -331,10 +348,6 @@ class AmazonBedrockChatGenerator:
|
|
|
331
348
|
serialized_callback_handler = init_params.get("streaming_callback")
|
|
332
349
|
if serialized_callback_handler:
|
|
333
350
|
data["init_parameters"]["streaming_callback"] = deserialize_callable(serialized_callback_handler)
|
|
334
|
-
deserialize_secrets_inplace(
|
|
335
|
-
data["init_parameters"],
|
|
336
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
337
|
-
)
|
|
338
351
|
deserialize_tools_or_toolset_inplace(data["init_parameters"], key="tools")
|
|
339
352
|
return default_from_dict(cls, data)
|
|
340
353
|
|
|
@@ -389,7 +402,7 @@ class AmazonBedrockChatGenerator:
|
|
|
389
402
|
tool_config = merged_kwargs.pop("toolConfig", None)
|
|
390
403
|
if flattened_tools:
|
|
391
404
|
# Format Haystack tools to Bedrock format
|
|
392
|
-
tool_config = _format_tools(flattened_tools)
|
|
405
|
+
tool_config = _format_tools(flattened_tools, tools_cachepoint_config=self.tools_cachepoint_config)
|
|
393
406
|
|
|
394
407
|
# Any remaining kwargs go to additionalModelRequestFields
|
|
395
408
|
additional_fields = merged_kwargs if merged_kwargs else None
|
|
@@ -40,7 +40,9 @@ FINISH_REASON_MAPPING: dict[str, FinishReason] = {
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
# Haystack to Bedrock util methods
|
|
43
|
-
def _format_tools(
|
|
43
|
+
def _format_tools(
|
|
44
|
+
tools: list[Tool] | None = None, tools_cachepoint_config: dict[str, dict[str, str]] | None = None
|
|
45
|
+
) -> dict[str, Any] | None:
|
|
44
46
|
"""
|
|
45
47
|
Format Haystack Tool(s) to Amazon Bedrock toolConfig format.
|
|
46
48
|
|
|
@@ -51,13 +53,16 @@ def _format_tools(tools: list[Tool] | None = None) -> dict[str, Any] | None:
|
|
|
51
53
|
if not tools:
|
|
52
54
|
return None
|
|
53
55
|
|
|
54
|
-
tool_specs = []
|
|
56
|
+
tool_specs: list[dict[str, Any]] = []
|
|
55
57
|
for tool in tools:
|
|
56
58
|
tool_specs.append(
|
|
57
59
|
{"toolSpec": {"name": tool.name, "description": tool.description, "inputSchema": {"json": tool.parameters}}}
|
|
58
60
|
)
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
if tools_cachepoint_config:
|
|
63
|
+
tool_specs.append({"cachePoint": tools_cachepoint_config})
|
|
64
|
+
|
|
65
|
+
return {"tools": tool_specs}
|
|
61
66
|
|
|
62
67
|
|
|
63
68
|
def _convert_image_content_to_bedrock_format(image_content: ImageContent) -> dict[str, Any]:
|
|
@@ -181,20 +186,23 @@ def _repair_tool_result_messages(bedrock_formatted_messages: list[dict[str, Any]
|
|
|
181
186
|
original_idx = None
|
|
182
187
|
for tool_call_id in tool_call_ids:
|
|
183
188
|
for idx, tool_result in tool_result_messages:
|
|
184
|
-
tool_result_contents = [c for c in tool_result["content"] if "toolResult" in c]
|
|
189
|
+
tool_result_contents = [c for c in tool_result["content"] if "toolResult" in c or "cachePoint" in c]
|
|
185
190
|
for content in tool_result_contents:
|
|
186
|
-
if content["toolResult"]["toolUseId"] == tool_call_id:
|
|
191
|
+
if "toolResult" in content and content["toolResult"]["toolUseId"] == tool_call_id:
|
|
187
192
|
regrouped_tool_result.append(content)
|
|
188
193
|
# Keep track of the original index of the last tool result message
|
|
189
194
|
original_idx = idx
|
|
195
|
+
elif "cachePoint" in content and content not in regrouped_tool_result:
|
|
196
|
+
regrouped_tool_result.append(content)
|
|
197
|
+
|
|
190
198
|
if regrouped_tool_result and original_idx is not None:
|
|
191
199
|
repaired_tool_result_prompts.append((original_idx, {"role": "user", "content": regrouped_tool_result}))
|
|
192
200
|
|
|
193
201
|
# Remove the tool result messages from bedrock_formatted_messages
|
|
194
202
|
bedrock_formatted_messages_minus_tool_results: list[tuple[int, Any]] = []
|
|
195
203
|
for idx, msg in enumerate(bedrock_formatted_messages):
|
|
196
|
-
#
|
|
197
|
-
if msg.get("content") and "toolResult"
|
|
204
|
+
# Filter out messages that contain toolResult (they are handled by repaired_tool_result_prompts)
|
|
205
|
+
if msg.get("content") and not any("toolResult" in c for c in msg["content"]):
|
|
198
206
|
bedrock_formatted_messages_minus_tool_results.append((idx, msg))
|
|
199
207
|
|
|
200
208
|
# Add the repaired tool result messages and sort to maintain the correct order
|
|
@@ -251,6 +259,32 @@ def _format_text_image_message(message: ChatMessage) -> dict[str, Any]:
|
|
|
251
259
|
return {"role": message.role.value, "content": bedrock_content_blocks}
|
|
252
260
|
|
|
253
261
|
|
|
262
|
+
def _validate_and_format_cache_point(cache_point: dict[str, str] | None) -> dict[str, dict[str, str]] | None:
|
|
263
|
+
"""
|
|
264
|
+
Validate and format a cache point dictionary.
|
|
265
|
+
|
|
266
|
+
Schema available at https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_CachePointBlock.html
|
|
267
|
+
|
|
268
|
+
:param cache_point: Cache point dictionary to validate and format.
|
|
269
|
+
:returns: Dictionary in Bedrock cachePoint format or None if no cache point is provided.
|
|
270
|
+
:raises ValueError: If cache point is not valid.
|
|
271
|
+
"""
|
|
272
|
+
if not cache_point:
|
|
273
|
+
return None
|
|
274
|
+
|
|
275
|
+
if "type" not in cache_point or cache_point["type"] != "default":
|
|
276
|
+
err_msg = "Cache point must have a 'type' key with value 'default'."
|
|
277
|
+
raise ValueError(err_msg)
|
|
278
|
+
if not set(cache_point).issubset({"type", "ttl"}):
|
|
279
|
+
err_msg = "Cache point can only contain 'type' and 'ttl' keys."
|
|
280
|
+
raise ValueError(err_msg)
|
|
281
|
+
if "ttl" in cache_point and cache_point["ttl"] not in ("5m", "1h"):
|
|
282
|
+
err_msg = "Cache point 'ttl' must be one of '5m', '1h'."
|
|
283
|
+
raise ValueError(err_msg)
|
|
284
|
+
|
|
285
|
+
return {"cachePoint": cache_point}
|
|
286
|
+
|
|
287
|
+
|
|
254
288
|
def _format_messages(messages: list[ChatMessage]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
|
|
255
289
|
"""
|
|
256
290
|
Format a list of Haystack ChatMessages to the format expected by Bedrock API.
|
|
@@ -264,21 +298,30 @@ def _format_messages(messages: list[ChatMessage]) -> tuple[list[dict[str, Any]],
|
|
|
264
298
|
non_system_messages is a list of properly formatted message dictionaries.
|
|
265
299
|
"""
|
|
266
300
|
# Separate system messages, tool calls, and tool results
|
|
267
|
-
system_prompts = []
|
|
301
|
+
system_prompts: list[dict[str, Any]] = []
|
|
268
302
|
bedrock_formatted_messages = []
|
|
269
303
|
for msg in messages:
|
|
304
|
+
cache_point = _validate_and_format_cache_point(msg.meta.get("cachePoint"))
|
|
270
305
|
if msg.is_from(ChatRole.SYSTEM):
|
|
271
306
|
# Assuming system messages can only contain text
|
|
272
307
|
# Don't need to track idx since system_messages are handled separately
|
|
273
308
|
system_prompts.append({"text": msg.text})
|
|
274
|
-
|
|
275
|
-
|
|
309
|
+
if cache_point:
|
|
310
|
+
system_prompts.append(cache_point)
|
|
311
|
+
continue
|
|
312
|
+
|
|
313
|
+
if msg.tool_calls:
|
|
314
|
+
formatted_msg = _format_tool_call_message(msg)
|
|
276
315
|
elif msg.tool_call_results:
|
|
277
|
-
|
|
316
|
+
formatted_msg = _format_tool_result_message(msg)
|
|
278
317
|
else:
|
|
279
|
-
|
|
318
|
+
formatted_msg = _format_text_image_message(msg)
|
|
319
|
+
if cache_point:
|
|
320
|
+
formatted_msg["content"].append(cache_point)
|
|
321
|
+
bedrock_formatted_messages.append(formatted_msg)
|
|
280
322
|
|
|
281
323
|
repaired_bedrock_formatted_messages = _repair_tool_result_messages(bedrock_formatted_messages)
|
|
324
|
+
|
|
282
325
|
return system_prompts, repaired_bedrock_formatted_messages
|
|
283
326
|
|
|
284
327
|
|
|
@@ -310,6 +353,9 @@ def _parse_completion_response(response_body: dict[str, Any], model: str) -> lis
|
|
|
310
353
|
"prompt_tokens": response_body.get("usage", {}).get("inputTokens", 0),
|
|
311
354
|
"completion_tokens": response_body.get("usage", {}).get("outputTokens", 0),
|
|
312
355
|
"total_tokens": response_body.get("usage", {}).get("totalTokens", 0),
|
|
356
|
+
"cache_read_input_tokens": response_body.get("usage", {}).get("cacheReadInputTokens", 0),
|
|
357
|
+
"cache_write_input_tokens": response_body.get("usage", {}).get("cacheWriteInputTokens", 0),
|
|
358
|
+
"cache_details": response_body.get("usage", {}).get("CacheDetails", {}),
|
|
313
359
|
},
|
|
314
360
|
}
|
|
315
361
|
# guardrail trace
|
|
@@ -461,6 +507,9 @@ def _convert_event_to_streaming_chunk(
|
|
|
461
507
|
"prompt_tokens": usage.get("inputTokens", 0),
|
|
462
508
|
"completion_tokens": usage.get("outputTokens", 0),
|
|
463
509
|
"total_tokens": usage.get("totalTokens", 0),
|
|
510
|
+
"cache_read_input_tokens": usage.get("cacheReadInputTokens", 0),
|
|
511
|
+
"cache_write_input_tokens": usage.get("cacheWriteInputTokens", 0),
|
|
512
|
+
"cache_details": usage.get("cacheDetails", {}),
|
|
464
513
|
}
|
|
465
514
|
if "trace" in event_meta:
|
|
466
515
|
chunk_meta["trace"] = event_meta["trace"]
|
|
@@ -8,7 +8,7 @@ from botocore.config import Config
|
|
|
8
8
|
from botocore.exceptions import ClientError
|
|
9
9
|
from haystack import component, default_from_dict, default_to_dict, logging
|
|
10
10
|
from haystack.dataclasses import StreamingChunk
|
|
11
|
-
from haystack.utils import Secret, deserialize_callable,
|
|
11
|
+
from haystack.utils import Secret, deserialize_callable, serialize_callable
|
|
12
12
|
|
|
13
13
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
14
14
|
AmazonBedrockConfigurationError,
|
|
@@ -287,11 +287,11 @@ class AmazonBedrockGenerator:
|
|
|
287
287
|
callback_name = serialize_callable(self.streaming_callback) if self.streaming_callback else None
|
|
288
288
|
return default_to_dict(
|
|
289
289
|
self,
|
|
290
|
-
aws_access_key_id=self.aws_access_key_id
|
|
291
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
292
|
-
aws_session_token=self.aws_session_token
|
|
293
|
-
aws_region_name=self.aws_region_name
|
|
294
|
-
aws_profile_name=self.aws_profile_name
|
|
290
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
291
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
292
|
+
aws_session_token=self.aws_session_token,
|
|
293
|
+
aws_region_name=self.aws_region_name,
|
|
294
|
+
aws_profile_name=self.aws_profile_name,
|
|
295
295
|
model=self.model,
|
|
296
296
|
max_length=self.max_length,
|
|
297
297
|
streaming_callback=callback_name,
|
|
@@ -310,10 +310,6 @@ class AmazonBedrockGenerator:
|
|
|
310
310
|
:returns:
|
|
311
311
|
Deserialized component.
|
|
312
312
|
"""
|
|
313
|
-
deserialize_secrets_inplace(
|
|
314
|
-
data["init_parameters"],
|
|
315
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
316
|
-
)
|
|
317
313
|
init_params = data.get("init_parameters", {})
|
|
318
314
|
serialized_callback_handler = init_params.get("streaming_callback")
|
|
319
315
|
if serialized_callback_handler:
|
|
@@ -3,7 +3,7 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from botocore.exceptions import ClientError
|
|
5
5
|
from haystack import Document, component, default_from_dict, default_to_dict, logging
|
|
6
|
-
from haystack.utils import Secret
|
|
6
|
+
from haystack.utils import Secret
|
|
7
7
|
|
|
8
8
|
from haystack_integrations.common.amazon_bedrock.errors import (
|
|
9
9
|
AmazonBedrockConfigurationError,
|
|
@@ -133,11 +133,11 @@ class AmazonBedrockRanker:
|
|
|
133
133
|
return default_to_dict(
|
|
134
134
|
self,
|
|
135
135
|
model=self.model_name,
|
|
136
|
-
aws_access_key_id=self.aws_access_key_id
|
|
137
|
-
aws_secret_access_key=self.aws_secret_access_key
|
|
138
|
-
aws_session_token=self.aws_session_token
|
|
139
|
-
aws_region_name=self.aws_region_name
|
|
140
|
-
aws_profile_name=self.aws_profile_name
|
|
136
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
137
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
138
|
+
aws_session_token=self.aws_session_token,
|
|
139
|
+
aws_region_name=self.aws_region_name,
|
|
140
|
+
aws_profile_name=self.aws_profile_name,
|
|
141
141
|
top_k=self.top_k,
|
|
142
142
|
max_chunks_per_doc=self.max_chunks_per_doc,
|
|
143
143
|
meta_fields_to_embed=self.meta_fields_to_embed,
|
|
@@ -154,10 +154,6 @@ class AmazonBedrockRanker:
|
|
|
154
154
|
:returns:
|
|
155
155
|
The deserialized component.
|
|
156
156
|
"""
|
|
157
|
-
deserialize_secrets_inplace(
|
|
158
|
-
data["init_parameters"],
|
|
159
|
-
["aws_access_key_id", "aws_secret_access_key", "aws_session_token", "aws_region_name", "aws_profile_name"],
|
|
160
|
-
)
|
|
161
157
|
return default_from_dict(cls, data)
|
|
162
158
|
|
|
163
159
|
def _prepare_bedrock_input_docs(self, documents: list[Document]) -> list[str]:
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_chat_generator.py
RENAMED
|
@@ -39,6 +39,10 @@ MODELS_TO_TEST_WITH_THINKING = [
|
|
|
39
39
|
"us.anthropic.claude-sonnet-4-20250514-v1:0",
|
|
40
40
|
]
|
|
41
41
|
|
|
42
|
+
MODELS_TO_TEST_WITH_PROMPT_CACHING = [
|
|
43
|
+
"amazon.nova-micro-v1:0" # cheap, fast model
|
|
44
|
+
]
|
|
45
|
+
|
|
42
46
|
|
|
43
47
|
def hello_world():
|
|
44
48
|
return "Hello, World!"
|
|
@@ -164,6 +168,7 @@ class TestAmazonBedrockChatGenerator:
|
|
|
164
168
|
"boto3_config": boto3_config,
|
|
165
169
|
"tools": None,
|
|
166
170
|
"guardrail_config": {"guardrailIdentifier": "test", "guardrailVersion": "test"},
|
|
171
|
+
"tools_cachepoint_config": None,
|
|
167
172
|
},
|
|
168
173
|
}
|
|
169
174
|
|
|
@@ -298,6 +303,7 @@ class TestAmazonBedrockChatGenerator:
|
|
|
298
303
|
}
|
|
299
304
|
],
|
|
300
305
|
"guardrail_config": None,
|
|
306
|
+
"tools_cachepoint_config": None,
|
|
301
307
|
},
|
|
302
308
|
}
|
|
303
309
|
},
|
|
@@ -945,6 +951,28 @@ class TestAmazonBedrockChatGeneratorInference:
|
|
|
945
951
|
assert "trace" in results["replies"][0].meta
|
|
946
952
|
assert "guardrail" in results["replies"][0].meta["trace"]
|
|
947
953
|
|
|
954
|
+
@pytest.mark.parametrize("streaming_callback", [None, print_streaming_chunk])
|
|
955
|
+
@pytest.mark.parametrize("model_name", MODELS_TO_TEST_WITH_PROMPT_CACHING)
|
|
956
|
+
def test_prompt_caching_live_run_with_user_message(self, model_name, streaming_callback):
|
|
957
|
+
generator = AmazonBedrockChatGenerator(model=model_name, streaming_callback=streaming_callback)
|
|
958
|
+
|
|
959
|
+
system_message = ChatMessage.from_system("Always respond with: 'Life is beautiful' (and nothing else).")
|
|
960
|
+
|
|
961
|
+
user_message = ChatMessage.from_user(
|
|
962
|
+
"User message that should be long enough to cache. " * 100, meta={"cachePoint": {"type": "default"}}
|
|
963
|
+
)
|
|
964
|
+
messages = [system_message, user_message]
|
|
965
|
+
result = generator.run(messages=messages)
|
|
966
|
+
|
|
967
|
+
assert "replies" in result
|
|
968
|
+
assert len(result["replies"]) == 1
|
|
969
|
+
usage = result["replies"][0].meta["usage"]
|
|
970
|
+
|
|
971
|
+
# tests run in parallel based on the workflow matrix, so this request should either hit the cache (read tokens)
|
|
972
|
+
# or populate it (write tokens)
|
|
973
|
+
assert usage["cache_read_input_tokens"] > 1000 or usage["cache_write_input_tokens"] > 1000
|
|
974
|
+
assert "cache_details" in usage
|
|
975
|
+
|
|
948
976
|
@pytest.mark.parametrize("model_name", [MODELS_TO_TEST_WITH_TOOLS[0]]) # just one model is enough
|
|
949
977
|
def test_pipeline_with_amazon_bedrock_chat_generator(self, model_name, tools):
|
|
950
978
|
"""
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_chat_generator_utils.py
RENAMED
|
@@ -22,6 +22,7 @@ from haystack_integrations.components.generators.amazon_bedrock.chat.utils impor
|
|
|
22
22
|
_format_tools,
|
|
23
23
|
_parse_completion_response,
|
|
24
24
|
_parse_streaming_response,
|
|
25
|
+
_validate_and_format_cache_point,
|
|
25
26
|
_validate_guardrail_config,
|
|
26
27
|
)
|
|
27
28
|
|
|
@@ -59,7 +60,7 @@ def tools():
|
|
|
59
60
|
|
|
60
61
|
class TestAmazonBedrockChatGeneratorUtils:
|
|
61
62
|
def test_format_tools(self, tools):
|
|
62
|
-
formatted_tool = _format_tools(tools)
|
|
63
|
+
formatted_tool = _format_tools(tools, tools_cachepoint_config={"type": "default"})
|
|
63
64
|
assert formatted_tool == {
|
|
64
65
|
"tools": [
|
|
65
66
|
{
|
|
@@ -84,7 +85,8 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
84
85
|
},
|
|
85
86
|
}
|
|
86
87
|
},
|
|
87
|
-
|
|
88
|
+
{"cachePoint": {"type": "default"}},
|
|
89
|
+
],
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
def test_format_messages(self):
|
|
@@ -121,6 +123,52 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
121
123
|
{"role": "assistant", "content": [{"text": "The weather in Paris is sunny and 25°C."}]},
|
|
122
124
|
]
|
|
123
125
|
|
|
126
|
+
def test_format_messages_with_cache_point(self):
|
|
127
|
+
meta = {"cachePoint": {"type": "default"}}
|
|
128
|
+
|
|
129
|
+
messages = [
|
|
130
|
+
ChatMessage.from_system("\\nYou are a helpful assistant, be super brief in your responses.", meta=meta),
|
|
131
|
+
ChatMessage.from_user("What is the weather in Paris?", meta=meta),
|
|
132
|
+
ChatMessage.from_assistant(
|
|
133
|
+
tool_calls=[ToolCall(id="123", tool_name="weather", arguments={"city": "Paris"})], meta=meta
|
|
134
|
+
),
|
|
135
|
+
ChatMessage.from_tool(
|
|
136
|
+
tool_result="Sunny and 25°C",
|
|
137
|
+
origin=ToolCall(id="123", tool_name="weather", arguments={"city": "Paris"}),
|
|
138
|
+
meta=meta,
|
|
139
|
+
),
|
|
140
|
+
ChatMessage.from_assistant("The weather in Paris is sunny and 25°C.", meta=meta),
|
|
141
|
+
]
|
|
142
|
+
formatted_system_prompts, formatted_messages = _format_messages(messages)
|
|
143
|
+
assert formatted_system_prompts == [
|
|
144
|
+
{"text": "\\nYou are a helpful assistant, be super brief in your responses."},
|
|
145
|
+
{"cachePoint": {"type": "default"}},
|
|
146
|
+
]
|
|
147
|
+
assert formatted_messages == [
|
|
148
|
+
{
|
|
149
|
+
"role": "user",
|
|
150
|
+
"content": [{"text": "What is the weather in Paris?"}, {"cachePoint": {"type": "default"}}],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"role": "assistant",
|
|
154
|
+
"content": [
|
|
155
|
+
{"toolUse": {"toolUseId": "123", "name": "weather", "input": {"city": "Paris"}}},
|
|
156
|
+
{"cachePoint": {"type": "default"}},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"role": "user",
|
|
161
|
+
"content": [
|
|
162
|
+
{"toolResult": {"toolUseId": "123", "content": [{"text": "Sunny and 25°C"}]}},
|
|
163
|
+
{"cachePoint": {"type": "default"}},
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"role": "assistant",
|
|
168
|
+
"content": [{"text": "The weather in Paris is sunny and 25°C."}, {"cachePoint": {"type": "default"}}],
|
|
169
|
+
},
|
|
170
|
+
]
|
|
171
|
+
|
|
124
172
|
def test_format_messages_tool_result_with_image(self):
|
|
125
173
|
base64_image = (
|
|
126
174
|
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=="
|
|
@@ -420,7 +468,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
420
468
|
text_response = {
|
|
421
469
|
"output": {"message": {"role": "assistant", "content": [{"text": "This is a test response"}]}},
|
|
422
470
|
"stopReason": "end_turn",
|
|
423
|
-
"usage": {
|
|
471
|
+
"usage": {
|
|
472
|
+
"inputTokens": 10,
|
|
473
|
+
"outputTokens": 20,
|
|
474
|
+
"totalTokens": 30,
|
|
475
|
+
"cacheReadInputTokens": 1000,
|
|
476
|
+
"cacheWriteInputTokens": 0,
|
|
477
|
+
"cacheDetails": {},
|
|
478
|
+
},
|
|
424
479
|
}
|
|
425
480
|
|
|
426
481
|
replies = _parse_completion_response(text_response, model)
|
|
@@ -430,7 +485,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
430
485
|
assert replies[0].meta == {
|
|
431
486
|
"model": model,
|
|
432
487
|
"finish_reason": "stop",
|
|
433
|
-
"usage": {
|
|
488
|
+
"usage": {
|
|
489
|
+
"prompt_tokens": 10,
|
|
490
|
+
"completion_tokens": 20,
|
|
491
|
+
"total_tokens": 30,
|
|
492
|
+
"cache_read_input_tokens": 1000,
|
|
493
|
+
"cache_write_input_tokens": 0,
|
|
494
|
+
"cache_details": {},
|
|
495
|
+
},
|
|
434
496
|
"index": 0,
|
|
435
497
|
}
|
|
436
498
|
|
|
@@ -457,7 +519,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
457
519
|
assert replies[0].meta == {
|
|
458
520
|
"model": model,
|
|
459
521
|
"finish_reason": "tool_calls",
|
|
460
|
-
"usage": {
|
|
522
|
+
"usage": {
|
|
523
|
+
"prompt_tokens": 15,
|
|
524
|
+
"completion_tokens": 25,
|
|
525
|
+
"total_tokens": 40,
|
|
526
|
+
"cache_read_input_tokens": 0,
|
|
527
|
+
"cache_write_input_tokens": 0,
|
|
528
|
+
"cache_details": {},
|
|
529
|
+
},
|
|
461
530
|
"index": 0,
|
|
462
531
|
}
|
|
463
532
|
|
|
@@ -488,7 +557,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
488
557
|
assert replies[0].meta == {
|
|
489
558
|
"model": model,
|
|
490
559
|
"finish_reason": "stop",
|
|
491
|
-
"usage": {
|
|
560
|
+
"usage": {
|
|
561
|
+
"prompt_tokens": 25,
|
|
562
|
+
"completion_tokens": 35,
|
|
563
|
+
"total_tokens": 60,
|
|
564
|
+
"cache_read_input_tokens": 0,
|
|
565
|
+
"cache_write_input_tokens": 0,
|
|
566
|
+
"cache_details": {},
|
|
567
|
+
},
|
|
492
568
|
"index": 0,
|
|
493
569
|
}
|
|
494
570
|
|
|
@@ -556,7 +632,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
556
632
|
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0",
|
|
557
633
|
"index": 0,
|
|
558
634
|
"finish_reason": "tool_calls",
|
|
559
|
-
"usage": {
|
|
635
|
+
"usage": {
|
|
636
|
+
"prompt_tokens": 366,
|
|
637
|
+
"completion_tokens": 134,
|
|
638
|
+
"total_tokens": 500,
|
|
639
|
+
"cache_read_input_tokens": 0,
|
|
640
|
+
"cache_write_input_tokens": 0,
|
|
641
|
+
"cache_details": {},
|
|
642
|
+
},
|
|
560
643
|
},
|
|
561
644
|
)
|
|
562
645
|
assert replies[0] == expected_message
|
|
@@ -610,6 +693,7 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
610
693
|
"totalTokens": 558,
|
|
611
694
|
"cacheReadInputTokens": 0,
|
|
612
695
|
"cacheWriteInputTokens": 0,
|
|
696
|
+
"cacheDetails": {},
|
|
613
697
|
},
|
|
614
698
|
"metrics": {"latencyMs": 4811},
|
|
615
699
|
}
|
|
@@ -646,7 +730,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
646
730
|
"model": "arn:aws:bedrock:us-east-1::inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0",
|
|
647
731
|
"index": 0,
|
|
648
732
|
"finish_reason": "tool_calls",
|
|
649
|
-
"usage": {
|
|
733
|
+
"usage": {
|
|
734
|
+
"prompt_tokens": 412,
|
|
735
|
+
"completion_tokens": 146,
|
|
736
|
+
"total_tokens": 558,
|
|
737
|
+
"cache_read_input_tokens": 0,
|
|
738
|
+
"cache_write_input_tokens": 0,
|
|
739
|
+
"cache_details": {},
|
|
740
|
+
},
|
|
650
741
|
},
|
|
651
742
|
)
|
|
652
743
|
assert replies[0] == expected_message
|
|
@@ -712,7 +803,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
712
803
|
"model": model,
|
|
713
804
|
"finish_reason": "content_filter",
|
|
714
805
|
"index": 0,
|
|
715
|
-
"usage": {
|
|
806
|
+
"usage": {
|
|
807
|
+
"prompt_tokens": 0,
|
|
808
|
+
"completion_tokens": 0,
|
|
809
|
+
"total_tokens": 0,
|
|
810
|
+
"cache_read_input_tokens": 0,
|
|
811
|
+
"cache_write_input_tokens": 0,
|
|
812
|
+
"cache_details": {},
|
|
813
|
+
},
|
|
716
814
|
"trace": trace,
|
|
717
815
|
}
|
|
718
816
|
|
|
@@ -784,7 +882,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
784
882
|
"model": model,
|
|
785
883
|
"index": 0,
|
|
786
884
|
"finish_reason": "tool_calls",
|
|
787
|
-
"usage": {
|
|
885
|
+
"usage": {
|
|
886
|
+
"prompt_tokens": 364,
|
|
887
|
+
"completion_tokens": 71,
|
|
888
|
+
"total_tokens": 435,
|
|
889
|
+
"cache_read_input_tokens": 0,
|
|
890
|
+
"cache_write_input_tokens": 0,
|
|
891
|
+
"cache_details": {},
|
|
892
|
+
},
|
|
788
893
|
},
|
|
789
894
|
)
|
|
790
895
|
]
|
|
@@ -852,7 +957,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
852
957
|
meta={
|
|
853
958
|
"model": model,
|
|
854
959
|
"received_at": ANY,
|
|
855
|
-
"usage": {
|
|
960
|
+
"usage": {
|
|
961
|
+
"prompt_tokens": 364,
|
|
962
|
+
"completion_tokens": 71,
|
|
963
|
+
"total_tokens": 435,
|
|
964
|
+
"cache_read_input_tokens": 0,
|
|
965
|
+
"cache_write_input_tokens": 0,
|
|
966
|
+
"cache_details": {},
|
|
967
|
+
},
|
|
856
968
|
},
|
|
857
969
|
component_info=c_info,
|
|
858
970
|
),
|
|
@@ -976,7 +1088,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
976
1088
|
"model": "arn:aws:bedrock:us-east-1::inference-profile/us.anthropic.claude-sonnet-4-20250514-v1:0",
|
|
977
1089
|
"index": 0,
|
|
978
1090
|
"finish_reason": "tool_calls",
|
|
979
|
-
"usage": {
|
|
1091
|
+
"usage": {
|
|
1092
|
+
"prompt_tokens": 412,
|
|
1093
|
+
"completion_tokens": 104,
|
|
1094
|
+
"total_tokens": 516,
|
|
1095
|
+
"cache_read_input_tokens": 0,
|
|
1096
|
+
"cache_write_input_tokens": 0,
|
|
1097
|
+
"cache_details": {},
|
|
1098
|
+
},
|
|
980
1099
|
"completion_start_time": ANY,
|
|
981
1100
|
},
|
|
982
1101
|
)
|
|
@@ -1062,7 +1181,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
1062
1181
|
"model": model,
|
|
1063
1182
|
"index": 0,
|
|
1064
1183
|
"finish_reason": "stop",
|
|
1065
|
-
"usage": {
|
|
1184
|
+
"usage": {
|
|
1185
|
+
"prompt_tokens": 461,
|
|
1186
|
+
"completion_tokens": 138,
|
|
1187
|
+
"total_tokens": 599,
|
|
1188
|
+
"cache_read_input_tokens": 0,
|
|
1189
|
+
"cache_write_input_tokens": 0,
|
|
1190
|
+
"cache_details": {},
|
|
1191
|
+
},
|
|
1066
1192
|
"completion_start_time": ANY,
|
|
1067
1193
|
},
|
|
1068
1194
|
)
|
|
@@ -1140,7 +1266,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
1140
1266
|
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0",
|
|
1141
1267
|
"index": 0,
|
|
1142
1268
|
"finish_reason": "tool_calls",
|
|
1143
|
-
"usage": {
|
|
1269
|
+
"usage": {
|
|
1270
|
+
"prompt_tokens": 366,
|
|
1271
|
+
"completion_tokens": 83,
|
|
1272
|
+
"total_tokens": 449,
|
|
1273
|
+
"cache_read_input_tokens": 0,
|
|
1274
|
+
"cache_write_input_tokens": 0,
|
|
1275
|
+
"cache_details": {},
|
|
1276
|
+
},
|
|
1144
1277
|
"completion_start_time": ANY,
|
|
1145
1278
|
},
|
|
1146
1279
|
)
|
|
@@ -1216,7 +1349,14 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
1216
1349
|
"model": model,
|
|
1217
1350
|
"index": 0,
|
|
1218
1351
|
"finish_reason": "content_filter",
|
|
1219
|
-
"usage": {
|
|
1352
|
+
"usage": {
|
|
1353
|
+
"prompt_tokens": 0,
|
|
1354
|
+
"completion_tokens": 0,
|
|
1355
|
+
"total_tokens": 0,
|
|
1356
|
+
"cache_read_input_tokens": 0,
|
|
1357
|
+
"cache_write_input_tokens": 0,
|
|
1358
|
+
"cache_details": {},
|
|
1359
|
+
},
|
|
1220
1360
|
"trace": trace,
|
|
1221
1361
|
},
|
|
1222
1362
|
)
|
|
@@ -1450,3 +1590,25 @@ class TestAmazonBedrockChatGeneratorUtils:
|
|
|
1450
1590
|
},
|
|
1451
1591
|
streaming=False,
|
|
1452
1592
|
)
|
|
1593
|
+
|
|
1594
|
+
def test_validate_and_format_cache_point(self):
|
|
1595
|
+
cache_point = _validate_and_format_cache_point(None)
|
|
1596
|
+
assert cache_point is None
|
|
1597
|
+
|
|
1598
|
+
cache_point = _validate_and_format_cache_point({})
|
|
1599
|
+
assert cache_point is None
|
|
1600
|
+
|
|
1601
|
+
cache_point = _validate_and_format_cache_point({"type": "default"})
|
|
1602
|
+
assert cache_point == {"cachePoint": {"type": "default"}}
|
|
1603
|
+
|
|
1604
|
+
cache_point = _validate_and_format_cache_point({"type": "default", "ttl": "5m"})
|
|
1605
|
+
assert cache_point == {"cachePoint": {"type": "default", "ttl": "5m"}}
|
|
1606
|
+
|
|
1607
|
+
with pytest.raises(ValueError, match=r"Cache point must have a 'type' key with value 'default'."):
|
|
1608
|
+
_validate_and_format_cache_point({"invalid": "config"})
|
|
1609
|
+
|
|
1610
|
+
with pytest.raises(ValueError, match=r"Cache point must have a 'type' key with value 'default'."):
|
|
1611
|
+
_validate_and_format_cache_point({"type": "invalid"})
|
|
1612
|
+
|
|
1613
|
+
with pytest.raises(ValueError, match=r"Cache point can only contain 'type' and 'ttl' keys."):
|
|
1614
|
+
_validate_and_format_cache_point({"type": "default", "invalid": "config"})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/bedrock_ranker_example.py
RENAMED
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/chatgenerator_example.py
RENAMED
|
File without changes
|
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/examples/s3_downloader_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_document_embedder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_files/haystack-logo.png
RENAMED
|
File without changes
|
{amazon_bedrock_haystack-6.3.0 → amazon_bedrock_haystack-6.4.0}/tests/test_files/sample_pdf_1.pdf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|