agno 2.1.9__py3-none-any.whl → 2.2.0__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 (83) hide show
  1. agno/agent/agent.py +2048 -1204
  2. agno/culture/__init__.py +3 -0
  3. agno/culture/manager.py +954 -0
  4. agno/db/async_postgres/async_postgres.py +232 -0
  5. agno/db/async_postgres/schemas.py +15 -0
  6. agno/db/async_postgres/utils.py +58 -0
  7. agno/db/base.py +83 -6
  8. agno/db/dynamo/dynamo.py +162 -0
  9. agno/db/dynamo/schemas.py +44 -0
  10. agno/db/dynamo/utils.py +59 -0
  11. agno/db/firestore/firestore.py +231 -0
  12. agno/db/firestore/schemas.py +10 -0
  13. agno/db/firestore/utils.py +96 -0
  14. agno/db/gcs_json/gcs_json_db.py +190 -0
  15. agno/db/gcs_json/utils.py +58 -0
  16. agno/db/in_memory/in_memory_db.py +118 -0
  17. agno/db/in_memory/utils.py +58 -0
  18. agno/db/json/json_db.py +129 -0
  19. agno/db/json/utils.py +58 -0
  20. agno/db/mongo/mongo.py +222 -0
  21. agno/db/mongo/schemas.py +10 -0
  22. agno/db/mongo/utils.py +59 -0
  23. agno/db/mysql/mysql.py +232 -1
  24. agno/db/mysql/schemas.py +14 -0
  25. agno/db/mysql/utils.py +58 -0
  26. agno/db/postgres/postgres.py +242 -0
  27. agno/db/postgres/schemas.py +15 -0
  28. agno/db/postgres/utils.py +58 -0
  29. agno/db/redis/redis.py +181 -0
  30. agno/db/redis/schemas.py +14 -0
  31. agno/db/redis/utils.py +58 -0
  32. agno/db/schemas/__init__.py +2 -1
  33. agno/db/schemas/culture.py +120 -0
  34. agno/db/singlestore/schemas.py +14 -0
  35. agno/db/singlestore/singlestore.py +231 -0
  36. agno/db/singlestore/utils.py +58 -0
  37. agno/db/sqlite/schemas.py +14 -0
  38. agno/db/sqlite/sqlite.py +274 -7
  39. agno/db/sqlite/utils.py +62 -0
  40. agno/db/surrealdb/models.py +51 -1
  41. agno/db/surrealdb/surrealdb.py +154 -0
  42. agno/db/surrealdb/utils.py +61 -1
  43. agno/knowledge/reader/field_labeled_csv_reader.py +0 -2
  44. agno/memory/manager.py +28 -11
  45. agno/models/anthropic/claude.py +2 -2
  46. agno/models/message.py +0 -1
  47. agno/models/ollama/chat.py +7 -2
  48. agno/os/app.py +29 -7
  49. agno/os/interfaces/a2a/router.py +2 -2
  50. agno/os/interfaces/agui/router.py +2 -2
  51. agno/os/router.py +7 -7
  52. agno/os/routers/evals/schemas.py +31 -31
  53. agno/os/routers/health.py +6 -2
  54. agno/os/routers/knowledge/schemas.py +49 -47
  55. agno/os/routers/memory/schemas.py +16 -16
  56. agno/os/routers/metrics/schemas.py +16 -16
  57. agno/os/routers/session/session.py +382 -7
  58. agno/os/schema.py +254 -231
  59. agno/os/utils.py +1 -1
  60. agno/run/agent.py +49 -1
  61. agno/run/team.py +43 -0
  62. agno/session/summary.py +45 -13
  63. agno/session/team.py +90 -5
  64. agno/team/team.py +1118 -857
  65. agno/tools/gmail.py +59 -14
  66. agno/utils/agent.py +372 -0
  67. agno/utils/events.py +144 -2
  68. agno/utils/print_response/agent.py +10 -6
  69. agno/utils/print_response/team.py +6 -4
  70. agno/utils/print_response/workflow.py +7 -5
  71. agno/utils/team.py +9 -8
  72. agno/workflow/condition.py +17 -9
  73. agno/workflow/loop.py +18 -10
  74. agno/workflow/parallel.py +14 -6
  75. agno/workflow/router.py +17 -9
  76. agno/workflow/step.py +14 -6
  77. agno/workflow/steps.py +14 -6
  78. agno/workflow/workflow.py +245 -122
  79. {agno-2.1.9.dist-info → agno-2.2.0.dist-info}/METADATA +60 -23
  80. {agno-2.1.9.dist-info → agno-2.2.0.dist-info}/RECORD +83 -79
  81. {agno-2.1.9.dist-info → agno-2.2.0.dist-info}/WHEEL +0 -0
  82. {agno-2.1.9.dist-info → agno-2.2.0.dist-info}/licenses/LICENSE +0 -0
  83. {agno-2.1.9.dist-info → agno-2.2.0.dist-info}/top_level.txt +0 -0
