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
agno/tools/scrapegraph.py CHANGED
@@ -1,62 +1,222 @@
1
1
  import json
2
- import os
3
- from typing import Optional
2
+ from os import getenv
3
+ from typing import Any, List, Optional
4
4
 
5
5
  from agno.tools import Toolkit
6
+ from agno.utils.log import log_debug, log_error
6
7
 
7
8
  try:
8
9
  from scrapegraph_py import Client
10
+ from scrapegraph_py.logger import sgai_logger
9
11
  except ImportError:
10
12
  raise ImportError("`scrapegraph-py` not installed. Please install using `pip install scrapegraph-py`")
11
13
 
14
+ # Set logging level
15
+ sgai_logger.set_logging(level="INFO")
16
+
12
17
 
13
18
  class ScrapeGraphTools(Toolkit):
14
19
  def __init__(
15
20
  self,
16
21
  api_key: Optional[str] = None,
17
- smartscraper: bool = True,
18
- markdownify: bool = False,
22
+ enable_smartscraper: bool = True,
23
+ enable_markdownify: bool = False,
24
+ enable_crawl: bool = False,
25
+ enable_searchscraper: bool = False,
26
+ enable_agentic_crawler: bool = False,
27
+ enable_scrape: bool = False,
28
+ render_heavy_js: bool = False,
29
+ all: bool = False,
30
+ **kwargs,
19
31
  ):
20
- super().__init__(name="scrapegraph_tools")
21
-
22
- self.api_key: Optional[str] = api_key or os.getenv("SGAI_API_KEY")
32
+ self.api_key: Optional[str] = api_key or getenv("SGAI_API_KEY")
23
33
  self.client = Client(api_key=self.api_key)
34
+ self.render_heavy_js = render_heavy_js
24
35
 
25
36
  # Start with smartscraper by default
26
37
  # Only enable markdownify if smartscraper is False
27
- if not smartscraper:
28
- markdownify = True
38
+ if not enable_smartscraper and not all:
39
+ enable_markdownify = True
40
+
41
+ tools: List[Any] = []
42
+ if enable_smartscraper or all:
43
+ tools.append(self.smartscraper)
44
+ if enable_markdownify or all:
45
+ tools.append(self.markdownify)
46
+ if enable_crawl or all:
47
+ tools.append(self.crawl)
48
+ if enable_searchscraper or all:
49
+ tools.append(self.searchscraper)
50
+ if enable_agentic_crawler or all:
51
+ tools.append(self.agentic_crawler)
52
+ if enable_scrape or all:
53
+ tools.append(self.scrape)
29
54
 
30
- if smartscraper:
31
- self.register(self.smartscraper)
32
- if markdownify:
33
- self.register(self.markdownify)
55
+ super().__init__(name="scrapegraph_tools", tools=tools, **kwargs)
34
56
 
35
57
  def smartscraper(self, url: str, prompt: str) -> str:
36
- """Use this function to extract structured data from a webpage using LLM.
58
+ """Extract structured data from a webpage using LLM.
37
59
  Args:
38
60
  url (str): The URL to scrape
39
61
  prompt (str): Natural language prompt describing what to extract
40
62
  Returns:
41
63
  The structured data extracted from the webpage
42
64
  """
43
-
44
65
  try:
66
+ log_debug(f"ScrapeGraph smartscraper request for URL: {url}")
45
67
  response = self.client.smartscraper(website_url=url, user_prompt=prompt)
46
68
  return json.dumps(response["result"])
47
69
  except Exception as e:
48
- return json.dumps({"error": str(e)})
70
+ error_msg = f"Smartscraper failed: {str(e)}"
71
+ log_error(error_msg)
72
+ return f"Error: {error_msg}"
49
73
 
50
74
  def markdownify(self, url: str) -> str:
51
- """Use this function to convert a webpage to markdown format.
75
+ """Convert a webpage to markdown format.
52
76
  Args:
53
77
  url (str): The URL to convert
54
78
  Returns:
55
79
  The markdown version of the webpage
56
80
  """
