agno 0.1.2__py3-none-any.whl → 2.3.13__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 (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  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/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/run/agent.py ADDED
@@ -0,0 +1,822 @@
1
+ from dataclasses import asdict, dataclass, field
2
+ from enum import Enum
3
+ from time import time
4
+ from typing import TYPE_CHECKING, 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.run.requirement import RunRequirement
15
+ from agno.utils.log import logger
16
+ from agno.utils.media import (
17
+ reconstruct_audio_list,
18
+ reconstruct_files,
19
+ reconstruct_images,
20
+ reconstruct_response_audio,
21
+ reconstruct_videos,
22
+ )
23
+
24
+ if TYPE_CHECKING:
25
+ from agno.session.summary import SessionSummary
26
+
27
+
28
+ @dataclass
29
+ class RunInput:
30
+ """Container for the raw input data passed to Agent.run().
31
+
32
+ This captures the original input exactly as provided by the user,
33
+ separate from the processed messages that go to the model.
34
+
35
+ Attributes:
36
+ input_content: The literal input message/content passed to run()
37
+ images: Images directly passed to run()
38
+ videos: Videos directly passed to run()
39
+ audios: Audio files directly passed to run()
40
+ files: Files directly passed to run()
41
+ """
42
+
43
+ input_content: Union[str, List, Dict, Message, BaseModel, List[Message]]
44
+ images: Optional[Sequence[Image]] = None
45
+ videos: Optional[Sequence[Video]] = None
46
+ audios: Optional[Sequence[Audio]] = None
47
+ files: Optional[Sequence[File]] = None
48
+
49
+ def input_content_string(self) -> str:
50
+ import json
51
+
52
+ if isinstance(self.input_content, (str)):
53
+ return self.input_content
54
+ elif isinstance(self.input_content, BaseModel):
55
+ return self.input_content.model_dump_json(exclude_none=True)
56
+ elif isinstance(self.input_content, Message):
57
+ return json.dumps(self.input_content.to_dict())
58
+ elif isinstance(self.input_content, list) and self.input_content and isinstance(self.input_content[0], Message):
59
+ return json.dumps([m.to_dict() for m in self.input_content])
60
+ else:
61
+ return str(self.input_content)
62
+
63
+ def to_dict(self) -> Dict[str, Any]:
64
+ """Convert to dictionary representation"""
65
+ result: Dict[str, Any] = {}
66
+
67
+ if self.input_content is not None:
68
+ if isinstance(self.input_content, (str)):
69
+ result["input_content"] = self.input_content
70
+ elif isinstance(self.input_content, BaseModel):
71
+ result["input_content"] = self.input_content.model_dump(exclude_none=True)
72
+ elif isinstance(self.input_content, Message):
73
+ result["input_content"] = self.input_content.to_dict()
74
+
75
+ # Handle input_content provided as a list of Message objects
76
+ elif (
77
+ isinstance(self.input_content, list)
78
+ and self.input_content
79
+ and isinstance(self.input_content[0], Message)
80
+ ):
81
+ result["input_content"] = [m.to_dict() for m in self.input_content]
82
+
83
+ # Handle input_content provided as a list of dicts
84
+ elif (
85
+ isinstance(self.input_content, list) and self.input_content and isinstance(self.input_content[0], dict)
86
+ ):
87
+ for content in self.input_content:
88
+ # Handle media input
89
+ if isinstance(content, dict):
90
+ if content.get("images"):
91
+ content["images"] = [
92
+ img.to_dict() if isinstance(img, Image) else img for img in content["images"]
93
+ ]
94
+ if content.get("videos"):
95
+ content["videos"] = [
96
+ vid.to_dict() if isinstance(vid, Video) else vid for vid in content["videos"]
97
+ ]
98
+ if content.get("audios"):
99
+ content["audios"] = [
100
+ aud.to_dict() if isinstance(aud, Audio) else aud for aud in content["audios"]
101
+ ]
102
+ if content.get("files"):
103
+ content["files"] = [
104
+ file.to_dict() if isinstance(file, File) else file for file in content["files"]
105
+ ]
106
+ result["input_content"] = self.input_content
107
+ else:
108
+ result["input_content"] = self.input_content
109
+
110
+ if self.images:
111
+ result["images"] = [img.to_dict() for img in self.images]
112
+ if self.videos:
113
+ result["videos"] = [vid.to_dict() for vid in self.videos]
114
+ if self.audios:
115
+ result["audios"] = [aud.to_dict() for aud in self.audios]
116
+ if self.files:
117
+ result["files"] = [file.to_dict() for file in self.files]
118
+
119
+ return result
120
+
121
+ @classmethod
122
+ def from_dict(cls, data: Dict[str, Any]) -> "RunInput":
123
+ """Create RunInput from dictionary"""
124
+ images = reconstruct_images(data.get("images"))
125
+ videos = reconstruct_videos(data.get("videos"))
126
+ audios = reconstruct_audio_list(data.get("audios"))
127
+ files = reconstruct_files(data.get("files"))
128
+
129
+ return cls(
130
+ input_content=data.get("input_content", ""), images=images, videos=videos, audios=audios, files=files
131
+ )
132
+
133
+
134
+ class RunEvent(str, Enum):
135
+ """Events that can be sent by the run() functions"""
136
+
137
+ run_started = "RunStarted"
138
+ run_content = "RunContent"
139
+ run_content_completed = "RunContentCompleted"
140
+ run_intermediate_content = "RunIntermediateContent"
141
+ run_completed = "RunCompleted"
142
+ run_error = "RunError"
143
+ run_cancelled = "RunCancelled"
144
+
145
+ run_paused = "RunPaused"
146
+ run_continued = "RunContinued"
147
+
148
+ pre_hook_started = "PreHookStarted"
149
+ pre_hook_completed = "PreHookCompleted"
150
+
151
+ post_hook_started = "PostHookStarted"
152
+ post_hook_completed = "PostHookCompleted"
153
+
154
+ tool_call_started = "ToolCallStarted"
155
+ tool_call_completed = "ToolCallCompleted"
156
+
157
+ reasoning_started = "ReasoningStarted"
158
+ reasoning_step = "ReasoningStep"
159
+ reasoning_completed = "ReasoningCompleted"
160
+
161
+ memory_update_started = "MemoryUpdateStarted"
162
+ memory_update_completed = "MemoryUpdateCompleted"
163
+
164
+ session_summary_started = "SessionSummaryStarted"
165
+ session_summary_completed = "SessionSummaryCompleted"
166
+
167
+ parser_model_response_started = "ParserModelResponseStarted"
168
+ parser_model_response_completed = "ParserModelResponseCompleted"
169
+
170
+ output_model_response_started = "OutputModelResponseStarted"
171
+ output_model_response_completed = "OutputModelResponseCompleted"
172
+
173
+ custom_event = "CustomEvent"
174
+
175
+
176
+ @dataclass
177
+ class BaseAgentRunEvent(BaseRunOutputEvent):
178
+ created_at: int = field(default_factory=lambda: int(time()))
179
+ event: str = ""
180
+ agent_id: str = ""
181
+ agent_name: str = ""
182
+ run_id: Optional[str] = None
183
+ parent_run_id: Optional[str] = None
184
+ session_id: Optional[str] = None
185
+
186
+ # Step context for workflow execution
187
+ workflow_id: Optional[str] = None
188
+ workflow_run_id: Optional[str] = None
189
+ step_id: Optional[str] = None
190
+ step_name: Optional[str] = None
191
+ step_index: Optional[int] = None
192
+ tools: Optional[List[ToolExecution]] = None
193
+
194
+ # For backwards compatibility
195
+ content: Optional[Any] = None
196
+
197
+ @property
198
+ def tools_requiring_confirmation(self):
199
+ return [t for t in self.tools if t.requires_confirmation] if self.tools else []
200
+
201
+ @property
202
+ def tools_requiring_user_input(self):
203
+ return [t for t in self.tools if t.requires_user_input] if self.tools else []
204
+
205
+ @property
206
+ def tools_awaiting_external_execution(self):
207
+ return [t for t in self.tools if t.external_execution_required] if self.tools else []
208
+
209
+
210
+ @dataclass
211
+ class RunStartedEvent(BaseAgentRunEvent):
212
+ """Event sent when the run starts"""
213
+
214
+ event: str = RunEvent.run_started.value
215
+ model: str = ""
216
+ model_provider: str = ""
217
+
218
+
219
+ @dataclass
220
+ class RunContentEvent(BaseAgentRunEvent):
221
+ """Main event for each delta of the RunOutput"""
222
+
223
+ event: str = RunEvent.run_content.value
224
+ content: Optional[Any] = None
225
+ workflow_agent: bool = (
226
+ False # Used by consumers of the events to distinguish between workflow agent and regular agent
227
+ )
228
+ content_type: str = "str"
229
+ reasoning_content: Optional[str] = None
230
+ model_provider_data: Optional[Dict[str, Any]] = None
231
+ citations: Optional[Citations] = None
232
+ response_audio: Optional[Audio] = None # Model audio response
233
+ image: Optional[Image] = None # Image attached to the response
234
+ references: Optional[List[MessageReferences]] = None
235
+ additional_input: Optional[List[Message]] = None
236
+ reasoning_steps: Optional[List[ReasoningStep]] = None
237
+ reasoning_messages: Optional[List[Message]] = None
238
+
239
+
240
+ @dataclass
241
+ class RunContentCompletedEvent(BaseAgentRunEvent):
242
+ event: str = RunEvent.run_content_completed.value
243
+
244
+
245
+ @dataclass
246
+ class IntermediateRunContentEvent(BaseAgentRunEvent):
247
+ event: str = RunEvent.run_intermediate_content.value
248
+ content: Optional[Any] = None
249
+ content_type: str = "str"
250
+
251
+
252
+ @dataclass
253
+ class RunCompletedEvent(BaseAgentRunEvent):
254
+ event: str = RunEvent.run_completed.value
255
+ content: Optional[Any] = None
256
+ content_type: str = "str"
257
+ reasoning_content: Optional[str] = None
258
+ citations: Optional[Citations] = None
259
+ model_provider_data: Optional[Dict[str, Any]] = None
260
+ images: Optional[List[Image]] = None # Images attached to the response
261
+ videos: Optional[List[Video]] = None # Videos attached to the response
262
+ audio: Optional[List[Audio]] = None # Audio attached to the response
263
+ response_audio: Optional[Audio] = None # Model audio response
264
+ references: Optional[List[MessageReferences]] = None
265
+ additional_input: Optional[List[Message]] = None
266
+ reasoning_steps: Optional[List[ReasoningStep]] = None
267
+ reasoning_messages: Optional[List[Message]] = None
268
+ metadata: Optional[Dict[str, Any]] = None
269
+ metrics: Optional[Metrics] = None
270
+ session_state: Optional[Dict[str, Any]] = None
271
+
272
+
273
+ @dataclass
274
+ class RunPausedEvent(BaseAgentRunEvent):
275
+ event: str = RunEvent.run_paused.value
276
+ tools: Optional[List[ToolExecution]] = None
277
+ requirements: Optional[List[RunRequirement]] = None
278
+
279
+ @property
280
+ def is_paused(self):
281
+ return True
282
+
283
+ @property
284
+ def active_requirements(self) -> List[RunRequirement]:
285
+ if not self.requirements:
286
+ return []
287
+ return [requirement for requirement in self.requirements if not requirement.is_resolved()]
288
+
289
+
290
+ @dataclass
291
+ class RunContinuedEvent(BaseAgentRunEvent):
292
+ event: str = RunEvent.run_continued.value
293
+
294
+
295
+ @dataclass
296
+ class RunErrorEvent(BaseAgentRunEvent):
297
+ event: str = RunEvent.run_error.value
298
+ content: Optional[str] = None
299
+
300
+ # From exceptions
301
+ error_type: Optional[str] = None
302
+ error_id: Optional[str] = None
303
+ additional_data: Optional[Dict[str, Any]] = None
304
+
305
+
306
+ @dataclass
307
+ class RunCancelledEvent(BaseAgentRunEvent):
308
+ event: str = RunEvent.run_cancelled.value
309
+ reason: Optional[str] = None
310
+
311
+ @property
312
+ def is_cancelled(self):
313
+ return True
314
+
315
+
316
+ @dataclass
317
+ class PreHookStartedEvent(BaseAgentRunEvent):
318
+ event: str = RunEvent.pre_hook_started.value
319
+ pre_hook_name: Optional[str] = None
320
+ run_input: Optional[RunInput] = None
321
+
322
+
323
+ @dataclass
324
+ class PreHookCompletedEvent(BaseAgentRunEvent):
325
+ event: str = RunEvent.pre_hook_completed.value
326
+ pre_hook_name: Optional[str] = None
327
+ run_input: Optional[RunInput] = None
328
+
329
+
330
+ @dataclass
331
+ class PostHookStartedEvent(BaseAgentRunEvent):
332
+ event: str = RunEvent.post_hook_started.value
333
+ post_hook_name: Optional[str] = None
334
+
335
+
336
+ @dataclass
337
+ class PostHookCompletedEvent(BaseAgentRunEvent):
338
+ event: str = RunEvent.post_hook_completed.value
339
+ post_hook_name: Optional[str] = None
340
+
341
+
342
+ @dataclass
343
+ class MemoryUpdateStartedEvent(BaseAgentRunEvent):
344
+ event: str = RunEvent.memory_update_started.value
345
+
346
+
347
+ @dataclass
348
+ class MemoryUpdateCompletedEvent(BaseAgentRunEvent):
349
+ event: str = RunEvent.memory_update_completed.value
350
+
351
+
352
+ @dataclass
353
+ class SessionSummaryStartedEvent(BaseAgentRunEvent):
354
+ event: str = RunEvent.session_summary_started.value
355
+
356
+
357
+ @dataclass
358
+ class SessionSummaryCompletedEvent(BaseAgentRunEvent):
359
+ event: str = RunEvent.session_summary_completed.value
360
+ session_summary: Optional["SessionSummary"] = None
361
+
362
+
363
+ @dataclass
364
+ class ReasoningStartedEvent(BaseAgentRunEvent):
365
+ event: str = RunEvent.reasoning_started.value
366
+
367
+
368
+ @dataclass
369
+ class ReasoningStepEvent(BaseAgentRunEvent):
370
+ event: str = RunEvent.reasoning_step.value
371
+ content: Optional[Any] = None
372
+ content_type: str = "str"
373
+ reasoning_content: str = ""
374
+
375
+
376
+ @dataclass
377
+ class ReasoningCompletedEvent(BaseAgentRunEvent):
378
+ event: str = RunEvent.reasoning_completed.value
379
+ content: Optional[Any] = None
380
+ content_type: str = "str"
381
+
382
+
383
+ @dataclass
384
+ class ToolCallStartedEvent(BaseAgentRunEvent):
385
+ event: str = RunEvent.tool_call_started.value
386
+ tool: Optional[ToolExecution] = None
387
+
388
+
389
+ @dataclass
390
+ class ToolCallCompletedEvent(BaseAgentRunEvent):
391
+ event: str = RunEvent.tool_call_completed.value
392
+ tool: Optional[ToolExecution] = None
393
+ content: Optional[Any] = None
394
+ images: Optional[List[Image]] = None # Images produced by the tool call
395
+ videos: Optional[List[Video]] = None # Videos produced by the tool call
396
+ audio: Optional[List[Audio]] = None # Audio produced by the tool call
397
+
398
+
399
+ @dataclass
400
+ class ParserModelResponseStartedEvent(BaseAgentRunEvent):
401
+ event: str = RunEvent.parser_model_response_started.value
402
+
403
+
404
+ @dataclass
405
+ class ParserModelResponseCompletedEvent(BaseAgentRunEvent):
406
+ event: str = RunEvent.parser_model_response_completed.value
407
+
408
+
409
+ @dataclass
410
+ class OutputModelResponseStartedEvent(BaseAgentRunEvent):
411
+ event: str = RunEvent.output_model_response_started.value
412
+
413
+
414
+ @dataclass
415
+ class OutputModelResponseCompletedEvent(BaseAgentRunEvent):
416
+ event: str = RunEvent.output_model_response_completed.value
417
+
418
+
419
+ @dataclass
420
+ class CustomEvent(BaseAgentRunEvent):
421
+ event: str = RunEvent.custom_event.value
422
+
423
+ def __init__(self, **kwargs):
424
+ # Store arbitrary attributes directly on the instance
425
+ for key, value in kwargs.items():
426
+ setattr(self, key, value)
427
+
428
+
429
+ RunOutputEvent = Union[
430
+ RunStartedEvent,
431
+ RunContentEvent,
432
+ IntermediateRunContentEvent,
433
+ RunContentCompletedEvent,
434
+ RunCompletedEvent,
435
+ RunErrorEvent,
436
+ RunCancelledEvent,
437
+ RunPausedEvent,
438
+ RunContinuedEvent,
439
+ PreHookStartedEvent,
440
+ PreHookCompletedEvent,
441
+ PostHookStartedEvent,
442
+ PostHookCompletedEvent,
443
+ ReasoningStartedEvent,
444
+ ReasoningStepEvent,
445
+ ReasoningCompletedEvent,
446
+ MemoryUpdateStartedEvent,
447
+ MemoryUpdateCompletedEvent,
448
+ SessionSummaryStartedEvent,
449
+ SessionSummaryCompletedEvent,
450
+ ToolCallStartedEvent,
451
+ ToolCallCompletedEvent,
452
+ ParserModelResponseStartedEvent,
453
+ ParserModelResponseCompletedEvent,
454
+ OutputModelResponseStartedEvent,
455
+ OutputModelResponseCompletedEvent,
456
+ CustomEvent,
457
+ ]
458
+
459
+
460
+ # Map event string to dataclass
461
+ RUN_EVENT_TYPE_REGISTRY = {
462
+ RunEvent.run_started.value: RunStartedEvent,
463
+ RunEvent.run_content.value: RunContentEvent,
464
+ RunEvent.run_content_completed.value: RunContentCompletedEvent,
465
+ RunEvent.run_intermediate_content.value: IntermediateRunContentEvent,
466
+ RunEvent.run_completed.value: RunCompletedEvent,
467
+ RunEvent.run_error.value: RunErrorEvent,
468
+ RunEvent.run_cancelled.value: RunCancelledEvent,
469
+ RunEvent.run_paused.value: RunPausedEvent,
470
+ RunEvent.run_continued.value: RunContinuedEvent,
471
+ RunEvent.pre_hook_started.value: PreHookStartedEvent,
472
+ RunEvent.pre_hook_completed.value: PreHookCompletedEvent,
473
+ RunEvent.post_hook_started.value: PostHookStartedEvent,
474
+ RunEvent.post_hook_completed.value: PostHookCompletedEvent,
475
+ RunEvent.reasoning_started.value: ReasoningStartedEvent,
476
+ RunEvent.reasoning_step.value: ReasoningStepEvent,
477
+ RunEvent.reasoning_completed.value: ReasoningCompletedEvent,
478
+ RunEvent.memory_update_started.value: MemoryUpdateStartedEvent,
479
+ RunEvent.memory_update_completed.value: MemoryUpdateCompletedEvent,
480
+ RunEvent.session_summary_started.value: SessionSummaryStartedEvent,
481
+ RunEvent.session_summary_completed.value: SessionSummaryCompletedEvent,
482
+ RunEvent.tool_call_started.value: ToolCallStartedEvent,
483
+ RunEvent.tool_call_completed.value: ToolCallCompletedEvent,
484
+ RunEvent.parser_model_response_started.value: ParserModelResponseStartedEvent,
485
+ RunEvent.parser_model_response_completed.value: ParserModelResponseCompletedEvent,
486
+ RunEvent.output_model_response_started.value: OutputModelResponseStartedEvent,
487
+ RunEvent.output_model_response_completed.value: OutputModelResponseCompletedEvent,
488
+ RunEvent.custom_event.value: CustomEvent,
489
+ }
490
+
491
+
492
+ def run_output_event_from_dict(data: dict) -> BaseRunOutputEvent:
493
+ event_type = data.get("event", "")
494
+ cls = RUN_EVENT_TYPE_REGISTRY.get(event_type)
495
+ if not cls:
496
+ raise ValueError(f"Unknown event type: {event_type}")
497
+ return cls.from_dict(data) # type: ignore
498
+
499
+
500
+ @dataclass
501
+ class RunOutput:
502
+ """Response returned by Agent.run() or Workflow.run() functions"""
503
+
504
+ run_id: Optional[str] = None
505
+ agent_id: Optional[str] = None
506
+ agent_name: Optional[str] = None
507
+ session_id: Optional[str] = None
508
+ parent_run_id: Optional[str] = None
509
+ workflow_id: Optional[str] = None
510
+ user_id: Optional[str] = None
511
+
512
+ # Input media and messages from user
513
+ input: Optional[RunInput] = None
514
+
515
+ content: Optional[Any] = None
516
+ content_type: str = "str"
517
+
518
+ reasoning_content: Optional[str] = None
519
+ reasoning_steps: Optional[List[ReasoningStep]] = None
520
+ reasoning_messages: Optional[List[Message]] = None
521
+
522
+ model_provider_data: Optional[Dict[str, Any]] = None
523
+
524
+ model: Optional[str] = None
525
+ model_provider: Optional[str] = None
526
+ messages: Optional[List[Message]] = None
527
+ metrics: Optional[Metrics] = None
528
+ additional_input: Optional[List[Message]] = None
529
+
530
+ tools: Optional[List[ToolExecution]] = None
531
+
532
+ images: Optional[List[Image]] = None # Images attached to the response
533
+ videos: Optional[List[Video]] = None # Videos attached to the response
534
+ audio: Optional[List[Audio]] = None # Audio attached to the response
535
+ files: Optional[List[File]] = None # Files attached to the response
536
+ response_audio: Optional[Audio] = None # Model audio response
537
+
538
+ citations: Optional[Citations] = None
539
+ references: Optional[List[MessageReferences]] = None
540
+
541
+ metadata: Optional[Dict[str, Any]] = None
542
+ session_state: Optional[Dict[str, Any]] = None
543
+
544
+ created_at: int = field(default_factory=lambda: int(time()))
545
+
546
+ events: Optional[List[RunOutputEvent]] = None
547
+
548
+ status: RunStatus = RunStatus.running
549
+
550
+ # User control flow (HITL) requirements to continue a run when paused, in order of arrival
551
+ requirements: Optional[list[RunRequirement]] = None
552
+
553
+ # === FOREIGN KEY RELATIONSHIPS ===
554
+ # These fields establish relationships to parent workflow/step structures
555
+ # and should be treated as foreign keys for data integrity
556
+ workflow_step_id: Optional[str] = None # FK: Points to StepOutput.step_id
557
+
558
+ @property
559
+ def active_requirements(self) -> list[RunRequirement]:
560
+ if not self.requirements:
561
+ return []
562
+ return [requirement for requirement in self.requirements if not requirement.is_resolved()]
563
+
564
+ @property
565
+ def is_paused(self):
566
+ return self.status == RunStatus.paused
567
+
568
+ @property
569
+ def is_cancelled(self):
570
+ return self.status == RunStatus.cancelled
571
+
572
+ @property
573
+ def tools_requiring_confirmation(self):
574
+ return [t for t in self.tools if t.requires_confirmation] if self.tools else []
575
+
576
+ @property
577
+ def tools_requiring_user_input(self):
578
+ return [t for t in self.tools if t.requires_user_input] if self.tools else []
579
+
580
+ @property
581
+ def tools_awaiting_external_execution(self):
582
+ return [t for t in self.tools if t.external_execution_required] if self.tools else []
583
+
584
+ def to_dict(self) -> Dict[str, Any]:
585
+ _dict = {
586
+ k: v
587
+ for k, v in asdict(self).items()
588
+ if v is not None
589
+ and k
590
+ not in [
591
+ "messages",
592
+ "metrics",
593
+ "tools",
594
+ "metadata",
595
+ "images",
596
+ "videos",
597
+ "audio",
598
+ "files",
599
+ "response_audio",
600
+ "input",
601
+ "citations",
602
+ "events",
603
+ "additional_input",
604
+ "reasoning_steps",
605
+ "reasoning_messages",
606
+ "references",
607
+ "requirements",
608
+ ]
609
+ }
610
+
611
+ if self.metrics is not None:
612
+ _dict["metrics"] = self.metrics.to_dict() if isinstance(self.metrics, Metrics) else self.metrics
613
+
614
+ if self.events is not None:
615
+ _dict["events"] = [e.to_dict() for e in self.events]
616
+
617
+ if self.status is not None:
618
+ _dict["status"] = self.status.value if isinstance(self.status, RunStatus) else self.status
619
+
620
+ if self.messages is not None:
621
+ _dict["messages"] = [m.to_dict() for m in self.messages]
622
+
623
+ if self.metadata is not None:
624
+ _dict["metadata"] = self.metadata
625
+
626
+ if self.additional_input is not None:
627
+ _dict["additional_input"] = [m.to_dict() for m in self.additional_input]
628
+
629
+ if self.reasoning_messages is not None:
630
+ _dict["reasoning_messages"] = [m.to_dict() for m in self.reasoning_messages]
631
+
632
+ if self.reasoning_steps is not None:
633
+ _dict["reasoning_steps"] = [rs.model_dump() for rs in self.reasoning_steps]
634
+
635
+ if self.references is not None:
636
+ _dict["references"] = [r.model_dump() for r in self.references]
637
+
638
+ if self.images is not None:
639
+ _dict["images"] = []
640
+ for img in self.images:
641
+ if isinstance(img, Image):
642
+ _dict["images"].append(img.to_dict())
643
+ else:
644
+ _dict["images"].append(img)
645
+
646
+ if self.videos is not None:
647
+ _dict["videos"] = []
648
+ for vid in self.videos:
649
+ if isinstance(vid, Video):
650
+ _dict["videos"].append(vid.to_dict())
651
+ else:
652
+ _dict["videos"].append(vid)
653
+
654
+ if self.audio is not None:
655
+ _dict["audio"] = []
656
+ for aud in self.audio:
657
+ if isinstance(aud, Audio):
658
+ _dict["audio"].append(aud.to_dict())
659
+ else:
660
+ _dict["audio"].append(aud)
661
+
662
+ if self.files is not None:
663
+ _dict["files"] = []
664
+ for file in self.files:
665
+ if isinstance(file, File):
666
+ _dict["files"].append(file.to_dict())
667
+ else:
668
+ _dict["files"].append(file)
669
+
670
+ if self.response_audio is not None:
671
+ if isinstance(self.response_audio, Audio):
672
+ _dict["response_audio"] = self.response_audio.to_dict()
673
+ else:
674
+ _dict["response_audio"] = self.response_audio
675
+
676
+ if self.citations is not None:
677
+ if isinstance(self.citations, Citations):
678
+ _dict["citations"] = self.citations.model_dump(exclude_none=True)
679
+ else:
680
+ _dict["citations"] = self.citations
681
+
682
+ if self.content and isinstance(self.content, BaseModel):
683
+ _dict["content"] = self.content.model_dump(exclude_none=True, mode="json")
684
+
685
+ if self.tools is not None:
686
+ _dict["tools"] = []
687
+ for tool in self.tools:
688
+ if isinstance(tool, ToolExecution):
689
+ _dict["tools"].append(tool.to_dict())
690
+ else:
691
+ _dict["tools"].append(tool)
692
+
693
+ if self.requirements is not None:
694
+ _dict["requirements"] = [req.to_dict() if hasattr(req, "to_dict") else req for req in self.requirements]
695
+
696
+ if self.input is not None:
697
+ _dict["input"] = self.input.to_dict()
698
+
699
+ return _dict
700
+
701
+ def to_json(self, separators=(", ", ": "), indent: Optional[int] = 2) -> str:
702
+ import json
703
+
704
+ try:
705
+ _dict = self.to_dict()
706
+ except Exception:
707
+ logger.error("Failed to convert response to json", exc_info=True)
708
+ raise
709
+
710
+ if indent is None:
711
+ return json.dumps(_dict, separators=separators)
712
+ else:
713
+ return json.dumps(_dict, indent=indent, separators=separators)
714
+
715
+ @classmethod
716
+ def from_dict(cls, data: Dict[str, Any]) -> "RunOutput":
717
+ if "run" in data:
718
+ data = data.pop("run")
719
+
720
+ events = data.pop("events", None)
721
+ final_events = []
722
+ for event in events or []:
723
+ if "agent_id" in event:
724
+ event = run_output_event_from_dict(event)
725
+ else:
726
+ # Use the factory from response.py for agent events
727
+ from agno.run.team import team_run_output_event_from_dict
728
+
729
+ event = team_run_output_event_from_dict(event)
730
+ final_events.append(event)
731
+ events = final_events
732
+
733
+ messages = data.pop("messages", None)
734
+ messages = [Message.from_dict(message) for message in messages] if messages else None
735
+
736
+ citations = data.pop("citations", None)
737
+ citations = Citations.model_validate(citations) if citations else None
738
+
739
+ tools = data.pop("tools", [])
740
+ tools = [ToolExecution.from_dict(tool) for tool in tools] if tools else None
741
+
742
+ # Handle requirements
743
+ requirements_data = data.pop("requirements", None)
744
+ requirements: Optional[List[RunRequirement]] = None
745
+ if requirements_data is not None:
746
+ requirements_list: List[RunRequirement] = []
747
+ for item in requirements_data:
748
+ if isinstance(item, RunRequirement):
749
+ requirements_list.append(item)
750
+ elif isinstance(item, dict):
751
+ requirements_list.append(RunRequirement.from_dict(item))
752
+ requirements = requirements_list if requirements_list else None
753
+
754
+ images = reconstruct_images(data.pop("images", []))
755
+ videos = reconstruct_videos(data.pop("videos", []))
756
+ audio = reconstruct_audio_list(data.pop("audio", []))
757
+ files = reconstruct_files(data.pop("files", []))
758
+ response_audio = reconstruct_response_audio(data.pop("response_audio", None))
759
+
760
+ input_data = data.pop("input", None)
761
+ input_obj = None
762
+ if input_data:
763
+ input_obj = RunInput.from_dict(input_data)
764
+
765
+ metrics = data.pop("metrics", None)
766
+ if metrics:
767
+ metrics = Metrics(**metrics)
768
+
769
+ additional_input = data.pop("additional_input", None)
770
+
771
+ if additional_input is not None:
772
+ additional_input = [Message.from_dict(message) for message in additional_input]
773
+
774
+ reasoning_steps = data.pop("reasoning_steps", None)
775
+ if reasoning_steps is not None:
776
+ reasoning_steps = [ReasoningStep.model_validate(step) for step in reasoning_steps]
777
+
778
+ reasoning_messages = data.pop("reasoning_messages", None)
779
+ if reasoning_messages is not None:
780
+ reasoning_messages = [Message.from_dict(message) for message in reasoning_messages]
781
+
782
+ references = data.pop("references", None)
783
+ if references is not None:
784
+ references = [MessageReferences.model_validate(reference) for reference in references]
785
+
786
+ # Filter data to only include fields that are actually defined in the RunOutput dataclass
787
+ from dataclasses import fields
788
+
789
+ supported_fields = {f.name for f in fields(cls)}
790
+ filtered_data = {k: v for k, v in data.items() if k in supported_fields}
791
+
792
+ return cls(
793
+ messages=messages,
794
+ metrics=metrics,
795
+ citations=citations,
796
+ tools=tools,
797
+ images=images,
798
+ audio=audio,
799
+ videos=videos,
800
+ files=files,
801
+ response_audio=response_audio,
802
+ input=input_obj,
803
+ events=events,
804
+ additional_input=additional_input,
805
+ reasoning_steps=reasoning_steps,
806
+ reasoning_messages=reasoning_messages,
807
+ references=references,
808
+ requirements=requirements,
809
+ **filtered_data,
810
+ )
811
+
812
+ def get_content_as_string(self, **kwargs) -> str:
813
+ import json
814
+
815
+ from pydantic import BaseModel
816
+
817
+ if isinstance(self.content, str):
818
+ return self.content
819
+ elif isinstance(self.content, BaseModel):
820
+ return self.content.model_dump_json(exclude_none=True, **kwargs)
821
+ else:
822
+ return json.dumps(self.content, **kwargs)