agno/os/schema.py CHANGED
@@ -3,7 +3,7 @@ from enum import Enum
3
3
  from typing import Any, Dict, Generic, List, Optional, TypeVar, Union
4
4
  from uuid import uuid4
5
5
 
6
- from pydantic import BaseModel
6
+ from pydantic import BaseModel, ConfigDict, Field
7
7
 
8
8
  from agno.agent import Agent
9
9
  from agno.db.base import SessionType
@@ -25,78 +25,80 @@ from agno.workflow.workflow import Workflow
25
25
 
26
26
 
27
27
  class BadRequestResponse(BaseModel):
28
- detail: str
29
- error_code: Optional[str] = None
28
+ model_config = ConfigDict(json_schema_extra={"example": {"detail": "Bad request", "error_code": "BAD_REQUEST"}})
30
29
 
31
- class Config:
32
- json_schema_extra = {"example": {"detail": "Bad request", "error_code": "BAD_REQUEST"}}
30
+ detail: str = Field(..., description="Error detail message")
31
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
33
32
 
34
33
 
35
34
  class NotFoundResponse(BaseModel):
36
- detail: str
37
- error_code: Optional[str] = None
35
+ model_config = ConfigDict(json_schema_extra={"example": {"detail": "Not found", "error_code": "NOT_FOUND"}})
38
36
 
39
- class Config:
40
- json_schema_extra = {"example": {"detail": "Not found", "error_code": "NOT_FOUND"}}
37
+ detail: str = Field(..., description="Error detail message")
38
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
41
39
 
42
40
 
43
41
  class UnauthorizedResponse(BaseModel):
44
- detail: str
45
- error_code: Optional[str] = None
42
+ model_config = ConfigDict(
43
+ json_schema_extra={"example": {"detail": "Unauthorized access", "error_code": "UNAUTHORIZED"}}
44
+ )
46
45
 
47
- class Config:
48
- json_schema_extra = {"example": {"detail": "Unauthorized access", "error_code": "UNAUTHORIZED"}}
46
+ detail: str = Field(..., description="Error detail message")
47
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
49
48
 
50
49
 
51
50
  class UnauthenticatedResponse(BaseModel):
52
- detail: str
53
- error_code: Optional[str] = None
51
+ model_config = ConfigDict(
52
+ json_schema_extra={"example": {"detail": "Unauthenticated access", "error_code": "UNAUTHENTICATED"}}
53
+ )
54
54
 
55
- class Config:
56
- json_schema_extra = {"example": {"detail": "Unauthenticated access", "error_code": "UNAUTHENTICATED"}}
55
+ detail: str = Field(..., description="Error detail message")
56
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
57
57
 
58
58
 
59
59
  class ValidationErrorResponse(BaseModel):
60
- detail: str
61
- error_code: Optional[str] = None
60
+ model_config = ConfigDict(
61
+ json_schema_extra={"example": {"detail": "Validation error", "error_code": "VALIDATION_ERROR"}}
62
+ )
62
63
 
63
- class Config:
64
- json_schema_extra = {"example": {"detail": "Validation error", "error_code": "VALIDATION_ERROR"}}
64
+ detail: str = Field(..., description="Error detail message")
65
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
65
66
 
66
67
 
67
68
  class InternalServerErrorResponse(BaseModel):
68
- detail: str
69
- error_code: Optional[str] = None
69
+ model_config = ConfigDict(
70
+ json_schema_extra={"example": {"detail": "Internal server error", "error_code": "INTERNAL_SERVER_ERROR"}}
71
+ )
70
72
 
71
- class Config:
72
- json_schema_extra = {"example": {"detail": "Internal server error", "error_code": "INTERNAL_SERVER_ERROR"}}
73
+ detail: str = Field(..., description="Error detail message")
74
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
73
75
 
74
76
 
75
77
  class HealthResponse(BaseModel):
76
- status: str
78
+ model_config = ConfigDict(json_schema_extra={"example": {"status": "ok", "instantiated_at": "1760169236.778903"}})
77
79
 
78
- class Config:
79
- json_schema_extra = {"example": {"status": "ok"}}
80
+ status: str = Field(..., description="Health status of the service")
81
+ instantiated_at: str = Field(..., description="Unix timestamp when service was instantiated")
80
82
 
81
83
 
82
84
  class InterfaceResponse(BaseModel):
83
- type: str
84
- version: str
85
- route: str
85
+ type: str = Field(..., description="Type of the interface")
86
+ version: str = Field(..., description="Version of the interface")
87
+ route: str = Field(..., description="API route path")
86
88
 
