agno 2.2.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 (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -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 +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -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 +1335 -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 +1160 -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 +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
agno/session/team.py ADDED
@@ -0,0 +1,392 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import asdict, dataclass
4
+ from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from agno.models.message import Message
9
+ from agno.run.agent import RunOutput, RunStatus
10
+ from agno.run.team import TeamRunOutput
11
+ from agno.session.summary import SessionSummary
12
+ from agno.utils.log import log_debug, log_warning
13
+
14
+
15
+ @dataclass
16
+ class TeamSession:
17
+ """Team Session that is stored in the database"""
18
+
19
+ # Session UUID
20
+ session_id: str
21
+
22
+ # ID of the team that this session is associated with
23
+ team_id: Optional[str] = None
24
+ # ID of the user interacting with this team
25
+ user_id: Optional[str] = None
26
+ # ID of the workflow that this session is associated with
27
+ workflow_id: Optional[str] = None
28
+
29
+ # Team Data: agent_id, name and model
30
+ team_data: Optional[Dict[str, Any]] = None
31
+ # Session Data: session_name, session_state, images, videos, audio
32
+ session_data: Optional[Dict[str, Any]] = None
33
+ # Metadata stored with this team
34
+ metadata: Optional[Dict[str, Any]] = None
35
+ # List of all runs in the session
36
+ runs: Optional[list[Union[TeamRunOutput, RunOutput]]] = None
37
+ # Summary of the session
38
+ summary: Optional[SessionSummary] = None
39
+
40
+ # The unix timestamp when this session was created
41
+ created_at: Optional[int] = None
42
+ # The unix timestamp when this session was last updated
43
+ updated_at: Optional[int] = None
44
+
45
+ def to_dict(self) -> Dict[str, Any]:
46
+ session_dict = asdict(self)
47
+
48
+ session_dict["runs"] = [run.to_dict() for run in self.runs] if self.runs else None
49
+ session_dict["summary"] = self.summary.to_dict() if self.summary else None
50
+
51
+ return session_dict
52
+
53
+ @classmethod
54
+ def from_dict(cls, data: Mapping[str, Any]) -> Optional[TeamSession]:
55
+ if data is None or data.get("session_id") is None:
56
+ log_warning("TeamSession is missing session_id")
57
+ return None
58
+
59
+ summary = data.get("summary")
60
+ if summary is not None and isinstance(summary, dict):
61
+ data["summary"] = SessionSummary.from_dict(data["summary"]) # type: ignore
62
+
63
+ runs = data.get("runs")
64
+ serialized_runs: List[Union[TeamRunOutput, RunOutput]] = []
65
+ if runs is not None and isinstance(runs[0], dict):
66
+ for run in runs:
67
+ if "agent_id" in run:
68
+ serialized_runs.append(RunOutput.from_dict(run))
69
+ elif "team_id" in run:
70
+ serialized_runs.append(TeamRunOutput.from_dict(run))
71
+
72
+ return cls(
73
+ session_id=data.get("session_id"), # type: ignore
74
+ team_id=data.get("team_id"),
75
+ user_id=data.get("user_id"),
76
+ workflow_id=data.get("workflow_id"),
77
+ team_data=data.get("team_data"),
78
+ session_data=data.get("session_data"),
79
+ metadata=data.get("metadata"),
80
+ created_at=data.get("created_at"),
81
+ updated_at=data.get("updated_at"),
82
+ runs=serialized_runs,
83
+ summary=data.get("summary"),
84
+ )
85
+
86
+ def get_run(self, run_id: str) -> Optional[Union[TeamRunOutput, RunOutput]]:
87
+ for run in self.runs or []:
88
+ if run.run_id == run_id:
89
+ return run
90
+ return None
91
+
92
+ def upsert_run(self, run_response: Union[TeamRunOutput, RunOutput]):
93
+ """Adds a RunOutput, together with some calculated data, to the runs list."""
94
+
95
+ messages = run_response.messages
96
+ if messages is None:
97
+ return
98
+
99
+ # Make message duration None
100
+ for m in messages or []:
101
+ if m.metrics is not None:
102
+ m.metrics.duration = None
103
+
104
+ if not self.runs:
105
+ self.runs = []
106
+
107
+ for i, existing_run in enumerate(self.runs or []):
108
+ if existing_run.run_id == run_response.run_id:
109
+ self.runs[i] = run_response
110
+ break
111
+ else:
112
+ self.runs.append(run_response)
113
+
114
+ log_debug("Added RunOutput to Team Session")
115
+
116
+ def _should_skip_message(
117
+ self, message: Message, skip_role: Optional[str] = None, skip_history_messages: bool = True
118
+ ) -> bool:
119
+ """Processes a message for history"""
120
+ # Skip messages that were tagged as history in previous runs
121
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
122
+ return True
123
+
124
+ # Skip messages with specified role
125
+ if skip_role and message.role == skip_role:
126
+ return True
127
+ return False
128
+
129
+ def get_messages_from_last_n_runs(
130
+ self,
131
+ agent_id: Optional[str] = None,
132
+ team_id: Optional[str] = None,
133
+ last_n: Optional[int] = None,
134
+ last_n_messages: Optional[int] = None,
135
+ skip_role: Optional[str] = None,
136
+ skip_status: Optional[List[RunStatus]] = None,
137
+ skip_history_messages: bool = True,
138
+ member_runs: bool = False,
139
+ ) -> List[Message]:
140
+ """Returns the messages from the last_n runs, excluding previously tagged history messages.
141
+ Args:
142
+
143
+ agent_id: The id of the agent to get the messages from.
144
+ team_id: The id of the team to get the messages from.
145
+ last_n: The number of runs to return from the end of the conversation. Defaults to all runs.
146
+ last_n_messages: The number of messages to return from the end of the conversation. Defaults to all messages.
147
+ skip_role: Skip messages with this role.
148
+ skip_status: Skip messages with this status.
149
+ skip_history_messages: Skip messages that were tagged as history in previous runs.
150
+ Returns:
151
+ A list of Messages from the specified runs, excluding history messages.
152
+ """
153
+ if not self.runs:
154
+ return []
155
+
156
+ if skip_status is None:
157
+ skip_status = [RunStatus.paused, RunStatus.cancelled, RunStatus.error]
158
+
159
+ session_runs = self.runs
160
+
161
+ # Filter by agent_id and team_id
162
+ if agent_id:
163
+ session_runs = [run for run in session_runs if hasattr(run, "agent_id") and run.agent_id == agent_id] # type: ignore
164
+ if team_id:
165
+ session_runs = [run for run in session_runs if hasattr(run, "team_id") and run.team_id == team_id] # type: ignore
166
+
167
+ if not member_runs:
168
+ # Filter for the top-level runs (main team runs or agent runs when sharing session)
169
+ session_runs = [run for run in session_runs if run.parent_run_id is None] # type: ignore
170
+ # Filter by status
171
+ session_runs = [run for run in session_runs if hasattr(run, "status") and run.status not in skip_status] # type: ignore
172
+
173
+ messages_from_history = []
174
+ system_message = None
175
+
176
+ # Filter by last_n_messages
177
+ if last_n_messages is not None:
178
+ for run_response in session_runs:
179
+ if not run_response or not run_response.messages:
180
+ continue
181
+
182
+ for message in run_response.messages or []:
183
+ if self._should_skip_message(message, skip_role, skip_history_messages):
184
+ continue
185
+
186
+ if message.role == "system":
187
+ # Only add the system message once
188
+ if system_message is None:
189
+ system_message = message
190
+ else:
191
+ messages_from_history.append(message)
192
+
193
+ if system_message:
194
+ messages_from_history = [system_message] + messages_from_history[
195
+ -(last_n_messages - 1) :
196
+ ] # Grab one less message then add the system message
197
+ else:
198
+ messages_from_history = messages_from_history[-last_n_messages:]
199
+
200
+ # Remove tool result messages that don't have an associated assistant message with tool calls
201
+ while len(messages_from_history) > 0 and messages_from_history[0].role == "tool":
202
+ messages_from_history.pop(0)
203
+ else:
204
+ # Filter by last_n runs
205
+ runs_to_process = session_runs[-last_n:] if last_n is not None else session_runs
206
+
207
+ for run_response in runs_to_process:
208
+ if not (run_response and run_response.messages):
209
+ continue
210
+
211
+ for message in run_response.messages or []:
212
+ if self._should_skip_message(message, skip_role, skip_history_messages):
213
+ continue
214
+
215
+ if message.role == "system":
216
+ # Only add the system message once
217
+ if system_message is None:
218
+ system_message = message
219
+ messages_from_history.append(system_message)
220
+ else:
221
+ messages_from_history.append(message)
222
+
223
+ log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
224
+ return messages_from_history
225
+
226
+ def get_tool_calls(self, num_calls: Optional[int] = None) -> List[Dict[str, Any]]:
227
+ """Returns a list of tool calls from the messages"""
228
+
229
+ tool_calls = []
230
+ session_runs = self.runs
231
+ if session_runs is None:
232
+ return []
233
+
234
+ for run_response in session_runs[::-1]:
235
+ if run_response and run_response.messages:
236
+ for message in run_response.messages or []:
237
+ if message.tool_calls:
238
+ for tool_call in message.tool_calls:
239
+ tool_calls.append(tool_call)
240
+ if num_calls and len(tool_calls) >= num_calls:
241
+ return tool_calls
242
+ return tool_calls
243
+
244
+ def get_messages_for_session(
245
+ self,
246
+ user_role: str = "user",
247
+ assistant_role: Optional[List[str]] = None,
248
+ skip_history_messages: bool = True,
249
+ ) -> List[Message]:
250
+ """Returns a list of messages for the session that iterate through user message and assistant response."""
251
+
252
+ if assistant_role is None:
253
+ # TODO: Check if we still need CHATBOT as a role
254
+ assistant_role = ["assistant", "model", "CHATBOT"]
255
+
256
+ final_messages: List[Message] = []
257
+ session_runs = self.runs
258
+ if session_runs is None:
259
+ return []
260
+
261
+ for run_response in session_runs:
262
+ if run_response and run_response.messages:
263
+ user_message_from_run = None
264
+ assistant_message_from_run = None
265
+
266
+ # Start from the beginning to look for the user message
267
+ for message in run_response.messages or []:
268
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
269
+ continue
270
+ if message.role == user_role:
271
+ user_message_from_run = message
272
+ break
273
+
274
+ # Start from the end to look for the assistant response
275
+ for message in run_response.messages[::-1]:
276
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
277
+ continue
278
+ if message.role in assistant_role:
279
+ assistant_message_from_run = message
280
+ break
281
+
282
+ if user_message_from_run and assistant_message_from_run:
283
+ final_messages.append(user_message_from_run)
284
+ final_messages.append(assistant_message_from_run)
285
+ return final_messages
286
+
287
+ def get_team_history(self, num_runs: Optional[int] = None) -> List[Tuple[str, str]]:
288
+ """Get team history as structured data (input, response pairs) -> This is the history of the team leader, not the members.
289
+
290
+ Args:
291
+ num_runs: Number of recent runs to include. If None, returns all available history.
292
+ """
293
+ if not self.runs:
294
+ return []
295
+
296
+ from agno.run.base import RunStatus
297
+
298
+ # Get completed runs only (exclude current/pending run)
299
+ completed_runs = [run for run in self.runs if run.status == RunStatus.completed and run.parent_run_id is None]
300
+
301
+ if num_runs is not None and len(completed_runs) > num_runs:
302
+ recent_runs = completed_runs[-num_runs:]
303
+ else:
304
+ recent_runs = completed_runs
305
+
306
+ if not recent_runs:
307
+ return []
308
+
309
+ # Return structured data as list of (input, response) tuples
310
+ history_data = []
311
+ for run in recent_runs:
312
+ # Get input
313
+ input_str = ""
314
+ if run.input:
315
+ input_str = run.input.input_content_string()
316
+
317
+ # Get response
318
+ response_str = ""
319
+ if run.content:
320
+ response_str = (
321
+ run.content.model_dump_json(indent=2, exclude_none=True)
322
+ if isinstance(run.content, BaseModel)
323
+ else str(run.content)
324
+ )
325
+
326
+ history_data.append((input_str, response_str))
327
+
328
+ return history_data
329
+
330
+ def get_team_history_context(self, num_runs: Optional[int] = None) -> Optional[str]:
331
+ """Get formatted team history context for steps
332
+
333
+ Args:
334
+ num_runs: Number of recent runs to include. If None, returns all available history.
335
+ """
336
+ history_data = self.get_team_history(num_runs)
337
+
338
+ if not history_data:
339
+ return None
340
+
341
+ # Format as team history context using the structured data
342
+ context_parts = ["<team_history_context>"]
343
+
344
+ for i, (input_str, response_str) in enumerate(history_data, 1):
345
+ context_parts.append(f"[run-{i}]")
346
+
347
+ if input_str:
348
+ context_parts.append(f"input: {input_str}")
349
+ if response_str:
350
+ context_parts.append(f"response: {response_str}")
351
+
352
+ context_parts.append("") # Empty line between runs
353
+
354
+ context_parts.append("</team_history_context>")
355
+ context_parts.append("") # Empty line before current input
356
+
357
+ return "\n".join(context_parts)
358
+
359
+ def get_session_summary(self) -> Optional[SessionSummary]:
360
+ """Get the session summary for the session"""
361
+
362
+ if self.summary is None:
363
+ return None
364
+
365
+ return self.summary # type: ignore
366
+
367
+ # Chat History functions
368
+ def get_chat_history(
369
+ self, skip_history_messages: bool = True, skip_roles: Optional[List[str]] = None
370
+ ) -> List[Message]:
371
+ """
372
+ Get the chat history for the session.
373
+ This is all messages across all runs for the team leader.
374
+ """
375
+
376
+ messages = []
377
+ if self.runs is None:
378
+ return []
379
+
380
+ for run in self.runs or []:
381
+ if run.parent_run_id is not None:
382
+ continue
383
+
384
+ if run.messages is not None:
385
+ for msg in run.messages or []:
386
+ if skip_history_messages and msg.from_history:
387
+ continue
388
+ if skip_roles and msg.role in skip_roles:
389
+ continue
390
+ messages.append(msg)
391
+
392
+ return messages
@@ -0,0 +1,205 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from dataclasses import dataclass
5
+ from typing import Any, Dict, List, Mapping, Optional, Tuple
6
+
7
+ from agno.run.workflow import WorkflowRunOutput
8
+ from agno.utils.log import logger
9
+
10
+
11
+ @dataclass
12
+ class WorkflowSession:
13
+ """Workflow Session V2 for pipeline-based workflows"""
14
+
15
+ # Session UUID - this is the workflow_session_id that gets set on agents/teams
16
+ session_id: str
17
+ # ID of the user interacting with this workflow
18
+ user_id: Optional[str] = None
19
+
20
+ # ID of the workflow that this session is associated with
21
+ workflow_id: Optional[str] = None
22
+ # Workflow name
23
+ workflow_name: Optional[str] = None
24
+
25
+ # Workflow runs - stores WorkflowRunOutput objects in memory
26
+ runs: Optional[List[WorkflowRunOutput]] = None
27
+
28
+ # Session Data: session_name, session_state, images, videos, audio
29
+ session_data: Optional[Dict[str, Any]] = None
30
+ # Workflow configuration and metadata
31
+ workflow_data: Optional[Dict[str, Any]] = None
32
+ # Metadata stored with this workflow session
33
+ metadata: Optional[Dict[str, Any]] = None
34
+
35
+ # The unix timestamp when this session was created
36
+ created_at: Optional[int] = None
37
+ # The unix timestamp when this session was last updated
38
+ updated_at: Optional[int] = None
39
+
40
+ def __post_init__(self):
41
+ if self.runs is None:
42
+ self.runs = []
43
+
44
+ # Ensure session_data, workflow_data, and metadata are dictionaries, not None
45
+ if self.session_data is None:
46
+ self.session_data = {}
47
+ if self.workflow_data is None:
48
+ self.workflow_data = {}
49
+ if self.metadata is None:
50
+ self.metadata = {}
51
+
52
+ # Set timestamps if they're not already set
53
+ current_time = int(time.time())
54
+ if self.created_at is None:
55
+ self.created_at = current_time
56
+ if self.updated_at is None:
57
+ self.updated_at = current_time
58
+
59
+ def get_run(self, run_id: str) -> Optional[WorkflowRunOutput]:
60
+ for run in self.runs or []:
61
+ if run.run_id == run_id:
62
+ return run
63
+ return None
64
+
65
+ def upsert_run(self, run: WorkflowRunOutput) -> None:
66
+ """Add or update a workflow run (upsert behavior)"""
67
+ if self.runs is None:
68
+ self.runs = []
69
+
70
+ # Find existing run and update it, or append new one
71
+ for i, existing_run in enumerate(self.runs):
72
+ if existing_run.run_id == run.run_id:
73
+ self.runs[i] = run
74
+ break
75
+ else:
76
+ self.runs.append(run)
77
+
78
+ def get_workflow_history(self, num_runs: Optional[int] = None) -> List[Tuple[str, str]]:
79
+ """Get workflow history as structured data (input, response pairs)
80
+
81
+ Args:
82
+ num_runs: Number of recent runs to include. If None, returns all available history.
83
+ """
84
+ if not self.runs:
85
+ return []
86
+
87
+ from agno.run.base import RunStatus
88
+
89
+ # Get completed runs only (exclude current/pending run)
90
+ completed_runs = [run for run in self.runs if run.status == RunStatus.completed]
91
+
92
+ if num_runs is not None and len(completed_runs) > num_runs:
93
+ recent_runs = completed_runs[-num_runs:]
94
+ else:
95
+ recent_runs = completed_runs
96
+
97
+ if not recent_runs:
98
+ return []
99
+
100
+ # Return structured data as list of (input, response) tuples
101
+ history_data = []
102
+ for run in recent_runs:
103
+ # Get input
104
+ input_str = ""
105
+ if run.input:
106
+ input_str = str(run.input) if not isinstance(run.input, str) else run.input
107
+
108
+ # Get response
109
+ response_str = ""
110
+ if run.content:
111
+ response_str = str(run.content) if not isinstance(run.content, str) else run.content
112
+
113
+ history_data.append((input_str, response_str))
114
+
115
+ return history_data
116
+
117
+ def get_workflow_history_context(self, num_runs: Optional[int] = None) -> Optional[str]:
118
+ """Get formatted workflow history context for steps
119
+
120
+ Args:
121
+ num_runs: Number of recent runs to include. If None, returns all available history.
122
+ """
123
+ history_data = self.get_workflow_history(num_runs)
124
+
125
+ if not history_data:
126
+ return None
127
+
128
+ # Format as workflow context using the structured data
129
+ context_parts = ["<workflow_history_context>"]
130
+
131
+ for i, (input_str, response_str) in enumerate(history_data, 1):
132
+ context_parts.append(f"[Workflow Run-{i}]")
133
+
134
+ if input_str:
135
+ context_parts.append(f"User input: {input_str}")
136
+ if response_str:
137
+ context_parts.append(f"Workflow output: {response_str}")
138
+
139
+ context_parts.append("") # Empty line between runs
140
+
141
+ context_parts.append("</workflow_history_context>")
142
+ context_parts.append("") # Empty line before current input
143
+
144
+ return "\n".join(context_parts)
145
+
146
+ def to_dict(self) -> Dict[str, Any]:
147
+ """Convert to dictionary for storage, serializing runs to dicts"""
148
+
149
+ runs_data = None
150
+ if self.runs:
151
+ runs_data = []
152
+ for run in self.runs:
153
+ try:
154
+ runs_data.append(run.to_dict())
155
+ except Exception as e:
156
+ raise ValueError(f"Serialization failed: {str(e)}")
157
+
158
+ return {
159
+ "session_id": self.session_id,
160
+ "user_id": self.user_id,
161
+ "workflow_id": self.workflow_id,
162
+ "workflow_name": self.workflow_name,
163
+ "runs": runs_data,
164
+ "session_data": self.session_data,
165
+ "workflow_data": self.workflow_data,
166
+ "metadata": self.metadata,
167
+ "created_at": self.created_at,
168
+ "updated_at": self.updated_at,
169
+ }
170
+
171
+ @classmethod
172
+ def from_dict(cls, data: Mapping[str, Any]) -> Optional[WorkflowSession]:
173
+ """Create WorkflowSession from dictionary, deserializing runs from dicts"""
174
+ if data is None or data.get("session_id") is None:
175
+ logger.warning("WorkflowSession is missing session_id")
176
+ return None
177
+
178
+ # Deserialize runs from dictionaries back to WorkflowRunOutput objects
179
+ runs_data = data.get("runs")
180
+ runs: Optional[List[WorkflowRunOutput]] = None
181
+
182
+ if runs_data is not None:
183
+ runs = []
184
+ for run_item in runs_data:
185
+ if isinstance(run_item, WorkflowRunOutput):
186
+ # Already a WorkflowRunOutput object (from deserialize_session_json_fields)
187
+ runs.append(run_item)
188
+ elif isinstance(run_item, dict):
189
+ # Still a dictionary, needs to be converted
190
+ runs.append(WorkflowRunOutput.from_dict(run_item))
191
+ else:
192
+ logger.warning(f"Unexpected run item type: {type(run_item)}")
193
+
194
+ return cls(
195
+ session_id=data.get("session_id"), # type: ignore
196
+ user_id=data.get("user_id"),
197
+ workflow_id=data.get("workflow_id"),
198
+ workflow_name=data.get("workflow_name"),
199
+ runs=runs,
200
+ session_data=data.get("session_data"),
201
+ workflow_data=data.get("workflow_data"),
202
+ metadata=data.get("metadata"),
203
+ created_at=data.get("created_at"),
204
+ updated_at=data.get("updated_at"),
205
+ )
agno/team/__init__.py ADDED
@@ -0,0 +1,37 @@
1
+ from agno.run.team import (
2
+ MemoryUpdateCompletedEvent,
3
+ MemoryUpdateStartedEvent,
4
+ ReasoningCompletedEvent,
5
+ ReasoningStartedEvent,
6
+ ReasoningStepEvent,
7
+ RunCancelledEvent,
8
+ RunCompletedEvent,
9
+ RunContentEvent,
10
+ RunErrorEvent,
11
+ RunStartedEvent,
12
+ TeamRunEvent,
13
+ TeamRunOutput,
14
+ TeamRunOutputEvent,
15
+ ToolCallCompletedEvent,
16
+ ToolCallStartedEvent,
17
+ )
18
+ from agno.team.team import Team
19
+
20
+ __all__ = [
21
+ "Team",
22
+ "TeamRunOutput",
23
+ "TeamRunOutputEvent",
24
+ "TeamRunEvent",
25
+ "RunContentEvent",
26
+ "RunCancelledEvent",
27
+ "RunErrorEvent",
28
+ "RunStartedEvent",
29
+ "RunCompletedEvent",
30
+ "MemoryUpdateStartedEvent",
31
+ "MemoryUpdateCompletedEvent",
32
+ "ReasoningStartedEvent",
33
+ "ReasoningStepEvent",
34
+ "ReasoningCompletedEvent",
35
+ "ToolCallStartedEvent",
36
+ "ToolCallCompletedEvent",
37
+ ]