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