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/duckdb.py CHANGED
@@ -1,7 +1,8 @@
1
+ from pathlib import Path
1
2
  from typing import Any, Dict, List, Optional, Tuple
2
3
 
3
4
  from agno.tools import Toolkit
4
- from agno.utils.log import logger
5
+ from agno.utils.log import log_debug, log_info, logger
5
6
 
6
7
  try:
7
8
  import duckdb
@@ -17,32 +18,31 @@ class DuckDbTools(Toolkit):
17
18
  init_commands: Optional[List] = None,
18
19
  read_only: bool = False,
19
20
  config: Optional[dict] = None,
20
- run_queries: bool = True,
21
- inspect_queries: bool = False,
22
- create_tables: bool = True,
23
- summarize_tables: bool = True,
24
- export_tables: bool = False,
21
+ **kwargs,
25
22
  ):
26
- super().__init__(name="duckdb_tools")
27
-
28
23
  self.db_path: Optional[str] = db_path
29
24
  self.read_only: bool = read_only
30
25
  self.config: Optional[dict] = config
31
26
  self._connection: Optional[duckdb.DuckDBPyConnection] = connection
32
27
  self.init_commands: Optional[List] = init_commands
33
28
 
34
- self.register(self.show_tables)
35
- self.register(self.describe_table)
36
- if inspect_queries:
37
- self.register(self.inspect_query)
38
- if run_queries:
39
- self.register(self.run_query)
40
- if create_tables:
41
- self.register(self.create_table_from_path)
42
- if summarize_tables:
43
- self.register(self.summarize_table)
44
- if export_tables:
45
- self.register(self.export_table_to_path)
29
+ tools: List[Any] = [
30
+ self.show_tables,
31
+ self.describe_table,
32
+ self.inspect_query,
33
+ self.run_query,
34
+ self.create_table_from_path,
35
+ self.summarize_table,
36
+ self.export_table_to_path,
37
+ self.load_local_path_to_table,
38
+ self.load_local_csv_to_table,
39
+ self.load_s3_path_to_table,
40
+ self.load_s3_csv_to_table,
41
+ self.create_fts_index,
42
+ self.full_text_search,
43
+ ]
44
+
45
+ super().__init__(name="duckdb_tools", tools=tools, **kwargs)
46
46
 
47
47
  @property
48
48
  def connection(self) -> duckdb.DuckDBPyConnection:
@@ -79,7 +79,7 @@ class DuckDbTools(Toolkit):
79
79
  if show_tables:
80
80
  stmt = "SHOW TABLES;"
81
81
  tables = self.run_query(stmt)
82
- logger.debug(f"Tables: {tables}")
82
+ log_debug(f"Tables: {tables}")
83
83
  return tables
84
84
  return "No tables to show"
85
85
 
@@ -92,7 +92,7 @@ class DuckDbTools(Toolkit):
92
92
  stmt = f"DESCRIBE {table};"
93
93
  table_description = self.run_query(stmt)
94
94
 
95
- logger.debug(f"Table description: {table_description}")
95
+ log_debug(f"Table description: {table_description}")
96
96
  return f"{table}\n{table_description}"
97
97
 
98
98
  def inspect_query(self, query: str) -> str:
@@ -104,7 +104,7 @@ class DuckDbTools(Toolkit):
104
104
  stmt = f"explain {query};"
105
105
  explain_plan = self.run_query(stmt)
106
106
 
107
- logger.debug(f"Explain plan: {explain_plan}")
107
+ log_debug(f"Explain plan: {explain_plan}")
108
108
  return explain_plan
109
109
 
110
110
  def run_query(self, query: str) -> str:
@@ -121,7 +121,7 @@ class DuckDbTools(Toolkit):
121
121
  formatted_sql = formatted_sql.split(";")[0]
122
122
 
123
123
  try:
124
- logger.info(f"Running: {formatted_sql}")
124
+ log_info(f"Running: {formatted_sql}")
125
125
 
126
126
  query_result = self.connection.sql(formatted_sql)
127
127
  result_output = "No output"
@@ -140,7 +140,7 @@ class DuckDbTools(Toolkit):
140
140
  except AttributeError:
141
141
  result_output = str(query_result)
142
142
 
143
- logger.debug(f"Query result: {result_output}")
143
+ log_debug(f"Query result: {result_output}")
144
144
  return result_output
145
145
  except duckdb.ProgrammingError as e:
146
146
  return str(e)
