agno 2.2.13__py3-none-any.whl

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