agno 2.0.0rc1__py3-none-any.whl → 2.0.0rc2__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 (49) hide show
  1. agno/agent/agent.py +32 -14
  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/utils.py +10 -10
  22. agno/models/aws/bedrock.py +3 -7
  23. agno/models/base.py +37 -6
  24. agno/os/app.py +32 -24
  25. agno/os/mcp.py +39 -59
  26. agno/os/router.py +547 -16
  27. agno/os/routers/evals/evals.py +197 -12
  28. agno/os/routers/knowledge/knowledge.py +428 -14
  29. agno/os/routers/memory/memory.py +250 -28
  30. agno/os/routers/metrics/metrics.py +125 -7
  31. agno/os/routers/session/session.py +393 -25
  32. agno/os/schema.py +55 -2
  33. agno/run/agent.py +9 -0
  34. agno/run/team.py +93 -2
  35. agno/run/workflow.py +25 -12
  36. agno/team/team.py +861 -1051
  37. agno/tools/mcp.py +1 -2
  38. agno/utils/log.py +52 -2
  39. agno/utils/mcp.py +55 -3
  40. agno/utils/models/claude.py +0 -8
  41. agno/utils/print_response/team.py +177 -73
  42. agno/utils/streamlit.py +27 -0
  43. agno/workflow/workflow.py +9 -0
  44. {agno-2.0.0rc1.dist-info → agno-2.0.0rc2.dist-info}/METADATA +1 -1
  45. {agno-2.0.0rc1.dist-info → agno-2.0.0rc2.dist-info}/RECORD +48 -49
  46. agno/knowledge/reader/gcs_reader.py +0 -67
  47. {agno-2.0.0rc1.dist-info → agno-2.0.0rc2.dist-info}/WHEEL +0 -0
  48. {agno-2.0.0rc1.dist-info → agno-2.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  49. {agno-2.0.0rc1.dist-info → agno-2.0.0rc2.dist-info}/top_level.txt +0 -0
agno/run/team.py CHANGED
@@ -1,11 +1,11 @@
1
1
  from dataclasses import asdict, dataclass, field
2
2
  from enum import Enum
3
3
  from time import time
4
- from typing import Any, Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Optional, Sequence, Union
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
8
- from agno.media import AudioArtifact, AudioResponse, ImageArtifact, VideoArtifact
8
+ from agno.media import AudioArtifact, AudioResponse, File, ImageArtifact, VideoArtifact
9
9
  from agno.models.message import Citations, Message
10
10
  from agno.models.metrics import Metrics
11
11
  from agno.models.response import ToolExecution
@@ -40,6 +40,8 @@ class TeamRunEvent(str, Enum):
40
40
  output_model_response_started = "TeamOutputModelResponseStarted"
41
41
  output_model_response_completed = "TeamOutputModelResponseCompleted"
42
42
 
43
+ custom_event = "CustomEvent"
44
+
43
45
 
44
46
  @dataclass
45
47
  class BaseTeamRunEvent(BaseRunOutputEvent):
@@ -213,6 +215,11 @@ class OutputModelResponseCompletedEvent(BaseTeamRunEvent):
213
215
  event: str = TeamRunEvent.output_model_response_completed.value
214
216
 
215
217
 
218
+ @dataclass
219
+ class CustomEvent(BaseTeamRunEvent):
220
+ event: str = TeamRunEvent.custom_event.value
221
+
222
+
216
223
  TeamRunOutputEvent = Union[
217
224
  RunStartedEvent,
218
225
  RunContentEvent,
@@ -231,6 +238,7 @@ TeamRunOutputEvent = Union[
231
238
  ParserModelResponseCompletedEvent,
232
239
  OutputModelResponseStartedEvent,
233
240
  OutputModelResponseCompletedEvent,
241
+ CustomEvent,
234
242
  ]
235
243
 
236
244
  # Map event string to dataclass for team events
@@ -252,6 +260,7 @@ TEAM_RUN_EVENT_TYPE_REGISTRY = {
252
260
  TeamRunEvent.parser_model_response_completed.value: ParserModelResponseCompletedEvent,
253
261
  TeamRunEvent.output_model_response_started.value: OutputModelResponseStartedEvent,
254
262
  TeamRunEvent.output_model_response_completed.value: OutputModelResponseCompletedEvent,
263
+ TeamRunEvent.custom_event.value: CustomEvent,
255
264
  }
256
265
 
257
266
 
@@ -266,6 +275,76 @@ def team_run_output_event_from_dict(data: dict) -> BaseTeamRunEvent:
266
275
  return event_class.from_dict(data) # type: ignore
267
276
 
268
277
 
278
+ @dataclass
279
+ class TeamRunInput:
280
+ """Container for the raw input data passed to Agent.run().
281
+ This captures the original input exactly as provided by the user,
282
+ separate from the processed messages that go to the model.
283
+ Attributes:
284
+ input_content: The literal input message/content passed to run()
285
+ images: Images directly passed to run()
286
+ videos: Videos directly passed to run()
287
+ audios: Audio files directly passed to run()
288
+ files: Files directly passed to run()
289
+ """
290
+
291
+ input_content: Optional[Union[str, List, Dict, Message, BaseModel, List[Message]]] = None
292
+ images: Optional[Sequence[ImageArtifact]] = None
293
+ videos: Optional[Sequence[VideoArtifact]] = None
294
+ audios: Optional[Sequence[AudioArtifact]] = None
295
+ files: Optional[Sequence[File]] = None
296
+
297
+ def to_dict(self) -> Dict[str, Any]:
298
+ """Convert to dictionary representation"""
299
+ result: Dict[str, Any] = {}
300
+
301
+ if self.input_content is not None:
302
+ if isinstance(self.input_content, (str)):
303
+ result["input_content"] = self.input_content
304
+ elif isinstance(self.input_content, BaseModel):
305
+ result["input_content"] = self.input_content.model_dump(exclude_none=True)
306
+ elif isinstance(self.input_content, Message):
307
+ result["input_content"] = self.input_content.to_dict()
308
+ elif (
309
+ isinstance(self.input_content, list)
310
+ and self.input_content
311
+ and isinstance(self.input_content[0], Message)
312
+ ):
313
+ result["input_content"] = [m.to_dict() for m in self.input_content]
314
+ else:
315
+ result["input_content"] = self.input_content
316
+
317
+ if self.images:
318
+ result["images"] = [img.to_dict() for img in self.images]
319
+ if self.videos:
320
+ result["videos"] = [vid.to_dict() for vid in self.videos]
321
+ if self.audios:
322
+ result["audios"] = [aud.to_dict() for aud in self.audios]
323
+
324
+ return result
325
+
326
+ @classmethod
327
+ def from_dict(cls, data: Dict[str, Any]) -> "TeamRunInput":
328
+ """Create TeamRunInput from dictionary"""
329
+ images = None
330
+ if data.get("images"):
331
+ images = [ImageArtifact.model_validate(img_data) for img_data in data["images"]]
332
+
333
+ videos = None
334
+ if data.get("videos"):
335
+ videos = [VideoArtifact.model_validate(vid_data) for vid_data in data["videos"]]
336
+
337
+ audios = None
338
+ if data.get("audios"):
339
+ audios = [AudioArtifact.model_validate(aud_data) for aud_data in data["audios"]]
340
+
341
+ files = None
342
+ if data.get("files"):
343
+ files = [File.model_validate(file_data) for file_data in data["files"]]
344
+
345
+ return cls(input_content=data.get("input_content"), images=images, videos=videos, audios=audios, files=files)
346
+
347
+
269
348
  @dataclass
270
349
  class TeamRunOutput:
271
350
  """Response returned by Team.run() functions"""
@@ -293,6 +372,9 @@ class TeamRunOutput:
293
372
 
294
373
  response_audio: Optional[AudioResponse] = None # Model audio response
295
374
 
375
+ # Input media and messages from user
376
+ input: Optional[TeamRunInput] = None
377
+
296
378
  reasoning_content: Optional[str] = None
297
379
 
298
380
  citations: Optional[Citations] = None
@@ -401,6 +483,9 @@ class TeamRunOutput:
401
483
  else:
402
484
  _dict["tools"].append(tool)
403
485
 
486
+ if self.input is not None:
487
+ _dict["input"] = self.input.to_dict()
488
+
404
489
  return _dict
405
490
 
406
491
  def to_json(self) -> str:
@@ -468,6 +553,11 @@ class TeamRunOutput:
468
553
  response_audio = data.pop("response_audio", None)
469
554
  response_audio = AudioResponse.model_validate(response_audio) if response_audio else None
470
555
 
556
+ input_data = data.pop("input", None)
557
+ input_obj = None
558
+ if input_data:
559
+ input_obj = TeamRunInput.from_dict(input_data)
560
+
471
561
  metrics = data.pop("metrics", None)
472
562
  if metrics:
473
563
  metrics = Metrics(**metrics)
@@ -487,6 +577,7 @@ class TeamRunOutput:
487
577
  videos=videos,
488
578
  audio=audio,
489
579
  response_audio=response_audio,
580
+ input=input_obj,
490
581
  citations=citations,
491
582
  tools=tools,
492
583
  events=events,
agno/run/workflow.py CHANGED
@@ -13,6 +13,9 @@ from agno.utils.log import log_error
13
13
 
14
14
  if TYPE_CHECKING:
15
15
  from agno.workflow.types import StepOutput, WorkflowMetrics
16
+ else:
17
+ StepOutput = Any
18
+ WorkflowMetrics = Any
16
19
 
17
20
 
18
21
  class WorkflowRunEvent(str, Enum):
@@ -46,6 +49,8 @@ class WorkflowRunEvent(str, Enum):
46
49
 
47
50
  step_output = "StepOutput"
48
51
 
52
+ custom_event = "CustomEvent"
53
+
49
54
 
50
55
  @dataclass
51
56
  class BaseWorkflowRunOutputEvent:
@@ -132,7 +137,7 @@ class WorkflowCompletedEvent(BaseWorkflowRunOutputEvent):
132
137
  content_type: str = "str"
133
138
 
134
139
  # Store actual step execution results as StepOutput objects
135
- step_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
140
+ step_results: List[StepOutput] = field(default_factory=list)
136
141
  metadata: Optional[Dict[str, Any]] = None
137
142
 
138
143
 
@@ -183,7 +188,7 @@ class StepCompletedEvent(BaseWorkflowRunOutputEvent):
183
188
  response_audio: Optional[AudioResponse] = None
184
189
 
185
190
  # Store actual step execution results as StepOutput objects
186
- step_response: Optional["StepOutput"] = None # noqa: F821
191
+ step_response: Optional[StepOutput] = None
187
192
 
188
193
 
189
194
  @dataclass
@@ -226,7 +231,7 @@ class LoopIterationCompletedEvent(BaseWorkflowRunOutputEvent):
226
231
  step_index: Optional[Union[int, tuple]] = None
227
232
  iteration: int = 0
228
233
  max_iterations: Optional[int] = None
229
- iteration_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
234
+ iteration_results: List[StepOutput] = field(default_factory=list)
230
235
  should_continue: bool = True
231
236
 
232
237
 
@@ -239,7 +244,7 @@ class LoopExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
239
244
  step_index: Optional[Union[int, tuple]] = None
240
245
  total_iterations: int = 0
241
246
  max_iterations: Optional[int] = None
242
- all_results: List[List["StepOutput"]] = field(default_factory=list) # noqa: F821
247
+ all_results: List[List[StepOutput]] = field(default_factory=list)
243
248
 
244
249
 
245
250
  @dataclass
@@ -262,7 +267,7 @@ class ParallelExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
262
267
  parallel_step_count: Optional[int] = None
263
268
 
264
269
  # Results from all parallel steps
265
- step_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
270
+ step_results: List[StepOutput] = field(default_factory=list)
266
271
 
267
272
 
268
273
  @dataclass
@@ -286,7 +291,7 @@ class ConditionExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
286
291
  executed_steps: Optional[int] = None
287
292
 
288
293
  # Results from executed steps
289
- step_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
294
+ step_results: List[StepOutput] = field(default_factory=list)
290
295
 
291
296
 
292
297
  @dataclass
@@ -312,7 +317,7 @@ class RouterExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
312
317
  executed_steps: Optional[int] = None
313
318
 
314
319
  # Results from executed steps
315
- step_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
320
+ step_results: List[StepOutput] = field(default_factory=list)
316
321
 
317
322
 
318
323
  @dataclass
@@ -336,7 +341,7 @@ class StepsExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
336
341
  executed_steps: Optional[int] = None
337
342
 
338
343
  # Results from executed steps
339
- step_results: List["StepOutput"] = field(default_factory=list) # noqa: F821
344
+ step_results: List[StepOutput] = field(default_factory=list)
340
345
 
341
346
 
342
347
  @dataclass
@@ -348,7 +353,7 @@ class StepOutputEvent(BaseWorkflowRunOutputEvent):
348
353
  step_index: Optional[Union[int, tuple]] = None
349
354
 
350
355
  # Store actual step execution result as StepOutput object
351
- step_output: Optional["StepOutput"] = None # noqa: F821
356
+ step_output: Optional[StepOutput] = None
352
357
 
353
358
  # Properties for backward compatibility
354
359
  @property
@@ -380,6 +385,13 @@ class StepOutputEvent(BaseWorkflowRunOutputEvent):
380
385
  return self.step_output.stop if self.step_output else False
381
386
 
382
387
 
388
+ @dataclass
389
+ class CustomEvent(BaseWorkflowRunOutputEvent):
390
+ """Event sent when a custom event is produced"""
391
+
392
+ event: str = WorkflowRunEvent.custom_event.value
393
+
394
+
383
395
  # Union type for all workflow run response events
384
396
  WorkflowRunOutputEvent = Union[
385
397
  WorkflowStartedEvent,
@@ -402,6 +414,7 @@ WorkflowRunOutputEvent = Union[
402
414
  StepsExecutionStartedEvent,
403
415
  StepsExecutionCompletedEvent,
404
416
  StepOutputEvent,
417
+ CustomEvent,
405
418
  ]
406
419
 
407
420
 
@@ -426,7 +439,7 @@ class WorkflowRunOutput:
426
439
  response_audio: Optional[AudioResponse] = None
427
440
 
428
441
  # Store actual step execution results as StepOutput objects
429
- step_results: List[Union["StepOutput", List["StepOutput"]]] = field(default_factory=list) # noqa: F821
442
+ step_results: List[Union[StepOutput, List[StepOutput]]] = field(default_factory=list)
430
443
 
431
444
  # Store agent/team responses separately with parent_run_id references
432
445
  step_executor_runs: Optional[List[Union[RunOutput, TeamRunOutput]]] = None
@@ -435,7 +448,7 @@ class WorkflowRunOutput:
435
448
  events: Optional[List[WorkflowRunOutputEvent]] = None
436
449
 
437
450
  # Workflow metrics aggregated from all steps
438
- metrics: Optional["WorkflowMetrics"] = None
451
+ metrics: Optional[WorkflowMetrics] = None
439
452
 
440
453
  metadata: Optional[Dict[str, Any]] = None
441
454
  created_at: int = field(default_factory=lambda: int(time()))
@@ -521,7 +534,7 @@ class WorkflowRunOutput:
521
534
  workflow_metrics = WorkflowMetrics.from_dict(workflow_metrics_dict)
522
535
 
523
536
  step_results = data.pop("step_results", [])
524
- parsed_step_results: List[Union["StepOutput", List["StepOutput"]]] = []
537
+ parsed_step_results: List[Union[StepOutput, List[StepOutput]]] = []
525
538
  if step_results:
526
539
  for step_output_dict in step_results:
527
540
  # Reconstruct StepOutput from dict