87
89
 
88
90
  class ManagerResponse(BaseModel):
89
- type: str
90
- name: str
91
- version: str
92
- route: str
91
+ type: str = Field(..., description="Type of the manager")
92
+ name: str = Field(..., description="Name of the manager")
93
+ version: str = Field(..., description="Version of the manager")
94
+ route: str = Field(..., description="API route path")
93
95
 
94
96
 
95
97
  class AgentSummaryResponse(BaseModel):
96
- id: Optional[str] = None
97
- name: Optional[str] = None
98
- description: Optional[str] = None
99
- db_id: Optional[str] = None
98
+ id: Optional[str] = Field(None, description="Unique identifier for the agent")
99
+ name: Optional[str] = Field(None, description="Name of the agent")
100
+ description: Optional[str] = Field(None, description="Description of the agent")
101
+ db_id: Optional[str] = Field(None, description="Database identifier")
100
102
 
101
103
  @classmethod
102
104
  def from_agent(cls, agent: Agent) -> "AgentSummaryResponse":
@@ -104,10 +106,10 @@ class AgentSummaryResponse(BaseModel):
104
106
 
105
107
 
106
108
  class TeamSummaryResponse(BaseModel):
107
- id: Optional[str] = None
108
- name: Optional[str] = None
109
- description: Optional[str] = None
110
- db_id: Optional[str] = None
109
+ id: Optional[str] = Field(None, description="Unique identifier for the team")
110
+ name: Optional[str] = Field(None, description="Name of the team")
111
+ description: Optional[str] = Field(None, description="Description of the team")
112
+ db_id: Optional[str] = Field(None, description="Database identifier")
111
113
 
112
114
  @classmethod
113
115
  def from_team(cls, team: Team) -> "TeamSummaryResponse":
@@ -115,10 +117,10 @@ class TeamSummaryResponse(BaseModel):
115
117
 
116
118
 
117
119
  class WorkflowSummaryResponse(BaseModel):
118
- id: Optional[str] = None
119
- name: Optional[str] = None
120
- description: Optional[str] = None
121
- db_id: Optional[str] = None
120
+ id: Optional[str] = Field(None, description="Unique identifier for the workflow")
121
+ name: Optional[str] = Field(None, description="Name of the workflow")
122
+ description: Optional[str] = Field(None, description="Description of the workflow")
123
+ db_id: Optional[str] = Field(None, description="Database identifier")
122
124
 
123
125
  @classmethod
124
126
  def from_workflow(cls, workflow: Workflow) -> "WorkflowSummaryResponse":
@@ -133,55 +135,52 @@ class WorkflowSummaryResponse(BaseModel):
133
135
  class ConfigResponse(BaseModel):
134
136
  """Response schema for the general config endpoint"""
135
137
 
136
- os_id: str
137
- name: Optional[str] = None
138
- description: Optional[str] = None
139
- available_models: Optional[List[str]] = None
140
- databases: List[str]
141
- chat: Optional[ChatConfig] = None
138
+ os_id: str = Field(..., description="Unique identifier for the OS instance")
139
+ name: Optional[str] = Field(None, description="Name of the OS instance")
140
+ description: Optional[str] = Field(None, description="Description of the OS instance")
141
+ available_models: Optional[List[str]] = Field(None, description="List of available models")
142
+ databases: List[str] = Field(..., description="List of database IDs")
143
+ chat: Optional[ChatConfig] = Field(None, description="Chat configuration")
142
144
 
143
- session: Optional[SessionConfig] = None
144
- metrics: Optional[MetricsConfig] = None
145
- memory: Optional[MemoryConfig] = None
146
- knowledge: Optional[KnowledgeConfig] = None
147
- evals: Optional[EvalsConfig] = None
145
+ session: Optional[SessionConfig] = Field(None, description="Session configuration")
146
+ metrics: Optional[MetricsConfig] = Field(None, description="Metrics configuration")
147
+ memory: Optional[MemoryConfig] = Field(None, description="Memory configuration")
148
+ knowledge: Optional[KnowledgeConfig] = Field(None, description="Knowledge configuration")
149
+ evals: Optional[EvalsConfig] = Field(None, description="Evaluations configuration")
148
150
 
149
- agents: List[AgentSummaryResponse]
150
- teams: List[TeamSummaryResponse]
151
- workflows: List[WorkflowSummaryResponse]
152
- interfaces: List[InterfaceResponse]
151
+ agents: List[AgentSummaryResponse] = Field(..., description="List of registered agents")
152
+ teams: List[TeamSummaryResponse] = Field(..., description="List of registered teams")
153
+ workflows: List[WorkflowSummaryResponse] = Field(..., description="List of registered workflows")
154
+ interfaces: List[InterfaceResponse] = Field(..., description="List of available interfaces")
153
155
 
