From 1a5f8edc2f963aaea0db73157d40e39b6d8e5678 Mon Sep 17 00:00:00 2001 From: Kiko0301 Date: Fri, 23 Oct 2026 16:00:41 +0800 Subject: [PATCH] docs(config): explain skills and sandbox paths across platforms (#7304) * docs(config): explain skills and sandbox paths across platforms * docs: clarify YAML paths and trim startup guidance --------- Co-authored-by: Kiko0301 <191240073+Kiko0301@users.noreply.github.com> Co-authored-by: Willem Jiang --- README.md | 2 +- backend/docs/CONFIGURATION.md | 75 +++++++++++++++++++++++++++++++++-- config.example.yaml | 17 +++++--- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3458805dd5..ab19345ae3 100644 --- a/README.md +++ b/README.md @@ -911,7 +911,7 @@ reports failure and can be retried; retries verify the runtime identity and abse before completing cleanup. Healthy replacements with the same logical ID remain reusable, including after background recovery into the warm pool. -See the [Sandbox Configuration Guide](backend/docs/CONFIGURATION.md#sandbox) to configure your preferred mode. +See the [Sandbox Configuration Guide](backend/docs/CONFIGURATION.md#sandbox) to configure your preferred mode. For absolute skills paths and custom directory mappings on Linux, macOS, Windows, WSL, or a Docker Gateway, see [Skills and sandbox paths](backend/docs/CONFIGURATION.md#skills-and-sandbox-paths). Managed async AIO runs can opt into bounded sandbox prewarming to overlap startup with the first model call. Direct SDK graphs keep lazy acquisition. It defaults off; see the guide and diff --git a/backend/docs/CONFIGURATION.md b/backend/docs/CONFIGURATION.md index 37e140409c..c0b0839597 100644 --- a/backend/docs/CONFIGURATION.md +++ b/backend/docs/CONFIGURATION.md @@ -1589,7 +1589,7 @@ sandbox: read_only: false ``` -When you configure `sandbox.mounts`, DeerFlow exposes those `container_path` values in the agent prompt so the agent can discover and operate on mounted directories directly instead of assuming everything must live under `/mnt/user-data`. +When you configure `sandbox.mounts`, DeerFlow exposes those `container_path` values in the agent prompt so the agent can discover and operate on mounted directories directly instead of assuming everything must live under `/mnt/user-data`. See [Skills and sandbox paths](#skills-and-sandbox-paths) for Windows, WSL, and Docker path examples. #### Sandbox network policy @@ -1792,13 +1792,80 @@ Configure the skills directory for specialized workflows: ```yaml skills: - # Host path (optional, default: ../skills) + # Gateway-visible source root (optional; see resolution order below) path: /custom/path/to/skills - # Container mount path (default: /mnt/skills) + # Agent-facing POSIX path (default: /mnt/skills, including on Windows) container_path: /mnt/skills ``` +#### Skills and sandbox paths + +Choose paths from the filesystem of the process that reads them: + +| Setting | Meaning | +| --- | --- | +| `skills.path` | Source directory read by the Gateway, containing `public/` and any legacy `custom/` skills. It is not the path the agent uses. | +| `skills.container_path` | Agent-facing skills root, normally `/mnt/skills`. DeerFlow prepares the enabled skill views beneath this root; do not add a second `sandbox.mounts` entry for skills. | +| `sandbox.mounts[].host_path` | Existing absolute source directory. With `LocalSandboxProvider`, it must be visible to the Gateway process. With local AIO Docker, it must be available to the Docker daemon creating the sandbox. | +| `sandbox.mounts[].container_path` | Absolute POSIX path used by agent tools, such as `/mnt/shared`, on every host OS. Local mode maps it to the source; AIO Docker bind-mounts the source there. | + +Skills source resolution is: explicit `skills.path`, then `DEER_FLOW_SKILLS_PATH`, +then `/skills`. The project root is `DEER_FLOW_PROJECT_ROOT` when +set, otherwise the Gateway process's working directory. Relative skill source +paths use that root, **not the directory containing `config.yaml`**. If the default +directory is absent, a source checkout also tries its repository `skills/` +directory. Use an absolute path to remove ambiguity; `~` is not expanded in +these path fields. Changing `skills.path` does not relocate per-user custom +skills, which live under `DEER_FLOW_HOME/users//skills/custom/`. + +For a Gateway running directly on the machine with `LocalSandboxProvider`, +adapt the two source paths in this example to your platform: + +```yaml +skills: + path: /home/alice/deer-flow/skills + container_path: /mnt/skills +sandbox: + use: deerflow.sandbox.local:LocalSandboxProvider + mounts: + - host_path: /home/alice/data + container_path: /mnt/shared + read_only: true +``` + +| Gateway environment | Example `skills.path` | Example `sandbox.mounts[].host_path` | +| --- | --- | --- | +| Linux | `/home/alice/deer-flow/skills` | `/home/alice/data` | +| macOS | `/Users/alice/deer-flow/skills` | `/Users/alice/data` | +| Native Windows Python (including when launched from Git Bash) | `'D:/deer-flow/skills'` | `'D:/data'` | +| Linux Python inside WSL, using files on Windows drive D | `/mnt/d/deer-flow/skills` | `/mnt/d/data` | + +Keep both `container_path` values unchanged. For example, an agent reads +`/mnt/shared/report.csv`; native Windows resolves that to `D:/data/report.csv`, +while WSL resolves it to `/mnt/d/data/report.csv`. WSL-native files can instead +use `/home/alice/...`. Native Windows paths can use forward slashes as above, +or single-quoted backslashes (`'D:\data'`). Plain, unquoted YAML scalars also keep +backslashes literal; only double-quoted scalars interpret backslash escapes. +These are path examples; the [local development prerequisites](../../README.md#option-2-local-development) +still apply, including the documented WSL limitations of the startup scripts. + +**Gateway in Docker:** both bundled Compose files mount the repository's +`skills/` at `/app/skills` and set `DEER_FLOW_PROJECT_ROOT=/app`. Leave +`skills.path` unset, or use `/app/skills`. To use another host skills directory, +replace that Gateway volume's source and keep its container destination consistent +with `skills.path`; a host path such as `D:/deer-flow/skills` is not a path inside +the Linux Gateway container. + +For local-sandbox custom directories, use the two-step [Gateway bind mount +example](#sandbox) above: Docker host directory → Gateway-visible `host_path` → +agent-facing `container_path`. In AIO Docker-outside-of-Docker mode, custom mounts +go directly from the Docker host to the sandbox: on a Linux Docker host, +`host_path: /srv/data` and `container_path: /mnt/shared` expose `/srv/data` there, +even if the Gateway sees the same directory at `/app/data`. Do not substitute +`/app/data` unless it is also the intended source on the Docker host. These local +mount examples do not configure Kubernetes PVCs or remote sandbox storage. + For the AIO provider (including the Kubernetes provisioner) and E2B, `skills.container_path` is captured when the provider starts and must be one canonical absolute, non-root POSIX path. Do not use redundant separators, @@ -1809,7 +1876,7 @@ same root. E2B also records the root in remote metadata and refuses to adopt a VM created for another root. **How Skills Work**: -- Skills are stored in `deer-flow/skills/{public,custom}/` +- Public and legacy skills use the configured source root; user-installed custom skills use the per-user runtime directory above - Each skill has a `SKILL.md` file with metadata - Skills are automatically discovered and loaded - Available in both local and Docker sandbox via path mapping diff --git a/config.example.yaml b/config.example.yaml index 8fbba4cb69..d34c1c2513 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -1726,11 +1726,14 @@ sandbox: # This is not a total container or deployment-wide capacity limit. prewarm_max_concurrent: 1 # Optional: Mount additional host directories into the sandbox. - # Each mount maps a host path to a virtual container path accessible by the agent. + # host_path: existing absolute source path; container_path: agent-facing /mnt/... path. + # Native Windows source example: 'D:/data'; WSL source example: /mnt/d/data. + # Keep container_path POSIX-style on every OS (for example, /mnt/my-project). # Note: with LocalSandboxProvider under `make up` (docker-compose), host_path is # checked from inside the deer-flow-gateway container — you must also bind-mount # the same directory into services.gateway.volumes in docker/docker-compose.yaml - # for this mount to take effect (see issue #3244). + # for this mount to take effect. AIO Docker mounts instead use Docker-host paths. + # Platform examples: backend/docs/CONFIGURATION.md#skills-and-sandbox-paths # mounts: # - host_path: /home/user/my-project # Absolute path; see note above for Docker mode # container_path: /mnt/my-project # Virtual path inside the sandbox @@ -2145,13 +2148,17 @@ verification: # Configure skills directory for specialized agent workflows skills: - # Path to skills directory on the host (relative to project root or absolute) - # Default: skills under the project root + # Skills source root read by the Gateway (contains public/ and legacy custom/). + # Absolute, or relative to DEER_FLOW_PROJECT_ROOT (process cwd when unset). + # Default: skills under that root, with a source-checkout fallback to repo skills/. # Override with DEER_FLOW_SKILLS_PATH when this field is omitted. + # In Docker, use a Gateway-visible path, such as the bundled /app/skills mount. + # Native Windows: 'D:/deer-flow/skills'; WSL: /mnt/d/deer-flow/skills. + # See backend/docs/CONFIGURATION.md#skills-and-sandbox-paths for mappings. # Uncomment to customize: # path: /absolute/path/to/custom/skills - # Path where skills are mounted in the sandbox container + # Agent-facing POSIX path; keep /mnt/skills even when the Gateway runs on Windows. # This is used by the agent to access skills in both local and Docker sandbox # AIO/provisioner and E2B modes require a canonical absolute non-root path # that does not overlap reserved platform mounts. Providers snapshot this