agno 2.2.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
agno/tools/arxiv.py ADDED
@@ -0,0 +1,127 @@
1
+ import json
2
+ from pathlib import Path
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
+ import arxiv
10
+ except ImportError:
11
+ raise ImportError("`arxiv` not installed. Please install using `pip install arxiv`")
12
+
13
+ try:
14
+ from pypdf import PdfReader
15
+ except ImportError:
16
+ raise ImportError("`pypdf` not installed. Please install using `pip install pypdf`")
17
+
18
+
19
+ class ArxivTools(Toolkit):
20
+ def __init__(
21
+ self,
22
+ enable_search_arxiv: bool = True,
23
+ enable_read_arxiv_papers: bool = True,
24
+ all: bool = False,
25
+ download_dir: Optional[Path] = None,
26
+ **kwargs,
27
+ ):
28
+ self.client: arxiv.Client = arxiv.Client()
29
+ self.download_dir: Path = download_dir or Path(__file__).parent.joinpath("arxiv_pdfs")
30
+
31
+ tools: List[Any] = []
32
+ if all or enable_search_arxiv:
33
+ tools.append(self.search_arxiv_and_return_articles)
34
+ if all or enable_read_arxiv_papers:
35
+ tools.append(self.read_arxiv_papers)
36
+
37
+ super().__init__(name="arxiv_tools", tools=tools, **kwargs)
38
+
39
+ def search_arxiv_and_return_articles(self, query: str, num_articles: int = 10) -> str:
40
+ """Use this function to search arXiv for a query and return the top articles.
41
+
42
+ Args:
43
+ query (str): The query to search arXiv for.
44
+ num_articles (int, optional): The number of articles to return. Defaults to 10.
45
+ Returns:
46
+ str: A JSON of the articles with title, id, authors, pdf_url and summary.
47
+ """
48
+
49
+ articles = []
50
+ log_debug(f"Searching arxiv for: {query}")
51
+ for result in self.client.results(
52
+ search=arxiv.Search(
53
+ query=query,
54
+ max_results=num_articles,
55
+ sort_by=arxiv.SortCriterion.Relevance,
56
+ sort_order=arxiv.SortOrder.Descending,
57
+ )
58
+ ):
59
+ try:
60
+ article = {
61
+ "title": result.title,
62
+ "id": result.get_short_id(),
63
+ "entry_id": result.entry_id,
64
+ "authors": [author.name for author in result.authors],
65
+ "primary_category": result.primary_category,
66
+ "categories": result.categories,
67
+ "published": result.published.isoformat() if result.published else None,
68
+ "pdf_url": result.pdf_url,
69
+ "links": [link.href for link in result.links],
70
+ "summary": result.summary,
71
+ "comment": result.comment,
72
+ }
73
+ articles.append(article)
74
+ except Exception as e:
75
+ logger.error(f"Error processing article: {e}")
76
+ return json.dumps(articles, indent=4)
77
+
78
+ def read_arxiv_papers(self, id_list: List[str], pages_to_read: Optional[int] = None) -> str:
79
+ """Use this function to read a list of arxiv papers and return the content.
80
+
81
+ Args:
82
+ id_list (list, str): The list of `id` of the papers to add to the knowledge base.
83
+ Should be of the format: ["2103.03404v1", "2103.03404v2"]
84
+ pages_to_read (int, optional): The number of pages to read from the paper.
85
+ None means read all pages. Defaults to None.
86
+ Returns:
87
+ str: JSON of the papers.
88
+ """
89
+
90
+ download_dir = self.download_dir
91
+ download_dir.mkdir(parents=True, exist_ok=True)
92
+
93
+ articles = []
94
+ log_debug(f"Searching arxiv for: {id_list}")
95
+ for result in self.client.results(search=arxiv.Search(id_list=id_list)):
96
+ try:
97
+ article: Dict[str, Any] = {
98
+ "title": result.title,
99
+ "id": result.get_short_id(),
100
+ "entry_id": result.entry_id,
101
+ "authors": [author.name for author in result.authors],
102
+ "primary_category": result.primary_category,
103
+ "categories": result.categories,
104
+ "published": result.published.isoformat() if result.published else None,
105
+ "pdf_url": result.pdf_url,
106
+ "links": [link.href for link in result.links],
107
+ "summary": result.summary,
108
+ "comment": result.comment,
109
+ }
110
+ if result.pdf_url:
111
+ log_debug(f"Downloading: {result.pdf_url}")
112
+ pdf_path = result.download_pdf(dirpath=str(download_dir))
113
+ log_debug(f"To: {pdf_path}")
114
+ pdf_reader = PdfReader(pdf_path)
115
+ article["content"] = []
116
+ for page_number, page in enumerate(pdf_reader.pages, start=1):
117
+ if pages_to_read and page_number > pages_to_read:
118
+ break
119
+ content = {
120
+ "page": page_number,
121
+ "text": page.extract_text(),
122
+ }
123
+ article["content"].append(content)
124
+ articles.append(article)
125
+ except Exception as e:
126
+ logger.error(f"Error processing article: {e}")
127
+ return json.dumps(articles, indent=4)
@@ -0,0 +1,53 @@
1
+ from typing import Any, List
2
+
3
+ from agno.tools import Toolkit
4
+
5
+ try:
6
+ import boto3
7
+ except ImportError:
8
+ raise ImportError("boto3 is required for AWSLambdaTool. Please install it using `pip install boto3`.")
9
+
10
+
11
+ class AWSLambdaTools(Toolkit):
12
+ def __init__(
13
+ self,
14
+ region_name: str = "us-east-1",
15
+ enable_list_functions: bool = True,
16
+ enable_invoke_function: bool = True,
17
+ all: bool = False,
18
+ **kwargs,
19
+ ):
20
+ self.client = boto3.client("lambda", region_name=region_name)
21
+
22
+ tools: List[Any] = []
23
+ if all or enable_list_functions:
24
+ tools.append(self.list_functions)
25
+ if all or enable_invoke_function:
26
+ tools.append(self.invoke_function)
27
+
28
+ super().__init__(name="aws-lambda", tools=tools, **kwargs)
29
+
30
+ def list_functions(self) -> str:
31
+ """
32
+ List all AWS Lambda functions in the configured AWS account.
33
+ """
34
+ try:
35
+ response = self.client.list_functions()
36
+ functions = [func["FunctionName"] for func in response["Functions"]]
37
+ return f"Available Lambda functions: {', '.join(functions)}"
38
+ except Exception as e:
39
+ return f"Error listing functions: {str(e)}"
40
+
41
+ def invoke_function(self, function_name: str, payload: str = "{}") -> str:
42
+ """
43
+ Invoke a specific AWS Lambda function with an optional JSON payload.
44
+
45
+ Args:
46
+ function_name (str): The name of the Lambda function to invoke.
47
+ payload (str): The JSON payload to send to the function. Defaults to "{}".
48
+ """
49
+ try:
50
+ response = self.client.invoke(FunctionName=function_name, Payload=payload)
51
+ return f"Function invoked successfully. Status code: {response['StatusCode']}, Payload: {response['Payload'].read().decode('utf-8')}"
52
+ except Exception as e:
53
+ return f"Error invoking function: {str(e)}"
agno/tools/aws_ses.py ADDED
@@ -0,0 +1,66 @@
1
+ from typing import Optional
2
+
3
+ from agno.tools import Toolkit
4
+ from agno.utils.log import log_debug
5
+
6
+ try:
7
+ import boto3
8
+ except ImportError:
9
+ raise ImportError("boto3 is required for AWSSESTool. Please install it using `pip install boto3`.")
10
+
11
+
12
+ class AWSSESTool(Toolkit):
13
+ def __init__(
14
+ self,
15
+ sender_email: Optional[str] = None,
16
+ sender_name: Optional[str] = None,
17
+ region_name: str = "us-east-1",
18
+ enable_send_email: bool = True,
19
+ all: bool = False,
20
+ **kwargs,
21
+ ):
22
+ tools = []
23
+ if all or enable_send_email:
24
+ tools.append(self.send_email)
25
+ super().__init__(name="aws_ses_tool", tools=tools, **kwargs)
26
+ self.client = boto3.client("ses", region_name=region_name)
27
+ self.sender_email = sender_email
28
+ self.sender_name = sender_name
29
+
30
+ def send_email(self, subject: str, body: str, receiver_email: str) -> str:
31
+ """
32
+ Use this tool to send an email using AWS SES.
33
+
34
+ Args: subject: The subject of the email
35
+ body: The body of the email
36
+ receiver_email: The email address of the receiver
37
+ """
38
+ if not self.client:
39
+ raise Exception("AWS SES client not initialized. Please check the configuration.")
40
+ if not subject:
41
+ return "Email subject cannot be empty."
42
+ if not body:
43
+ return "Email body cannot be empty."
44
+ try:
45
+ response = self.client.send_email(
46
+ Source=f"{self.sender_name} <{self.sender_email}>",
47
+ Destination={
48
+ "ToAddresses": [receiver_email],
49
+ },
50
+ Message={
51
+ "Body": {
52
+ "Text": {
53
+ "Charset": "UTF-8",
54
+ "Data": body,
55
+ },
56
+ },
57
+ "Subject": {
58
+ "Charset": "UTF-8",
59
+ "Data": subject,
60
+ },
61
+ },
62
+ )
63
+ log_debug(f"Email sent with message ID: {response['MessageId']}")
64
+ return "Email sent successfully!"
65
+ except Exception as e:
66
+ raise Exception(f"Failed to send email: {e}")
@@ -0,0 +1,89 @@
1
+ import json
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ from agno.tools import Toolkit
5
+ from agno.utils.log import log_debug
6
+
7
+ try:
8
+ from baidusearch.baidusearch import search # type: ignore
9
+ except ImportError:
10
+ raise ImportError("`baidusearch` not installed. Please install using `pip install baidusearch`")
11
+
12
+ try:
13
+ from pycountry import pycountry
14
+ except ImportError:
15
+ raise ImportError("`pycountry` not installed. Please install using `pip install pycountry`")
16
+
17
+
18
+ class BaiduSearchTools(Toolkit):
19
+ """
20
+ BaiduSearch is a toolkit for searching Baidu easily.
21
+
22
+ Args:
23
+ fixed_max_results (Optional[int]): A fixed number of maximum results.
24
+ fixed_language (Optional[str]): A fixed language for the search results.
25
+ headers (Optional[Any]): Headers to be used in the search request.
26
+ proxy (Optional[str]): Proxy to be used in the search request.
27
+ debug (Optional[bool]): Enable debug output.
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ fixed_max_results: Optional[int] = None,
33
+ fixed_language: Optional[str] = None,
34
+ headers: Optional[Any] = None,
35
+ proxy: Optional[str] = None,
36
+ timeout: Optional[int] = 10,
37
+ debug: Optional[bool] = False,
38
+ enable_baidu_search: bool = True,
39
+ all: bool = False,
40
+ **kwargs,
41
+ ):
42
+ self.fixed_max_results = fixed_max_results
43
+ self.fixed_language = fixed_language
44
+ self.headers = headers
45
+ self.proxy = proxy
46
+ self.timeout = timeout
47
+ self.debug = debug
48
+
49
+ tools = []
50
+ if all or enable_baidu_search:
51
+ tools.append(self.baidu_search)
52
+
53
+ super().__init__(name="baidusearch", tools=tools, **kwargs)
54
+
55
+ def baidu_search(self, query: str, max_results: int = 5, language: str = "zh") -> str:
56
+ """Execute Baidu search and return results
57
+
58
+ Args:
59
+ query (str): Search keyword
60
+ max_results (int, optional): Maximum number of results to return, default 5
61
+ language (str, optional): Search language, default Chinese
62
+
63
+ Returns:
64
+ str: A JSON formatted string containing the search results.
65
+ """
66
+ max_results = self.fixed_max_results or max_results
67
+ language = self.fixed_language or language
68
+
69
+ if len(language) != 2:
70
+ try:
71
+ language = pycountry.languages.lookup(language).alpha_2
72
+ except LookupError:
73
+ language = "zh"
74
+
75
+ log_debug(f"Searching Baidu [{language}] for: {query}")
76
+
77
+ results = search(keyword=query, num_results=max_results)
78
+
79
+ res: List[Dict[str, str]] = []
80
+ for idx, item in enumerate(results, 1):
81
+ res.append(
82
+ {
83
+ "title": item.get("title", ""),
84
+ "url": item.get("url", ""),
85
+ "abstract": item.get("abstract", ""),
86
+ "rank": str(idx),
87
+ }
88
+ )
89
+ return json.dumps(res, indent=2)
@@ -0,0 +1,292 @@
1
+ import base64
2
+ import json
3
+ from os import getenv
4
+ from typing import Any, Dict, Optional, Union
5
+
6
+ import requests
7
+
8
+ from agno.tools import Toolkit
9
+ from agno.utils.log import logger
10
+
11
+
12
+ class BitbucketTools(Toolkit):
13
+ def __init__(
14
+ self,
15
+ server_url: str = "api.bitbucket.org",
16
+ username: Optional[str] = None,
17
+ password: Optional[str] = None,
18
+ token: Optional[str] = None,
19
+ workspace: Optional[str] = None,
20
+ repo_slug: Optional[str] = None,
21
+ api_version: str = "2.0",
22
+ **kwargs,
23
+ ):
24
+ self.username = username or getenv("BITBUCKET_USERNAME")
25
+ self.password = password or getenv("BITBUCKET_PASSWORD")
26
+ self.token = token or getenv("BITBUCKET_TOKEN")
27
+ self.auth_password = self.token or self.password
28
+ self.server_url = server_url or "api.bitbucket.org"
29
+ self.api_version = api_version or "2.0"
30
+ self.base_url = (
31
+ f"https://{self.server_url}/{api_version}"
32
+ if not self.server_url.startswith(("http://", "https://"))
33
+ else f"{self.server_url}/{api_version}"
34
+ )
35
+ self.workspace = workspace
36
+ self.repo_slug = repo_slug
37
+
38
+ if not (self.username and self.auth_password):
39
+ raise ValueError("Username and password or token are required")
40
+
41
+ if not self.workspace:
42
+ raise ValueError("Workspace is required")
43
+ if not self.repo_slug:
44
+ raise ValueError("Repo slug is required")
45
+
46
+ self.headers = {"Accept": "application/json", "Authorization": f"Basic {self._generate_access_token()}"}
47
+
48
+ super().__init__(
49
+ name="bitbucket",
50
+ tools=[
51
+ self.list_repositories,
52
+ self.get_repository_details,
53
+ self.create_repository,
54
+ self.list_repository_commits,
55
+ self.list_all_pull_requests,
56
+ self.get_pull_request_details,
57
+ self.get_pull_request_changes,
58
+ self.list_issues,
59
+ ],
60
+ **kwargs,
61
+ )
62
+
63
+ def _generate_access_token(self) -> str:
64
+ auth_str = f"{self.username}:{self.auth_password}"
65
+ auth_bytes = auth_str.encode("ascii")
66
+ auth_base64 = base64.b64encode(auth_bytes).decode("ascii")
67
+ return auth_base64
68
+
69
+ def _make_request(
70
+ self,
71
+ method: str,
72
+ endpoint: str,
73
+ params: Optional[Dict[str, Any]] = None,
74
+ data: Optional[Dict[str, Any]] = None,
75
+ ) -> Union[str, Dict[str, Any]]:
76
+ url = f"{self.base_url}{endpoint}"
77
+ response = requests.request(method, url, headers=self.headers, json=data, params=params)
78
+ response.raise_for_status()
79
+ encoding_type = response.headers.get("Content-Type", "application/json")
80
+ if encoding_type.startswith("application/json"):
81
+ return response.json() if response.text else {}
82
+ elif encoding_type == "text/plain":
83
+ return response.text
84
+
85
+ logger.warning(f"Unsupported content type: {encoding_type}")
86
+ return {}
87
+
88
+ def list_repositories(self, count: int = 10) -> str:
89
+ """
90
+ Get all repositories in the workspace.
91
+ Args:
92
+ count (int, optional): The number of repositories to retrieve
93
+
94
+ Returns:
95
+ str: A JSON string containing repository list.
96
+ """
97
+ try:
98
+ # Limit count to maximum of 50
99
+ count = min(count, 50)
100
+
101
+ # Use count directly as pagelen for simplicity, max out at 50 per our limit
102
+ pagelen = min(count, 50)
103
+ params = {"page": 1, "pagelen": pagelen}
104
+
105
+ repo = self._make_request("GET", f"/repositories/{self.workspace}", params=params)
106
+
107
+ return json.dumps(repo, indent=2)
108
+ except Exception as e:
109
+ logger.error(f"Error retrieving repository list for workspace {self.workspace}: {str(e)}")
110
+ return json.dumps({"error": str(e)})
111
+
112
+ def get_repository_details(self) -> str:
113
+ """
114
+ Retrieves repository information.
115
+ API Docs: https://developer.atlassian.com/cloud/bitbucket/rest/api-group-repositories/#api-repositories-workspace-repo-slug-get
116
+
117
+ Returns:
118
+ str: A JSON string containing repository information.
119
+ """
120
+ try:
121
+ repo = self._make_request("GET", f"/repositories/{self.workspace}/{self.repo_slug}")
122
+ return json.dumps(repo, indent=2)
123
+ except Exception as e:
124
+ logger.error(f"Error retrieving repository information for {self.repo_slug}: {str(e)}")
125
+ return json.dumps({"error": str(e)})
126
+
127
+ def create_repository(
128
+ self,
129
+ name: str,
130
+ project: Optional[str] = None,
131
+ is_private: bool = False,
132
+ description: Optional[str] = None,
133
+ language: Optional[str] = None,
134
+ has_issues: bool = False,
135
+ has_wiki: bool = False,
136
+ ) -> str:
137
+ """
138
+ Creates a new repository in Bitbucket for the given workspace.
139
+
140
+ Args:
141
+ name (str): The name of the new repository.
142
+ project (str, optional): The key of the project to create the repository in.
143
+ is_private (bool, optional): Whether the repository is private.
144
+ description (str, optional): A short description of the repository.
145
+ language (str, optional): The primary language of the repository
146
+ has_issues (bool, optional): Whether the repository has issues enabled.
147
+ has_wiki (bool, optional): Whether the repository has a wiki enabled.
148
+
149
+ Returns:
150
+ str: A JSON string containing repository information.
151
+ """
152
+ try:
153
+ payload: Dict[str, Any] = {
154
+ "name": name,
155
+ "scm": "git",
156
+ "is_private": is_private,
157
+ "description": description,
158
+ "language": language,
159
+ "has_issues": has_issues,
160
+ "has_wiki": has_wiki,
161
+ }
162
+ if project:
163
+ payload["project"] = {"key": project}
164
+ repo = self._make_request("POST", f"/repositories/{self.workspace}/{self.repo_slug}", data=payload)
165
+ return json.dumps(repo, indent=2)
166
+ except Exception as e:
167
+ logger.error(f"Error creating repository {self.repo_slug} for {self.workspace}: {str(e)}")
168
+ return json.dumps({"error": str(e)})
169
+
170
+ def list_repository_commits(self, count: int = 10) -> str:
171
+ """
172
+ Retrieves all commits in a repository.
173
+
174
+ Args:
175
+ count (int, optional): The number of commits to retrieve. Defaults to 10. Maximum 50.
176
+
177
+ Returns:
178
+ str: A JSON string containing all commits.
179
+ """
180
+ try:
181
+ count = min(count, 50)
182
+ params = {"pagelen": count}
183
+
184
+ commits = self._make_request(
185
+ "GET", f"/repositories/{self.workspace}/{self.repo_slug}/commits", params=params
186
+ )
187
+
188
+ if isinstance(commits, dict) and commits.get("next"):
189
+ collected_commits = commits.get("values", [])
190
+
191
+ while len(collected_commits) < count and isinstance(commits, dict) and commits.get("next"):
192
+ next_url = commits["next"] # type: ignore
193
+ query_param = next_url.split("?")[1] if "?" in next_url else ""
194
+ commits = self._make_request(
195
+ "GET", f"/repositories/{self.workspace}/{self.repo_slug}/commits?{query_param}"
196
+ )
197
+ if isinstance(commits, dict):
198
+ collected_commits.extend(commits.get("values", []))
199
+
200
+ if isinstance(commits, dict):
201
+ commits["values"] = collected_commits[:count]
202
+
203
+ return json.dumps(commits, indent=2)
204
+ except Exception as e:
205
+ logger.error(f"Error retrieving commits for {self.repo_slug}: {str(e)}")
206
+ return json.dumps({"error": str(e)})
207
+
208
+ def list_all_pull_requests(self, state: str = "OPEN") -> str:
209
+ """
210
+ Retrieves all pull requests for a repository.
211
+
212
+ Args:
213
+ state (str, optional): The state of the pull requests to retrieve.
214
+
215
+ Returns:
216
+ str: A JSON string containing all pull requests.
217
+ """
218
+ try:
219
+ if state not in ["OPEN", "MERGED", "DECLINED", "SUPERSEDED"]:
220
+ logger.debug(f"Invalid pull request state: {state}. Defaulting to OPEN")
221
+ state = "OPEN"
222
+
223
+ params = {"state": state}
224
+
225
+ pull_requests = self._make_request(
226
+ "GET", f"/repositories/{self.workspace}/{self.repo_slug}/pullrequests", params=params
227
+ )
228
+
229
+ return json.dumps(pull_requests, indent=2)
230
+ except Exception as e:
231
+ logger.error(f"Error retrieving pull requests for {self.repo_slug}: {str(e)}")
232
+ return json.dumps({"error": str(e)})
233
+
234
+ def get_pull_request_details(self, pull_request_id: int) -> str:
235
+ """
236
+ Retrieves a pull request for a repository.
237
+ Args:
238
+ pull_request_id (int): The ID of the pull request to retrieve.
239
+
240
+ Returns:
241
+ str: A JSON string containing the pull request.
242
+ """
243
+ try:
244
+ pull_request = self._make_request(
245
+ "GET", f"/repositories/{self.workspace}/{self.repo_slug}/pullrequests/{pull_request_id}"
246
+ )
247
+ return json.dumps(pull_request, indent=2)
248
+ except Exception as e:
249
+ logger.error(f"Error retrieving pull requests for {self.repo_slug}: {str(e)}")
250
+ return json.dumps({"error": str(e)})
251
+
252
+ def get_pull_request_changes(self, pull_request_id: int) -> str:
253
+ """
254
+ Retrieves changes for a pull request in a repository.
255
+
256
+ Args:
257
+ pull_request_id (int): The ID of the pull request to retrieve.
258
+
259
+ Returns:
260
+ str: A markdown string containing the pull request diff.
261
+ """
262
+ try:
263
+ diff = self._make_request(
264
+ "GET", f"/repositories/{self.workspace}/{self.repo_slug}/pullrequests/{pull_request_id}/diff"
265
+ )
266
+ if isinstance(diff, dict):
267
+ return json.dumps(diff, indent=2)
268
+ return diff
269
+ except Exception as e:
270
+ logger.error(f"Error retrieving changes for pull request {pull_request_id} in {self.repo_slug}: {str(e)}")
271
+ return json.dumps({"error": str(e)})
272
+
273
+ def list_issues(self, count: int = 10) -> str:
274
+ """
275
+ Retrieves all issues for a repository.
276
+
277
+ Args:
278
+ count (int, optional): The number of issues to retrieve. Defaults to 10. Maximum 50.
279
+
280
+ Returns:
281
+ str: A JSON string containing all issues.
282
+ """
283
+ try:
284
+ count = min(count, 50)
285
+ params = {"pagelen": count}
286
+
287
+ issues = self._make_request("GET", f"/repositories/{self.workspace}/{self.repo_slug}/issues", params=params)
288
+
289
+ return json.dumps(issues, indent=2)
290
+ except Exception as e:
291
+ logger.error(f"Error retrieving issues for {self.repo_slug}: {str(e)}")
292
+ return json.dumps({"error": str(e)})