154
156
 
155
157
  class Model(BaseModel):
156
- id: Optional[str] = None
157
- provider: Optional[str] = None
158
+ id: Optional[str] = Field(None, description="Model identifier")
159
+ provider: Optional[str] = Field(None, description="Model provider name")
158
160
 
159
161
 
160
162
  class ModelResponse(BaseModel):
161
- name: Optional[str] = None
162
- model: Optional[str] = None
163
- provider: Optional[str] = None
163
+ name: Optional[str] = Field(None, description="Name of the model")
164
+ model: Optional[str] = Field(None, description="Model identifier")
165
+ provider: Optional[str] = Field(None, description="Model provider name")
164
166
 
165
167
 
166
168
  class AgentResponse(BaseModel):
167
- id: Optional[str] = None
168
- name: Optional[str] = None
169
- db_id: Optional[str] = None
170
- model: Optional[ModelResponse] = None
171
- tools: Optional[Dict[str, Any]] = None
172
- sessions: Optional[Dict[str, Any]] = None
173
- knowledge: Optional[Dict[str, Any]] = None
174
- memory: Optional[Dict[str, Any]] = None
175
- reasoning: Optional[Dict[str, Any]] = None
176
- default_tools: Optional[Dict[str, Any]] = None
177
- system_message: Optional[Dict[str, Any]] = None
178
- extra_messages: Optional[Dict[str, Any]] = None
179
- response_settings: Optional[Dict[str, Any]] = None
180
- streaming: Optional[Dict[str, Any]] = None
181
- metadata: Optional[Dict[str, Any]] = None
182
-
183
- class Config:
184
- exclude_none = True
169
+ id: Optional[str] = Field(None, description="Unique identifier for the agent")
170
+ name: Optional[str] = Field(None, description="Name of the agent")
171
+ db_id: Optional[str] = Field(None, description="Database identifier")
172
+ model: Optional[ModelResponse] = Field(None, description="Model configuration")
173
+ tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
174
+ sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
175
+ knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
176
+ memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
177
+ reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
178
+ default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
179
+ system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
180
+ extra_messages: Optional[Dict[str, Any]] = Field(None, description="Extra message configurations")
181
+ response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
182
+ streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
183
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
185
184
 
186
185
  @classmethod
187
186
  def from_agent(cls, agent: Agent) -> "AgentResponse":
@@ -240,6 +239,7 @@ class AgentResponse(BaseModel):
240
239
  "parse_response": True,
241
240
  "use_json_mode": False,
242
241
  # Streaming defaults
242
+ "stream_events": False,
243
243
  "stream_intermediate_steps": False,
244
244
  }
245
245
 
@@ -372,6 +372,7 @@ class AgentResponse(BaseModel):
372
372
 
373
373
  streaming_info = {
374
374
  "stream": agent.stream,
375
+ "stream_events": agent.stream_events,
375
376
  "stream_intermediate_steps": agent.stream_intermediate_steps,
376
377
  }
377
378
  return AgentResponse(
@@ -394,22 +395,24 @@ class AgentResponse(BaseModel):
394
395
 
395
396
 
396
397
  class TeamResponse(BaseModel):
397
- id: Optional[str] = None
398
- name: Optional[str] = None
399
- db_id: Optional[str] = None
400
- description: Optional[str] = None
401
- model: Optional[ModelResponse] = None
402
- tools: Optional[Dict[str, Any]] = None
403
- sessions: Optional[Dict[str, Any]] = None
404
- knowledge: Optional[Dict[str, Any]] = None
405
- memory: Optional[Dict[str, Any]] = None
406
- reasoning: Optional[Dict[str, Any]] = None
407
- default_tools: Optional[Dict[str, Any]] = None
408
- system_message: Optional[Dict[str, Any]] = None
409
- response_settings: Optional[Dict[str, Any]] = None
410
- streaming: Optional[Dict[str, Any]] = None
411
- members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = None
412
- metadata: Optional[Dict[str, Any]] = None
398
+ id: Optional[str] = Field(None, description="Unique identifier for the team")
399
+ name: Optional[str] = Field(None, description="Name of the team")
400
+ db_id: Optional[str] = Field(None, description="Database identifier")
401
+ description: Optional[str] = Field(None, description="Description of the team")
402
+ model: Optional[ModelResponse] = Field(None, description="Model configuration")
403
+ tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
404
+ sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
405
+ knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
406
+ memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
407
+ reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
408
+ default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
409
+ system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
410
+ response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
411
+ streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
412
+ members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = Field(
413
+ None, description="List of team members (agents or teams)"
414
+ )
415
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
413
416
 
414
417
  @classmethod
415
418
  def from_team(cls, team: Team) -> "TeamResponse":
@@ -458,6 +461,7 @@ class TeamResponse(BaseModel):
458
461
  "parse_response": True,
459
462
  "use_json_mode": False,
460
463
  # Streaming defaults
464
+ "stream_events": False,
461
465
  "stream_intermediate_steps": False,
462
466
  "stream_member_events": False,
463
467
  }