@@ -159,7 +159,7 @@ class DuckDbTools(Toolkit):
159
159
  """
160
160
  table_summary = self.run_query(f"SUMMARIZE {table};")
161
161
 
162
- logger.debug(f"Table description: {table_summary}")
162
+ log_debug(f"Table description: {table_summary}")
163
163
  return table_summary
164
164
 
165
165
  def get_table_name_from_path(self, path: str) -> str:
@@ -168,12 +168,10 @@ class DuckDbTools(Toolkit):
168
168
  :param path: Path to get the table name from
169
169
  :return: Table name
170
170
  """
171
- import os
172
-
173
171
  # Get the file name from the path
174
- file_name = path.split("/")[-1]
172
+ path_obj = Path(path)
175
173
  # Get the file name without extension from the path
176
- table, extension = os.path.splitext(file_name)
174
+ table = path_obj.stem
177
175
  # If the table isn't a valid SQL identifier, we'll need to use something else
178
176
  table = table.replace("-", "_").replace(".", "_").replace(" ", "_").replace("/", "_")
179
177
 
@@ -191,14 +189,19 @@ class DuckDbTools(Toolkit):
191
189
  if table is None:
192
190
  table = self.get_table_name_from_path(path)
193
191
 
194
- logger.debug(f"Creating table {table} from {path}")
192
+ log_debug(f"Creating table {table} from {path}")
195
193
  create_statement = "CREATE TABLE IF NOT EXISTS"
196
194
  if replace:
197
195
  create_statement = "CREATE OR REPLACE TABLE"
198
196
 
199
- create_statement += f" '{table}' AS SELECT * FROM '{path}';"
197
+ # Check if the file is a CSV
198
+ if path.lower().endswith(".csv"):
199
+ create_statement += f" {table} AS SELECT * FROM read_csv('{path}', ignore_errors=false, auto_detect=true);"
200
+ else:
201
+ create_statement += f" {table} AS SELECT * FROM '{path}';"
202
+
200
203
  self.run_query(create_statement)
201
- logger.debug(f"Created table {table} from {path}")
204
+ log_debug(f"Created table {table} from {path}")
202
205
  return table
203
206
 
204
207
  def export_table_to_path(self, table: str, format: Optional[str] = "PARQUET", path: Optional[str] = None) -> str:
@@ -215,14 +218,14 @@ class DuckDbTools(Toolkit):
215
218
  if format is None:
216
219
  format = "PARQUET"
217
220
 
218
- logger.debug(f"Exporting Table {table} as {format.upper()} to path {path}")
221
+ log_debug(f"Exporting Table {table} as {format.upper()} to path {path}")
219
222
  if path is None:
220
223
  path = f"{table}.{format}"
221
224
  else:
222
225
  path = f"{path}/{table}.{format}"
223
226
  export_statement = f"COPY (SELECT * FROM {table}) TO '{path}' (FORMAT {format.upper()});"
224
227
  result = self.run_query(export_statement)
225
- logger.debug(f"Exported {table} to {path}/{table}")
228
+ log_debug(f"Exported {table} to {path}/{table}")
226
229
  return result
227
230
 
228
231
  def load_local_path_to_table(self, path: str, table: Optional[str] = None) -> Tuple[str, str]:
@@ -232,22 +235,20 @@ class DuckDbTools(Toolkit):
232
235
  :param table: Optional table name to use
233
236
  :return: Table name, SQL statement used to load the file
234
237
  """
235
- import os
236
-
237
- logger.debug(f"Loading {path} into duckdb")
238
+ log_debug(f"Loading {path} into duckdb")
238
239
 
239
240
  if table is None:
240
- # Get the file name from the s3 path
241
- file_name = path.split("/")[-1]
242
- # Get the file name without extension from the s3 path
243
- table, extension = os.path.splitext(file_name)
241
+ # Get the file name from the path
242
+ path_obj = Path(path)
243
+ # Get the file name without extension from the path
244
+ table = path_obj.stem
244
245
  # If the table isn't a valid SQL identifier, we'll need to use something else
245
246
  table = table.replace("-", "_").replace(".", "_").replace(" ", "_").replace("/", "_")
246
247
 
247
- create_statement = f"CREATE OR REPLACE TABLE '{table}' AS SELECT * FROM '{path}';"
248
+ create_statement = f"CREATE OR REPLACE TABLE {table} AS SELECT * FROM '{path}';"
248
249
  self.run_query(create_statement)
249
250
 
250
- logger.debug(f"Loaded {path} into duckdb as {table}")
251
+ log_debug(f"Loaded {path} into duckdb as {table}")
251
252
  return table, create_statement
252
253
 
253
254
  def load_local_csv_to_table(
@@ -260,28 +261,26 @@ class DuckDbTools(Toolkit):
260
261
  :param delimiter: Optional delimiter to use
261
262
  :return: Table name, SQL statement used to load the file
262
263
  """
