agno 2.0.3__py3-none-any.whl → 2.0.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 +162 -86
- agno/db/dynamo/dynamo.py +8 -0
- agno/db/firestore/firestore.py +8 -1
- agno/db/gcs_json/gcs_json_db.py +9 -0
- agno/db/json/json_db.py +8 -0
- agno/db/mongo/mongo.py +10 -1
- agno/db/mysql/mysql.py +10 -0
- agno/db/postgres/postgres.py +16 -8
- agno/db/redis/redis.py +6 -0
- agno/db/singlestore/schemas.py +1 -1
- agno/db/singlestore/singlestore.py +8 -1
- agno/db/sqlite/sqlite.py +9 -1
- agno/db/utils.py +14 -0
- agno/knowledge/knowledge.py +91 -65
- agno/models/base.py +2 -2
- agno/models/openai/chat.py +3 -0
- agno/models/openai/responses.py +6 -0
- agno/models/response.py +5 -0
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +25 -0
- agno/os/app.py +4 -1
- agno/os/auth.py +24 -14
- agno/os/router.py +128 -55
- agno/os/routers/evals/utils.py +9 -9
- agno/os/routers/health.py +26 -0
- agno/os/routers/knowledge/knowledge.py +11 -11
- agno/os/routers/session/session.py +24 -8
- agno/os/schema.py +8 -2
- agno/run/workflow.py +64 -10
- agno/session/team.py +1 -0
- agno/team/team.py +192 -92
- agno/tools/mem0.py +11 -17
- agno/tools/memory.py +34 -6
- agno/utils/common.py +90 -1
- agno/utils/streamlit.py +14 -8
- agno/vectordb/chroma/chromadb.py +8 -2
- agno/workflow/step.py +111 -13
- agno/workflow/workflow.py +16 -13
- {agno-2.0.3.dist-info → agno-2.0.4.dist-info}/METADATA +1 -1
- {agno-2.0.3.dist-info → agno-2.0.4.dist-info}/RECORD +43 -40
- {agno-2.0.3.dist-info → agno-2.0.4.dist-info}/WHEEL +0 -0
- {agno-2.0.3.dist-info → agno-2.0.4.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.3.dist-info → agno-2.0.4.dist-info}/top_level.txt +0 -0
agno/os/schema.py
CHANGED
|
@@ -826,7 +826,8 @@ class WorkflowSessionDetailSchema(BaseModel):
|
|
|
826
826
|
|
|
827
827
|
class RunSchema(BaseModel):
|
|
828
828
|
run_id: str
|
|
829
|
-
|
|
829
|
+
parent_run_id: Optional[str]
|
|
830
|
+
agent_id: Optional[str]
|
|
830
831
|
user_id: Optional[str]
|
|
831
832
|
run_input: Optional[str]
|
|
832
833
|
content: Optional[Union[str, dict]]
|
|
@@ -844,7 +845,8 @@ class RunSchema(BaseModel):
|
|
|
844
845
|
run_response_format = "text" if run_dict.get("content_type", "str") == "str" else "json"
|
|
845
846
|
return cls(
|
|
846
847
|
run_id=run_dict.get("run_id", ""),
|
|
847
|
-
|
|
848
|
+
parent_run_id=run_dict.get("parent_run_id", ""),
|
|
849
|
+
agent_id=run_dict.get("agent_id", ""),
|
|
848
850
|
user_id=run_dict.get("user_id", ""),
|
|
849
851
|
run_input=run_input,
|
|
850
852
|
content=run_dict.get("content", ""),
|
|
@@ -863,6 +865,7 @@ class RunSchema(BaseModel):
|
|
|
863
865
|
class TeamRunSchema(BaseModel):
|
|
864
866
|
run_id: str
|
|
865
867
|
parent_run_id: Optional[str]
|
|
868
|
+
team_id: Optional[str]
|
|
866
869
|
content: Optional[Union[str, dict]]
|
|
867
870
|
reasoning_content: Optional[str]
|
|
868
871
|
run_input: Optional[str]
|
|
@@ -880,6 +883,7 @@ class TeamRunSchema(BaseModel):
|
|
|
880
883
|
return cls(
|
|
881
884
|
run_id=run_dict.get("run_id", ""),
|
|
882
885
|
parent_run_id=run_dict.get("parent_run_id", ""),
|
|
886
|
+
team_id=run_dict.get("team_id", ""),
|
|
883
887
|
run_input=run_input,
|
|
884
888
|
content=run_dict.get("content", ""),
|
|
885
889
|
run_response_format=run_response_format,
|
|
@@ -897,6 +901,7 @@ class TeamRunSchema(BaseModel):
|
|
|
897
901
|
class WorkflowRunSchema(BaseModel):
|
|
898
902
|
run_id: str
|
|
899
903
|
run_input: Optional[str]
|
|
904
|
+
workflow_id: Optional[str]
|
|
900
905
|
user_id: Optional[str]
|
|
901
906
|
content: Optional[Union[str, dict]]
|
|
902
907
|
content_type: Optional[str]
|
|
@@ -912,6 +917,7 @@ class WorkflowRunSchema(BaseModel):
|
|
|
912
917
|
return cls(
|
|
913
918
|
run_id=run_response.get("run_id", ""),
|
|
914
919
|
run_input=run_input,
|
|
920
|
+
workflow_id=run_response.get("workflow_id", ""),
|
|
915
921
|
user_id=run_response.get("user_id", ""),
|
|
916
922
|
content=run_response.get("content", ""),
|
|
917
923
|
content_type=run_response.get("content_type", ""),
|
agno/run/workflow.py
CHANGED
|
@@ -7,7 +7,7 @@ from pydantic import BaseModel
|
|
|
7
7
|
|
|
8
8
|
from agno.media import Audio, Image, Video
|
|
9
9
|
from agno.run.agent import RunOutput
|
|
10
|
-
from agno.run.base import RunStatus
|
|
10
|
+
from agno.run.base import BaseRunOutputEvent, RunStatus
|
|
11
11
|
from agno.run.team import TeamRunOutput
|
|
12
12
|
from agno.utils.log import log_error
|
|
13
13
|
|
|
@@ -53,7 +53,7 @@ class WorkflowRunEvent(str, Enum):
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
@dataclass
|
|
56
|
-
class BaseWorkflowRunOutputEvent:
|
|
56
|
+
class BaseWorkflowRunOutputEvent(BaseRunOutputEvent):
|
|
57
57
|
"""Base class for all workflow run response events"""
|
|
58
58
|
|
|
59
59
|
created_at: int = field(default_factory=lambda: int(time()))
|
|
@@ -75,19 +75,23 @@ class BaseWorkflowRunOutputEvent:
|
|
|
75
75
|
|
|
76
76
|
# Handle StepOutput fields that contain Message objects
|
|
77
77
|
if hasattr(self, "step_results") and self.step_results is not None:
|
|
78
|
-
_dict["step_results"] = [step.to_dict() for step in self.step_results]
|
|
78
|
+
_dict["step_results"] = [step.to_dict() if hasattr(step, "to_dict") else step for step in self.step_results]
|
|
79
79
|
|
|
80
80
|
if hasattr(self, "step_response") and self.step_response is not None:
|
|
81
|
-
_dict["step_response"] =
|
|
81
|
+
_dict["step_response"] = (
|
|
82
|
+
self.step_response.to_dict() if hasattr(self.step_response, "to_dict") else self.step_response
|
|
83
|
+
)
|
|
82
84
|
|
|
83
85
|
if hasattr(self, "iteration_results") and self.iteration_results is not None:
|
|
84
|
-
_dict["iteration_results"] = [
|
|
86
|
+
_dict["iteration_results"] = [
|
|
87
|
+
step.to_dict() if hasattr(step, "to_dict") else step for step in self.iteration_results
|
|
88
|
+
]
|
|
85
89
|
|
|
86
90
|
if hasattr(self, "all_results") and self.all_results is not None:
|
|
87
|
-
_dict["all_results"] = [
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
_dict["all_results"] = [
|
|
92
|
+
[step.to_dict() if hasattr(step, "to_dict") else step for step in iteration]
|
|
93
|
+
for iteration in self.all_results
|
|
94
|
+
]
|
|
91
95
|
|
|
92
96
|
return _dict
|
|
93
97
|
|
|
@@ -420,6 +424,39 @@ WorkflowRunOutputEvent = Union[
|
|
|
420
424
|
CustomEvent,
|
|
421
425
|
]
|
|
422
426
|
|
|
427
|
+
# Map event string to dataclass for workflow events
|
|
428
|
+
WORKFLOW_RUN_EVENT_TYPE_REGISTRY = {
|
|
429
|
+
WorkflowRunEvent.workflow_started.value: WorkflowStartedEvent,
|
|
430
|
+
WorkflowRunEvent.workflow_completed.value: WorkflowCompletedEvent,
|
|
431
|
+
WorkflowRunEvent.workflow_cancelled.value: WorkflowCancelledEvent,
|
|
432
|
+
WorkflowRunEvent.workflow_error.value: WorkflowErrorEvent,
|
|
433
|
+
WorkflowRunEvent.step_started.value: StepStartedEvent,
|
|
434
|
+
WorkflowRunEvent.step_completed.value: StepCompletedEvent,
|
|
435
|
+
WorkflowRunEvent.step_error.value: StepErrorEvent,
|
|
436
|
+
WorkflowRunEvent.loop_execution_started.value: LoopExecutionStartedEvent,
|
|
437
|
+
WorkflowRunEvent.loop_iteration_started.value: LoopIterationStartedEvent,
|
|
438
|
+
WorkflowRunEvent.loop_iteration_completed.value: LoopIterationCompletedEvent,
|
|
439
|
+
WorkflowRunEvent.loop_execution_completed.value: LoopExecutionCompletedEvent,
|
|
440
|
+
WorkflowRunEvent.parallel_execution_started.value: ParallelExecutionStartedEvent,
|
|
441
|
+
WorkflowRunEvent.parallel_execution_completed.value: ParallelExecutionCompletedEvent,
|
|
442
|
+
WorkflowRunEvent.condition_execution_started.value: ConditionExecutionStartedEvent,
|
|
443
|
+
WorkflowRunEvent.condition_execution_completed.value: ConditionExecutionCompletedEvent,
|
|
444
|
+
WorkflowRunEvent.router_execution_started.value: RouterExecutionStartedEvent,
|
|
445
|
+
WorkflowRunEvent.router_execution_completed.value: RouterExecutionCompletedEvent,
|
|
446
|
+
WorkflowRunEvent.steps_execution_started.value: StepsExecutionStartedEvent,
|
|
447
|
+
WorkflowRunEvent.steps_execution_completed.value: StepsExecutionCompletedEvent,
|
|
448
|
+
WorkflowRunEvent.step_output.value: StepOutputEvent,
|
|
449
|
+
WorkflowRunEvent.custom_event.value: CustomEvent,
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def workflow_run_output_event_from_dict(data: dict) -> BaseWorkflowRunOutputEvent:
|
|
454
|
+
event_type = data.get("event", "")
|
|
455
|
+
cls = WORKFLOW_RUN_EVENT_TYPE_REGISTRY.get(event_type)
|
|
456
|
+
if not cls:
|
|
457
|
+
raise ValueError(f"Unknown workflow event type: {event_type}")
|
|
458
|
+
return cls.from_dict(data) # type: ignore
|
|
459
|
+
|
|
423
460
|
|
|
424
461
|
@dataclass
|
|
425
462
|
class WorkflowRunOutput:
|
|
@@ -568,7 +605,24 @@ class WorkflowRunOutput:
|
|
|
568
605
|
response_audio = data.pop("response_audio", None)
|
|
569
606
|
response_audio = Audio.model_validate(response_audio) if response_audio else None
|
|
570
607
|
|
|
571
|
-
|
|
608
|
+
events_data = data.pop("events", [])
|
|
609
|
+
final_events = []
|
|
610
|
+
for event in events_data or []:
|
|
611
|
+
if "agent_id" in event:
|
|
612
|
+
# Agent event from agent step
|
|
613
|
+
from agno.run.agent import run_output_event_from_dict
|
|
614
|
+
|
|
615
|
+
event = run_output_event_from_dict(event)
|
|
616
|
+
elif "team_id" in event:
|
|
617
|
+
# Team event from team step
|
|
618
|
+
from agno.run.team import team_run_output_event_from_dict
|
|
619
|
+
|
|
620
|
+
event = team_run_output_event_from_dict(event)
|
|
621
|
+
else:
|
|
622
|
+
# Pure workflow event
|
|
623
|
+
event = workflow_run_output_event_from_dict(event)
|
|
624
|
+
final_events.append(event)
|
|
625
|
+
events = final_events
|
|
572
626
|
|
|
573
627
|
return cls(
|
|
574
628
|
step_results=parsed_step_results,
|