agno 2.0.0rc1__py3-none-any.whl → 2.0.1__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 +101 -140
- agno/db/mongo/mongo.py +8 -3
- agno/eval/accuracy.py +12 -5
- agno/knowledge/chunking/strategy.py +14 -14
- agno/knowledge/knowledge.py +156 -120
- agno/knowledge/reader/arxiv_reader.py +5 -5
- agno/knowledge/reader/csv_reader.py +6 -77
- agno/knowledge/reader/docx_reader.py +5 -5
- agno/knowledge/reader/firecrawl_reader.py +5 -5
- agno/knowledge/reader/json_reader.py +5 -5
- agno/knowledge/reader/markdown_reader.py +31 -9
- agno/knowledge/reader/pdf_reader.py +10 -123
- agno/knowledge/reader/reader_factory.py +65 -72
- agno/knowledge/reader/s3_reader.py +44 -114
- agno/knowledge/reader/text_reader.py +5 -5
- agno/knowledge/reader/url_reader.py +75 -31
- agno/knowledge/reader/web_search_reader.py +6 -29
- agno/knowledge/reader/website_reader.py +5 -5
- agno/knowledge/reader/wikipedia_reader.py +5 -5
- agno/knowledge/reader/youtube_reader.py +6 -6
- agno/knowledge/reranker/__init__.py +9 -0
- agno/knowledge/utils.py +10 -10
- agno/media.py +269 -268
- agno/models/aws/bedrock.py +3 -7
- agno/models/base.py +50 -54
- agno/models/google/gemini.py +11 -10
- agno/models/message.py +4 -4
- agno/models/ollama/chat.py +1 -1
- agno/models/openai/chat.py +33 -14
- agno/models/response.py +5 -5
- agno/os/app.py +40 -29
- agno/os/mcp.py +39 -59
- agno/os/router.py +547 -16
- agno/os/routers/evals/evals.py +197 -12
- agno/os/routers/knowledge/knowledge.py +428 -14
- agno/os/routers/memory/memory.py +250 -28
- agno/os/routers/metrics/metrics.py +125 -7
- agno/os/routers/session/session.py +393 -25
- agno/os/schema.py +55 -2
- agno/run/agent.py +37 -28
- agno/run/base.py +9 -19
- agno/run/team.py +110 -19
- agno/run/workflow.py +41 -28
- agno/team/team.py +808 -1080
- agno/tools/brightdata.py +3 -3
- agno/tools/cartesia.py +3 -5
- agno/tools/dalle.py +7 -4
- agno/tools/desi_vocal.py +2 -2
- agno/tools/e2b.py +6 -6
- agno/tools/eleven_labs.py +3 -3
- agno/tools/fal.py +4 -4
- agno/tools/function.py +7 -7
- agno/tools/giphy.py +2 -2
- agno/tools/lumalab.py +3 -3
- agno/tools/mcp.py +1 -2
- agno/tools/models/azure_openai.py +2 -2
- agno/tools/models/gemini.py +3 -3
- agno/tools/models/groq.py +3 -5
- agno/tools/models/nebius.py +2 -2
- agno/tools/models_labs.py +5 -5
- agno/tools/openai.py +4 -9
- agno/tools/opencv.py +3 -3
- agno/tools/replicate.py +7 -7
- agno/utils/events.py +5 -5
- agno/utils/gemini.py +1 -1
- agno/utils/log.py +52 -2
- agno/utils/mcp.py +57 -5
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +0 -8
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/print_response/team.py +177 -73
- agno/utils/streamlit.py +27 -0
- agno/vectordb/lancedb/lance_db.py +82 -25
- agno/workflow/step.py +7 -7
- agno/workflow/types.py +13 -13
- agno/workflow/workflow.py +37 -28
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/METADATA +140 -1
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/RECORD +83 -84
- agno-2.0.1.dist-info/licenses/LICENSE +201 -0
- agno/knowledge/reader/gcs_reader.py +0 -67
- agno-2.0.0rc1.dist-info/licenses/LICENSE +0 -375
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/WHEEL +0 -0
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/top_level.txt +0 -0
agno/tools/brightdata.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional
|
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Image
|
|
9
9
|
from agno.tools import Toolkit
|
|
10
10
|
from agno.tools.function import ToolResult
|
|
11
11
|
from agno.utils.log import log_debug, log_error, log_info
|
|
@@ -158,8 +158,8 @@ class BrightDataTools(Toolkit):
|
|
|
158
158
|
|
|
159
159
|
media_id = str(uuid4())
|
|
160
160
|
|
|
161
|
-
# Create
|
|
162
|
-
image_artifact =
|
|
161
|
+
# Create Image for the screenshot
|
|
162
|
+
image_artifact = Image(
|
|
163
163
|
id=media_id,
|
|
164
164
|
content=base64_encoded_image.encode("utf-8"),
|
|
165
165
|
mime_type="image/png",
|
agno/tools/cartesia.py
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from base64 import b64encode
|
|
3
2
|
from os import getenv
|
|
4
3
|
from typing import Any, Dict, List, Optional, Union
|
|
5
4
|
from uuid import uuid4
|
|
6
5
|
|
|
7
6
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
7
|
+
from agno.media import Audio
|
|
9
8
|
from agno.team.team import Team
|
|
10
9
|
from agno.tools import Toolkit
|
|
11
10
|
from agno.tools.function import ToolResult
|
|
@@ -170,12 +169,11 @@ class CartesiaTools(Toolkit):
|
|
|
170
169
|
|
|
171
170
|
audio_iterator = self.client.tts.bytes(**params)
|
|
172
171
|
audio_data = b"".join(chunk for chunk in audio_iterator)
|
|
173
|
-
base64_audio = b64encode(audio_data).decode("utf-8")
|
|
174
172
|
|
|
175
173
|
# Create AudioArtifact
|
|
176
|
-
audio_artifact =
|
|
174
|
+
audio_artifact = Audio(
|
|
177
175
|
id=str(uuid4()),
|
|
178
|
-
|
|
176
|
+
content=audio_data,
|
|
179
177
|
mime_type=mime_type, # Hardcoded to audio/mpeg
|
|
180
178
|
)
|
|
181
179
|
|
agno/tools/dalle.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import Any, List, Literal, Optional, Union
|
|
|
3
3
|
from uuid import uuid4
|
|
4
4
|
|
|
5
5
|
from agno.agent import Agent
|
|
6
|
-
from agno.media import
|
|
6
|
+
from agno.media import Image
|
|
7
7
|
from agno.team.team import Team
|
|
8
8
|
from agno.tools import Toolkit
|
|
9
9
|
from agno.tools.function import ToolResult
|
|
@@ -94,10 +94,13 @@ class DalleTools(Toolkit):
|
|
|
94
94
|
if response.data:
|
|
95
95
|
for img in response.data:
|
|
96
96
|
if img.url:
|
|
97
|
-
|
|
98
|
-
id=str(uuid4()),
|
|
97
|
+
image = Image(
|
|
98
|
+
id=str(uuid4()),
|
|
99
|
+
url=img.url,
|
|
100
|
+
original_prompt=prompt,
|
|
101
|
+
revised_prompt=img.revised_prompt,
|
|
99
102
|
)
|
|
100
|
-
generated_images.append(
|
|
103
|
+
generated_images.append(image)
|
|
101
104
|
response_str += f"Image has been generated at the URL {img.url}\n"
|
|
102
105
|
|
|
103
106
|
return ToolResult(
|
agno/tools/desi_vocal.py
CHANGED
|
@@ -5,7 +5,7 @@ from uuid import uuid4
|
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Audio
|
|
9
9
|
from agno.team.team import Team
|
|
10
10
|
from agno.tools import Toolkit
|
|
11
11
|
from agno.tools.function import ToolResult
|
|
@@ -97,7 +97,7 @@ class DesiVocalTools(Toolkit):
|
|
|
97
97
|
response_json = response.json()
|
|
98
98
|
audio_url = response_json["s3_path"]
|
|
99
99
|
|
|
100
|
-
audio_artifact =
|
|
100
|
+
audio_artifact = Audio(id=str(uuid4()), url=audio_url)
|
|
101
101
|
|
|
102
102
|
return ToolResult(
|
|
103
103
|
content=f"Audio generated successfully: {audio_url}",
|
agno/tools/e2b.py
CHANGED
|
@@ -8,7 +8,7 @@ from typing import Any, Callable, Dict, List, Optional, Union
|
|
|
8
8
|
from uuid import uuid4
|
|
9
9
|
|
|
10
10
|
from agno.agent import Agent
|
|
11
|
-
from agno.media import
|
|
11
|
+
from agno.media import Image
|
|
12
12
|
from agno.team.team import Team
|
|
13
13
|
from agno.tools import Toolkit
|
|
14
14
|
from agno.tools.function import ToolResult
|
|
@@ -161,7 +161,7 @@ class E2BTools(Toolkit):
|
|
|
161
161
|
self, agent: Union[Agent, Team], result_index: int = 0, output_path: Optional[str] = None
|
|
162
162
|
) -> ToolResult:
|
|
163
163
|
"""
|
|
164
|
-
Add a PNG image result from the last code execution as an
|
|
164
|
+
Add a PNG image result from the last code execution as an Image object.
|
|
165
165
|
|
|
166
166
|
Args:
|
|
167
167
|
agent: The agent to add the image artifact to
|
|
@@ -205,9 +205,9 @@ class E2BTools(Toolkit):
|
|
|
205
205
|
# Generate a file:// URL for the temp file
|
|
206
206
|
file_url = f"file://{temp_path}"
|
|
207
207
|
|
|
208
|
-
# Create
|
|
208
|
+
# Create Image object
|
|
209
209
|
image_id = str(uuid4())
|
|
210
|
-
image_artifact =
|
|
210
|
+
image_artifact = Image(
|
|
211
211
|
id=image_id, url=file_url, original_prompt=f"Generated from code execution result {result_index}"
|
|
212
212
|
)
|
|
213
213
|
|
|
@@ -292,9 +292,9 @@ class E2BTools(Toolkit):
|
|
|
292
292
|
# Generate a file:// URL for the temp file
|
|
293
293
|
file_url = f"file://{temp_path}"
|
|
294
294
|
|
|
295
|
-
# Create
|
|
295
|
+
# Create Image object
|
|
296
296
|
image_id = str(uuid4())
|
|
297
|
-
image_artifact =
|
|
297
|
+
image_artifact = Image(
|
|
298
298
|
id=image_id, url=file_url, original_prompt=f"Interactive {chart_type} chart from code execution"
|
|
299
299
|
)
|
|
300
300
|
|
agno/tools/eleven_labs.py
CHANGED
|
@@ -6,7 +6,7 @@ from typing import Any, Iterator, List, Literal, Optional, Union
|
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
8
|
from agno.agent import Agent
|
|
9
|
-
from agno.media import
|
|
9
|
+
from agno.media import Audio
|
|
10
10
|
from agno.team.team import Team
|
|
11
11
|
from agno.tools import Toolkit
|
|
12
12
|
from agno.tools.function import ToolResult
|
|
@@ -147,7 +147,7 @@ class ElevenLabsTools(Toolkit):
|
|
|
147
147
|
base64_audio = self._process_audio(audio_generator)
|
|
148
148
|
|
|
149
149
|
# Create AudioArtifact
|
|
150
|
-
audio_artifact =
|
|
150
|
+
audio_artifact = Audio(
|
|
151
151
|
id=str(uuid4()),
|
|
152
152
|
base64_audio=base64_audio,
|
|
153
153
|
mime_type="audio/mpeg",
|
|
@@ -182,7 +182,7 @@ class ElevenLabsTools(Toolkit):
|
|
|
182
182
|
base64_audio = self._process_audio(audio_generator)
|
|
183
183
|
|
|
184
184
|
# Create AudioArtifact
|
|
185
|
-
audio_artifact =
|
|
185
|
+
audio_artifact = Audio(
|
|
186
186
|
id=str(uuid4()),
|
|
187
187
|
base64_audio=base64_audio,
|
|
188
188
|
mime_type="audio/mpeg",
|
agno/tools/fal.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import Optional, Union
|
|
|
7
7
|
from uuid import uuid4
|
|
8
8
|
|
|
9
9
|
from agno.agent import Agent
|
|
10
|
-
from agno.media import
|
|
10
|
+
from agno.media import Image, Video
|
|
11
11
|
from agno.team.team import Team
|
|
12
12
|
from agno.tools import Toolkit
|
|
13
13
|
from agno.tools.function import ToolResult
|
|
@@ -72,14 +72,14 @@ class FalTools(Toolkit):
|
|
|
72
72
|
|
|
73
73
|
if "image" in result:
|
|
74
74
|
url = result.get("image", {}).get("url", "")
|
|
75
|
-
image_artifact =
|
|
75
|
+
image_artifact = Image(
|
|
76
76
|
id=media_id,
|
|
77
77
|
url=url,
|
|
78
78
|
)
|
|
79
79
|
return ToolResult(content=f"Image generated successfully at {url}", images=[image_artifact])
|
|
80
80
|
elif "video" in result:
|
|
81
81
|
url = result.get("video", {}).get("url", "")
|
|
82
|
-
video_artifact =
|
|
82
|
+
video_artifact = Video(
|
|
83
83
|
id=media_id,
|
|
84
84
|
url=url,
|
|
85
85
|
)
|
|
@@ -115,7 +115,7 @@ class FalTools(Toolkit):
|
|
|
115
115
|
)
|
|
116
116
|
url = result.get("images", [{}])[0].get("url", "")
|
|
117
117
|
media_id = str(uuid4())
|
|
118
|
-
image_artifact =
|
|
118
|
+
image_artifact = Image(
|
|
119
119
|
id=media_id,
|
|
120
120
|
url=url,
|
|
121
121
|
)
|
agno/tools/function.py
CHANGED
|
@@ -8,7 +8,7 @@ from packaging.version import Version
|
|
|
8
8
|
from pydantic import BaseModel, Field, validate_call
|
|
9
9
|
|
|
10
10
|
from agno.exceptions import AgentRunException
|
|
11
|
-
from agno.media import Audio,
|
|
11
|
+
from agno.media import Audio, File, Image, Video
|
|
12
12
|
from agno.utils.log import log_debug, log_error, log_exception, log_warning
|
|
13
13
|
|
|
14
14
|
T = TypeVar("T")
|
|
@@ -482,9 +482,9 @@ class FunctionExecutionResult(BaseModel):
|
|
|
482
482
|
updated_session_state: Optional[Dict[str, Any]] = None
|
|
483
483
|
|
|
484
484
|
# New fields for media artifacts
|
|
485
|
-
images: Optional[List[
|
|
486
|
-
videos: Optional[List[
|
|
487
|
-
audios: Optional[List[
|
|
485
|
+
images: Optional[List[Image]] = None
|
|
486
|
+
videos: Optional[List[Video]] = None
|
|
487
|
+
audios: Optional[List[Audio]] = None
|
|
488
488
|
|
|
489
489
|
|
|
490
490
|
class FunctionCall(BaseModel):
|
|
@@ -962,6 +962,6 @@ class ToolResult(BaseModel):
|
|
|
962
962
|
"""Result from a tool that can include media artifacts."""
|
|
963
963
|
|
|
964
964
|
content: str
|
|
965
|
-
images: Optional[List[
|
|
966
|
-
videos: Optional[List[
|
|
967
|
-
audios: Optional[List[
|
|
965
|
+
images: Optional[List[Image]] = None
|
|
966
|
+
videos: Optional[List[Video]] = None
|
|
967
|
+
audios: Optional[List[Audio]] = None
|
agno/tools/giphy.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any, List, Optional, Union
|
|
|
5
5
|
import httpx
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Image
|
|
9
9
|
from agno.team.team import Team
|
|
10
10
|
from agno.tools import Toolkit
|
|
11
11
|
from agno.tools.function import ToolResult
|
|
@@ -77,7 +77,7 @@ class GiphyTools(Toolkit):
|
|
|
77
77
|
gif_urls.append(gif_url)
|
|
78
78
|
|
|
79
79
|
# Create ImageArtifact for the GIF
|
|
80
|
-
image_artifact =
|
|
80
|
+
image_artifact = Image(id=media_id, url=gif_url, alt_text=alt_text, revised_prompt=query)
|
|
81
81
|
image_artifacts.append(image_artifact)
|
|
82
82
|
|
|
83
83
|
if image_artifacts:
|
agno/tools/lumalab.py
CHANGED
|
@@ -4,7 +4,7 @@ from os import getenv
|
|
|
4
4
|
from typing import Any, Dict, List, Literal, Optional, TypedDict
|
|
5
5
|
|
|
6
6
|
from agno.agent import Agent
|
|
7
|
-
from agno.media import
|
|
7
|
+
from agno.media import Video
|
|
8
8
|
from agno.tools import Toolkit
|
|
9
9
|
from agno.tools.function import ToolResult
|
|
10
10
|
from agno.utils.log import log_info, logger
|
|
@@ -109,7 +109,7 @@ class LumaLabTools(Toolkit):
|
|
|
109
109
|
if generation.state == "completed" and generation.assets:
|
|
110
110
|
video_url = generation.assets.video
|
|
111
111
|
if video_url:
|
|
112
|
-
video_artifact =
|
|
112
|
+
video_artifact = Video(id=video_id, url=video_url, eta="completed")
|
|
113
113
|
return ToolResult(
|
|
114
114
|
content=f"Video generated successfully: {video_url}",
|
|
115
115
|
videos=[video_artifact],
|
|
@@ -164,7 +164,7 @@ class LumaLabTools(Toolkit):
|
|
|
164
164
|
if generation.state == "completed" and generation.assets:
|
|
165
165
|
video_url = generation.assets.video
|
|
166
166
|
if video_url:
|
|
167
|
-
video_artifact =
|
|
167
|
+
video_artifact = Video(id=video_id, url=video_url, state="completed")
|
|
168
168
|
return ToolResult(
|
|
169
169
|
content=f"Video generated successfully: {video_url}",
|
|
170
170
|
videos=[video_artifact],
|
agno/tools/mcp.py
CHANGED
|
@@ -365,7 +365,7 @@ class MultiMCPTools(Toolkit):
|
|
|
365
365
|
*,
|
|
366
366
|
env: Optional[dict[str, str]] = None,
|
|
367
367
|
server_params_list: Optional[
|
|
368
|
-
|
|
368
|
+
list[Union[SSEClientParams, StdioServerParameters, StreamableHTTPClientParams]]
|
|
369
369
|
] = None,
|
|
370
370
|
timeout_seconds: int = 5,
|
|
371
371
|
client=None,
|
|
@@ -531,7 +531,6 @@ class MultiMCPTools(Toolkit):
|
|
|
531
531
|
session = await self._async_exit_stack.enter_async_context(ClientSession(read, write))
|
|
532
532
|
self._active_contexts.append(session)
|
|
533
533
|
await self.initialize(session)
|
|
534
|
-
|
|
535
534
|
# Handle Streamable HTTP connections
|
|
536
535
|
elif isinstance(server_params, StreamableHTTPClientParams):
|
|
537
536
|
client_connection = await self._async_exit_stack.enter_async_context(
|
|
@@ -5,7 +5,7 @@ from uuid import uuid4
|
|
|
5
5
|
from requests import post
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Image
|
|
9
9
|
from agno.tools import Toolkit
|
|
10
10
|
from agno.tools.function import ToolResult
|
|
11
11
|
from agno.utils.log import log_debug, logger
|
|
@@ -170,7 +170,7 @@ class AzureOpenAITools(Toolkit):
|
|
|
170
170
|
revised_prompt = img.get("revised_prompt")
|
|
171
171
|
|
|
172
172
|
# Create ImageArtifact with URL
|
|
173
|
-
image_artifact =
|
|
173
|
+
image_artifact = Image(
|
|
174
174
|
id=str(uuid4()), url=image_url, original_prompt=prompt, revised_prompt=revised_prompt
|
|
175
175
|
)
|
|
176
176
|
generated_images.append(image_artifact)
|
agno/tools/models/gemini.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any, Optional
|
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Image, Video
|
|
9
9
|
from agno.tools import Toolkit
|
|
10
10
|
from agno.tools.function import ToolResult
|
|
11
11
|
from agno.utils.log import log_debug, log_error, log_info
|
|
@@ -109,7 +109,7 @@ class GeminiTools(Toolkit):
|
|
|
109
109
|
media_id = str(uuid4())
|
|
110
110
|
|
|
111
111
|
# Create ImageArtifact with raw bytes (not base64 encoded)
|
|
112
|
-
image_artifact =
|
|
112
|
+
image_artifact = Image(
|
|
113
113
|
id=media_id,
|
|
114
114
|
content=image_bytes,
|
|
115
115
|
original_prompt=prompt,
|
|
@@ -181,7 +181,7 @@ class GeminiTools(Toolkit):
|
|
|
181
181
|
media_id = str(uuid4())
|
|
182
182
|
|
|
183
183
|
# Create VideoArtifact with base64 encoded content
|
|
184
|
-
video_artifact =
|
|
184
|
+
video_artifact = Video(
|
|
185
185
|
id=media_id,
|
|
186
186
|
content=base64.b64encode(generated_video.video_bytes).decode("utf-8"),
|
|
187
187
|
original_prompt=prompt,
|
agno/tools/models/groq.py
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import base64
|
|
2
1
|
from os import getenv
|
|
3
2
|
from pathlib import Path
|
|
4
3
|
from typing import Any, List, Optional
|
|
5
4
|
from uuid import uuid4
|
|
6
5
|
|
|
7
6
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
7
|
+
from agno.media import Audio
|
|
9
8
|
from agno.tools import Toolkit
|
|
10
9
|
from agno.tools.function import ToolResult
|
|
11
10
|
from agno.utils.log import log_debug, log_error
|
|
@@ -143,12 +142,11 @@ class GroqTools(Toolkit):
|
|
|
143
142
|
log_debug(f"Groq TTS Response: {response}")
|
|
144
143
|
|
|
145
144
|
audio_data: bytes = response.read()
|
|
146
|
-
base64_encoded_audio = base64.b64encode(audio_data).decode("utf-8")
|
|
147
145
|
|
|
148
146
|
media_id = str(uuid4())
|
|
149
|
-
audio_artifact =
|
|
147
|
+
audio_artifact = Audio(
|
|
150
148
|
id=media_id,
|
|
151
|
-
|
|
149
|
+
content=audio_data,
|
|
152
150
|
mime_type="audio/wav",
|
|
153
151
|
)
|
|
154
152
|
|
agno/tools/models/nebius.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Optional
|
|
|
4
4
|
from uuid import uuid4
|
|
5
5
|
|
|
6
6
|
from agno.agent import Agent
|
|
7
|
-
from agno.media import
|
|
7
|
+
from agno.media import Image
|
|
8
8
|
from agno.models.nebius import Nebius
|
|
9
9
|
from agno.tools import Toolkit
|
|
10
10
|
from agno.tools.function import ToolResult
|
|
@@ -108,7 +108,7 @@ class NebiusTools(Toolkit):
|
|
|
108
108
|
media_id = str(uuid4())
|
|
109
109
|
|
|
110
110
|
# Create ImageArtifact with raw bytes
|
|
111
|
-
image_artifact =
|
|
111
|
+
image_artifact = Image(
|
|
112
112
|
id=media_id, content=image_content_bytes, mime_type="image/png", original_prompt=prompt
|
|
113
113
|
)
|
|
114
114
|
|
agno/tools/models_labs.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional, Union
|
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Audio, Image, Video
|
|
9
9
|
from agno.models.response import FileType
|
|
10
10
|
from agno.team import Team
|
|
11
11
|
from agno.tools import Toolkit
|
|
@@ -89,20 +89,20 @@ class ModelsLabTools(Toolkit):
|
|
|
89
89
|
|
|
90
90
|
def _create_media_artifacts(self, media_id: str, media_url: str, eta: Optional[str] = None) -> Dict[str, List]:
|
|
91
91
|
"""Create appropriate media artifacts based on file type."""
|
|
92
|
-
artifacts: Dict[str, List[Union[
|
|
92
|
+
artifacts: Dict[str, List[Union[Image, Video, Audio]]] = {
|
|
93
93
|
"images": [],
|
|
94
94
|
"videos": [],
|
|
95
95
|
"audios": [],
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
if self.file_type == FileType.MP4:
|
|
99
|
-
video_artifact =
|
|
99
|
+
video_artifact = Video(id=str(media_id), url=media_url, eta=str(eta))
|
|
100
100
|
artifacts["videos"].append(video_artifact)
|
|
101
101
|
elif self.file_type == FileType.GIF:
|
|
102
|
-
image_artifact =
|
|
102
|
+
image_artifact = Image(id=str(media_id), url=media_url)
|
|
103
103
|
artifacts["images"].append(image_artifact)
|
|
104
104
|
elif self.file_type == FileType.MP3:
|
|
105
|
-
audio_artifact =
|
|
105
|
+
audio_artifact = Audio(id=str(media_id), url=media_url)
|
|
106
106
|
artifacts["audios"].append(audio_artifact)
|
|
107
107
|
|
|
108
108
|
return artifacts
|
agno/tools/openai.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import Any, List, Literal, Optional, Union
|
|
|
3
3
|
from uuid import uuid4
|
|
4
4
|
|
|
5
5
|
from agno.agent import Agent
|
|
6
|
-
from agno.media import
|
|
6
|
+
from agno.media import Audio, Image
|
|
7
7
|
from agno.team.team import Team
|
|
8
8
|
from agno.tools import Toolkit
|
|
9
9
|
from agno.tools.function import ToolResult
|
|
@@ -149,7 +149,7 @@ class OpenAITools(Toolkit):
|
|
|
149
149
|
image_bytes = base64.b64decode(image_base64)
|
|
150
150
|
|
|
151
151
|
# Create ImageArtifact and return in ToolResult
|
|
152
|
-
image_artifact =
|
|
152
|
+
image_artifact = Image(
|
|
153
153
|
id=media_id,
|
|
154
154
|
content=image_bytes, # ← Store as bytes, not encoded string
|
|
155
155
|
mime_type="image/png",
|
|
@@ -176,8 +176,6 @@ class OpenAITools(Toolkit):
|
|
|
176
176
|
text_input (str): The text to synthesize into speech.
|
|
177
177
|
"""
|
|
178
178
|
try:
|
|
179
|
-
import base64
|
|
180
|
-
|
|
181
179
|
response = OpenAIClient(api_key=self.api_key).audio.speech.create(
|
|
182
180
|
model=self.tts_model,
|
|
183
181
|
voice=self.tts_voice,
|
|
@@ -188,14 +186,11 @@ class OpenAITools(Toolkit):
|
|
|
188
186
|
# Get raw audio data for artifact creation before potentially saving
|
|
189
187
|
audio_data: bytes = response.content
|
|
190
188
|
|
|
191
|
-
# Base64 encode the audio data
|
|
192
|
-
base64_encoded_audio = base64.b64encode(audio_data).decode("utf-8")
|
|
193
|
-
|
|
194
189
|
# Create AudioArtifact and return in ToolResult
|
|
195
190
|
media_id = str(uuid4())
|
|
196
|
-
audio_artifact =
|
|
191
|
+
audio_artifact = Audio(
|
|
197
192
|
id=media_id,
|
|
198
|
-
|
|
193
|
+
content=audio_data,
|
|
199
194
|
mime_type=f"audio/{self.tts_format}",
|
|
200
195
|
)
|
|
201
196
|
|
agno/tools/opencv.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Callable, List
|
|
|
4
4
|
from uuid import uuid4
|
|
5
5
|
|
|
6
6
|
from agno.agent import Agent
|
|
7
|
-
from agno.media import
|
|
7
|
+
from agno.media import Image, Video
|
|
8
8
|
from agno.tools import Toolkit
|
|
9
9
|
from agno.tools.function import ToolResult
|
|
10
10
|
from agno.utils.log import log_debug, log_error, log_info
|
|
@@ -120,7 +120,7 @@ class OpenCVTools(Toolkit):
|
|
|
120
120
|
media_id = str(uuid4())
|
|
121
121
|
|
|
122
122
|
# Create ImageArtifact with raw bytes (not base64 encoded)
|
|
123
|
-
image_artifact =
|
|
123
|
+
image_artifact = Image(
|
|
124
124
|
id=media_id,
|
|
125
125
|
content=image_bytes, # Store as raw bytes
|
|
126
126
|
original_prompt=prompt,
|
|
@@ -292,7 +292,7 @@ class OpenCVTools(Toolkit):
|
|
|
292
292
|
media_id = str(uuid4())
|
|
293
293
|
|
|
294
294
|
# Create VideoArtifact with base64 encoded content
|
|
295
|
-
video_artifact =
|
|
295
|
+
video_artifact = Video(
|
|
296
296
|
id=media_id,
|
|
297
297
|
content=video_bytes,
|
|
298
298
|
original_prompt=prompt,
|
agno/tools/replicate.py
CHANGED
|
@@ -5,7 +5,7 @@ from urllib.parse import urlparse
|
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import
|
|
8
|
+
from agno.media import Image, Video
|
|
9
9
|
from agno.team.team import Team
|
|
10
10
|
from agno.tools import Toolkit
|
|
11
11
|
from agno.tools.function import ToolResult
|
|
@@ -72,9 +72,9 @@ class ReplicateTools(Toolkit):
|
|
|
72
72
|
result_msg, media_artifact = self._parse_output(output)
|
|
73
73
|
results.append(result_msg)
|
|
74
74
|
|
|
75
|
-
if isinstance(media_artifact,
|
|
75
|
+
if isinstance(media_artifact, Image):
|
|
76
76
|
images.append(media_artifact)
|
|
77
|
-
elif isinstance(media_artifact,
|
|
77
|
+
elif isinstance(media_artifact, Video):
|
|
78
78
|
videos.append(media_artifact)
|
|
79
79
|
|
|
80
80
|
content = "\n".join(results)
|
|
@@ -87,7 +87,7 @@ class ReplicateTools(Toolkit):
|
|
|
87
87
|
logger.error(f"Failed to generate media: {e}")
|
|
88
88
|
return ToolResult(content=f"Error: {e}")
|
|
89
89
|
|
|
90
|
-
def _parse_output(self, output: FileOutput) -> Tuple[str, Union[
|
|
90
|
+
def _parse_output(self, output: FileOutput) -> Tuple[str, Union[Image, Video]]:
|
|
91
91
|
"""
|
|
92
92
|
Parse the outputs from the replicate model.
|
|
93
93
|
"""
|
|
@@ -101,14 +101,14 @@ class ReplicateTools(Toolkit):
|
|
|
101
101
|
video_extensions = {".mp4", ".mov", ".avi", ".mkv", ".flv", ".wmv", ".webm"}
|
|
102
102
|
|
|
103
103
|
media_id = str(uuid4())
|
|
104
|
-
artifact: Union[
|
|
104
|
+
artifact: Union[Image, Video]
|
|
105
105
|
media_type: str
|
|
106
106
|
|
|
107
107
|
if ext in image_extensions:
|
|
108
|
-
artifact =
|
|
108
|
+
artifact = Image(id=media_id, url=output.url)
|
|
109
109
|
media_type = "image"
|
|
110
110
|
elif ext in video_extensions:
|
|
111
|
-
artifact =
|
|
111
|
+
artifact = Video(id=media_id, url=output.url)
|
|
112
112
|
media_type = "video"
|
|
113
113
|
else:
|
|
114
114
|
logger.error(f"Unsupported media type with extension '{ext}' for URL: {output.url}")
|
agno/utils/events.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any, List, Optional
|
|
2
2
|
|
|
3
|
-
from agno.media import
|
|
3
|
+
from agno.media import Audio, Image
|
|
4
4
|
from agno.models.message import Citations
|
|
5
5
|
from agno.models.response import ToolExecution
|
|
6
6
|
from agno.reasoning.step import ReasoningStep
|
|
@@ -344,8 +344,8 @@ def create_run_output_content_event(
|
|
|
344
344
|
reasoning_content: Optional[str] = None,
|
|
345
345
|
redacted_reasoning_content: Optional[str] = None,
|
|
346
346
|
citations: Optional[Citations] = None,
|
|
347
|
-
response_audio: Optional[
|
|
348
|
-
image: Optional[
|
|
347
|
+
response_audio: Optional[Audio] = None,
|
|
348
|
+
image: Optional[Image] = None,
|
|
349
349
|
) -> RunContentEvent:
|
|
350
350
|
thinking_combined = (reasoning_content or "") + (redacted_reasoning_content or "")
|
|
351
351
|
|
|
@@ -374,8 +374,8 @@ def create_team_run_output_content_event(
|
|
|
374
374
|
reasoning_content: Optional[str] = None,
|
|
375
375
|
redacted_reasoning_content: Optional[str] = None,
|
|
376
376
|
citations: Optional[Citations] = None,
|
|
377
|
-
response_audio: Optional[
|
|
378
|
-
image: Optional[
|
|
377
|
+
response_audio: Optional[Audio] = None,
|
|
378
|
+
image: Optional[Image] = None,
|
|
379
379
|
) -> TeamRunContentEvent:
|
|
380
380
|
thinking_combined = (reasoning_content or "") + (redacted_reasoning_content or "")
|
|
381
381
|
|
agno/utils/gemini.py
CHANGED
|
@@ -19,7 +19,7 @@ def format_image_for_message(image: Image) -> Optional[Dict[str, Any]]:
|
|
|
19
19
|
# Case 1: Image is a URL
|
|
20
20
|
# Download the image from the URL and add it as base64 encoded data
|
|
21
21
|
if image.url is not None:
|
|
22
|
-
content_bytes = image.
|
|
22
|
+
content_bytes = image.get_content_bytes() # type: ignore
|
|
23
23
|
if content_bytes is not None:
|
|
24
24
|
try:
|
|
25
25
|
import base64
|