263
- import os
264
-
265
- logger.debug(f"Loading {path} into duckdb")
264
+ log_debug(f"Loading {path} into duckdb")
266
265
 
267
266
  if table is None:
268
- # Get the file name from the s3 path
269
- file_name = path.split("/")[-1]
270
- # Get the file name without extension from the s3 path
271
- table, extension = os.path.splitext(file_name)
267
+ # Get the file name from the path
268
+ path_obj = Path(path)
269
+ # Get the file name without extension from the path
270
+ table = path_obj.stem
272
271
  # If the table isn't a valid SQL identifier, we'll need to use something else
273
272
  table = table.replace("-", "_").replace(".", "_").replace(" ", "_").replace("/", "_")
274
273
 
275
- select_statement = f"SELECT * FROM read_csv('{path}'"
274
+ select_statement = f"SELECT * FROM read_csv('{path}', ignore_errors=false, auto_detect=true"
276
275
  if delimiter is not None:
277
276
  select_statement += f", delim='{delimiter}')"
278
277
  else:
279
278
  select_statement += ")"
280
279
 
281
- create_statement = f"CREATE OR REPLACE TABLE '{table}' AS {select_statement};"
280
+ create_statement = f"CREATE OR REPLACE TABLE {table} AS {select_statement};"
282
281
  self.run_query(create_statement)
283
282
 
284
- logger.debug(f"Loaded CSV {path} into duckdb as {table}")
283
+ log_debug(f"Loaded CSV {path} into duckdb as {table}")
285
284
  return table, create_statement
286
285
 
287
286
  def load_s3_path_to_table(self, path: str, table: Optional[str] = None) -> Tuple[str, str]:
@@ -291,22 +290,20 @@ class DuckDbTools(Toolkit):
291
290
  :param table: Optional table name to use
292
291
  :return: Table name, SQL statement used to load the file
293
292
  """
294
- import os
295
-
296
- logger.debug(f"Loading {path} into duckdb")
293
+ log_debug(f"Loading {path} into duckdb")
297
294
 
298
295
  if table is None:
299
- # Get the file name from the s3 path
300
- file_name = path.split("/")[-1]
301
- # Get the file name without extension from the s3 path
302
- table, extension = os.path.splitext(file_name)
296
+ # Get the file name from the path
297
+ path_obj = Path(path)
298
+ # Get the file name without extension from the path
299
+ table = path_obj.stem
303
300
  # If the table isn't a valid SQL identifier, we'll need to use something else
304
301
  table = table.replace("-", "_").replace(".", "_").replace(" ", "_").replace("/", "_")
305
302
 
306
- create_statement = f"CREATE OR REPLACE TABLE '{table}' AS SELECT * FROM '{path}';"
303
+ create_statement = f"CREATE OR REPLACE TABLE {table} AS SELECT * FROM '{path}';"
307
304
  self.run_query(create_statement)
308
305
 
309
- logger.debug(f"Loaded {path} into duckdb as {table}")
306
+ log_debug(f"Loaded {path} into duckdb as {table}")
310
307
  return table, create_statement
311
308
 
312
309
  def load_s3_csv_to_table(
@@ -318,28 +315,26 @@ class DuckDbTools(Toolkit):
318
315
  :param table: Optional table name to use
319
316
  :return: Table name, SQL statement used to load the file
320
317
  """
321
- import os
322
-
323
- logger.debug(f"Loading {path} into duckdb")
318
+ log_debug(f"Loading {path} into duckdb")
324
319
 
325
320
  if table is None:
326
- # Get the file name from the s3 path
327
- file_name = path.split("/")[-1]
328
- # Get the file name without extension from the s3 path
329
- table, extension = os.path.splitext(file_name)
321
+ # Get the file name from the path
322
+ path_obj = Path(path)
323
+ # Get the file name without extension from the path
324
+ table = path_obj.stem
330
325
  # If the table isn't a valid SQL identifier, we'll need to use something else
331
326
  table = table.replace("-", "_").replace(".", "_").replace(" ", "_").replace("/", "_")
332
327
 
333
- select_statement = f"SELECT * FROM read_csv('{path}'"
328
+ select_statement = f"SELECT * FROM read_csv('{path}', ignore_errors=false, auto_detect=true"
334
329
  if delimiter is not None:
