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
agno/utils/http.py ADDED
@@ -0,0 +1,74 @@
1
+ import asyncio
2
+ import logging
3
+ from time import sleep
4
+ from typing import Optional
5
+
6
+ import httpx
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ DEFAULT_MAX_RETRIES = 3
11
+ DEFAULT_BACKOFF_FACTOR = 2 # Exponential backoff: 1, 2, 4, 8...
12
+
13
+
14
+ def fetch_with_retry(
15
+ url: str,
16
+ max_retries: int = DEFAULT_MAX_RETRIES,
17
+ backoff_factor: int = DEFAULT_BACKOFF_FACTOR,
18
+ proxy: Optional[str] = None,
19
+ ) -> httpx.Response:
20
+ """Synchronous HTTP GET with retry logic."""
21
+
22
+ for attempt in range(max_retries):
23
+ try:
24
+ response = httpx.get(url, proxy=proxy) if proxy else httpx.get(url)
25
+ response.raise_for_status()
26
+ return response
27
+ except httpx.RequestError as e:
28
+ if attempt == max_retries - 1:
29
+ logger.error(f"Failed to fetch {url} after {max_retries} attempts: {e}")
30
+ raise
31
+ wait_time = backoff_factor**attempt
32
+ logger.warning(f"Request failed (attempt {attempt + 1}), retrying in {wait_time} seconds...")
33
+ sleep(wait_time)
34
+ except httpx.HTTPStatusError as e:
35
+ logger.error(f"HTTP error for {url}: {e.response.status_code} - {e.response.text}")
36
+ raise
37
+
38
+ raise httpx.RequestError(f"Failed to fetch {url} after {max_retries} attempts")
39
+
40
+
41
+ async def async_fetch_with_retry(
42
+ url: str,
43
+ client: Optional[httpx.AsyncClient] = None,
44
+ max_retries: int = DEFAULT_MAX_RETRIES,
45
+ backoff_factor: int = DEFAULT_BACKOFF_FACTOR,
46
+ proxy: Optional[str] = None,
47
+ ) -> httpx.Response:
48
+ """Asynchronous HTTP GET with retry logic."""
49
+
50
+ async def _fetch():
51
+ if client is None:
52
+ client_args = {"proxy": proxy} if proxy else {}
53
+ async with httpx.AsyncClient(**client_args) as local_client: # type: ignore
54
+ return await local_client.get(url)
55
+ else:
56
+ return await client.get(url)
57
+
58
+ for attempt in range(max_retries):
59
+ try:
60
+ response = await _fetch()
61
+ response.raise_for_status()
62
+ return response
63
+ except httpx.RequestError as e:
64
+ if attempt == max_retries - 1:
65
+ logger.error(f"Failed to fetch {url} after {max_retries} attempts: {e}")
66
+ raise
67
+ wait_time = backoff_factor**attempt
68
+ logger.warning(f"Request failed (attempt {attempt + 1}), retrying in {wait_time} seconds...")
69
+ await asyncio.sleep(wait_time)
70
+ except httpx.HTTPStatusError as e:
71
+ logger.error(f"HTTP error for {url}: {e.response.status_code} - {e.response.text}")
72
+ raise
73
+
74
+ raise httpx.RequestError(f"Failed to fetch {url} after {max_retries} attempts")
@@ -0,0 +1,234 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, Optional, Union, get_args, get_origin
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from agno.utils.log import logger
7
+
8
+
9
+ def is_origin_union_type(origin: Any) -> bool:
10
+ import sys
11
+
12
+ if sys.version_info.minor >= 10:
13
+ from types import UnionType # type: ignore
14
+
15
+ return origin in [Union, UnionType]
16
+
17
+ return origin is Union
18
+
19
+
20
+ def get_json_type_for_py_type(arg: str) -> str:
21
+ """
22
+ Get the JSON schema type for a given type.
23
+ :param arg: The type to get the JSON schema type for.
24
+ :return: The JSON schema type.
25
+ """
26
+ # log_info(f"Getting JSON type for: {arg}")
27
+ if arg in ("int", "float", "complex", "Decimal"):
28
+ return "number"
29
+ elif arg in ("str", "string"):
30
+ return "string"
31
+ elif arg in ("bool", "boolean"):
32
+ return "boolean"
33
+ elif arg in ("NoneType", "None"):
34
+ return "null"
35
+ elif arg in ("list", "tuple", "set", "frozenset"):
36
+ return "array"
37
+ elif arg in ("dict", "mapping"):
38
+ return "object"
39
+
40
+ # If the type is not recognized, return "object"
41
+ return "object"
42
+
43
+
44
+ def inline_pydantic_schema(schema: Dict[str, Any]) -> Dict[str, Any]:
45
+ """
46
+ Recursively inline Pydantic model schemas by replacing $ref with actual schema.
47
+ """
48
+ if not isinstance(schema, dict):
49
+ return schema
50
+
51
+ def resolve_ref(ref: str, defs: Dict[str, Any]) -> Dict[str, Any]:
52
+ """Resolve a $ref to its actual schema."""
53
+ if not ref.startswith("#/$defs/"):
54
+ return {"type": "object"} # Fallback for external refs
55
+
56
+ def_name = ref.split("/")[-1]
57
+ if def_name in defs:
58
+ return defs[def_name]
59
+ return {"type": "object"} # Fallback if definition not found
60
+
61
+ def process_schema(s: Dict[str, Any], defs: Dict[str, Any]) -> Dict[str, Any]:
62
+ """Process a schema dictionary, resolving all references."""
63
+ if not isinstance(s, dict):
64
+ return s
65
+
66
+ # Handle $ref
67
+ if "$ref" in s:
68
+ return resolve_ref(s["$ref"], defs)
69
+
70
+ # Create a new dict to avoid modifying the input
71
+ result = s.copy()
72
+
73
+ # Handle arrays
74
+ if "items" in result:
75
+ result["items"] = process_schema(result["items"], defs)
76
+
77
+ # Handle object properties
78
+ if "properties" in result:
79
+ for prop_name, prop_schema in result["properties"].items():
80
+ result["properties"][prop_name] = process_schema(prop_schema, defs)
81
+
82
+ # Handle anyOf (for Union types)
83
+ if "anyOf" in result:
84
+ result["anyOf"] = [process_schema(sub_schema, defs) for sub_schema in result["anyOf"]]
85
+
86
+ # Handle allOf (for inheritance)
87
+ if "allOf" in result:
88
+ result["allOf"] = [process_schema(sub_schema, defs) for sub_schema in result["allOf"]]
89
+
90
+ # Handle additionalProperties
91
+ if "additionalProperties" in result:
92
+ result["additionalProperties"] = process_schema(result["additionalProperties"], defs)
93
+
94
+ # Handle propertyNames
95
+ if "propertyNames" in result:
96
+ result["propertyNames"] = process_schema(result["propertyNames"], defs)
97
+
98
+ return result
99
+
100
+ # Store definitions for later use
101
+ definitions = schema.pop("$defs", {})
102
+
103
+ # First, resolve any nested references in definitions
104
+ resolved_definitions = {}
105
+ for def_name, def_schema in definitions.items():
106
+ resolved_definitions[def_name] = process_schema(def_schema, definitions)
107
+
108
+ # Process the main schema with resolved definitions
109
+ result = process_schema(schema, resolved_definitions)
110
+
111
+ # Remove any remaining definitions
112
+ if "$defs" in result:
113
+ del result["$defs"]
114
+
115
+ return result
116
+
117
+
118
+ def get_json_schema_for_arg(type_hint: Any) -> Optional[Dict[str, Any]]:
119
+ # log_info(f"Getting JSON schema for arg: {t}")
120
+ type_args = get_args(type_hint)
121
+ # log_info(f"Type args: {type_args}")
122
+ type_origin = get_origin(type_hint)
123
+ # log_info(f"Type origin: {type_origin}")
124
+ if type_origin is not None:
125
+ if type_origin in (list, tuple, set, frozenset):
126
+ json_schema_for_items = get_json_schema_for_arg(type_args[0]) if type_args else {"type": "string"}
127
+ return {"type": "array", "items": json_schema_for_items}
128
+ elif type_origin is dict:
129
+ # Handle both key and value types for dictionaries
130
+ key_schema = get_json_schema_for_arg(type_args[0]) if type_args else {"type": "string"}
131
+ value_schema = get_json_schema_for_arg(type_args[1]) if len(type_args) > 1 else {"type": "string"}
132
+ return {"type": "object", "propertyNames": key_schema, "additionalProperties": value_schema}
133
+ elif is_origin_union_type(type_origin):
134
+ types = []
135
+ for arg in type_args:
136
+ try:
137
+ schema = get_json_schema_for_arg(arg)
138
+ if schema:
139
+ types.append(schema)
140
+ except Exception:
141
+ continue
142
+ return {"anyOf": types} if types else None
143
+
144
+ if isinstance(type_hint, type) and issubclass(type_hint, Enum):
145
+ enum_values = [member.value for member in type_hint]
146
+ return {"type": "string", "enum": enum_values}
147
+
148
+ if isinstance(type_hint, type) and issubclass(type_hint, BaseModel):
149
+ # Get the schema and inline it
150
+ schema = type_hint.model_json_schema()
151
+ return inline_pydantic_schema(schema) # type: ignore
152
+
153
+ if hasattr(type_hint, "__dataclass_fields__"):
154
+ # Convert dataclass to JSON schema
155
+ properties = {}
156
+ required = []
157
+
158
+ for field_name, field in type_hint.__dataclass_fields__.items():
159
+ field_type = field.type
160
+ field_schema = get_json_schema_for_arg(field_type)
161
+
162
+ if (
163
+ field_schema
164
+ and "anyOf" in field_schema
165
+ and any(schema["type"] == "null" for schema in field_schema["anyOf"])
166
+ ):
167
+ field_schema["type"] = next(
168
+ schema["type"] for schema in field_schema["anyOf"] if schema["type"] != "null"
169
+ )
170
+ field_schema.pop("anyOf")
171
+ else:
172
+ required.append(field_name)
173
+
174
+ if field_schema:
175
+ properties[field_name] = field_schema
176
+
177
+ arg_json_schema = {"type": "object", "properties": properties, "additionalProperties": False}
178
+
179
+ if required:
180
+ arg_json_schema["required"] = required
181
+ return arg_json_schema
182
+
183
+ json_schema: Dict[str, Any] = {"type": get_json_type_for_py_type(type_hint.__name__)}
184
+ if json_schema["type"] == "object":
185
+ json_schema["properties"] = {}
186
+ json_schema["additionalProperties"] = False
187
+ return json_schema
188
+
189
+
190
+ def get_json_schema(
191
+ type_hints: Dict[str, Any], param_descriptions: Optional[Dict[str, str]] = None, strict: bool = False
192
+ ) -> Dict[str, Any]:
193
+ json_schema: Dict[str, Any] = {
194
+ "type": "object",
195
+ "properties": {},
196
+ }
197
+ if strict:
198
+ json_schema["additionalProperties"] = False
199
+
200
+ # We only include the fields in the type_hints dict
201
+ for parameter_name, type_hint in type_hints.items():
202
+ # log_info(f"Parsing arg: {k} | {v}")
203
+ if parameter_name == "return":
204
+ continue
205
+
206
+ try:
207
+ # Check if type is Optional (Union with NoneType)
208
+ type_origin = get_origin(type_hint)
209
+ type_args = get_args(type_hint)
210
+ is_optional = type_origin is Union and len(type_args) == 2 and any(arg is type(None) for arg in type_args)
211
+
212
+ # Get the actual type if it's Optional
213
+ if is_optional:
214
+ type_hint = next(arg for arg in type_args if arg is not type(None))
215
+
216
+ if type_hint:
217
+ arg_json_schema = get_json_schema_for_arg(type_hint)
218
+ else:
219
+ arg_json_schema = {}
220
+
221
+ if arg_json_schema is not None:
222
+ # Add description
223
+ if param_descriptions and parameter_name in param_descriptions and param_descriptions[parameter_name]:
224
+ arg_json_schema["description"] = param_descriptions[parameter_name]
225
+
226
+ json_schema["properties"][parameter_name] = arg_json_schema
227
+
228
+ else:
229
+ logger.warning(f"Could not parse argument {parameter_name} of type {type_hint}")
230
+ except Exception as e:
231
+ logger.error(f"Error processing argument {parameter_name}: {str(e)}")
232
+ continue
233
+
234
+ return json_schema
@@ -0,0 +1,36 @@
1
+ from typing import Any, Dict, List, Optional, Union
2
+
3
+ from agno.filters import FilterExpr
4
+ from agno.utils.log import log_info
5
+
6
+
7
+ def get_agentic_or_user_search_filters(
8
+ filters: Optional[Dict[str, Any]], effective_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]]
9
+ ) -> Dict[str, Any]:
10
+ """Helper function to determine the final filters to use for the search.
11
+
12
+ Args:
13
+ filters: Filters passed by the agent.
14
+ effective_filters: Filters passed by user.
15
+
16
+ Returns:
17
+ Dict[str, Any]: The final filters to use for the search.
18
+ """
19
+ search_filters = None
20
+
21
+ # If agentic filters exist and manual filters (passed by user) do not, use agentic filters
22
+ if filters and not effective_filters:
23
+ search_filters = filters
24
+
25
+ # If both agentic filters exist and manual filters (passed by user) exist, use manual filters (give priority to user and override)
26
+ if filters and effective_filters:
27
+ if isinstance(effective_filters, dict):
28
+ search_filters = effective_filters
29
+ elif isinstance(effective_filters, list):
30
+ # If effective_filters is a list (likely List[FilterExpr]), convert both filters and effective_filters to a dict if possible, otherwise raise
31
+ raise ValueError(
32
+ "Merging dict and list of filters is not supported; effective_filters should be a dict for search compatibility."
33
+ )
34
+
35
+ log_info(f"Filters used by Agent: {search_filters}")
36
+ return search_filters or {}
agno/utils/location.py ADDED
@@ -0,0 +1,19 @@
1
+ from typing import Any, Dict
2
+
3
+ import requests
4
+
5
+ from agno.utils.log import log_warning
6
+
7
+
8
+ def get_location() -> Dict[str, Any]:
9
+ """Get approximate location using IP geolocation."""
10
+ try:
11
+ response = requests.get("https://api.ipify.org?format=json", timeout=5)
12
+ ip = response.json()["ip"]
13
+ response = requests.get(f"http://ip-api.com/json/{ip}", timeout=5)
14
+ if response.status_code == 200:
15
+ data = response.json()
16
+ return {"city": data.get("city"), "region": data.get("region"), "country": data.get("country")}
17
+ except Exception as e:
18
+ log_warning(f"Failed to get location: {e}")
19
+ return {}
agno/utils/log.py ADDED
@@ -0,0 +1,255 @@
1
+ import logging
2
+ from functools import lru_cache
3
+ from os import getenv
4
+ from typing import Any, Literal, Optional
5
+
6
+ from rich.logging import RichHandler
7
+ from rich.text import Text
8
+
9
+ LOGGER_NAME = "agno"
10
+ TEAM_LOGGER_NAME = f"{LOGGER_NAME}-team"
11
+ WORKFLOW_LOGGER_NAME = f"{LOGGER_NAME}-workflow"
12
+
13
+ # Define custom styles for different log sources
14
+ LOG_STYLES = {
15
+ "agent": {
16
+ "debug": "green",
17
+ "info": "blue",
18
+ },
19
+ "team": {
20
+ "debug": "magenta",
21
+ "info": "steel_blue1",
22
+ },
23
+ "workflow": {
24
+ "debug": "sandy_brown",
25
+ "info": "orange3",
26
+ },
27
+ }
28
+
29
+
30
+ class ColoredRichHandler(RichHandler):
31
+ def __init__(self, *args, source_type: Optional[str] = None, **kwargs):
32
+ super().__init__(*args, **kwargs)
33
+ self.source_type = source_type
34
+
35
+ def get_level_text(self, record: logging.LogRecord) -> Text:
36
+ # Return empty Text if message is empty
37
+ if not record.msg:
38
+ return Text("")
39
+
40
+ level_name = record.levelname.lower()
41
+ if self.source_type and self.source_type in LOG_STYLES:
42
+ if level_name in LOG_STYLES[self.source_type]:
43
+ color = LOG_STYLES[self.source_type][level_name]
44
+ return Text(record.levelname, style=color)
45
+ else:
46
+ if level_name in LOG_STYLES["agent"]:
47
+ color = LOG_STYLES["agent"][level_name]
48
+ return Text(record.levelname, style=color)
49
+ return super().get_level_text(record)
50
+
51
+
52
+ class AgnoLogger(logging.Logger):
53
+ def __init__(self, name: str, level: int = logging.NOTSET):
54
+ super().__init__(name, level)
55
+
56
+ def debug(self, msg: str, center: bool = False, symbol: str = "*", *args, **kwargs): # type: ignore
57
+ if center:
58
+ msg = center_header(str(msg), symbol)
59
+ super().debug(msg, *args, **kwargs)
60
+
61
+ def info(self, msg: str, center: bool = False, symbol: str = "*", *args, **kwargs): # type: ignore
62
+ if center:
63
+ msg = center_header(str(msg), symbol)
64
+ super().info(msg, *args, **kwargs)
65
+
66
+
67
+ def build_logger(logger_name: str, source_type: Optional[str] = None) -> Any:
68
+ # If a logger with the name "agno.{source_type}" is already set, we want to use that one
69
+ _logger = logging.getLogger(f"agno.{logger_name}")
70
+ if _logger.handlers or _logger.level != logging.NOTSET:
71
+ return _logger
72
+
73
+ # Set the custom logger class as the default for this logger
74
+ logging.setLoggerClass(AgnoLogger)
75
+
76
+ # Create logger with custom class
77
+ _logger = logging.getLogger(logger_name)
78
+
79
+ # Reset logger class to default to avoid affecting other loggers
80
+ logging.setLoggerClass(logging.Logger)
81
+
82
+ # https://rich.readthedocs.io/en/latest/reference/logging.html#rich.logging.RichHandler
83
+ # https://rich.readthedocs.io/en/latest/logging.html#handle-exceptions
84
+ rich_handler = ColoredRichHandler(
85
+ show_time=False,
86
+ rich_tracebacks=False,
87
+ show_path=True if getenv("AGNO_API_RUNTIME") == "dev" else False,
88
+ tracebacks_show_locals=False,
89
+ source_type=source_type or "agent",
90
+ )
91
+ rich_handler.setFormatter(
92
+ logging.Formatter(
93
+ fmt="%(message)s",
94
+ datefmt="[%X]",
95
+ )
96
+ )
97
+
98
+ _logger.addHandler(rich_handler)
99
+ _logger.setLevel(logging.INFO)
100
+ _logger.propagate = False
101
+ return _logger
102
+
103
+
104
+ agent_logger: AgnoLogger = build_logger(LOGGER_NAME, source_type="agent")
105
+ team_logger: AgnoLogger = build_logger(TEAM_LOGGER_NAME, source_type="team")
106
+ workflow_logger: AgnoLogger = build_logger(WORKFLOW_LOGGER_NAME, source_type="workflow")
107
+
108
+ # Set the default logger to the agent logger
109
+ logger: AgnoLogger = agent_logger
110
+
111
+
112
+ debug_on: bool = False
113
+ debug_level: Literal[1, 2] = 1
114
+
115
+
116
+ def set_log_level_to_debug(source_type: Optional[str] = None, level: Literal[1, 2] = 1):
117
+ if source_type is None:
118
+ use_agent_logger()
119
+
120
+ _logger = logging.getLogger(LOGGER_NAME if source_type is None else f"{LOGGER_NAME}-{source_type}")
121
+ _logger.setLevel(logging.DEBUG)
122
+
123
+ global debug_on
124
+ debug_on = True
125
+
126
+ global debug_level
127
+ debug_level = level
128
+
129
+
130
+ def set_log_level_to_info(source_type: Optional[str] = None):
131
+ _logger = logging.getLogger(LOGGER_NAME if source_type is None else f"{LOGGER_NAME}-{source_type}")
132
+ _logger.setLevel(logging.INFO)
133
+
134
+ global debug_on
135
+ debug_on = False
136
+
137
+
138
+ def set_log_level_to_warning(source_type: Optional[str] = None):
139
+ _logger = logging.getLogger(LOGGER_NAME if source_type is None else f"{LOGGER_NAME}-{source_type}")
140
+ _logger.setLevel(logging.WARNING)
141
+
142
+ global debug_on
143
+ debug_on = False
144
+
145
+
146
+ def set_log_level_to_error(source_type: Optional[str] = None):
147
+ _logger = logging.getLogger(LOGGER_NAME if source_type is None else f"{LOGGER_NAME}-{source_type}")
148
+ _logger.setLevel(logging.ERROR)
149
+
150
+ global debug_on
151
+ debug_on = False
152
+
153
+
154
+ def center_header(message: str, symbol: str = "*") -> str:
155
+ try:
156
+ import shutil
157
+
158
+ terminal_width = shutil.get_terminal_size().columns
159
+ except Exception:
160
+ terminal_width = 80 # fallback width
161
+
162
+ header = f" {message} "
163
+ return f"{header.center(terminal_width - 20, symbol)}"
164
+
165
+
166
+ def use_team_logger():
167
+ """Switch the default logger to use team_logger"""
168
+ global logger
169
+ logger = team_logger
170
+
171
+
172
+ def use_agent_logger():
173
+ """Switch the default logger to use the default agent logger"""
174
+ global logger
175
+ logger = agent_logger
176
+
177
+
178
+ def use_workflow_logger():
179
+ """Switch the default logger to use workflow_logger"""
180
+ global logger
181
+ logger = workflow_logger
182
+
183
+
184
+ @lru_cache(maxsize=128)
185
+ def _using_default_logger(logger_instance: Any) -> bool:
186
+ """Return True if the currently active logger is our default AgnoLogger"""
187
+ return isinstance(logger_instance, AgnoLogger)
188
+
189
+
190
+ def log_debug(msg, center: bool = False, symbol: str = "*", log_level: Literal[1, 2] = 1, *args, **kwargs):
191
+ global logger
192
+ global debug_on
193
+ global debug_level
194
+
195
+ if debug_on:
196
+ if debug_level >= log_level:
197
+ if _using_default_logger(logger):
198
+ logger.debug(msg, center, symbol, *args, **kwargs)
199
+ else:
200
+ logger.debug(msg, *args, **kwargs)
201
+
202
+
203
+ def log_info(msg, center: bool = False, symbol: str = "*", *args, **kwargs):
204
+ global logger
205
+ if _using_default_logger(logger):
206
+ logger.info(msg, center, symbol, *args, **kwargs)
207
+ else:
208
+ logger.info(msg, *args, **kwargs)
209
+
210
+
211
+ def log_warning(msg, *args, **kwargs):
212
+ global logger
213
+ logger.warning(msg, *args, **kwargs)
214
+
215
+
216
+ def log_error(msg, *args, **kwargs):
217
+ global logger
218
+ logger.error(msg, *args, **kwargs)
219
+
220
+
221
+ def log_exception(msg, *args, **kwargs):
222
+ global logger
223
+ logger.exception(msg, *args, **kwargs)
224
+
225
+
226
+ def configure_agno_logging(
227
+ custom_default_logger: Optional[Any] = None,
228
+ custom_agent_logger: Optional[Any] = None,
229
+ custom_team_logger: Optional[Any] = None,
230
+ custom_workflow_logger: Optional[Any] = None,
231
+ ) -> None:
232
+ """
233
+ Util to set custom loggers. These will be used everywhere across the Agno library.
234
+
235
+ Args:
236
+ custom_default_logger: Default logger to use (overrides agent_logger for default)
237
+ custom_agent_logger: Custom logger for agent operations
238
+ custom_team_logger: Custom logger for team operations
239
+ custom_workflow_logger: Custom logger for workflow operations
240
+ """
241
+ if custom_default_logger is not None:
242
+ global logger
243
+ logger = custom_default_logger
244
+
245
+ if custom_agent_logger is not None:
246
+ global agent_logger
247
+ agent_logger = custom_agent_logger
248
+
249
+ if custom_team_logger is not None:
250
+ global team_logger
251
+ team_logger = custom_team_logger
252
+
253
+ if custom_workflow_logger is not None:
254
+ global workflow_logger
255
+ workflow_logger = custom_workflow_logger