agno 2.2.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
@@ -0,0 +1,209 @@
1
+ import json
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import log_debug, logger
7
+
8
+ try:
9
+ from browserbase import Browserbase
10
+ except ImportError:
11
+ raise ImportError("`browserbase` not installed. Please install using `pip install browserbase`")
12
+
13
+ try:
14
+ from playwright.sync_api import sync_playwright
15
+ except ImportError:
16
+ raise ImportError(
17
+ "`playwright` not installed. Please install using `pip install playwright` and run `playwright install`"
18
+ )
19
+
20
+
21
+ class BrowserbaseTools(Toolkit):
22
+ def __init__(
23
+ self,
24
+ api_key: Optional[str] = None,
25
+ project_id: Optional[str] = None,
26
+ base_url: Optional[str] = None,
27
+ enable_navigate_to: bool = True,
28
+ enable_screenshot: bool = True,
29
+ enable_get_page_content: bool = True,
30
+ enable_close_session: bool = True,
31
+ all: bool = False,
32
+ **kwargs,
33
+ ):
34
+ """Initialize BrowserbaseTools.
35
+
36
+ Args:
37
+ api_key (str, optional): Browserbase API key.
38
+ project_id (str, optional): Browserbase project ID.
39
+ base_url (str, optional): Custom Browserbase API endpoint URL (NOT the target website URL). Only use this if you're using a self-hosted Browserbase instance or need to connect to a different region.
40
+ """
41
+ self.api_key = api_key or getenv("BROWSERBASE_API_KEY")
42
+ if not self.api_key:
43
+ raise ValueError(
44
+ "BROWSERBASE_API_KEY is required. Please set the BROWSERBASE_API_KEY environment variable."
45
+ )
46
+
47
+ self.project_id = project_id or getenv("BROWSERBASE_PROJECT_ID")
48
+ if not self.project_id:
49
+ raise ValueError(
50
+ "BROWSERBASE_PROJECT_ID is required. Please set the BROWSERBASE_PROJECT_ID environment variable."
51
+ )
52
+
53
+ self.base_url = base_url or getenv("BROWSERBASE_BASE_URL")
54
+
55
+ # Initialize the Browserbase client with optional base_url
56
+ if self.base_url:
57
+ self.app = Browserbase(api_key=self.api_key, base_url=self.base_url)
58
+ log_debug(f"Using custom Browserbase API endpoint: {self.base_url}")
59
+ else:
60
+ self.app = Browserbase(api_key=self.api_key)
61
+
62
+ self._playwright = None
63
+ self._browser = None
64
+ self._page = None
65
+ self._session = None
66
+ self._connect_url = None
67
+
68
+ tools: List[Any] = []
69
+ if all or enable_navigate_to:
70
+ tools.append(self.navigate_to)
71
+ if all or enable_screenshot:
72
+ tools.append(self.screenshot)
73
+ if all or enable_get_page_content:
74
+ tools.append(self.get_page_content)
75
+ if all or enable_close_session:
76
+ tools.append(self.close_session)
77
+
78
+ super().__init__(name="browserbase_tools", tools=tools, **kwargs)
79
+
80
+ def _ensure_session(self):
81
+ """Ensures a session exists, creating one if needed."""
82
+ if not self._session:
83
+ try:
84
+ self._session = self.app.sessions.create(project_id=self.project_id) # type: ignore
85
+ self._connect_url = self._session.connect_url if self._session else "" # type: ignore
86
+ if self._session:
87
+ log_debug(f"Created new session with ID: {self._session.id}")
88
+ except Exception as e:
89
+ logger.error(f"Failed to create session: {str(e)}")
90
+ raise
91
+
92
+ def _initialize_browser(self, connect_url: Optional[str] = None):
93
+ """
94
+ Initialize browser connection if not already initialized.
95
+ Use provided connect_url or ensure we have a session with a connect_url
96
+ """
97
+ if connect_url:
98
+ self._connect_url = connect_url if connect_url else "" # type: ignore
99
+ elif not self._connect_url:
100
+ self._ensure_session()
101
+
102
+ if not self._playwright:
103
+ self._playwright = sync_playwright().start() # type: ignore
104
+ if self._playwright:
105
+ self._browser = self._playwright.chromium.connect_over_cdp(self._connect_url)
106
+ context = self._browser.contexts[0] if self._browser else ""
107
+ self._page = context.pages[0] or context.new_page() # type: ignore
108
+
109
+ def _cleanup(self):
110
+ """Clean up browser resources."""
111
+ if self._browser:
112
+ self._browser.close()
113
+ self._browser = None
114
+ if self._playwright:
115
+ self._playwright.stop()
116
+ self._playwright = None
117
+ self._page = None
118
+
119
+ def _create_session(self) -> Dict[str, str]:
120
+ """Creates a new browser session.
121
+
122
+ Returns:
123
+ Dictionary containing session details including session_id and connect_url.
124
+ """
125
+ self._ensure_session()
126
+ return {
127
+ "session_id": self._session.id if self._session else "",
128
+ "connect_url": self._session.connect_url if self._session else "",
129
+ }
130
+
131
+ def navigate_to(self, url: str, connect_url: Optional[str] = None) -> str:
132
+ """Navigates to a URL.
133
+
134
+ Args:
135
+ url (str): The URL to navigate to
136
+ connect_url (str, optional): The connection URL from an existing session
137
+
138
+ Returns:
139
+ JSON string with navigation status
140
+ """
141
+ try:
142
+ self._initialize_browser(connect_url)
143
+ if self._page:
144
+ self._page.goto(url, wait_until="networkidle")
145
+ result = {"status": "complete", "title": self._page.title() if self._page else "", "url": url}
146
+ return json.dumps(result)
147
+ except Exception as e:
148
+ self._cleanup()
149
+ raise e
150
+
151
+ def screenshot(self, path: str, full_page: bool = True, connect_url: Optional[str] = None) -> str:
152
+ """Takes a screenshot of the current page.
153
+
154
+ Args:
155
+ path (str): Where to save the screenshot
156
+ full_page (bool): Whether to capture the full page
157
+ connect_url (str, optional): The connection URL from an existing session
158
+
159
+ Returns:
160
+ JSON string confirming screenshot was saved
161
+ """
162
+ try:
163
+ self._initialize_browser(connect_url)
164
+ if self._page:
165
+ self._page.screenshot(path=path, full_page=full_page)
166
+ return json.dumps({"status": "success", "path": path})
167
+ except Exception as e:
168
+ self._cleanup()
169
+ raise e
170
+
171
+ def get_page_content(self, connect_url: Optional[str] = None) -> str:
172
+ """Gets the HTML content of the current page.
173
+
174
+ Args:
175
+ connect_url (str, optional): The connection URL from an existing session
176
+
177
+ Returns:
178
+ The page HTML content
179
+ """
180
+ try:
181
+ self._initialize_browser(connect_url)
182
+ return self._page.content() if self._page else ""
183
+ except Exception as e:
184
+ self._cleanup()
185
+ raise e
186
+
187
+ def close_session(self) -> str:
188
+ """Closes a browser session.
189
+ Args:
190
+ session_id (str, optional): The session ID to close. If not provided, will use the current session.
191
+ Returns:
192
+ JSON string with closure status
193
+ """
194
+ try:
195
+ # First cleanup our local browser resources
196
+ self._cleanup()
197
+
198
+ # Reset session state
199
+ self._session = None
200
+ self._connect_url = None
201
+
202
+ return json.dumps(
203
+ {
204
+ "status": "closed",
205
+ "message": "Browser resources cleaned up. Session will auto-close if not already closed.",
206
+ }
207
+ )
208
+ except Exception as e:
209
+ return json.dumps({"status": "warning", "message": f"Cleanup completed with warning: {str(e)}"})
agno/tools/calcom.py ADDED
@@ -0,0 +1,255 @@
1
+ from datetime import datetime
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import logger
7
+
8
+ try:
9
+ import pytz
10
+ import requests
11
+ except ImportError:
12
+ raise ImportError("`requests` and `pytz` not installed. Please install using `pip install requests pytz`")
13
+
14
+
15
+ class CalComTools(Toolkit):
16
+ def __init__(
17
+ self,
18
+ api_key: Optional[str] = None,
19
+ event_type_id: Optional[int] = None,
20
+ user_timezone: Optional[str] = None,
21
+ # Enable flags for <6 functions
22
+ enable_get_available_slots: bool = True,
23
+ enable_create_booking: bool = True,
24
+ enable_get_upcoming_bookings: bool = True,
25
+ enable_reschedule_booking: bool = True,
26
+ enable_cancel_booking: bool = True,
27
+ all: bool = False,
28
+ **kwargs,
29
+ ):
30
+ """Initialize the Cal.com toolkit.
31
+
32
+ Args:
33
+ api_key: Cal.com API key
34
+ event_type_id: Default event type ID for bookings
35
+ user_timezone: User's timezone in IANA format (e.g., 'Asia/Kolkata')
36
+ """
37
+
38
+ # Get credentials from environment if not provided
39
+ self.api_key = api_key or getenv("CALCOM_API_KEY")
40
+ event_type_str = getenv("CALCOM_EVENT_TYPE_ID")
41
+ if event_type_id is not None:
42
+ self.event_type_id = int(event_type_id)
43
+ else:
44
+ self.event_type_id = int(event_type_str) if event_type_str is not None else 0
45
+
46
+ if not self.api_key:
47
+ logger.error("CALCOM_API_KEY not set. Please set the CALCOM_API_KEY environment variable.")
48
+ if not self.event_type_id:
49
+ logger.error("CALCOM_EVENT_TYPE_ID not set. Please set the CALCOM_EVENT_TYPE_ID environment variable.")
50
+
51
+ self.user_timezone = user_timezone or "America/New_York"
52
+
53
+ tools: List[Any] = []
54
+ if all or enable_get_available_slots:
55
+ tools.append(self.get_available_slots)
56
+ if all or enable_create_booking:
57
+ tools.append(self.create_booking)
58
+ if all or enable_get_upcoming_bookings:
59
+ tools.append(self.get_upcoming_bookings)
60
+ if all or enable_reschedule_booking:
61
+ tools.append(self.reschedule_booking)
62
+ if all or enable_cancel_booking:
63
+ tools.append(self.cancel_booking)
64
+
65
+ super().__init__(name="calcom", tools=tools, **kwargs)
66
+
67
+ def _convert_to_user_timezone(self, utc_time: str) -> str:
68
+ """Convert UTC time to user's timezone.
69
+
70
+ Args:
71
+ utc_time: UTC time string
72
+ user_timezone: User's timezone (e.g., 'Asia/Kolkata')
73
+
74
+ Returns:
75
+ str: Formatted time in user's timezone
76
+ """
77
+ utc_dt = datetime.fromisoformat(utc_time.replace("Z", "+00:00"))
78
+ user_tz = pytz.timezone(self.user_timezone)
79
+ user_dt = utc_dt.astimezone(user_tz)
80
+ return user_dt.strftime("%Y-%m-%d %H:%M %Z")
81
+
82
+ def _get_headers(self, api_version: str = "2024-08-13") -> Dict[str, str]:
83
+ """Get headers for Cal.com API requests.
84
+
85
+ Args:
86
+ api_version: Cal.com API version
87
+
88
+ Returns:
89
+ Dict[str, str]: Headers dictionary
90
+ """
91
+ return {
92
+ "Authorization": f"Bearer {self.api_key}",
93
+ "cal-api-version": api_version,
94
+ "Content-Type": "application/json",
95
+ }
96
+
97
+ def get_available_slots(
98
+ self,
99
+ start_date: str,
100
+ end_date: str,
101
+ ) -> str:
102
+ """Get available time slots for booking.
103
+
104
+ Args:
105
+ start_date: Start date in YYYY-MM-DD format
106
+ end_date: End date in YYYY-MM-DD format
107
+ user_timezone: User's timezone
108
+ event_type_id: Optional specific event type ID
109
+
110
+ Returns:
111
+ str: Available slots or error message
112
+ """
113
+ try:
114
+ url = "https://api.cal.com/v2/slots/available"
115
+ querystring = {
116
+ "startTime": f"{start_date}T00:00:00Z",
117
+ "endTime": f"{end_date}T23:59:59Z",
118
+ "eventTypeId": str(self.event_type_id),
119
+ }
120
+
121
+ response = requests.get(url, headers=self._get_headers(), params=querystring) # type: ignore
122
+ if response.status_code == 200:
123
+ slots = response.json()["data"]["slots"]
124
+ available_slots = []
125
+ for date, times in slots.items():
126
+ for slot in times:
127
+ user_time = self._convert_to_user_timezone(slot["time"])
128
+ available_slots.append(user_time)
129
+ return f"Available slots: {', '.join(available_slots)}"
130
+ return f"Failed to fetch slots: {response.text}"
131
+ except Exception as e:
132
+ logger.error(f"Error fetching available slots: {e}")
133
+ return f"Error: {str(e)}"
134
+
135
+ def create_booking(
136
+ self,
137
+ start_time: str,
138
+ name: str,
139
+ email: str,
140
+ ) -> str:
141
+ """Create a new booking.
142
+
143
+ Args:
144
+ start_time: Start time in YYYY-MM-DDTHH:MM:SSZ format
145
+ name: Attendee's name
146
+ email: Attendee's email
147
+
148
+ Returns:
149
+ str: Booking confirmation or error message
150
+ """
151
+ try:
152
+ url = "https://api.cal.com/v2/bookings"
153
+ start_time = datetime.fromisoformat(start_time).astimezone(pytz.utc).isoformat(timespec="seconds")
154
+ payload = {
155
+ "start": start_time,
156
+ "eventTypeId": self.event_type_id,
157
+ "attendee": {"name": name, "email": email, "timeZone": self.user_timezone},
158
+ }
159
+
160
+ response = requests.post(url, json=payload, headers=self._get_headers())
161
+ if response.status_code == 201:
162
+ booking_data = response.json()["data"]
163
+ user_time = self._convert_to_user_timezone(booking_data["start"])
164
+ return f"Booking created successfully for {user_time}. Booking uid: {booking_data['uid']}"
165
+ return f"Failed to create booking: {response.text}"
166
+ except Exception as e:
167
+ logger.error(f"Error creating booking: {e}")
168
+ return f"Error: {str(e)}"
169
+
170
+ def get_upcoming_bookings(self, email: Optional[str] = None) -> str:
171
+ """Get all upcoming bookings for an attendee.
172
+
173
+ Args:
174
+ email (str): Attendee's email [Optional]
175
+
176
+ Returns:
177
+ str: List of upcoming bookings or error message
178
+ """
179
+ try:
180
+ url = "https://api.cal.com/v2/bookings"
181
+ querystring = {"status": "upcoming"}
182
+ if email:
183
+ querystring["attendeeEmail"] = email
184
+
185
+ response = requests.get(url, headers=self._get_headers(), params=querystring)
186
+ if response.status_code == 200:
187
+ bookings = response.json()["data"]
188
+ if not bookings:
189
+ return "No upcoming bookings found."
190
+
191
+ booking_info = []
192
+ for booking in bookings:
193
+ user_time = self._convert_to_user_timezone(booking["start"])
194
+ booking_info.append(
195
+ f"uid: {booking['uid']}, Title: {booking['title']}, Time: {user_time}, Status: {booking['status']}"
196
+ )
197
+ return "Upcoming bookings:\n" + "\n".join(booking_info)
198
+ return f"Failed to fetch bookings: {response.text}"
199
+ except Exception as e:
200
+ logger.error(f"Error fetching upcoming bookings: {e}")
201
+ return f"Error: {str(e)}"
202
+
203
+ def reschedule_booking(
204
+ self,
205
+ booking_uid: str,
206
+ new_start_time: str,
207
+ reason: str,
208
+ ) -> str:
209
+ """Reschedule an existing booking.
210
+
211
+ Args:
212
+ booking_uid: Booking UID to reschedule
213
+ new_start_time: New start time in YYYY-MM-DDTHH:MM:SSZ format
214
+ reason: Reason for rescheduling
215
+ user_timezone: User's timezone
216
+
217
+ Returns:
218
+ str: Rescheduling confirmation or error message
219
+ """
220
+ try:
221
+ url = f"https://api.cal.com/v2/bookings/{booking_uid}/reschedule"
222
+ new_start_time = datetime.fromisoformat(new_start_time).astimezone(pytz.utc).isoformat(timespec="seconds")
223
+ payload = {"start": new_start_time, "reschedulingReason": reason}
224
+
225
+ response = requests.post(url, json=payload, headers=self._get_headers())
226
+ if response.status_code == 201:
227
+ booking_data = response.json()["data"]
228
+ user_time = self._convert_to_user_timezone(booking_data["start"])
229
+ return f"Booking rescheduled to {user_time}. New booking uid: {booking_data['uid']}"
230
+ return f"Failed to reschedule booking: {response.text}"
231
+ except Exception as e:
232
+ logger.error(f"Error rescheduling booking: {e}")
233
+ return f"Error: {str(e)}"
234
+
235
+ def cancel_booking(self, booking_uid: str, reason: str) -> str:
236
+ """Cancel an existing booking.
237
+
238
+ Args:
239
+ booking_uid: Booking UID to cancel
240
+ reason: Reason for cancellation
241
+
242
+ Returns:
243
+ str: Cancellation confirmation or error message
244
+ """
245
+ try:
246
+ url = f"https://api.cal.com/v2/bookings/{booking_uid}/cancel"
247
+ payload = {"cancellationReason": reason}
248
+
249
+ response = requests.post(url, json=payload, headers=self._get_headers())
250
+ if response.status_code == 200:
251
+ return "Booking cancelled successfully."
252
+ return f"Failed to cancel booking: {response.text}"
253
+ except Exception as e:
254
+ logger.error(f"Error cancelling booking: {e}")
255
+ return f"Error: {str(e)}"
@@ -0,0 +1,151 @@
1
+ import json
2
+ import math
3
+ from typing import Callable, List
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import log_debug, logger
7
+
8
+
9
+ class CalculatorTools(Toolkit):
10
+ def __init__(
11
+ self,
12
+ **kwargs,
13
+ ):
14
+ tools: List[Callable] = [
15
+ self.add,
16
+ self.subtract,
17
+ self.multiply,
18
+ self.divide,
19
+ self.exponentiate,
20
+ self.factorial,
21
+ self.is_prime,
22
+ self.square_root,
23
+ ]
24
+
25
+ # Initialize the toolkit with auto-registration enabled
26
+ super().__init__(name="calculator", tools=tools, **kwargs)
27
+
28
+ def add(self, a: float, b: float) -> str:
29
+ """Add two numbers and return the result.
30
+
31
+ Args:
32
+ a (float): First number.
33
+ b (float): Second number.
34
+
35
+ Returns:
36
+ str: JSON string of the result.
37
+ """
38
+ result = a + b
39
+ log_debug(f"Adding {a} and {b} to get {result}")
40
+ return json.dumps({"operation": "addition", "result": result})
41
+
42
+ def subtract(self, a: float, b: float) -> str:
43
+ """Subtract second number from first and return the result.
44
+
45
+ Args:
46
+ a (float): First number.
47
+ b (float): Second number.
48
+
49
+ Returns:
50
+ str: JSON string of the result.
51
+ """
52
+ result = a - b
53
+ log_debug(f"Subtracting {b} from {a} to get {result}")
54
+ return json.dumps({"operation": "subtraction", "result": result})
55
+
56
+ def multiply(self, a: float, b: float) -> str:
57
+ """Multiply two numbers and return the result.
58
+
59
+ Args:
60
+ a (float): First number.
61
+ b (float): Second number.
62
+
63
+ Returns:
64
+ str: JSON string of the result.
65
+ """
66
+ result = a * b
67
+ log_debug(f"Multiplying {a} and {b} to get {result}")
68
+ return json.dumps({"operation": "multiplication", "result": result})
69
+
70
+ def divide(self, a: float, b: float) -> str:
71
+ """Divide first number by second and return the result.
72
+
73
+ Args:
74
+ a (float): Numerator.
75
+ b (float): Denominator.
76
+
77
+ Returns:
78
+ str: JSON string of the result.
79
+ """
80
+ if b == 0:
81
+ logger.error("Attempt to divide by zero")
82
+ return json.dumps({"operation": "division", "error": "Division by zero is undefined"})
83
+ try:
84
+ result = a / b
85
+ except Exception as e:
86
+ return json.dumps({"operation": "division", "error": str(e), "result": "Error"})
87
+ log_debug(f"Dividing {a} by {b} to get {result}")
88
+ return json.dumps({"operation": "division", "result": result})
89
+
90
+ def exponentiate(self, a: float, b: float) -> str:
91
+ """Raise first number to the power of the second number and return the result.
92
+
93
+ Args:
94
+ a (float): Base.
95
+ b (float): Exponent.
96
+
97
+ Returns:
98
+ str: JSON string of the result.
99
+ """
100
+ result = math.pow(a, b)
101
+ log_debug(f"Raising {a} to the power of {b} to get {result}")
102
+ return json.dumps({"operation": "exponentiation", "result": result})
103
+
104
+ def factorial(self, n: int) -> str:
105
+ """Calculate the factorial of a number and return the result.
106
+
107
+ Args:
108
+ n (int): Number to calculate the factorial of.
109
+
110
+ Returns:
111
+ str: JSON string of the result.
112
+ """
113
+ if n < 0:
114
+ logger.error("Attempt to calculate factorial of a negative number")
115
+ return json.dumps({"operation": "factorial", "error": "Factorial of a negative number is undefined"})
116
+ result = math.factorial(n)
117
+ log_debug(f"Calculating factorial of {n} to get {result}")
118
+ return json.dumps({"operation": "factorial", "result": result})
119
+
120
+ def is_prime(self, n: int) -> str:
121
+ """Check if a number is prime and return the result.
122
+
123
+ Args:
124
+ n (int): Number to check if prime.
125
+
126
+ Returns:
127
+ str: JSON string of the result.
128
+ """
129
+ if n <= 1:
130
+ return json.dumps({"operation": "prime_check", "result": False})
131
+ for i in range(2, int(math.sqrt(n)) + 1):
132
+ if n % i == 0:
133
+ return json.dumps({"operation": "prime_check", "result": False})
134
+ return json.dumps({"operation": "prime_check", "result": True})
135
+
136
+ def square_root(self, n: float) -> str:
137
+ """Calculate the square root of a number and return the result.
138
+
139
+ Args:
140
+ n (float): Number to calculate the square root of.
141
+
142
+ Returns:
143
+ str: JSON string of the result.
144
+ """
145
+ if n < 0:
146
+ logger.error("Attempt to calculate square root of a negative number")
147
+ return json.dumps({"operation": "square_root", "error": "Square root of a negative number is undefined"})
148
+
149
+ result = math.sqrt(n)
150
+ log_debug(f"Calculating square root of {n} to get {result}")
151
+ return json.dumps({"operation": "square_root", "result": result})