agno 1.8.2__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +393 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +850 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +410 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +178 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +3260 -4824
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +43 -23
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +20 -17
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,779 @@
1
+ import json
2
+ from collections.abc import Set
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union, cast, get_args
4
+
5
+ from pydantic import BaseModel
6
+ from rich.console import Group
7
+ from rich.json import JSON
8
+ from rich.live import Live
9
+ from rich.markdown import Markdown
10
+ from rich.status import Status
11
+ from rich.text import Text
12
+
13
+ from agno.media import Audio, File, Image, Video
14
+ from agno.models.message import Message
15
+ from agno.reasoning.step import ReasoningStep
16
+ from agno.run.agent import RunEvent, RunOutput, RunOutputEvent, RunPausedEvent
17
+ from agno.utils.log import log_warning
18
+ from agno.utils.message import get_text_from_message
19
+ from agno.utils.response import create_panel, create_paused_run_output_panel, escape_markdown_tags, format_tool_calls
20
+ from agno.utils.timer import Timer
21
+
22
+ if TYPE_CHECKING:
23
+ from agno.agent.agent import Agent
24
+
25
+
26
+ def print_response_stream(
27
+ agent: "Agent",
28
+ input: Union[List, Dict, str, Message, BaseModel, List[Message]],
29
+ session_id: Optional[str] = None,
30
+ session_state: Optional[Dict[str, Any]] = None,
31
+ user_id: Optional[str] = None,
32
+ audio: Optional[Sequence[Audio]] = None,
33
+ images: Optional[Sequence[Image]] = None,
34
+ videos: Optional[Sequence[Video]] = None,
35
+ files: Optional[Sequence[File]] = None,
36
+ stream_intermediate_steps: bool = False,
37
+ knowledge_filters: Optional[Dict[str, Any]] = None,
38
+ debug_mode: Optional[bool] = None,
39
+ markdown: bool = False,
40
+ show_message: bool = True,
41
+ show_reasoning: bool = True,
42
+ show_full_reasoning: bool = False,
43
+ tags_to_include_in_markdown: Set[str] = {"think", "thinking"},
44
+ console: Optional[Any] = None,
45
+ add_history_to_context: Optional[bool] = None,
46
+ dependencies: Optional[Dict[str, Any]] = None,
47
+ metadata: Optional[Dict[str, Any]] = None,
48
+ **kwargs: Any,
49
+ ):
50
+ _response_content: str = ""
51
+ _response_reasoning_content: str = ""
52
+ response_content_batch: Union[str, JSON, Markdown] = ""
53
+ reasoning_steps: List[ReasoningStep] = []
54
+ accumulated_tool_calls: List = []
55
+
56
+ with Live(console=console) as live_log:
57
+ status = Status("Thinking...", spinner="aesthetic", speed=0.4, refresh_per_second=10)
58
+ live_log.update(status)
59
+ response_timer = Timer()
60
+ response_timer.start()
61
+ # Flag which indicates if the panels should be rendered
62
+ render = False
63
+ # Panels to be rendered
64
+ panels = [status]
65
+ # First render the message panel if the message is not None
66
+ if input and show_message:
67
+ render = True
68
+ # Convert message to a panel
69
+ message_content = get_text_from_message(input)
70
+ message_panel = create_panel(
71
+ content=Text(message_content, style="green"),
72
+ title="Message",
73
+ border_style="cyan",
74
+ )
75
+ panels.append(message_panel)
76
+ if render:
77
+ live_log.update(Group(*panels))
78
+
79
+ for response_event in agent.run(
80
+ input=input,
81
+ session_id=session_id,
82
+ session_state=session_state,
83
+ user_id=user_id,
84
+ audio=audio,
85
+ images=images,
86
+ videos=videos,
87
+ files=files,
88
+ stream=True,
89
+ stream_intermediate_steps=stream_intermediate_steps,
90
+ knowledge_filters=knowledge_filters,
91
+ debug_mode=debug_mode,
92
+ add_history_to_context=add_history_to_context,
93
+ dependencies=dependencies,
94
+ metadata=metadata,
95
+ **kwargs,
96
+ ):
97
+ if isinstance(response_event, tuple(get_args(RunOutputEvent))):
98
+ if response_event.is_paused: # type: ignore
99
+ response_event = cast(RunPausedEvent, response_event) # type: ignore
100
+ response_panel = create_paused_run_output_panel(response_event) # type: ignore
101
+ panels.append(response_panel)
102
+ live_log.update(Group(*panels))
103
+ return
104
+
105
+ if (
106
+ response_event.event == RunEvent.tool_call_started # type: ignore
107
+ and hasattr(response_event, "tool")
108
+ and response_event.tool is not None
109
+ ):
110
+ accumulated_tool_calls.append(response_event.tool)
111
+
112
+ if response_event.event == RunEvent.run_content: # type: ignore
113
+ if hasattr(response_event, "content"):
114
+ if isinstance(response_event.content, str):
115
+ _response_content += response_event.content
116
+ elif agent.output_schema is not None and isinstance(response_event.content, BaseModel):
117
+ try:
118
+ response_content_batch = JSON( # type: ignore
119
+ response_event.content.model_dump_json(exclude_none=True), indent=2
120
+ )
121
+ except Exception as e:
122
+ log_warning(f"Failed to convert response to JSON: {e}")
123
+ else:
124
+ try:
125
+ response_content_batch = JSON(json.dumps(response_event.content), indent=4)
126
+ except Exception as e:
127
+ log_warning(f"Failed to convert response to JSON: {e}")
128
+ if hasattr(response_event, "reasoning_content") and response_event.reasoning_content is not None: # type: ignore
129
+ _response_reasoning_content += response_event.reasoning_content # type: ignore
130
+ if hasattr(response_event, "reasoning_steps") and response_event.reasoning_steps is not None: # type: ignore
131
+ reasoning_steps = response_event.reasoning_steps # type: ignore
132
+
133
+ # Escape special tags before markdown conversion
134
+ if markdown:
135
+ escaped_content = escape_markdown_tags(_response_content, tags_to_include_in_markdown) # type: ignore
136
+ response_content_batch = Markdown(escaped_content)
137
+
138
+ response_content_stream: str = _response_content
139
+
140
+ # Check if we have any response content to display
141
+ if response_content_stream and not markdown:
142
+ response_content = response_content_stream
143
+ else:
144
+ response_content = response_content_batch # type: ignore
145
+
146
+ # Sanitize empty Markdown content
147
+ if isinstance(response_content, Markdown):
148
+ if not (response_content.markup and response_content.markup.strip()):
149
+ response_content = None # type: ignore
150
+
151
+ panels = [status]
152
+ if show_message:
153
+ # Convert message to a panel
154
+ message_content = get_text_from_message(input)
155
+ message_panel = create_panel(
156
+ content=Text(message_content, style="green"),
157
+ title="Message",
158
+ border_style="cyan",
159
+ )
160
+ panels.append(message_panel)
161
+
162
+ additional_panels = build_panels_stream(
163
+ response_content=response_content,
164
+ response_event=response_event, # type: ignore
165
+ response_timer=response_timer,
166
+ response_reasoning_content_buffer=_response_reasoning_content,
167
+ reasoning_steps=reasoning_steps,
168
+ show_reasoning=show_reasoning,
169
+ show_full_reasoning=show_full_reasoning,
170
+ accumulated_tool_calls=accumulated_tool_calls,
171
+ )
172
+ panels.extend(additional_panels)
173
+ if panels:
174
+ live_log.update(Group(*panels))
175
+
176
+ if agent.memory_manager is not None and agent.memory_manager.memories_updated:
177
+ memory_panel = create_panel(
178
+ content=Text("Memories updated"),
179
+ title="Memories",
180
+ border_style="green",
181
+ )
182
+ panels.append(memory_panel)
183
+ live_log.update(Group(*panels))
184
+ agent.memory_manager.memories_updated = False
185
+
186
+ if agent.session_summary_manager is not None and agent.session_summary_manager.summaries_updated:
187
+ summary_panel = create_panel(
188
+ content=Text("Session summary updated"),
189
+ title="Session Summary",
190
+ border_style="green",
191
+ )
192
+ panels.append(summary_panel)
193
+ live_log.update(Group(*panels))
194
+ agent.session_summary_manager.summaries_updated = False
195
+
196
+ response_timer.stop()
197
+
198
+ # Final update to remove the "Thinking..." status
199
+ panels = [p for p in panels if not isinstance(p, Status)]
200
+ live_log.update(Group(*panels))
201
+
202
+
203
+ async def aprint_response_stream(
204
+ agent: "Agent",
205
+ input: Union[List, Dict, str, Message, BaseModel, List[Message]],
206
+ session_id: Optional[str] = None,
207
+ session_state: Optional[Dict[str, Any]] = None,
208
+ user_id: Optional[str] = None,
209
+ audio: Optional[Sequence[Audio]] = None,
210
+ images: Optional[Sequence[Image]] = None,
211
+ videos: Optional[Sequence[Video]] = None,
212
+ files: Optional[Sequence[File]] = None,
213
+ stream_intermediate_steps: bool = False,
214
+ knowledge_filters: Optional[Dict[str, Any]] = None,
215
+ debug_mode: Optional[bool] = None,
216
+ markdown: bool = False,
217
+ show_message: bool = True,
218
+ show_reasoning: bool = True,
219
+ show_full_reasoning: bool = False,
220
+ tags_to_include_in_markdown: Set[str] = {"think", "thinking"},
221
+ console: Optional[Any] = None,
222
+ add_history_to_context: Optional[bool] = None,
223
+ dependencies: Optional[Dict[str, Any]] = None,
224
+ metadata: Optional[Dict[str, Any]] = None,
225
+ **kwargs: Any,
226
+ ):
227
+ _response_content: str = ""
228
+ _response_reasoning_content: str = ""
229
+ reasoning_steps: List[ReasoningStep] = []
230
+ response_content_batch: Union[str, JSON, Markdown] = ""
231
+ accumulated_tool_calls: List = []
232
+
233
+ with Live(console=console) as live_log:
234
+ status = Status("Thinking...", spinner="aesthetic", speed=0.4, refresh_per_second=10)
235
+ live_log.update(status)
236
+ response_timer = Timer()
237
+ response_timer.start()
238
+ # Flag which indicates if the panels should be rendered
239
+ render = False
240
+ # Panels to be rendered
241
+ panels = [status]
242
+ # First render the message panel if the message is not None
243
+ if input and show_message:
244
+ render = True
245
+ # Convert message to a panel
246
+ message_content = get_text_from_message(input)
247
+ message_panel = create_panel(
248
+ content=Text(message_content, style="green"),
249
+ title="Message",
250
+ border_style="cyan",
251
+ )
252
+ panels.append(message_panel)
253
+ if render:
254
+ live_log.update(Group(*panels))
255
+
256
+ result = agent.arun(
257
+ input=input,
258
+ session_id=session_id,
259
+ session_state=session_state,
260
+ user_id=user_id,
261
+ audio=audio,
262
+ images=images,
263
+ videos=videos,
264
+ files=files,
265
+ stream=True,
266
+ stream_intermediate_steps=stream_intermediate_steps,
267
+ knowledge_filters=knowledge_filters,
268
+ debug_mode=debug_mode,
269
+ add_history_to_context=add_history_to_context,
270
+ dependencies=dependencies,
271
+ metadata=metadata,
272
+ **kwargs,
273
+ )
274
+
275
+ async for resp in result: # type: ignore
276
+ if isinstance(resp, tuple(get_args(RunOutputEvent))):
277
+ if resp.is_paused:
278
+ response_panel = create_paused_run_output_panel(resp) # type: ignore
279
+ panels.append(response_panel)
280
+ live_log.update(Group(*panels))
281
+ break
282
+
283
+ if (
284
+ resp.event == RunEvent.tool_call_started # type: ignore
285
+ and hasattr(resp, "tool")
286
+ and resp.tool is not None
287
+ ):
288
+ accumulated_tool_calls.append(resp.tool)
289
+
290
+ if resp.event == RunEvent.run_content: # type: ignore
291
+ if isinstance(resp.content, str):
292
+ _response_content += resp.content
293
+ elif agent.output_schema is not None and isinstance(resp.content, BaseModel):
294
+ try:
295
+ response_content_batch = JSON(resp.content.model_dump_json(exclude_none=True), indent=2) # type: ignore
296
+ except Exception as e:
297
+ log_warning(f"Failed to convert response to JSON: {e}")
298
+ else:
299
+ try:
300
+ response_content_batch = JSON(json.dumps(resp.content), indent=4)
301
+ except Exception as e:
302
+ log_warning(f"Failed to convert response to JSON: {e}")
303
+ if resp.reasoning_content is not None: # type: ignore
304
+ _response_reasoning_content += resp.reasoning_content # type: ignore
305
+
306
+ if hasattr(resp, "reasoning_steps") and resp.reasoning_steps is not None: # type: ignore
307
+ reasoning_steps = resp.reasoning_steps # type: ignore
308
+
309
+ response_content_stream: str = _response_content
310
+
311
+ # Escape special tags before markdown conversion
312
+ if markdown:
313
+ escaped_content = escape_markdown_tags(_response_content, tags_to_include_in_markdown) # type: ignore
314
+ response_content_batch = Markdown(escaped_content)
315
+
316
+ # Check if we have any response content to display
317
+ if response_content_stream and not markdown:
318
+ response_content = response_content_stream
319
+ else:
320
+ response_content = response_content_batch # type: ignore
321
+
322
+ # Sanitize empty Markdown content
323
+ if isinstance(response_content, Markdown):
324
+ if not (response_content.markup and response_content.markup.strip()):
325
+ response_content = None # type: ignore
326
+
327
+ panels = [status]
328
+
329
+ if input and show_message:
330
+ render = True
331
+ # Convert message to a panel
332
+ message_content = get_text_from_message(input)
333
+ message_panel = create_panel(
334
+ content=Text(message_content, style="green"),
335
+ title="Message",
336
+ border_style="cyan",
337
+ )
338
+ panels.append(message_panel)
339
+
340
+ additional_panels = build_panels_stream(
341
+ response_content=response_content,
342
+ response_event=resp, # type: ignore
343
+ response_timer=response_timer,
344
+ response_reasoning_content_buffer=_response_reasoning_content,
345
+ reasoning_steps=reasoning_steps,
346
+ show_reasoning=show_reasoning,
347
+ show_full_reasoning=show_full_reasoning,
348
+ accumulated_tool_calls=accumulated_tool_calls,
349
+ )
350
+ panels.extend(additional_panels)
351
+ if panels:
352
+ live_log.update(Group(*panels))
353
+
354
+ if agent.memory_manager is not None and agent.memory_manager.memories_updated:
355
+ memory_panel = create_panel(
356
+ content=Text("Memories updated"),
357
+ title="Memories",
358
+ border_style="green",
359
+ )
360
+ panels.append(memory_panel)
361
+ live_log.update(Group(*panels))
362
+ agent.memory_manager.memories_updated = False
363
+
364
+ if agent.session_summary_manager is not None and agent.session_summary_manager.summaries_updated:
365
+ summary_panel = create_panel(
366
+ content=Text("Session summary updated"),
367
+ title="Session Summary",
368
+ border_style="green",
369
+ )
370
+ panels.append(summary_panel)
371
+ live_log.update(Group(*panels))
372
+ agent.session_summary_manager.summaries_updated = False
373
+
374
+ response_timer.stop()
375
+
376
+ # Final update to remove the "Thinking..." status
377
+ panels = [p for p in panels if not isinstance(p, Status)]
378
+ live_log.update(Group(*panels))
379
+
380
+
381
+ def build_panels_stream(
382
+ response_content: Union[str, JSON, Markdown],
383
+ response_event: RunOutputEvent,
384
+ response_timer: Timer,
385
+ response_reasoning_content_buffer: str,
386
+ reasoning_steps: List[ReasoningStep],
387
+ show_reasoning: bool = True,
388
+ show_full_reasoning: bool = False,
389
+ accumulated_tool_calls: Optional[List] = None,
390
+ ):
391
+ panels = []
392
+
393
+ if len(reasoning_steps) > 0 and show_reasoning:
394
+ # Create panels for reasoning steps
395
+ for i, step in enumerate(reasoning_steps, 1):
396
+ # Build step content
397
+ step_content = Text.assemble()
398
+ if step.title is not None:
399
+ step_content.append(f"{step.title}\n", "bold")
400
+ if step.action is not None:
401
+ step_content.append(Text.from_markup(f"[bold]Action:[/bold] {step.action}\n", style="dim"))
402
+ if step.result is not None:
403
+ step_content.append(Text.from_markup(step.result, style="dim"))
404
+
405
+ if show_full_reasoning:
406
+ # Add detailed reasoning information if available
407
+ if step.reasoning is not None:
408
+ step_content.append(Text.from_markup(f"\n[bold]Reasoning:[/bold] {step.reasoning}", style="dim"))
409
+ if step.confidence is not None:
410
+ step_content.append(Text.from_markup(f"\n[bold]Confidence:[/bold] {step.confidence}", style="dim"))
411
+ reasoning_panel = create_panel(content=step_content, title=f"Reasoning step {i}", border_style="green")
412
+ panels.append(reasoning_panel)
413
+
414
+ if len(response_reasoning_content_buffer) > 0:
415
+ # Create panel for thinking
416
+ thinking_panel = create_panel(
417
+ content=Text(response_reasoning_content_buffer),
418
+ title=f"Thinking ({response_timer.elapsed:.1f}s)",
419
+ border_style="green",
420
+ )
421
+ panels.append(thinking_panel)
422
+
423
+ if accumulated_tool_calls: # Use accumulated tool calls instead of just current event
424
+ # Create bullet points for each tool call
425
+ tool_calls_content = Text()
426
+ formatted_tool_calls = format_tool_calls(accumulated_tool_calls)
427
+ for formatted_tool_call in formatted_tool_calls:
428
+ tool_calls_content.append(f"• {formatted_tool_call}\n")
429
+
430
+ tool_calls_panel = create_panel(
431
+ content=tool_calls_content.plain.rstrip(),
432
+ title="Tool Calls",
433
+ border_style="yellow",
434
+ )
435
+ panels.append(tool_calls_panel)
436
+
437
+ response_panel = None
438
+ if response_content:
439
+ response_panel = create_panel(
440
+ content=response_content,
441
+ title=f"Response ({response_timer.elapsed:.1f}s)",
442
+ border_style="blue",
443
+ )
444
+ panels.append(response_panel)
445
+
446
+ if (
447
+ isinstance(response_event, tuple(get_args(RunOutputEvent)))
448
+ and hasattr(response_event, "citations")
449
+ and response_event.citations is not None
450
+ and response_event.citations.urls is not None
451
+ ):
452
+ md_content = "\n".join(
453
+ f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
454
+ for i, citation in enumerate(response_event.citations.urls)
455
+ if citation.url # Only include citations with valid URLs
456
+ )
457
+ if md_content: # Only create panel if there are citations
458
+ citations_panel = create_panel(
459
+ content=Markdown(md_content),
460
+ title="Citations",
461
+ border_style="green",
462
+ )
463
+ panels.append(citations_panel)
464
+
465
+ return panels
466
+
467
+
468
+ def print_response(
469
+ agent: "Agent",
470
+ input: Union[List, Dict, str, Message, BaseModel, List[Message]],
471
+ session_id: Optional[str] = None,
472
+ session_state: Optional[Dict[str, Any]] = None,
473
+ user_id: Optional[str] = None,
474
+ audio: Optional[Sequence[Audio]] = None,
475
+ images: Optional[Sequence[Image]] = None,
476
+ videos: Optional[Sequence[Video]] = None,
477
+ files: Optional[Sequence[File]] = None,
478
+ stream_intermediate_steps: bool = False,
479
+ knowledge_filters: Optional[Dict[str, Any]] = None,
480
+ debug_mode: Optional[bool] = None,
481
+ markdown: bool = False,
482
+ show_message: bool = True,
483
+ show_reasoning: bool = True,
484
+ show_full_reasoning: bool = False,
485
+ tags_to_include_in_markdown: Set[str] = {"think", "thinking"},
486
+ console: Optional[Any] = None,
487
+ add_history_to_context: Optional[bool] = None,
488
+ dependencies: Optional[Dict[str, Any]] = None,
489
+ metadata: Optional[Dict[str, Any]] = None,
490
+ **kwargs: Any,
491
+ ):
492
+ with Live(console=console) as live_log:
493
+ status = Status("Thinking...", spinner="aesthetic", speed=0.4, refresh_per_second=10)
494
+ live_log.update(status)
495
+ response_timer = Timer()
496
+ response_timer.start()
497
+ # Panels to be rendered
498
+ panels = [status]
499
+ # First render the message panel if the message is not None
500
+ if input and show_message:
501
+ # Convert message to a panel
502
+ message_content = get_text_from_message(input)
503
+ message_panel = create_panel(
504
+ content=Text(message_content, style="green"),
505
+ title="Message",
506
+ border_style="cyan",
507
+ )
508
+ panels.append(message_panel) # type: ignore
509
+ live_log.update(Group(*panels))
510
+
511
+ # Run the agent
512
+ run_response = agent.run(
513
+ input=input,
514
+ session_id=session_id,
515
+ session_state=session_state,
516
+ user_id=user_id,
517
+ audio=audio,
518
+ images=images,
519
+ videos=videos,
520
+ files=files,
521
+ stream=False,
522
+ stream_intermediate_steps=stream_intermediate_steps,
523
+ knowledge_filters=knowledge_filters,
524
+ debug_mode=debug_mode,
525
+ add_history_to_context=add_history_to_context,
526
+ dependencies=dependencies,
527
+ metadata=metadata,
528
+ **kwargs,
529
+ )
530
+ response_timer.stop()
531
+
532
+ additional_panels = build_panels(
533
+ run_response=run_response,
534
+ output_schema=agent.output_schema, # type: ignore
535
+ response_timer=response_timer,
536
+ show_reasoning=show_reasoning,
537
+ show_full_reasoning=show_full_reasoning,
538
+ tags_to_include_in_markdown=tags_to_include_in_markdown,
539
+ markdown=markdown,
540
+ )
541
+ panels.extend(additional_panels)
542
+
543
+ if agent.memory_manager is not None and agent.memory_manager.memories_updated:
544
+ memory_panel = create_panel(
545
+ content=Text("Memories updated"),
546
+ title="Memories",
547
+ border_style="green",
548
+ )
549
+ panels.append(memory_panel)
550
+ live_log.update(Group(*panels))
551
+ agent.memory_manager.memories_updated = False
552
+
553
+ if agent.session_summary_manager is not None and agent.session_summary_manager.summaries_updated:
554
+ summary_panel = create_panel(
555
+ content=Text("Session summary updated"),
556
+ title="Session Summary",
557
+ border_style="green",
558
+ )
559
+ panels.append(summary_panel)
560
+ live_log.update(Group(*panels))
561
+ agent.session_summary_manager.summaries_updated = False
562
+
563
+ # Final update to remove the "Thinking..." status
564
+ panels = [p for p in panels if not isinstance(p, Status)]
565
+ live_log.update(Group(*panels))
566
+
567
+
568
+ async def aprint_response(
569
+ agent: "Agent",
570
+ input: Union[List, Dict, str, Message, BaseModel, List[Message]],
571
+ session_id: Optional[str] = None,
572
+ session_state: Optional[Dict[str, Any]] = None,
573
+ user_id: Optional[str] = None,
574
+ audio: Optional[Sequence[Audio]] = None,
575
+ images: Optional[Sequence[Image]] = None,
576
+ videos: Optional[Sequence[Video]] = None,
577
+ files: Optional[Sequence[File]] = None,
578
+ stream_intermediate_steps: bool = False,
579
+ knowledge_filters: Optional[Dict[str, Any]] = None,
580
+ debug_mode: Optional[bool] = None,
581
+ markdown: bool = False,
582
+ show_message: bool = True,
583
+ show_reasoning: bool = True,
584
+ show_full_reasoning: bool = False,
585
+ tags_to_include_in_markdown: Set[str] = {"think", "thinking"},
586
+ console: Optional[Any] = None,
587
+ add_history_to_context: Optional[bool] = None,
588
+ dependencies: Optional[Dict[str, Any]] = None,
589
+ metadata: Optional[Dict[str, Any]] = None,
590
+ **kwargs: Any,
591
+ ):
592
+ with Live(console=console) as live_log:
593
+ status = Status("Thinking...", spinner="aesthetic", speed=0.4, refresh_per_second=10)
594
+ live_log.update(status)
595
+ response_timer = Timer()
596
+ response_timer.start()
597
+ # Panels to be rendered
598
+ panels = [status]
599
+ # First render the message panel if the message is not None
600
+ if input and show_message:
601
+ # Convert message to a panel
602
+ message_content = get_text_from_message(input)
603
+ message_panel = create_panel(
604
+ content=Text(message_content, style="green"),
605
+ title="Message",
606
+ border_style="cyan",
607
+ )
608
+ panels.append(message_panel)
609
+ live_log.update(Group(*panels))
610
+
611
+ # Run the agent
612
+ run_response = await agent.arun(
613
+ input=input,
614
+ session_id=session_id,
615
+ session_state=session_state,
616
+ user_id=user_id,
617
+ audio=audio,
618
+ images=images,
619
+ videos=videos,
620
+ files=files,
621
+ stream=False,
622
+ stream_intermediate_steps=stream_intermediate_steps,
623
+ knowledge_filters=knowledge_filters,
624
+ debug_mode=debug_mode,
625
+ add_history_to_context=add_history_to_context,
626
+ dependencies=dependencies,
627
+ metadata=metadata,
628
+ **kwargs,
629
+ )
630
+ response_timer.stop()
631
+
632
+ additional_panels = build_panels(
633
+ run_response=run_response,
634
+ output_schema=agent.output_schema, # type: ignore
635
+ response_timer=response_timer,
636
+ show_reasoning=show_reasoning,
637
+ show_full_reasoning=show_full_reasoning,
638
+ tags_to_include_in_markdown=tags_to_include_in_markdown,
639
+ markdown=markdown,
640
+ )
641
+ panels.extend(additional_panels)
642
+
643
+ if agent.memory_manager is not None and agent.memory_manager.memories_updated:
644
+ memory_panel = create_panel(
645
+ content=Text("Memories updated"),
646
+ title="Memories",
647
+ border_style="green",
648
+ )
649
+ panels.append(memory_panel)
650
+ live_log.update(Group(*panels))
651
+ agent.memory_manager.memories_updated = False
652
+
653
+ if agent.session_summary_manager is not None and agent.session_summary_manager.summaries_updated is not None:
654
+ summary_panel = create_panel(
655
+ content=Text("Session summary updated"),
656
+ title="Session Summary",
657
+ border_style="green",
658
+ )
659
+ agent.session_summary_manager.summaries_updated = False
660
+ panels.append(summary_panel)
661
+ live_log.update(Group(*panels))
662
+
663
+ # Final update to remove the "Thinking..." status
664
+ panels = [p for p in panels if not isinstance(p, Status)]
665
+ live_log.update(Group(*panels))
666
+
667
+
668
+ def build_panels(
669
+ run_response: RunOutput,
670
+ response_timer: Timer,
671
+ output_schema: Optional[BaseModel] = None,
672
+ show_reasoning: bool = True,
673
+ show_full_reasoning: bool = False,
674
+ tags_to_include_in_markdown: Optional[Set[str]] = None,
675
+ markdown: bool = False,
676
+ ):
677
+ panels = []
678
+
679
+ reasoning_steps = []
680
+
681
+ if isinstance(run_response, RunOutput) and run_response.is_paused:
682
+ response_panel = create_paused_run_output_panel(run_response)
683
+ panels.append(response_panel)
684
+ return panels
685
+
686
+ if isinstance(run_response, RunOutput) and run_response.reasoning_steps is not None:
687
+ reasoning_steps = run_response.reasoning_steps
688
+
689
+ if len(reasoning_steps) > 0 and show_reasoning:
690
+ # Create panels for reasoning steps
691
+ for i, step in enumerate(reasoning_steps, 1):
692
+ # Build step content
693
+ step_content = Text.assemble()
694
+ if step.title is not None:
695
+ step_content.append(f"{step.title}\n", "bold")
696
+ if step.action is not None:
697
+ step_content.append(Text.from_markup(f"[bold]Action:[/bold] {step.action}\n", style="dim"))
698
+ if step.result is not None:
699
+ step_content.append(Text.from_markup(step.result, style="dim"))
700
+
701
+ if show_full_reasoning:
702
+ # Add detailed reasoning information if available
703
+ if step.reasoning is not None:
704
+ step_content.append(Text.from_markup(f"\n[bold]Reasoning:[/bold] {step.reasoning}", style="dim"))
705
+ if step.confidence is not None:
706
+ step_content.append(Text.from_markup(f"\n[bold]Confidence:[/bold] {step.confidence}", style="dim"))
707
+ reasoning_panel = create_panel(content=step_content, title=f"Reasoning step {i}", border_style="green")
708
+ panels.append(reasoning_panel)
709
+
710
+ if isinstance(run_response, RunOutput) and run_response.reasoning_content is not None:
711
+ # Create panel for thinking
712
+ thinking_panel = create_panel(
713
+ content=Text(run_response.reasoning_content),
714
+ title=f"Thinking ({response_timer.elapsed:.1f}s)",
715
+ border_style="green",
716
+ )
717
+ panels.append(thinking_panel)
718
+
719
+ # Add tool calls panel if available
720
+ if isinstance(run_response, RunOutput) and run_response.tools:
721
+ # Create bullet points for each tool call
722
+ tool_calls_content = Text()
723
+ formatted_tool_calls = format_tool_calls(run_response.tools)
724
+ for formatted_tool_call in formatted_tool_calls:
725
+ tool_calls_content.append(f"• {formatted_tool_call}\n")
726
+
727
+ tool_calls_panel = create_panel(
728
+ content=tool_calls_content.plain.rstrip(),
729
+ title="Tool Calls",
730
+ border_style="yellow",
731
+ )
732
+ panels.append(tool_calls_panel)
733
+
734
+ response_content_batch: Union[str, JSON, Markdown] = "" # type: ignore
735
+ if isinstance(run_response, RunOutput):
736
+ if isinstance(run_response.content, str):
737
+ if markdown:
738
+ escaped_content = escape_markdown_tags(run_response.content, tags_to_include_in_markdown) # type: ignore
739
+ response_content_batch = Markdown(escaped_content)
740
+ else:
741
+ response_content_batch = run_response.get_content_as_string(indent=4)
742
+ elif output_schema is not None and isinstance(run_response.content, BaseModel):
743
+ try:
744
+ response_content_batch = JSON(run_response.content.model_dump_json(exclude_none=True), indent=2)
745
+ except Exception as e:
746
+ log_warning(f"Failed to convert response to JSON: {e}")
747
+ else:
748
+ try:
749
+ response_content_batch = JSON(json.dumps(run_response.content), indent=4)
750
+ except Exception as e:
751
+ log_warning(f"Failed to convert response to JSON: {e}")
752
+
753
+ # Create panel for response
754
+ response_panel = create_panel(
755
+ content=response_content_batch,
756
+ title=f"Response ({response_timer.elapsed:.1f}s)",
757
+ border_style="blue",
758
+ )
759
+ panels.append(response_panel)
760
+
761
+ if (
762
+ isinstance(run_response, RunOutput)
763
+ and run_response.citations is not None
764
+ and run_response.citations.urls is not None
765
+ ):
766
+ md_content = "\n".join(
767
+ f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
768
+ for i, citation in enumerate(run_response.citations.urls)
769
+ if citation.url # Only include citations with valid URLs
770
+ )
771
+ if md_content: # Only create panel if there are citations
772
+ citations_panel = create_panel(
773
+ content=Markdown(md_content),
774
+ title="Citations",
775
+ border_style="green",
776
+ )
777
+ panels.append(citations_panel)
778
+
779
+ return panels