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/tools/daytona.py
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from os import getenv
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from textwrap import dedent
|
|
5
|
+
from typing import Any, Dict, List, Optional, Union
|
|
6
|
+
|
|
7
|
+
from agno.agent import Agent
|
|
8
|
+
from agno.team import Team
|
|
9
|
+
from agno.tools import Toolkit
|
|
10
|
+
from agno.utils.code_execution import prepare_python_code
|
|
11
|
+
from agno.utils.log import log_debug, log_error, log_info, log_warning
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from daytona import (
|
|
15
|
+
CodeLanguage,
|
|
16
|
+
CreateSandboxFromSnapshotParams,
|
|
17
|
+
Daytona,
|
|
18
|
+
DaytonaConfig,
|
|
19
|
+
Sandbox,
|
|
20
|
+
)
|
|
21
|
+
except ImportError:
|
|
22
|
+
raise ImportError("`daytona` not installed. Please install using `pip install daytona`")
|
|
23
|
+
|
|
24
|
+
DEFAULT_INSTRUCTIONS = dedent(
|
|
25
|
+
"""\
|
|
26
|
+
You have access to a persistent Daytona sandbox for code execution. The sandbox maintains state across interactions.
|
|
27
|
+
Available tools:
|
|
28
|
+
- `run_code`: Execute code in the sandbox
|
|
29
|
+
- `run_shell_command`: Execute shell commands (bash)
|
|
30
|
+
- `create_file`: Create or update files
|
|
31
|
+
- `read_file`: Read file contents
|
|
32
|
+
- `list_files`: List directory contents
|
|
33
|
+
- `delete_file`: Delete files or directories
|
|
34
|
+
- `change_directory`: Change the working directory
|
|
35
|
+
MANDATORY: When users ask for code (Python, JavaScript, TypeScript, etc.), you MUST:
|
|
36
|
+
1. Write the code
|
|
37
|
+
2. Execute it using run_code tool
|
|
38
|
+
3. Show the actual output/results
|
|
39
|
+
4. Never just provide code without executing it
|
|
40
|
+
CRITICAL WORKFLOW:
|
|
41
|
+
1. Before running Python scripts, check if required packages are installed
|
|
42
|
+
2. Install missing packages with: run_shell_command("pip install package1 package2")
|
|
43
|
+
3. When running scripts, capture both output AND errors
|
|
44
|
+
4. If a script produces no output, check for errors or add print statements
|
|
45
|
+
|
|
46
|
+
IMPORTANT: Always use single quotes for the content parameter when creating files
|
|
47
|
+
|
|
48
|
+
Remember: Your job is to provide working, executed code examples, not just code snippets!
|
|
49
|
+
"""
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class DaytonaTools(Toolkit):
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
api_key: Optional[str] = None,
|
|
57
|
+
api_url: Optional[str] = None,
|
|
58
|
+
sandbox_id: Optional[str] = None,
|
|
59
|
+
sandbox_language: Optional[CodeLanguage] = None,
|
|
60
|
+
sandbox_target: Optional[str] = None,
|
|
61
|
+
sandbox_os: Optional[str] = None,
|
|
62
|
+
auto_stop_interval: Optional[int] = 60, # Stop after 1 hour
|
|
63
|
+
sandbox_os_user: Optional[str] = None,
|
|
64
|
+
sandbox_env_vars: Optional[Dict[str, str]] = None,
|
|
65
|
+
sandbox_labels: Optional[Dict[str, str]] = None,
|
|
66
|
+
sandbox_public: Optional[bool] = None,
|
|
67
|
+
organization_id: Optional[str] = None,
|
|
68
|
+
timeout: int = 300,
|
|
69
|
+
auto_create_sandbox: bool = True,
|
|
70
|
+
verify_ssl: Optional[bool] = False,
|
|
71
|
+
persistent: bool = True,
|
|
72
|
+
instructions: Optional[str] = None,
|
|
73
|
+
add_instructions: bool = False,
|
|
74
|
+
**kwargs,
|
|
75
|
+
):
|
|
76
|
+
self.api_key = api_key or getenv("DAYTONA_API_KEY")
|
|
77
|
+
if not self.api_key:
|
|
78
|
+
raise ValueError("DAYTONA_API_KEY not set. Please set the DAYTONA_API_KEY environment variable.")
|
|
79
|
+
|
|
80
|
+
self.api_url = api_url or getenv("DAYTONA_API_URL")
|
|
81
|
+
self.sandbox_id = sandbox_id
|
|
82
|
+
self.sandbox_target = sandbox_target
|
|
83
|
+
self.organization_id = organization_id
|
|
84
|
+
self.sandbox_language = sandbox_language or CodeLanguage.PYTHON
|
|
85
|
+
self.sandbox_os = sandbox_os
|
|
86
|
+
self.auto_stop_interval = auto_stop_interval
|
|
87
|
+
self.sandbox_os_user = sandbox_os_user
|
|
88
|
+
self.sandbox_env_vars = sandbox_env_vars
|
|
89
|
+
self.sandbox_labels = sandbox_labels or {}
|
|
90
|
+
self.sandbox_public = sandbox_public
|
|
91
|
+
self.timeout = timeout
|
|
92
|
+
self.auto_create_sandbox = auto_create_sandbox
|
|
93
|
+
self.persistent = persistent
|
|
94
|
+
self.verify_ssl = verify_ssl
|
|
95
|
+
|
|
96
|
+
# Set instructions - use default if none provided
|
|
97
|
+
self.instructions = instructions or DEFAULT_INSTRUCTIONS
|
|
98
|
+
|
|
99
|
+
if not self.verify_ssl:
|
|
100
|
+
self._disable_ssl_verification()
|
|
101
|
+
|
|
102
|
+
self.config = DaytonaConfig(
|
|
103
|
+
api_key=self.api_key,
|
|
104
|
+
api_url=self.api_url,
|
|
105
|
+
target=self.sandbox_target,
|
|
106
|
+
organization_id=self.organization_id,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
self.daytona = Daytona(self.config)
|
|
110
|
+
tools: List[Any] = [
|
|
111
|
+
self.run_code,
|
|
112
|
+
self.run_shell_command,
|
|
113
|
+
self.create_file,
|
|
114
|
+
self.read_file,
|
|
115
|
+
self.list_files,
|
|
116
|
+
self.delete_file,
|
|
117
|
+
self.change_directory,
|
|
118
|
+
]
|
|
119
|
+
super().__init__(
|
|
120
|
+
name="daytona_tools",
|
|
121
|
+
tools=tools,
|
|
122
|
+
instructions=self.instructions,
|
|
123
|
+
add_instructions=add_instructions,
|
|
124
|
+
**kwargs,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def _disable_ssl_verification(self) -> None:
|
|
128
|
+
try:
|
|
129
|
+
from daytona_api_client import Configuration
|
|
130
|
+
|
|
131
|
+
original_init = Configuration.__init__
|
|
132
|
+
|
|
133
|
+
# Create a wrapper that sets verify_ssl = False
|
|
134
|
+
def patched_init(self, *args, **kwargs):
|
|
135
|
+
original_init(self, *args, **kwargs)
|
|
136
|
+
self.verify_ssl = False
|
|
137
|
+
|
|
138
|
+
setattr(Configuration, "__init__", patched_init)
|
|
139
|
+
import urllib3
|
|
140
|
+
|
|
141
|
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
142
|
+
log_debug(
|
|
143
|
+
"SSL certificate verification is disabled",
|
|
144
|
+
)
|
|
145
|
+
except ImportError:
|
|
146
|
+
log_warning("Could not import daytona_api_client.Configuration for SSL patching")
|
|
147
|
+
|
|
148
|
+
def _get_working_directory(self, agent: Union[Agent, Team]) -> str:
|
|
149
|
+
"""Get the current working directory from agent session state."""
|
|
150
|
+
if agent and hasattr(agent, "session_state"):
|
|
151
|
+
if agent.session_state is None:
|
|
152
|
+
agent.session_state = {}
|
|
153
|
+
return agent.session_state.get("working_directory", "/home/daytona")
|
|
154
|
+
return "/home/daytona"
|
|
155
|
+
|
|
156
|
+
def _set_working_directory(self, agent: Union[Agent, Team], directory: str) -> None:
|
|
157
|
+
"""Set the working directory in agent session state."""
|
|
158
|
+
if agent and hasattr(agent, "session_state"):
|
|
159
|
+
if agent.session_state is None:
|
|
160
|
+
agent.session_state = {}
|
|
161
|
+
agent.session_state["working_directory"] = directory
|
|
162
|
+
log_info(f"Updated working directory to: {directory}")
|
|
163
|
+
|
|
164
|
+
def _get_or_create_sandbox(self, agent: Union[Agent, Team]) -> Sandbox:
|
|
165
|
+
"""Get existing sandbox or create new one"""
|
|
166
|
+
try:
|
|
167
|
+
sandbox = None
|
|
168
|
+
|
|
169
|
+
# Use explicit sandbox
|
|
170
|
+
if self.sandbox_id:
|
|
171
|
+
try:
|
|
172
|
+
sandbox = self.daytona.get(self.sandbox_id)
|
|
173
|
+
log_debug(f"Using explicit sandbox: {self.sandbox_id}")
|
|
174
|
+
except Exception as e:
|
|
175
|
+
log_debug(f"Failed to get sandbox {self.sandbox_id}: {e}")
|
|
176
|
+
sandbox = None
|
|
177
|
+
|
|
178
|
+
# Use persistent sandbox
|
|
179
|
+
elif self.persistent and hasattr(agent, "session_state"):
|
|
180
|
+
if agent.session_state is None:
|
|
181
|
+
agent.session_state = {}
|
|
182
|
+
|
|
183
|
+
sandbox_id = agent.session_state.get("sandbox_id")
|
|
184
|
+
if sandbox_id:
|
|
185
|
+
try:
|
|
186
|
+
sandbox = self.daytona.get(sandbox_id)
|
|
187
|
+
log_debug(f"Using persistent sandbox: {sandbox_id}")
|
|
188
|
+
except Exception as e:
|
|
189
|
+
log_debug(f"Failed to get sandbox {sandbox_id}: {e}")
|
|
190
|
+
sandbox = None
|
|
191
|
+
|
|
192
|
+
# Create new sandbox if none found
|
|
193
|
+
if sandbox is None:
|
|
194
|
+
sandbox = self._create_new_sandbox(agent)
|
|
195
|
+
# Store sandbox ID for persistent sandboxes
|
|
196
|
+
if self.persistent and hasattr(agent, "session_state"):
|
|
197
|
+
if agent.session_state is None:
|
|
198
|
+
agent.session_state = {}
|
|
199
|
+
agent.session_state["sandbox_id"] = sandbox.id
|
|
200
|
+
|
|
201
|
+
# Ensure sandbox is started
|
|
202
|
+
if sandbox.state != "started":
|
|
203
|
+
log_info(f"Starting sandbox {sandbox.id}")
|
|
204
|
+
self.daytona.start(sandbox, timeout=self.timeout)
|
|
205
|
+
|
|
206
|
+
return sandbox
|
|
207
|
+
except Exception as e:
|
|
208
|
+
if self.auto_create_sandbox:
|
|
209
|
+
log_warning(f"Error in sandbox management: {e}. Creating new sandbox.")
|
|
210
|
+
return self._create_new_sandbox(agent)
|
|
211
|
+
else:
|
|
212
|
+
raise e
|
|
213
|
+
|
|
214
|
+
def _create_new_sandbox(self, agent: Optional[Union[Agent, Team]] = None) -> Sandbox:
|
|
215
|
+
"""Create a new sandbox with the configured parameters."""
|
|
216
|
+
try:
|
|
217
|
+
labels = self.sandbox_labels.copy()
|
|
218
|
+
labels.setdefault("created_by", "agno_daytona_toolkit")
|
|
219
|
+
labels.setdefault("language", str(self.sandbox_language))
|
|
220
|
+
|
|
221
|
+
if self.persistent:
|
|
222
|
+
labels.setdefault("persistent", "true")
|
|
223
|
+
|
|
224
|
+
params = CreateSandboxFromSnapshotParams(
|
|
225
|
+
language=self.sandbox_language,
|
|
226
|
+
os_user=self.sandbox_os_user,
|
|
227
|
+
env_vars=self.sandbox_env_vars,
|
|
228
|
+
auto_stop_interval=self.auto_stop_interval,
|
|
229
|
+
labels=labels,
|
|
230
|
+
public=self.sandbox_public,
|
|
231
|
+
)
|
|
232
|
+
sandbox = self.daytona.create(params, timeout=self.timeout)
|
|
233
|
+
|
|
234
|
+
# Add the sandbox_id to the Agent state
|
|
235
|
+
if self.persistent and agent and hasattr(agent, "session_state"):
|
|
236
|
+
if agent.session_state is None:
|
|
237
|
+
agent.session_state = {}
|
|
238
|
+
agent.session_state["sandbox_id"] = sandbox.id
|
|
239
|
+
|
|
240
|
+
log_info(f"Created new Daytona sandbox: {sandbox.id}")
|
|
241
|
+
return sandbox
|
|
242
|
+
except Exception as e:
|
|
243
|
+
log_error(f"Error creating Daytona sandbox: {e}")
|
|
244
|
+
raise e
|
|
245
|
+
|
|
246
|
+
# Tools
|
|
247
|
+
def run_code(self, agent: Union[Agent, Team], code: str) -> str:
|
|
248
|
+
"""Execute Python code in the Daytona sandbox.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
code: Code to execute
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Execution output as a string
|
|
255
|
+
"""
|
|
256
|
+
try:
|
|
257
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
258
|
+
|
|
259
|
+
if self.sandbox_language == CodeLanguage.PYTHON:
|
|
260
|
+
code = prepare_python_code(code)
|
|
261
|
+
|
|
262
|
+
response = current_sandbox.process.code_run(code)
|
|
263
|
+
|
|
264
|
+
self.result = response.result
|
|
265
|
+
return self.result
|
|
266
|
+
except Exception as e:
|
|
267
|
+
return json.dumps({"status": "error", "message": f"Error executing code: {str(e)}"})
|
|
268
|
+
|
|
269
|
+
def run_shell_command(self, agent: Union[Agent, Team], command: str) -> str:
|
|
270
|
+
"""Execute a shell command in the sandbox.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
command: Shell command to execute
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
Command output as a string
|
|
277
|
+
"""
|
|
278
|
+
try:
|
|
279
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
280
|
+
|
|
281
|
+
# Use persistent working directory if not specified
|
|
282
|
+
cwd = self._get_working_directory(agent)
|
|
283
|
+
|
|
284
|
+
# Handle cd commands specially to update working directory
|
|
285
|
+
if command.strip().startswith("cd "):
|
|
286
|
+
new_dir = command.strip()[3:].strip()
|
|
287
|
+
# Convert to Path
|
|
288
|
+
new_path = Path(new_dir)
|
|
289
|
+
|
|
290
|
+
# Resolve relative paths
|
|
291
|
+
if not new_path.is_absolute():
|
|
292
|
+
# Get current absolute path first
|
|
293
|
+
result = current_sandbox.process.exec(f"cd {cwd} && pwd", cwd="/")
|
|
294
|
+
current_abs_path = Path(result.result.strip())
|
|
295
|
+
new_path = current_abs_path / new_path
|
|
296
|
+
|
|
297
|
+
# Normalize the path
|
|
298
|
+
new_path_str = str(new_path.resolve())
|
|
299
|
+
|
|
300
|
+
# Test if directory exists
|
|
301
|
+
test_result = current_sandbox.process.exec(
|
|
302
|
+
f"test -d {new_path_str} && echo 'exists' || echo 'not found'", cwd="/"
|
|
303
|
+
)
|
|
304
|
+
if "exists" in test_result.result:
|
|
305
|
+
self._set_working_directory(agent, new_path_str)
|
|
306
|
+
return f"Changed directory to: {new_path_str}"
|
|
307
|
+
else:
|
|
308
|
+
return f"Error: Directory {new_path_str} not found"
|
|
309
|
+
|
|
310
|
+
# Execute the command
|
|
311
|
+
response = current_sandbox.process.exec(command, cwd=cwd)
|
|
312
|
+
return response.result
|
|
313
|
+
except Exception as e:
|
|
314
|
+
return json.dumps({"status": "error", "message": f"Error executing command: {str(e)}"})
|
|
315
|
+
|
|
316
|
+
def create_file(self, agent: Union[Agent, Team], file_path: str, content: str) -> str:
|
|
317
|
+
"""Create or update a file in the sandbox.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
file_path: Path to the file (relative to current directory or absolute)
|
|
321
|
+
content: Content to write to the file
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
Success message or error
|
|
325
|
+
"""
|
|
326
|
+
try:
|
|
327
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
328
|
+
|
|
329
|
+
# Convert to Path object
|
|
330
|
+
path = Path(file_path)
|
|
331
|
+
|
|
332
|
+
# Handle relative paths
|
|
333
|
+
if not path.is_absolute():
|
|
334
|
+
path = Path(self._get_working_directory(agent)) / path
|
|
335
|
+
|
|
336
|
+
# Ensure the path is normalized
|
|
337
|
+
path_str = str(path)
|
|
338
|
+
|
|
339
|
+
# Create directory if needed
|
|
340
|
+
parent_dir = str(path.parent)
|
|
341
|
+
if parent_dir and parent_dir != "/":
|
|
342
|
+
result = current_sandbox.process.exec(f"mkdir -p {parent_dir}")
|
|
343
|
+
if result.exit_code != 0:
|
|
344
|
+
return json.dumps({"status": "error", "message": f"Failed to create directory: {result.result}"})
|
|
345
|
+
|
|
346
|
+
# Write the file using shell command
|
|
347
|
+
# Use cat with heredoc for better handling of special characters
|
|
348
|
+
escaped_content = content.replace("'", "'\"'\"'")
|
|
349
|
+
command = f"cat > '{path_str}' << 'EOF'\n{escaped_content}\nEOF"
|
|
350
|
+
result = current_sandbox.process.exec(command)
|
|
351
|
+
|
|
352
|
+
if result.exit_code != 0:
|
|
353
|
+
return json.dumps({"status": "error", "message": f"Failed to create file: {result.result}"})
|
|
354
|
+
|
|
355
|
+
return f"File created/updated: {path_str}"
|
|
356
|
+
except Exception as e:
|
|
357
|
+
return json.dumps({"status": "error", "message": f"Error creating file: {str(e)}"})
|
|
358
|
+
|
|
359
|
+
def read_file(self, agent: Union[Agent, Team], file_path: str) -> str:
|
|
360
|
+
"""Read a file from the sandbox.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
file_path: Path to the file (relative to current directory or absolute)
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
File content or error message
|
|
367
|
+
"""
|
|
368
|
+
try:
|
|
369
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
370
|
+
|
|
371
|
+
# Convert to Path object
|
|
372
|
+
path = Path(file_path)
|
|
373
|
+
|
|
374
|
+
# Handle relative paths
|
|
375
|
+
if not path.is_absolute():
|
|
376
|
+
path = Path(self._get_working_directory(agent)) / path
|
|
377
|
+
|
|
378
|
+
path_str = str(path)
|
|
379
|
+
|
|
380
|
+
# Read file using cat
|
|
381
|
+
result = current_sandbox.process.exec(f"cat '{path_str}'")
|
|
382
|
+
|
|
383
|
+
if result.exit_code != 0:
|
|
384
|
+
return json.dumps({"status": "error", "message": f"Error reading file: {result.result}"})
|
|
385
|
+
|
|
386
|
+
return result.result
|
|
387
|
+
except Exception as e:
|
|
388
|
+
return json.dumps({"status": "error", "message": f"Error reading file: {str(e)}"})
|
|
389
|
+
|
|
390
|
+
def list_files(self, agent: Union[Agent, Team], directory: Optional[str] = None) -> str:
|
|
391
|
+
"""List files in a directory.
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
directory: Directory to list (defaults to current working directory)
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
List of files and directories as formatted string
|
|
398
|
+
"""
|
|
399
|
+
try:
|
|
400
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
401
|
+
|
|
402
|
+
# Use current directory if not specified
|
|
403
|
+
if directory is None:
|
|
404
|
+
dir_path = Path(self._get_working_directory(agent))
|
|
405
|
+
else:
|
|
406
|
+
dir_path = Path(directory)
|
|
407
|
+
# Handle relative paths
|
|
408
|
+
if not dir_path.is_absolute():
|
|
409
|
+
dir_path = Path(self._get_working_directory(agent)) / dir_path
|
|
410
|
+
|
|
411
|
+
path_str = str(dir_path)
|
|
412
|
+
|
|
413
|
+
# List files using ls -la for detailed info
|
|
414
|
+
result = current_sandbox.process.exec(f"ls -la '{path_str}'")
|
|
415
|
+
|
|
416
|
+
if result.exit_code != 0:
|
|
417
|
+
return json.dumps({"status": "error", "message": f"Error listing directory: {result.result}"})
|
|
418
|
+
|
|
419
|
+
return f"Contents of {path_str}:\n{result.result}"
|
|
420
|
+
except Exception as e:
|
|
421
|
+
return json.dumps({"status": "error", "message": f"Error listing files: {str(e)}"})
|
|
422
|
+
|
|
423
|
+
def delete_file(self, agent: Union[Agent, Team], file_path: str) -> str:
|
|
424
|
+
"""Delete a file or directory from the sandbox.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
file_path: Path to the file or directory (relative to current directory or absolute)
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Success message or error
|
|
431
|
+
"""
|
|
432
|
+
try:
|
|
433
|
+
current_sandbox = self._get_or_create_sandbox(agent)
|
|
434
|
+
|
|
435
|
+
# Convert to Path object
|
|
436
|
+
path = Path(file_path)
|
|
437
|
+
|
|
438
|
+
# Handle relative paths
|
|
439
|
+
if not path.is_absolute():
|
|
440
|
+
path = Path(self._get_working_directory(agent)) / path
|
|
441
|
+
|
|
442
|
+
path_str = str(path)
|
|
443
|
+
|
|
444
|
+
# Check if it's a directory or file
|
|
445
|
+
check_result = current_sandbox.process.exec(f"test -d '{path_str}' && echo 'directory' || echo 'file'")
|
|
446
|
+
|
|
447
|
+
if "directory" in check_result.result:
|
|
448
|
+
# Remove directory recursively
|
|
449
|
+
result = current_sandbox.process.exec(f"rm -rf '{path_str}'")
|
|
450
|
+
else:
|
|
451
|
+
# Remove file
|
|
452
|
+
result = current_sandbox.process.exec(f"rm -f '{path_str}'")
|
|
453
|
+
|
|
454
|
+
if result.exit_code != 0:
|
|
455
|
+
return json.dumps({"status": "error", "message": f"Failed to delete: {result.result}"})
|
|
456
|
+
|
|
457
|
+
return f"Deleted: {path_str}"
|
|
458
|
+
except Exception as e:
|
|
459
|
+
return json.dumps({"status": "error", "message": f"Error deleting file: {str(e)}"})
|
|
460
|
+
|
|
461
|
+
def change_directory(self, agent: Union[Agent, Team], directory: str) -> str:
|
|
462
|
+
"""Change the current working directory.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
directory: Directory to change to (relative to current directory or absolute)
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
Success message or error
|
|
469
|
+
"""
|
|
470
|
+
try:
|
|
471
|
+
result = self.run_shell_command(agent, f"cd {directory}")
|
|
472
|
+
self._set_working_directory(agent, directory)
|
|
473
|
+
return result
|
|
474
|
+
except Exception as e:
|
|
475
|
+
return json.dumps({"status": "error", "message": f"Error changing directory: {str(e)}"})
|