amazon-bedrock-haystack 6.2.1__py3-none-any.whl → 6.4.0__py3-none-any.whl
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.2.1.dist-info → amazon_bedrock_haystack-6.4.0.dist-info}/METADATA +2 -2
- {amazon_bedrock_haystack-6.2.1.dist-info → amazon_bedrock_haystack-6.4.0.dist-info}/RECORD +12 -12
- haystack_integrations/components/downloaders/s3/s3_downloader.py +6 -10
- haystack_integrations/components/embedders/amazon_bedrock/document_embedder.py +6 -10
- haystack_integrations/components/embedders/amazon_bedrock/document_image_embedder.py +6 -17
- haystack_integrations/components/embedders/amazon_bedrock/text_embedder.py +6 -10
- haystack_integrations/components/generators/amazon_bedrock/chat/chat_generator.py +24 -11
- haystack_integrations/components/generators/amazon_bedrock/chat/utils.py +99 -30
- haystack_integrations/components/generators/amazon_bedrock/generator.py +6 -10
- haystack_integrations/components/rankers/amazon_bedrock/ranker.py +6 -10
- {amazon_bedrock_haystack-6.2.1.dist-info → amazon_bedrock_haystack-6.4.0.dist-info}/WHEEL +0 -0
- {amazon_bedrock_haystack-6.2.1.dist-info → amazon_bedrock_haystack-6.4.0.dist-info}/licenses/LICENSE.txt +0 -0
{amazon_bedrock_haystack-6.2.1.dist-info → amazon_bedrock_haystack-6.4.0.dist-info}/METADATA
RENAMED
|
@@ -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
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
21
|
Requires-Dist: aioboto3>=14.0.0
|
|
22
22
|
Requires-Dist: boto3>=1.28.57
|
|
23
|
-
Requires-Dist: haystack-ai>=2.
|
|
23
|
+
Requires-Dist: haystack-ai>=2.23.0
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
25
|
|
|
26
26
|
# amazon-bedrock-haystack
|
|
@@ -7,23 +7,23 @@ haystack_integrations/common/s3/errors.py,sha256=BrTDLdhQvAuQutyg35cFyP5h8PNkDEi
|
|
|
7
7
|
haystack_integrations/common/s3/utils.py,sha256=lrPTc4r0l9Bm6dACxCDgvcbDPPtuxjU6nzTDFw4g2Fs,4707
|
|
8
8
|
haystack_integrations/components/downloaders/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
haystack_integrations/components/downloaders/s3/__init__.py,sha256=2BOd3_N0kGqRJGH-ENrTJqOqzqHryRYaSuNqpLYKMFo,179
|
|
10
|
-
haystack_integrations/components/downloaders/s3/s3_downloader.py,sha256=
|
|
10
|
+
haystack_integrations/components/downloaders/s3/s3_downloader.py,sha256=LQw-rIvC1q-Cc9mZkgn-KzBS9Z6W9S8roiigxCNAmpE,12011
|
|
11
11
|
haystack_integrations/components/embedders/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
haystack_integrations/components/embedders/amazon_bedrock/__init__.py,sha256=7GlhHJ4jFHCxq5QN5losGuGtrGNjvEx2dSQvEYD2yG0,408
|
|
13
|
-
haystack_integrations/components/embedders/amazon_bedrock/document_embedder.py,sha256=
|
|
14
|
-
haystack_integrations/components/embedders/amazon_bedrock/document_image_embedder.py,sha256=
|
|
15
|
-
haystack_integrations/components/embedders/amazon_bedrock/text_embedder.py,sha256=
|
|
13
|
+
haystack_integrations/components/embedders/amazon_bedrock/document_embedder.py,sha256=OG3RcsVPDEA3bJAlpotgXoOD3PfrBeTjTF8Q0N5RKSI,12895
|
|
14
|
+
haystack_integrations/components/embedders/amazon_bedrock/document_image_embedder.py,sha256=TSAnekrEFZ5MX5bWSoHZlYulSh-aKFRvZwyyKfbS0G8,15577
|
|
15
|
+
haystack_integrations/components/embedders/amazon_bedrock/text_embedder.py,sha256=Z5-PUtyiE1_7tgDAj6CqxUVI09WwmwJavfGJ-pO9GlA,8851
|
|
16
16
|
haystack_integrations/components/generators/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
haystack_integrations/components/generators/amazon_bedrock/__init__.py,sha256=lv4NouIVm78YavUssWQrHHP_81u-7j21qW8v1kZMJPQ,284
|
|
18
18
|
haystack_integrations/components/generators/amazon_bedrock/adapters.py,sha256=4-gIWfw70hGaXMNS30UbJFNFCWK2KG6RMnT_4z5RHxc,19625
|
|
19
|
-
haystack_integrations/components/generators/amazon_bedrock/generator.py,sha256=
|
|
19
|
+
haystack_integrations/components/generators/amazon_bedrock/generator.py,sha256=p52Fq63lzp6UkAygBfiZqFigOT-XOrIZX1F7BiHoAAI,14437
|
|
20
20
|
haystack_integrations/components/generators/amazon_bedrock/chat/__init__.py,sha256=6GZ8Y3Lw0rLOsOAqi6Tu5mZC977UzQvgDxKpOWr8IQw,110
|
|
21
|
-
haystack_integrations/components/generators/amazon_bedrock/chat/chat_generator.py,sha256=
|
|
22
|
-
haystack_integrations/components/generators/amazon_bedrock/chat/utils.py,sha256=
|
|
21
|
+
haystack_integrations/components/generators/amazon_bedrock/chat/chat_generator.py,sha256=F6GTX021cHar3WoaTp2gY9Wqx5JSdv_1rFmP5iX9szM,28437
|
|
22
|
+
haystack_integrations/components/generators/amazon_bedrock/chat/utils.py,sha256=2tbyU0I1tQ6FjpqegVlr97c3zzkvOBSS1-Cx5dKJ-2w,30334
|
|
23
23
|
haystack_integrations/components/rankers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
haystack_integrations/components/rankers/amazon_bedrock/__init__.py,sha256=mJQKShAP5AfZvfKQisSh7kfKu6RIXzsYdk4eqMtcaEk,75
|
|
25
|
-
haystack_integrations/components/rankers/amazon_bedrock/ranker.py,sha256=
|
|
26
|
-
amazon_bedrock_haystack-6.
|
|
27
|
-
amazon_bedrock_haystack-6.
|
|
28
|
-
amazon_bedrock_haystack-6.
|
|
29
|
-
amazon_bedrock_haystack-6.
|
|
25
|
+
haystack_integrations/components/rankers/amazon_bedrock/ranker.py,sha256=CozmHnmLX2bfAXNyCS29ofIzCs-oIF436opsUdipBXI,11305
|
|
26
|
+
amazon_bedrock_haystack-6.4.0.dist-info/METADATA,sha256=UXrT6hxyNx-0UUAprInGPIVAMgDWLDMyiNQcA8ADn0o,2179
|
|
27
|
+
amazon_bedrock_haystack-6.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
28
|
+
amazon_bedrock_haystack-6.4.0.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
|
|
29
|
+
amazon_bedrock_haystack-6.4.0.dist-info/RECORD,,
|
|
@@ -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,34 @@ 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}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _convert_image_content_to_bedrock_format(image_content: ImageContent) -> dict[str, Any]:
|
|
69
|
+
"""
|
|
70
|
+
Convert a Haystack ImageContent to Bedrock format.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
image_format = image_content.mime_type.split("/")[-1] if image_content.mime_type else None
|
|
74
|
+
if image_format not in IMAGE_SUPPORTED_FORMATS:
|
|
75
|
+
err_msg = (
|
|
76
|
+
f"Unsupported image format: {image_format}. "
|
|
77
|
+
f"Bedrock supports the following image formats: {IMAGE_SUPPORTED_FORMATS}"
|
|
78
|
+
)
|
|
79
|
+
raise ValueError(err_msg)
|
|
80
|
+
|
|
81
|
+
source = {"bytes": base64.b64decode(image_content.base64_image)}
|
|
82
|
+
|
|
83
|
+
return {"image": {"format": image_format, "source": source}}
|
|
61
84
|
|
|
62
85
|
|
|
63
86
|
def _format_tool_call_message(tool_call_message: ChatMessage) -> dict[str, Any]:
|
|
@@ -94,19 +117,30 @@ def _format_tool_result_message(tool_call_result_message: ChatMessage) -> dict[s
|
|
|
94
117
|
"""
|
|
95
118
|
# Assuming tool call result messages will only contain tool results
|
|
96
119
|
tool_results = []
|
|
97
|
-
for
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
120
|
+
for tool_call_result in tool_call_result_message.tool_call_results:
|
|
121
|
+
if isinstance(tool_call_result.result, str):
|
|
122
|
+
try:
|
|
123
|
+
json_result = json.loads(tool_call_result.result)
|
|
124
|
+
content = [{"json": json_result}]
|
|
125
|
+
except json.JSONDecodeError:
|
|
126
|
+
content = [{"text": tool_call_result.result}]
|
|
127
|
+
elif isinstance(tool_call_result.result, list):
|
|
128
|
+
content = []
|
|
129
|
+
for item in tool_call_result.result:
|
|
130
|
+
if isinstance(item, TextContent):
|
|
131
|
+
content.append({"text": item.text})
|
|
132
|
+
elif isinstance(item, ImageContent):
|
|
133
|
+
content.append(_convert_image_content_to_bedrock_format(item))
|
|
134
|
+
else:
|
|
135
|
+
err_msg = "Unsupported content type in tool call result"
|
|
136
|
+
raise ValueError(err_msg)
|
|
103
137
|
|
|
104
138
|
tool_results.append(
|
|
105
139
|
{
|
|
106
140
|
"toolResult": {
|
|
107
|
-
"toolUseId":
|
|
141
|
+
"toolUseId": tool_call_result.origin.id,
|
|
108
142
|
"content": content,
|
|
109
|
-
**({"status": "error"} if
|
|
143
|
+
**({"status": "error"} if tool_call_result.error else {}),
|
|
110
144
|
}
|
|
111
145
|
}
|
|
112
146
|
)
|
|
@@ -152,20 +186,23 @@ def _repair_tool_result_messages(bedrock_formatted_messages: list[dict[str, Any]
|
|
|
152
186
|
original_idx = None
|
|
153
187
|
for tool_call_id in tool_call_ids:
|
|
154
188
|
for idx, tool_result in tool_result_messages:
|
|
155
|
-
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]
|
|
156
190
|
for content in tool_result_contents:
|
|
157
|
-
if content["toolResult"]["toolUseId"] == tool_call_id:
|
|
191
|
+
if "toolResult" in content and content["toolResult"]["toolUseId"] == tool_call_id:
|
|
158
192
|
regrouped_tool_result.append(content)
|
|
159
193
|
# Keep track of the original index of the last tool result message
|
|
160
194
|
original_idx = idx
|
|
195
|
+
elif "cachePoint" in content and content not in regrouped_tool_result:
|
|
196
|
+
regrouped_tool_result.append(content)
|
|
197
|
+
|
|
161
198
|
if regrouped_tool_result and original_idx is not None:
|
|
162
199
|
repaired_tool_result_prompts.append((original_idx, {"role": "user", "content": regrouped_tool_result}))
|
|
163
200
|
|
|
164
201
|
# Remove the tool result messages from bedrock_formatted_messages
|
|
165
202
|
bedrock_formatted_messages_minus_tool_results: list[tuple[int, Any]] = []
|
|
166
203
|
for idx, msg in enumerate(bedrock_formatted_messages):
|
|
167
|
-
#
|
|
168
|
-
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"]):
|
|
169
206
|
bedrock_formatted_messages_minus_tool_results.append((idx, msg))
|
|
170
207
|
|
|
171
208
|
# Add the repaired tool result messages and sort to maintain the correct order
|
|
@@ -217,20 +254,37 @@ def _format_text_image_message(message: ChatMessage) -> dict[str, Any]:
|
|
|
217
254
|
if message.is_from(ChatRole.ASSISTANT):
|
|
218
255
|
err_msg = "Image content is not supported for assistant messages"
|
|
219
256
|
raise ValueError(err_msg)
|
|
220
|
-
|
|
221
|
-
image_format = part.mime_type.split("/")[-1] if part.mime_type else None
|
|
222
|
-
if image_format not in IMAGE_SUPPORTED_FORMATS:
|
|
223
|
-
err_msg = (
|
|
224
|
-
f"Unsupported image format: {image_format}. "
|
|
225
|
-
f"Bedrock supports the following image formats: {IMAGE_SUPPORTED_FORMATS}"
|
|
226
|
-
)
|
|
227
|
-
raise ValueError(err_msg)
|
|
228
|
-
source = {"bytes": base64.b64decode(part.base64_image)}
|
|
229
|
-
bedrock_content_blocks.append({"image": {"format": image_format, "source": source}})
|
|
257
|
+
bedrock_content_blocks.append(_convert_image_content_to_bedrock_format(part))
|
|
230
258
|
|
|
231
259
|
return {"role": message.role.value, "content": bedrock_content_blocks}
|
|
232
260
|
|
|
233
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
|
+
|
|
234
288
|
def _format_messages(messages: list[ChatMessage]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
|
|
235
289
|
"""
|
|
236
290
|
Format a list of Haystack ChatMessages to the format expected by Bedrock API.
|
|
@@ -244,21 +298,30 @@ def _format_messages(messages: list[ChatMessage]) -> tuple[list[dict[str, Any]],
|
|
|
244
298
|
non_system_messages is a list of properly formatted message dictionaries.
|
|
245
299
|
"""
|
|
246
300
|
# Separate system messages, tool calls, and tool results
|
|
247
|
-
system_prompts = []
|
|
301
|
+
system_prompts: list[dict[str, Any]] = []
|
|
248
302
|
bedrock_formatted_messages = []
|
|
249
303
|
for msg in messages:
|
|
304
|
+
cache_point = _validate_and_format_cache_point(msg.meta.get("cachePoint"))
|
|
250
305
|
if msg.is_from(ChatRole.SYSTEM):
|
|
251
306
|
# Assuming system messages can only contain text
|
|
252
307
|
# Don't need to track idx since system_messages are handled separately
|
|
253
308
|
system_prompts.append({"text": msg.text})
|
|
254
|
-
|
|
255
|
-
|
|
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)
|
|
256
315
|
elif msg.tool_call_results:
|
|
257
|
-
|
|
316
|
+
formatted_msg = _format_tool_result_message(msg)
|
|
258
317
|
else:
|
|
259
|
-
|
|
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)
|
|
260
322
|
|
|
261
323
|
repaired_bedrock_formatted_messages = _repair_tool_result_messages(bedrock_formatted_messages)
|
|
324
|
+
|
|
262
325
|
return system_prompts, repaired_bedrock_formatted_messages
|
|
263
326
|
|
|
264
327
|
|
|
@@ -290,6 +353,9 @@ def _parse_completion_response(response_body: dict[str, Any], model: str) -> lis
|
|
|
290
353
|
"prompt_tokens": response_body.get("usage", {}).get("inputTokens", 0),
|
|
291
354
|
"completion_tokens": response_body.get("usage", {}).get("outputTokens", 0),
|
|
292
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", {}),
|
|
293
359
|
},
|
|
294
360
|
}
|
|
295
361
|
# guardrail trace
|
|
@@ -441,6 +507,9 @@ def _convert_event_to_streaming_chunk(
|
|
|
441
507
|
"prompt_tokens": usage.get("inputTokens", 0),
|
|
442
508
|
"completion_tokens": usage.get("outputTokens", 0),
|
|
443
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", {}),
|
|
444
513
|
}
|
|
445
514
|
if "trace" in event_meta:
|
|
446
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]:
|
|
File without changes
|
|
File without changes
|