57
-
58
81
  try:
82
+ log_debug(f"ScrapeGraph markdownify request for URL: {url}")
59
83
  response = self.client.markdownify(website_url=url)
60
84
  return response["result"]
61
85
  except Exception as e:
62
- return f"Error converting to markdown: {str(e)}"
86
+ error_msg = f"Markdownify failed: {str(e)}"
87
+ log_error(error_msg)
88
+ return f"Error: {error_msg}"
89
+
90
+ def crawl(
91
+ self,
92
+ url: str,
93
+ prompt: str,
94
+ schema: dict,
95
+ cache_website: bool = True,
96
+ depth: int = 2,
97
+ max_pages: int = 2,
98
+ same_domain_only: bool = True,
99
+ batch_size: int = 1,
100
+ ) -> str:
101
+ """Crawl a website and extract structured data
102
+ Args:
103
+ url (str): The URL to crawl
104
+ prompt (str): Natural language prompt describing what to extract
105
+ schema (dict): JSON schema for extraction
106
+ cache_website (bool): Whether to cache the website
107
+ depth (int): Crawl depth
108
+ max_pages (int): Max number of pages to crawl
109
+ same_domain_only (bool): Restrict to same domain
110
+ batch_size (int): Batch size for crawling
111
+ Returns:
112
+ The structured data extracted from the website
113
+ """
114
+ try:
115
+ log_debug(f"ScrapeGraph crawl request for URL: {url}")
116
+ response = self.client.crawl(
117
+ url=url,
118
+ prompt=prompt,
119
+ data_schema=schema,
120
+ cache_website=cache_website,
121
+ depth=depth,
122
+ max_pages=max_pages,
123
+ same_domain_only=same_domain_only,
124
+ batch_size=batch_size,
125
+ )
126
+ return json.dumps(response, indent=2)
127
+ except Exception as e:
128
+ error_msg = f"Crawl failed: {str(e)}"
129
+ log_error(error_msg)
130
+ return f"Error: {error_msg}"
131
+
132
+ def agentic_crawler(
133
+ self,
134
+ url: str,
135
+ steps: List[str],
136
+ use_session: bool = True,
137
+ user_prompt: Optional[str] = None,
138
+ output_schema: Optional[dict] = None,
139
+ ai_extraction: bool = False,
140
+ ) -> str:
141
+ """Perform agentic crawling with automated browser actions and optional AI extraction.
142
+
143
+ This tool can:
144
+ 1. Navigate to a website
145
+ 2. Perform a series of automated actions (like filling forms, clicking buttons)
146
+ 3. Extract the resulting HTML content as markdown
147
+ 4. Optionally use AI to extract structured data
148
+
149
+ Args:
150
+ url (str): The URL to scrape
151
+ steps (List[str]): List of steps to perform on the webpage (e.g., ["Type email in input box", "click login"])
152
+ use_session (bool): Whether to use session for the scraping (default: True)
153
+ user_prompt (Optional[str]): Prompt for AI extraction (only used when ai_extraction=True)
154
+ output_schema (Optional[dict]): Schema for structured data extraction (only used when ai_extraction=True)
155
+ ai_extraction (bool): Whether to use AI for data extraction from the scraped content (default: False)
156
+
157
+ Returns:
158
+ JSON string containing the scraping results, including request_id, status, and extracted data
159
+ """
160
+ try:
161
+ log_debug(f"ScrapeGraph agentic_crawler request for URL: {url}")
162
+
163
+ # Prepare parameters for the API call
164
+ params = {"url": url, "steps": steps, "use_session": use_session, "ai_extraction": ai_extraction}
165
+
166
+ # Add optional parameters only if they are provided
167
+ if user_prompt:
168
+ params["user_prompt"] = user_prompt
169
+ if output_schema:
170
+ params["output_schema"] = output_schema
171
+
172
+ # Call the agentic scraper API
173
+ response = self.client.agenticscraper(**params)
174
+ return json.dumps(response, indent=2)
175
+
176
+ except Exception as e:
177
+ error_msg = f"Agentic crawler failed: {str(e)}"
178
+ log_error(error_msg)
179
+ return f"Error: {error_msg}"
180
+
181
+ def searchscraper(self, user_prompt: str) -> str:
182
+ """Search the web and extract information from the web.
183
+ Args:
184
+ user_prompt (str): Search query
185
+ Returns:
186
+ JSON of the search results
187
+ """
188
+ try:
189
+ log_debug(f"ScrapeGraph searchscraper request with prompt: {user_prompt}")
190
+ response = self.client.searchscraper(user_prompt=user_prompt)
191
+ return json.dumps(response["result"])
192
+ except Exception as e:
193
+ error_msg = f"Searchscraper failed: {str(e)}"
194
+ log_error(error_msg)
195
+ return f"Error: {error_msg}"
196
+
197
+ def scrape(
198
+ self,
199
+ website_url: str,
200
+ headers: Optional[dict] = None,
201
+ ) -> str:
202
+ """Get raw HTML content from a website using the ScrapeGraphAI scrape API.
203
+
204
+ Args:
205
+ website_url (str): The URL of the website to scrape
206
+ headers (Optional[dict]): Optional headers to send with the request
207
+
208
+ Returns:
209
+ JSON string containing the HTML content and metadata
210
+ """
211
+ try:
212
+ log_debug(f"ScrapeGraph scrape request for URL: {website_url}")
213
+ response = self.client.scrape(
214
+ website_url=website_url,
215
+ headers=headers,
216
+ render_heavy_js=self.render_heavy_js,
217
+ )
218
+ return json.dumps(response, indent=2)
219
+ except Exception as e:
220
+ error_msg = f"Scrape failed: {str(e)}"
221
+ log_error(error_msg)
222
+ return f"Error: {error_msg}"
agno/tools/searxng.py CHANGED
@@ -1,11 +1,11 @@
1
1
  import json
