agno 2.3.2__py3-none-any.whl → 2.3.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/agent/agent.py +513 -185
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +176 -0
- agno/db/dynamo/dynamo.py +11 -0
- agno/db/firestore/firestore.py +5 -1
- agno/db/gcs_json/gcs_json_db.py +5 -2
- agno/db/in_memory/in_memory_db.py +5 -2
- agno/db/json/json_db.py +5 -1
- agno/db/migrations/manager.py +4 -4
- agno/db/mongo/async_mongo.py +158 -34
- agno/db/mongo/mongo.py +6 -2
- agno/db/mysql/mysql.py +48 -54
- agno/db/postgres/async_postgres.py +66 -52
- agno/db/postgres/postgres.py +42 -50
- agno/db/redis/redis.py +5 -0
- agno/db/redis/utils.py +5 -5
- agno/db/singlestore/singlestore.py +99 -108
- agno/db/sqlite/async_sqlite.py +29 -27
- agno/db/sqlite/sqlite.py +30 -26
- agno/knowledge/reader/pdf_reader.py +2 -2
- agno/knowledge/reader/tavily_reader.py +0 -1
- agno/memory/__init__.py +14 -1
- agno/memory/manager.py +217 -4
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +67 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/aimlapi.py +18 -0
- agno/models/anthropic/claude.py +87 -81
- agno/models/aws/bedrock.py +38 -16
- agno/models/aws/claude.py +97 -277
- agno/models/azure/ai_foundry.py +8 -4
- agno/models/base.py +101 -14
- agno/models/cerebras/cerebras.py +25 -9
- agno/models/cerebras/cerebras_openai.py +22 -2
- agno/models/cohere/chat.py +18 -6
- agno/models/cometapi/cometapi.py +19 -1
- agno/models/deepinfra/deepinfra.py +19 -1
- agno/models/fireworks/fireworks.py +19 -1
- agno/models/google/gemini.py +583 -21
- agno/models/groq/groq.py +23 -6
- agno/models/huggingface/huggingface.py +22 -7
- agno/models/ibm/watsonx.py +21 -7
- agno/models/internlm/internlm.py +19 -1
- agno/models/langdb/langdb.py +10 -0
- agno/models/litellm/chat.py +17 -7
- agno/models/litellm/litellm_openai.py +19 -1
- agno/models/message.py +19 -5
- agno/models/meta/llama.py +25 -5
- agno/models/meta/llama_openai.py +18 -0
- agno/models/mistral/mistral.py +13 -5
- agno/models/nvidia/nvidia.py +19 -1
- agno/models/ollama/chat.py +17 -6
- agno/models/openai/chat.py +22 -7
- agno/models/openai/responses.py +28 -10
- agno/models/openrouter/openrouter.py +20 -0
- agno/models/perplexity/perplexity.py +17 -0
- agno/models/requesty/requesty.py +18 -0
- agno/models/sambanova/sambanova.py +19 -1
- agno/models/siliconflow/siliconflow.py +19 -1
- agno/models/together/together.py +19 -1
- agno/models/vercel/v0.py +19 -1
- agno/models/vertexai/claude.py +99 -5
- agno/models/xai/xai.py +18 -0
- agno/os/interfaces/agui/router.py +1 -0
- agno/os/interfaces/agui/utils.py +97 -57
- agno/os/router.py +16 -0
- agno/os/routers/memory/memory.py +143 -0
- agno/os/routers/memory/schemas.py +26 -0
- agno/os/schema.py +33 -6
- agno/os/utils.py +134 -10
- agno/run/base.py +2 -1
- agno/run/workflow.py +1 -1
- agno/team/team.py +566 -219
- agno/tools/mcp/mcp.py +1 -1
- agno/utils/agent.py +119 -1
- agno/utils/models/ai_foundry.py +9 -2
- agno/utils/models/claude.py +12 -5
- agno/utils/models/cohere.py +9 -2
- agno/utils/models/llama.py +9 -2
- agno/utils/models/mistral.py +4 -2
- agno/utils/print_response/agent.py +37 -2
- agno/utils/print_response/team.py +52 -0
- agno/utils/tokens.py +41 -0
- agno/workflow/types.py +2 -2
- {agno-2.3.2.dist-info → agno-2.3.4.dist-info}/METADATA +45 -40
- {agno-2.3.2.dist-info → agno-2.3.4.dist-info}/RECORD +90 -83
- {agno-2.3.2.dist-info → agno-2.3.4.dist-info}/WHEEL +0 -0
- {agno-2.3.2.dist-info → agno-2.3.4.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.2.dist-info → agno-2.3.4.dist-info}/top_level.txt +0 -0
agno/models/meta/llama_openai.py
CHANGED
|
@@ -7,6 +7,7 @@ try:
|
|
|
7
7
|
except ImportError:
|
|
8
8
|
raise ImportError("`openai` not installed. Please install using `pip install openai`")
|
|
9
9
|
|
|
10
|
+
from agno.exceptions import ModelProviderError
|
|
10
11
|
from agno.models.meta.llama import Message
|
|
11
12
|
from agno.models.openai.like import OpenAILike
|
|
12
13
|
from agno.utils.models.llama import format_message
|
|
@@ -49,6 +50,23 @@ class LlamaOpenAI(OpenAILike):
|
|
|
49
50
|
# Cached async client
|
|
50
51
|
openai_async_client: Optional[AsyncOpenAIClient] = None
|
|
51
52
|
|
|
53
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
54
|
+
"""
|
|
55
|
+
Returns client parameters for API requests, checking for LLAMA_API_KEY.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
59
|
+
"""
|
|
60
|
+
if not self.api_key:
|
|
61
|
+
self.api_key = getenv("LLAMA_API_KEY")
|
|
62
|
+
if not self.api_key:
|
|
63
|
+
raise ModelProviderError(
|
|
64
|
+
message="LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.",
|
|
65
|
+
model_name=self.name,
|
|
66
|
+
model_id=self.id,
|
|
67
|
+
)
|
|
68
|
+
return super()._get_client_params()
|
|
69
|
+
|
|
52
70
|
def _format_message(self, message: Message) -> Dict[str, Any]:
|
|
53
71
|
"""
|
|
54
72
|
Format a message into the format expected by Llama API.
|
agno/models/mistral/mistral.py
CHANGED
|
@@ -94,7 +94,11 @@ class MistralChat(Model):
|
|
|
94
94
|
|
|
95
95
|
self.api_key = self.api_key or getenv("MISTRAL_API_KEY")
|
|
96
96
|
if not self.api_key:
|
|
97
|
-
|
|
97
|
+
raise ModelProviderError(
|
|
98
|
+
message="MISTRAL_API_KEY not set. Please set the MISTRAL_API_KEY environment variable.",
|
|
99
|
+
model_name=self.name,
|
|
100
|
+
model_id=self.id,
|
|
101
|
+
)
|
|
98
102
|
|
|
99
103
|
client_params.update(
|
|
100
104
|
{
|
|
@@ -174,11 +178,12 @@ class MistralChat(Model):
|
|
|
174
178
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
175
179
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
176
180
|
run_response: Optional[RunOutput] = None,
|
|
181
|
+
compress_tool_results: bool = False,
|
|
177
182
|
) -> ModelResponse:
|
|
178
183
|
"""
|
|
179
184
|
Send a chat completion request to the Mistral model.
|
|
180
185
|
"""
|
|
181
|
-
mistral_messages = format_messages(messages)
|
|
186
|
+
mistral_messages = format_messages(messages, compress_tool_results)
|
|
182
187
|
try:
|
|
183
188
|
response: Union[ChatCompletionResponse, ParsedChatCompletionResponse]
|
|
184
189
|
if (
|
|
@@ -229,11 +234,12 @@ class MistralChat(Model):
|
|
|
229
234
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
230
235
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
231
236
|
run_response: Optional[RunOutput] = None,
|
|
237
|
+
compress_tool_results: bool = False,
|
|
232
238
|
) -> Iterator[ModelResponse]:
|
|
233
239
|
"""
|
|
234
240
|
Stream the response from the Mistral model.
|
|
235
241
|
"""
|
|
236
|
-
mistral_messages = format_messages(messages)
|
|
242
|
+
mistral_messages = format_messages(messages, compress_tool_results)
|
|
237
243
|
|
|
238
244
|
if run_response and run_response.metrics:
|
|
239
245
|
run_response.metrics.set_time_to_first_token()
|
|
@@ -265,11 +271,12 @@ class MistralChat(Model):
|
|
|
265
271
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
266
272
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
267
273
|
run_response: Optional[RunOutput] = None,
|
|
274
|
+
compress_tool_results: bool = False,
|
|
268
275
|
) -> ModelResponse:
|
|
269
276
|
"""
|
|
270
277
|
Send an asynchronous chat completion request to the Mistral API.
|
|
271
278
|
"""
|
|
272
|
-
mistral_messages = format_messages(messages)
|
|
279
|
+
mistral_messages = format_messages(messages, compress_tool_results)
|
|
273
280
|
try:
|
|
274
281
|
response: Union[ChatCompletionResponse, ParsedChatCompletionResponse]
|
|
275
282
|
if (
|
|
@@ -316,11 +323,12 @@ class MistralChat(Model):
|
|
|
316
323
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
317
324
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
318
325
|
run_response: Optional[RunOutput] = None,
|
|
326
|
+
compress_tool_results: bool = False,
|
|
319
327
|
) -> AsyncIterator[ModelResponse]:
|
|
320
328
|
"""
|
|
321
329
|
Stream an asynchronous response from the Mistral API.
|
|
322
330
|
"""
|
|
323
|
-
mistral_messages = format_messages(messages)
|
|
331
|
+
mistral_messages = format_messages(messages, compress_tool_results)
|
|
324
332
|
try:
|
|
325
333
|
if run_response and run_response.metrics:
|
|
326
334
|
run_response.metrics.set_time_to_first_token()
|
agno/models/nvidia/nvidia.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
|
+
from agno.exceptions import ModelProviderError
|
|
5
6
|
from agno.models.openai.like import OpenAILike
|
|
6
7
|
|
|
7
8
|
|
|
@@ -26,3 +27,20 @@ class Nvidia(OpenAILike):
|
|
|
26
27
|
base_url: str = "https://integrate.api.nvidia.com/v1"
|
|
27
28
|
|
|
28
29
|
supports_native_structured_outputs: bool = False
|
|
30
|
+
|
|
31
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
32
|
+
"""
|
|
33
|
+
Returns client parameters for API requests, checking for NVIDIA_API_KEY.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
37
|
+
"""
|
|
38
|
+
if not self.api_key:
|
|
39
|
+
self.api_key = getenv("NVIDIA_API_KEY")
|
|
40
|
+
if not self.api_key:
|
|
41
|
+
raise ModelProviderError(
|
|
42
|
+
message="NVIDIA_API_KEY not set. Please set the NVIDIA_API_KEY environment variable.",
|
|
43
|
+
model_name=self.name,
|
|
44
|
+
model_id=self.id,
|
|
45
|
+
)
|
|
46
|
+
return super()._get_client_params()
|
agno/models/ollama/chat.py
CHANGED
|
@@ -147,19 +147,26 @@ class Ollama(Model):
|
|
|
147
147
|
cleaned_dict = {k: v for k, v in model_dict.items() if v is not None}
|
|
148
148
|
return cleaned_dict
|
|
149
149
|
|
|
150
|
-
def _format_message(self, message: Message) -> Dict[str, Any]:
|
|
150
|
+
def _format_message(self, message: Message, compress_tool_results: bool = False) -> Dict[str, Any]:
|
|
151
151
|
"""
|
|
152
152
|
Format a message into the format expected by Ollama.
|
|
153
153
|
|
|
154
154
|
Args:
|
|
155
155
|
message (Message): The message to format.
|
|
156
|
+
compress_tool_results: Whether to compress tool results.
|
|
156
157
|
|
|
157
158
|
Returns:
|
|
158
159
|
Dict[str, Any]: The formatted message.
|
|
159
160
|
"""
|
|
161
|
+
# Use compressed content for tool messages if compression is active
|
|
162
|
+
if message.role == "tool":
|
|
163
|
+
content = message.get_content(use_compressed_content=compress_tool_results)
|
|
164
|
+
else:
|
|
165
|
+
content = message.content
|
|
166
|
+
|
|
160
167
|
_message: Dict[str, Any] = {
|
|
161
168
|
"role": message.role,
|
|
162
|
-
"content":
|
|
169
|
+
"content": content,
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
if message.role == "assistant" and message.tool_calls is not None:
|
|
@@ -228,6 +235,7 @@ class Ollama(Model):
|
|
|
228
235
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
229
236
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
230
237
|
run_response: Optional[RunOutput] = None,
|
|
238
|
+
compress_tool_results: bool = False,
|
|
231
239
|
) -> ModelResponse:
|
|
232
240
|
"""
|
|
233
241
|
Send a chat request to the Ollama API.
|
|
@@ -241,7 +249,7 @@ class Ollama(Model):
|
|
|
241
249
|
|
|
242
250
|
provider_response = self.get_client().chat(
|
|
243
251
|
model=self.id.strip(),
|
|
244
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
252
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
245
253
|
**request_kwargs,
|
|
246
254
|
) # type: ignore
|
|
247
255
|
|
|
@@ -258,6 +266,7 @@ class Ollama(Model):
|
|
|
258
266
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
259
267
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
260
268
|
run_response: Optional[RunOutput] = None,
|
|
269
|
+
compress_tool_results: bool = False,
|
|
261
270
|
) -> ModelResponse:
|
|
262
271
|
"""
|
|
263
272
|
Sends an asynchronous chat request to the Ollama API.
|
|
@@ -271,7 +280,7 @@ class Ollama(Model):
|
|
|
271
280
|
|
|
272
281
|
provider_response = await self.get_async_client().chat(
|
|
273
282
|
model=self.id.strip(),
|
|
274
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
283
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
275
284
|
**request_kwargs,
|
|
276
285
|
) # type: ignore
|
|
277
286
|
|
|
@@ -288,6 +297,7 @@ class Ollama(Model):
|
|
|
288
297
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
289
298
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
290
299
|
run_response: Optional[RunOutput] = None,
|
|
300
|
+
compress_tool_results: bool = False,
|
|
291
301
|
) -> Iterator[ModelResponse]:
|
|
292
302
|
"""
|
|
293
303
|
Sends a streaming chat request to the Ollama API.
|
|
@@ -299,7 +309,7 @@ class Ollama(Model):
|
|
|
299
309
|
|
|
300
310
|
for chunk in self.get_client().chat(
|
|
301
311
|
model=self.id,
|
|
302
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
312
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
303
313
|
stream=True,
|
|
304
314
|
**self.get_request_params(tools=tools),
|
|
305
315
|
):
|
|
@@ -315,6 +325,7 @@ class Ollama(Model):
|
|
|
315
325
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
316
326
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
317
327
|
run_response: Optional[RunOutput] = None,
|
|
328
|
+
compress_tool_results: bool = False,
|
|
318
329
|
) -> AsyncIterator[ModelResponse]:
|
|
319
330
|
"""
|
|
320
331
|
Sends an asynchronous streaming chat completion request to the Ollama API.
|
|
@@ -326,7 +337,7 @@ class Ollama(Model):
|
|
|
326
337
|
|
|
327
338
|
async for chunk in await self.get_async_client().chat(
|
|
328
339
|
model=self.id.strip(),
|
|
329
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
340
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
330
341
|
stream=True,
|
|
331
342
|
**self.get_request_params(tools=tools),
|
|
332
343
|
):
|
agno/models/openai/chat.py
CHANGED
|
@@ -102,7 +102,11 @@ class OpenAIChat(Model):
|
|
|
102
102
|
if not self.api_key:
|
|
103
103
|
self.api_key = getenv("OPENAI_API_KEY")
|
|
104
104
|
if not self.api_key:
|
|
105
|
-
|
|
105
|
+
raise ModelProviderError(
|
|
106
|
+
message="OPENAI_API_KEY not set. Please set the OPENAI_API_KEY environment variable.",
|
|
107
|
+
model_name=self.name,
|
|
108
|
+
model_id=self.id,
|
|
109
|
+
)
|
|
106
110
|
|
|
107
111
|
# Define base client params
|
|
108
112
|
base_params = {
|
|
@@ -302,19 +306,22 @@ class OpenAIChat(Model):
|
|
|
302
306
|
cleaned_dict = {k: v for k, v in model_dict.items() if v is not None}
|
|
303
307
|
return cleaned_dict
|
|
304
308
|
|
|
305
|
-
def _format_message(self, message: Message) -> Dict[str, Any]:
|
|
309
|
+
def _format_message(self, message: Message, compress_tool_results: bool = False) -> Dict[str, Any]:
|
|
306
310
|
"""
|
|
307
311
|
Format a message into the format expected by OpenAI.
|
|
308
312
|
|
|
309
313
|
Args:
|
|
310
314
|
message (Message): The message to format.
|
|
315
|
+
compress_tool_results: Whether to compress tool results.
|
|
311
316
|
|
|
312
317
|
Returns:
|
|
313
318
|
Dict[str, Any]: The formatted message.
|
|
314
319
|
"""
|
|
320
|
+
tool_result = message.get_content(use_compressed_content=compress_tool_results)
|
|
321
|
+
|
|
315
322
|
message_dict: Dict[str, Any] = {
|
|
316
323
|
"role": self.role_map[message.role] if self.role_map else self.default_role_map[message.role],
|
|
317
|
-
"content":
|
|
324
|
+
"content": tool_result,
|
|
318
325
|
"name": message.name,
|
|
319
326
|
"tool_call_id": message.tool_call_id,
|
|
320
327
|
"tool_calls": message.tool_calls,
|
|
@@ -374,6 +381,7 @@ class OpenAIChat(Model):
|
|
|
374
381
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
375
382
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
376
383
|
run_response: Optional[Union[RunOutput, TeamRunOutput]] = None,
|
|
384
|
+
compress_tool_results: bool = False,
|
|
377
385
|
) -> ModelResponse:
|
|
378
386
|
"""
|
|
379
387
|
Send a chat completion request to the OpenAI API and parse the response.
|
|
@@ -384,6 +392,7 @@ class OpenAIChat(Model):
|
|
|
384
392
|
response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
|
|
385
393
|
tools (Optional[List[Dict[str, Any]]]): The tools to use.
|
|
386
394
|
tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
|
|
395
|
+
compress_tool_results: Whether to compress tool results.
|
|
387
396
|
|
|
388
397
|
Returns:
|
|
389
398
|
ModelResponse: The chat completion response from the API.
|
|
@@ -396,7 +405,7 @@ class OpenAIChat(Model):
|
|
|
396
405
|
|
|
397
406
|
provider_response = self.get_client().chat.completions.create(
|
|
398
407
|
model=self.id,
|
|
399
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
408
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
400
409
|
**self.get_request_params(
|
|
401
410
|
response_format=response_format, tools=tools, tool_choice=tool_choice, run_response=run_response
|
|
402
411
|
),
|
|
@@ -454,6 +463,7 @@ class OpenAIChat(Model):
|
|
|
454
463
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
455
464
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
456
465
|
run_response: Optional[Union[RunOutput, TeamRunOutput]] = None,
|
|
466
|
+
compress_tool_results: bool = False,
|
|
457
467
|
) -> ModelResponse:
|
|
458
468
|
"""
|
|
459
469
|
Sends an asynchronous chat completion request to the OpenAI API.
|
|
@@ -464,6 +474,7 @@ class OpenAIChat(Model):
|
|
|
464
474
|
response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
|
|
465
475
|
tools (Optional[List[Dict[str, Any]]]): The tools to use.
|
|
466
476
|
tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
|
|
477
|
+
compress_tool_results: Whether to compress tool results.
|
|
467
478
|
|
|
468
479
|
Returns:
|
|
469
480
|
ModelResponse: The chat completion response from the API.
|
|
@@ -475,7 +486,7 @@ class OpenAIChat(Model):
|
|
|
475
486
|
assistant_message.metrics.start_timer()
|
|
476
487
|
response = await self.get_async_client().chat.completions.create(
|
|
477
488
|
model=self.id,
|
|
478
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
489
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
479
490
|
**self.get_request_params(
|
|
480
491
|
response_format=response_format, tools=tools, tool_choice=tool_choice, run_response=run_response
|
|
481
492
|
),
|
|
@@ -533,12 +544,14 @@ class OpenAIChat(Model):
|
|
|
533
544
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
534
545
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
535
546
|
run_response: Optional[Union[RunOutput, TeamRunOutput]] = None,
|
|
547
|
+
compress_tool_results: bool = False,
|
|
536
548
|
) -> Iterator[ModelResponse]:
|
|
537
549
|
"""
|
|
538
550
|
Send a streaming chat completion request to the OpenAI API.
|
|
539
551
|
|
|
540
552
|
Args:
|
|
541
553
|
messages (List[Message]): A list of messages to send to the model.
|
|
554
|
+
compress_tool_results: Whether to compress tool results.
|
|
542
555
|
|
|
543
556
|
Returns:
|
|
544
557
|
Iterator[ModelResponse]: An iterator of model responses.
|
|
@@ -552,7 +565,7 @@ class OpenAIChat(Model):
|
|
|
552
565
|
|
|
553
566
|
for chunk in self.get_client().chat.completions.create(
|
|
554
567
|
model=self.id,
|
|
555
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
568
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
556
569
|
stream=True,
|
|
557
570
|
stream_options={"include_usage": True},
|
|
558
571
|
**self.get_request_params(
|
|
@@ -609,12 +622,14 @@ class OpenAIChat(Model):
|
|
|
609
622
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
610
623
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
611
624
|
run_response: Optional[Union[RunOutput, TeamRunOutput]] = None,
|
|
625
|
+
compress_tool_results: bool = False,
|
|
612
626
|
) -> AsyncIterator[ModelResponse]:
|
|
613
627
|
"""
|
|
614
628
|
Sends an asynchronous streaming chat completion request to the OpenAI API.
|
|
615
629
|
|
|
616
630
|
Args:
|
|
617
631
|
messages (List[Message]): A list of messages to send to the model.
|
|
632
|
+
compress_tool_results: Whether to compress tool results.
|
|
618
633
|
|
|
619
634
|
Returns:
|
|
620
635
|
Any: An asynchronous iterator of model responses.
|
|
@@ -628,7 +643,7 @@ class OpenAIChat(Model):
|
|
|
628
643
|
|
|
629
644
|
async_stream = await self.get_async_client().chat.completions.create(
|
|
630
645
|
model=self.id,
|
|
631
|
-
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
646
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
632
647
|
stream=True,
|
|
633
648
|
stream_options={"include_usage": True},
|
|
634
649
|
**self.get_request_params(
|
agno/models/openai/responses.py
CHANGED
|
@@ -117,7 +117,11 @@ class OpenAIResponses(Model):
|
|
|
117
117
|
if not self.api_key:
|
|
118
118
|
self.api_key = getenv("OPENAI_API_KEY")
|
|
119
119
|
if not self.api_key:
|
|
120
|
-
|
|
120
|
+
raise ModelProviderError(
|
|
121
|
+
message="OPENAI_API_KEY not set. Please set the OPENAI_API_KEY environment variable.",
|
|
122
|
+
model_name=self.name,
|
|
123
|
+
model_id=self.id,
|
|
124
|
+
)
|
|
121
125
|
|
|
122
126
|
# Define base client params
|
|
123
127
|
base_params = {
|
|
@@ -395,12 +399,15 @@ class OpenAIResponses(Model):
|
|
|
395
399
|
|
|
396
400
|
return formatted_tools
|
|
397
401
|
|
|
398
|
-
def _format_messages(
|
|
402
|
+
def _format_messages(
|
|
403
|
+
self, messages: List[Message], compress_tool_results: bool = False
|
|
404
|
+
) -> List[Union[Dict[str, Any], ResponseReasoningItem]]:
|
|
399
405
|
"""
|
|
400
406
|
Format a message into the format expected by OpenAI.
|
|
401
407
|
|
|
402
408
|
Args:
|
|
403
409
|
messages (List[Message]): The message to format.
|
|
410
|
+
compress_tool_results: Whether to compress tool results.
|
|
404
411
|
|
|
405
412
|
Returns:
|
|
406
413
|
Dict[str, Any]: The formatted message.
|
|
@@ -445,7 +452,7 @@ class OpenAIResponses(Model):
|
|
|
445
452
|
if message.role in ["user", "system"]:
|
|
446
453
|
message_dict: Dict[str, Any] = {
|
|
447
454
|
"role": self.role_map[message.role],
|
|
448
|
-
"content": message.
|
|
455
|
+
"content": message.get_content(use_compressed_content=compress_tool_results),
|
|
449
456
|
}
|
|
450
457
|
message_dict = {k: v for k, v in message_dict.items() if v is not None}
|
|
451
458
|
|
|
@@ -469,7 +476,9 @@ class OpenAIResponses(Model):
|
|
|
469
476
|
|
|
470
477
|
# Tool call result
|
|
471
478
|
elif message.role == "tool":
|
|
472
|
-
|
|
479
|
+
tool_result = message.get_content(use_compressed_content=compress_tool_results)
|
|
480
|
+
|
|
481
|
+
if message.tool_call_id and tool_result is not None:
|
|
473
482
|
function_call_id = message.tool_call_id
|
|
474
483
|
# Normalize: if a fc_* id was provided, translate to its corresponding call_* id
|
|
475
484
|
if isinstance(function_call_id, str) and function_call_id in fc_id_to_call_id:
|
|
@@ -477,7 +486,7 @@ class OpenAIResponses(Model):
|
|
|
477
486
|
else:
|
|
478
487
|
call_id_value = function_call_id
|
|
479
488
|
formatted_messages.append(
|
|
480
|
-
{"type": "function_call_output", "call_id": call_id_value, "output":
|
|
489
|
+
{"type": "function_call_output", "call_id": call_id_value, "output": tool_result}
|
|
481
490
|
)
|
|
482
491
|
# Tool Calls
|
|
483
492
|
elif message.tool_calls is not None and len(message.tool_calls) > 0:
|
|
@@ -519,6 +528,7 @@ class OpenAIResponses(Model):
|
|
|
519
528
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
520
529
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
521
530
|
run_response: Optional[RunOutput] = None,
|
|
531
|
+
compress_tool_results: bool = False,
|
|
522
532
|
) -> ModelResponse:
|
|
523
533
|
"""
|
|
524
534
|
Send a request to the OpenAI Responses API.
|
|
@@ -535,7 +545,7 @@ class OpenAIResponses(Model):
|
|
|
535
545
|
|
|
536
546
|
provider_response = self.get_client().responses.create(
|
|
537
547
|
model=self.id,
|
|
538
|
-
input=self._format_messages(messages), # type: ignore
|
|
548
|
+
input=self._format_messages(messages, compress_tool_results), # type: ignore
|
|
539
549
|
**request_params,
|
|
540
550
|
)
|
|
541
551
|
|
|
@@ -588,6 +598,7 @@ class OpenAIResponses(Model):
|
|
|
588
598
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
589
599
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
590
600
|
run_response: Optional[RunOutput] = None,
|
|
601
|
+
compress_tool_results: bool = False,
|
|
591
602
|
) -> ModelResponse:
|
|
592
603
|
"""
|
|
593
604
|
Sends an asynchronous request to the OpenAI Responses API.
|
|
@@ -604,7 +615,7 @@ class OpenAIResponses(Model):
|
|
|
604
615
|
|
|
605
616
|
provider_response = await self.get_async_client().responses.create(
|
|
606
617
|
model=self.id,
|
|
607
|
-
input=self._format_messages(messages), # type: ignore
|
|
618
|
+
input=self._format_messages(messages, compress_tool_results), # type: ignore
|
|
608
619
|
**request_params,
|
|
609
620
|
)
|
|
610
621
|
|
|
@@ -657,6 +668,7 @@ class OpenAIResponses(Model):
|
|
|
657
668
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
658
669
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
659
670
|
run_response: Optional[RunOutput] = None,
|
|
671
|
+
compress_tool_results: bool = False,
|
|
660
672
|
) -> Iterator[ModelResponse]:
|
|
661
673
|
"""
|
|
662
674
|
Send a streaming request to the OpenAI Responses API.
|
|
@@ -674,7 +686,7 @@ class OpenAIResponses(Model):
|
|
|
674
686
|
|
|
675
687
|
for chunk in self.get_client().responses.create(
|
|
676
688
|
model=self.id,
|
|
677
|
-
input=self._format_messages(messages), # type: ignore
|
|
689
|
+
input=self._format_messages(messages, compress_tool_results), # type: ignore
|
|
678
690
|
stream=True,
|
|
679
691
|
**request_params,
|
|
680
692
|
):
|
|
@@ -730,6 +742,7 @@ class OpenAIResponses(Model):
|
|
|
730
742
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
731
743
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
732
744
|
run_response: Optional[RunOutput] = None,
|
|
745
|
+
compress_tool_results: bool = False,
|
|
733
746
|
) -> AsyncIterator[ModelResponse]:
|
|
734
747
|
"""
|
|
735
748
|
Sends an asynchronous streaming request to the OpenAI Responses API.
|
|
@@ -747,7 +760,7 @@ class OpenAIResponses(Model):
|
|
|
747
760
|
|
|
748
761
|
async_stream = await self.get_async_client().responses.create(
|
|
749
762
|
model=self.id,
|
|
750
|
-
input=self._format_messages(messages), # type: ignore
|
|
763
|
+
input=self._format_messages(messages, compress_tool_results), # type: ignore
|
|
751
764
|
stream=True,
|
|
752
765
|
**request_params,
|
|
753
766
|
)
|
|
@@ -793,7 +806,11 @@ class OpenAIResponses(Model):
|
|
|
793
806
|
raise ModelProviderError(message=str(exc), model_name=self.name, model_id=self.id) from exc
|
|
794
807
|
|
|
795
808
|
def format_function_call_results(
|
|
796
|
-
self,
|
|
809
|
+
self,
|
|
810
|
+
messages: List[Message],
|
|
811
|
+
function_call_results: List[Message],
|
|
812
|
+
tool_call_ids: List[str],
|
|
813
|
+
compress_tool_results: bool = False,
|
|
797
814
|
) -> None:
|
|
798
815
|
"""
|
|
799
816
|
Handle the results of function calls.
|
|
@@ -802,6 +819,7 @@ class OpenAIResponses(Model):
|
|
|
802
819
|
messages (List[Message]): The list of conversation messages.
|
|
803
820
|
function_call_results (List[Message]): The results of the function calls.
|
|
804
821
|
tool_ids (List[str]): The tool ids.
|
|
822
|
+
compress_tool_results (bool): Whether to compress tool results.
|
|
805
823
|
"""
|
|
806
824
|
if len(function_call_results) > 0:
|
|
807
825
|
for _fc_message_index, _fc_message in enumerate(function_call_results):
|
|
@@ -4,6 +4,7 @@ from typing import Any, Dict, List, Optional, Type, Union
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
+
from agno.exceptions import ModelProviderError
|
|
7
8
|
from agno.models.openai.like import OpenAILike
|
|
8
9
|
from agno.run.agent import RunOutput
|
|
9
10
|
|
|
@@ -34,6 +35,25 @@ class OpenRouter(OpenAILike):
|
|
|
34
35
|
max_tokens: int = 1024
|
|
35
36
|
models: Optional[List[str]] = None # Dynamic model routing https://openrouter.ai/docs/features/model-routing
|
|
36
37
|
|
|
38
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
39
|
+
"""
|
|
40
|
+
Returns client parameters for API requests, checking for OPENROUTER_API_KEY.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
44
|
+
"""
|
|
45
|
+
# Fetch API key from env if not already set
|
|
46
|
+
if not self.api_key:
|
|
47
|
+
self.api_key = getenv("OPENROUTER_API_KEY")
|
|
48
|
+
if not self.api_key:
|
|
49
|
+
raise ModelProviderError(
|
|
50
|
+
message="OPENROUTER_API_KEY not set. Please set the OPENROUTER_API_KEY environment variable.",
|
|
51
|
+
model_name=self.name,
|
|
52
|
+
model_id=self.id,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return super()._get_client_params()
|
|
56
|
+
|
|
37
57
|
def get_request_params(
|
|
38
58
|
self,
|
|
39
59
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -50,6 +50,23 @@ class Perplexity(OpenAILike):
|
|
|
50
50
|
supports_native_structured_outputs: bool = False
|
|
51
51
|
supports_json_schema_outputs: bool = True
|
|
52
52
|
|
|
53
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
54
|
+
"""
|
|
55
|
+
Returns client parameters for API requests, checking for PERPLEXITY_API_KEY.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
59
|
+
"""
|
|
60
|
+
if not self.api_key:
|
|
61
|
+
self.api_key = getenv("PERPLEXITY_API_KEY")
|
|
62
|
+
if not self.api_key:
|
|
63
|
+
raise ModelProviderError(
|
|
64
|
+
message="PERPLEXITY_API_KEY not set. Please set the PERPLEXITY_API_KEY environment variable.",
|
|
65
|
+
model_name=self.name,
|
|
66
|
+
model_id=self.id,
|
|
67
|
+
)
|
|
68
|
+
return super()._get_client_params()
|
|
69
|
+
|
|
53
70
|
def get_request_params(
|
|
54
71
|
self,
|
|
55
72
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
agno/models/requesty/requesty.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import Any, Dict, List, Optional, Type, Union
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
+
from agno.exceptions import ModelProviderError
|
|
7
8
|
from agno.models.openai.like import OpenAILike
|
|
8
9
|
from agno.run.agent import RunOutput
|
|
9
10
|
from agno.run.team import TeamRunOutput
|
|
@@ -30,6 +31,23 @@ class Requesty(OpenAILike):
|
|
|
30
31
|
base_url: str = "https://router.requesty.ai/v1"
|
|
31
32
|
max_tokens: int = 1024
|
|
32
33
|
|
|
34
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
35
|
+
"""
|
|
36
|
+
Returns client parameters for API requests, checking for REQUESTY_API_KEY.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
40
|
+
"""
|
|
41
|
+
if not self.api_key:
|
|
42
|
+
self.api_key = getenv("REQUESTY_API_KEY")
|
|
43
|
+
if not self.api_key:
|
|
44
|
+
raise ModelProviderError(
|
|
45
|
+
message="REQUESTY_API_KEY not set. Please set the REQUESTY_API_KEY environment variable.",
|
|
46
|
+
model_name=self.name,
|
|
47
|
+
model_id=self.id,
|
|
48
|
+
)
|
|
49
|
+
return super()._get_client_params()
|
|
50
|
+
|
|
33
51
|
def get_request_params(
|
|
34
52
|
self,
|
|
35
53
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
|
+
from agno.exceptions import ModelProviderError
|
|
5
6
|
from agno.models.openai.like import OpenAILike
|
|
6
7
|
|
|
7
8
|
|
|
@@ -26,3 +27,20 @@ class Sambanova(OpenAILike):
|
|
|
26
27
|
base_url: str = "https://api.sambanova.ai/v1"
|
|
27
28
|
|
|
28
29
|
supports_native_structured_outputs: bool = False
|
|
30
|
+
|
|
31
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
32
|
+
"""
|
|
33
|
+
Returns client parameters for API requests, checking for SAMBANOVA_API_KEY.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
37
|
+
"""
|
|
38
|
+
if not self.api_key:
|
|
39
|
+
self.api_key = getenv("SAMBANOVA_API_KEY")
|
|
40
|
+
if not self.api_key:
|
|
41
|
+
raise ModelProviderError(
|
|
42
|
+
message="SAMBANOVA_API_KEY not set. Please set the SAMBANOVA_API_KEY environment variable.",
|
|
43
|
+
model_name=self.name,
|
|
44
|
+
model_id=self.id,
|
|
45
|
+
)
|
|
46
|
+
return super()._get_client_params()
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
|
+
from agno.exceptions import ModelProviderError
|
|
5
6
|
from agno.models.openai.like import OpenAILike
|
|
6
7
|
|
|
7
8
|
|
|
@@ -23,3 +24,20 @@ class Siliconflow(OpenAILike):
|
|
|
23
24
|
provider: str = "Siliconflow"
|
|
24
25
|
api_key: Optional[str] = getenv("SILICONFLOW_API_KEY")
|
|
25
26
|
base_url: str = "https://api.siliconflow.com/v1"
|
|
27
|
+
|
|
28
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
29
|
+
"""
|
|
30
|
+
Returns client parameters for API requests, checking for SILICONFLOW_API_KEY.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
34
|
+
"""
|
|
35
|
+
if not self.api_key:
|
|
36
|
+
self.api_key = getenv("SILICONFLOW_API_KEY")
|
|
37
|
+
if not self.api_key:
|
|
38
|
+
raise ModelProviderError(
|
|
39
|
+
message="SILICONFLOW_API_KEY not set. Please set the SILICONFLOW_API_KEY environment variable.",
|
|
40
|
+
model_name=self.name,
|
|
41
|
+
model_id=self.id,
|
|
42
|
+
)
|
|
43
|
+
return super()._get_client_params()
|