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
agno/api/__init__.py
ADDED
|
File without changes
|
agno/api/agent.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from agno.api.api import api
|
|
2
|
+
from agno.api.routes import ApiRoutes
|
|
3
|
+
from agno.api.schemas.agent import AgentRunCreate
|
|
4
|
+
from agno.utils.log import log_debug
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_agent_run(run: AgentRunCreate) -> None:
|
|
8
|
+
"""Telemetry recording for Agent runs"""
|
|
9
|
+
with api.Client() as api_client:
|
|
10
|
+
try:
|
|
11
|
+
api_client.post(
|
|
12
|
+
ApiRoutes.RUN_CREATE,
|
|
13
|
+
json=run.model_dump(exclude_none=True),
|
|
14
|
+
)
|
|
15
|
+
except Exception as e:
|
|
16
|
+
log_debug(f"Could not create Agent run: {e}")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def acreate_agent_run(run: AgentRunCreate) -> None:
|
|
20
|
+
"""Telemetry recording for async Agent runs"""
|
|
21
|
+
async with api.AsyncClient() as api_client:
|
|
22
|
+
try:
|
|
23
|
+
await api_client.post(
|
|
24
|
+
ApiRoutes.RUN_CREATE,
|
|
25
|
+
json=run.model_dump(exclude_none=True),
|
|
26
|
+
)
|
|
27
|
+
except Exception as e:
|
|
28
|
+
log_debug(f"Could not create Agent run: {e}")
|
agno/api/api.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
from httpx import AsyncClient as HttpxAsyncClient
|
|
4
|
+
from httpx import Client as HttpxClient
|
|
5
|
+
from httpx import Response
|
|
6
|
+
|
|
7
|
+
from agno.api.settings import agno_api_settings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Api:
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.headers: Dict[str, str] = {
|
|
13
|
+
"user-agent": f"{agno_api_settings.app_name}/{agno_api_settings.app_version}",
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def Client(self) -> HttpxClient:
|
|
18
|
+
return HttpxClient(
|
|
19
|
+
base_url=agno_api_settings.api_url,
|
|
20
|
+
headers=self.headers,
|
|
21
|
+
timeout=60,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def AsyncClient(self) -> HttpxAsyncClient:
|
|
25
|
+
return HttpxAsyncClient(
|
|
26
|
+
base_url=agno_api_settings.api_url,
|
|
27
|
+
headers=self.headers,
|
|
28
|
+
timeout=60,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
api = Api()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def invalid_response(r: Response) -> bool:
|
|
36
|
+
"""Returns true if the response is invalid"""
|
|
37
|
+
|
|
38
|
+
if r.status_code >= 400:
|
|
39
|
+
return True
|
|
40
|
+
return False
|
agno/api/evals.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from agno.api.api import api
|
|
2
|
+
from agno.api.routes import ApiRoutes
|
|
3
|
+
from agno.api.schemas.evals import EvalRunCreate
|
|
4
|
+
from agno.utils.log import log_debug
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_eval_run_telemetry(eval_run: EvalRunCreate) -> None:
|
|
8
|
+
"""Telemetry recording for Eval runs"""
|
|
9
|
+
with api.Client() as api_client:
|
|
10
|
+
try:
|
|
11
|
+
api_client.post(ApiRoutes.EVAL_RUN_CREATE, json=eval_run.model_dump(exclude_none=True))
|
|
12
|
+
except Exception as e:
|
|
13
|
+
log_debug(f"Could not create evaluation run: {e}")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def async_create_eval_run_telemetry(eval_run: EvalRunCreate) -> None:
|
|
17
|
+
"""Telemetry recording for async Eval runs"""
|
|
18
|
+
async with api.AsyncClient() as api_client:
|
|
19
|
+
try:
|
|
20
|
+
await api_client.post(ApiRoutes.EVAL_RUN_CREATE, json=eval_run.model_dump(exclude_none=True))
|
|
21
|
+
except Exception as e:
|
|
22
|
+
log_debug(f"Could not create evaluation run: {e}")
|
agno/api/os.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from agno.api.api import api
|
|
2
|
+
from agno.api.routes import ApiRoutes
|
|
3
|
+
from agno.api.schemas.os import OSLaunch
|
|
4
|
+
from agno.utils.log import log_debug
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def log_os_telemetry(launch: OSLaunch) -> None:
|
|
8
|
+
"""Telemetry recording for OS launches"""
|
|
9
|
+
with api.Client() as api_client:
|
|
10
|
+
try:
|
|
11
|
+
response = api_client.post(
|
|
12
|
+
ApiRoutes.AGENT_OS_LAUNCH,
|
|
13
|
+
json=launch.model_dump(exclude_none=True),
|
|
14
|
+
)
|
|
15
|
+
response.raise_for_status()
|
|
16
|
+
except Exception as e:
|
|
17
|
+
log_debug(f"Could not register OS launch for telemetry: {e}")
|
agno/api/routes.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class ApiRoutes:
|
|
6
|
+
"""API routes for telemetry recordings"""
|
|
7
|
+
|
|
8
|
+
# Runs
|
|
9
|
+
RUN_CREATE: str = "/telemetry/runs"
|
|
10
|
+
EVAL_RUN_CREATE: str = "/telemetry/evals"
|
|
11
|
+
|
|
12
|
+
# OS launch
|
|
13
|
+
AGENT_OS_LAUNCH: str = "/telemetry/os"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
from agno.api.schemas.agent import AgentRunCreate
|
|
4
|
+
from agno.api.schemas.evals import EvalRunCreate
|
|
5
|
+
from agno.api.schemas.os import OSLaunch
|
|
6
|
+
from agno.api.schemas.team import TeamRunCreate
|
|
7
|
+
from agno.api.schemas.workflows import WorkflowRunCreate
|
|
8
|
+
|
|
9
|
+
__all__ = ["AgentRunCreate", "OSLaunch", "EvalRunCreate", "TeamRunCreate", "WorkflowRunCreate"]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from agno.api.schemas.utils import TelemetryRunEventType, get_sdk_version
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AgentRunCreate(BaseModel):
|
|
9
|
+
"""Data sent to API to create an Agent Run"""
|
|
10
|
+
|
|
11
|
+
session_id: str
|
|
12
|
+
run_id: Optional[str] = None
|
|
13
|
+
data: Optional[Dict[Any, Any]] = None
|
|
14
|
+
|
|
15
|
+
sdk_version: str = Field(default_factory=get_sdk_version)
|
|
16
|
+
type: TelemetryRunEventType = TelemetryRunEventType.AGENT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from agno.api.schemas.utils import get_sdk_version
|
|
6
|
+
from agno.db.schemas.evals import EvalType
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EvalRunCreate(BaseModel):
|
|
10
|
+
"""Data sent to the telemetry API to create an Eval run event"""
|
|
11
|
+
|
|
12
|
+
run_id: str
|
|
13
|
+
eval_type: EvalType
|
|
14
|
+
data: Optional[Dict[Any, Any]] = None
|
|
15
|
+
|
|
16
|
+
sdk_version: str = Field(default_factory=get_sdk_version)
|
agno/api/schemas/os.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from agno.api.schemas.utils import get_sdk_version
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OSLaunch(BaseModel):
|
|
9
|
+
"""Data sent to API to create an OS Launch"""
|
|
10
|
+
|
|
11
|
+
os_id: Optional[str] = None
|
|
12
|
+
data: Optional[Dict[Any, Any]] = None
|
|
13
|
+
|
|
14
|
+
sdk_version: str = Field(default_factory=get_sdk_version)
|
agno/api/schemas/team.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from agno.api.schemas.utils import TelemetryRunEventType, get_sdk_version
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TeamRunCreate(BaseModel):
|
|
9
|
+
"""Data sent to API to create a Team Run"""
|
|
10
|
+
|
|
11
|
+
session_id: str
|
|
12
|
+
run_id: Optional[str] = None
|
|
13
|
+
data: Optional[Dict[Any, Any]] = None
|
|
14
|
+
|
|
15
|
+
sdk_version: str = Field(default_factory=get_sdk_version)
|
|
16
|
+
type: TelemetryRunEventType = TelemetryRunEventType.TEAM
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TelemetryRunEventType(str, Enum):
|
|
5
|
+
AGENT = "agent"
|
|
6
|
+
EVAL = "eval"
|
|
7
|
+
TEAM = "team"
|
|
8
|
+
WORKFLOW = "workflow"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_sdk_version() -> str:
|
|
12
|
+
"""Return the installed agno SDK version from package metadata.
|
|
13
|
+
|
|
14
|
+
Falls back to "unknown" if the package metadata isn't available.
|
|
15
|
+
"""
|
|
16
|
+
from importlib.metadata import version as pkg_version
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
return pkg_version("agno")
|
|
20
|
+
except Exception:
|
|
21
|
+
return "unknown"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from agno.api.schemas.utils import TelemetryRunEventType, get_sdk_version
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WorkflowRunCreate(BaseModel):
|
|
9
|
+
"""Data sent to API to create a Workflow Run"""
|
|
10
|
+
|
|
11
|
+
session_id: str
|
|
12
|
+
run_id: Optional[str] = None
|
|
13
|
+
data: Optional[Dict[Any, Any]] = None
|
|
14
|
+
|
|
15
|
+
sdk_version: str = Field(default_factory=get_sdk_version)
|
|
16
|
+
type: TelemetryRunEventType = TelemetryRunEventType.WORKFLOW
|
agno/api/settings.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from importlib import metadata
|
|
4
|
+
|
|
5
|
+
from pydantic import field_validator
|
|
6
|
+
from pydantic_core.core_schema import ValidationInfo
|
|
7
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
8
|
+
|
|
9
|
+
from agno.utils.log import logger
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AgnoAPISettings(BaseSettings):
|
|
13
|
+
app_name: str = "agno"
|
|
14
|
+
app_version: str = metadata.version("agno")
|
|
15
|
+
|
|
16
|
+
api_runtime: str = "prd"
|
|
17
|
+
alpha_features: bool = False
|
|
18
|
+
|
|
19
|
+
api_url: str = "https://os-api.agno.com"
|
|
20
|
+
|
|
21
|
+
model_config = SettingsConfigDict(env_prefix="AGNO_")
|
|
22
|
+
|
|
23
|
+
@field_validator("api_runtime", mode="before")
|
|
24
|
+
def validate_runtime_env(cls, v):
|
|
25
|
+
"""Validate api_runtime."""
|
|
26
|
+
|
|
27
|
+
valid_api_runtimes = ["dev", "stg", "prd"]
|
|
28
|
+
if v.lower() not in valid_api_runtimes:
|
|
29
|
+
raise ValueError(f"Invalid api_runtime: {v}")
|
|
30
|
+
|
|
31
|
+
return v.lower()
|
|
32
|
+
|
|
33
|
+
@field_validator("api_url", mode="before")
|
|
34
|
+
def update_api_url(cls, v, info: ValidationInfo):
|
|
35
|
+
api_runtime = info.data["api_runtime"]
|
|
36
|
+
if api_runtime == "dev":
|
|
37
|
+
from os import getenv
|
|
38
|
+
|
|
39
|
+
if getenv("AGNO_RUNTIME") == "docker":
|
|
40
|
+
return "http://host.docker.internal:7070"
|
|
41
|
+
return "http://localhost:7070"
|
|
42
|
+
elif api_runtime == "stg":
|
|
43
|
+
return "https://api-stg.agno.com"
|
|
44
|
+
else:
|
|
45
|
+
return "https://os-api.agno.com"
|
|
46
|
+
|
|
47
|
+
def gate_alpha_feature(self):
|
|
48
|
+
if not self.alpha_features:
|
|
49
|
+
logger.error("This is an Alpha feature not for general use.\nPlease message the Agno team for access.")
|
|
50
|
+
exit(1)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
agno_api_settings = AgnoAPISettings()
|
agno/api/team.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from agno.api.api import api
|
|
2
|
+
from agno.api.routes import ApiRoutes
|
|
3
|
+
from agno.api.schemas.team import TeamRunCreate
|
|
4
|
+
from agno.utils.log import log_debug
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_team_run(run: TeamRunCreate) -> None:
|
|
8
|
+
"""Telemetry recording for Team runs"""
|
|
9
|
+
with api.Client() as api_client:
|
|
10
|
+
try:
|
|
11
|
+
response = api_client.post(
|
|
12
|
+
ApiRoutes.RUN_CREATE,
|
|
13
|
+
json=run.model_dump(exclude_none=True),
|
|
14
|
+
)
|
|
15
|
+
response.raise_for_status()
|
|
16
|
+
except Exception as e:
|
|
17
|
+
log_debug(f"Could not create Team run: {e}")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def acreate_team_run(run: TeamRunCreate) -> None:
|
|
21
|
+
"""Telemetry recording for async Team runs"""
|
|
22
|
+
async with api.AsyncClient() as api_client:
|
|
23
|
+
try:
|
|
24
|
+
response = await api_client.post(
|
|
25
|
+
ApiRoutes.RUN_CREATE,
|
|
26
|
+
json=run.model_dump(exclude_none=True),
|
|
27
|
+
)
|
|
28
|
+
response.raise_for_status()
|
|
29
|
+
except Exception as e:
|
|
30
|
+
log_debug(f"Could not create Team run: {e}")
|
agno/api/workflow.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from agno.api.api import api
|
|
2
|
+
from agno.api.routes import ApiRoutes
|
|
3
|
+
from agno.api.schemas.workflows import WorkflowRunCreate
|
|
4
|
+
from agno.utils.log import log_debug
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_workflow_run(workflow: WorkflowRunCreate) -> None:
|
|
8
|
+
"""Telemetry recording for Workflow runs"""
|
|
9
|
+
with api.Client() as api_client:
|
|
10
|
+
try:
|
|
11
|
+
api_client.post(
|
|
12
|
+
ApiRoutes.RUN_CREATE,
|
|
13
|
+
json=workflow.model_dump(exclude_none=True),
|
|
14
|
+
)
|
|
15
|
+
except Exception as e:
|
|
16
|
+
log_debug(f"Could not create Workflow: {e}")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def acreate_workflow_run(workflow: WorkflowRunCreate) -> None:
|
|
20
|
+
"""Telemetry recording for async Workflow runs"""
|
|
21
|
+
async with api.AsyncClient() as api_client:
|
|
22
|
+
try:
|
|
23
|
+
await api_client.post(
|
|
24
|
+
ApiRoutes.RUN_CREATE,
|
|
25
|
+
json=workflow.model_dump(exclude_none=True),
|
|
26
|
+
)
|
|
27
|
+
except Exception as e:
|
|
28
|
+
log_debug(f"Could not create Team: {e}")
|
agno/cloud/aws/base.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict
|
|
4
|
+
|
|
5
|
+
from agno.cloud.aws.s3.api_client import AwsApiClient
|
|
6
|
+
from agno.utils.log import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AwsResource(BaseModel):
|
|
10
|
+
"""Base class for AWS Resources."""
|
|
11
|
+
|
|
12
|
+
# Resource name (required)
|
|
13
|
+
name: str
|
|
14
|
+
|
|
15
|
+
# Resource type
|
|
16
|
+
resource_type: Optional[str] = None
|
|
17
|
+
active_resource: Optional[Any] = None
|
|
18
|
+
|
|
19
|
+
skip_delete: bool = False
|
|
20
|
+
skip_create: bool = False
|
|
21
|
+
skip_read: bool = False
|
|
22
|
+
skip_update: bool = False
|
|
23
|
+
|
|
24
|
+
wait_for_create: bool = True
|
|
25
|
+
wait_for_update: bool = True
|
|
26
|
+
wait_for_delete: bool = True
|
|
27
|
+
waiter_delay: int = 30
|
|
28
|
+
waiter_max_attempts: int = 50
|
|
29
|
+
save_output: bool = False
|
|
30
|
+
use_cache: bool = True
|
|
31
|
+
|
|
32
|
+
service_name: str
|
|
33
|
+
service_client: Optional[Any] = None
|
|
34
|
+
service_resource: Optional[Any] = None
|
|
35
|
+
|
|
36
|
+
aws_region: Optional[str] = None
|
|
37
|
+
aws_profile: Optional[str] = None
|
|
38
|
+
|
|
39
|
+
aws_client: Optional[AwsApiClient] = None
|
|
40
|
+
|
|
41
|
+
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
|
|
42
|
+
|
|
43
|
+
def get_resource_name(self) -> str:
|
|
44
|
+
return self.name or self.__class__.__name__
|
|
45
|
+
|
|
46
|
+
def get_resource_type(self) -> str:
|
|
47
|
+
if self.resource_type is None:
|
|
48
|
+
return self.__class__.__name__
|
|
49
|
+
return self.resource_type
|
|
50
|
+
|
|
51
|
+
def get_service_client(self, aws_client: AwsApiClient):
|
|
52
|
+
from boto3 import session
|
|
53
|
+
|
|
54
|
+
if self.service_client is None:
|
|
55
|
+
boto3_session: session = aws_client.boto3_session
|
|
56
|
+
self.service_client = boto3_session.client(service_name=self.service_name)
|
|
57
|
+
return self.service_client
|
|
58
|
+
|
|
59
|
+
def get_service_resource(self, aws_client: AwsApiClient):
|
|
60
|
+
from boto3 import session
|
|
61
|
+
|
|
62
|
+
if self.service_resource is None:
|
|
63
|
+
boto3_session: session = aws_client.boto3_session
|
|
64
|
+
self.service_resource = boto3_session.resource(service_name=self.service_name)
|
|
65
|
+
return self.service_resource
|
|
66
|
+
|
|
67
|
+
def get_aws_region(self) -> Optional[str]:
|
|
68
|
+
if self.aws_region:
|
|
69
|
+
return self.aws_region
|
|
70
|
+
|
|
71
|
+
from os import getenv
|
|
72
|
+
|
|
73
|
+
aws_region_env = getenv("AWS_REGION")
|
|
74
|
+
if aws_region_env is not None:
|
|
75
|
+
logger.debug(f"{'AWS_REGION'}: {aws_region_env}")
|
|
76
|
+
self.aws_region = aws_region_env
|
|
77
|
+
return self.aws_region
|
|
78
|
+
|
|
79
|
+
def get_aws_profile(self) -> Optional[str]:
|
|
80
|
+
if self.aws_profile:
|
|
81
|
+
return self.aws_profile
|
|
82
|
+
|
|
83
|
+
from os import getenv
|
|
84
|
+
|
|
85
|
+
aws_profile_env = getenv("AWS_PROFILE")
|
|
86
|
+
if aws_profile_env is not None:
|
|
87
|
+
logger.debug(f"{'AWS_PROFILE'}: {aws_profile_env}")
|
|
88
|
+
self.aws_profile = aws_profile_env
|
|
89
|
+
return self.aws_profile
|
|
90
|
+
|
|
91
|
+
def get_aws_client(self) -> AwsApiClient:
|
|
92
|
+
if self.aws_client is not None:
|
|
93
|
+
return self.aws_client
|
|
94
|
+
self.aws_client = AwsApiClient(aws_region=self.get_aws_region(), aws_profile=self.get_aws_profile())
|
|
95
|
+
return self.aws_client
|
|
96
|
+
|
|
97
|
+
def _read(self, aws_client: AwsApiClient) -> Any:
|
|
98
|
+
logger.warning(f"@_read method not defined for {self.get_resource_name()}")
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
def read(self, aws_client: Optional[AwsApiClient] = None) -> Any:
|
|
102
|
+
"""Reads the resource from Aws"""
|
|
103
|
+
# Step 1: Use cached value if available
|
|
104
|
+
if self.use_cache and self.active_resource is not None:
|
|
105
|
+
return self.active_resource
|
|
106
|
+
|
|
107
|
+
# Step 2: Skip resource creation if skip_read = True
|
|
108
|
+
if self.skip_read:
|
|
109
|
+
print(f"Skipping read: {self.get_resource_name()}")
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
# Step 3: Read resource
|
|
113
|
+
client: AwsApiClient = aws_client or self.get_aws_client()
|
|
114
|
+
return self._read(client)
|
|
115
|
+
|
|
116
|
+
def is_active(self, aws_client: AwsApiClient) -> bool:
|
|
117
|
+
"""Returns True if the resource is active on Aws"""
|
|
118
|
+
_resource = self.read(aws_client=aws_client)
|
|
119
|
+
return True if _resource is not None else False
|
|
120
|
+
|
|
121
|
+
def _create(self, aws_client: AwsApiClient) -> bool:
|
|
122
|
+
logger.warning(f"@_create method not defined for {self.get_resource_name()}")
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
def create(self, aws_client: Optional[AwsApiClient] = None) -> bool:
|
|
126
|
+
"""Creates the resource on Aws"""
|
|
127
|
+
|
|
128
|
+
# Step 1: Skip resource creation if skip_create = True
|
|
129
|
+
if self.skip_create:
|
|
130
|
+
print(f"Skipping create: {self.get_resource_name()}")
|
|
131
|
+
return True
|
|
132
|
+
|
|
133
|
+
# Step 2: Check if resource is active and use_cache = True
|
|
134
|
+
client: AwsApiClient = aws_client or self.get_aws_client()
|
|
135
|
+
if self.use_cache and self.is_active(client):
|
|
136
|
+
self.resource_created = True
|
|
137
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} already exists")
|
|
138
|
+
# Step 3: Create the resource
|
|
139
|
+
else:
|
|
140
|
+
self.resource_created = self._create(client)
|
|
141
|
+
if self.resource_created:
|
|
142
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} created")
|
|
143
|
+
|
|
144
|
+
# Step 4: Run post create steps
|
|
145
|
+
if self.resource_created:
|
|
146
|
+
logger.debug(f"Running post-create for {self.get_resource_type()}: {self.get_resource_name()}")
|
|
147
|
+
return self.post_create(client)
|
|
148
|
+
logger.error(f"Failed to create {self.get_resource_type()}: {self.get_resource_name()}")
|
|
149
|
+
return self.resource_created
|
|
150
|
+
|
|
151
|
+
def post_create(self, aws_client: AwsApiClient) -> bool:
|
|
152
|
+
return True
|
|
153
|
+
|
|
154
|
+
def _update(self, aws_client: AwsApiClient) -> Any:
|
|
155
|
+
logger.warning(f"@_update method not defined for {self.get_resource_name()}")
|
|
156
|
+
return True
|
|
157
|
+
|
|
158
|
+
def update(self, aws_client: Optional[AwsApiClient] = None) -> bool:
|
|
159
|
+
"""Updates the resource on Aws"""
|
|
160
|
+
|
|
161
|
+
# Step 1: Skip resource update if skip_update = True
|
|
162
|
+
if self.skip_update:
|
|
163
|
+
print(f"Skipping update: {self.get_resource_name()}")
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
# Step 2: Update the resource
|
|
167
|
+
client: AwsApiClient = aws_client or self.get_aws_client()
|
|
168
|
+
if self.is_active(client):
|
|
169
|
+
self.resource_updated = self._update(client)
|
|
170
|
+
else:
|
|
171
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} does not exist")
|
|
172
|
+
return True
|
|
173
|
+
|
|
174
|
+
# Step 3: Run post update steps
|
|
175
|
+
if self.resource_updated:
|
|
176
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} updated")
|
|
177
|
+
logger.debug(f"Running post-update for {self.get_resource_type()}: {self.get_resource_name()}")
|
|
178
|
+
return self.post_update(client)
|
|
179
|
+
logger.error(f"Failed to update {self.get_resource_type()}: {self.get_resource_name()}")
|
|
180
|
+
return self.resource_updated
|
|
181
|
+
|
|
182
|
+
def post_update(self, aws_client: AwsApiClient) -> bool:
|
|
183
|
+
return True
|
|
184
|
+
|
|
185
|
+
def _delete(self, aws_client: AwsApiClient) -> Any:
|
|
186
|
+
logger.warning(f"@_delete method not defined for {self.get_resource_name()}")
|
|
187
|
+
return True
|
|
188
|
+
|
|
189
|
+
def delete(self, aws_client: Optional[AwsApiClient] = None) -> bool:
|
|
190
|
+
"""Deletes the resource from Aws"""
|
|
191
|
+
|
|
192
|
+
# Step 1: Skip resource deletion if skip_delete = True
|
|
193
|
+
if self.skip_delete:
|
|
194
|
+
print(f"Skipping delete: {self.get_resource_name()}")
|
|
195
|
+
return True
|
|
196
|
+
|
|
197
|
+
# Step 2: Delete the resource
|
|
198
|
+
client: AwsApiClient = aws_client or self.get_aws_client()
|
|
199
|
+
if self.is_active(client):
|
|
200
|
+
self.resource_deleted = self._delete(client)
|
|
201
|
+
else:
|
|
202
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} does not exist")
|
|
203
|
+
return True
|
|
204
|
+
|
|
205
|
+
# Step 3: Run post delete steps
|
|
206
|
+
if self.resource_deleted:
|
|
207
|
+
print(f"{self.get_resource_type()}: {self.get_resource_name()} deleted")
|
|
208
|
+
logger.debug(f"Running post-delete for {self.get_resource_type()}: {self.get_resource_name()}.")
|
|
209
|
+
return self.post_delete(client)
|
|
210
|
+
logger.error(f"Failed to delete {self.get_resource_type()}: {self.get_resource_name()}")
|
|
211
|
+
return self.resource_deleted
|
|
212
|
+
|
|
213
|
+
def post_delete(self, aws_client: AwsApiClient) -> bool:
|
|
214
|
+
return True
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
from agno.utils.log import logger
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AwsApiClient:
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
aws_region: Optional[str] = None,
|
|
10
|
+
aws_profile: Optional[str] = None,
|
|
11
|
+
):
|
|
12
|
+
super().__init__()
|
|
13
|
+
self.aws_region: Optional[str] = aws_region
|
|
14
|
+
self.aws_profile: Optional[str] = aws_profile
|
|
15
|
+
|
|
16
|
+
# aws boto3 session
|
|
17
|
+
self._boto3_session: Optional[Any] = None
|
|
18
|
+
logger.debug("**-+-** AwsApiClient created")
|
|
19
|
+
|
|
20
|
+
def create_boto3_session(self) -> Optional[Any]:
|
|
21
|
+
"""Create a boto3 session"""
|
|
22
|
+
import boto3
|
|
23
|
+
|
|
24
|
+
logger.debug("Creating boto3.Session")
|
|
25
|
+
try:
|
|
26
|
+
self._boto3_session = boto3.Session(
|
|
27
|
+
region_name=self.aws_region,
|
|
28
|
+
profile_name=self.aws_profile,
|
|
29
|
+
)
|
|
30
|
+
logger.debug("**-+-** boto3.Session created")
|
|
31
|
+
logger.debug(f"\taws_region: {self._boto3_session.region_name}")
|
|
32
|
+
logger.debug(f"\taws_profile: {self._boto3_session.profile_name}")
|
|
33
|
+
except Exception as e:
|
|
34
|
+
logger.error("Could not connect to aws. Please confirm aws cli is installed and configured")
|
|
35
|
+
logger.error(e)
|
|
36
|
+
exit(0)
|
|
37
|
+
return self._boto3_session
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def boto3_session(self) -> Optional[Any]:
|
|
41
|
+
if self._boto3_session is None:
|
|
42
|
+
self._boto3_session = self.create_boto3_session()
|
|
43
|
+
return self._boto3_session
|