agno 1.8.1__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 (590) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3143 -4170
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +11 -66
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1743 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1432 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +882 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1045 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1416 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +154 -48
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +15 -11
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1551 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/{document → knowledge}/reader/json_reader.py +30 -9
  118. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  119. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  120. agno/knowledge/reader/reader_factory.py +268 -0
  121. agno/knowledge/reader/s3_reader.py +101 -0
  122. agno/{document → knowledge}/reader/text_reader.py +31 -10
  123. agno/knowledge/reader/url_reader.py +128 -0
  124. agno/knowledge/reader/web_search_reader.py +366 -0
  125. agno/{document → knowledge}/reader/website_reader.py +37 -10
  126. agno/knowledge/reader/wikipedia_reader.py +59 -0
  127. agno/knowledge/reader/youtube_reader.py +78 -0
  128. agno/knowledge/remote_content/remote_content.py +88 -0
  129. agno/{reranker → knowledge/reranker}/base.py +1 -1
  130. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  131. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  132. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  133. agno/knowledge/types.py +30 -0
  134. agno/knowledge/utils.py +169 -0
  135. agno/media.py +269 -268
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +131 -131
  141. agno/models/aws/bedrock.py +110 -182
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +346 -290
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +105 -46
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +46 -151
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +85 -47
  158. agno/models/openai/chat.py +154 -37
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +15 -9
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +497 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +77 -33
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +32 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  184. agno/os/mcp.py +235 -0
  185. agno/os/router.py +1400 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +393 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +850 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +410 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +178 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +536 -0
  202. agno/os/schema.py +945 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/agent.py +633 -0
  213. agno/run/base.py +53 -77
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +243 -96
  216. agno/run/workflow.py +550 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +3260 -4824
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +43 -23
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +20 -17
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +22 -12
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +17 -8
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +62 -62
  253. agno/tools/eleven_labs.py +36 -29
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +30 -30
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +23 -11
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +32 -20
  277. agno/tools/mcp.py +1 -2
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +33 -15
  282. agno/tools/models/gemini.py +59 -32
  283. agno/tools/models/groq.py +30 -23
  284. agno/tools/models/nebius.py +28 -12
  285. agno/tools/models_labs.py +40 -16
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +10 -8
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +58 -32
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +63 -47
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +55 -42
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +100 -123
  335. agno/utils/gemini.py +32 -2
  336. agno/utils/knowledge.py +29 -0
  337. agno/utils/log.py +54 -4
  338. agno/utils/mcp.py +68 -10
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/aws_claude.py +1 -1
  342. agno/utils/models/claude.py +47 -4
  343. agno/utils/models/cohere.py +1 -1
  344. agno/utils/models/mistral.py +8 -7
  345. agno/utils/models/schema_utils.py +3 -3
  346. agno/utils/models/watsonx.py +1 -1
  347. agno/utils/openai.py +1 -1
  348. agno/utils/pprint.py +33 -32
  349. agno/utils/print_response/agent.py +779 -0
  350. agno/utils/print_response/team.py +1669 -0
  351. agno/utils/print_response/workflow.py +1451 -0
  352. agno/utils/prompts.py +14 -14
  353. agno/utils/reasoning.py +87 -0
  354. agno/utils/response.py +42 -42
  355. agno/utils/streamlit.py +481 -0
  356. agno/utils/string.py +8 -22
  357. agno/utils/team.py +50 -0
  358. agno/utils/timer.py +2 -2
  359. agno/vectordb/base.py +33 -21
  360. agno/vectordb/cassandra/cassandra.py +287 -23
  361. agno/vectordb/chroma/chromadb.py +482 -59
  362. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  363. agno/vectordb/couchbase/couchbase.py +309 -29
  364. agno/vectordb/lancedb/lance_db.py +360 -21
  365. agno/vectordb/langchaindb/__init__.py +5 -0
  366. agno/vectordb/langchaindb/langchaindb.py +145 -0
  367. agno/vectordb/lightrag/__init__.py +5 -0
  368. agno/vectordb/lightrag/lightrag.py +374 -0
  369. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  370. agno/vectordb/milvus/milvus.py +242 -32
  371. agno/vectordb/mongodb/mongodb.py +200 -24
  372. agno/vectordb/pgvector/pgvector.py +319 -37
  373. agno/vectordb/pineconedb/pineconedb.py +221 -27
  374. agno/vectordb/qdrant/qdrant.py +334 -14
  375. agno/vectordb/singlestore/singlestore.py +286 -29
  376. agno/vectordb/surrealdb/surrealdb.py +187 -7
  377. agno/vectordb/upstashdb/upstashdb.py +342 -26
  378. agno/vectordb/weaviate/weaviate.py +227 -165
  379. agno/workflow/__init__.py +17 -13
  380. agno/workflow/{v2/condition.py → condition.py} +135 -32
  381. agno/workflow/{v2/loop.py → loop.py} +115 -28
  382. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  383. agno/workflow/{v2/router.py → router.py} +133 -32
  384. agno/workflow/{v2/step.py → step.py} +207 -49
  385. agno/workflow/{v2/steps.py → steps.py} +147 -66
  386. agno/workflow/types.py +482 -0
  387. agno/workflow/workflow.py +2410 -696
  388. agno-2.0.0.dist-info/METADATA +494 -0
  389. agno-2.0.0.dist-info/RECORD +515 -0
  390. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  391. agno/agent/metrics.py +0 -107
  392. agno/api/app.py +0 -35
  393. agno/api/playground.py +0 -92
  394. agno/api/schemas/app.py +0 -12
  395. agno/api/schemas/playground.py +0 -22
  396. agno/api/schemas/user.py +0 -35
  397. agno/api/schemas/workspace.py +0 -46
  398. agno/api/user.py +0 -160
  399. agno/api/workflows.py +0 -33
  400. agno/api/workspace.py +0 -175
  401. agno/app/agui/__init__.py +0 -3
  402. agno/app/agui/app.py +0 -17
  403. agno/app/agui/sync_router.py +0 -120
  404. agno/app/base.py +0 -186
  405. agno/app/discord/__init__.py +0 -3
  406. agno/app/fastapi/__init__.py +0 -3
  407. agno/app/fastapi/app.py +0 -107
  408. agno/app/fastapi/async_router.py +0 -457
  409. agno/app/fastapi/sync_router.py +0 -448
  410. agno/app/playground/app.py +0 -228
  411. agno/app/playground/async_router.py +0 -1050
  412. agno/app/playground/deploy.py +0 -249
  413. agno/app/playground/operator.py +0 -183
  414. agno/app/playground/schemas.py +0 -220
  415. agno/app/playground/serve.py +0 -55
  416. agno/app/playground/sync_router.py +0 -1042
  417. agno/app/playground/utils.py +0 -46
  418. agno/app/settings.py +0 -15
  419. agno/app/slack/__init__.py +0 -3
  420. agno/app/slack/app.py +0 -19
  421. agno/app/slack/sync_router.py +0 -92
  422. agno/app/utils.py +0 -54
  423. agno/app/whatsapp/__init__.py +0 -3
  424. agno/app/whatsapp/app.py +0 -15
  425. agno/app/whatsapp/sync_router.py +0 -197
  426. agno/cli/auth_server.py +0 -249
  427. agno/cli/config.py +0 -274
  428. agno/cli/console.py +0 -88
  429. agno/cli/credentials.py +0 -23
  430. agno/cli/entrypoint.py +0 -571
  431. agno/cli/operator.py +0 -357
  432. agno/cli/settings.py +0 -96
  433. agno/cli/ws/ws_cli.py +0 -817
  434. agno/constants.py +0 -13
  435. agno/document/__init__.py +0 -5
  436. agno/document/chunking/semantic.py +0 -45
  437. agno/document/chunking/strategy.py +0 -31
  438. agno/document/reader/__init__.py +0 -5
  439. agno/document/reader/base.py +0 -47
  440. agno/document/reader/docx_reader.py +0 -60
  441. agno/document/reader/gcs/pdf_reader.py +0 -44
  442. agno/document/reader/s3/pdf_reader.py +0 -59
  443. agno/document/reader/s3/text_reader.py +0 -63
  444. agno/document/reader/url_reader.py +0 -59
  445. agno/document/reader/youtube_reader.py +0 -58
  446. agno/embedder/__init__.py +0 -5
  447. agno/embedder/langdb.py +0 -80
  448. agno/embedder/mistral.py +0 -82
  449. agno/embedder/openai.py +0 -78
  450. agno/file/__init__.py +0 -5
  451. agno/file/file.py +0 -16
  452. agno/file/local/csv.py +0 -32
  453. agno/file/local/txt.py +0 -19
  454. agno/infra/app.py +0 -240
  455. agno/infra/base.py +0 -144
  456. agno/infra/context.py +0 -20
  457. agno/infra/db_app.py +0 -52
  458. agno/infra/resource.py +0 -205
  459. agno/infra/resources.py +0 -55
  460. agno/knowledge/agent.py +0 -702
  461. agno/knowledge/arxiv.py +0 -33
  462. agno/knowledge/combined.py +0 -36
  463. agno/knowledge/csv.py +0 -144
  464. agno/knowledge/csv_url.py +0 -124
  465. agno/knowledge/document.py +0 -223
  466. agno/knowledge/docx.py +0 -137
  467. agno/knowledge/firecrawl.py +0 -34
  468. agno/knowledge/gcs/__init__.py +0 -0
  469. agno/knowledge/gcs/base.py +0 -39
  470. agno/knowledge/gcs/pdf.py +0 -125
  471. agno/knowledge/json.py +0 -137
  472. agno/knowledge/langchain.py +0 -71
  473. agno/knowledge/light_rag.py +0 -273
  474. agno/knowledge/llamaindex.py +0 -66
  475. agno/knowledge/markdown.py +0 -154
  476. agno/knowledge/pdf.py +0 -164
  477. agno/knowledge/pdf_bytes.py +0 -42
  478. agno/knowledge/pdf_url.py +0 -148
  479. agno/knowledge/s3/__init__.py +0 -0
  480. agno/knowledge/s3/base.py +0 -64
  481. agno/knowledge/s3/pdf.py +0 -33
  482. agno/knowledge/s3/text.py +0 -34
  483. agno/knowledge/text.py +0 -141
  484. agno/knowledge/url.py +0 -46
  485. agno/knowledge/website.py +0 -179
  486. agno/knowledge/wikipedia.py +0 -32
  487. agno/knowledge/youtube.py +0 -35
  488. agno/memory/agent.py +0 -423
  489. agno/memory/classifier.py +0 -104
  490. agno/memory/db/__init__.py +0 -5
  491. agno/memory/db/base.py +0 -42
  492. agno/memory/db/mongodb.py +0 -189
  493. agno/memory/db/postgres.py +0 -203
  494. agno/memory/db/sqlite.py +0 -193
  495. agno/memory/memory.py +0 -22
  496. agno/memory/row.py +0 -36
  497. agno/memory/summarizer.py +0 -201
  498. agno/memory/summary.py +0 -19
  499. agno/memory/team.py +0 -415
  500. agno/memory/v2/__init__.py +0 -2
  501. agno/memory/v2/db/__init__.py +0 -1
  502. agno/memory/v2/db/base.py +0 -42
  503. agno/memory/v2/db/firestore.py +0 -339
  504. agno/memory/v2/db/mongodb.py +0 -196
  505. agno/memory/v2/db/postgres.py +0 -214
  506. agno/memory/v2/db/redis.py +0 -187
  507. agno/memory/v2/db/schema.py +0 -54
  508. agno/memory/v2/db/sqlite.py +0 -209
  509. agno/memory/v2/manager.py +0 -437
  510. agno/memory/v2/memory.py +0 -1097
  511. agno/memory/v2/schema.py +0 -55
  512. agno/memory/v2/summarizer.py +0 -215
  513. agno/memory/workflow.py +0 -38
  514. agno/models/ollama/tools.py +0 -430
  515. agno/models/qwen/__init__.py +0 -5
  516. agno/playground/__init__.py +0 -10
  517. agno/playground/deploy.py +0 -3
  518. agno/playground/playground.py +0 -3
  519. agno/playground/serve.py +0 -3
  520. agno/playground/settings.py +0 -3
  521. agno/reranker/__init__.py +0 -0
  522. agno/run/response.py +0 -467
  523. agno/run/v2/__init__.py +0 -0
  524. agno/run/v2/workflow.py +0 -567
  525. agno/storage/__init__.py +0 -0
  526. agno/storage/agent/__init__.py +0 -0
  527. agno/storage/agent/dynamodb.py +0 -1
  528. agno/storage/agent/json.py +0 -1
  529. agno/storage/agent/mongodb.py +0 -1
  530. agno/storage/agent/postgres.py +0 -1
  531. agno/storage/agent/singlestore.py +0 -1
  532. agno/storage/agent/sqlite.py +0 -1
  533. agno/storage/agent/yaml.py +0 -1
  534. agno/storage/base.py +0 -60
  535. agno/storage/dynamodb.py +0 -673
  536. agno/storage/firestore.py +0 -297
  537. agno/storage/gcs_json.py +0 -261
  538. agno/storage/in_memory.py +0 -234
  539. agno/storage/json.py +0 -237
  540. agno/storage/mongodb.py +0 -328
  541. agno/storage/mysql.py +0 -685
  542. agno/storage/postgres.py +0 -682
  543. agno/storage/redis.py +0 -336
  544. agno/storage/session/__init__.py +0 -16
  545. agno/storage/session/agent.py +0 -64
  546. agno/storage/session/team.py +0 -63
  547. agno/storage/session/v2/__init__.py +0 -5
  548. agno/storage/session/workflow.py +0 -61
  549. agno/storage/singlestore.py +0 -606
  550. agno/storage/sqlite.py +0 -646
  551. agno/storage/workflow/__init__.py +0 -0
  552. agno/storage/workflow/mongodb.py +0 -1
  553. agno/storage/workflow/postgres.py +0 -1
  554. agno/storage/workflow/sqlite.py +0 -1
  555. agno/storage/yaml.py +0 -241
  556. agno/tools/thinking.py +0 -73
  557. agno/utils/defaults.py +0 -57
  558. agno/utils/filesystem.py +0 -39
  559. agno/utils/git.py +0 -52
  560. agno/utils/json_io.py +0 -30
  561. agno/utils/load_env.py +0 -19
  562. agno/utils/py_io.py +0 -19
  563. agno/utils/pyproject.py +0 -18
  564. agno/utils/resource_filter.py +0 -31
  565. agno/workflow/v2/__init__.py +0 -21
  566. agno/workflow/v2/types.py +0 -357
  567. agno/workflow/v2/workflow.py +0 -3312
  568. agno/workspace/__init__.py +0 -0
  569. agno/workspace/config.py +0 -325
  570. agno/workspace/enums.py +0 -6
  571. agno/workspace/helpers.py +0 -52
  572. agno/workspace/operator.py +0 -757
  573. agno/workspace/settings.py +0 -158
  574. agno-1.8.1.dist-info/METADATA +0 -982
  575. agno-1.8.1.dist-info/RECORD +0 -566
  576. agno-1.8.1.dist-info/entry_points.txt +0 -3
  577. agno-1.8.1.dist-info/licenses/LICENSE +0 -375
  578. /agno/{app → db/migrations}/__init__.py +0 -0
  579. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  580. /agno/{cli → integrations}/__init__.py +0 -0
  581. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  582. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  583. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  584. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  585. /agno/{app → os/interfaces}/slack/security.py +0 -0
  586. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  587. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  588. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  589. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  590. {agno-1.8.1.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)