2
2
  import urllib.parse
3
- from typing import List, Optional
3
+ from typing import Any, List, Optional
4
4
 
5
5
  import httpx
6
6
 
7
- from agno.tools.toolkit import Toolkit
8
- from agno.utils.log import logger
7
+ from agno.tools import Toolkit
8
+ from agno.utils.log import log_info
9
9
 
10
10
 
11
11
  class Searxng(Toolkit):
@@ -14,38 +14,26 @@ class Searxng(Toolkit):
14
14
  host: str,
15
15
  engines: List[str] = [],
16
16
  fixed_max_results: Optional[int] = None,
17
- images: bool = False,
18
- it: bool = False,
19
- map: bool = False,
20
- music: bool = False,
21
- news: bool = False,
22
- science: bool = False,
23
- videos: bool = False,
17
+ **kwargs,
24
18
  ):
25
- super().__init__(name="searxng")
26
-
27
19
  self.host = host
28
20
  self.engines = engines
29
21
  self.fixed_max_results = fixed_max_results
30
22
 
31
- self.register(self.search)
32
-
33
- if images:
34
- self.register(self.image_search)
35
- if it:
36
- self.register(self.it_search)
37
- if map:
38
- self.register(self.map_search)
39
- if music:
40
- self.register(self.music_search)
41
- if news:
42
- self.register(self.news_search)
43
- if science:
44
- self.register(self.science_search)
45
- if videos:
46
- self.register(self.video_search)
47
-
48
- def search(self, query: str, max_results: int = 5) -> str:
23
+ tools: List[Any] = [
24
+ self.search_web,
25
+ self.image_search,
26
+ self.it_search,
27
+ self.map_search,
28
+ self.music_search,
29
+ self.news_search,
30
+ self.science_search,
31
+ self.video_search,
32
+ ]
33
+
34
+ super().__init__(name="searxng", tools=tools, **kwargs)
35
+
36
+ def search_web(self, query: str, max_results: int = 5) -> str:
49
37
  """Use this function to search the web.
50
38
 
51
39
  Args:
@@ -150,7 +138,7 @@ class Searxng(Toolkit):
150
138
  if category:
151
139
  url += f"&categories={category}"
152
140
 
153
- logger.info(f"Fetching results from searxng: {url}")
141
+ log_info(f"Fetching results from searxng: {url}")
154
142
  try:
155
143
  resp = httpx.get(url).json()
156
144
  results = self.fixed_max_results or max_results
@@ -158,3 +146,7 @@ class Searxng(Toolkit):
158
146
  return json.dumps(resp)
159
147
  except Exception as e:
160
148
  return f"Error fetching results from searxng: {e}"
149
+
150
+
151
+ # Alias for consistency with other tools
152
+ SearxngTools = Searxng
agno/tools/serpapi.py CHANGED
@@ -1,9 +1,9 @@
1
1
  import json
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, List, Optional
4
4
 
5
5
  from agno.tools import Toolkit
6
- from agno.utils.log import logger
6
+ from agno.utils.log import log_info, logger
7
7
 
8
8
  try:
9
9
  import serpapi
@@ -15,17 +15,22 @@ class SerpApiTools(Toolkit):
15
15
  def __init__(
16
16
  self,
17
17
  api_key: Optional[str] = None,
18
- search_youtube: bool = False,
18
+ enable_search_google: bool = True,
19
+ enable_search_youtube: bool = False,
20
+ all: bool = False,
21
+ **kwargs,
19
22
  ):
20
- super().__init__(name="serpapi_tools")
21
-
22
23
  self.api_key = api_key or getenv("SERP_API_KEY")
23
24
  if not self.api_key:
24
25
  logger.warning("No Serpapi API key provided")
25
26
 
26
- self.register(self.search_google)
27
- if search_youtube:
28
- self.register(self.search_youtube)
27
+ tools: List[Any] = []
28
+ if all or enable_search_google:
29
+ tools.append(self.search_google)
30
+ if all or enable_search_youtube:
31
+ tools.append(self.search_youtube)
32
+
33
+ super().__init__(name="serpapi_tools", tools=tools, **kwargs)
29
34
 
30
35
  def search_google(self, query: str, num_results: int = 10) -> str:
31
36
  """