@@ -577,6 +581,7 @@ class TeamResponse(BaseModel):
577
581
 
578
582
  streaming_info = {
579
583
  "stream": team.stream,
584
+ "stream_events": team.stream_events,
580
585
  "stream_intermediate_steps": team.stream_intermediate_steps,
581
586
  "stream_member_events": team.stream_member_events,
582
587
  }
@@ -617,18 +622,15 @@ class TeamResponse(BaseModel):
617
622
 
618
623
 
619
624
  class WorkflowResponse(BaseModel):
620
- id: Optional[str] = None
621
- name: Optional[str] = None
622
- db_id: Optional[str] = None
623
- description: Optional[str] = None
624
- input_schema: Optional[Dict[str, Any]] = None
625
- steps: Optional[List[Dict[str, Any]]] = None
626
- agent: Optional[AgentResponse] = None
627
- team: Optional[TeamResponse] = None
628
- metadata: Optional[Dict[str, Any]] = None
629
-
630
- class Config:
631
- exclude_none = True
625
+ id: Optional[str] = Field(None, description="Unique identifier for the workflow")
626
+ name: Optional[str] = Field(None, description="Name of the workflow")
627
+ db_id: Optional[str] = Field(None, description="Database identifier")
628
+ description: Optional[str] = Field(None, description="Description of the workflow")
629
+ input_schema: Optional[Dict[str, Any]] = Field(None, description="Input schema for the workflow")
630
+ steps: Optional[List[Dict[str, Any]]] = Field(None, description="List of workflow steps")
631
+ agent: Optional[AgentResponse] = Field(None, description="Agent configuration if used")
632
+ team: Optional[TeamResponse] = Field(None, description="Team configuration if used")
633
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
632
634
 
633
635
  @classmethod
