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

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