@@ -51,7 +56,7 @@ class SerpApiTools(Toolkit):
51
56
  if not query:
52
57
  return "Please provide a query to search for"
53
58
 
54
- logger.info(f"Searching Google for: {query}")
59
+ log_info(f"Searching Google for: {query}")
55
60
 
56
61
  params = {"q": query, "api_key": self.api_key, "num": num_results}
57
62
 
@@ -92,7 +97,7 @@ class SerpApiTools(Toolkit):
92
97
  if not query:
93
98
  return "Please provide a query to search for"
94
99
 
95
- logger.info(f"Searching Youtube for: {query}")
100
+ log_info(f"Searching Youtube for: {query}")
96
101
 
97
102
  params = {"search_query": query, "api_key": self.api_key}
98
103
 
agno/tools/serper.py ADDED
@@ -0,0 +1,255 @@
1
+ import json
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ import requests
6
+
7
+ from agno.tools import Toolkit
8
+ from agno.utils.log import log_debug, log_error, log_warning
9
+
10
+
11
+ class SerperTools(Toolkit):
12
+ def __init__(
13
+ self,
14
+ api_key: Optional[str] = None,
15
+ location: str = "us",
16
+ language: str = "en",
17
+ num_results: int = 10,
18
+ date_range: Optional[str] = None,
19
+ enable_search: bool = True,
20
+ enable_search_news: bool = True,
21
+ enable_search_scholar: bool = True,
22
+ enable_scrape_webpage: bool = True,
23
+ all: bool = False,
24
+ **kwargs,
25
+ ):
26
+ """
27
+ Initialize the SerperTools.
28
+
29
+ Args:
30
+ api_key Optional[str]: The Serper API key.
31
+ location Optional[str]: The Google location code for search results.
32
+ language Optional[str]: The language code for search results.
33
+ num_results Optional[int]: The number of search results to retrieve.
34
+ date_range Optional[str]: Default date range filter for searches.
35
+ """
36
+ self.api_key = api_key or getenv("SERPER_API_KEY")
37
+ if not self.api_key:
38
+ log_debug("No Serper API key provided")
39
+
40
+ self.location = location
41
+ self.language = language
42
+ self.num_results = num_results
43
+ self.date_range = date_range
44
+
45
+ tools: List[Any] = []
46
+ if all or enable_search:
47
+ tools.append(self.search_web)
48
+ if all or enable_search_news:
49
+ tools.append(self.search_news)
50
+ if all or enable_search_scholar:
51
+ tools.append(self.search_scholar)
52
+ if all or enable_scrape_webpage:
53
+ tools.append(self.scrape_webpage)
54
+
55
+ super().__init__(name="serper_tools", tools=tools, **kwargs)
56
+
57
+ def _make_request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]:
58
+ """
59
+ Makes a request to the Serper API.
60
+
61
+ Args:
62
+ endpoint (str): The API endpoint
63
+ params (Dict[str, Any]): Request parameters
64
+
65
+ Returns:
66
+ Dict[str, Any]: Search response
67
+ """
68
+ try:
69
+ if not self.api_key:
70
+ log_error("No Serper API key provided")
71
+ return {"success": False, "error": "Please provide a Serper API key"}
72
+
73
+ url = f"https://google.serper.dev/{endpoint}"
74
+ if endpoint == "scrape":
75
+ url = "https://scrape.serper.dev"
76
+
77
+ headers = {"X-API-KEY": self.api_key, "Content-Type": "application/json"}
78
+
79
+ # Add optional parameters
80
+ if self.date_range:
81
+ params["tbs"] = self.date_range
82
+ if self.location:
83
+ params["gl"] = self.location
84
+
85
+ if self.language:
86
+ params["hl"] = self.language
87
+
88
+ payload = json.dumps(params)
89
+
90
+ log_debug(f"Making request to {url} with params: {params}")
91
+ response = requests.request("POST", url, headers=headers, data=payload)
92
+ response.raise_for_status()
93
+
94
+ log_debug(f"Successfully received response from {endpoint} endpoint")
95
+ return {"success": True, "data": response.json(), "raw_response": response.text}
96
+ except Exception as e:
97
+ log_error(f"Serper API error: {str(e)}")
98
+ return {"success": False, "error": str(e)}
99
+
100
+ def search_web(
101
+ self,
102
+ query: str,
103
+ num_results: Optional[int] = None,
104
+ ) -> str:
105
+ """
106
+ Searches Google for the provided query using the Serper API.
107
+
108
+ Args:
109
+ query (str): The search query to search for on Google.
110
+ num_results (int, optional): Number of search results to retrieve.
111
+
112
+ Returns:
113
+ str: A JSON-formatted string containing the search results or an error message if the search fails.
114
+ """
115
+ try:
116
+ if not query:
117
+ return json.dumps({"error": "Please provide a query to search for"}, indent=2)
118
+
119
+ log_debug(f"Searching Google for: {query}")
120
+
121
+ params = {
122
+ "q": query,
123
+ "num": num_results or self.num_results,
124
+ }
125
+
126
+ result = self._make_request("search", params)
127
+
128
+ if result["success"]:
129
+ log_debug(f"Successfully found Google search results for query: {query}")
130
+ return result["raw_response"]
131
+ else:
132
+ log_error(f"Error searching Google for query {query}: {result['error']}")
133
+ return json.dumps({"error": result["error"]}, indent=2)
134
+
135
+ except Exception as e:
136
+ log_error(f"Unexpected error searching Google for query {query}: {e}")
137
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, indent=2)
138
+
139
+ def search_news(
140
+ self,
141
+ query: str,
142
+ num_results: Optional[int] = None,
143
+ ) -> str:
144
+ """
145
+ Searches for news articles using the Serper News API.
146
+
147
+ Args:
148
+ query (str): The search query for news articles.
149
+ num_results (int, optional): Number of news results to retrieve.
150
+
151
+ Returns:
152
+ str: A JSON-formatted string containing the news search results or an error message.
153
+ """
154
+ try:
155
+ if not query:
156
+ return json.dumps({"error": "Please provide a query to search for news"}, indent=2)
157
+
158
+ log_debug(f"Searching news for: {query}")
159
+
160
+ params = {
161
+ "q": query,
162
+ "num": num_results or self.num_results,
163
+ }
164
+
165
+ result = self._make_request("news", params)
166
+
167
+ if result["success"]:
168
+ log_debug(f"Successfully found {num_results or self.num_results} news articles for query: {query}")
169
+ return result["raw_response"]
170
+ else:
171
+ log_error(f"Error searching news for query {query}: {result['error']}")
172
+ return json.dumps({"error": result["error"]}, indent=2)
173
+
174
+ except Exception as e:
175
+ log_error(f"Unexpected error searching news for query {query}: {e}")
176
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, indent=2)
177
+
178
+ def search_scholar(
179
+ self,
180
+ query: str,
181
+ num_results: Optional[int] = None,
182
+ ) -> str:
183
+ """
184
+ Searches for academic papers using Google Scholar via Serper API.
185
+
186
+ Args:
187
+ query (str): The search query for academic papers.
188
+ num_results (int, optional): Number of academic papers to retrieve.
189
+
190
+ Returns:
191
+ str: A JSON-formatted string containing the scholar search results or an error message.
192
+ """
193
+ try:
194
+ if not query:
195
+ return json.dumps({"error": "Please provide a query to search for academic papers"}, indent=2)
196
+
197
+ log_debug(f"Searching scholar for: {query}")
198
+
199
+ params = {
200
+ "q": query,
201
+ "num": num_results or self.num_results,
202
+ }
203
+
204
+ result = self._make_request("scholar", params)
205
+
206
+ if result["success"]:
207
+ log_debug(f"Successfully found academic papers for query: {query}")
208
+ return result["raw_response"]
209
+ else:
210
+ log_error(f"Error searching scholar for query {query}: {result['error']}")
211
+ return json.dumps({"error": result["error"]}, indent=2)
212
+
213
+ except Exception as e:
214
+ log_error(f"Unexpected error searching scholar for query {query}: {e}")
215
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, indent=2)
216
+
217
+ def scrape_webpage(
218
+ self,
219
+ url: str,
220
+ markdown: bool = False,
221
+ ) -> str:
222
+ """
223
+ Scrapes and extracts content from a webpage using the Serper scraping API.
224
+
225
+ Args:
226
+ url (str): The URL of the webpage to scrape.
227
+ markdown (bool, optional): Return content in markdown format (default: False).
228
+
229
+ Returns:
230
+ str: A JSON-formatted string containing the scraped webpage content or an error message.
231
+ """
232
+ try:
233
+ if not url:
234
+ log_warning("No URL provided to scrape")
235
+ return json.dumps({"error": "Please provide a URL to scrape"}, indent=2)
236
+
237
+ log_debug(f"Scraping webpage: {url}")
238
+
239
+ params = {
240
+ "url": url,
241
+ "includeMarkdown": markdown,
242
+ }
243
+
244
+ result = self._make_request("scrape", params)
245
+
246
+ if result["success"]:
247
+ log_debug(f"Successfully scraped webpage: {url}")
248
+ return result["raw_response"]
249
+ else:
250
+ log_error(f"Error scraping webpage {url}: {result['error']}")
251
+ return json.dumps({"error": result["error"]}, indent=2)
252
+
253
+ except Exception as e:
254
+ log_error(f"Unexpected error scraping webpage {url}: {e}")
255
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, indent=2)