335
330
  select_statement += f", delim='{delimiter}')"
336
331
  else:
337
332
  select_statement += ")"
338
333
 
339
- create_statement = f"CREATE OR REPLACE TABLE '{table}' AS {select_statement};"
334
+ create_statement = f"CREATE OR REPLACE TABLE {table} AS {select_statement};"
340
335
  self.run_query(create_statement)
341
336
 
342
- logger.debug(f"Loaded CSV {path} into duckdb as {table}")
337
+ log_debug(f"Loaded CSV {path} into duckdb as {table}")
343
338
  return table, create_statement
344
339
 
345
340
  def create_fts_index(self, table: str, unique_key: str, input_values: list[str]) -> str:
@@ -350,16 +345,16 @@ class DuckDbTools(Toolkit):
350
345
  :param input_values: Values to index
351
346
  :return: None
352
347
  """
353
- logger.debug(f"Creating FTS index on {table} for {input_values}")
348
+ log_debug(f"Creating FTS index on {table} for {input_values}")
354
349
  self.run_query("INSTALL fts;")
355
- logger.debug("Installed FTS extension")
350
+ log_debug("Installed FTS extension")
356
351
  self.run_query("LOAD fts;")
357
- logger.debug("Loaded FTS extension")
352
+ log_debug("Loaded FTS extension")
358
353
 
359
354
  create_fts_index_statement = f"PRAGMA create_fts_index('{table}', '{unique_key}', '{input_values}');"
360
- logger.debug(f"Running {create_fts_index_statement}")
355
+ log_debug(f"Running {create_fts_index_statement}")
361
356
  result = self.run_query(create_fts_index_statement)
362
- logger.debug(f"Created FTS index on {table} for {input_values}")
357
+ log_debug(f"Created FTS index on {table} for {input_values}")
363
358
 
364
359
  return result
365
360
 
@@ -371,14 +366,14 @@ class DuckDbTools(Toolkit):
371
366
  :param search_text: Text to search
372
367
  :return: None
373
368
  """
374
- logger.debug(f"Running full_text_search for {search_text} in {table}")
369
+ log_debug(f"Running full_text_search for {search_text} in {table}")
375
370
  search_text_statement = f"""SELECT fts_main_corpus.match_bm25({unique_key}, '{search_text}') AS score,*
376
371
  FROM {table}
377
372
  WHERE score IS NOT NULL
378
373
  ORDER BY score;"""
379
374
 
380
- logger.debug(f"Running {search_text_statement}")
375
+ log_debug(f"Running {search_text_statement}")
381
376
  result = self.run_query(search_text_statement)
382
- logger.debug(f"Search results for {search_text} in {table}")
377
+ log_debug(f"Search results for {search_text} in {table}")
383
378
 
384
379
  return result
agno/tools/duckduckgo.py CHANGED
@@ -1,88 +1,91 @@
1
1
  import json
2
- from typing import Any, Optional
2
+ from typing import Any, List, Optional
3
3
 
4
4
  from agno.tools import Toolkit
5
- from agno.utils.log import logger
5
+ from agno.utils.log import log_debug
6
6
 
7
7
  try:
8
- from duckduckgo_search import DDGS
8
+ from ddgs import DDGS
9
9
  except ImportError:
10
- raise ImportError("`duckduckgo-search` not installed. Please install using `pip install duckduckgo-search`")
10
+ raise ImportError("`ddgs` not installed. Please install using `pip install ddgs`")
11
11
 
12
12
 
13
13
  class DuckDuckGoTools(Toolkit):
14
14
  """
15
- DuckDuckGo is a toolkit for searching DuckDuckGo easily.
15
+ DuckDuckGo is a toolkit for searching using DuckDuckGo easily.
16
+ It uses the meta-search library DDGS, so it also has access to other backends.
16
17
  Args:
17
- search (bool): Enable DuckDuckGo search function.
18
- news (bool): Enable DuckDuckGo news function.
18
+ enable_search (bool): Enable DDGS search function.
19
+ enable_news (bool): Enable DDGS news function.
20
+ modifier (Optional[str]): A modifier to be used in the search request.
19
21
  fixed_max_results (Optional[int]): A fixed number of maximum results.
20
- headers (Optional[Any]): Headers to be used in the search request.
21
22
  proxy (Optional[str]): Proxy to be used in the search request.
22
- proxies (Optional[Any]): A list of proxies to be used in the search request.
23
23
  timeout (Optional[int]): The maximum number of seconds to wait for a response.
24
+ backend (Optional[str]): The backend to be used in the search request.
25
+
24
26
  """
