agno 0.1.2__py3-none-any.whl → 2.3.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 +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- 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/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -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 +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -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 +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -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 +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- 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/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- 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/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -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 +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -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 +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- 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 +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -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 +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -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 +249 -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 +147 -0
- agno/os/interfaces/agui/utils.py +574 -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 +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -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 +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -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/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -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 +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- 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 +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- 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/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- 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 +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- 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 +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -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 +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -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/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- 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 +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -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 +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/workspace/operator.py
DELETED
|
@@ -1,758 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Dict, List, Optional, cast
|
|
3
|
-
|
|
4
|
-
from rich.prompt import Prompt
|
|
5
|
-
|
|
6
|
-
from agno.api.schemas.team import TeamIdentifier, TeamSchema
|
|
7
|
-
from agno.api.schemas.workspace import (
|
|
8
|
-
WorkspaceCreate,
|
|
9
|
-
WorkspaceEvent,
|
|
10
|
-
WorkspaceSchema,
|
|
11
|
-
WorkspaceUpdate,
|
|
12
|
-
)
|
|
13
|
-
from agno.api.workspace import log_workspace_event
|
|
14
|
-
from agno.cli.config import AgnoCliConfig
|
|
15
|
-
from agno.cli.console import (
|
|
16
|
-
console,
|
|
17
|
-
log_config_not_available_msg,
|
|
18
|
-
print_heading,
|
|
19
|
-
print_info,
|
|
20
|
-
print_subheading,
|
|
21
|
-
)
|
|
22
|
-
from agno.infra.resources import InfraResources
|
|
23
|
-
from agno.utils.common import str_to_int
|
|
24
|
-
from agno.utils.log import logger
|
|
25
|
-
from agno.workspace.config import WorkspaceConfig
|
|
26
|
-
from agno.workspace.enums import WorkspaceStarterTemplate
|
|
27
|
-
|
|
28
|
-
TEMPLATE_TO_NAME_MAP: Dict[WorkspaceStarterTemplate, str] = {
|
|
29
|
-
WorkspaceStarterTemplate.agent_app: "agent-app",
|
|
30
|
-
WorkspaceStarterTemplate.agent_api: "agent-api",
|
|
31
|
-
}
|
|
32
|
-
TEMPLATE_TO_REPO_MAP: Dict[WorkspaceStarterTemplate, str] = {
|
|
33
|
-
WorkspaceStarterTemplate.agent_app: "https://github.com/phidatahq/agent-app.git",
|
|
34
|
-
WorkspaceStarterTemplate.agent_api: "https://github.com/phidatahq/agent-api.git",
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def create_workspace(
|
|
39
|
-
name: Optional[str] = None, template: Optional[str] = None, url: Optional[str] = None
|
|
40
|
-
) -> Optional[WorkspaceConfig]:
|
|
41
|
-
"""Creates a new workspace and returns the WorkspaceConfig.
|
|
42
|
-
|
|
43
|
-
This function clones a template or url on the users machine at the path:
|
|
44
|
-
cwd/name
|
|
45
|
-
"""
|
|
46
|
-
from shutil import copytree
|
|
47
|
-
|
|
48
|
-
import git
|
|
49
|
-
|
|
50
|
-
from agno.cli.operator import initialize_agno
|
|
51
|
-
from agno.utils.filesystem import rmdir_recursive
|
|
52
|
-
from agno.utils.git import GitCloneProgress
|
|
53
|
-
from agno.workspace.helpers import get_workspace_dir_path
|
|
54
|
-
|
|
55
|
-
current_dir: Path = Path(".").resolve()
|
|
56
|
-
|
|
57
|
-
# Initialize Agno before creating a workspace
|
|
58
|
-
agno_config: Optional[AgnoCliConfig] = AgnoCliConfig.from_saved_config()
|
|
59
|
-
if not agno_config:
|
|
60
|
-
agno_config = initialize_agno()
|
|
61
|
-
if not agno_config:
|
|
62
|
-
log_config_not_available_msg()
|
|
63
|
-
return None
|
|
64
|
-
agno_config = cast(AgnoCliConfig, agno_config)
|
|
65
|
-
|
|
66
|
-
ws_dir_name: Optional[str] = name
|
|
67
|
-
repo_to_clone: Optional[str] = url
|
|
68
|
-
ws_template = WorkspaceStarterTemplate.agent_app
|
|
69
|
-
templates = list(WorkspaceStarterTemplate.__members__.values())
|
|
70
|
-
|
|
71
|
-
if repo_to_clone is None:
|
|
72
|
-
# Get repo_to_clone from template
|
|
73
|
-
if template is None:
|
|
74
|
-
# Get starter template from the user if template is not provided
|
|
75
|
-
# Display available starter templates and ask user to select one
|
|
76
|
-
print_info("Select starter template or press Enter for default (agent-app)")
|
|
77
|
-
for template_id, template_name in enumerate(templates, start=1):
|
|
78
|
-
print_info(" [b][{}][/b] {}".format(template_id, WorkspaceStarterTemplate(template_name).value))
|
|
79
|
-
|
|
80
|
-
# Get starter template from the user
|
|
81
|
-
template_choices = [str(idx) for idx, _ in enumerate(templates, start=1)]
|
|
82
|
-
template_inp_raw = Prompt.ask("Template Number", choices=template_choices, default="1", show_choices=False)
|
|
83
|
-
# Convert input to int
|
|
84
|
-
template_inp = str_to_int(template_inp_raw)
|
|
85
|
-
|
|
86
|
-
if template_inp is not None:
|
|
87
|
-
template_inp_idx = template_inp - 1
|
|
88
|
-
ws_template = WorkspaceStarterTemplate(templates[template_inp_idx])
|
|
89
|
-
elif template.lower() in WorkspaceStarterTemplate.__members__.values():
|
|
90
|
-
ws_template = WorkspaceStarterTemplate(template)
|
|
91
|
-
else:
|
|
92
|
-
raise Exception(f"{template} is not a supported template, please choose from: {templates}")
|
|
93
|
-
|
|
94
|
-
logger.debug(f"Selected Template: {ws_template.value}")
|
|
95
|
-
repo_to_clone = TEMPLATE_TO_REPO_MAP.get(ws_template)
|
|
96
|
-
|
|
97
|
-
if ws_dir_name is None:
|
|
98
|
-
default_ws_name = "agent-app"
|
|
99
|
-
if url is not None:
|
|
100
|
-
# Get default_ws_name from url
|
|
101
|
-
default_ws_name = url.split("/")[-1].split(".")[0]
|
|
102
|
-
else:
|
|
103
|
-
# Get default_ws_name from template
|
|
104
|
-
default_ws_name = TEMPLATE_TO_NAME_MAP.get(ws_template, "agent-app")
|
|
105
|
-
logger.debug(f"Asking for ws name with default: {default_ws_name}")
|
|
106
|
-
# Ask user for workspace name if not provided
|
|
107
|
-
ws_dir_name = Prompt.ask("Workspace Name", default=default_ws_name, console=console)
|
|
108
|
-
|
|
109
|
-
if ws_dir_name is None:
|
|
110
|
-
logger.error("Workspace name is required")
|
|
111
|
-
return None
|
|
112
|
-
if repo_to_clone is None:
|
|
113
|
-
logger.error("URL or Template is required")
|
|
114
|
-
return None
|
|
115
|
-
|
|
116
|
-
# Check if we can create the workspace in the current dir
|
|
117
|
-
ws_root_path: Path = current_dir.joinpath(ws_dir_name)
|
|
118
|
-
if ws_root_path.exists():
|
|
119
|
-
logger.error(f"Directory {ws_root_path} exists, please delete directory or choose another name for workspace")
|
|
120
|
-
return None
|
|
121
|
-
|
|
122
|
-
print_info(f"Creating {str(ws_root_path)}")
|
|
123
|
-
logger.debug("Cloning: {}".format(repo_to_clone))
|
|
124
|
-
try:
|
|
125
|
-
_cloned_git_repo: git.Repo = git.Repo.clone_from(
|
|
126
|
-
repo_to_clone,
|
|
127
|
-
str(ws_root_path),
|
|
128
|
-
progress=GitCloneProgress(), # type: ignore
|
|
129
|
-
)
|
|
130
|
-
except Exception as e:
|
|
131
|
-
logger.error(e)
|
|
132
|
-
return None
|
|
133
|
-
|
|
134
|
-
# Remove existing .git folder
|
|
135
|
-
_dot_git_folder = ws_root_path.joinpath(".git")
|
|
136
|
-
_dot_git_exists = _dot_git_folder.exists()
|
|
137
|
-
if _dot_git_exists:
|
|
138
|
-
logger.debug(f"Deleting {_dot_git_folder}")
|
|
139
|
-
try:
|
|
140
|
-
_dot_git_exists = not rmdir_recursive(_dot_git_folder)
|
|
141
|
-
except Exception as e:
|
|
142
|
-
logger.warning(f"Failed to delete {_dot_git_folder}: {e}")
|
|
143
|
-
logger.info("Please delete the .git folder manually")
|
|
144
|
-
pass
|
|
145
|
-
|
|
146
|
-
agno_config.add_new_ws_to_config(ws_root_path=ws_root_path)
|
|
147
|
-
|
|
148
|
-
try:
|
|
149
|
-
# workspace_dir_path is the path to the ws_root/workspace dir
|
|
150
|
-
workspace_dir_path: Path = get_workspace_dir_path(ws_root_path)
|
|
151
|
-
workspace_secrets_dir = workspace_dir_path.joinpath("secrets").resolve()
|
|
152
|
-
workspace_example_secrets_dir = workspace_dir_path.joinpath("example_secrets").resolve()
|
|
153
|
-
|
|
154
|
-
print_info(f"Creating {str(workspace_secrets_dir)}")
|
|
155
|
-
copytree(
|
|
156
|
-
str(workspace_example_secrets_dir),
|
|
157
|
-
str(workspace_secrets_dir),
|
|
158
|
-
)
|
|
159
|
-
except Exception as e:
|
|
160
|
-
logger.warning(f"Could not create workspace/secrets: {e}")
|
|
161
|
-
logger.warning("Please manually copy workspace/example_secrets to workspace/secrets")
|
|
162
|
-
|
|
163
|
-
print_info(f"Your new workspace is available at {str(ws_root_path)}\n")
|
|
164
|
-
return setup_workspace(ws_root_path=ws_root_path)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def setup_workspace(ws_root_path: Path) -> Optional[WorkspaceConfig]:
|
|
168
|
-
"""Setup an Agno workspace at `ws_root_path` and return the WorkspaceConfig
|
|
169
|
-
|
|
170
|
-
1. Pre-requisites
|
|
171
|
-
1.1 Check ws_root_path exists and is a directory
|
|
172
|
-
1.2 Create AgnoCliConfig if needed
|
|
173
|
-
1.3 Create a WorkspaceConfig if needed
|
|
174
|
-
1.4 Get the workspace name
|
|
175
|
-
1.5 Get the git remote origin url
|
|
176
|
-
1.6 Create anon user if needed
|
|
177
|
-
|
|
178
|
-
2. Create or update WorkspaceSchema
|
|
179
|
-
2.1 Check if a ws_schema exists for this workspace, meaning this workspace has a record in agno-api
|
|
180
|
-
2.2 Create WorkspaceSchema if it doesn't exist
|
|
181
|
-
2.3 Update WorkspaceSchema if git_url is updated
|
|
182
|
-
"""
|
|
183
|
-
from rich.live import Live
|
|
184
|
-
from rich.status import Status
|
|
185
|
-
|
|
186
|
-
from agno.cli.operator import initialize_agno
|
|
187
|
-
from agno.utils.git import get_remote_origin_for_dir
|
|
188
|
-
from agno.workspace.helpers import get_workspace_dir_path
|
|
189
|
-
|
|
190
|
-
print_heading("Setting up workspace\n")
|
|
191
|
-
|
|
192
|
-
######################################################
|
|
193
|
-
## 1. Pre-requisites
|
|
194
|
-
######################################################
|
|
195
|
-
# 1.1 Check ws_root_path exists and is a directory
|
|
196
|
-
ws_is_valid: bool = ws_root_path is not None and ws_root_path.exists() and ws_root_path.is_dir()
|
|
197
|
-
if not ws_is_valid:
|
|
198
|
-
logger.error("Invalid directory: {}".format(ws_root_path))
|
|
199
|
-
return None
|
|
200
|
-
|
|
201
|
-
# 1.2 Create AgnoCliConfig if needed
|
|
202
|
-
agno_config: Optional[AgnoCliConfig] = AgnoCliConfig.from_saved_config()
|
|
203
|
-
if not agno_config:
|
|
204
|
-
agno_config = initialize_agno()
|
|
205
|
-
if not agno_config:
|
|
206
|
-
log_config_not_available_msg()
|
|
207
|
-
return None
|
|
208
|
-
|
|
209
|
-
# 1.3 Create a WorkspaceConfig if needed
|
|
210
|
-
logger.debug(f"Checking for a workspace at {ws_root_path}")
|
|
211
|
-
ws_config: Optional[WorkspaceConfig] = agno_config.get_ws_config_by_path(ws_root_path)
|
|
212
|
-
if ws_config is None:
|
|
213
|
-
# There's no record of this workspace, reasons:
|
|
214
|
-
# - The user is setting up a new workspace
|
|
215
|
-
# - The user ran `ag init -r` which erased existing workspaces
|
|
216
|
-
logger.debug(f"Could not find a workspace at: {ws_root_path}")
|
|
217
|
-
|
|
218
|
-
# Check if the workspace contains a `workspace` dir
|
|
219
|
-
workspace_ws_dir_path = get_workspace_dir_path(ws_root_path)
|
|
220
|
-
logger.debug(f"Found the `workspace` configuration at: {workspace_ws_dir_path}")
|
|
221
|
-
ws_config = agno_config.create_or_update_ws_config(ws_root_path=ws_root_path, set_as_active=True)
|
|
222
|
-
if ws_config is None:
|
|
223
|
-
logger.error(f"Failed to create WorkspaceConfig for {ws_root_path}")
|
|
224
|
-
return None
|
|
225
|
-
else:
|
|
226
|
-
logger.debug(f"Found workspace at {ws_root_path}")
|
|
227
|
-
|
|
228
|
-
# 1.4 Get the workspace name
|
|
229
|
-
workspace_name = ws_root_path.stem.replace(" ", "-").replace("_", "-").lower()
|
|
230
|
-
logger.debug(f"Workspace name: {workspace_name}")
|
|
231
|
-
|
|
232
|
-
# 1.5 Get the git remote origin url
|
|
233
|
-
git_remote_origin_url: Optional[str] = get_remote_origin_for_dir(ws_root_path)
|
|
234
|
-
logger.debug("Git origin: {}".format(git_remote_origin_url))
|
|
235
|
-
|
|
236
|
-
# 1.6 Create anon user if the user is not logged in
|
|
237
|
-
if agno_config.user is None:
|
|
238
|
-
from agno.api.user import create_anon_user
|
|
239
|
-
|
|
240
|
-
logger.debug("Creating anon user")
|
|
241
|
-
with Live(transient=True) as live_log:
|
|
242
|
-
status = Status("Creating user...", spinner="aesthetic", speed=2.0, refresh_per_second=10)
|
|
243
|
-
live_log.update(status)
|
|
244
|
-
anon_user = create_anon_user()
|
|
245
|
-
status.stop()
|
|
246
|
-
if anon_user is not None:
|
|
247
|
-
agno_config.user = anon_user
|
|
248
|
-
|
|
249
|
-
######################################################
|
|
250
|
-
## 2. Create or update WorkspaceSchema
|
|
251
|
-
######################################################
|
|
252
|
-
# 2.1 Check if a ws_schema exists for this workspace, meaning this workspace has a record in agno-api
|
|
253
|
-
ws_schema: Optional[WorkspaceSchema] = ws_config.ws_schema if ws_config is not None else None
|
|
254
|
-
if agno_config.user is not None:
|
|
255
|
-
# 2.2 Create WorkspaceSchema if it doesn't exist
|
|
256
|
-
if ws_schema is None or ws_schema.id_workspace is None:
|
|
257
|
-
from agno.api.team import get_teams_for_user
|
|
258
|
-
from agno.api.workspace import create_workspace_for_user
|
|
259
|
-
|
|
260
|
-
# If ws_schema is None, this is a NEW WORKSPACE.
|
|
261
|
-
# We make a call to the api to create a new ws_schema
|
|
262
|
-
logger.debug("Creating ws_schema")
|
|
263
|
-
logger.debug(f"Getting teams for user: {agno_config.user.email}")
|
|
264
|
-
teams: Optional[List[TeamSchema]] = None
|
|
265
|
-
selected_team: Optional[TeamSchema] = None
|
|
266
|
-
team_identifier: Optional[TeamIdentifier] = None
|
|
267
|
-
with Live(transient=True) as live_log:
|
|
268
|
-
status = Status(
|
|
269
|
-
"Checking for available teams...", spinner="aesthetic", speed=2.0, refresh_per_second=10
|
|
270
|
-
)
|
|
271
|
-
live_log.update(status)
|
|
272
|
-
teams = get_teams_for_user(agno_config.user)
|
|
273
|
-
status.stop()
|
|
274
|
-
if teams is not None and len(teams) > 0:
|
|
275
|
-
logger.debug(f"The user has {len(teams)} available teams. Checking if they want to use one of them")
|
|
276
|
-
print_info("Which account would you like to create this workspace in?")
|
|
277
|
-
print_info(" [b][1][/b] Personal (default)")
|
|
278
|
-
for team_idx, team_schema in enumerate(teams, start=2):
|
|
279
|
-
print_info(" [b][{}][/b] {}".format(team_idx, team_schema.name))
|
|
280
|
-
|
|
281
|
-
account_choices = ["1"] + [str(idx) for idx, _ in enumerate(teams, start=2)]
|
|
282
|
-
account_inp_raw = Prompt.ask("Account Number", choices=account_choices, default="1", show_choices=False)
|
|
283
|
-
account_inp = str_to_int(account_inp_raw)
|
|
284
|
-
|
|
285
|
-
if account_inp is not None:
|
|
286
|
-
if account_inp == 1:
|
|
287
|
-
print_info("Creating workspace in your personal account")
|
|
288
|
-
else:
|
|
289
|
-
selected_team = teams[account_inp - 2]
|
|
290
|
-
print_info(f"Creating workspace in {selected_team.name}")
|
|
291
|
-
team_identifier = TeamIdentifier(id_team=selected_team.id_team, team_url=selected_team.url)
|
|
292
|
-
|
|
293
|
-
with Live(transient=True) as live_log:
|
|
294
|
-
status = Status("Creating workspace...", spinner="aesthetic", speed=2.0, refresh_per_second=10)
|
|
295
|
-
live_log.update(status)
|
|
296
|
-
ws_schema = create_workspace_for_user(
|
|
297
|
-
user=agno_config.user,
|
|
298
|
-
workspace=WorkspaceCreate(
|
|
299
|
-
ws_name=workspace_name,
|
|
300
|
-
git_url=git_remote_origin_url,
|
|
301
|
-
),
|
|
302
|
-
team=team_identifier,
|
|
303
|
-
)
|
|
304
|
-
status.stop()
|
|
305
|
-
|
|
306
|
-
logger.debug(f"Workspace created: {workspace_name}")
|
|
307
|
-
if selected_team is not None:
|
|
308
|
-
logger.debug(f"Selected team: {selected_team.name}")
|
|
309
|
-
ws_config = agno_config.create_or_update_ws_config(
|
|
310
|
-
ws_root_path=ws_root_path, ws_schema=ws_schema, ws_team=selected_team, set_as_active=True
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
# 2.3 Update WorkspaceSchema if git_url is updated
|
|
314
|
-
if git_remote_origin_url is not None and ws_schema is not None and ws_schema.git_url != git_remote_origin_url:
|
|
315
|
-
from agno.api.workspace import update_workspace_for_team, update_workspace_for_user
|
|
316
|
-
|
|
317
|
-
logger.debug("Updating workspace")
|
|
318
|
-
logger.debug(f"Existing git_url: {ws_schema.git_url}")
|
|
319
|
-
logger.debug(f"New git_url: {git_remote_origin_url}")
|
|
320
|
-
|
|
321
|
-
if ws_config is not None and ws_config.ws_team is not None:
|
|
322
|
-
updated_workspace_schema = update_workspace_for_team(
|
|
323
|
-
user=agno_config.user,
|
|
324
|
-
workspace=WorkspaceUpdate(
|
|
325
|
-
id_workspace=ws_schema.id_workspace,
|
|
326
|
-
git_url=git_remote_origin_url,
|
|
327
|
-
),
|
|
328
|
-
team=TeamIdentifier(id_team=ws_config.ws_team.id_team, team_url=ws_config.ws_team.url),
|
|
329
|
-
)
|
|
330
|
-
else:
|
|
331
|
-
updated_workspace_schema = update_workspace_for_user(
|
|
332
|
-
user=agno_config.user,
|
|
333
|
-
workspace=WorkspaceUpdate(
|
|
334
|
-
id_workspace=ws_schema.id_workspace,
|
|
335
|
-
git_url=git_remote_origin_url,
|
|
336
|
-
),
|
|
337
|
-
)
|
|
338
|
-
if updated_workspace_schema is not None:
|
|
339
|
-
# Update the ws_schema for this workspace.
|
|
340
|
-
ws_config = agno_config.create_or_update_ws_config(
|
|
341
|
-
ws_root_path=ws_root_path, ws_schema=updated_workspace_schema, set_as_active=True
|
|
342
|
-
)
|
|
343
|
-
else:
|
|
344
|
-
logger.debug("Failed to update workspace. Please setup again")
|
|
345
|
-
|
|
346
|
-
if ws_config is not None:
|
|
347
|
-
# logger.debug("Workspace Config: {}".format(ws_config.model_dump_json(indent=2)))
|
|
348
|
-
print_subheading("Setup complete! Next steps:")
|
|
349
|
-
print_info("1. Start workspace:")
|
|
350
|
-
print_info("\tag ws up")
|
|
351
|
-
print_info("2. Stop workspace:")
|
|
352
|
-
print_info("\tag ws down")
|
|
353
|
-
|
|
354
|
-
if ws_config.ws_schema is not None and agno_config.user is not None:
|
|
355
|
-
log_workspace_event(
|
|
356
|
-
user=agno_config.user,
|
|
357
|
-
workspace_event=WorkspaceEvent(
|
|
358
|
-
id_workspace=ws_config.ws_schema.id_workspace,
|
|
359
|
-
event_type="setup",
|
|
360
|
-
event_status="success",
|
|
361
|
-
event_data={"workspace_root_path": str(ws_root_path)},
|
|
362
|
-
),
|
|
363
|
-
)
|
|
364
|
-
return ws_config
|
|
365
|
-
else:
|
|
366
|
-
print_info("Workspace setup unsuccessful. Please try again.")
|
|
367
|
-
return None
|
|
368
|
-
######################################################
|
|
369
|
-
## End Workspace setup
|
|
370
|
-
######################################################
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
def start_workspace(
|
|
374
|
-
agno_config: AgnoCliConfig,
|
|
375
|
-
ws_config: WorkspaceConfig,
|
|
376
|
-
target_env: Optional[str] = None,
|
|
377
|
-
target_infra: Optional[str] = None,
|
|
378
|
-
target_group: Optional[str] = None,
|
|
379
|
-
target_name: Optional[str] = None,
|
|
380
|
-
target_type: Optional[str] = None,
|
|
381
|
-
dry_run: Optional[bool] = False,
|
|
382
|
-
auto_confirm: Optional[bool] = False,
|
|
383
|
-
force: Optional[bool] = None,
|
|
384
|
-
pull: Optional[bool] = False,
|
|
385
|
-
) -> None:
|
|
386
|
-
"""Start an Agno Workspace. This is called from `ag ws up`"""
|
|
387
|
-
if ws_config is None:
|
|
388
|
-
logger.error("WorkspaceConfig invalid")
|
|
389
|
-
return
|
|
390
|
-
|
|
391
|
-
print_heading("Starting workspace: {}".format(str(ws_config.ws_root_path.stem)))
|
|
392
|
-
logger.debug(f"\ttarget_env : {target_env}")
|
|
393
|
-
logger.debug(f"\ttarget_infra : {target_infra}")
|
|
394
|
-
logger.debug(f"\ttarget_group : {target_group}")
|
|
395
|
-
logger.debug(f"\ttarget_name : {target_name}")
|
|
396
|
-
logger.debug(f"\ttarget_type : {target_type}")
|
|
397
|
-
logger.debug(f"\tdry_run : {dry_run}")
|
|
398
|
-
logger.debug(f"\tauto_confirm : {auto_confirm}")
|
|
399
|
-
logger.debug(f"\tforce : {force}")
|
|
400
|
-
logger.debug(f"\tpull : {pull}")
|
|
401
|
-
|
|
402
|
-
# Set the local environment variables before processing configs
|
|
403
|
-
ws_config.set_local_env()
|
|
404
|
-
|
|
405
|
-
# Get resource groups to deploy
|
|
406
|
-
resource_groups_to_create: List[InfraResources] = ws_config.get_resources(
|
|
407
|
-
env=target_env,
|
|
408
|
-
infra=target_infra,
|
|
409
|
-
order="create",
|
|
410
|
-
)
|
|
411
|
-
|
|
412
|
-
# Track number of resource groups created
|
|
413
|
-
num_rgs_created = 0
|
|
414
|
-
num_rgs_to_create = len(resource_groups_to_create)
|
|
415
|
-
# Track number of resources created
|
|
416
|
-
num_resources_created = 0
|
|
417
|
-
num_resources_to_create = 0
|
|
418
|
-
|
|
419
|
-
if num_rgs_to_create == 0:
|
|
420
|
-
print_info("No resources to create")
|
|
421
|
-
return
|
|
422
|
-
|
|
423
|
-
logger.debug(f"Deploying {num_rgs_to_create} resource groups")
|
|
424
|
-
for rg in resource_groups_to_create:
|
|
425
|
-
_num_resources_created, _num_resources_to_create = rg.create_resources(
|
|
426
|
-
group_filter=target_group,
|
|
427
|
-
name_filter=target_name,
|
|
428
|
-
type_filter=target_type,
|
|
429
|
-
dry_run=dry_run,
|
|
430
|
-
auto_confirm=auto_confirm,
|
|
431
|
-
force=force,
|
|
432
|
-
pull=pull,
|
|
433
|
-
)
|
|
434
|
-
if _num_resources_created > 0:
|
|
435
|
-
num_rgs_created += 1
|
|
436
|
-
num_resources_created += _num_resources_created
|
|
437
|
-
num_resources_to_create += _num_resources_to_create
|
|
438
|
-
logger.debug(f"Deployed {num_resources_created} resources in {num_rgs_created} resource groups")
|
|
439
|
-
|
|
440
|
-
if dry_run:
|
|
441
|
-
return
|
|
442
|
-
|
|
443
|
-
if num_resources_created == 0:
|
|
444
|
-
return
|
|
445
|
-
|
|
446
|
-
print_heading(f"\n--**-- ResourceGroups deployed: {num_rgs_created}/{num_rgs_to_create}\n")
|
|
447
|
-
|
|
448
|
-
workspace_event_status = "in_progress"
|
|
449
|
-
if num_resources_created == num_resources_to_create:
|
|
450
|
-
workspace_event_status = "success"
|
|
451
|
-
else:
|
|
452
|
-
logger.error("Some resources failed to create, please check logs")
|
|
453
|
-
workspace_event_status = "failed"
|
|
454
|
-
|
|
455
|
-
if (
|
|
456
|
-
agno_config.user is not None
|
|
457
|
-
and ws_config.ws_schema is not None
|
|
458
|
-
and ws_config.ws_schema.id_workspace is not None
|
|
459
|
-
):
|
|
460
|
-
# Log workspace start event
|
|
461
|
-
log_workspace_event(
|
|
462
|
-
user=agno_config.user,
|
|
463
|
-
workspace_event=WorkspaceEvent(
|
|
464
|
-
id_workspace=ws_config.ws_schema.id_workspace,
|
|
465
|
-
event_type="start",
|
|
466
|
-
event_status=workspace_event_status,
|
|
467
|
-
event_data={
|
|
468
|
-
"target_env": target_env,
|
|
469
|
-
"target_infra": target_infra,
|
|
470
|
-
"target_group": target_group,
|
|
471
|
-
"target_name": target_name,
|
|
472
|
-
"target_type": target_type,
|
|
473
|
-
"dry_run": dry_run,
|
|
474
|
-
"auto_confirm": auto_confirm,
|
|
475
|
-
"force": force,
|
|
476
|
-
},
|
|
477
|
-
),
|
|
478
|
-
)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
def stop_workspace(
|
|
482
|
-
agno_config: AgnoCliConfig,
|
|
483
|
-
ws_config: WorkspaceConfig,
|
|
484
|
-
target_env: Optional[str] = None,
|
|
485
|
-
target_infra: Optional[str] = None,
|
|
486
|
-
target_group: Optional[str] = None,
|
|
487
|
-
target_name: Optional[str] = None,
|
|
488
|
-
target_type: Optional[str] = None,
|
|
489
|
-
dry_run: Optional[bool] = False,
|
|
490
|
-
auto_confirm: Optional[bool] = False,
|
|
491
|
-
force: Optional[bool] = None,
|
|
492
|
-
) -> None:
|
|
493
|
-
"""Stop an Agno Workspace. This is called from `ag ws down`"""
|
|
494
|
-
if ws_config is None:
|
|
495
|
-
logger.error("WorkspaceConfig invalid")
|
|
496
|
-
return
|
|
497
|
-
|
|
498
|
-
print_heading("Stopping workspace: {}".format(str(ws_config.ws_root_path.stem)))
|
|
499
|
-
logger.debug(f"\ttarget_env : {target_env}")
|
|
500
|
-
logger.debug(f"\ttarget_infra : {target_infra}")
|
|
501
|
-
logger.debug(f"\ttarget_group : {target_group}")
|
|
502
|
-
logger.debug(f"\ttarget_name : {target_name}")
|
|
503
|
-
logger.debug(f"\ttarget_type : {target_type}")
|
|
504
|
-
logger.debug(f"\tdry_run : {dry_run}")
|
|
505
|
-
logger.debug(f"\tauto_confirm : {auto_confirm}")
|
|
506
|
-
logger.debug(f"\tforce : {force}")
|
|
507
|
-
|
|
508
|
-
# Set the local environment variables before processing configs
|
|
509
|
-
ws_config.set_local_env()
|
|
510
|
-
|
|
511
|
-
# Get resource groups to delete
|
|
512
|
-
resource_groups_to_delete: List[InfraResources] = ws_config.get_resources(
|
|
513
|
-
env=target_env,
|
|
514
|
-
infra=target_infra,
|
|
515
|
-
order="delete",
|
|
516
|
-
)
|
|
517
|
-
|
|
518
|
-
# Track number of resource groups deleted
|
|
519
|
-
num_rgs_deleted = 0
|
|
520
|
-
num_rgs_to_delete = len(resource_groups_to_delete)
|
|
521
|
-
# Track number of resources deleted
|
|
522
|
-
num_resources_deleted = 0
|
|
523
|
-
num_resources_to_delete = 0
|
|
524
|
-
|
|
525
|
-
if num_rgs_to_delete == 0:
|
|
526
|
-
print_info("No resources to delete")
|
|
527
|
-
return
|
|
528
|
-
|
|
529
|
-
logger.debug(f"Deleting {num_rgs_to_delete} resource groups")
|
|
530
|
-
for rg in resource_groups_to_delete:
|
|
531
|
-
_num_resources_deleted, _num_resources_to_delete = rg.delete_resources(
|
|
532
|
-
group_filter=target_group,
|
|
533
|
-
name_filter=target_name,
|
|
534
|
-
type_filter=target_type,
|
|
535
|
-
dry_run=dry_run,
|
|
536
|
-
auto_confirm=auto_confirm,
|
|
537
|
-
force=force,
|
|
538
|
-
)
|
|
539
|
-
if _num_resources_deleted > 0:
|
|
540
|
-
num_rgs_deleted += 1
|
|
541
|
-
num_resources_deleted += _num_resources_deleted
|
|
542
|
-
num_resources_to_delete += _num_resources_to_delete
|
|
543
|
-
logger.debug(f"Deleted {num_resources_deleted} resources in {num_rgs_deleted} resource groups")
|
|
544
|
-
|
|
545
|
-
if dry_run:
|
|
546
|
-
return
|
|
547
|
-
|
|
548
|
-
if num_resources_deleted == 0:
|
|
549
|
-
return
|
|
550
|
-
|
|
551
|
-
print_heading(f"\n--**-- ResourceGroups deleted: {num_rgs_deleted}/{num_rgs_to_delete}\n")
|
|
552
|
-
|
|
553
|
-
workspace_event_status = "in_progress"
|
|
554
|
-
if num_resources_to_delete == num_resources_deleted:
|
|
555
|
-
workspace_event_status = "success"
|
|
556
|
-
else:
|
|
557
|
-
logger.error("Some resources failed to delete, please check logs")
|
|
558
|
-
workspace_event_status = "failed"
|
|
559
|
-
|
|
560
|
-
if (
|
|
561
|
-
agno_config.user is not None
|
|
562
|
-
and ws_config.ws_schema is not None
|
|
563
|
-
and ws_config.ws_schema.id_workspace is not None
|
|
564
|
-
):
|
|
565
|
-
# Log workspace stop event
|
|
566
|
-
log_workspace_event(
|
|
567
|
-
user=agno_config.user,
|
|
568
|
-
workspace_event=WorkspaceEvent(
|
|
569
|
-
id_workspace=ws_config.ws_schema.id_workspace,
|
|
570
|
-
event_type="stop",
|
|
571
|
-
event_status=workspace_event_status,
|
|
572
|
-
event_data={
|
|
573
|
-
"target_env": target_env,
|
|
574
|
-
"target_infra": target_infra,
|
|
575
|
-
"target_group": target_group,
|
|
576
|
-
"target_name": target_name,
|
|
577
|
-
"target_type": target_type,
|
|
578
|
-
"dry_run": dry_run,
|
|
579
|
-
"auto_confirm": auto_confirm,
|
|
580
|
-
"force": force,
|
|
581
|
-
},
|
|
582
|
-
),
|
|
583
|
-
)
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
def update_workspace(
|
|
587
|
-
agno_config: AgnoCliConfig,
|
|
588
|
-
ws_config: WorkspaceConfig,
|
|
589
|
-
target_env: Optional[str] = None,
|
|
590
|
-
target_infra: Optional[str] = None,
|
|
591
|
-
target_group: Optional[str] = None,
|
|
592
|
-
target_name: Optional[str] = None,
|
|
593
|
-
target_type: Optional[str] = None,
|
|
594
|
-
dry_run: Optional[bool] = False,
|
|
595
|
-
auto_confirm: Optional[bool] = False,
|
|
596
|
-
force: Optional[bool] = None,
|
|
597
|
-
pull: Optional[bool] = False,
|
|
598
|
-
) -> None:
|
|
599
|
-
"""Update an Agno Workspace. This is called from `ag ws patch`"""
|
|
600
|
-
if ws_config is None:
|
|
601
|
-
logger.error("WorkspaceConfig invalid")
|
|
602
|
-
return
|
|
603
|
-
|
|
604
|
-
print_heading("Updating workspace: {}".format(str(ws_config.ws_root_path.stem)))
|
|
605
|
-
logger.debug(f"\ttarget_env : {target_env}")
|
|
606
|
-
logger.debug(f"\ttarget_infra : {target_infra}")
|
|
607
|
-
logger.debug(f"\ttarget_group : {target_group}")
|
|
608
|
-
logger.debug(f"\ttarget_name : {target_name}")
|
|
609
|
-
logger.debug(f"\ttarget_type : {target_type}")
|
|
610
|
-
logger.debug(f"\tdry_run : {dry_run}")
|
|
611
|
-
logger.debug(f"\tauto_confirm : {auto_confirm}")
|
|
612
|
-
logger.debug(f"\tforce : {force}")
|
|
613
|
-
logger.debug(f"\tpull : {pull}")
|
|
614
|
-
|
|
615
|
-
# Set the local environment variables before processing configs
|
|
616
|
-
ws_config.set_local_env()
|
|
617
|
-
|
|
618
|
-
# Get resource groups to update
|
|
619
|
-
resource_groups_to_update: List[InfraResources] = ws_config.get_resources(
|
|
620
|
-
env=target_env,
|
|
621
|
-
infra=target_infra,
|
|
622
|
-
order="create",
|
|
623
|
-
)
|
|
624
|
-
# Track number of resource groups updated
|
|
625
|
-
num_rgs_updated = 0
|
|
626
|
-
num_rgs_to_update = len(resource_groups_to_update)
|
|
627
|
-
# Track number of resources updated
|
|
628
|
-
num_resources_updated = 0
|
|
629
|
-
num_resources_to_update = 0
|
|
630
|
-
|
|
631
|
-
if num_rgs_to_update == 0:
|
|
632
|
-
print_info("No resources to update")
|
|
633
|
-
return
|
|
634
|
-
|
|
635
|
-
logger.debug(f"Updating {num_rgs_to_update} resource groups")
|
|
636
|
-
for rg in resource_groups_to_update:
|
|
637
|
-
_num_resources_updated, _num_resources_to_update = rg.update_resources(
|
|
638
|
-
group_filter=target_group,
|
|
639
|
-
name_filter=target_name,
|
|
640
|
-
type_filter=target_type,
|
|
641
|
-
dry_run=dry_run,
|
|
642
|
-
auto_confirm=auto_confirm,
|
|
643
|
-
force=force,
|
|
644
|
-
pull=pull,
|
|
645
|
-
)
|
|
646
|
-
if _num_resources_updated > 0:
|
|
647
|
-
num_rgs_updated += 1
|
|
648
|
-
num_resources_updated += _num_resources_updated
|
|
649
|
-
num_resources_to_update += _num_resources_to_update
|
|
650
|
-
logger.debug(f"Updated {num_resources_updated} resources in {num_rgs_updated} resource groups")
|
|
651
|
-
|
|
652
|
-
if dry_run:
|
|
653
|
-
return
|
|
654
|
-
|
|
655
|
-
if num_resources_updated == 0:
|
|
656
|
-
return
|
|
657
|
-
|
|
658
|
-
print_heading(f"\n--**-- ResourceGroups updated: {num_rgs_updated}/{num_rgs_to_update}\n")
|
|
659
|
-
|
|
660
|
-
workspace_event_status = "in_progress"
|
|
661
|
-
if num_resources_updated == num_resources_to_update:
|
|
662
|
-
workspace_event_status = "success"
|
|
663
|
-
else:
|
|
664
|
-
logger.error("Some resources failed to update, please check logs")
|
|
665
|
-
workspace_event_status = "failed"
|
|
666
|
-
|
|
667
|
-
if (
|
|
668
|
-
agno_config.user is not None
|
|
669
|
-
and ws_config.ws_schema is not None
|
|
670
|
-
and ws_config.ws_schema.id_workspace is not None
|
|
671
|
-
):
|
|
672
|
-
# Log workspace start event
|
|
673
|
-
log_workspace_event(
|
|
674
|
-
user=agno_config.user,
|
|
675
|
-
workspace_event=WorkspaceEvent(
|
|
676
|
-
id_workspace=ws_config.ws_schema.id_workspace,
|
|
677
|
-
event_type="update",
|
|
678
|
-
event_status=workspace_event_status,
|
|
679
|
-
event_data={
|
|
680
|
-
"target_env": target_env,
|
|
681
|
-
"target_infra": target_infra,
|
|
682
|
-
"target_group": target_group,
|
|
683
|
-
"target_name": target_name,
|
|
684
|
-
"target_type": target_type,
|
|
685
|
-
"dry_run": dry_run,
|
|
686
|
-
"auto_confirm": auto_confirm,
|
|
687
|
-
"force": force,
|
|
688
|
-
},
|
|
689
|
-
),
|
|
690
|
-
)
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
def delete_workspace(agno_config: AgnoCliConfig, ws_to_delete: Optional[List[Path]]) -> None:
|
|
694
|
-
if ws_to_delete is None or len(ws_to_delete) == 0:
|
|
695
|
-
print_heading("No workspaces to delete")
|
|
696
|
-
return
|
|
697
|
-
|
|
698
|
-
for ws_root in ws_to_delete:
|
|
699
|
-
agno_config.delete_ws(ws_root_path=ws_root)
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
def set_workspace_as_active(ws_dir_name: Optional[str]) -> None:
|
|
703
|
-
from agno.cli.operator import initialize_agno
|
|
704
|
-
|
|
705
|
-
######################################################
|
|
706
|
-
## 1. Validate Pre-requisites
|
|
707
|
-
######################################################
|
|
708
|
-
######################################################
|
|
709
|
-
# 1.1 Check AgnoCliConfig is valid
|
|
710
|
-
######################################################
|
|
711
|
-
agno_config: Optional[AgnoCliConfig] = AgnoCliConfig.from_saved_config()
|
|
712
|
-
if not agno_config:
|
|
713
|
-
agno_config = initialize_agno()
|
|
714
|
-
if not agno_config:
|
|
715
|
-
log_config_not_available_msg()
|
|
716
|
-
return
|
|
717
|
-
|
|
718
|
-
######################################################
|
|
719
|
-
# 1.2 Check ws_root_path is valid
|
|
720
|
-
######################################################
|
|
721
|
-
# By default, we assume this command is run from the workspace directory
|
|
722
|
-
ws_root_path: Optional[Path] = None
|
|
723
|
-
if ws_dir_name is None:
|
|
724
|
-
# If the user does not provide a ws_name, that implies `ag set` is ran from
|
|
725
|
-
# the workspace directory.
|
|
726
|
-
ws_root_path = Path(".").resolve()
|
|
727
|
-
else:
|
|
728
|
-
# If the user provides a workspace name manually, we find the dir for that ws
|
|
729
|
-
ws_config: Optional[WorkspaceConfig] = agno_config.get_ws_config_by_dir_name(ws_dir_name)
|
|
730
|
-
if ws_config is None:
|
|
731
|
-
logger.error(f"Could not find workspace {ws_dir_name}")
|
|
732
|
-
return
|
|
733
|
-
ws_root_path = ws_config.ws_root_path
|
|
734
|
-
|
|
735
|
-
ws_dir_is_valid: bool = ws_root_path is not None and ws_root_path.exists() and ws_root_path.is_dir()
|
|
736
|
-
if not ws_dir_is_valid:
|
|
737
|
-
logger.error("Invalid workspace directory: {}".format(ws_root_path))
|
|
738
|
-
return
|
|
739
|
-
|
|
740
|
-
######################################################
|
|
741
|
-
# 1.3 Validate WorkspaceConfig is available i.e. a workspace is available at this directory
|
|
742
|
-
######################################################
|
|
743
|
-
logger.debug(f"Checking for a workspace at path: {ws_root_path}")
|
|
744
|
-
active_ws_config: Optional[WorkspaceConfig] = agno_config.get_ws_config_by_path(ws_root_path)
|
|
745
|
-
if active_ws_config is None:
|
|
746
|
-
# This happens when the workspace is not yet setup
|
|
747
|
-
print_info(f"Could not find a workspace at path: {ws_root_path}")
|
|
748
|
-
# TODO: setup automatically for the user
|
|
749
|
-
print_info("If this workspace has not been setup, please run `ag ws setup` from the workspace directory")
|
|
750
|
-
return
|
|
751
|
-
|
|
752
|
-
######################################################
|
|
753
|
-
## 2. Set workspace as active
|
|
754
|
-
######################################################
|
|
755
|
-
print_heading(f"Setting workspace {active_ws_config.ws_root_path.stem} as active")
|
|
756
|
-
agno_config.set_active_ws_dir(active_ws_config.ws_root_path)
|
|
757
|
-
print_info("Active workspace updated")
|
|
758
|
-
return
|