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.
Files changed (85) hide show
  1. agno/agent/agent.py +101 -140
  2. agno/db/mongo/mongo.py +8 -3
  3. agno/eval/accuracy.py +12 -5
  4. agno/knowledge/chunking/strategy.py +14 -14
  5. agno/knowledge/knowledge.py +156 -120
  6. agno/knowledge/reader/arxiv_reader.py +5 -5
  7. agno/knowledge/reader/csv_reader.py +6 -77
  8. agno/knowledge/reader/docx_reader.py +5 -5
  9. agno/knowledge/reader/firecrawl_reader.py +5 -5
  10. agno/knowledge/reader/json_reader.py +5 -5
  11. agno/knowledge/reader/markdown_reader.py +31 -9
  12. agno/knowledge/reader/pdf_reader.py +10 -123
  13. agno/knowledge/reader/reader_factory.py +65 -72
  14. agno/knowledge/reader/s3_reader.py +44 -114
  15. agno/knowledge/reader/text_reader.py +5 -5
  16. agno/knowledge/reader/url_reader.py +75 -31
  17. agno/knowledge/reader/web_search_reader.py +6 -29
  18. agno/knowledge/reader/website_reader.py +5 -5
  19. agno/knowledge/reader/wikipedia_reader.py +5 -5
  20. agno/knowledge/reader/youtube_reader.py +6 -6
  21. agno/knowledge/reranker/__init__.py +9 -0
  22. agno/knowledge/utils.py +10 -10
  23. agno/media.py +269 -268
  24. agno/models/aws/bedrock.py +3 -7
  25. agno/models/base.py +50 -54
  26. agno/models/google/gemini.py +11 -10
  27. agno/models/message.py +4 -4
  28. agno/models/ollama/chat.py +1 -1
  29. agno/models/openai/chat.py +33 -14
  30. agno/models/response.py +5 -5
  31. agno/os/app.py +40 -29
  32. agno/os/mcp.py +39 -59
  33. agno/os/router.py +547 -16
  34. agno/os/routers/evals/evals.py +197 -12
  35. agno/os/routers/knowledge/knowledge.py +428 -14
  36. agno/os/routers/memory/memory.py +250 -28
  37. agno/os/routers/metrics/metrics.py +125 -7
  38. agno/os/routers/session/session.py +393 -25
  39. agno/os/schema.py +55 -2
  40. agno/run/agent.py +37 -28
  41. agno/run/base.py +9 -19
  42. agno/run/team.py +110 -19
  43. agno/run/workflow.py +41 -28
  44. agno/team/team.py +808 -1080
  45. agno/tools/brightdata.py +3 -3
  46. agno/tools/cartesia.py +3 -5
  47. agno/tools/dalle.py +7 -4
  48. agno/tools/desi_vocal.py +2 -2
  49. agno/tools/e2b.py +6 -6
  50. agno/tools/eleven_labs.py +3 -3
  51. agno/tools/fal.py +4 -4
  52. agno/tools/function.py +7 -7
  53. agno/tools/giphy.py +2 -2
  54. agno/tools/lumalab.py +3 -3
  55. agno/tools/mcp.py +1 -2
  56. agno/tools/models/azure_openai.py +2 -2
  57. agno/tools/models/gemini.py +3 -3
  58. agno/tools/models/groq.py +3 -5
  59. agno/tools/models/nebius.py +2 -2
  60. agno/tools/models_labs.py +5 -5
  61. agno/tools/openai.py +4 -9
  62. agno/tools/opencv.py +3 -3
  63. agno/tools/replicate.py +7 -7
  64. agno/utils/events.py +5 -5
  65. agno/utils/gemini.py +1 -1
  66. agno/utils/log.py +52 -2
  67. agno/utils/mcp.py +57 -5
  68. agno/utils/models/aws_claude.py +1 -1
  69. agno/utils/models/claude.py +0 -8
  70. agno/utils/models/cohere.py +1 -1
  71. agno/utils/models/watsonx.py +1 -1
  72. agno/utils/openai.py +1 -1
  73. agno/utils/print_response/team.py +177 -73
  74. agno/utils/streamlit.py +27 -0
  75. agno/vectordb/lancedb/lance_db.py +82 -25
  76. agno/workflow/step.py +7 -7
  77. agno/workflow/types.py +13 -13
  78. agno/workflow/workflow.py +37 -28
  79. {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/METADATA +140 -1
  80. {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/RECORD +83 -84
  81. agno-2.0.1.dist-info/licenses/LICENSE +201 -0
  82. agno/knowledge/reader/gcs_reader.py +0 -67
  83. agno-2.0.0rc1.dist-info/licenses/LICENSE +0 -375
  84. {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/WHEEL +0 -0
  85. {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 ImageArtifact
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 ImageArtifact for the screenshot
162
- image_artifact = ImageArtifact(
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 AudioArtifact
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 = AudioArtifact(
174
+ audio_artifact = Audio(
177
175
  id=str(uuid4()),
178
- base64_audio=base64_audio,
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 ImageArtifact
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
- image_artifact = ImageArtifact(
98
- id=str(uuid4()), url=img.url, original_prompt=prompt, revised_prompt=img.revised_prompt
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(image_artifact)
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 AudioArtifact
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 = AudioArtifact(id=str(uuid4()), url=audio_url)
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 ImageArtifact
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 ImageArtifact.
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 ImageArtifact
208
+ # Create Image object
209
209
  image_id = str(uuid4())
210
- image_artifact = ImageArtifact(
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 ImageArtifact
295
+ # Create Image object
296
296
  image_id = str(uuid4())
297
- image_artifact = ImageArtifact(
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 AudioArtifact
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 = AudioArtifact(
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 = AudioArtifact(
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 ImageArtifact, VideoArtifact
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 = ImageArtifact(
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 = VideoArtifact(
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 = ImageArtifact(
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, AudioArtifact, File, Image, ImageArtifact, Video, VideoArtifact
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[ImageArtifact]] = None
486
- videos: Optional[List[VideoArtifact]] = None
487
- audios: Optional[List[AudioArtifact]] = None
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[ImageArtifact]] = None
966
- videos: Optional[List[VideoArtifact]] = None
967
- audios: Optional[List[AudioArtifact]] = None
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 ImageArtifact
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 = ImageArtifact(id=media_id, url=gif_url, alt_text=alt_text, revised_prompt=query)
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 VideoArtifact
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 = VideoArtifact(id=video_id, url=video_url, eta="completed")
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 = VideoArtifact(id=video_id, url=video_url, state="completed")
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
- List[Union[SSEClientParams, StdioServerParameters, StreamableHTTPClientParams]]
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 ImageArtifact
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 = ImageArtifact(
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)
@@ -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 ImageArtifact, VideoArtifact
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 = ImageArtifact(
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 = VideoArtifact(
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 AudioArtifact
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 = AudioArtifact(
147
+ audio_artifact = Audio(
150
148
  id=media_id,
151
- base64_audio=base64_encoded_audio,
149
+ content=audio_data,
152
150
  mime_type="audio/wav",
153
151
  )
154
152
 
@@ -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 ImageArtifact
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 = ImageArtifact(
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 AudioArtifact, ImageArtifact, VideoArtifact
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[ImageArtifact, VideoArtifact, AudioArtifact]]] = {
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 = VideoArtifact(id=str(media_id), url=media_url, eta=str(eta))
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 = ImageArtifact(id=str(media_id), url=media_url)
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 = AudioArtifact(id=str(media_id), url=media_url)
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 AudioArtifact, ImageArtifact
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 = ImageArtifact(
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 = AudioArtifact(
191
+ audio_artifact = Audio(
197
192
  id=media_id,
198
- base64_audio=base64_encoded_audio,
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 ImageArtifact, VideoArtifact
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 = ImageArtifact(
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 = VideoArtifact(
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 ImageArtifact, VideoArtifact
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, ImageArtifact):
75
+ if isinstance(media_artifact, Image):
76
76
  images.append(media_artifact)
77
- elif isinstance(media_artifact, VideoArtifact):
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[ImageArtifact, VideoArtifact]]:
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[ImageArtifact, VideoArtifact]
104
+ artifact: Union[Image, Video]
105
105
  media_type: str
106
106
 
107
107
  if ext in image_extensions:
108
- artifact = ImageArtifact(id=media_id, url=output.url)
108
+ artifact = Image(id=media_id, url=output.url)
109
109
  media_type = "image"
110
110
  elif ext in video_extensions:
111
- artifact = VideoArtifact(id=media_id, url=output.url)
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 AudioResponse, ImageArtifact
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[AudioResponse] = None,
348
- image: Optional[ImageArtifact] = None,
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[AudioResponse] = None,
378
- image: Optional[ImageArtifact] = None,
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.image_url_content
22
+ content_bytes = image.get_content_bytes() # type: ignore
23
23
  if content_bytes is not None:
24
24
  try:
25
25
  import base64