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/x.py ADDED
@@ -0,0 +1,335 @@
1
+ import json
2
+ from os import getenv
3
+ from typing import Any, List, Optional
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import log_debug, log_info, logger
7
+
8
+ try:
9
+ import tweepy
10
+ except ImportError:
11
+ raise ImportError("`tweepy` not installed. Please install using `pip install tweepy`.")
12
+
13
+
14
+ class XTools(Toolkit):
15
+ def __init__(
16
+ self,
17
+ bearer_token: Optional[str] = None,
18
+ consumer_key: Optional[str] = None,
19
+ consumer_secret: Optional[str] = None,
20
+ access_token: Optional[str] = None,
21
+ access_token_secret: Optional[str] = None,
22
+ include_post_metrics: bool = False,
23
+ wait_on_rate_limit: bool = False,
24
+ **kwargs,
25
+ ):
26
+ """
27
+ Initialize the XTools.
28
+
29
+ Args:
30
+ bearer_token Optional[str]: The bearer token for Twitter API.
31
+ consumer_key Optional[str]: The consumer key for Twitter API.
32
+ consumer_secret Optional[str]: The consumer secret for Twitter API.
33
+ access_token Optional[str]: The access token for Twitter API.
34
+ access_token_secret Optional[str]: The access token secret for Twitter API.
35
+ include_post_metrics Optional[bool]: Whether to include post metrics in the search results.
36
+ wait_on_rate_limit Optional[bool]: Whether to wait on rate limit.
37
+ """
38
+ self.bearer_token = bearer_token or getenv("X_BEARER_TOKEN")
39
+ self.consumer_key = consumer_key or getenv("X_CONSUMER_KEY")
40
+ self.consumer_secret = consumer_secret or getenv("X_CONSUMER_SECRET")
41
+ self.access_token = access_token or getenv("X_ACCESS_TOKEN")
42
+ self.access_token_secret = access_token_secret or getenv("X_ACCESS_TOKEN_SECRET")
43
+ self.wait_on_rate_limit = wait_on_rate_limit
44
+ self.client = tweepy.Client(
45
+ bearer_token=self.bearer_token,
46
+ consumer_key=self.consumer_key,
47
+ consumer_secret=self.consumer_secret,
48
+ access_token=self.access_token,
49
+ access_token_secret=self.access_token_secret,
50
+ wait_on_rate_limit=self.wait_on_rate_limit,
51
+ )
52
+ self.include_post_metrics = include_post_metrics
53
+
54
+ tools: List[Any] = [
55
+ self.create_post,
56
+ self.reply_to_post,
57
+ self.send_dm,
58
+ self.get_user_info,
59
+ self.get_home_timeline,
60
+ self.search_posts,
61
+ ]
62
+
63
+ super().__init__(name="x", tools=tools, **kwargs)
64
+
65
+ def create_post(self, text: str) -> str:
66
+ """
67
+ Create a new X post.
68
+
69
+ Args:
70
+ text (str): The content of the post to create.
71
+
72
+ Returns:
73
+ A JSON-formatted string containing the response from X API (Twitter API) with the created post details,
74
+ or an error message if the post creation fails.
75
+ """
76
+ log_debug(f"Attempting to create post with text: {text}")
77
+ try:
78
+ response = self.client.create_tweet(text=text)
79
+ post_id = response.data["id"]
80
+ user = self.client.get_me().data
81
+ post_url = f"https://x.com/{user.username}/status/{post_id}"
82
+
83
+ result = {"message": "Post successfully created!", "url": post_url}
84
+ return json.dumps(result, indent=2)
85
+ except tweepy.TweepyException as e:
86
+ logger.error(f"Error creating post: {e}")
87
+ return json.dumps({"error": str(e)})
88
+
89
+ def reply_to_post(self, post_id: str, text: str) -> str:
90
+ """
91
+ Reply to an existing post.
92
+
93
+ Args:
94
+ post_id (str): The ID of the post to reply to.
95
+ text (str): The content of the reply post.
96
+
97
+ Returns:
98
+ A JSON-formatted string containing the response from Twitter API with the reply post details,
99
+ or an error message if the reply fails.
100
+ """
101
+ log_debug(f"Attempting to reply to {post_id} with text {text}")
102
+ try:
103
+ response = self.client.create_tweet(text=text, in_reply_to_tweet_id=post_id)
104
+ reply_id = response.data["id"]
105
+ user = self.client.get_me().data
106
+ reply_url = f"https://twitter.com/{user.username}/status/{reply_id}"
107
+ result = {"message": "Reply successfully posted!", "url": reply_url}
108
+ return json.dumps(result, indent=2)
109
+ except tweepy.TweepyException as e:
110
+ logger.error(f"Error replying to post: {e}")
111
+ return json.dumps({"error": str(e)})
112
+
113
+ def send_dm(self, recipient: str, text: str) -> str:
114
+ """
115
+ Send a direct message to a user.
116
+
117
+ Args:
118
+ recipient (str): The username or user ID of the recipient.
119
+ text (str): The content of the direct message.
120
+
121
+ Returns:
122
+ A JSON-formatted string containing the response from Twitter API with the sent message details,
123
+ or an error message if sending the DM fails.
124
+ """
125
+ log_debug(f"Attempting to send DM to user {recipient}")
126
+ try:
127
+ # Check if recipient is a user ID (numeric) or username
128
+ if not recipient.isdigit():
129
+ # If it's not numeric, assume it's a username and get the user ID
130
+ user = self.client.get_user(username=recipient)
131
+ log_debug(f"Attempting to send DM to user's id {user}")
132
+ recipient_id = user.data.id
133
+ else:
134
+ recipient_id = recipient
135
+
136
+ log_debug(f"Attempting to send DM to user's id {recipient_id}")
137
+ response = self.client.create_direct_message(participant_id=recipient_id, text=text)
138
+ result = {
139
+ "message": "Direct message sent successfully!",
140
+ "dm_id": response.data["id"],
141
+ "recipient_id": recipient_id,
142
+ "recipient_username": recipient if not recipient.isdigit() else None,
143
+ }
144
+ return json.dumps(result, indent=2)
145
+ except tweepy.TweepyException as e:
146
+ logger.error(f"Error from X while sending DM: {e}")
147
+ error_message = str(e)
148
+ if "User not found" in error_message:
149
+ error_message = f"User '{recipient}' not found. Please check the username or user ID."
150
+ elif "You cannot send messages to this user" in error_message:
151
+ error_message = (
152
+ f"Unable to send message to '{recipient}'. The user may have restricted who can send them messages."
153
+ )
154
+ return json.dumps({"error": error_message}, indent=2)
155
+ except Exception as e:
156
+ logger.error(f"Unexpected error sending DM: {e}")
157
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, indent=2)
158
+
159
+ def get_my_info(self) -> str:
160
+ """
161
+ Retrieve information about the authenticated user.
162
+
163
+ Returns:
164
+ A JSON-formatted string containing the user's profile information,
165
+ including id, name, username, description, and follower/following counts,
166
+ or an error message if fetching the information fails.
167
+ """
168
+ log_debug("Fetching information about myself")
169
+ try:
170
+ me = self.client.get_me(user_fields=["description", "public_metrics"])
171
+ user_info = me.data.data
172
+ result = {
173
+ "id": user_info["id"],
174
+ "name": user_info["name"],
175
+ "username": user_info["username"],
176
+ "description": user_info["description"],
177
+ "followers_count": user_info["public_metrics"]["followers_count"],
178
+ "following_count": user_info["public_metrics"]["following_count"],
179
+ "tweet_count": user_info["public_metrics"]["tweet_count"],
180
+ }
181
+ return json.dumps(result, indent=2)
182
+ except tweepy.TweepyException as e:
183
+ logger.error(f"Error fetching user info: {e}")
184
+ return json.dumps({"error": str(e)})
185
+
186
+ def get_user_info(self, username: str) -> str:
187
+ """
188
+ Retrieve information about a specific user.
189
+
190
+ Args:
191
+ username (str): The username of the user to fetch information about.
192
+
193
+ Returns:
194
+ A JSON-formatted string containing the user's profile information,
195
+ including id, name, username, description, and follower/following counts,
196
+ or an error message if fetching the information fails.
197
+ """
198
+ log_debug(f"Fetching information about user {username}")
199
+ try:
200
+ user = self.client.get_user(username=username, user_fields=["description", "public_metrics"])
201
+ user_info = user.data.data
202
+ result = {
203
+ "id": user_info["id"],
204
+ "name": user_info["name"],
205
+ "username": user_info["username"],
206
+ "description": user_info["description"],
207
+ "followers_count": user_info["public_metrics"]["followers_count"],
208
+ "following_count": user_info["public_metrics"]["following_count"],
209
+ "tweet_count": user_info["public_metrics"]["tweet_count"],
210
+ }
211
+ return json.dumps(result, indent=2)
212
+ except tweepy.TweepyException as e:
213
+ logger.error(f"Error fetching user info: {e}")
214
+ return json.dumps({"error": str(e)})
215
+
216
+ def get_home_timeline(self, max_results: int = 10) -> str:
217
+ """
218
+ Retrieve the authenticated user's home timeline.
219
+
220
+ Args:
221
+ max_results (int): The maximum number of tweets to retrieve. Default is 10.
222
+
223
+ Returns:
224
+ A JSON-formatted string containing a list of tweets from the user's home timeline,
225
+ including tweet id, text, creation time, and author id,
226
+ or an error message if fetching the timeline fails.
227
+ """
228
+ log_debug(f"Fetching home timeline, max results: {max_results}")
229
+ try:
230
+ tweets = self.client.get_home_timeline(
231
+ max_results=max_results, tweet_fields=["created_at", "public_metrics"]
232
+ )
233
+ timeline = []
234
+ for tweet in tweets.data:
235
+ timeline.append(
236
+ {
237
+ "id": tweet.id,
238
+ "text": tweet.text,
239
+ "created_at": tweet.created_at.strftime("%Y-%m-%d %H:%M:%S"),
240
+ "author_id": tweet.author_id,
241
+ }
242
+ )
243
+ log_info(f"Successfully fetched {len(timeline)} tweets")
244
+ result = {"home_timeline": timeline}
245
+ return json.dumps(result, indent=2)
246
+ except tweepy.TweepyException as e:
247
+ logger.error(f"Error fetching home timeline: {e}")
248
+ return json.dumps({"error": str(e)})
249
+
250
+ def search_posts(self, query: str, max_results: int = 10) -> str:
251
+ """
252
+ Search for tweets based on a search query.
253
+
254
+ Args:
255
+ query (str): The search query.
256
+ max_results (int): The maximum number of posts to retrieve.
257
+
258
+ Returns:
259
+ A list of posts matching the search query
260
+ """
261
+ try:
262
+ max_results = max(10, min(max_results, 100)) # range 10 - 100
263
+
264
+ log_debug(f"Searching for posts with query: {query}, bounded max results: {max_results}")
265
+ results = self.client.search_recent_tweets(
266
+ query=query,
267
+ max_results=max_results,
268
+ tweet_fields=[
269
+ "author_id",
270
+ "created_at",
271
+ "id",
272
+ "public_metrics",
273
+ "text",
274
+ ],
275
+ user_fields=["name", "username", "verified"],
276
+ )
277
+
278
+ users_data = {}
279
+ if hasattr(results, "includes") and "users" in results.includes:
280
+ for user in results.includes["users"]:
281
+ users_data[user.id] = {
282
+ "id": user.id,
283
+ "name": user.name,
284
+ "username": user.username,
285
+ "verified": getattr(user, "verified", False),
286
+ }
287
+ tweets = []
288
+
289
+ if results.data:
290
+ for tweet in results.data:
291
+ author_info = users_data.get(
292
+ tweet.author_id, {"id": tweet.author_id, "name": "Unknown", "username": "unknown"}
293
+ )
294
+
295
+ post_url = f"https://x.com/{author_info.get('username', 'unknown')}/status/{tweet.id}"
296
+
297
+ post_data = {
298
+ "id": tweet.id,
299
+ "text": tweet.text,
300
+ "created_at": tweet.created_at.strftime("%Y-%m-%d %H:%M:%S")
301
+ if hasattr(tweet, "created_at")
302
+ else None,
303
+ "author": author_info,
304
+ "url": post_url,
305
+ }
306
+ if self.include_post_metrics:
307
+ post_data["metrics"] = {
308
+ "retweet_count": tweet.public_metrics.get("retweet_count", 0)
309
+ if hasattr(tweet, "public_metrics")
310
+ else 0,
311
+ "reply_count": tweet.public_metrics.get("reply_count", 0)
312
+ if hasattr(tweet, "public_metrics")
313
+ else 0,
314
+ "like_count": tweet.public_metrics.get("like_count", 0)
315
+ if hasattr(tweet, "public_metrics")
316
+ else 0,
317
+ "quote_count": tweet.public_metrics.get("quote_count", 0)
318
+ if hasattr(tweet, "public_metrics")
319
+ else 0,
320
+ }
321
+ tweets.append(post_data)
322
+
323
+ log_info(f"Successfully found {len(tweets)} posts for query: {query}")
324
+ result = {"query": query, "count": len(tweets), "posts": tweets}
325
+ else:
326
+ log_info(f"No posts found for query: {query}")
327
+ result = {}
328
+ return json.dumps(result, indent=2)
329
+
330
+ except tweepy.TweepyException as e:
331
+ logger.error(f"Error searching posts: {e}")
332
+ return json.dumps({"error": str(e), "query": query})
333
+ except Exception as e:
334
+ logger.error(f"Unexpected error searching posts: {e}")
335
+ return json.dumps({"error": f"An unexpected error occurred: {str(e)}", "query": query})
agno/tools/yfinance.py ADDED
@@ -0,0 +1,257 @@
1
+ import json
2
+ from typing import Any, List
3
+
4
+ from agno.tools import Toolkit
5
+ from agno.utils.log import log_debug
6
+
7
+ try:
8
+ import yfinance as yf
9
+ except ImportError:
10
+ raise ImportError("`yfinance` not installed. Please install using `pip install yfinance`.")
11
+
12
+
13
+ class YFinanceTools(Toolkit):
14
+ """
15
+ YFinanceTools is a toolkit for getting financial data from Yahoo Finance.
16
+ Includes all available financial data tools.
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ **kwargs,
22
+ ):
23
+ tools: List[Any] = [
24
+ self.get_current_stock_price,
25
+ self.get_company_info,
26
+ self.get_stock_fundamentals,
27
+ self.get_income_statements,
28
+ self.get_key_financial_ratios,
29
+ self.get_analyst_recommendations,
30
+ self.get_company_news,
31
+ self.get_technical_indicators,
32
+ self.get_historical_stock_prices,
33
+ ]
34
+
35
+ super().__init__(name="yfinance_tools", tools=tools, **kwargs)
36
+
37
+ def get_current_stock_price(self, symbol: str) -> str:
38
+ """
39
+ Use this function to get the current stock price for a given symbol.
40
+
41
+ Args:
42
+ symbol (str): The stock symbol.
43
+
44
+ Returns:
45
+ str: The current stock price or error message.
46
+ """
47
+ try:
48
+ log_debug(f"Fetching current price for {symbol}")
49
+ stock = yf.Ticker(symbol)
50
+ # Use "regularMarketPrice" for regular market hours, or "currentPrice" for pre/post market
51
+ current_price = stock.info.get("regularMarketPrice", stock.info.get("currentPrice"))
52
+ return f"{current_price:.4f}" if current_price else f"Could not fetch current price for {symbol}"
53
+ except Exception as e:
54
+ return f"Error fetching current price for {symbol}: {e}"
55
+
56
+ def get_company_info(self, symbol: str) -> str:
57
+ """Use this function to get company information and overview for a given stock symbol.
58
+
59
+ Args:
60
+ symbol (str): The stock symbol.
61
+
62
+ Returns:
63
+ str: JSON containing company profile and overview.
64
+ """
65
+ try:
66
+ company_info_full = yf.Ticker(symbol).info
67
+ if company_info_full is None:
68
+ return f"Could not fetch company info for {symbol}"
69
+
70
+ log_debug(f"Fetching company info for {symbol}")
71
+
72
+ company_info_cleaned = {
73
+ "Name": company_info_full.get("shortName"),
74
+ "Symbol": company_info_full.get("symbol"),
75
+ "Current Stock Price": f"{company_info_full.get('regularMarketPrice', company_info_full.get('currentPrice'))} {company_info_full.get('currency', 'USD')}",
76
+ "Market Cap": f"{company_info_full.get('marketCap', company_info_full.get('enterpriseValue'))} {company_info_full.get('currency', 'USD')}",
77
+ "Sector": company_info_full.get("sector"),
78
+ "Industry": company_info_full.get("industry"),
79
+ "Address": company_info_full.get("address1"),
80
+ "City": company_info_full.get("city"),
81
+ "State": company_info_full.get("state"),
82
+ "Zip": company_info_full.get("zip"),
83
+ "Country": company_info_full.get("country"),
84
+ "EPS": company_info_full.get("trailingEps"),
85
+ "P/E Ratio": company_info_full.get("trailingPE"),
86
+ "52 Week Low": company_info_full.get("fiftyTwoWeekLow"),
87
+ "52 Week High": company_info_full.get("fiftyTwoWeekHigh"),
88
+ "50 Day Average": company_info_full.get("fiftyDayAverage"),
89
+ "200 Day Average": company_info_full.get("twoHundredDayAverage"),
90
+ "Website": company_info_full.get("website"),
91
+ "Summary": company_info_full.get("longBusinessSummary"),
92
+ "Analyst Recommendation": company_info_full.get("recommendationKey"),
93
+ "Number Of Analyst Opinions": company_info_full.get("numberOfAnalystOpinions"),
94
+ "Employees": company_info_full.get("fullTimeEmployees"),
95
+ "Total Cash": company_info_full.get("totalCash"),
96
+ "Free Cash flow": company_info_full.get("freeCashflow"),
97
+ "Operating Cash flow": company_info_full.get("operatingCashflow"),
98
+ "EBITDA": company_info_full.get("ebitda"),
99
+ "Revenue Growth": company_info_full.get("revenueGrowth"),
100
+ "Gross Margins": company_info_full.get("grossMargins"),
101
+ "Ebitda Margins": company_info_full.get("ebitdaMargins"),
102
+ }
103
+ return json.dumps(company_info_cleaned, indent=2)
104
+ except Exception as e:
105
+ return f"Error fetching company profile for {symbol}: {e}"
106
+
107
+ def get_historical_stock_prices(self, symbol: str, period: str = "1mo", interval: str = "1d") -> str:
108
+ """
109
+ Use this function to get the historical stock price for a given symbol.
110
+
111
+ Args:
112
+ symbol (str): The stock symbol.
113
+ period (str): The period for which to retrieve historical prices. Defaults to "1mo".
114
+ Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
115
+ interval (str): The interval between data points. Defaults to "1d".
116
+ Valid intervals: 1d,5d,1wk,1mo,3mo
117
+
118
+ Returns:
119
+ str: The current stock price or error message.
120
+ """
121
+ try:
122
+ log_debug(f"Fetching historical prices for {symbol}")
123
+ stock = yf.Ticker(symbol)
124
+ historical_price = stock.history(period=period, interval=interval)
125
+ return historical_price.to_json(orient="index")
126
+ except Exception as e:
127
+ return f"Error fetching historical prices for {symbol}: {e}"
128
+
129
+ def get_stock_fundamentals(self, symbol: str) -> str:
130
+ """Use this function to get fundamental data for a given stock symbol yfinance API.
131
+
132
+ Args:
133
+ symbol (str): The stock symbol.
134
+
135
+ Returns:
136
+ str: A JSON string containing fundamental data or an error message.
137
+ Keys:
138
+ - 'symbol': The stock symbol.
139
+ - 'company_name': The long name of the company.
140
+ - 'sector': The sector to which the company belongs.
141
+ - 'industry': The industry to which the company belongs.
142
+ - 'market_cap': The market capitalization of the company.
143
+ - 'pe_ratio': The forward price-to-earnings ratio.
144
+ - 'pb_ratio': The price-to-book ratio.
145
+ - 'dividend_yield': The dividend yield.
146
+ - 'eps': The trailing earnings per share.
147
+ - 'beta': The beta value of the stock.
148
+ - '52_week_high': The 52-week high price of the stock.
149
+ - '52_week_low': The 52-week low price of the stock.
150
+ """
151
+ try:
152
+ log_debug(f"Fetching fundamentals for {symbol}")
153
+ stock = yf.Ticker(symbol)
154
+ info = stock.info
155
+ fundamentals = {
156
+ "symbol": symbol,
157
+ "company_name": info.get("longName", ""),
158
+ "sector": info.get("sector", ""),
159
+ "industry": info.get("industry", ""),
160
+ "market_cap": info.get("marketCap", "N/A"),
161
+ "pe_ratio": info.get("forwardPE", "N/A"),
162
+ "pb_ratio": info.get("priceToBook", "N/A"),
163
+ "dividend_yield": info.get("dividendYield", "N/A"),
164
+ "eps": info.get("trailingEps", "N/A"),
165
+ "beta": info.get("beta", "N/A"),
166
+ "52_week_high": info.get("fiftyTwoWeekHigh", "N/A"),
167
+ "52_week_low": info.get("fiftyTwoWeekLow", "N/A"),
168
+ }
169
+ return json.dumps(fundamentals, indent=2)
170
+ except Exception as e:
171
+ return f"Error getting fundamentals for {symbol}: {e}"
172
+
173
+ def get_income_statements(self, symbol: str) -> str:
174
+ """Use this function to get income statements for a given stock symbol.
175
+
176
+ Args:
177
+ symbol (str): The stock symbol.
178
+
179
+ Returns:
180
+ dict: JSON containing income statements or an empty dictionary.
181
+ """
182
+ try:
183
+ log_debug(f"Fetching income statements for {symbol}")
184
+ stock = yf.Ticker(symbol)
185
+ financials = stock.financials
186
+ return financials.to_json(orient="index")
187
+ except Exception as e:
188
+ return f"Error fetching income statements for {symbol}: {e}"
189
+
190
+ def get_key_financial_ratios(self, symbol: str) -> str:
191
+ """Use this function to get key financial ratios for a given stock symbol.
192
+
193
+ Args:
194
+ symbol (str): The stock symbol.
195
+
196
+ Returns:
197
+ dict: JSON containing key financial ratios.
198
+ """
199
+ try:
200
+ log_debug(f"Fetching key financial ratios for {symbol}")
201
+ stock = yf.Ticker(symbol)
202
+ key_ratios = stock.info
203
+ return json.dumps(key_ratios, indent=2)
204
+ except Exception as e:
205
+ return f"Error fetching key financial ratios for {symbol}: {e}"
206
+
207
+ def get_analyst_recommendations(self, symbol: str) -> str:
208
+ """Use this function to get analyst recommendations for a given stock symbol.
209
+
210
+ Args:
211
+ symbol (str): The stock symbol.
212
+
213
+ Returns:
214
+ str: JSON containing analyst recommendations.
215
+ """
216
+ try:
217
+ log_debug(f"Fetching analyst recommendations for {symbol}")
218
+ stock = yf.Ticker(symbol)
219
+ recommendations = stock.recommendations
220
+ return recommendations.to_json(orient="index")
221
+ except Exception as e:
222
+ return f"Error fetching analyst recommendations for {symbol}: {e}"
223
+
224
+ def get_company_news(self, symbol: str, num_stories: int = 3) -> str:
225
+ """Use this function to get company news and press releases for a given stock symbol.
226
+
227
+ Args:
228
+ symbol (str): The stock symbol.
229
+ num_stories (int): The number of news stories to return. Defaults to 3.
230
+
231
+ Returns:
232
+ str: JSON containing company news and press releases.
233
+ """
234
+ try:
235
+ log_debug(f"Fetching company news for {symbol}")
236
+ news = yf.Ticker(symbol).news
237
+ return json.dumps(news[:num_stories], indent=2)
238
+ except Exception as e:
239
+ return f"Error fetching company news for {symbol}: {e}"
240
+
241
+ def get_technical_indicators(self, symbol: str, period: str = "3mo") -> str:
242
+ """Use this function to get technical indicators for a given stock symbol.
243
+
244
+ Args:
245
+ symbol (str): The stock symbol.
246
+ period (str): The time period for which to retrieve technical indicators.
247
+ Valid periods: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max. Defaults to 3mo.
248
+
249
+ Returns:
250
+ str: JSON containing technical indicators.
251
+ """
252
+ try:
253
+ log_debug(f"Fetching technical indicators for {symbol}")
254
+ indicators = yf.Ticker(symbol).history(period=period)
255
+ return indicators.to_json(orient="index")
256
+ except Exception as e:
257
+ return f"Error fetching technical indicators for {symbol}: {e}"