agno 0.1.2__py3-none-any.whl → 2.3.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 (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -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 +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -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 +1791 -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 +1312 -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 +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,467 @@
1
+ import json
2
+ import os
3
+ from typing import Any, Dict, List, Optional, Union
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import log_info, logger
7
+
8
+
9
+ class VisualizationTools(Toolkit):
10
+ def __init__(
11
+ self,
12
+ output_dir: str = "charts",
13
+ enable_create_bar_chart: bool = True,
14
+ enable_create_line_chart: bool = True,
15
+ enable_create_pie_chart: bool = True,
16
+ enable_create_scatter_plot: bool = True,
17
+ enable_create_histogram: bool = True,
18
+ all: bool = False,
19
+ **kwargs,
20
+ ):
21
+ """
22
+ Initialize the VisualizationTools toolkit.
23
+
24
+ Args:
25
+ output_dir (str): Directory to save charts. Default is "charts".
26
+ """
27
+ # Check if matplotlib is available
28
+ try:
29
+ import matplotlib
30
+
31
+ # Use non-interactive backend to avoid display issues
32
+ matplotlib.use("Agg")
33
+ except ImportError:
34
+ raise ImportError("matplotlib is not installed. Please install it using: `pip install matplotlib`")
35
+
36
+ # Create output directory if it doesn't exist
37
+ if not os.path.exists(output_dir):
38
+ os.makedirs(output_dir)
39
+
40
+ self.output_dir = output_dir
41
+
42
+ tools: List[Any] = []
43
+ if enable_create_bar_chart or all:
44
+ tools.append(self.create_bar_chart)
45
+ if enable_create_line_chart or all:
46
+ tools.append(self.create_line_chart)
47
+ if enable_create_pie_chart or all:
48
+ tools.append(self.create_pie_chart)
49
+ if enable_create_scatter_plot or all:
50
+ tools.append(self.create_scatter_plot)
51
+ if enable_create_histogram or all:
52
+ tools.append(self.create_histogram)
53
+
54
+ super().__init__(name="visualization_tools", tools=tools, **kwargs)
55
+
56
+ def _normalize_data_for_charts(
57
+ self, data: Union[Dict[str, Any], List[Dict[str, Any]], List[Any], str]
58
+ ) -> Dict[str, Union[int, float]]:
59
+ """
60
+ Normalize various data formats into a simple dictionary format for charts.
61
+
62
+ Args:
63
+ data: Can be a dict, list of dicts, or list of values
64
+
65
+ Returns:
66
+ Dict with string keys and numeric values
67
+ """
68
+ if isinstance(data, dict):
69
+ # Already in the right format, just ensure values are numeric
70
+ return {str(k): float(v) if isinstance(v, (int, float)) else 0 for k, v in data.items()}
71
+
72
+ elif isinstance(data, list) and len(data) > 0:
73
+ if isinstance(data[0], dict):
74
+ # List of dictionaries - try to find key-value pairs
75
+ result = {}
76
+ for item in data:
77
+ if isinstance(item, dict):
78
+ # Look for common key patterns
79
+ keys = list(item.keys())
80
+ if len(keys) >= 2:
81
+ # Use first key as label, second as value
82
+ label_key = keys[0]
83
+ value_key = keys[1]
84
+ result[str(item[label_key])] = (
85
+ float(item[value_key]) if isinstance(item[value_key], (int, float)) else 0
86
+ )
87
+ return result
88
+ else:
89
+ # List of values - create numbered keys
90
+ return {f"Item {i + 1}": float(v) if isinstance(v, (int, float)) else 0 for i, v in enumerate(data)}
91
+
92
+ # Fallback
93
+ return {"Data": 1.0}
94
+
95
+ def create_bar_chart(
96
+ self,
97
+ data: Union[Dict[str, Union[int, float]], List[Dict[str, Any]], str],
98
+ title: str = "Bar Chart",
99
+ x_label: str = "Categories",
100
+ y_label: str = "Values",
101
+ filename: Optional[str] = None,
102
+ ) -> str:
103
+ """
104
+ Create a bar chart from the provided data.
105
+
106
+ Args:
107
+ data: Dictionary with categories as keys and values as numbers,
108
+ or list of dictionaries, or JSON string
109
+ title (str): Title of the chart
110
+ x_label (str): Label for x-axis
111
+ y_label (str): Label for y-axis
112
+ filename (Optional[str]): Custom filename for the chart image
113
+
114
+ Returns:
115
+ str: JSON string with chart information and file path
116
+ """
117
+ try:
118
+ import matplotlib.pyplot as plt
119
+
120
+ # Handle string input (JSON)
121
+ if isinstance(data, str):
122
+ try:
123
+ data = json.loads(data)
124
+ except json.JSONDecodeError:
125
+ pass
126
+
127
+ # Normalize data format
128
+ normalized_data = self._normalize_data_for_charts(data)
129
+
130
+ # Prepare data
131
+ categories = list(normalized_data.keys())
132
+ values = list(normalized_data.values())
133
+
134
+ # Create the chart
135
+ plt.figure(figsize=(10, 6))
136
+ plt.bar(categories, values)
137
+ plt.title(title)
138
+ plt.xlabel(x_label)
139
+ plt.ylabel(y_label)
140
+ plt.xticks(rotation=45, ha="right")
141
+ plt.tight_layout()
142
+
143
+ # Save the chart
144
+ if filename is None:
145
+ filename = f"bar_chart_{len(os.listdir(self.output_dir)) + 1}.png"
146
+
147
+ file_path = os.path.join(self.output_dir, filename)
148
+ plt.savefig(file_path, dpi=300, bbox_inches="tight")
149
+ plt.close()
150
+
151
+ log_info(f"Bar chart created and saved to {file_path}")
152
+
153
+ return json.dumps(
154
+ {
155
+ "chart_type": "bar_chart",
156
+ "title": title,
157
+ "file_path": file_path,
158
+ "data_points": len(normalized_data),
159
+ "status": "success",
160
+ }
161
+ )
162
+
163
+ except Exception as e:
164
+ logger.error(f"Error creating bar chart: {str(e)}")
165
+ return json.dumps({"chart_type": "bar_chart", "error": str(e), "status": "error"})
166
+
167
+ def create_line_chart(
168
+ self,
169
+ data: Union[Dict[str, Union[int, float]], List[Dict[str, Any]], str],
170
+ title: str = "Line Chart",
171
+ x_label: str = "X-axis",
172
+ y_label: str = "Y-axis",
173
+ filename: Optional[str] = None,
174
+ ) -> str:
175
+ """
176
+ Create a line chart from the provided data.
177
+
178
+ Args:
179
+ data: Dictionary with x-values as keys and y-values as numbers,
180
+ or list of dictionaries, or JSON string
181
+ title (str): Title of the chart
182
+ x_label (str): Label for x-axis
183
+ y_label (str): Label for y-axis
184
+ filename (Optional[str]): Custom filename for the chart image
185
+
186
+ Returns:
187
+ str: JSON string with chart information and file path
188
+ """
189
+ try:
190
+ import matplotlib.pyplot as plt
191
+
192
+ # Handle string input (JSON)
193
+ if isinstance(data, str):
194
+ try:
195
+ data = json.loads(data)
196
+ except json.JSONDecodeError:
197
+ pass
198
+
199
+ # Normalize data format
200
+ normalized_data = self._normalize_data_for_charts(data)
201
+
202
+ # Prepare data
203
+ x_values = list(normalized_data.keys())
204
+ y_values = list(normalized_data.values())
205
+
206
+ # Create the chart
207
+ plt.figure(figsize=(10, 6))
208
+ plt.plot(x_values, y_values, marker="o", linewidth=2, markersize=6)
209
+ plt.title(title)
210
+ plt.xlabel(x_label)
211
+ plt.ylabel(y_label)
212
+ plt.xticks(rotation=45, ha="right")
213
+ plt.grid(True, alpha=0.3)
214
+ plt.tight_layout()
215
+
216
+ # Save the chart
217
+ if filename is None:
218
+ filename = f"line_chart_{len(os.listdir(self.output_dir)) + 1}.png"
219
+
220
+ file_path = os.path.join(self.output_dir, filename)
221
+ plt.savefig(file_path, dpi=300, bbox_inches="tight")
222
+ plt.close()
223
+
224
+ log_info(f"Line chart created and saved to {file_path}")
225
+
226
+ return json.dumps(
227
+ {
228
+ "chart_type": "line_chart",
229
+ "title": title,
230
+ "file_path": file_path,
231
+ "data_points": len(normalized_data),
232
+ "status": "success",
233
+ }
234
+ )
235
+
236
+ except Exception as e:
237
+ logger.error(f"Error creating line chart: {str(e)}")
238
+ return json.dumps({"chart_type": "line_chart", "error": str(e), "status": "error"})
239
+
240
+ def create_pie_chart(
241
+ self,
242
+ data: Union[Dict[str, Union[int, float]], List[Dict[str, Any]], str],
243
+ title: str = "Pie Chart",
244
+ filename: Optional[str] = None,
245
+ ) -> str:
246
+ """
247
+ Create a pie chart from the provided data.
248
+
249
+ Args:
250
+ data: Dictionary with categories as keys and values as numbers,
251
+ or list of dictionaries, or JSON string
252
+ title (str): Title of the chart
253
+ filename (Optional[str]): Custom filename for the chart image
254
+
255
+ Returns:
256
+ str: JSON string with chart information and file path
257
+ """
258
+ try:
259
+ import matplotlib.pyplot as plt
260
+
261
+ # Handle string input (JSON)
262
+ if isinstance(data, str):
263
+ try:
264
+ data = json.loads(data)
265
+ except json.JSONDecodeError:
266
+ pass
267
+
268
+ # Normalize data format
269
+ normalized_data = self._normalize_data_for_charts(data)
270
+
271
+ # Prepare data
272
+ labels = list(normalized_data.keys())
273
+ values = list(normalized_data.values())
274
+
275
+ # Create the chart
276
+ plt.figure(figsize=(10, 8))
277
+ plt.pie(values, labels=labels, autopct="%1.1f%%", startangle=90)
278
+ plt.title(title)
279
+ plt.axis("equal") # Equal aspect ratio ensures that pie is drawn as a circle
280
+
281
+ # Save the chart
282
+ if filename is None:
283
+ filename = f"pie_chart_{len(os.listdir(self.output_dir)) + 1}.png"
284
+
285
+ file_path = os.path.join(self.output_dir, filename)
286
+ plt.savefig(file_path, dpi=300, bbox_inches="tight")
287
+ plt.close()
288
+
289
+ log_info(f"Pie chart created and saved to {file_path}")
290
+
291
+ return json.dumps(
292
+ {
293
+ "chart_type": "pie_chart",
294
+ "title": title,
295
+ "file_path": file_path,
296
+ "data_points": len(normalized_data),
297
+ "status": "success",
298
+ }
299
+ )
300
+
301
+ except Exception as e:
302
+ logger.error(f"Error creating pie chart: {str(e)}")
303
+ return json.dumps({"chart_type": "pie_chart", "error": str(e), "status": "error"})
304
+
305
+ def create_scatter_plot(
306
+ self,
307
+ x_data: Optional[List[Union[int, float]]] = None,
308
+ y_data: Optional[List[Union[int, float]]] = None,
309
+ title: str = "Scatter Plot",
310
+ x_label: str = "X-axis",
311
+ y_label: str = "Y-axis",
312
+ filename: Optional[str] = None,
313
+ # Alternative parameter names that agents might use
314
+ x: Optional[List[Union[int, float]]] = None,
315
+ y: Optional[List[Union[int, float]]] = None,
316
+ data: Optional[Union[List[List[Union[int, float]]], Dict[str, List[Union[int, float]]]]] = None,
317
+ ) -> str:
318
+ """
319
+ Create a scatter plot from the provided data.
320
+
321
+ Args:
322
+ x_data: List of x-values (can also use 'x' parameter)
323
+ y_data: List of y-values (can also use 'y' parameter)
324
+ title (str): Title of the chart
325
+ x_label (str): Label for x-axis
326
+ y_label (str): Label for y-axis
327
+ filename (Optional[str]): Custom filename for the chart image
328
+ data: Alternative format - list of [x,y] pairs or dict with 'x' and 'y' keys
329
+
330
+ Returns:
331
+ str: JSON string with chart information and file path
332
+ """
333
+ try:
334
+ import matplotlib.pyplot as plt
335
+
336
+ # Handle different parameter formats
337
+ if x_data is None:
338
+ x_data = x
339
+ if y_data is None:
340
+ y_data = y
341
+
342
+ # Handle data parameter
343
+ if data is not None:
344
+ if isinstance(data, dict):
345
+ if "x" in data and "y" in data:
346
+ x_data = data["x"]
347
+ y_data = data["y"]
348
+ elif isinstance(data, list) and len(data) > 0:
349
+ if isinstance(data[0], list) and len(data[0]) == 2:
350
+ # List of [x,y] pairs
351
+ x_data = [point[0] for point in data]
352
+ y_data = [point[1] for point in data]
353
+
354
+ # Validate that we have data
355
+ if x_data is None or y_data is None:
356
+ raise ValueError("Missing x_data and y_data parameters")
357
+
358
+ if len(x_data) != len(y_data):
359
+ raise ValueError("x_data and y_data must have the same length")
360
+
361
+ # Create the chart
362
+ plt.figure(figsize=(10, 6))
363
+ plt.scatter(x_data, y_data, alpha=0.7, s=50)
364
+ plt.title(title)
365
+ plt.xlabel(x_label)
366
+ plt.ylabel(y_label)
367
+ plt.grid(True, alpha=0.3)
368
+ plt.tight_layout()
369
+
370
+ # Save the chart
371
+ if filename is None:
372
+ filename = f"scatter_plot_{len(os.listdir(self.output_dir)) + 1}.png"
373
+
374
+ file_path = os.path.join(self.output_dir, filename)
375
+ plt.savefig(file_path, dpi=300, bbox_inches="tight")
376
+ plt.close()
377
+
378
+ log_info(f"Scatter plot created and saved to {file_path}")
379
+
380
+ return json.dumps(
381
+ {
382
+ "chart_type": "scatter_plot",
383
+ "title": title,
384
+ "file_path": file_path,
385
+ "data_points": len(x_data),
386
+ "status": "success",
387
+ }
388
+ )
389
+
390
+ except Exception as e:
391
+ logger.error(f"Error creating scatter plot: {str(e)}")
392
+ return json.dumps({"chart_type": "scatter_plot", "error": str(e), "status": "error"})
393
+
394
+ def create_histogram(
395
+ self,
396
+ data: List[Union[int, float]],
397
+ bins: int = 10,
398
+ title: str = "Histogram",
399
+ x_label: str = "Values",
400
+ y_label: str = "Frequency",
401
+ filename: Optional[str] = None,
402
+ ) -> str:
403
+ """
404
+ Create a histogram from the provided data.
405
+
406
+ Args:
407
+ data: List of numeric values to plot
408
+ bins (int): Number of bins for the histogram
409
+ title (str): Title of the chart
410
+ x_label (str): Label for x-axis
411
+ y_label (str): Label for y-axis
412
+ filename (Optional[str]): Custom filename for the chart image
413
+
414
+ Returns:
415
+ str: JSON string with chart information and file path
416
+ """
417
+ try:
418
+ import matplotlib.pyplot as plt
419
+
420
+ # Validate data
421
+ if not isinstance(data, list) or len(data) == 0:
422
+ raise ValueError("Data must be a non-empty list of numbers")
423
+
424
+ # Convert to numeric values
425
+ numeric_data = []
426
+ for value in data:
427
+ try:
428
+ numeric_data.append(float(value))
429
+ except (ValueError, TypeError):
430
+ continue
431
+
432
+ if len(numeric_data) == 0:
433
+ raise ValueError("No valid numeric data found")
434
+
435
+ # Create the chart
436
+ plt.figure(figsize=(10, 6))
437
+ plt.hist(numeric_data, bins=bins, alpha=0.7, edgecolor="black")
438
+ plt.title(title)
439
+ plt.xlabel(x_label)
440
+ plt.ylabel(y_label)
441
+ plt.grid(True, alpha=0.3)
442
+ plt.tight_layout()
443
+
444
+ # Save the chart
445
+ if filename is None:
446
+ filename = f"histogram_{len(os.listdir(self.output_dir)) + 1}.png"
447
+
448
+ file_path = os.path.join(self.output_dir, filename)
449
+ plt.savefig(file_path, dpi=300, bbox_inches="tight")
450
+ plt.close()
451
+
452
+ log_info(f"Histogram created and saved to {file_path}")
453
+
454
+ return json.dumps(
455
+ {
456
+ "chart_type": "histogram",
457
+ "title": title,
458
+ "file_path": file_path,
459
+ "data_points": len(numeric_data),
460
+ "bins": bins,
461
+ "status": "success",
462
+ }
463
+ )
464
+
465
+ except Exception as e:
466
+ logger.error(f"Error creating histogram: {str(e)}")
467
+ return json.dumps({"chart_type": "histogram", "error": str(e), "status": "error"})
@@ -0,0 +1,28 @@
1
+ import webbrowser
2
+ from typing import Any, List
3
+
4
+ from agno.tools import Toolkit
5
+
6
+
7
+ class WebBrowserTools(Toolkit):
8
+ """Tools for opening a page on the web browser"""
9
+
10
+ def __init__(self, enable_open_page: bool = True, all: bool = False, **kwargs):
11
+ tools: List[Any] = []
12
+ if all or enable_open_page:
13
+ tools.append(self.open_page)
14
+
15
+ super().__init__(name="webbrowser_tools", tools=tools, **kwargs)
16
+
17
+ def open_page(self, url: str, new_window: bool = False):
18
+ """Open a URL in a browser window
19
+ Args:
20
+ url (str): URL to open
21
+ new_window (bool): If True, open in a new window, otherwise open in a new tab. Default is False.
22
+ Returns:
23
+ None
24
+ """
25
+ if new_window:
26
+ webbrowser.open_new(url)
27
+ else:
28
+ webbrowser.open_new_tab(url)
agno/tools/webex.py ADDED
@@ -0,0 +1,76 @@
1
+ import json
2
+ from os import getenv
3
+ from typing import Any, List, Optional
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import logger
7
+
8
+ try:
9
+ from webexpythonsdk import WebexAPI
10
+ from webexpythonsdk.exceptions import ApiError
11
+ except ImportError:
12
+ logger.error("Webex tools require the `webexpythonsdk` package. Run `pip install webexpythonsdk` to install it.")
13
+
14
+
15
+ class WebexTools(Toolkit):
16
+ def __init__(
17
+ self,
18
+ enable_send_message: bool = True,
19
+ enable_list_rooms: bool = True,
20
+ all: bool = False,
21
+ access_token: Optional[str] = None,
22
+ **kwargs,
23
+ ):
24
+ access_token = access_token or getenv("WEBEX_ACCESS_TOKEN")
25
+ if access_token is None:
26
+ raise ValueError("Webex access token is not set. Please set the WEBEX_ACCESS_TOKEN environment variable.")
27
+
28
+ self.client = WebexAPI(access_token=access_token)
29
+
30
+ tools: List[Any] = []
31
+ if all or enable_send_message:
32
+ tools.append(self.send_message)
33
+ if all or enable_list_rooms:
34
+ tools.append(self.list_rooms)
35
+
36
+ super().__init__(name="webex", tools=tools, **kwargs)
37
+
38
+ def send_message(self, room_id: str, text: str) -> str:
39
+ """
40
+ Send a message to a Webex Room.
41
+ Args:
42
+ room_id (str): The Room ID to send the message to.
43
+ text (str): The text of the message to send.
44
+ Returns:
45
+ str: A JSON string containing the response from the Webex.
46
+ """
47
+ try:
48
+ response = self.client.messages.create(roomId=room_id, text=text)
49
+ return json.dumps(response.json_data)
50
+ except ApiError as e:
51
+ logger.error(f"Error sending message: {e} in room: {room_id}")
52
+ return json.dumps({"error": str(e)})
53
+
54
+ def list_rooms(self) -> str:
55
+ """
56
+ List all rooms in the Webex.
57
+ Returns:
58
+ str: A JSON string containing the list of rooms.
59
+ """
60
+ try:
61
+ response = self.client.rooms.list()
62
+ rooms_list = [
63
+ {
64
+ "id": room.id,
65
+ "title": room.title,
66
+ "type": room.type,
67
+ "isPublic": room.isPublic,
68
+ "isReadOnly": room.isReadOnly,
69
+ }
70
+ for room in response
71
+ ]
72
+
73
+ return json.dumps({"rooms": rooms_list}, indent=4)
74
+ except ApiError as e:
75
+ logger.error(f"Error listing rooms: {e}")
76
+ return json.dumps({"error": str(e)})
agno/tools/website.py CHANGED
@@ -1,23 +1,29 @@
1
1
  import json
2
- from typing import List, Optional
2
+ from typing import Any, List, Optional
3
3
 
4
- from agno.document import Document
5
- from agno.knowledge.website import WebsiteKnowledgeBase
4
+ from agno.knowledge.document import Document
5
+ from agno.knowledge.knowledge import Knowledge
6
6
  from agno.tools import Toolkit
7
- from agno.utils.log import logger
7
+ from agno.utils.log import log_debug
8
8
 
9
9
 
10
10
  class WebsiteTools(Toolkit):
11
- def __init__(self, knowledge_base: Optional[WebsiteKnowledgeBase] = None):
12
- super().__init__(name="website_tools")
13
- self.knowledge_base: Optional[WebsiteKnowledgeBase] = knowledge_base
14
-
15
- if self.knowledge_base is not None and isinstance(self.knowledge_base, WebsiteKnowledgeBase):
16
- self.register(self.add_website_to_knowledge_base)
11
+ def __init__(
12
+ self,
13
+ knowledge: Optional[Knowledge] = None,
14
+ **kwargs,
15
+ ):
16
+ self.knowledge: Optional[Knowledge] = knowledge
17
+
18
+ tools: List[Any] = []
19
+ if self.knowledge is not None:
20
+ tools.append(self.add_website_to_knowledge)
17
21
  else:
18
- self.register(self.read_url)
22
+ tools.append(self.read_url)
23
+
24
+ super().__init__(name="website_tools", tools=tools, **kwargs)
19
25
 
20
- def add_website_to_knowledge_base(self, url: str) -> str:
26
+ def add_website_to_knowledge(self, url: str) -> str:
21
27
  """This function adds a websites content to the knowledge base.
22
28
  NOTE: The website must start with https:// and should be a valid website.
23
29
 
@@ -26,13 +32,11 @@ class WebsiteTools(Toolkit):
26
32
  :param url: The url of the website to add.
27
33
  :return: 'Success' if the website was added to the knowledge base.
28
34
  """
29
- if self.knowledge_base is None:
35
+ if self.knowledge is None:
30
36
  return "Knowledge base not provided"
31
37
 
32
- logger.debug(f"Adding to knowledge base: {url}")
33
- self.knowledge_base.urls.append(url)
34
- logger.debug("Loading knowledge base.")
35
- self.knowledge_base.load(recreate=False)
38
+ log_debug(f"Adding to knowledge base: {url}")
39
+ self.knowledge.add_content(url=url)
36
40
  return "Success"
37
41
 
38
42
  def read_url(self, url: str) -> str:
@@ -41,10 +45,10 @@ class WebsiteTools(Toolkit):
41
45
  :param url: The url of the website to read.
42
46
  :return: Relevant documents from the website.
43
47
  """
44
- from agno.document.reader.website_reader import WebsiteReader
48
+ from agno.knowledge.reader.website_reader import WebsiteReader
45
49
 
46
50
  website = WebsiteReader()
47
51
 
48
- logger.debug(f"Reading website: {url}")
52
+ log_debug(f"Reading website: {url}")
49
53
  relevant_docs: List[Document] = website.read(url=url)
50
54
  return json.dumps([doc.to_dict() for doc in relevant_docs])
agno/tools/webtools.py ADDED
@@ -0,0 +1,45 @@
1
+ import httpx
2
+
3
+ from agno.tools import Toolkit
4
+ from agno.utils.log import logger
5
+
6
+
7
+ class WebTools(Toolkit):
8
+ """
9
+ A toolkit for working with web-related tools.
10
+ """
11
+
12
+ def __init__(
13
+ self,
14
+ retries: int = 3,
15
+ enable_expand_url: bool = True,
16
+ all: bool = False,
17
+ **kwargs,
18
+ ):
19
+ self.retries = retries
20
+
21
+ tools = []
22
+ if all or enable_expand_url:
23
+ tools.append(self.expand_url)
24
+
25
+ super().__init__(name="web_tools", tools=tools, **kwargs)
26
+
27
+ def expand_url(self, url: str) -> str:
28
+ """
29
+ Expands a shortened URL to its final destination using HTTP HEAD requests with retries.
30
+
31
+ :param url: The URL to expand.
32
+
33
+ :return: The final destination URL if successful; otherwise, returns the original URL.
34
+ """
35
+ timeout = 5
36
+ for attempt in range(1, self.retries + 1):
37
+ try:
38
+ response = httpx.head(url, follow_redirects=True, timeout=timeout)
39
+ final_url = response.url
40
+ logger.info(f"expand_url: {url} expanded to {final_url} on attempt {attempt}")
41
+ return str(final_url)
42
+ except Exception as e:
43
+ logger.error(f"Error expanding URL {url} on attempt {attempt}: {e}")
44
+
45
+ return url