From 7c5bf1c6376efaa0f1f3393cd7e0972df2e73e1f Mon Sep 17 00:00:00 2001 From: Mislav Ivanda Date: Tue, 14 Jul 2026 17:02:49 +0200 Subject: [PATCH 1/3] docs(dify-plugin): document the full tool set added by the port The plugin registers 17 tools but the README/metadata only described the original 7. Document the 10 added tools (list_sandboxes, manage_sandbox, git_clone, read_file, write_file, list_files, search_files, find_in_files, start_service, get_service_logs): - README: add them to Features and the Tool Reference table, plus usage sections for git, services/preview, files, and sandbox management - manifest.yaml + provider: broaden the plugin description beyond 'run code and commands' - PRIVACY.md: cover Write/Read File transfers and Git Clone credential handling Signed-off-by: Mislav Ivanda --- apps/dify-plugin/PRIVACY.md | 3 +- apps/dify-plugin/README.md | 44 +++++++++++++++++++++++--- apps/dify-plugin/manifest.yaml | 8 ++--- apps/dify-plugin/provider/daytona.yaml | 8 ++--- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/apps/dify-plugin/PRIVACY.md b/apps/dify-plugin/PRIVACY.md index 2c934e1..7ff8d25 100644 --- a/apps/dify-plugin/PRIVACY.md +++ b/apps/dify-plugin/PRIVACY.md @@ -6,7 +6,8 @@ This plugin connects to the Daytona API to create and manage sandbox environment - **API Key**: Your Daytona API key is stored by Dify and sent to the Daytona API for authentication. It is never shared with third parties. - **Code and Commands**: Code snippets and shell commands you submit are sent to the Daytona API for execution inside isolated sandboxes. Daytona does not use your code to train models or improve services. -- **File Contents**: Files you upload to a sandbox via the Upload File tool are transmitted through the plugin to the Daytona API and stored inside the sandbox. Files you retrieve via the Download File tool are transferred from the sandbox through the plugin back into Dify. The plugin itself does not retain any file contents; storage is managed by Daytona for the lifetime of the sandbox. +- **File Contents**: Files and text you send to a sandbox (via the Upload File or Write File tools) are transmitted through the plugin to the Daytona API and stored inside the sandbox. Files and text you retrieve (via the Download File or Read File tools) are transferred from the sandbox through the plugin back into Dify. The plugin itself does not retain any file contents; storage is managed by Daytona for the lifetime of the sandbox. +- **Git Credentials**: When you clone a private repository via the Git Clone tool, any username and password/token you provide are sent through the plugin to the Daytona API to authenticate the clone. They are not retained or logged by the plugin and are redacted from the tool's output. - **Sandbox Identifiers**: Sandbox IDs returned by the Daytona API are surfaced in Dify so subsequent tool calls can target the same sandbox. - **Execution Output**: stdout, stderr, and exit codes from code and commands you run are returned by the Daytona API and surfaced in Dify. diff --git a/apps/dify-plugin/README.md b/apps/dify-plugin/README.md index e8283fb..6f56978 100644 --- a/apps/dify-plugin/README.md +++ b/apps/dify-plugin/README.md @@ -2,17 +2,27 @@ ### Description -Dify plugin for [Daytona](https://www.daytona.io/), secure sandbox infrastructure for AI agents. Create isolated sandboxes, run code, execute shell commands, and manage their lifecycle directly from Dify workflows and agents. +Dify plugin for [Daytona](https://www.daytona.io/), secure sandbox infrastructure for AI agents. Create isolated sandboxes, run code and shell commands, manage files, clone Git repositories, run background services, and manage the full sandbox lifecycle directly from Dify workflows and agents. ### Features - **Create Sandbox**. Provision an isolated sandbox from a Daytona snapshot or a custom Docker image, with optional resource limits, environment variables, and a chosen language runtime. -- **Run Code**. Execute a Python, TypeScript, or JavaScript snippet in a sandbox. For larger or multi-file scripts, upload them with **Upload File** and run them via **Run Command**. +- **List Sandboxes**. List existing sandboxes with their IDs and states. +- **Manage Sandbox**. Start, stop, or archive an existing sandbox. +- **Destroy Sandbox**. Stop and delete a sandbox when it is no longer needed. +- **Run Code**. Execute a Python, TypeScript, or JavaScript snippet in a sandbox; any charts it generates (e.g. matplotlib) are returned as images. - **Run Command**. Run a shell command in a sandbox and get back its combined output (stdout and stderr) and exit code, with optional working directory and environment variables. +- **Git Clone**. Clone a Git repository into a sandbox, with an optional branch or commit and credentials for private repositories. - **Upload File**. Upload a file from Dify into a sandbox (e.g. a CSV to analyze, a script to run). - **Download File**. Download a file from a sandbox back into Dify (e.g. a generated chart, processed data). +- **Read File**. Read a text file's contents from a sandbox. +- **Write File**. Write text content to a file in a sandbox. +- **List Files**. List the contents of a directory in a sandbox. +- **Search Files**. Find files by name pattern in a sandbox. +- **Find in Files**. Search file contents for a text pattern across a sandbox (like grep). +- **Start Service**. Start a long-running background process (web server, daemon) in a sandbox. +- **Get Service Logs**. Retrieve output from a background service started with **Start Service**. - **Get Preview URL**. Get the public URL that exposes a port from inside a sandbox so users can open a running web app, dashboard, or API in their browser. -- **Destroy Sandbox**. Stop and delete a sandbox when it is no longer needed. ### Setup @@ -30,6 +40,22 @@ Use **Create Sandbox** to provision a new environment. The contents of the sandb If you don't pass a `sandbox_id` to **Run Code** or **Run Command**, a temporary ephemeral sandbox is created automatically using the Daytona default snapshot, used for the execution, and destroyed afterward. +#### Work with a Git repository + +Use **Git Clone** to pull a repository into a sandbox, then **Run Command** or **Run Code** to build and run it. Private repositories can be cloned by supplying a username and a password/token. + +#### Run and preview a web service + +Use **Start Service** to launch a long-running server (bind it to `0.0.0.0` so it is reachable), **Get Preview URL** to obtain a public HTTPS URL for its port, and **Get Service Logs** to inspect its output. + +#### Inspect and edit files + +Use **List Files**, **Read File**, **Write File**, **Search Files**, and **Find in Files** to explore and modify a sandbox's filesystem, or **Upload File** / **Download File** to move files between Dify and the sandbox. + +#### Manage sandboxes + +Use **List Sandboxes** to see what exists, and **Manage Sandbox** to start, stop, or archive one (archiving preserves a stopped sandbox's filesystem in cold storage). + #### Cleanup Use **Destroy Sandbox** to permanently delete a sandbox you provisioned with **Create Sandbox**. Ephemeral sandboxes created by **Run Code** and **Run Command** are cleaned up automatically. @@ -39,12 +65,22 @@ Use **Destroy Sandbox** to permanently delete a sandbox you provisioned with **C | Tool | Inputs | Returns | |------|--------|---------| | `create_sandbox` | `name`, `snapshot`, `image`, `language`, `env_vars` (JSON string), `cpu`, `memory`, `disk`, `auto_stop_interval` (all optional) | `sandbox_id` | +| `list_sandboxes` | `limit` (optional, default 50) | `sandboxes` (list of `{id, name, state}`), `count` | +| `manage_sandbox` | `sandbox_id`, `action` (`start`/`stop`/`archive`) (both required) | `success`, `sandbox_id`, `action`, `state` | +| `destroy_sandbox` | `sandbox_id` (required) | `success`, `sandbox_id` | | `run_code` | `code` (required), `language` (optional: `python`/`typescript`/`javascript`, default `python`, only used when creating an ephemeral sandbox), `sandbox_id` (optional, ephemeral if omitted) | `exit_code`, `output` (combined stdout+stderr), `sandbox_id`, `charts_count`, `charts` (list of `{type, title}`); any generated charts (e.g. matplotlib) are also emitted as PNG image blobs | | `run_command` | `command` (required), `cwd` (optional), `env_vars` (JSON string, optional), `timeout` (optional, seconds; empty = Daytona default, `0` = no timeout), `sandbox_id` (optional, ephemeral if omitted) | `exit_code`, `output` (combined stdout+stderr), `sandbox_id` | +| `git_clone` | `sandbox_id`, `url`, `path` (all required), `branch`, `commit_id`, `username`, `password` (all optional) | `success`, `sandbox_id`, `url` (credentials redacted), `path`, `branch`, `commit_id` | | `upload_file` | `sandbox_id`, `file` (Dify file picker), `remote_path` (all required) | `success`, `sandbox_id`, `remote_path`, `size_bytes` | | `download_file` | `sandbox_id`, `remote_path` (both required) | File as Dify blob plus `success`, `sandbox_id`, `remote_path`, `size_bytes`, `mime_type`, `filename` | +| `read_file` | `sandbox_id`, `remote_path` (both required) | File contents as text plus `success`, `sandbox_id`, `remote_path`, `size_bytes` (max 100 MB) | +| `write_file` | `sandbox_id`, `remote_path`, `content` (all required) | `success`, `sandbox_id`, `remote_path`, `size_bytes` (max 100 MB) | +| `list_files` | `sandbox_id`, `path` (both required) | `entries` (list of `{name, size, is_dir, mode, owner}`), `count` | +| `search_files` | `sandbox_id`, `path`, `pattern` (all required) | `files` (matching file paths), `count` | +| `find_in_files` | `sandbox_id`, `path`, `pattern` (all required) | `matches` (list of `{file, line_number, line_content}`), `count` | +| `start_service` | `sandbox_id`, `command` (both required) | `session_id`, `cmd_id`, `sandbox_id`, `command` | +| `get_service_logs` | `sandbox_id`, `session_id` (required), `cmd_id` (optional) | Logs as text plus `session_id`, `cmd_id`, `sandbox_id`, `stdout`, `stderr` | | `get_preview_url` | `sandbox_id`, `port` (1–65535) (both required) | `url`, `token`, `port`, `sandbox_id`. URL persists while the sandbox runs. For private sandboxes, callers must send the token via the `x-daytona-preview-token` header. | -| `destroy_sandbox` | `sandbox_id` (required) | `success`, `sandbox_id` | ### Support diff --git a/apps/dify-plugin/manifest.yaml b/apps/dify-plugin/manifest.yaml index 0bfa3f3..156a811 100644 --- a/apps/dify-plugin/manifest.yaml +++ b/apps/dify-plugin/manifest.yaml @@ -8,10 +8,10 @@ label: ja_JP: Daytona pt_BR: Daytona description: - en_US: Tool for running code securely in Daytona sandboxes. - zh_Hans: Tool for running code securely in Daytona sandboxes. - ja_JP: Tool for running code securely in Daytona sandboxes. - pt_BR: Tool for running code securely in Daytona sandboxes. + en_US: Create and manage Daytona sandboxes — run code and shell commands, manage files, clone Git repositories, run background services, and expose preview URLs. + zh_Hans: Create and manage Daytona sandboxes — run code and shell commands, manage files, clone Git repositories, run background services, and expose preview URLs. + ja_JP: Create and manage Daytona sandboxes — run code and shell commands, manage files, clone Git repositories, run background services, and expose preview URLs. + pt_BR: Create and manage Daytona sandboxes — run code and shell commands, manage files, clone Git repositories, run background services, and expose preview URLs. icon: icon.png resource: memory: 268435456 diff --git a/apps/dify-plugin/provider/daytona.yaml b/apps/dify-plugin/provider/daytona.yaml index e3c63de..9021cdc 100644 --- a/apps/dify-plugin/provider/daytona.yaml +++ b/apps/dify-plugin/provider/daytona.yaml @@ -7,10 +7,10 @@ identity: ja_JP: Daytona pt_BR: Daytona description: - en_US: Secure sandbox infrastructure for AI agents. Create isolated environments, run code, and execute commands via Daytona. - zh_Hans: Secure sandbox infrastructure for AI agents. Create isolated environments, run code, and execute commands via Daytona. - ja_JP: Secure sandbox infrastructure for AI agents. Create isolated environments, run code, and execute commands via Daytona. - pt_BR: Secure sandbox infrastructure for AI agents. Create isolated environments, run code, and execute commands via Daytona. + en_US: Secure sandbox infrastructure for AI agents. Create and manage isolated sandboxes — run code and commands, manage files, clone Git repositories, run background services, and expose preview URLs — via Daytona. + zh_Hans: Secure sandbox infrastructure for AI agents. Create and manage isolated sandboxes — run code and commands, manage files, clone Git repositories, run background services, and expose preview URLs — via Daytona. + ja_JP: Secure sandbox infrastructure for AI agents. Create and manage isolated sandboxes — run code and commands, manage files, clone Git repositories, run background services, and expose preview URLs — via Daytona. + pt_BR: Secure sandbox infrastructure for AI agents. Create and manage isolated sandboxes — run code and commands, manage files, clone Git repositories, run background services, and expose preview URLs — via Daytona. icon: icon.png credentials_for_provider: api_key: From 6478833c538145e2fc62f542ccf8ec52dcff73b6 Mon Sep 17 00:00:00 2001 From: Mislav Ivanda Date: Tue, 14 Jul 2026 17:35:23 +0200 Subject: [PATCH 2/3] docs(dify-plugin): clarify Run Command vs Run Code for cloned repos cubic review: the git-repo usage section implied Run Code could build/launch the project, but Run Code only executes a supplied snippet (no cwd/entrypoint). Point build/run steps at Run Command (with cwd) and describe Run Code as running snippets against the checkout. Signed-off-by: Mislav Ivanda --- apps/dify-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dify-plugin/README.md b/apps/dify-plugin/README.md index 6f56978..c5cbf54 100644 --- a/apps/dify-plugin/README.md +++ b/apps/dify-plugin/README.md @@ -42,7 +42,7 @@ If you don't pass a `sandbox_id` to **Run Code** or **Run Command**, a temporary #### Work with a Git repository -Use **Git Clone** to pull a repository into a sandbox, then **Run Command** or **Run Code** to build and run it. Private repositories can be cloned by supplying a username and a password/token. +Use **Git Clone** to pull a repository into a sandbox, then **Run Command** to build and run it (install dependencies, start the app, etc.), using `cwd` to target the checkout. **Run Code** is best for running snippets that operate on the cloned files. Private repositories can be cloned by supplying a username and a password/token. #### Run and preview a web service From 389c2f82a270335a24f2a76aab4c63fee4b37d2e Mon Sep 17 00:00:00 2001 From: Mislav Ivanda Date: Tue, 14 Jul 2026 17:45:04 +0200 Subject: [PATCH 3/3] docs(dify-plugin): steer long-running servers to Start Service, not Run Command cubic review: 'start the app' under Run Command could lead to a foreground command that blocks/times out (Run Command is synchronous). Limit Run Command examples to finite build/test steps and defer server startup to Start Service. Signed-off-by: Mislav Ivanda --- apps/dify-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dify-plugin/README.md b/apps/dify-plugin/README.md index c5cbf54..b850e57 100644 --- a/apps/dify-plugin/README.md +++ b/apps/dify-plugin/README.md @@ -42,7 +42,7 @@ If you don't pass a `sandbox_id` to **Run Code** or **Run Command**, a temporary #### Work with a Git repository -Use **Git Clone** to pull a repository into a sandbox, then **Run Command** to build and run it (install dependencies, start the app, etc.), using `cwd` to target the checkout. **Run Code** is best for running snippets that operate on the cloned files. Private repositories can be cloned by supplying a username and a password/token. +Use **Git Clone** to pull a repository into a sandbox, then **Run Command** for finite build and test steps (install dependencies, compile, run tests), using `cwd` to target the checkout. To launch a long-running server from the repo, use **Start Service** (see below) rather than **Run Command**, which waits for the command to finish and would time out. **Run Code** is best for running snippets that operate on the cloned files. Private repositories can be cloned by supplying a username and a password/token. #### Run and preview a web service