agno 1.8.1__py3-none-any.whl → 2.0.0a1__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 (580) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2778 -4123
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  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 +9 -64
  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 +1749 -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 +1438 -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 +888 -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 +1051 -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 +1417 -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 +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -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 +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -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 +10 -10
  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 +129 -82
  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 +38 -144
  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 +393 -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 +65 -28
  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 +33 -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 +30 -0
  184. agno/os/router.py +843 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +204 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +413 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +179 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +58 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +163 -0
  201. agno/os/schema.py +892 -0
  202. agno/{app/playground → os}/settings.py +8 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/{response.py → agent.py} +144 -72
  212. agno/run/base.py +44 -58
  213. agno/run/cancel.py +83 -0
  214. agno/run/team.py +133 -77
  215. agno/run/workflow.py +537 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +2961 -4253
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +42 -22
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +18 -13
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +18 -11
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +16 -7
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +61 -61
  252. agno/tools/eleven_labs.py +35 -28
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +29 -29
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +22 -22
  260. agno/tools/function.py +68 -17
  261. agno/tools/giphy.py +22 -10
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +31 -19
  276. agno/tools/mem0.py +18 -12
  277. agno/tools/memori.py +14 -10
  278. agno/tools/mlx_transcribe.py +3 -2
  279. agno/tools/models/azure_openai.py +32 -14
  280. agno/tools/models/gemini.py +58 -31
  281. agno/tools/models/groq.py +29 -20
  282. agno/tools/models/nebius.py +27 -11
  283. agno/tools/models_labs.py +39 -15
  284. agno/tools/moviepy_video.py +7 -6
  285. agno/tools/neo4j.py +10 -8
  286. agno/tools/newspaper.py +7 -2
  287. agno/tools/newspaper4k.py +8 -3
  288. agno/tools/openai.py +57 -26
  289. agno/tools/openbb.py +12 -11
  290. agno/tools/opencv.py +62 -46
  291. agno/tools/openweather.py +14 -12
  292. agno/tools/pandas.py +11 -3
  293. agno/tools/postgres.py +4 -12
  294. agno/tools/pubmed.py +4 -1
  295. agno/tools/python.py +9 -22
  296. agno/tools/reasoning.py +35 -27
  297. agno/tools/reddit.py +11 -26
  298. agno/tools/replicate.py +54 -41
  299. agno/tools/resend.py +4 -1
  300. agno/tools/scrapegraph.py +15 -14
  301. agno/tools/searxng.py +10 -23
  302. agno/tools/serpapi.py +6 -3
  303. agno/tools/serper.py +13 -4
  304. agno/tools/shell.py +9 -2
  305. agno/tools/slack.py +12 -11
  306. agno/tools/sleep.py +3 -2
  307. agno/tools/spider.py +24 -4
  308. agno/tools/sql.py +7 -6
  309. agno/tools/tavily.py +6 -4
  310. agno/tools/telegram.py +12 -4
  311. agno/tools/todoist.py +11 -31
  312. agno/tools/toolkit.py +1 -1
  313. agno/tools/trafilatura.py +22 -6
  314. agno/tools/trello.py +9 -22
  315. agno/tools/twilio.py +10 -3
  316. agno/tools/user_control_flow.py +6 -1
  317. agno/tools/valyu.py +34 -5
  318. agno/tools/visualization.py +19 -28
  319. agno/tools/webbrowser.py +4 -3
  320. agno/tools/webex.py +11 -7
  321. agno/tools/website.py +15 -46
  322. agno/tools/webtools.py +12 -4
  323. agno/tools/whatsapp.py +5 -9
  324. agno/tools/wikipedia.py +20 -13
  325. agno/tools/x.py +14 -13
  326. agno/tools/yfinance.py +13 -40
  327. agno/tools/youtube.py +26 -20
  328. agno/tools/zendesk.py +7 -2
  329. agno/tools/zep.py +10 -7
  330. agno/tools/zoom.py +10 -9
  331. agno/utils/common.py +1 -19
  332. agno/utils/events.py +95 -118
  333. agno/utils/knowledge.py +29 -0
  334. agno/utils/log.py +2 -2
  335. agno/utils/mcp.py +11 -5
  336. agno/utils/media.py +39 -0
  337. agno/utils/message.py +12 -1
  338. agno/utils/models/claude.py +6 -4
  339. agno/utils/models/mistral.py +8 -7
  340. agno/utils/models/schema_utils.py +3 -3
  341. agno/utils/pprint.py +33 -32
  342. agno/utils/print_response/agent.py +779 -0
  343. agno/utils/print_response/team.py +1565 -0
  344. agno/utils/print_response/workflow.py +1451 -0
  345. agno/utils/prompts.py +14 -14
  346. agno/utils/reasoning.py +87 -0
  347. agno/utils/response.py +42 -42
  348. agno/utils/string.py +8 -22
  349. agno/utils/team.py +50 -0
  350. agno/utils/timer.py +2 -2
  351. agno/vectordb/base.py +33 -21
  352. agno/vectordb/cassandra/cassandra.py +287 -23
  353. agno/vectordb/chroma/chromadb.py +482 -59
  354. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  355. agno/vectordb/couchbase/couchbase.py +309 -29
  356. agno/vectordb/lancedb/lance_db.py +360 -21
  357. agno/vectordb/langchaindb/__init__.py +5 -0
  358. agno/vectordb/langchaindb/langchaindb.py +145 -0
  359. agno/vectordb/lightrag/__init__.py +5 -0
  360. agno/vectordb/lightrag/lightrag.py +374 -0
  361. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  362. agno/vectordb/milvus/milvus.py +242 -32
  363. agno/vectordb/mongodb/mongodb.py +200 -24
  364. agno/vectordb/pgvector/pgvector.py +319 -37
  365. agno/vectordb/pineconedb/pineconedb.py +221 -27
  366. agno/vectordb/qdrant/qdrant.py +334 -14
  367. agno/vectordb/singlestore/singlestore.py +286 -29
  368. agno/vectordb/surrealdb/surrealdb.py +187 -7
  369. agno/vectordb/upstashdb/upstashdb.py +342 -26
  370. agno/vectordb/weaviate/weaviate.py +227 -165
  371. agno/workflow/__init__.py +17 -13
  372. agno/workflow/{v2/condition.py → condition.py} +135 -32
  373. agno/workflow/{v2/loop.py → loop.py} +115 -28
  374. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  375. agno/workflow/{v2/router.py → router.py} +133 -32
  376. agno/workflow/{v2/step.py → step.py} +200 -42
  377. agno/workflow/{v2/steps.py → steps.py} +147 -66
  378. agno/workflow/types.py +482 -0
  379. agno/workflow/workflow.py +2394 -696
  380. agno-2.0.0a1.dist-info/METADATA +355 -0
  381. agno-2.0.0a1.dist-info/RECORD +514 -0
  382. agno/agent/metrics.py +0 -107
  383. agno/api/app.py +0 -35
  384. agno/api/playground.py +0 -92
  385. agno/api/schemas/app.py +0 -12
  386. agno/api/schemas/playground.py +0 -22
  387. agno/api/schemas/user.py +0 -35
  388. agno/api/schemas/workspace.py +0 -46
  389. agno/api/user.py +0 -160
  390. agno/api/workflows.py +0 -33
  391. agno/api/workspace.py +0 -175
  392. agno/app/agui/__init__.py +0 -3
  393. agno/app/agui/app.py +0 -17
  394. agno/app/agui/sync_router.py +0 -120
  395. agno/app/base.py +0 -186
  396. agno/app/discord/__init__.py +0 -3
  397. agno/app/fastapi/__init__.py +0 -3
  398. agno/app/fastapi/app.py +0 -107
  399. agno/app/fastapi/async_router.py +0 -457
  400. agno/app/fastapi/sync_router.py +0 -448
  401. agno/app/playground/app.py +0 -228
  402. agno/app/playground/async_router.py +0 -1050
  403. agno/app/playground/deploy.py +0 -249
  404. agno/app/playground/operator.py +0 -183
  405. agno/app/playground/schemas.py +0 -220
  406. agno/app/playground/serve.py +0 -55
  407. agno/app/playground/sync_router.py +0 -1042
  408. agno/app/playground/utils.py +0 -46
  409. agno/app/settings.py +0 -15
  410. agno/app/slack/__init__.py +0 -3
  411. agno/app/slack/app.py +0 -19
  412. agno/app/slack/sync_router.py +0 -92
  413. agno/app/utils.py +0 -54
  414. agno/app/whatsapp/__init__.py +0 -3
  415. agno/app/whatsapp/app.py +0 -15
  416. agno/app/whatsapp/sync_router.py +0 -197
  417. agno/cli/auth_server.py +0 -249
  418. agno/cli/config.py +0 -274
  419. agno/cli/console.py +0 -88
  420. agno/cli/credentials.py +0 -23
  421. agno/cli/entrypoint.py +0 -571
  422. agno/cli/operator.py +0 -357
  423. agno/cli/settings.py +0 -96
  424. agno/cli/ws/ws_cli.py +0 -817
  425. agno/constants.py +0 -13
  426. agno/document/__init__.py +0 -5
  427. agno/document/chunking/semantic.py +0 -45
  428. agno/document/chunking/strategy.py +0 -31
  429. agno/document/reader/__init__.py +0 -5
  430. agno/document/reader/base.py +0 -47
  431. agno/document/reader/docx_reader.py +0 -60
  432. agno/document/reader/gcs/pdf_reader.py +0 -44
  433. agno/document/reader/s3/pdf_reader.py +0 -59
  434. agno/document/reader/s3/text_reader.py +0 -63
  435. agno/document/reader/url_reader.py +0 -59
  436. agno/document/reader/youtube_reader.py +0 -58
  437. agno/embedder/__init__.py +0 -5
  438. agno/embedder/langdb.py +0 -80
  439. agno/embedder/mistral.py +0 -82
  440. agno/embedder/openai.py +0 -78
  441. agno/file/__init__.py +0 -5
  442. agno/file/file.py +0 -16
  443. agno/file/local/csv.py +0 -32
  444. agno/file/local/txt.py +0 -19
  445. agno/infra/app.py +0 -240
  446. agno/infra/base.py +0 -144
  447. agno/infra/context.py +0 -20
  448. agno/infra/db_app.py +0 -52
  449. agno/infra/resource.py +0 -205
  450. agno/infra/resources.py +0 -55
  451. agno/knowledge/agent.py +0 -702
  452. agno/knowledge/arxiv.py +0 -33
  453. agno/knowledge/combined.py +0 -36
  454. agno/knowledge/csv.py +0 -144
  455. agno/knowledge/csv_url.py +0 -124
  456. agno/knowledge/document.py +0 -223
  457. agno/knowledge/docx.py +0 -137
  458. agno/knowledge/firecrawl.py +0 -34
  459. agno/knowledge/gcs/__init__.py +0 -0
  460. agno/knowledge/gcs/base.py +0 -39
  461. agno/knowledge/gcs/pdf.py +0 -125
  462. agno/knowledge/json.py +0 -137
  463. agno/knowledge/langchain.py +0 -71
  464. agno/knowledge/light_rag.py +0 -273
  465. agno/knowledge/llamaindex.py +0 -66
  466. agno/knowledge/markdown.py +0 -154
  467. agno/knowledge/pdf.py +0 -164
  468. agno/knowledge/pdf_bytes.py +0 -42
  469. agno/knowledge/pdf_url.py +0 -148
  470. agno/knowledge/s3/__init__.py +0 -0
  471. agno/knowledge/s3/base.py +0 -64
  472. agno/knowledge/s3/pdf.py +0 -33
  473. agno/knowledge/s3/text.py +0 -34
  474. agno/knowledge/text.py +0 -141
  475. agno/knowledge/url.py +0 -46
  476. agno/knowledge/website.py +0 -179
  477. agno/knowledge/wikipedia.py +0 -32
  478. agno/knowledge/youtube.py +0 -35
  479. agno/memory/agent.py +0 -423
  480. agno/memory/classifier.py +0 -104
  481. agno/memory/db/__init__.py +0 -5
  482. agno/memory/db/base.py +0 -42
  483. agno/memory/db/mongodb.py +0 -189
  484. agno/memory/db/postgres.py +0 -203
  485. agno/memory/db/sqlite.py +0 -193
  486. agno/memory/memory.py +0 -22
  487. agno/memory/row.py +0 -36
  488. agno/memory/summarizer.py +0 -201
  489. agno/memory/summary.py +0 -19
  490. agno/memory/team.py +0 -415
  491. agno/memory/v2/__init__.py +0 -2
  492. agno/memory/v2/db/__init__.py +0 -1
  493. agno/memory/v2/db/base.py +0 -42
  494. agno/memory/v2/db/firestore.py +0 -339
  495. agno/memory/v2/db/mongodb.py +0 -196
  496. agno/memory/v2/db/postgres.py +0 -214
  497. agno/memory/v2/db/redis.py +0 -187
  498. agno/memory/v2/db/schema.py +0 -54
  499. agno/memory/v2/db/sqlite.py +0 -209
  500. agno/memory/v2/manager.py +0 -437
  501. agno/memory/v2/memory.py +0 -1097
  502. agno/memory/v2/schema.py +0 -55
  503. agno/memory/v2/summarizer.py +0 -215
  504. agno/memory/workflow.py +0 -38
  505. agno/models/ollama/tools.py +0 -430
  506. agno/models/qwen/__init__.py +0 -5
  507. agno/playground/__init__.py +0 -10
  508. agno/playground/deploy.py +0 -3
  509. agno/playground/playground.py +0 -3
  510. agno/playground/serve.py +0 -3
  511. agno/playground/settings.py +0 -3
  512. agno/reranker/__init__.py +0 -0
  513. agno/run/v2/__init__.py +0 -0
  514. agno/run/v2/workflow.py +0 -567
  515. agno/storage/__init__.py +0 -0
  516. agno/storage/agent/__init__.py +0 -0
  517. agno/storage/agent/dynamodb.py +0 -1
  518. agno/storage/agent/json.py +0 -1
  519. agno/storage/agent/mongodb.py +0 -1
  520. agno/storage/agent/postgres.py +0 -1
  521. agno/storage/agent/singlestore.py +0 -1
  522. agno/storage/agent/sqlite.py +0 -1
  523. agno/storage/agent/yaml.py +0 -1
  524. agno/storage/base.py +0 -60
  525. agno/storage/dynamodb.py +0 -673
  526. agno/storage/firestore.py +0 -297
  527. agno/storage/gcs_json.py +0 -261
  528. agno/storage/in_memory.py +0 -234
  529. agno/storage/json.py +0 -237
  530. agno/storage/mongodb.py +0 -328
  531. agno/storage/mysql.py +0 -685
  532. agno/storage/postgres.py +0 -682
  533. agno/storage/redis.py +0 -336
  534. agno/storage/session/__init__.py +0 -16
  535. agno/storage/session/agent.py +0 -64
  536. agno/storage/session/team.py +0 -63
  537. agno/storage/session/v2/__init__.py +0 -5
  538. agno/storage/session/workflow.py +0 -61
  539. agno/storage/singlestore.py +0 -606
  540. agno/storage/sqlite.py +0 -646
  541. agno/storage/workflow/__init__.py +0 -0
  542. agno/storage/workflow/mongodb.py +0 -1
  543. agno/storage/workflow/postgres.py +0 -1
  544. agno/storage/workflow/sqlite.py +0 -1
  545. agno/storage/yaml.py +0 -241
  546. agno/tools/thinking.py +0 -73
  547. agno/utils/defaults.py +0 -57
  548. agno/utils/filesystem.py +0 -39
  549. agno/utils/git.py +0 -52
  550. agno/utils/json_io.py +0 -30
  551. agno/utils/load_env.py +0 -19
  552. agno/utils/py_io.py +0 -19
  553. agno/utils/pyproject.py +0 -18
  554. agno/utils/resource_filter.py +0 -31
  555. agno/workflow/v2/__init__.py +0 -21
  556. agno/workflow/v2/types.py +0 -357
  557. agno/workflow/v2/workflow.py +0 -3312
  558. agno/workspace/__init__.py +0 -0
  559. agno/workspace/config.py +0 -325
  560. agno/workspace/enums.py +0 -6
  561. agno/workspace/helpers.py +0 -52
  562. agno/workspace/operator.py +0 -757
  563. agno/workspace/settings.py +0 -158
  564. agno-1.8.1.dist-info/METADATA +0 -982
  565. agno-1.8.1.dist-info/RECORD +0 -566
  566. agno-1.8.1.dist-info/entry_points.txt +0 -3
  567. /agno/{app → db/migrations}/__init__.py +0 -0
  568. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  569. /agno/{cli → integrations}/__init__.py +0 -0
  570. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  571. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  572. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  573. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  574. /agno/{app → os/interfaces}/slack/security.py +0 -0
  575. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  576. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  577. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  578. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  579. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  580. {agno-1.8.1.dist-info → agno-2.0.0a1.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