agno 2.0.1__py3-none-any.whl → 2.3.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 (314) hide show
  1. agno/agent/agent.py +6015 -2823
  2. agno/api/api.py +2 -0
  3. agno/api/os.py +1 -1
  4. agno/culture/__init__.py +3 -0
  5. agno/culture/manager.py +956 -0
  6. agno/db/async_postgres/__init__.py +3 -0
  7. agno/db/base.py +385 -6
  8. agno/db/dynamo/dynamo.py +388 -81
  9. agno/db/dynamo/schemas.py +47 -10
  10. agno/db/dynamo/utils.py +63 -4
  11. agno/db/firestore/firestore.py +435 -64
  12. agno/db/firestore/schemas.py +11 -0
  13. agno/db/firestore/utils.py +102 -4
  14. agno/db/gcs_json/gcs_json_db.py +384 -42
  15. agno/db/gcs_json/utils.py +60 -26
  16. agno/db/in_memory/in_memory_db.py +351 -66
  17. agno/db/in_memory/utils.py +60 -2
  18. agno/db/json/json_db.py +339 -48
  19. agno/db/json/utils.py +60 -26
  20. agno/db/migrations/manager.py +199 -0
  21. agno/db/migrations/v1_to_v2.py +510 -37
  22. agno/db/migrations/versions/__init__.py +0 -0
  23. agno/db/migrations/versions/v2_3_0.py +938 -0
  24. agno/db/mongo/__init__.py +15 -1
  25. agno/db/mongo/async_mongo.py +2036 -0
  26. agno/db/mongo/mongo.py +653 -76
  27. agno/db/mongo/schemas.py +13 -0
  28. agno/db/mongo/utils.py +80 -8
  29. agno/db/mysql/mysql.py +687 -25
  30. agno/db/mysql/schemas.py +61 -37
  31. agno/db/mysql/utils.py +60 -2
  32. agno/db/postgres/__init__.py +2 -1
  33. agno/db/postgres/async_postgres.py +2001 -0
  34. agno/db/postgres/postgres.py +676 -57
  35. agno/db/postgres/schemas.py +43 -18
  36. agno/db/postgres/utils.py +164 -2
  37. agno/db/redis/redis.py +344 -38
  38. agno/db/redis/schemas.py +18 -0
  39. agno/db/redis/utils.py +60 -2
  40. agno/db/schemas/__init__.py +2 -1
  41. agno/db/schemas/culture.py +120 -0
  42. agno/db/schemas/memory.py +13 -0
  43. agno/db/singlestore/schemas.py +26 -1
  44. agno/db/singlestore/singlestore.py +687 -53
  45. agno/db/singlestore/utils.py +60 -2
  46. agno/db/sqlite/__init__.py +2 -1
  47. agno/db/sqlite/async_sqlite.py +2371 -0
  48. agno/db/sqlite/schemas.py +24 -0
  49. agno/db/sqlite/sqlite.py +774 -85
  50. agno/db/sqlite/utils.py +168 -5
  51. agno/db/surrealdb/__init__.py +3 -0
  52. agno/db/surrealdb/metrics.py +292 -0
  53. agno/db/surrealdb/models.py +309 -0
  54. agno/db/surrealdb/queries.py +71 -0
  55. agno/db/surrealdb/surrealdb.py +1361 -0
  56. agno/db/surrealdb/utils.py +147 -0
  57. agno/db/utils.py +50 -22
  58. agno/eval/accuracy.py +50 -43
  59. agno/eval/performance.py +6 -3
  60. agno/eval/reliability.py +6 -3
  61. agno/eval/utils.py +33 -16
  62. agno/exceptions.py +68 -1
  63. agno/filters.py +354 -0
  64. agno/guardrails/__init__.py +6 -0
  65. agno/guardrails/base.py +19 -0
  66. agno/guardrails/openai.py +144 -0
  67. agno/guardrails/pii.py +94 -0
  68. agno/guardrails/prompt_injection.py +52 -0
  69. agno/integrations/discord/client.py +1 -0
  70. agno/knowledge/chunking/agentic.py +13 -10
  71. agno/knowledge/chunking/fixed.py +1 -1
  72. agno/knowledge/chunking/semantic.py +40 -8
  73. agno/knowledge/chunking/strategy.py +59 -15
  74. agno/knowledge/embedder/aws_bedrock.py +9 -4
  75. agno/knowledge/embedder/azure_openai.py +54 -0
  76. agno/knowledge/embedder/base.py +2 -0
  77. agno/knowledge/embedder/cohere.py +184 -5
  78. agno/knowledge/embedder/fastembed.py +1 -1
  79. agno/knowledge/embedder/google.py +79 -1
  80. agno/knowledge/embedder/huggingface.py +9 -4
  81. agno/knowledge/embedder/jina.py +63 -0
  82. agno/knowledge/embedder/mistral.py +78 -11
  83. agno/knowledge/embedder/nebius.py +1 -1
  84. agno/knowledge/embedder/ollama.py +13 -0
  85. agno/knowledge/embedder/openai.py +37 -65
  86. agno/knowledge/embedder/sentence_transformer.py +8 -4
  87. agno/knowledge/embedder/vllm.py +262 -0
  88. agno/knowledge/embedder/voyageai.py +69 -16
  89. agno/knowledge/knowledge.py +594 -186
  90. agno/knowledge/reader/base.py +9 -2
  91. agno/knowledge/reader/csv_reader.py +8 -10
  92. agno/knowledge/reader/docx_reader.py +5 -6
  93. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  94. agno/knowledge/reader/json_reader.py +6 -5
  95. agno/knowledge/reader/markdown_reader.py +13 -13
  96. agno/knowledge/reader/pdf_reader.py +43 -68
  97. agno/knowledge/reader/pptx_reader.py +101 -0
  98. agno/knowledge/reader/reader_factory.py +51 -6
  99. agno/knowledge/reader/s3_reader.py +3 -15
  100. agno/knowledge/reader/tavily_reader.py +194 -0
  101. agno/knowledge/reader/text_reader.py +13 -13
  102. agno/knowledge/reader/web_search_reader.py +2 -43
  103. agno/knowledge/reader/website_reader.py +43 -25
  104. agno/knowledge/reranker/__init__.py +2 -8
  105. agno/knowledge/types.py +9 -0
  106. agno/knowledge/utils.py +20 -0
  107. agno/media.py +72 -0
  108. agno/memory/manager.py +336 -82
  109. agno/models/aimlapi/aimlapi.py +2 -2
  110. agno/models/anthropic/claude.py +183 -37
  111. agno/models/aws/bedrock.py +52 -112
  112. agno/models/aws/claude.py +33 -1
  113. agno/models/azure/ai_foundry.py +33 -15
  114. agno/models/azure/openai_chat.py +25 -8
  115. agno/models/base.py +999 -519
  116. agno/models/cerebras/cerebras.py +19 -13
  117. agno/models/cerebras/cerebras_openai.py +8 -5
  118. agno/models/cohere/chat.py +27 -1
  119. agno/models/cometapi/__init__.py +5 -0
  120. agno/models/cometapi/cometapi.py +57 -0
  121. agno/models/dashscope/dashscope.py +1 -0
  122. agno/models/deepinfra/deepinfra.py +2 -2
  123. agno/models/deepseek/deepseek.py +2 -2
  124. agno/models/fireworks/fireworks.py +2 -2
  125. agno/models/google/gemini.py +103 -31
  126. agno/models/groq/groq.py +28 -11
  127. agno/models/huggingface/huggingface.py +2 -1
  128. agno/models/internlm/internlm.py +2 -2
  129. agno/models/langdb/langdb.py +4 -4
  130. agno/models/litellm/chat.py +18 -1
  131. agno/models/litellm/litellm_openai.py +2 -2
  132. agno/models/llama_cpp/__init__.py +5 -0
  133. agno/models/llama_cpp/llama_cpp.py +22 -0
  134. agno/models/message.py +139 -0
  135. agno/models/meta/llama.py +27 -10
  136. agno/models/meta/llama_openai.py +5 -17
  137. agno/models/nebius/nebius.py +6 -6
  138. agno/models/nexus/__init__.py +3 -0
  139. agno/models/nexus/nexus.py +22 -0
  140. agno/models/nvidia/nvidia.py +2 -2
  141. agno/models/ollama/chat.py +59 -5
  142. agno/models/openai/chat.py +69 -29
  143. agno/models/openai/responses.py +103 -106
  144. agno/models/openrouter/openrouter.py +41 -3
  145. agno/models/perplexity/perplexity.py +4 -5
  146. agno/models/portkey/portkey.py +3 -3
  147. agno/models/requesty/__init__.py +5 -0
  148. agno/models/requesty/requesty.py +52 -0
  149. agno/models/response.py +77 -1
  150. agno/models/sambanova/sambanova.py +2 -2
  151. agno/models/siliconflow/__init__.py +5 -0
  152. agno/models/siliconflow/siliconflow.py +25 -0
  153. agno/models/together/together.py +2 -2
  154. agno/models/utils.py +254 -8
  155. agno/models/vercel/v0.py +2 -2
  156. agno/models/vertexai/__init__.py +0 -0
  157. agno/models/vertexai/claude.py +96 -0
  158. agno/models/vllm/vllm.py +1 -0
  159. agno/models/xai/xai.py +3 -2
  160. agno/os/app.py +543 -178
  161. agno/os/auth.py +24 -14
  162. agno/os/config.py +1 -0
  163. agno/os/interfaces/__init__.py +1 -0
  164. agno/os/interfaces/a2a/__init__.py +3 -0
  165. agno/os/interfaces/a2a/a2a.py +42 -0
  166. agno/os/interfaces/a2a/router.py +250 -0
  167. agno/os/interfaces/a2a/utils.py +924 -0
  168. agno/os/interfaces/agui/agui.py +23 -7
  169. agno/os/interfaces/agui/router.py +27 -3
  170. agno/os/interfaces/agui/utils.py +242 -142
  171. agno/os/interfaces/base.py +6 -2
  172. agno/os/interfaces/slack/router.py +81 -23
  173. agno/os/interfaces/slack/slack.py +29 -14
  174. agno/os/interfaces/whatsapp/router.py +11 -4
  175. agno/os/interfaces/whatsapp/whatsapp.py +14 -7
  176. agno/os/mcp.py +111 -54
  177. agno/os/middleware/__init__.py +7 -0
  178. agno/os/middleware/jwt.py +233 -0
  179. agno/os/router.py +556 -139
  180. agno/os/routers/evals/evals.py +71 -34
  181. agno/os/routers/evals/schemas.py +31 -31
  182. agno/os/routers/evals/utils.py +6 -5
  183. agno/os/routers/health.py +31 -0
  184. agno/os/routers/home.py +52 -0
  185. agno/os/routers/knowledge/knowledge.py +185 -38
  186. agno/os/routers/knowledge/schemas.py +82 -22
  187. agno/os/routers/memory/memory.py +158 -53
  188. agno/os/routers/memory/schemas.py +20 -16
  189. agno/os/routers/metrics/metrics.py +20 -8
  190. agno/os/routers/metrics/schemas.py +16 -16
  191. agno/os/routers/session/session.py +499 -38
  192. agno/os/schema.py +308 -198
  193. agno/os/utils.py +401 -41
  194. agno/reasoning/anthropic.py +80 -0
  195. agno/reasoning/azure_ai_foundry.py +2 -2
  196. agno/reasoning/deepseek.py +2 -2
  197. agno/reasoning/default.py +3 -1
  198. agno/reasoning/gemini.py +73 -0
  199. agno/reasoning/groq.py +2 -2
  200. agno/reasoning/ollama.py +2 -2
  201. agno/reasoning/openai.py +7 -2
  202. agno/reasoning/vertexai.py +76 -0
  203. agno/run/__init__.py +6 -0
  204. agno/run/agent.py +248 -94
  205. agno/run/base.py +44 -5
  206. agno/run/team.py +238 -97
  207. agno/run/workflow.py +144 -33
  208. agno/session/agent.py +105 -89
  209. agno/session/summary.py +65 -25
  210. agno/session/team.py +176 -96
  211. agno/session/workflow.py +406 -40
  212. agno/team/team.py +3854 -1610
  213. agno/tools/dalle.py +2 -4
  214. agno/tools/decorator.py +4 -2
  215. agno/tools/duckduckgo.py +15 -11
  216. agno/tools/e2b.py +14 -7
  217. agno/tools/eleven_labs.py +23 -25
  218. agno/tools/exa.py +21 -16
  219. agno/tools/file.py +153 -23
  220. agno/tools/file_generation.py +350 -0
  221. agno/tools/firecrawl.py +4 -4
  222. agno/tools/function.py +250 -30
  223. agno/tools/gmail.py +238 -14
  224. agno/tools/google_drive.py +270 -0
  225. agno/tools/googlecalendar.py +36 -8
  226. agno/tools/googlesheets.py +20 -5
  227. agno/tools/jira.py +20 -0
  228. agno/tools/knowledge.py +3 -3
  229. agno/tools/mcp/__init__.py +10 -0
  230. agno/tools/mcp/mcp.py +331 -0
  231. agno/tools/mcp/multi_mcp.py +347 -0
  232. agno/tools/mcp/params.py +24 -0
  233. agno/tools/mcp_toolbox.py +284 -0
  234. agno/tools/mem0.py +11 -17
  235. agno/tools/memori.py +1 -53
  236. agno/tools/memory.py +419 -0
  237. agno/tools/models/nebius.py +5 -5
  238. agno/tools/models_labs.py +20 -10
  239. agno/tools/notion.py +204 -0
  240. agno/tools/parallel.py +314 -0
  241. agno/tools/scrapegraph.py +58 -31
  242. agno/tools/searxng.py +2 -2
  243. agno/tools/serper.py +2 -2
  244. agno/tools/slack.py +18 -3
  245. agno/tools/spider.py +2 -2
  246. agno/tools/tavily.py +146 -0
  247. agno/tools/whatsapp.py +1 -1
  248. agno/tools/workflow.py +278 -0
  249. agno/tools/yfinance.py +12 -11
  250. agno/utils/agent.py +820 -0
  251. agno/utils/audio.py +27 -0
  252. agno/utils/common.py +90 -1
  253. agno/utils/events.py +217 -2
  254. agno/utils/gemini.py +180 -22
  255. agno/utils/hooks.py +57 -0
  256. agno/utils/http.py +111 -0
  257. agno/utils/knowledge.py +12 -5
  258. agno/utils/log.py +1 -0
  259. agno/utils/mcp.py +92 -2
  260. agno/utils/media.py +188 -10
  261. agno/utils/merge_dict.py +22 -1
  262. agno/utils/message.py +60 -0
  263. agno/utils/models/claude.py +40 -11
  264. agno/utils/print_response/agent.py +105 -21
  265. agno/utils/print_response/team.py +103 -38
  266. agno/utils/print_response/workflow.py +251 -34
  267. agno/utils/reasoning.py +22 -1
  268. agno/utils/serialize.py +32 -0
  269. agno/utils/streamlit.py +16 -10
  270. agno/utils/string.py +41 -0
  271. agno/utils/team.py +98 -9
  272. agno/utils/tools.py +1 -1
  273. agno/vectordb/base.py +23 -4
  274. agno/vectordb/cassandra/cassandra.py +65 -9
  275. agno/vectordb/chroma/chromadb.py +182 -38
  276. agno/vectordb/clickhouse/clickhousedb.py +64 -11
  277. agno/vectordb/couchbase/couchbase.py +105 -10
  278. agno/vectordb/lancedb/lance_db.py +124 -133
  279. agno/vectordb/langchaindb/langchaindb.py +25 -7
  280. agno/vectordb/lightrag/lightrag.py +17 -3
  281. agno/vectordb/llamaindex/__init__.py +3 -0
  282. agno/vectordb/llamaindex/llamaindexdb.py +46 -7
  283. agno/vectordb/milvus/milvus.py +126 -9
  284. agno/vectordb/mongodb/__init__.py +7 -1
  285. agno/vectordb/mongodb/mongodb.py +112 -7
  286. agno/vectordb/pgvector/pgvector.py +142 -21
  287. agno/vectordb/pineconedb/pineconedb.py +80 -8
  288. agno/vectordb/qdrant/qdrant.py +125 -39
  289. agno/vectordb/redis/__init__.py +9 -0
  290. agno/vectordb/redis/redisdb.py +694 -0
  291. agno/vectordb/singlestore/singlestore.py +111 -25
  292. agno/vectordb/surrealdb/surrealdb.py +31 -5
  293. agno/vectordb/upstashdb/upstashdb.py +76 -8
  294. agno/vectordb/weaviate/weaviate.py +86 -15
  295. agno/workflow/__init__.py +2 -0
  296. agno/workflow/agent.py +299 -0
  297. agno/workflow/condition.py +112 -18
  298. agno/workflow/loop.py +69 -10
  299. agno/workflow/parallel.py +266 -118
  300. agno/workflow/router.py +110 -17
  301. agno/workflow/step.py +638 -129
  302. agno/workflow/steps.py +65 -6
  303. agno/workflow/types.py +61 -23
  304. agno/workflow/workflow.py +2085 -272
  305. {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/METADATA +182 -58
  306. agno-2.3.0.dist-info/RECORD +577 -0
  307. agno/knowledge/reader/url_reader.py +0 -128
  308. agno/tools/googlesearch.py +0 -98
  309. agno/tools/mcp.py +0 -610
  310. agno/utils/models/aws_claude.py +0 -170
  311. agno-2.0.1.dist-info/RECORD +0 -515
  312. {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/WHEEL +0 -0
  313. {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/licenses/LICENSE +0 -0
  314. {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/top_level.txt +0 -0
agno/os/schema.py CHANGED
@@ -3,99 +3,106 @@ 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
10
10
  from agno.models.message import Message
11
11
  from agno.os.config import ChatConfig, EvalsConfig, KnowledgeConfig, MemoryConfig, MetricsConfig, SessionConfig
12
12
  from agno.os.utils import (
13
+ extract_input_media,
13
14
  format_team_tools,
14
15
  format_tools,
16
+ get_agent_input_schema_dict,
15
17
  get_run_input,
16
18
  get_session_name,
19
+ get_team_input_schema_dict,
17
20
  get_workflow_input_schema_dict,
18
21
  )
22
+ from agno.run import RunContext
19
23
  from agno.run.agent import RunOutput
20
24
  from agno.run.team import TeamRunOutput
21
25
  from agno.session import AgentSession, TeamSession, WorkflowSession
22
26
  from agno.team.team import Team
27
+ from agno.workflow.agent import WorkflowAgent
23
28
  from agno.workflow.workflow import Workflow
24
29
 
25
30
 
26
31
  class BadRequestResponse(BaseModel):
27
- detail: str
28
- error_code: Optional[str] = None
32
+ model_config = ConfigDict(json_schema_extra={"example": {"detail": "Bad request", "error_code": "BAD_REQUEST"}})
29
33
 
30
- class Config:
31
- json_schema_extra = {"example": {"detail": "Bad request", "error_code": "BAD_REQUEST"}}
34
+ detail: str = Field(..., description="Error detail message")
35
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
32
36
 
33
37
 
34
38
  class NotFoundResponse(BaseModel):
35
- detail: str
36
- error_code: Optional[str] = None
39
+ model_config = ConfigDict(json_schema_extra={"example": {"detail": "Not found", "error_code": "NOT_FOUND"}})
37
40
 
38
- class Config:
39
- json_schema_extra = {"example": {"detail": "Not found", "error_code": "NOT_FOUND"}}
41
+ detail: str = Field(..., description="Error detail message")
42
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
40
43
 
41
44
 
42
45
  class UnauthorizedResponse(BaseModel):
43
- detail: str
44
- error_code: Optional[str] = None
46
+ model_config = ConfigDict(
47
+ json_schema_extra={"example": {"detail": "Unauthorized access", "error_code": "UNAUTHORIZED"}}
48
+ )
45
49
 
46
- class Config:
47
- json_schema_extra = {"example": {"detail": "Unauthorized access", "error_code": "UNAUTHORIZED"}}
50
+ detail: str = Field(..., description="Error detail message")
51
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
48
52
 
49
53
 
50
54
  class UnauthenticatedResponse(BaseModel):
51
- detail: str
52
- error_code: Optional[str] = None
55
+ model_config = ConfigDict(
56
+ json_schema_extra={"example": {"detail": "Unauthenticated access", "error_code": "UNAUTHENTICATED"}}
57
+ )
53
58
 
54
- class Config:
55
- json_schema_extra = {"example": {"detail": "Unauthenticated access", "error_code": "UNAUTHENTICATED"}}
59
+ detail: str = Field(..., description="Error detail message")
60
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
56
61
 
57
62
 
58
63
  class ValidationErrorResponse(BaseModel):
59
- detail: str
60
- error_code: Optional[str] = None
64
+ model_config = ConfigDict(
65
+ json_schema_extra={"example": {"detail": "Validation error", "error_code": "VALIDATION_ERROR"}}
66
+ )
61
67
 
62
- class Config:
63
- json_schema_extra = {"example": {"detail": "Validation error", "error_code": "VALIDATION_ERROR"}}
68
+ detail: str = Field(..., description="Error detail message")
69
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
64
70
 
65
71
 
66
72
  class InternalServerErrorResponse(BaseModel):
67
- detail: str
68
- error_code: Optional[str] = None
73
+ model_config = ConfigDict(
74
+ json_schema_extra={"example": {"detail": "Internal server error", "error_code": "INTERNAL_SERVER_ERROR"}}
75
+ )
69
76
 
70
- class Config:
71
- json_schema_extra = {"example": {"detail": "Internal server error", "error_code": "INTERNAL_SERVER_ERROR"}}
77
+ detail: str = Field(..., description="Error detail message")
78
+ error_code: Optional[str] = Field(None, description="Error code for categorization")
72
79
 
73
80
 
74
81
  class HealthResponse(BaseModel):
75
- status: str
82
+ model_config = ConfigDict(json_schema_extra={"example": {"status": "ok", "instantiated_at": "1760169236.778903"}})
76
83
 
77
- class Config:
78
- json_schema_extra = {"example": {"status": "ok"}}
84
+ status: str = Field(..., description="Health status of the service")
85
+ instantiated_at: str = Field(..., description="Unix timestamp when service was instantiated")
79
86
 
80
87
 
81
88
  class InterfaceResponse(BaseModel):
82
- type: str
83
- version: str
84
- route: str
89
+ type: str = Field(..., description="Type of the interface")
90
+ version: str = Field(..., description="Version of the interface")
91
+ route: str = Field(..., description="API route path")
85
92
 
86
93
 
87
94
  class ManagerResponse(BaseModel):
88
- type: str
89
- name: str
90
- version: str
91
- route: str
95
+ type: str = Field(..., description="Type of the manager")
96
+ name: str = Field(..., description="Name of the manager")
97
+ version: str = Field(..., description="Version of the manager")
98
+ route: str = Field(..., description="API route path")
92
99
 
93
100
 
94
101
  class AgentSummaryResponse(BaseModel):
95
- id: Optional[str] = None
96
- name: Optional[str] = None
97
- description: Optional[str] = None
98
- db_id: Optional[str] = None
102
+ id: Optional[str] = Field(None, description="Unique identifier for the agent")
103
+ name: Optional[str] = Field(None, description="Name of the agent")
104
+ description: Optional[str] = Field(None, description="Description of the agent")
105
+ db_id: Optional[str] = Field(None, description="Database identifier")
99
106
 
100
107
  @classmethod
101
108
  def from_agent(cls, agent: Agent) -> "AgentSummaryResponse":
@@ -103,10 +110,10 @@ class AgentSummaryResponse(BaseModel):
103
110
 
104
111
 
105
112
  class TeamSummaryResponse(BaseModel):
106
- id: Optional[str] = None
107
- name: Optional[str] = None
108
- description: Optional[str] = None
109
- db_id: Optional[str] = None
113
+ id: Optional[str] = Field(None, description="Unique identifier for the team")
114
+ name: Optional[str] = Field(None, description="Name of the team")
115
+ description: Optional[str] = Field(None, description="Description of the team")
116
+ db_id: Optional[str] = Field(None, description="Database identifier")
110
117
 
111
118
  @classmethod
112
119
  def from_team(cls, team: Team) -> "TeamSummaryResponse":
@@ -114,10 +121,10 @@ class TeamSummaryResponse(BaseModel):
114
121
 
115
122
 
116
123
  class WorkflowSummaryResponse(BaseModel):
117
- id: Optional[str] = None
118
- name: Optional[str] = None
119
- description: Optional[str] = None
120
- db_id: Optional[str] = None
124
+ id: Optional[str] = Field(None, description="Unique identifier for the workflow")
125
+ name: Optional[str] = Field(None, description="Name of the workflow")
126
+ description: Optional[str] = Field(None, description="Description of the workflow")
127
+ db_id: Optional[str] = Field(None, description="Database identifier")
121
128
 
122
129
  @classmethod
123
130
  def from_workflow(cls, workflow: Workflow) -> "WorkflowSummaryResponse":
@@ -132,34 +139,34 @@ class WorkflowSummaryResponse(BaseModel):
132
139
  class ConfigResponse(BaseModel):
133
140
  """Response schema for the general config endpoint"""
134
141
 
135
- os_id: str
136
- name: Optional[str] = None
137
- description: Optional[str] = None
138
- available_models: Optional[List[str]] = None
139
- databases: List[str]
140
- chat: Optional[ChatConfig] = None
142
+ os_id: str = Field(..., description="Unique identifier for the OS instance")
143
+ name: Optional[str] = Field(None, description="Name of the OS instance")
144
+ description: Optional[str] = Field(None, description="Description of the OS instance")
145
+ available_models: Optional[List[str]] = Field(None, description="List of available models")
146
+ databases: List[str] = Field(..., description="List of database IDs")
147
+ chat: Optional[ChatConfig] = Field(None, description="Chat configuration")
141
148
 
142
- session: Optional[SessionConfig] = None
143
- metrics: Optional[MetricsConfig] = None
144
- memory: Optional[MemoryConfig] = None
145
- knowledge: Optional[KnowledgeConfig] = None
146
- evals: Optional[EvalsConfig] = None
149
+ session: Optional[SessionConfig] = Field(None, description="Session configuration")
150
+ metrics: Optional[MetricsConfig] = Field(None, description="Metrics configuration")
151
+ memory: Optional[MemoryConfig] = Field(None, description="Memory configuration")
152
+ knowledge: Optional[KnowledgeConfig] = Field(None, description="Knowledge configuration")
153
+ evals: Optional[EvalsConfig] = Field(None, description="Evaluations configuration")
147
154
 
148
- agents: List[AgentSummaryResponse]
149
- teams: List[TeamSummaryResponse]
150
- workflows: List[WorkflowSummaryResponse]
151
- interfaces: List[InterfaceResponse]
155
+ agents: List[AgentSummaryResponse] = Field(..., description="List of registered agents")
156
+ teams: List[TeamSummaryResponse] = Field(..., description="List of registered teams")
157
+ workflows: List[WorkflowSummaryResponse] = Field(..., description="List of registered workflows")
158
+ interfaces: List[InterfaceResponse] = Field(..., description="List of available interfaces")
152
159
 
153
160
 
154
161
  class Model(BaseModel):
155
- id: Optional[str] = None
156
- provider: Optional[str] = None
162
+ id: Optional[str] = Field(None, description="Model identifier")
163
+ provider: Optional[str] = Field(None, description="Model provider name")
157
164
 
158
165
 
159
166
  class ModelResponse(BaseModel):
160
- name: Optional[str] = None
161
- model: Optional[str] = None
162
- provider: Optional[str] = None
167
+ name: Optional[str] = Field(None, description="Name of the model")
168
+ model: Optional[str] = Field(None, description="Model identifier")
169
+ provider: Optional[str] = Field(None, description="Model provider name")
163
170
 
164
171
 
165
172
  class AgentResponse(BaseModel):
@@ -178,12 +185,10 @@ class AgentResponse(BaseModel):
178
185
  response_settings: Optional[Dict[str, Any]] = None
179
186
  streaming: Optional[Dict[str, Any]] = None
180
187
  metadata: Optional[Dict[str, Any]] = None
181
-
182
- class Config:
183
- exclude_none = True
188
+ input_schema: Optional[Dict[str, Any]] = None
184
189
 
185
190
  @classmethod
186
- def from_agent(cls, agent: Agent) -> "AgentResponse":
191
+ async def from_agent(cls, agent: Agent) -> "AgentResponse":
187
192
  def filter_meaningful_config(d: Dict[str, Any], defaults: Dict[str, Any]) -> Optional[Dict[str, Any]]:
188
193
  """Filter out fields that match their default values, keeping only meaningful user configurations"""
189
194
  filtered = {}
@@ -239,13 +244,17 @@ class AgentResponse(BaseModel):
239
244
  "parse_response": True,
240
245
  "use_json_mode": False,
241
246
  # Streaming defaults
247
+ "stream_events": False,
242
248
  "stream_intermediate_steps": False,
243
249
  }
244
250
 
245
- agent_tools = agent.get_tools(
246
- session=AgentSession(session_id=str(uuid4()), session_data={}),
247
- run_response=RunOutput(run_id=str(uuid4())),
248
- async_mode=True,
251
+ session_id = str(uuid4())
252
+ run_id = str(uuid4())
253
+ agent_tools = await agent.aget_tools(
254
+ session=AgentSession(session_id=session_id, session_data={}),
255
+ run_response=RunOutput(run_id=run_id, session_id=session_id),
256
+ run_context=RunContext(run_id=run_id, session_id=session_id, user_id=agent.user_id),
257
+ check_mcp_tools=False,
249
258
  )
250
259
  formatted_tools = format_tools(agent_tools) if agent_tools else None
251
260
 
@@ -371,8 +380,10 @@ class AgentResponse(BaseModel):
371
380
 
372
381
  streaming_info = {
373
382
  "stream": agent.stream,
383
+ "stream_events": agent.stream_events,
374
384
  "stream_intermediate_steps": agent.stream_intermediate_steps,
375
385
  }
386
+
376
387
  return AgentResponse(
377
388
  id=agent.id,
378
389
  name=agent.name,
@@ -389,6 +400,7 @@ class AgentResponse(BaseModel):
389
400
  response_settings=filter_meaningful_config(response_settings_info, agent_defaults),
390
401
  streaming=filter_meaningful_config(streaming_info, agent_defaults),
391
402
  metadata=agent.metadata,
403
+ input_schema=get_agent_input_schema_dict(agent),
392
404
  )
393
405
 
394
406
 
@@ -409,9 +421,10 @@ class TeamResponse(BaseModel):
409
421
  streaming: Optional[Dict[str, Any]] = None
410
422
  members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = None
411
423
  metadata: Optional[Dict[str, Any]] = None
424
+ input_schema: Optional[Dict[str, Any]] = None
412
425
 
413
426
  @classmethod
414
- def from_team(cls, team: Team) -> "TeamResponse":
427
+ async def from_team(cls, team: Team) -> "TeamResponse":
415
428
  def filter_meaningful_config(d: Dict[str, Any], defaults: Dict[str, Any]) -> Optional[Dict[str, Any]]:
416
429
  """Filter out fields that match their default values, keeping only meaningful user configurations"""
417
430
  filtered = {}
@@ -445,7 +458,7 @@ class TeamResponse(BaseModel):
445
458
  "reasoning_max_steps": 10,
446
459
  # Default tools defaults
447
460
  "search_knowledge": True,
448
- "read_team_history": False,
461
+ "read_chat_history": False,
449
462
  "get_member_information_tool": False,
450
463
  # System message defaults
451
464
  "system_message_role": "system",
@@ -457,22 +470,23 @@ class TeamResponse(BaseModel):
457
470
  "parse_response": True,
458
471
  "use_json_mode": False,
459
472
  # Streaming defaults
473
+ "stream_events": False,
460
474
  "stream_intermediate_steps": False,
461
475
  "stream_member_events": False,
462
476
  }
463
477
 
464
- if team.model is None:
465
- raise ValueError("Team model is required")
466
-
467
- team.determine_tools_for_model(
468
- model=team.model,
469
- session=TeamSession(session_id=str(uuid4()), session_data={}),
470
- run_response=TeamRunOutput(run_id=str(uuid4())),
478
+ run_id = str(uuid4())
479
+ session_id = str(uuid4())
480
+ _tools = team._determine_tools_for_model(
481
+ model=team.model, # type: ignore
482
+ session=TeamSession(session_id=session_id, session_data={}),
483
+ run_response=TeamRunOutput(run_id=run_id),
484
+ run_context=RunContext(run_id=run_id, session_id=session_id, session_state={}),
471
485
  async_mode=True,
472
- session_state={},
473
486
  team_run_context={},
487
+ check_mcp_tools=False,
474
488
  )
475
- team_tools = list(team._functions_for_model.values()) if team._functions_for_model else []
489
+ team_tools = _tools
476
490
  formatted_tools = format_team_tools(team_tools) if team_tools else None
477
491
 
478
492
  model_name = team.model.name or team.model.__class__.__name__ if team.model else None
@@ -542,7 +556,7 @@ class TeamResponse(BaseModel):
542
556
 
543
557
  default_tools_info = {
544
558
  "search_knowledge": team.search_knowledge,
545
- "read_team_history": team.read_team_history,
559
+ "read_chat_history": team.read_chat_history,
546
560
  "get_member_information_tool": team.get_member_information_tool,
547
561
  }
548
562
 
@@ -579,6 +593,7 @@ class TeamResponse(BaseModel):
579
593
 
580
594
  streaming_info = {
581
595
  "stream": team.stream,
596
+ "stream_events": team.stream_events,
582
597
  "stream_intermediate_steps": team.stream_intermediate_steps,
583
598
  "stream_member_events": team.stream_member_events,
584
599
  }
@@ -592,6 +607,15 @@ class TeamResponse(BaseModel):
592
607
  if team.model and team.model.provider is not None:
593
608
  _team_model_data["provider"] = team.model.provider
594
609
 
610
+ members: List[Union[AgentResponse, TeamResponse]] = []
611
+ for member in team.members:
612
+ if isinstance(member, Agent):
613
+ agent_response = await AgentResponse.from_agent(member)
614
+ members.append(agent_response)
615
+ if isinstance(member, Team):
616
+ team_response = await TeamResponse.from_team(member)
617
+ members.append(team_response)
618
+
595
619
  return TeamResponse(
596
620
  id=team.id,
597
621
  name=team.name,
@@ -606,34 +630,26 @@ class TeamResponse(BaseModel):
606
630
  system_message=filter_meaningful_config(system_message_info, team_defaults),
607
631
  response_settings=filter_meaningful_config(response_settings_info, team_defaults),
608
632
  streaming=filter_meaningful_config(streaming_info, team_defaults),
609
- members=[ # type: ignore
610
- AgentResponse.from_agent(member)
611
- if isinstance(member, Agent)
612
- else TeamResponse.from_team(member)
613
- if isinstance(member, Team)
614
- else None
615
- for member in team.members
616
- ],
633
+ members=members if members else None,
617
634
  metadata=team.metadata,
635
+ input_schema=get_team_input_schema_dict(team),
618
636
  )
619
637
 
620
638
 
621
639
  class WorkflowResponse(BaseModel):
622
- id: Optional[str] = None
623
- name: Optional[str] = None
624
- db_id: Optional[str] = None
625
- description: Optional[str] = None
626
- input_schema: Optional[Dict[str, Any]] = None
627
- steps: Optional[List[Dict[str, Any]]] = None
628
- agent: Optional[AgentResponse] = None
629
- team: Optional[TeamResponse] = None
630
- metadata: Optional[Dict[str, Any]] = None
631
-
632
- class Config:
633
- exclude_none = True
640
+ id: Optional[str] = Field(None, description="Unique identifier for the workflow")
641
+ name: Optional[str] = Field(None, description="Name of the workflow")
642
+ db_id: Optional[str] = Field(None, description="Database identifier")
643
+ description: Optional[str] = Field(None, description="Description of the workflow")
644
+ input_schema: Optional[Dict[str, Any]] = Field(None, description="Input schema for the workflow")
645
+ steps: Optional[List[Dict[str, Any]]] = Field(None, description="List of workflow steps")
646
+ agent: Optional[AgentResponse] = Field(None, description="Agent configuration if used")
647
+ team: Optional[TeamResponse] = Field(None, description="Team configuration if used")
648
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
649
+ workflow_agent: bool = Field(False, description="Whether this workflow uses a WorkflowAgent")
634
650
 
635
651
  @classmethod
636
- def _resolve_agents_and_teams_recursively(cls, steps: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
652
+ async def _resolve_agents_and_teams_recursively(cls, steps: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
637
653
  """Parse Agents and Teams into AgentResponse and TeamResponse objects.
638
654
 
639
655
  If the given steps have nested steps, recursively work on those."""
@@ -651,13 +667,15 @@ class WorkflowResponse(BaseModel):
651
667
  for idx, step in enumerate(steps):
652
668
  if step.get("agent"):
653
669
  # Convert to dict and exclude fields that are None
654
- step["agent"] = AgentResponse.from_agent(step["agent"]).model_dump(exclude_none=True)
670
+ agent_response = await AgentResponse.from_agent(step.get("agent")) # type: ignore
671
+ step["agent"] = agent_response.model_dump(exclude_none=True)
655
672
 
656
673
  if step.get("team"):
657
- step["team"] = TeamResponse.from_team(step["team"]).model_dump(exclude_none=True)
674
+ team_response = await TeamResponse.from_team(step.get("team")) # type: ignore
675
+ step["team"] = team_response.model_dump(exclude_none=True)
658
676
 
659
677
  if step.get("steps"):
660
- step["steps"] = cls._resolve_agents_and_teams_recursively(step["steps"])
678
+ step["steps"] = await cls._resolve_agents_and_teams_recursively(step["steps"])
661
679
 
662
680
  # Prune None values in the entire step
663
681
  steps[idx] = _prune_none(step)
@@ -665,12 +683,12 @@ class WorkflowResponse(BaseModel):
665
683
  return steps
666
684
 
667
685
  @classmethod
668
- def from_workflow(cls, workflow: Workflow) -> "WorkflowResponse":
686
+ async def from_workflow(cls, workflow: Workflow) -> "WorkflowResponse":
669
687
  workflow_dict = workflow.to_dict()
670
688
  steps = workflow_dict.get("steps")
671
689
 
672
690
  if steps:
673
- steps = cls._resolve_agents_and_teams_recursively(steps)
691
+ steps = await cls._resolve_agents_and_teams_recursively(steps)
674
692
 
675
693
  return cls(
676
694
  id=workflow.id,
@@ -680,21 +698,22 @@ class WorkflowResponse(BaseModel):
680
698
  steps=steps,
681
699
  input_schema=get_workflow_input_schema_dict(workflow),
682
700
  metadata=workflow.metadata,
701
+ workflow_agent=isinstance(workflow.agent, WorkflowAgent) if workflow.agent else False,
683
702
  )
684
703
 
685
704
 
686
705
  class WorkflowRunRequest(BaseModel):
687
- input: Dict[str, Any]
688
- user_id: Optional[str] = None
689
- session_id: Optional[str] = None
706
+ input: Dict[str, Any] = Field(..., description="Input parameters for the workflow run")
707
+ user_id: Optional[str] = Field(None, description="User identifier for the workflow run")
708
+ session_id: Optional[str] = Field(None, description="Session identifier for context persistence")
690
709
 
691
710
 
692
711
  class SessionSchema(BaseModel):
693
- session_id: str
694
- session_name: str
695
- session_state: Optional[dict]
696
- created_at: Optional[datetime]
697
- updated_at: Optional[datetime]
712
+ session_id: str = Field(..., description="Unique identifier for the session")
713
+ session_name: str = Field(..., description="Human-readable name for the session")
714
+ session_state: Optional[dict] = Field(None, description="Current state data of the session")
715
+ created_at: Optional[datetime] = Field(None, description="Timestamp when session was created")
716
+ updated_at: Optional[datetime] = Field(None, description="Timestamp when session was last updated")
698
717
 
699
718
  @classmethod
700
719
  def from_dict(cls, session: Dict[str, Any]) -> "SessionSchema":
@@ -713,24 +732,43 @@ class SessionSchema(BaseModel):
713
732
 
714
733
 
715
734
  class DeleteSessionRequest(BaseModel):
716
- session_ids: List[str]
717
- session_types: List[SessionType]
735
+ session_ids: List[str] = Field(..., description="List of session IDs to delete", min_length=1)
736
+ session_types: List[SessionType] = Field(..., description="Types of sessions to delete", min_length=1)
737
+
738
+
739
+ class CreateSessionRequest(BaseModel):
740
+ session_id: Optional[str] = Field(None, description="Optional session ID (generated if not provided)")
741
+ session_name: Optional[str] = Field(None, description="Name for the session")
742
+ session_state: Optional[Dict[str, Any]] = Field(None, description="Initial session state")
743
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
744
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
745
+ agent_id: Optional[str] = Field(None, description="Agent ID if this is an agent session")
746
+ team_id: Optional[str] = Field(None, description="Team ID if this is a team session")
747
+ workflow_id: Optional[str] = Field(None, description="Workflow ID if this is a workflow session")
748
+
749
+
750
+ class UpdateSessionRequest(BaseModel):
751
+ session_name: Optional[str] = Field(None, description="Updated session name")
752
+ session_state: Optional[Dict[str, Any]] = Field(None, description="Updated session state")
753
+ metadata: Optional[Dict[str, Any]] = Field(None, description="Updated metadata")
754
+ summary: Optional[Dict[str, Any]] = Field(None, description="Session summary")
718
755
 
719
756
 
720
757
  class AgentSessionDetailSchema(BaseModel):
721
- user_id: Optional[str]
722
- agent_session_id: str
723
- session_id: str
724
- session_name: str
725
- session_summary: Optional[dict]
726
- session_state: Optional[dict]
727
- agent_id: Optional[str]
728
- total_tokens: Optional[int]
729
- agent_data: Optional[dict]
730
- metrics: Optional[dict]
731
- chat_history: Optional[List[dict]]
732
- created_at: Optional[datetime]
733
- updated_at: Optional[datetime]
758
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
759
+ agent_session_id: str = Field(..., description="Unique agent session identifier")
760
+ session_id: str = Field(..., description="Session identifier")
761
+ session_name: str = Field(..., description="Human-readable session name")
762
+ session_summary: Optional[dict] = Field(None, description="Summary of session interactions")
763
+ session_state: Optional[dict] = Field(None, description="Current state of the session")
764
+ agent_id: Optional[str] = Field(None, description="Agent ID used in this session")
765
+ total_tokens: Optional[int] = Field(None, description="Total tokens used in this session")
766
+ agent_data: Optional[dict] = Field(None, description="Agent-specific data")
767
+ metrics: Optional[dict] = Field(None, description="Session metrics")
768
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
769
+ chat_history: Optional[List[dict]] = Field(None, description="Complete chat history")
770
+ created_at: Optional[datetime] = Field(None, description="Session creation timestamp")
771
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
734
772
 
735
773
  @classmethod
736
774
  def from_session(cls, session: AgentSession) -> "AgentSessionDetailSchema":
@@ -748,6 +786,7 @@ class AgentSessionDetailSchema(BaseModel):
748
786
  if session.session_data
749
787
  else None,
750
788
  metrics=session.session_data.get("session_metrics", {}) if session.session_data else None, # type: ignore
789
+ metadata=session.metadata,
751
790
  chat_history=[message.to_dict() for message in session.get_chat_history()],
752
791
  created_at=datetime.fromtimestamp(session.created_at, tz=timezone.utc) if session.created_at else None,
753
792
  updated_at=datetime.fromtimestamp(session.updated_at, tz=timezone.utc) if session.updated_at else None,
@@ -755,16 +794,19 @@ class AgentSessionDetailSchema(BaseModel):
755
794
 
756
795
 
757
796
  class TeamSessionDetailSchema(BaseModel):
758
- session_id: str
759
- session_name: str
760
- user_id: Optional[str]
761
- team_id: Optional[str]
762
- session_summary: Optional[dict]
763
- session_state: Optional[dict]
764
- metrics: Optional[dict]
765
- team_data: Optional[dict]
766
- created_at: Optional[datetime]
767
- updated_at: Optional[datetime]
797
+ session_id: str = Field(..., description="Unique session identifier")
798
+ session_name: str = Field(..., description="Human-readable session name")
799
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
800
+ team_id: Optional[str] = Field(None, description="Team ID used in this session")
801
+ session_summary: Optional[dict] = Field(None, description="Summary of team interactions")
802
+ session_state: Optional[dict] = Field(None, description="Current state of the session")
803
+ metrics: Optional[dict] = Field(None, description="Session metrics")
804
+ team_data: Optional[dict] = Field(None, description="Team-specific data")
805
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
806
+ chat_history: Optional[List[dict]] = Field(None, description="Complete chat history")
807
+ created_at: Optional[datetime] = Field(None, description="Session creation timestamp")
808
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
809
+ total_tokens: Optional[int] = Field(None, description="Total tokens used in this session")
768
810
 
769
811
  @classmethod
770
812
  def from_session(cls, session: TeamSession) -> "TeamSessionDetailSchema":
@@ -783,26 +825,27 @@ class TeamSessionDetailSchema(BaseModel):
783
825
  if session.session_data
784
826
  else None,
785
827
  metrics=session.session_data.get("session_metrics", {}) if session.session_data else None,
828
+ metadata=session.metadata,
829
+ chat_history=[message.to_dict() for message in session.get_chat_history()],
786
830
  created_at=datetime.fromtimestamp(session.created_at, tz=timezone.utc) if session.created_at else None,
787
831
  updated_at=datetime.fromtimestamp(session.updated_at, tz=timezone.utc) if session.updated_at else None,
788
832
  )
789
833
 
790
834
 
791
835
  class WorkflowSessionDetailSchema(BaseModel):
792
- user_id: Optional[str]
793
- workflow_id: Optional[str]
794
- workflow_name: Optional[str]
836
+ user_id: Optional[str] = Field(None, description="User ID associated with the session")
837
+ workflow_id: Optional[str] = Field(None, description="Workflow ID used in this session")
838
+ workflow_name: Optional[str] = Field(None, description="Name of the workflow")
839
+ session_id: str = Field(..., description="Unique session identifier")
840
+ session_name: str = Field(..., description="Human-readable session name")
795
841
 
796
- session_id: str
797
- session_name: str
842
+ session_data: Optional[dict] = Field(None, description="Complete session data")
843
+ session_state: Optional[dict] = Field(None, description="Current workflow state")
844
+ workflow_data: Optional[dict] = Field(None, description="Workflow-specific data")
845
+ metadata: Optional[dict] = Field(None, description="Additional metadata")
798
846
 
799
- session_data: Optional[dict]
800
- session_state: Optional[dict]
801
- workflow_data: Optional[dict]
802
- metadata: Optional[dict]
803
-
804
- created_at: Optional[int]
805
- updated_at: Optional[int]
847
+ created_at: Optional[int] = Field(None, description="Unix timestamp of session creation")
848
+ updated_at: Optional[int] = Field(None, description="Unix timestamp of last update")
806
849
 
807
850
  @classmethod
808
851
  def from_session(cls, session: WorkflowSession) -> "WorkflowSessionDetailSchema":
@@ -825,18 +868,29 @@ class WorkflowSessionDetailSchema(BaseModel):
825
868
 
826
869
 
827
870
  class RunSchema(BaseModel):
828
- run_id: str
829
- agent_session_id: Optional[str]
830
- user_id: Optional[str]
831
- run_input: Optional[str]
832
- content: Optional[Union[str, dict]]
833
- run_response_format: Optional[str]
834
- reasoning_content: Optional[str]
835
- metrics: Optional[dict]
836
- messages: Optional[List[dict]]
837
- tools: Optional[List[dict]]
838
- events: Optional[List[dict]]
839
- created_at: Optional[datetime]
871
+ run_id: str = Field(..., description="Unique identifier for the run")
872
+ parent_run_id: Optional[str] = Field(None, description="Parent run ID if this is a nested run")
873
+ agent_id: Optional[str] = Field(None, description="Agent ID that executed this run")
874
+ user_id: Optional[str] = Field(None, description="User ID associated with the run")
875
+ run_input: Optional[str] = Field(None, description="Input provided to the run")
876
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the run")
877
+ run_response_format: Optional[str] = Field(None, description="Format of the response (text/json)")
878
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
879
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
880
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
881
+ messages: Optional[List[dict]] = Field(None, description="Message history for the run")
882
+ tools: Optional[List[dict]] = Field(None, description="Tools used in the run")
883
+ events: Optional[List[dict]] = Field(None, description="Events generated during the run")
884
+ created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
885
+ references: Optional[List[dict]] = Field(None, description="References cited in the run")
886
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
887
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
888
+ images: Optional[List[dict]] = Field(None, description="Images included in the run")
889
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
890
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
891
+ files: Optional[List[dict]] = Field(None, description="Files included in the run")
892
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
893
+ input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
840
894
 
841
895
  @classmethod
842
896
  def from_dict(cls, run_dict: Dict[str, Any]) -> "RunSchema":
@@ -844,16 +898,27 @@ class RunSchema(BaseModel):
844
898
  run_response_format = "text" if run_dict.get("content_type", "str") == "str" else "json"
845
899
  return cls(
846
900
  run_id=run_dict.get("run_id", ""),
847
- agent_session_id=run_dict.get("session_id", ""),
901
+ parent_run_id=run_dict.get("parent_run_id", ""),
902
+ agent_id=run_dict.get("agent_id", ""),
848
903
  user_id=run_dict.get("user_id", ""),
849
904
  run_input=run_input,
850
905
  content=run_dict.get("content", ""),
851
906
  run_response_format=run_response_format,
852
907
  reasoning_content=run_dict.get("reasoning_content", ""),
908
+ reasoning_steps=run_dict.get("reasoning_steps", []),
853
909
  metrics=run_dict.get("metrics", {}),
854
910
  messages=[message for message in run_dict.get("messages", [])] if run_dict.get("messages") else None,
855
911
  tools=[tool for tool in run_dict.get("tools", [])] if run_dict.get("tools") else None,
856
912
  events=[event for event in run_dict["events"]] if run_dict.get("events") else None,
913
+ references=run_dict.get("references", []),
914
+ reasoning_messages=run_dict.get("reasoning_messages", []),
915
+ session_state=run_dict.get("session_state"),
916
+ images=run_dict.get("images", []),
917
+ videos=run_dict.get("videos", []),
918
+ audio=run_dict.get("audio", []),
919
+ files=run_dict.get("files", []),
920
+ response_audio=run_dict.get("response_audio", None),
921
+ input_media=extract_input_media(run_dict),
857
922
  created_at=datetime.fromtimestamp(run_dict.get("created_at", 0), tz=timezone.utc)
858
923
  if run_dict.get("created_at") is not None
859
924
  else None,
@@ -861,17 +926,28 @@ class RunSchema(BaseModel):
861
926
 
862
927
 
863
928
  class TeamRunSchema(BaseModel):
864
- run_id: str
865
- parent_run_id: Optional[str]
866
- content: Optional[Union[str, dict]]
867
- reasoning_content: Optional[str]
868
- run_input: Optional[str]
869
- run_response_format: Optional[str]
870
- metrics: Optional[dict]
871
- tools: Optional[List[dict]]
872
- messages: Optional[List[dict]]
873
- events: Optional[List[dict]]
874
- created_at: Optional[datetime]
929
+ run_id: str = Field(..., description="Unique identifier for the team run")
930
+ parent_run_id: Optional[str] = Field(None, description="Parent run ID if this is a nested run")
931
+ team_id: Optional[str] = Field(None, description="Team ID that executed this run")
932
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the team run")
933
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
934
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
935
+ run_input: Optional[str] = Field(None, description="Input provided to the run")
936
+ run_response_format: Optional[str] = Field(None, description="Format of the response (text/json)")
937
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
938
+ tools: Optional[List[dict]] = Field(None, description="Tools used in the run")
939
+ messages: Optional[List[dict]] = Field(None, description="Message history for the run")
940
+ events: Optional[List[dict]] = Field(None, description="Events generated during the run")
941
+ created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
942
+ references: Optional[List[dict]] = Field(None, description="References cited in the run")
943
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
944
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
945
+ input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
946
+ images: Optional[List[dict]] = Field(None, description="Images included in the run")
947
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
948
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
949
+ files: Optional[List[dict]] = Field(None, description="Files included in the run")
950
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
875
951
 
876
952
  @classmethod
877
953
  def from_dict(cls, run_dict: Dict[str, Any]) -> "TeamRunSchema":
@@ -880,10 +956,12 @@ class TeamRunSchema(BaseModel):
880
956
  return cls(
881
957
  run_id=run_dict.get("run_id", ""),
882
958
  parent_run_id=run_dict.get("parent_run_id", ""),
959
+ team_id=run_dict.get("team_id", ""),
883
960
  run_input=run_input,
884
961
  content=run_dict.get("content", ""),
885
962
  run_response_format=run_response_format,
886
963
  reasoning_content=run_dict.get("reasoning_content", ""),
964
+ reasoning_steps=run_dict.get("reasoning_steps", []),
887
965
  metrics=run_dict.get("metrics", {}),
888
966
  messages=[message for message in run_dict.get("messages", [])] if run_dict.get("messages") else None,
889
967
  tools=[tool for tool in run_dict.get("tools", [])] if run_dict.get("tools") else None,
@@ -891,20 +969,40 @@ class TeamRunSchema(BaseModel):
891
969
  created_at=datetime.fromtimestamp(run_dict.get("created_at", 0), tz=timezone.utc)
892
970
  if run_dict.get("created_at") is not None
893
971
  else None,
972
+ references=run_dict.get("references", []),
973
+ reasoning_messages=run_dict.get("reasoning_messages", []),
974
+ session_state=run_dict.get("session_state"),
975
+ images=run_dict.get("images", []),
976
+ videos=run_dict.get("videos", []),
977
+ audio=run_dict.get("audio", []),
978
+ files=run_dict.get("files", []),
979
+ response_audio=run_dict.get("response_audio", None),
980
+ input_media=extract_input_media(run_dict),
894
981
  )
895
982
 
896
983
 
897
984
  class WorkflowRunSchema(BaseModel):
898
- run_id: str
899
- run_input: Optional[str]
900
- user_id: Optional[str]
901
- content: Optional[Union[str, dict]]
902
- content_type: Optional[str]
903
- status: Optional[str]
904
- step_results: Optional[list[dict]]
905
- step_executor_runs: Optional[list[dict]]
906
- metrics: Optional[dict]
907
- created_at: Optional[int]
985
+ run_id: str = Field(..., description="Unique identifier for the workflow run")
986
+ run_input: Optional[str] = Field(None, description="Input provided to the workflow")
987
+ events: Optional[List[dict]] = Field(None, description="Events generated during the workflow")
988
+ workflow_id: Optional[str] = Field(None, description="Workflow ID that was executed")
989
+ user_id: Optional[str] = Field(None, description="User ID associated with the run")
990
+ content: Optional[Union[str, dict]] = Field(None, description="Output content from the workflow")
991
+ content_type: Optional[str] = Field(None, description="Type of content returned")
992
+ status: Optional[str] = Field(None, description="Status of the workflow run")
993
+ step_results: Optional[list[dict]] = Field(None, description="Results from each workflow step")
994
+ step_executor_runs: Optional[list[dict]] = Field(None, description="Executor runs for each step")
995
+ metrics: Optional[dict] = Field(None, description="Performance and usage metrics")
996
+ created_at: Optional[int] = Field(None, description="Unix timestamp of run creation")
997
+ reasoning_content: Optional[str] = Field(None, description="Reasoning content if reasoning was enabled")
998
+ reasoning_steps: Optional[List[dict]] = Field(None, description="List of reasoning steps")
999
+ references: Optional[List[dict]] = Field(None, description="References cited in the workflow")
1000
+ reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
1001
+ images: Optional[List[dict]] = Field(None, description="Images included in the workflow")
1002
+ videos: Optional[List[dict]] = Field(None, description="Videos included in the workflow")
1003
+ audio: Optional[List[dict]] = Field(None, description="Audio files included in the workflow")
1004
+ files: Optional[List[dict]] = Field(None, description="Files included in the workflow")
1005
+ response_audio: Optional[dict] = Field(None, description="Audio response if generated")
908
1006
 
909
1007
  @classmethod
910
1008
  def from_dict(cls, run_response: Dict[str, Any]) -> "WorkflowRunSchema":
@@ -912,6 +1010,8 @@ class WorkflowRunSchema(BaseModel):
912
1010
  return cls(
913
1011
  run_id=run_response.get("run_id", ""),
914
1012
  run_input=run_input,
1013
+ events=run_response.get("events", []),
1014
+ workflow_id=run_response.get("workflow_id", ""),
915
1015
  user_id=run_response.get("user_id", ""),
916
1016
  content=run_response.get("content", ""),
917
1017
  content_type=run_response.get("content_type", ""),
@@ -920,6 +1020,15 @@ class WorkflowRunSchema(BaseModel):
920
1020
  step_results=run_response.get("step_results", []),
921
1021
  step_executor_runs=run_response.get("step_executor_runs", []),
922
1022
  created_at=run_response["created_at"],
1023
+ reasoning_content=run_response.get("reasoning_content", ""),
1024
+ reasoning_steps=run_response.get("reasoning_steps", []),
1025
+ references=run_response.get("references", []),
1026
+ reasoning_messages=run_response.get("reasoning_messages", []),
1027
+ images=run_response.get("images", []),
1028
+ videos=run_response.get("videos", []),
1029
+ audio=run_response.get("audio", []),
1030
+ files=run_response.get("files", []),
1031
+ response_audio=run_response.get("response_audio", None),
923
1032
  )
924
1033
 
925
1034
 
@@ -932,14 +1041,15 @@ class SortOrder(str, Enum):
932
1041
 
933
1042
 
934
1043
  class PaginationInfo(BaseModel):
935
- page: Optional[int] = 0
936
- limit: Optional[int] = 20
937
- total_pages: Optional[int] = 0
938
- total_count: Optional[int] = 0
1044
+ page: int = Field(0, description="Current page number (0-indexed)", ge=0)
1045
+ limit: int = Field(20, description="Number of items per page", ge=1, le=100)
1046
+ total_pages: int = Field(0, description="Total number of pages", ge=0)
1047
+ total_count: int = Field(0, description="Total count of items", ge=0)
1048
+ search_time_ms: float = Field(0, description="Search execution time in milliseconds", ge=0)
939
1049
 
940
1050
 
941
1051
  class PaginatedResponse(BaseModel, Generic[T]):
942
1052
  """Wrapper to add pagination info to classes used as response models"""
943
1053
 
944
- data: List[T]
945
- meta: PaginationInfo
1054
+ data: List[T] = Field(..., description="List of items for the current page")
1055
+ meta: PaginationInfo = Field(..., description="Pagination metadata")