634
636
  def _resolve_agents_and_teams_recursively(cls, steps: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
@@ -682,17 +684,17 @@ class WorkflowResponse(BaseModel):
682
684
 
683
685
 
684
686
  class WorkflowRunRequest(BaseModel):
685
- input: Dict[str, Any]
686
- user_id: Optional[str] = None
687
- session_id: Optional[str] = None
687
+ input: Dict[str, Any] = Field(..., description="Input parameters for the workflow run")
688
+ user_id: Optional[str] = Field(None, description="User identifier for the workflow run")
689
+ session_id: Optional[str] = Field(None, description="Session identifier for context persistence")
688
690
 
689
691
 
690
692
  class SessionSchema(BaseModel):
691
- session_id: str
692
- session_name: str
693
- session_state: Optional[dict]
694
- created_at: Optional[datetime]
695
- updated_at: Optional[datetime]
693
+ session_id: str = Field(..., description="Unique identifier for the session")
694
+ session_name: str = Field(..., description="Human-readable name for the session")
695
+ session_state: Optional[dict] = Field(None, description="Current state data of the session")
696
+ created_at: Optional[datetime] = Field(None, description="Timestamp when session was created")
697
+ updated_at: Optional[datetime] = Field(None, description="Timestamp when session was last updated")
696
698
 
697
699
  @classmethod
698
700
  def from_dict(cls, session: Dict[str, Any]) -> "SessionSchema":
@@ -711,24 +713,43 @@ class SessionSchema(BaseModel):
711
713
 
712
714
 
713
715
  class DeleteSessionRequest(BaseModel):
714
- session_ids: List[str]
715
- session_types: List[SessionType]
716
+ session_ids: List[str] = Field(..., description="List of session IDs to delete", min_length=1)
717
+ session_types: List[SessionType] = Field(..., description="Types of sessions to delete", min_length=1)
718
+
719
+
720
+ class CreateSessionRequest(BaseModel):
721
+ session_id: Optional[str] = Field(None, description="Optional session ID (generated if not provided)")
722
+ session_name: Optional[str] = Field(None, description="Name for the session")
723
+ session_state: Optional[Dict[str, Any]] = Field(None, description="Initial session state")
724
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
725
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
726
+ agent_id: Optional[str] = Field(None, description="Agent ID if this is an agent session")
727
+ team_id: Optional[str] = Field(None, description="Team ID if this is a team session")
728
+ workflow_id: Optional[str] = Field(None, description="Workflow ID if this is a workflow session")
729
+
730
+
731
+ class UpdateSessionRequest(BaseModel):
732
+ session_name: Optional[str] = Field(None, description="Updated session name")
733
+ session_state: Optional[Dict[str, Any]] = Field(None, description="Updated session state")
734
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Updated metadata")
735
+ summary: Optional[Dict[str, Any]] = Field(None, description="Session summary")
716
736
 
717
737
 
718
738
  class AgentSessionDetailSchema(BaseModel):
719
- user_id: Optional[str]
720
- agent_session_id: str
721
- session_id: str
722
- session_name: str
723
- session_summary: Optional[dict]
724
- session_state: Optional[dict]
725
- agent_id: Optional[str]
726
- total_tokens: Optional[int]
727
- agent_data: Optional[dict]
728
- metrics: Optional[dict]
729
- chat_history: Optional[List[dict]]
730
- created_at: Optional[datetime]
731
- updated_at: Optional[datetime]
739
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
740
+ agent_session_id: str = Field(..., description="Unique agent session identifier")
741
+ session_id: str = Field(..., description="Session identifier")
742
+ session_name: str = Field(..., description="Human-readable session name")
743
+ session_summary: Optional[dict] = Field(None, description="Summary of session interactions")
744
+ session_state: Optional[dict] = Field(None, description="Current state of the session")
745
+ agent_id: Optional[str] = Field(None, description="Agent ID used in this session")
746
+ total_tokens: Optional[int] = Field(None, description="Total tokens used in this session")
747
+ agent_data: Optional[dict] = Field(None, description="Agent-specific data")
748
+ metrics: Optional[dict] = Field(None, description="Session metrics")
749
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
750
+ chat_history: Optional[List[dict]] = Field(None, description="Complete chat history")
751
+ created_at: Optional[datetime] = Field(None, description="Session creation timestamp")
752
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
732
753
 
733
754
  @classmethod
734
755
  def from_session(cls, session: AgentSession) -> "AgentSessionDetailSchema":
@@ -746,6 +767,7 @@ class AgentSessionDetailSchema(BaseModel):
746
767
  if session.session_data
747
768
  else None,
748
769
  metrics=session.session_data.get("session_metrics", {}) if session.session_data else None, # type: ignore
770
+ metadata=session.metadata,
749
771
  chat_history=[message.to_dict() for message in session.get_chat_history()],
750
772
  created_at=datetime.fromtimestamp(session.created_at, tz=timezone.utc) if session.created_at else None,
751
773
  updated_at=datetime.fromtimestamp(session.updated_at, tz=timezone.utc) if session.updated_at else None,
@@ -753,18 +775,19 @@ class AgentSessionDetailSchema(BaseModel):
753
775
 
754
776
 
755
777
  class TeamSessionDetailSchema(BaseModel):
756
- session_id: str
757
- session_name: str
758
- user_id: Optional[str]
759
- team_id: Optional[str]
760
- session_summary: Optional[dict]
761
- session_state: Optional[dict]
762
- metrics: Optional[dict]
763
- team_data: Optional[dict]
764
- chat_history: Optional[List[dict]]
765
- created_at: Optional[datetime]
766
- updated_at: Optional[datetime]
767
- total_tokens: Optional[int]
778
+ session_id: str = Field(..., description="Unique session identifier")
779
+ session_name: str = Field(..., description="Human-readable session name")
780
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
781
+ team_id: Optional[str] = Field(None, description="Team ID used in this session")
782
+ session_summary: Optional[dict] = Field(None, description="Summary of team interactions")
783
+ session_state: Optional[dict] = Field(None, description="Current state of the session")
784
+ metrics: Optional[dict] = Field(None, description="Session metrics")
785
+ team_data: Optional[dict] = Field(None, description="Team-specific data")
786
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
787
+ chat_history: Optional[List[dict]] = Field(None, description="Complete chat history")
788
+ created_at: Optional[datetime] = Field(None, description="Session creation timestamp")
789
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
790
+ total_tokens: Optional[int] = Field(None, description="Total tokens used in this session")
768
791
 
769
792
  @classmethod
770
793
  def from_session(cls, session: TeamSession) -> "TeamSessionDetailSchema":
@@ -783,6 +806,7 @@ class TeamSessionDetailSchema(BaseModel):
783
806
  if session.session_data
784
807
  else None,
785
808
  metrics=session.session_data.get("session_metrics", {}) if session.session_data else None,
809
+ metadata=session.metadata,
786
810
  chat_history=[message.to_dict() for message in session.get_chat_history()],
787
811
  created_at=datetime.fromtimestamp(session.created_at, tz=timezone.utc) if session.created_at else None,
788
812
  updated_at=datetime.fromtimestamp(session.updated_at, tz=timezone.utc) if session.updated_at else None,
@@ -790,20 +814,19 @@ class TeamSessionDetailSchema(BaseModel):
790
814
 
791
815
 
792
816
  class WorkflowSessionDetailSchema(BaseModel):
793
- user_id: Optional[str]
794
- workflow_id: Optional[str]
795
- workflow_name: Optional[str]
796
-
797
- session_id: str
798
- session_name: str
817
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
818
+ workflow_id: Optional[str] = Field(None, description="Workflow ID used in this session")
819
+ workflow_name: Optional[str] = Field(None, description="Name of the workflow")
820
+ session_id: str = Field(..., description="Unique session identifier")
821
+ session_name: str = Field(..., description="Human-readable session name")
799
822
 
800
- session_data: Optional[dict]
801
- session_state: Optional[dict]
802
- workflow_data: Optional[dict]
803
- metadata: Optional[dict]
823
+ session_data: Optional[dict] = Field(None, description="Complete session data")
824
+ session_state: Optional[dict] = Field(None, description="Current workflow state")
825
+ workflow_data: Optional[dict] = Field(None, description="Workflow-specific data")
826
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
804
827
 
805
- created_at: Optional[int]
806
- updated_at: Optional[int]
828
+ created_at: Optional[int] = Field(None, description="Unix timestamp of session creation")
829
+ updated_at: Optional[int] = Field(None, description="Unix timestamp of last update")
807
830
 
808
831
  @classmethod
809
832
  def from_session(cls, session: WorkflowSession) -> "WorkflowSessionDetailSchema":
@@ -826,28 +849,28 @@ class WorkflowSessionDetailSchema(BaseModel):
826
849
 
827
850
 
828
851
  class RunSchema(BaseModel):
829
- run_id: str
830
- parent_run_id: Optional[str]
831
- agent_id: Optional[str]
832
- user_id: Optional[str]
833
- run_input: Optional[str]
834
- content: Optional[Union[str, dict]]
835
- run_response_format: Optional[str]
836
- reasoning_content: Optional[str]
837
- reasoning_steps: Optional[List[dict]]
838
- metrics: Optional[dict]
839
- messages: Optional[List[dict]]
840
- tools: Optional[List[dict]]
841
- events: Optional[List[dict]]
842
- created_at: Optional[datetime]
843
- references: Optional[List[dict]]
844
- reasoning_messages: Optional[List[dict]]
845
- images: Optional[List[dict]]
846
- videos: Optional[List[dict]]
847
- audio: Optional[List[dict]]
848
- files: Optional[List[dict]]
849
- response_audio: Optional[dict]
850
- input_media: Optional[Dict[str, Any]]
852
+ run_id: str = Field(..., description="Unique identifier for the run")
853
+ parent_run_id: Optional[str] = Field(None, description="Parent run ID if this is a nested run")
854
+ agent_id: Optional[str] = Field(None, description="Agent ID that executed this run")
855
+ user_id: Optional[str] = Field(None, description="User ID associated with the run")
856
+ run_input: Optional[str] = Field(None, description="Input provided to the run")
857
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the run")
858
+ run_response_format: Optional[str] = Field(None, description="Format of the response (text/json)")
859
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
860
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
861
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
862
+ messages: Optional[List[dict]] = Field(None, description="Message history for the run")
863
+ tools: Optional[List[dict]] = Field(None, description="Tools used in the run")
864
+ events: Optional[List[dict]] = Field(None, description="Events generated during the run")
865
+ created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
866
+ references: Optional[List[dict]] = Field(None, description="References cited in the run")
867
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
868
+ images: Optional[List[dict]] = Field(None, description="Images included in the run")
869
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
870
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
871
+ files: Optional[List[dict]] = Field(None, description="Files included in the run")
872
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
873
+ input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
851
874
 
852
875
  @classmethod
853
876
  def from_dict(cls, run_dict: Dict[str, Any]) -> "RunSchema":
@@ -882,27 +905,27 @@ class RunSchema(BaseModel):
882
905
 
883
906
 
884
907
  class TeamRunSchema(BaseModel):
885
- run_id: str
886
- parent_run_id: Optional[str]
887
- team_id: Optional[str]
888
- content: Optional[Union[str, dict]]
889
- reasoning_content: Optional[str]
890
- reasoning_steps: Optional[List[dict]]
891
- run_input: Optional[str]
892
- run_response_format: Optional[str]
893
- metrics: Optional[dict]
894
- tools: Optional[List[dict]]
895
- messages: Optional[List[dict]]
896
- events: Optional[List[dict]]
897
- created_at: Optional[datetime]
898
- references: Optional[List[dict]]
899
- reasoning_messages: Optional[List[dict]]
900
- input_media: Optional[Dict[str, Any]]
901
- images: Optional[List[dict]]
902
- videos: Optional[List[dict]]
903
- audio: Optional[List[dict]]
904
- files: Optional[List[dict]]
905
- response_audio: Optional[dict]
908
+ run_id: str = Field(..., description="Unique identifier for the team run")
909
+ parent_run_id: Optional[str] = Field(None, description="Parent run ID if this is a nested run")
910
+ team_id: Optional[str] = Field(None, description="Team ID that executed this run")
911
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the team run")
912
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
913
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
914
+ run_input: Optional[str] = Field(None, description="Input provided to the run")
915
+ run_response_format: Optional[str] = Field(None, description="Format of the response (text/json)")
916
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
917
+ tools: Optional[List[dict]] = Field(None, description="Tools used in the run")
918
+ messages: Optional[List[dict]] = Field(None, description="Message history for the run")
919
+ events: Optional[List[dict]] = Field(None, description="Events generated during the run")
920
+ created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
921
+ references: Optional[List[dict]] = Field(None, description="References cited in the run")
922
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
923
+ input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
924
+ images: Optional[List[dict]] = Field(None, description="Images included in the run")
925
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
926
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
927
+ files: Optional[List[dict]] = Field(None, description="Files included in the run")
928
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
906
929
 
907
930
  @classmethod
908
931
  def from_dict(cls, run_dict: Dict[str, Any]) -> "TeamRunSchema":
@@ -936,27 +959,27 @@ class TeamRunSchema(BaseModel):
936
959
 
937
960
 
938
961
  class WorkflowRunSchema(BaseModel):
939
- run_id: str
940
- run_input: Optional[str]
941
- events: Optional[List[dict]]
942
- workflow_id: Optional[str]
943
- user_id: Optional[str]
944
- content: Optional[Union[str, dict]]
945
- content_type: Optional[str]
946
- status: Optional[str]
947
- step_results: Optional[list[dict]]
948
- step_executor_runs: Optional[list[dict]]
949
- metrics: Optional[dict]
950
- created_at: Optional[int]
951
- reasoning_content: Optional[str]
952
- reasoning_steps: Optional[List[dict]]
953
- references: Optional[List[dict]]
954
- reasoning_messages: Optional[List[dict]]
955
- images: Optional[List[dict]]
956
- videos: Optional[List[dict]]
957
- audio: Optional[List[dict]]
958
- files: Optional[List[dict]]
959
- response_audio: Optional[dict]
962
+ run_id: str = Field(..., description="Unique identifier for the workflow run")
963
+ run_input: Optional[str] = Field(None, description="Input provided to the workflow")
964
+ events: Optional[List[dict]] = Field(None, description="Events generated during the workflow")
965
+ workflow_id: Optional[str] = Field(None, description="Workflow ID that was executed")
966
+ user_id: Optional[str] = Field(None, description="User ID associated with the run")
967
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the workflow")
968
+ content_type: Optional[str] = Field(None, description="Type of content returned")
969
+ status: Optional[str] = Field(None, description="Status of the workflow run")
970
+ step_results: Optional[list[dict]] = Field(None, description="Results from each workflow step")
971
+ step_executor_runs: Optional[list[dict]] = Field(None, description="Executor runs for each step")
972
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
973
+ created_at: Optional[int] = Field(None, description="Unix timestamp of run creation")
974
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
975
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
976
+ references: Optional[List[dict]] = Field(None, description="References cited in the workflow")
977
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
978
+ images: Optional[List[dict]] = Field(None, description="Images included in the workflow")
979
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the workflow")
980
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the workflow")
981
+ files: Optional[List[dict]] = Field(None, description="Files included in the workflow")
982
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
960
983
 
961
984
  @classmethod
962
985
  def from_dict(cls, run_response: Dict[str, Any]) -> "WorkflowRunSchema":
@@ -995,15 +1018,15 @@ class SortOrder(str, Enum):
995
1018
 
996
1019
 
997
1020
  class PaginationInfo(BaseModel):
998
- page: Optional[int] = 0
999
- limit: Optional[int] = 20
1000
- total_pages: Optional[int] = 0
1001
- total_count: Optional[int] = 0
1002
- search_time_ms: Optional[float] = 0
1021
+ page: int = Field(0, description="Current page number (0-indexed)", ge=0)
1022
+ limit: int = Field(20, description="Number of items per page", ge=1, le=100)
1023
+ total_pages: int = Field(0, description="Total number of pages", ge=0)
1024
+ total_count: int = Field(0, description="Total count of items", ge=0)
1025
+ search_time_ms: float = Field(0, description="Search execution time in milliseconds", ge=0)
1003
1026
 
1004
1027
 
1005
1028
  class PaginatedResponse(BaseModel, Generic[T]):
1006
1029
  """Wrapper to add pagination info to classes used as response models"""
1007
1030
 
1008
- data: List[T]
1009
- meta: PaginationInfo
1031
+ data: List[T] = Field(..., description="List of items for the current page")
1032
+ meta: PaginationInfo = Field(..., description="Pagination metadata")