25
27
 
26
28
  def __init__(
27
29
  self,
28
- search: bool = True,
29
- news: bool = True,
30
+ enable_search: bool = True,
31
+ enable_news: bool = True,
32
+ all: bool = False,
33
+ backend: str = "duckduckgo",
30
34
  modifier: Optional[str] = None,
31
35
  fixed_max_results: Optional[int] = None,
32
- headers: Optional[Any] = None,
33
36
  proxy: Optional[str] = None,
34
- proxies: Optional[Any] = None,
35
37
  timeout: Optional[int] = 10,
36
38
  verify_ssl: bool = True,
39
+ **kwargs,
37
40
  ):
38
- super().__init__(name="duckduckgo")
39
-
40
- self.headers: Optional[Any] = headers
41
41
  self.proxy: Optional[str] = proxy
42
- self.proxies: Optional[Any] = proxies
43
42
  self.timeout: Optional[int] = timeout
44
43
  self.fixed_max_results: Optional[int] = fixed_max_results
45
44
  self.modifier: Optional[str] = modifier
46
45
  self.verify_ssl: bool = verify_ssl
46
+ self.backend: str = backend
47
47
 
48
- if search:
49
- self.register(self.duckduckgo_search)
50
- if news:
51
- self.register(self.duckduckgo_news)
48
+ tools: List[Any] = []
49
+ if all or enable_search:
50
+ tools.append(self.duckduckgo_search)
51
+ if all or enable_news:
52
+ tools.append(self.duckduckgo_news)
53
+
54
+ super().__init__(name="duckduckgo", tools=tools, **kwargs)
52
55
 
53
56
  def duckduckgo_search(self, query: str, max_results: int = 5) -> str:
54
- """Use this function to search DuckDuckGo for a query.
57
+ """Use this function to search DDGS for a query.
55
58
 
56
59
  Args:
57
60
  query(str): The query to search for.
58
61
  max_results (optional, default=5): The maximum number of results to return.
59
62
 
60
63
  Returns:
61
- The result from DuckDuckGo.
64
+ The result from DDGS.
62
65
  """
63
- logger.debug(f"Searching DDG for: {query}")
64
- ddgs = DDGS(
65
- headers=self.headers, proxy=self.proxy, proxies=self.proxies, timeout=self.timeout, verify=self.verify_ssl
66
- )
67
- if not self.modifier:
68
- return json.dumps(ddgs.text(keywords=query, max_results=(self.fixed_max_results or max_results)), indent=2)
69
- return json.dumps(
70
- ddgs.text(keywords=self.modifier + " " + query, max_results=(self.fixed_max_results or max_results)),
71
- indent=2,
72
- )
66
+ actual_max_results = self.fixed_max_results or max_results
67
+ search_query = f"{self.modifier} {query}" if self.modifier else query
68
+
69
+ log_debug(f"Searching DDG for: {search_query} using backend: {self.backend}")
70
+ with DDGS(proxy=self.proxy, timeout=self.timeout, verify=self.verify_ssl) as ddgs:
71
+ results = ddgs.text(query=search_query, max_results=actual_max_results, backend=self.backend)
72
+
73
+ return json.dumps(results, indent=2)
73
74
 
74
75
  def duckduckgo_news(self, query: str, max_results: int = 5) -> str:
75
- """Use this function to get the latest news from DuckDuckGo.
76
+ """Use this function to get the latest news from DDGS.
76
77
 
77
78
  Args:
78
79
  query(str): The query to search for.
79
80
  max_results (optional, default=5): The maximum number of results to return.
80
81
 
81
82
  Returns:
82
- The latest news from DuckDuckGo.
83
+ The latest news from DDGS.
83
84
  """
84
- logger.debug(f"Searching DDG news for: {query}")
85
- ddgs = DDGS(
86
- headers=self.headers, proxy=self.proxy, proxies=self.proxies, timeout=self.timeout, verify=self.verify_ssl
87
- )
88
- return json.dumps(ddgs.news(keywords=query, max_results=(self.fixed_max_results or max_results)), indent=2)
85
+ actual_max_results = self.fixed_max_results or max_results
86
+
87
+ log_debug(f"Searching DDG news for: {query} using backend: {self.backend}")
88
+ with DDGS(proxy=self.proxy, timeout=self.timeout, verify=self.verify_ssl) as ddgs:
89
+ results = ddgs.news(query=query, max_results=actual_max_results, backend=self.backend)
90
+
91
+ return json.dumps(results, indent=2)