agno 1.8.2__py3-none-any.whl → 1.8.4__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.
- agno/models/anthropic/claude.py +0 -20
- agno/models/aws/claude.py +1 -1
- agno/utils/models/claude.py +12 -2
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/METADATA +1 -1
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/RECORD +9 -10
- agno/utils/models/aws_claude.py +0 -170
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/WHEEL +0 -0
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/entry_points.txt +0 -0
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.2.dist-info → agno-1.8.4.dist-info}/top_level.txt +0 -0
agno/models/anthropic/claude.py
CHANGED
|
@@ -380,26 +380,6 @@ class Claude(Model):
|
|
|
380
380
|
log_error(f"Unexpected error calling Claude API: {str(e)}")
|
|
381
381
|
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
382
382
|
|
|
383
|
-
def format_function_call_results(self, messages: List[Message], function_call_results: List[Message]) -> None:
|
|
384
|
-
"""
|
|
385
|
-
Handle the results of function calls.
|
|
386
|
-
|
|
387
|
-
Args:
|
|
388
|
-
messages (List[Message]): The list of conversation messages.
|
|
389
|
-
function_call_results (List[Message]): The results of the function calls.
|
|
390
|
-
"""
|
|
391
|
-
if len(function_call_results) > 0:
|
|
392
|
-
fc_responses: List = []
|
|
393
|
-
for _fc_message in function_call_results:
|
|
394
|
-
fc_responses.append(
|
|
395
|
-
{
|
|
396
|
-
"type": "tool_result",
|
|
397
|
-
"tool_use_id": _fc_message.tool_call_id,
|
|
398
|
-
"content": str(_fc_message.content),
|
|
399
|
-
}
|
|
400
|
-
)
|
|
401
|
-
messages.append(Message(role="user", content=fc_responses))
|
|
402
|
-
|
|
403
383
|
def get_system_message_for_model(self, tools: Optional[List[Any]] = None) -> Optional[str]:
|
|
404
384
|
if tools is not None and len(tools) > 0:
|
|
405
385
|
tool_call_prompt = "Do not reflect on the quality of the returned search results in your response\n\n"
|
agno/models/aws/claude.py
CHANGED
|
@@ -8,7 +8,7 @@ from agno.exceptions import ModelProviderError, ModelRateLimitError
|
|
|
8
8
|
from agno.models.anthropic import Claude as AnthropicClaude
|
|
9
9
|
from agno.models.message import Message
|
|
10
10
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
11
|
-
from agno.utils.models.
|
|
11
|
+
from agno.utils.models.claude import format_messages
|
|
12
12
|
|
|
13
13
|
try:
|
|
14
14
|
from anthropic import AnthropicBedrock, APIConnectionError, APIStatusError, AsyncAnthropicBedrock, RateLimitError
|
agno/utils/models/claude.py
CHANGED
|
@@ -69,11 +69,11 @@ def _format_image_for_message(image: Image) -> Optional[Dict[str, Any]]:
|
|
|
69
69
|
try:
|
|
70
70
|
# Case 0: Image is an Anthropic uploaded file
|
|
71
71
|
if image.content is not None and hasattr(image.content, "id"):
|
|
72
|
-
|
|
72
|
+
content_bytes = image.content
|
|
73
73
|
|
|
74
74
|
# Case 1: Image is a URL
|
|
75
75
|
if image.url is not None:
|
|
76
|
-
|
|
76
|
+
content_bytes = image.image_url_content
|
|
77
77
|
|
|
78
78
|
# Case 2: Image is a local file path
|
|
79
79
|
elif image.filepath is not None:
|
|
@@ -277,6 +277,16 @@ def format_messages(messages: List[Message]) -> Tuple[List[Dict[str, str]], str]
|
|
|
277
277
|
type="tool_use",
|
|
278
278
|
)
|
|
279
279
|
)
|
|
280
|
+
|
|
281
|
+
elif message.role == "tool":
|
|
282
|
+
content = []
|
|
283
|
+
content.append(
|
|
284
|
+
{
|
|
285
|
+
"type": "tool_result",
|
|
286
|
+
"tool_use_id": message.tool_call_id,
|
|
287
|
+
"content": str(message.content),
|
|
288
|
+
}
|
|
289
|
+
)
|
|
280
290
|
|
|
281
291
|
# Skip empty assistant responses
|
|
282
292
|
if message.role == "assistant" and not content:
|
|
@@ -202,10 +202,10 @@ agno/models/response.py,sha256=iXUlBCM9FWZVRLygSQH8G-vhgKttQazLBa7L_NxgEjg,3771
|
|
|
202
202
|
agno/models/aimlapi/__init__.py,sha256=ulPl-IAEcXvr83AXoCuZmOnoSZ0v47ZGTgEHSzUD2KM,78
|
|
203
203
|
agno/models/aimlapi/aimlapi.py,sha256=o5pu9ypreAK-IkPAosHbLpAvbxu9u3jxBsgYPtS9bzo,1455
|
|
204
204
|
agno/models/anthropic/__init__.py,sha256=nbReX3p17JCwfrMDR9hR7-OaEFZm80I7dng93dl-Fhw,77
|
|
205
|
-
agno/models/anthropic/claude.py,sha256
|
|
205
|
+
agno/models/anthropic/claude.py,sha256=-R9MzNC9zZEgtXk75huDD0PbUiSlpA3b1uF6tG3WucI,23832
|
|
206
206
|
agno/models/aws/__init__.py,sha256=TbcwQwv9A7KjqBM5RQBR8x46GvyyCxbBCjwkpjfVGKE,352
|
|
207
207
|
agno/models/aws/bedrock.py,sha256=Yx09syx1Kv8awfHuy7jj_EK_gs-n6D2an3RUVRO2K2s,35123
|
|
208
|
-
agno/models/aws/claude.py,sha256=
|
|
208
|
+
agno/models/aws/claude.py,sha256=0E4PMfpiDcz9gmMTnmbieh14stzKo54axPTpYiqKVsk,13107
|
|
209
209
|
agno/models/azure/__init__.py,sha256=EoFdJHjayvmv_VOmaW9cJguwA1K5OFS_nFeazyn0B2w,605
|
|
210
210
|
agno/models/azure/ai_foundry.py,sha256=Fkn-BBPPUbw3vauiqqhSq4XQGMSq0TXBzshWCQIEuqg,16854
|
|
211
211
|
agno/models/azure/openai_chat.py,sha256=RYHmcHA7cn79_U6GTjNP5vYiYET6IfPgUp6XZ2WEiyQ,4423
|
|
@@ -495,8 +495,7 @@ agno/utils/whatsapp.py,sha256=242VwGOdbgkxVeIj4D899mpT3GnG_IpcaKnd5qebhTA,9936
|
|
|
495
495
|
agno/utils/yaml_io.py,sha256=cwTqCE-eBGoi87KLDcwB6iyWe0NcvEmadQjWL1cQ7jE,860
|
|
496
496
|
agno/utils/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
497
497
|
agno/utils/models/ai_foundry.py,sha256=PmhETWhdqZCq8NbDe-MdZVuRXx6DbVOePCyPFiPLceo,1511
|
|
498
|
-
agno/utils/models/
|
|
499
|
-
agno/utils/models/claude.py,sha256=CQ36iQda9UOjAeou8q7U4FtVY6UFj13pvRyO0sIHlh8,11285
|
|
498
|
+
agno/utils/models/claude.py,sha256=AYdFvQ8HjuYs7Pbs6CWqJWkfnRKEo0mu8Wu5InLom30,11517
|
|
500
499
|
agno/utils/models/cohere.py,sha256=SuZyupN1clBNMaSkHDQXWcTpY96rcF5EhMK5gpQAi94,3248
|
|
501
500
|
agno/utils/models/llama.py,sha256=Z5fdOFUFnov1JgUDcP6ICK3M7o64UB1fkcwAs2XaZkM,2515
|
|
502
501
|
agno/utils/models/mistral.py,sha256=v-ERNweHjmobUv5LOpB7XDxGZotXgGTC_hIFBJD1k3E,4013
|
|
@@ -558,9 +557,9 @@ agno/workspace/enums.py,sha256=MxF1CUMXBaZMTKLEfiR-7kEhTki2Gfz6W7u49RdYYaE,123
|
|
|
558
557
|
agno/workspace/helpers.py,sha256=Mp-VlRsPVhW10CfDWYVhc9ANLk9RjNurDfCgXmycZCg,2066
|
|
559
558
|
agno/workspace/operator.py,sha256=CNLwVR45eE5dSRjto2o0c9NgCi2xD-JZR5uLt9kfIt8,30758
|
|
560
559
|
agno/workspace/settings.py,sha256=bcyHHN7lH1LPSMt4i_20XpTjZLoNXdzwyW-G9nHYV40,5703
|
|
561
|
-
agno-1.8.
|
|
562
|
-
agno-1.8.
|
|
563
|
-
agno-1.8.
|
|
564
|
-
agno-1.8.
|
|
565
|
-
agno-1.8.
|
|
566
|
-
agno-1.8.
|
|
560
|
+
agno-1.8.4.dist-info/licenses/LICENSE,sha256=m2rfTWFUfIwCaQqgT2WeBjuKzMKEJRwnaiofg9n8MsQ,16751
|
|
561
|
+
agno-1.8.4.dist-info/METADATA,sha256=lGfIekKYNNmsPDU6iDcqe8ZGPp10TUNbui8LCxT_Y8o,44612
|
|
562
|
+
agno-1.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
563
|
+
agno-1.8.4.dist-info/entry_points.txt,sha256=Be-iPnPVabMohESsuUdV5w6IAYEIlpc2emJZbyNnfGI,88
|
|
564
|
+
agno-1.8.4.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
|
|
565
|
+
agno-1.8.4.dist-info/RECORD,,
|
agno/utils/models/aws_claude.py
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
3
|
-
|
|
4
|
-
from agno.media import Image
|
|
5
|
-
from agno.models.message import Message
|
|
6
|
-
from agno.utils.log import log_error, log_warning
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from anthropic.types import (
|
|
10
|
-
TextBlock,
|
|
11
|
-
ToolUseBlock,
|
|
12
|
-
)
|
|
13
|
-
except ImportError:
|
|
14
|
-
log_error("`anthropic[bedrock]` not installed. Please install it via `pip install anthropic[bedrock]`.")
|
|
15
|
-
raise
|
|
16
|
-
|
|
17
|
-
ROLE_MAP = {
|
|
18
|
-
"system": "system",
|
|
19
|
-
"user": "user",
|
|
20
|
-
"assistant": "assistant",
|
|
21
|
-
"tool": "user",
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _format_image_for_message(image: Image) -> Optional[Dict[str, Any]]:
|
|
26
|
-
"""
|
|
27
|
-
Add an image to a message by converting it to base64 encoded format.
|
|
28
|
-
"""
|
|
29
|
-
using_filetype = False
|
|
30
|
-
|
|
31
|
-
import base64
|
|
32
|
-
|
|
33
|
-
# 'imghdr' was deprecated in Python 3.11: https://docs.python.org/3/library/imghdr.html
|
|
34
|
-
# 'filetype' used as a fallback
|
|
35
|
-
try:
|
|
36
|
-
import imghdr
|
|
37
|
-
except (ModuleNotFoundError, ImportError):
|
|
38
|
-
try:
|
|
39
|
-
import filetype
|
|
40
|
-
|
|
41
|
-
using_filetype = True
|
|
42
|
-
except (ModuleNotFoundError, ImportError):
|
|
43
|
-
raise ImportError("`filetype` not installed. Please install using `pip install filetype`")
|
|
44
|
-
|
|
45
|
-
type_mapping = {
|
|
46
|
-
"jpeg": "image/jpeg",
|
|
47
|
-
"jpg": "image/jpeg",
|
|
48
|
-
"png": "image/png",
|
|
49
|
-
"gif": "image/gif",
|
|
50
|
-
"webp": "image/webp",
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
try:
|
|
54
|
-
# Case 1: Image is a URL
|
|
55
|
-
if image.url is not None:
|
|
56
|
-
content_bytes = image.image_url_content
|
|
57
|
-
|
|
58
|
-
# Case 2: Image is a local file path
|
|
59
|
-
elif image.filepath is not None:
|
|
60
|
-
from pathlib import Path
|
|
61
|
-
|
|
62
|
-
path = Path(image.filepath) if isinstance(image.filepath, str) else image.filepath
|
|
63
|
-
if path.exists() and path.is_file():
|
|
64
|
-
with open(image.filepath, "rb") as f:
|
|
65
|
-
content_bytes = f.read()
|
|
66
|
-
else:
|
|
67
|
-
log_error(f"Image file not found: {image}")
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
|
-
# Case 3: Image is a bytes object
|
|
71
|
-
elif image.content is not None:
|
|
72
|
-
content_bytes = image.content
|
|
73
|
-
|
|
74
|
-
else:
|
|
75
|
-
log_error(f"Unsupported image type: {type(image)}")
|
|
76
|
-
return None
|
|
77
|
-
|
|
78
|
-
if using_filetype:
|
|
79
|
-
kind = filetype.guess(content_bytes)
|
|
80
|
-
if not kind:
|
|
81
|
-
log_error("Unable to determine image type")
|
|
82
|
-
return None
|
|
83
|
-
|
|
84
|
-
img_type = kind.extension
|
|
85
|
-
else:
|
|
86
|
-
img_type = imghdr.what(None, h=content_bytes) # type: ignore
|
|
87
|
-
|
|
88
|
-
if not img_type:
|
|
89
|
-
log_error("Unable to determine image type")
|
|
90
|
-
return None
|
|
91
|
-
|
|
92
|
-
media_type = type_mapping.get(img_type)
|
|
93
|
-
if not media_type:
|
|
94
|
-
log_error(f"Unsupported image type: {img_type}")
|
|
95
|
-
return None
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
"type": "image",
|
|
99
|
-
"source": {
|
|
100
|
-
"type": "base64",
|
|
101
|
-
"media_type": media_type,
|
|
102
|
-
"data": base64.b64encode(content_bytes).decode("utf-8"), # type: ignore
|
|
103
|
-
},
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
except Exception as e:
|
|
107
|
-
log_error(f"Error processing image: {e}")
|
|
108
|
-
return None
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def format_messages(messages: List[Message]) -> Tuple[List[Dict[str, str]], str]:
|
|
112
|
-
"""
|
|
113
|
-
Process the list of messages and separate them into API messages and system messages.
|
|
114
|
-
|
|
115
|
-
Args:
|
|
116
|
-
messages (List[Message]): The list of messages to process.
|
|
117
|
-
|
|
118
|
-
Returns:
|
|
119
|
-
Tuple[List[Dict[str, str]], str]: A tuple containing the list of API messages and the concatenated system messages.
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
chat_messages: List[Dict[str, str]] = []
|
|
123
|
-
system_messages: List[str] = []
|
|
124
|
-
|
|
125
|
-
for message in messages:
|
|
126
|
-
content = message.content or ""
|
|
127
|
-
if message.role == "system":
|
|
128
|
-
if content is not None:
|
|
129
|
-
system_messages.append(content) # type: ignore
|
|
130
|
-
continue
|
|
131
|
-
elif message.role == "user":
|
|
132
|
-
if isinstance(content, str):
|
|
133
|
-
content = [{"type": "text", "text": content}]
|
|
134
|
-
|
|
135
|
-
if message.images is not None:
|
|
136
|
-
for image in message.images:
|
|
137
|
-
image_content = _format_image_for_message(image)
|
|
138
|
-
if image_content:
|
|
139
|
-
content.append(image_content)
|
|
140
|
-
|
|
141
|
-
if message.files is not None and len(message.files) > 0:
|
|
142
|
-
log_warning("Files are not supported for AWS Bedrock Claude")
|
|
143
|
-
|
|
144
|
-
if message.audio is not None and len(message.audio) > 0:
|
|
145
|
-
log_warning("Audio is not supported for AWS Bedrock Claude")
|
|
146
|
-
|
|
147
|
-
if message.videos is not None and len(message.videos) > 0:
|
|
148
|
-
log_warning("Video is not supported for AWS Bedrock Claude")
|
|
149
|
-
|
|
150
|
-
# Handle tool calls from history
|
|
151
|
-
elif message.role == "assistant":
|
|
152
|
-
content = []
|
|
153
|
-
|
|
154
|
-
if isinstance(message.content, str) and message.content and len(message.content.strip()) > 0:
|
|
155
|
-
content.append(TextBlock(text=message.content, type="text"))
|
|
156
|
-
|
|
157
|
-
if message.tool_calls:
|
|
158
|
-
for tool_call in message.tool_calls:
|
|
159
|
-
content.append(
|
|
160
|
-
ToolUseBlock(
|
|
161
|
-
id=tool_call["id"],
|
|
162
|
-
input=json.loads(tool_call["function"]["arguments"])
|
|
163
|
-
if "arguments" in tool_call["function"]
|
|
164
|
-
else {},
|
|
165
|
-
name=tool_call["function"]["name"],
|
|
166
|
-
type="tool_use",
|
|
167
|
-
)
|
|
168
|
-
)
|
|
169
|
-
chat_messages.append({"role": ROLE_MAP[message.role], "content": content}) # type: ignore
|
|
170
|
-
return chat_messages, " ".join(system_messages)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|