agno 1.8.2__py3-none-any.whl → 2.0.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 (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +393 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +850 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +410 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +178 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +3260 -4824
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +43 -23
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +20 -17
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/run/agent.py ADDED
@@ -0,0 +1,633 @@
1
+ from dataclasses import asdict, dataclass, field
2
+ from enum import Enum
3
+ from time import time
4
+ from typing import Any, Dict, List, Optional, Sequence, Union
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from agno.media import Audio, File, Image, Video
9
+ from agno.models.message import Citations, Message
10
+ from agno.models.metrics import Metrics
11
+ from agno.models.response import ToolExecution
12
+ from agno.reasoning.step import ReasoningStep
13
+ from agno.run.base import BaseRunOutputEvent, MessageReferences, RunStatus
14
+ from agno.utils.log import logger
15
+
16
+
17
+ class RunEvent(str, Enum):
18
+ """Events that can be sent by the run() functions"""
19
+
20
+ run_started = "RunStarted"
21
+ run_content = "RunContent"
22
+ run_intermediate_content = "RunIntermediateContent"
23
+ run_completed = "RunCompleted"
24
+ run_error = "RunError"
25
+ run_cancelled = "RunCancelled"
26
+
27
+ run_paused = "RunPaused"
28
+ run_continued = "RunContinued"
29
+
30
+ tool_call_started = "ToolCallStarted"
31
+ tool_call_completed = "ToolCallCompleted"
32
+
33
+ reasoning_started = "ReasoningStarted"
34
+ reasoning_step = "ReasoningStep"
35
+ reasoning_completed = "ReasoningCompleted"
36
+
37
+ memory_update_started = "MemoryUpdateStarted"
38
+ memory_update_completed = "MemoryUpdateCompleted"
39
+
40
+ parser_model_response_started = "ParserModelResponseStarted"
41
+ parser_model_response_completed = "ParserModelResponseCompleted"
42
+
43
+ output_model_response_started = "OutputModelResponseStarted"
44
+ output_model_response_completed = "OutputModelResponseCompleted"
45
+
46
+ custom_event = "CustomEvent"
47
+
48
+
49
+ @dataclass
50
+ class BaseAgentRunEvent(BaseRunOutputEvent):
51
+ created_at: int = field(default_factory=lambda: int(time()))
52
+ event: str = ""
53
+ agent_id: str = ""
54
+ agent_name: str = ""
55
+ run_id: Optional[str] = None
56
+ session_id: Optional[str] = None
57
+
58
+ # Step context for workflow execution
59
+ workflow_id: Optional[str] = None
60
+ workflow_run_id: Optional[str] = None
61
+ step_id: Optional[str] = None
62
+ step_name: Optional[str] = None
63
+ step_index: Optional[int] = None
64
+ tools: Optional[List[ToolExecution]] = None
65
+
66
+ # For backwards compatibility
67
+ content: Optional[Any] = None
68
+
69
+ @property
70
+ def tools_requiring_confirmation(self):
71
+ return [t for t in self.tools if t.requires_confirmation] if self.tools else []
72
+
73
+ @property
74
+ def tools_requiring_user_input(self):
75
+ return [t for t in self.tools if t.requires_user_input] if self.tools else []
76
+
77
+ @property
78
+ def tools_awaiting_external_execution(self):
79
+ return [t for t in self.tools if t.external_execution_required] if self.tools else []
80
+
81
+
82
+ @dataclass
83
+ class RunStartedEvent(BaseAgentRunEvent):
84
+ """Event sent when the run starts"""
85
+
86
+ event: str = RunEvent.run_started.value
87
+ model: str = ""
88
+ model_provider: str = ""
89
+
90
+
91
+ @dataclass
92
+ class RunContentEvent(BaseAgentRunEvent):
93
+ """Main event for each delta of the RunOutput"""
94
+
95
+ event: str = RunEvent.run_content.value
96
+ content: Optional[Any] = None
97
+ content_type: str = "str"
98
+ reasoning_content: Optional[str] = None
99
+ citations: Optional[Citations] = None
100
+ response_audio: Optional[Audio] = None # Model audio response
101
+ image: Optional[Image] = None # Image attached to the response
102
+ references: Optional[List[MessageReferences]] = None
103
+ additional_input: Optional[List[Message]] = None
104
+ reasoning_steps: Optional[List[ReasoningStep]] = None
105
+ reasoning_messages: Optional[List[Message]] = None
106
+
107
+
108
+ @dataclass
109
+ class IntermediateRunContentEvent(BaseAgentRunEvent):
110
+ event: str = RunEvent.run_intermediate_content.value
111
+ content: Optional[Any] = None
112
+ content_type: str = "str"
113
+
114
+
115
+ @dataclass
116
+ class RunCompletedEvent(BaseAgentRunEvent):
117
+ event: str = RunEvent.run_completed.value
118
+ content: Optional[Any] = None
119
+ content_type: str = "str"
120
+ reasoning_content: Optional[str] = None
121
+ citations: Optional[Citations] = None
122
+ images: Optional[List[Image]] = None # Images attached to the response
123
+ videos: Optional[List[Video]] = None # Videos attached to the response
124
+ audio: Optional[List[Audio]] = None # Audio attached to the response
125
+ response_audio: Optional[Audio] = None # Model audio response
126
+ references: Optional[List[MessageReferences]] = None
127
+ additional_input: Optional[List[Message]] = None
128
+ reasoning_steps: Optional[List[ReasoningStep]] = None
129
+ reasoning_messages: Optional[List[Message]] = None
130
+ metadata: Optional[Dict[str, Any]] = None
131
+ metrics: Optional[Metrics] = None
132
+
133
+
134
+ @dataclass
135
+ class RunPausedEvent(BaseAgentRunEvent):
136
+ event: str = RunEvent.run_paused.value
137
+ tools: Optional[List[ToolExecution]] = None
138
+
139
+ @property
140
+ def is_paused(self):
141
+ return True
142
+
143
+
144
+ @dataclass
145
+ class RunContinuedEvent(BaseAgentRunEvent):
146
+ event: str = RunEvent.run_continued.value
147
+
148
+
149
+ @dataclass
150
+ class RunErrorEvent(BaseAgentRunEvent):
151
+ event: str = RunEvent.run_error.value
152
+ content: Optional[str] = None
153
+
154
+
155
+ @dataclass
156
+ class RunCancelledEvent(BaseAgentRunEvent):
157
+ event: str = RunEvent.run_cancelled.value
158
+ reason: Optional[str] = None
159
+
160
+ @property
161
+ def is_cancelled(self):
162
+ return True
163
+
164
+
165
+ @dataclass
166
+ class MemoryUpdateStartedEvent(BaseAgentRunEvent):
167
+ event: str = RunEvent.memory_update_started.value
168
+
169
+
170
+ @dataclass
171
+ class MemoryUpdateCompletedEvent(BaseAgentRunEvent):
172
+ event: str = RunEvent.memory_update_completed.value
173
+
174
+
175
+ @dataclass
176
+ class ReasoningStartedEvent(BaseAgentRunEvent):
177
+ event: str = RunEvent.reasoning_started.value
178
+
179
+
180
+ @dataclass
181
+ class ReasoningStepEvent(BaseAgentRunEvent):
182
+ event: str = RunEvent.reasoning_step.value
183
+ content: Optional[Any] = None
184
+ content_type: str = "str"
185
+ reasoning_content: str = ""
186
+
187
+
188
+ @dataclass
189
+ class ReasoningCompletedEvent(BaseAgentRunEvent):
190
+ event: str = RunEvent.reasoning_completed.value
191
+ content: Optional[Any] = None
192
+ content_type: str = "str"
193
+
194
+
195
+ @dataclass
196
+ class ToolCallStartedEvent(BaseAgentRunEvent):
197
+ event: str = RunEvent.tool_call_started.value
198
+ tool: Optional[ToolExecution] = None
199
+
200
+
201
+ @dataclass
202
+ class ToolCallCompletedEvent(BaseAgentRunEvent):
203
+ event: str = RunEvent.tool_call_completed.value
204
+ tool: Optional[ToolExecution] = None
205
+ content: Optional[Any] = None
206
+ images: Optional[List[Image]] = None # Images produced by the tool call
207
+ videos: Optional[List[Video]] = None # Videos produced by the tool call
208
+ audio: Optional[List[Audio]] = None # Audio produced by the tool call
209
+
210
+
211
+ @dataclass
212
+ class ParserModelResponseStartedEvent(BaseAgentRunEvent):
213
+ event: str = RunEvent.parser_model_response_started.value
214
+
215
+
216
+ @dataclass
217
+ class ParserModelResponseCompletedEvent(BaseAgentRunEvent):
218
+ event: str = RunEvent.parser_model_response_completed.value
219
+
220
+
221
+ @dataclass
222
+ class OutputModelResponseStartedEvent(BaseAgentRunEvent):
223
+ event: str = RunEvent.output_model_response_started.value
224
+
225
+
226
+ @dataclass
227
+ class OutputModelResponseCompletedEvent(BaseAgentRunEvent):
228
+ event: str = RunEvent.output_model_response_completed.value
229
+
230
+
231
+ @dataclass
232
+ class CustomEvent(BaseAgentRunEvent):
233
+ event: str = RunEvent.custom_event.value
234
+
235
+
236
+ RunOutputEvent = Union[
237
+ RunStartedEvent,
238
+ RunContentEvent,
239
+ IntermediateRunContentEvent,
240
+ RunCompletedEvent,
241
+ RunErrorEvent,
242
+ RunCancelledEvent,
243
+ RunPausedEvent,
244
+ RunContinuedEvent,
245
+ ReasoningStartedEvent,
246
+ ReasoningStepEvent,
247
+ ReasoningCompletedEvent,
248
+ MemoryUpdateStartedEvent,
249
+ MemoryUpdateCompletedEvent,
250
+ ToolCallStartedEvent,
251
+ ToolCallCompletedEvent,
252
+ ParserModelResponseStartedEvent,
253
+ ParserModelResponseCompletedEvent,
254
+ OutputModelResponseStartedEvent,
255
+ OutputModelResponseCompletedEvent,
256
+ CustomEvent,
257
+ ]
258
+
259
+
260
+ # Map event string to dataclass
261
+ RUN_EVENT_TYPE_REGISTRY = {
262
+ RunEvent.run_started.value: RunStartedEvent,
263
+ RunEvent.run_content.value: RunContentEvent,
264
+ RunEvent.run_intermediate_content.value: IntermediateRunContentEvent,
265
+ RunEvent.run_completed.value: RunCompletedEvent,
266
+ RunEvent.run_error.value: RunErrorEvent,
267
+ RunEvent.run_cancelled.value: RunCancelledEvent,
268
+ RunEvent.run_paused.value: RunPausedEvent,
269
+ RunEvent.run_continued.value: RunContinuedEvent,
270
+ RunEvent.reasoning_started.value: ReasoningStartedEvent,
271
+ RunEvent.reasoning_step.value: ReasoningStepEvent,
272
+ RunEvent.reasoning_completed.value: ReasoningCompletedEvent,
273
+ RunEvent.memory_update_started.value: MemoryUpdateStartedEvent,
274
+ RunEvent.memory_update_completed.value: MemoryUpdateCompletedEvent,
275
+ RunEvent.tool_call_started.value: ToolCallStartedEvent,
276
+ RunEvent.tool_call_completed.value: ToolCallCompletedEvent,
277
+ RunEvent.parser_model_response_started.value: ParserModelResponseStartedEvent,
278
+ RunEvent.parser_model_response_completed.value: ParserModelResponseCompletedEvent,
279
+ RunEvent.output_model_response_started.value: OutputModelResponseStartedEvent,
280
+ RunEvent.output_model_response_completed.value: OutputModelResponseCompletedEvent,
281
+ RunEvent.custom_event.value: CustomEvent,
282
+ }
283
+
284
+
285
+ def run_output_event_from_dict(data: dict) -> BaseRunOutputEvent:
286
+ event_type = data.get("event", "")
287
+ cls = RUN_EVENT_TYPE_REGISTRY.get(event_type)
288
+ if not cls:
289
+ raise ValueError(f"Unknown event type: {event_type}")
290
+ return cls.from_dict(data) # type: ignore
291
+
292
+
293
+ @dataclass
294
+ class RunInput:
295
+ """Container for the raw input data passed to Agent.run().
296
+
297
+ This captures the original input exactly as provided by the user,
298
+ separate from the processed messages that go to the model.
299
+
300
+ Attributes:
301
+ input_content: The literal input message/content passed to run()
302
+ images: Images directly passed to run()
303
+ videos: Videos directly passed to run()
304
+ audios: Audio files directly passed to run()
305
+ files: Files directly passed to run()
306
+ """
307
+
308
+ input_content: Optional[Union[str, List, Dict, Message, BaseModel, List[Message]]] = None
309
+ images: Optional[Sequence[Image]] = None
310
+ videos: Optional[Sequence[Video]] = None
311
+ audios: Optional[Sequence[Audio]] = None
312
+ files: Optional[Sequence[File]] = None
313
+
314
+ def to_dict(self) -> Dict[str, Any]:
315
+ """Convert to dictionary representation"""
316
+ result: Dict[str, Any] = {}
317
+
318
+ if self.input_content is not None:
319
+ if isinstance(self.input_content, (str)):
320
+ result["input_content"] = self.input_content
321
+ elif isinstance(self.input_content, BaseModel):
322
+ result["input_content"] = self.input_content.model_dump(exclude_none=True)
323
+ elif isinstance(self.input_content, Message):
324
+ result["input_content"] = self.input_content.to_dict()
325
+ elif (
326
+ isinstance(self.input_content, list)
327
+ and self.input_content
328
+ and isinstance(self.input_content[0], Message)
329
+ ):
330
+ result["input_content"] = [m.to_dict() for m in self.input_content]
331
+ else:
332
+ result["input_content"] = self.input_content
333
+
334
+ if self.images:
335
+ result["images"] = [img.to_dict() for img in self.images]
336
+ if self.videos:
337
+ result["videos"] = [vid.to_dict() for vid in self.videos]
338
+ if self.audios:
339
+ result["audios"] = [aud.to_dict() for aud in self.audios]
340
+
341
+ return result
342
+
343
+ @classmethod
344
+ def from_dict(cls, data: Dict[str, Any]) -> "RunInput":
345
+ """Create RunInput from dictionary"""
346
+ images = None
347
+ if data.get("images"):
348
+ images = [Image.model_validate(img_data) for img_data in data["images"]]
349
+
350
+ videos = None
351
+ if data.get("videos"):
352
+ videos = [Video.model_validate(vid_data) for vid_data in data["videos"]]
353
+
354
+ audios = None
355
+ if data.get("audios"):
356
+ audios = [Audio.model_validate(aud_data) for aud_data in data["audios"]]
357
+
358
+ files = None
359
+ if data.get("files"):
360
+ files = [File.model_validate(file_data) for file_data in data["files"]]
361
+
362
+ return cls(input_content=data.get("input_content"), images=images, videos=videos, audios=audios, files=files)
363
+
364
+
365
+ @dataclass
366
+ class RunOutput:
367
+ """Response returned by Agent.run() or Workflow.run() functions"""
368
+
369
+ run_id: Optional[str] = None
370
+ agent_id: Optional[str] = None
371
+ agent_name: Optional[str] = None
372
+ session_id: Optional[str] = None
373
+ parent_run_id: Optional[str] = None
374
+ workflow_id: Optional[str] = None
375
+ user_id: Optional[str] = None
376
+
377
+ content: Optional[Any] = None
378
+ content_type: str = "str"
379
+
380
+ reasoning_content: Optional[str] = None
381
+ reasoning_steps: Optional[List[ReasoningStep]] = None
382
+ reasoning_messages: Optional[List[Message]] = None
383
+
384
+ model: Optional[str] = None
385
+ model_provider: Optional[str] = None
386
+ messages: Optional[List[Message]] = None
387
+ metrics: Optional[Metrics] = None
388
+ additional_input: Optional[List[Message]] = None
389
+
390
+ tools: Optional[List[ToolExecution]] = None
391
+
392
+ images: Optional[List[Image]] = None # Images attached to the response
393
+ videos: Optional[List[Video]] = None # Videos attached to the response
394
+ audio: Optional[List[Audio]] = None # Audio attached to the response
395
+ response_audio: Optional[Audio] = None # Model audio response
396
+
397
+ # Input media and messages from user
398
+ input: Optional[RunInput] = None
399
+
400
+ citations: Optional[Citations] = None
401
+ references: Optional[List[MessageReferences]] = None
402
+
403
+ metadata: Optional[Dict[str, Any]] = None
404
+
405
+ created_at: int = field(default_factory=lambda: int(time()))
406
+
407
+ events: Optional[List[RunOutputEvent]] = None
408
+
409
+ status: RunStatus = RunStatus.running
410
+
411
+ # === FOREIGN KEY RELATIONSHIPS ===
412
+ # These fields establish relationships to parent workflow/step structures
413
+ # and should be treated as foreign keys for data integrity
414
+ workflow_step_id: Optional[str] = None # FK: Points to StepOutput.step_id
415
+
416
+ @property
417
+ def is_paused(self):
418
+ return self.status == RunStatus.paused
419
+
420
+ @property
421
+ def is_cancelled(self):
422
+ return self.status == RunStatus.cancelled
423
+
424
+ @property
425
+ def tools_requiring_confirmation(self):
426
+ return [t for t in self.tools if t.requires_confirmation] if self.tools else []
427
+
428
+ @property
429
+ def tools_requiring_user_input(self):
430
+ return [t for t in self.tools if t.requires_user_input] if self.tools else []
431
+
432
+ @property
433
+ def tools_awaiting_external_execution(self):
434
+ return [t for t in self.tools if t.external_execution_required] if self.tools else []
435
+
436
+ def to_dict(self) -> Dict[str, Any]:
437
+ _dict = {
438
+ k: v
439
+ for k, v in asdict(self).items()
440
+ if v is not None
441
+ and k
442
+ not in [
443
+ "messages",
444
+ "tools",
445
+ "metadata",
446
+ "images",
447
+ "videos",
448
+ "audio",
449
+ "response_audio",
450
+ "input",
451
+ "citations",
452
+ "events",
453
+ "additional_input",
454
+ "reasoning_steps",
455
+ "reasoning_messages",
456
+ "references",
457
+ ]
458
+ }
459
+
460
+ if self.metrics is not None:
461
+ _dict["metrics"] = self.metrics.to_dict() if isinstance(self.metrics, Metrics) else self.metrics
462
+
463
+ if self.events is not None:
464
+ _dict["events"] = [e.to_dict() for e in self.events]
465
+
466
+ if self.status is not None:
467
+ _dict["status"] = self.status.value if isinstance(self.status, RunStatus) else self.status
468
+
469
+ if self.messages is not None:
470
+ _dict["messages"] = [m.to_dict() for m in self.messages]
471
+
472
+ if self.metadata is not None:
473
+ _dict["metadata"] = self.metadata
474
+
475
+ if self.additional_input is not None:
476
+ _dict["additional_input"] = [m.to_dict() for m in self.additional_input]
477
+
478
+ if self.reasoning_messages is not None:
479
+ _dict["reasoning_messages"] = [m.to_dict() for m in self.reasoning_messages]
480
+
481
+ if self.reasoning_steps is not None:
482
+ _dict["reasoning_steps"] = [rs.model_dump() for rs in self.reasoning_steps]
483
+
484
+ if self.references is not None:
485
+ _dict["references"] = [r.model_dump() for r in self.references]
486
+
487
+ if self.images is not None:
488
+ _dict["images"] = []
489
+ for img in self.images:
490
+ if isinstance(img, Image):
491
+ _dict["images"].append(img.to_dict())
492
+ else:
493
+ _dict["images"].append(img)
494
+
495
+ if self.videos is not None:
496
+ _dict["videos"] = []
497
+ for vid in self.videos:
498
+ if isinstance(vid, Video):
499
+ _dict["videos"].append(vid.to_dict())
500
+ else:
501
+ _dict["videos"].append(vid)
502
+
503
+ if self.audio is not None:
504
+ _dict["audio"] = []
505
+ for aud in self.audio:
506
+ if isinstance(aud, Audio):
507
+ _dict["audio"].append(aud.to_dict())
508
+ else:
509
+ _dict["audio"].append(aud)
510
+
511
+ if self.response_audio is not None:
512
+ if isinstance(self.response_audio, Audio):
513
+ _dict["response_audio"] = self.response_audio.to_dict()
514
+ else:
515
+ _dict["response_audio"] = self.response_audio
516
+
517
+ if self.citations is not None:
518
+ if isinstance(self.citations, Citations):
519
+ _dict["citations"] = self.citations.model_dump(exclude_none=True)
520
+ else:
521
+ _dict["citations"] = self.citations
522
+
523
+ if self.content and isinstance(self.content, BaseModel):
524
+ _dict["content"] = self.content.model_dump(exclude_none=True, mode="json")
525
+
526
+ if self.tools is not None:
527
+ _dict["tools"] = []
528
+ for tool in self.tools:
529
+ if isinstance(tool, ToolExecution):
530
+ _dict["tools"].append(tool.to_dict())
531
+ else:
532
+ _dict["tools"].append(tool)
533
+
534
+ if self.input is not None:
535
+ _dict["input"] = self.input.to_dict()
536
+
537
+ return _dict
538
+
539
+ def to_json(self) -> str:
540
+ import json
541
+
542
+ try:
543
+ _dict = self.to_dict()
544
+ except Exception:
545
+ logger.error("Failed to convert response to json", exc_info=True)
546
+ raise
547
+
548
+ return json.dumps(_dict, indent=2)
549
+
550
+ @classmethod
551
+ def from_dict(cls, data: Dict[str, Any]) -> "RunOutput":
552
+ if "run" in data:
553
+ data = data.pop("run")
554
+
555
+ events = data.pop("events", None)
556
+ events = [run_output_event_from_dict(event) for event in events] if events else None
557
+
558
+ messages = data.pop("messages", None)
559
+ messages = [Message.model_validate(message) for message in messages] if messages else None
560
+
561
+ citations = data.pop("citations", None)
562
+ citations = Citations.model_validate(citations) if citations else None
563
+
564
+ tools = data.pop("tools", [])
565
+ tools = [ToolExecution.from_dict(tool) for tool in tools] if tools else None
566
+
567
+ images = data.pop("images", [])
568
+ images = [Image.model_validate(image) for image in images] if images else None
569
+
570
+ videos = data.pop("videos", [])
571
+ videos = [Video.model_validate(video) for video in videos] if videos else None
572
+
573
+ audio = data.pop("audio", [])
574
+ audio = [Audio.model_validate(audio) for audio in audio] if audio else None
575
+
576
+ response_audio = data.pop("response_audio", None)
577
+ response_audio = Audio.model_validate(response_audio) if response_audio else None
578
+
579
+ input_data = data.pop("input", None)
580
+ input_obj = None
581
+ if input_data:
582
+ input_obj = RunInput.from_dict(input_data)
583
+
584
+ metrics = data.pop("metrics", None)
585
+ if metrics:
586
+ metrics = Metrics(**metrics)
587
+
588
+ additional_input = data.pop("additional_input", None)
589
+
590
+ if additional_input is not None:
591
+ additional_input = [Message.model_validate(message) for message in additional_input]
592
+
593
+ reasoning_steps = data.pop("reasoning_steps", None)
594
+ if reasoning_steps is not None:
595
+ reasoning_steps = [ReasoningStep.model_validate(step) for step in reasoning_steps]
596
+
597
+ reasoning_messages = data.pop("reasoning_messages", None)
598
+ if reasoning_messages is not None:
599
+ reasoning_messages = [Message.model_validate(message) for message in reasoning_messages]
600
+
601
+ references = data.pop("references", None)
602
+ if references is not None:
603
+ references = [MessageReferences.model_validate(reference) for reference in references]
604
+
605
+ return cls(
606
+ messages=messages,
607
+ metrics=metrics,
608
+ citations=citations,
609
+ tools=tools,
610
+ images=images,
611
+ audio=audio,
612
+ videos=videos,
613
+ response_audio=response_audio,
614
+ input=input_obj,
615
+ events=events,
616
+ additional_input=additional_input,
617
+ reasoning_steps=reasoning_steps,
618
+ reasoning_messages=reasoning_messages,
619
+ references=references,
620
+ **data,
621
+ )
622
+
623
+ def get_content_as_string(self, **kwargs) -> str:
624
+ import json
625
+
626
+ from pydantic import BaseModel
627
+
628
+ if isinstance(self.content, str):
629
+ return self.content
630
+ elif isinstance(self.content, BaseModel):
631
+ return self.content.model_dump_json(exclude_none=True, **kwargs)
632
+ else:
633
+ return json.dumps(self.content, **kwargs)