agno 1.8.1__py3-none-any.whl → 2.0.0rc1__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3181 -4169
  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 +1411 -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 +142 -43
  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 +1515 -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 +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  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 +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  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 +45 -150
  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 +84 -46
  158. agno/models/openai/chat.py +121 -23
  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 +14 -8
  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 +489 -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 +255 -0
  185. agno/os/router.py +869 -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 +208 -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 +436 -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 +188 -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 +60 -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 +168 -0
  202. agno/os/schema.py +892 -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/{response.py → agent.py} +231 -74
  213. agno/run/base.py +44 -58
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +133 -77
  216. agno/run/workflow.py +537 -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 +2960 -4252
  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 +42 -22
  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 +18 -13
  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 +18 -11
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +16 -7
  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 +61 -61
  253. agno/tools/eleven_labs.py +35 -28
  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 +29 -29
  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 +22 -10
  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 +31 -19
  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 +32 -14
  281. agno/tools/models/gemini.py +58 -31
  282. agno/tools/models/groq.py +29 -20
  283. agno/tools/models/nebius.py +27 -11
  284. agno/tools/models_labs.py +39 -15
  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 +57 -26
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +62 -46
  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 +54 -41
  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 +95 -118
  334. agno/utils/gemini.py +31 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +2 -2
  337. agno/utils/mcp.py +11 -5
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/claude.py +55 -4
  341. agno/utils/models/mistral.py +8 -7
  342. agno/utils/models/schema_utils.py +3 -3
  343. agno/utils/pprint.py +33 -32
  344. agno/utils/print_response/agent.py +779 -0
  345. agno/utils/print_response/team.py +1565 -0
  346. agno/utils/print_response/workflow.py +1451 -0
  347. agno/utils/prompts.py +14 -14
  348. agno/utils/reasoning.py +87 -0
  349. agno/utils/response.py +42 -42
  350. agno/utils/streamlit.py +454 -0
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +334 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2401 -696
  383. agno-2.0.0rc1.dist-info/METADATA +355 -0
  384. agno-2.0.0rc1.dist-info/RECORD +516 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -702
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.1.dist-info/METADATA +0 -982
  568. agno-1.8.1.dist-info/RECORD +0 -566
  569. agno-1.8.1.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.1.dist-info → agno-2.0.0rc1.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