Skip to content

feat: improve Daytona sandbox tools#5740

Merged
greysonlalonde merged 8 commits into
crewAIInc:mainfrom
mislavivanda:feat/daytona-sandbox-improvements
May 8, 2026
Merged

feat: improve Daytona sandbox tools#5740
greysonlalonde merged 8 commits into
crewAIInc:mainfrom
mislavivanda:feat/daytona-sandbox-improvements

Conversation

@mislavivanda
Copy link
Copy Markdown
Contributor

@mislavivanda mislavivanda commented May 7, 2026

Summary

This PR improves the existing Daytona sandbox tool integration in crewai-tools. It bumps the SDK pin to a current version, expands DaytonaFileTool with 6 new file operations, fixes several bugs in the existing implementation and docs, and ensures the docs sidebar correctly lists Daytona alongside E2B.

Motivation

  • SDK drift: daytona~=0.140.0 is 31 minor versions behind current (0.171.x). The narrow ~= constraint creates a resolver conflict for users who already have a recent daytona installed alongside crewai-tools[daytona].
  • Performance bug: DaytonaFileTool.append was O(N²) in network transfer — it downloaded the entire growing file, concatenated the new chunk in memory, and re-uploaded everything. The tool's own description tells agents to use chunked appends, so the bad path is reachable from the documented usage pattern. Appending 10 MB in 4 KB chunks transferred ~25 GB.
  • Broken docs discoverability: Daytona was missing from 2 of 13 English AI&ML sidebar groups in docs/docs.json.
  • Pre-existing docs bugs: Several examples used absolute /workspace/... paths that aren't writable in default Daytona sandboxes (which run as user daytona with home at /home/daytona). The "multi-step persistent session" example also created two separate sandboxes and then tried to read a file across them — silently broken.
  • Missing capabilities: DaytonaFileTool didn't expose several SDK methods that are very useful for agents (move, content grep, filename glob, chmod, bulk find-and-replace, existence check).

Changes

Code

  • SDK bump: daytona~=0.140.0daytona~=0.171 (PEP 440 form: >=0.171, <1.0; allows all 0.x updates, stops at 1.0)
  • Append performance: rewrote DaytonaFileTool._append — upload the chunk to a uniquely-named temp file once, do a server-side cat <temp> >> <target> via process.exec with shlex.quote-protected paths, then rm the temp. O(N²) → O(chunk_size) per call.
  • Public active_sandbox_id property on DaytonaBaseTool to replace the documented use of the private _persistent_sandbox.id attribute. Returns the explicitly-attached sandbox_id, the lazily-created persistent sandbox's id, or None for ephemeral mode.
  • 6 new actions on DaytonaFileTool: exists, move, find (recursive content grep), search (filename glob), chmod (mode/owner/group), replace (bulk find-and-replace across files)
  • Extended DaytonaFileToolSchema with the required new fields (destination, pattern, replacement, paths, owner, group) plus per-action validation in the existing model_validator.
  • Updated DaytonaFileTool.description so the LLM is aware of the new actions.

Docs (docs/{en,ko,pt-BR,ar}/tools/ai-ml/daytona.mdx + lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/README.md)

  • New "Searching, moving, and modifying files" example covering all 6 new actions.
  • Replaced _persistent_sandbox.id references with active_sandbox_id everywhere (5 files).
  • Fixed /workspace/...workspace/... (23 occurrences × 4 locale files = 92 corrections). Daytona resolves relative paths under the sandbox user's home (/home/daytona/).
  • Fixed broken multi-step persistent example: was creating two separate sandboxes (each persistent=True tool gets its own); now uses active_sandbox_id to share one sandbox correctly. Also swapped flaky httpx.get(httpbin.org) for an offline httpx.__version__ check so the example works regardless of sandbox egress policy.
  • Fixed misleading return-shape comment in one-shot Python example ('artifacts': None'artifacts': ExecutionArtifacts(...)).
  • Updated parameter table to include all new fields with required-by-action annotations.

Sidebar registration (docs/docs.json)

  • Registered Daytona in the 2 previously-missing English AI&ML sidebar groups.
  • The single daytona-only group at version v1.14.2 is preserved as-is.

Testing

Validated against a real Daytona sandbox (SDK 0.171.x). All 47 distinct validations PASS:

  • Smoke test (20 steps) — every existing action × every new action × every lifecycle mode (ephemeral / persistent / attach) + cross-tool sandbox sharing via active_sandbox_id.
  • Append edge cases (16 cases) — empty content, 100 chunks of 1 byte, all 256 byte values incl. NUL, shell-injection-resistant content (; rm -rf /, $(whoami), backticks), unicode (emoji + CJK + accents), paths with spaces, paths with shell metacharacters, deeply nested paths, 64 KB single chunk, append after delete, return-contract correctness, zero temp-file leakage.
  • Docs example verbatim (11 lines + 5 post-conditions) — ran the new "Searching, moving, and modifying files" code block character-for-character against a real sandbox with pre/post-condition checks confirming each operation actually changed sandbox state (e.g. chmod actually set 0755; replace actually rewrote both files).

Static analysis: ruff check and ruff format --check pass on all touched Python files. docs.json validates as JSON; pyproject.toml validates as TOML.

Out of scope (separate PRs welcome)

  • Locale translations: All four daytona.mdx files (en/ko/pt-BR/ar) are byte-for-byte identical English copies — that's the upstream pattern from PR docs: add Daytona sandbox tools documentation #5643, where the original author created locale-specific files so per-language sidebar links work but deferred actual translation. Our edits keep them in sync as English placeholders. Real localization is a community translation effort.

Notes for reviewers

  • The append fix uses shlex.quote() for path safety against shell metacharacters and uuid.uuid4() for temp file naming. The temp path lives in /tmp/ on the sandbox's ephemeral filesystem (not the host); a # noqa: S108 with security-context comment suppresses Ruff's flag.
  • Both Daytona and E2B currently use icon: box in their docs frontmatter — visual collision in the sidebar, but kept as-is to keep this PR scoped.
  • All examples now use Daytona's idiomatic relative-path style (matching the official Daytona Python SDK docs).

Related

Summary by CodeRabbit

Release Notes

  • New Features

    • DaytonaFileTool expanded with additional file operations: move, find, search, chmod, replace, and existence checks.
    • New active_sandbox_id property enables seamless sandbox sharing across multiple tool instances.
  • Documentation

    • Updated path conventions and added comprehensive examples for new file operations.
    • Improved guidance on sharing persistent sandboxes across tools in multiple languages (English, Arabic, Korean, Portuguese).

Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
greysonlalonde added a commit that referenced this pull request May 7, 2026
* chore(deps): use 3-day exclude-newer window

Aligns the root workspace with the per-package pyprojects, which
already use `exclude-newer = "3 days"`. The fixed 2026-04-27 cutoff
blocks legitimate dependency bumps (e.g. daytona ~=0.171 in #5740)
without adding meaningful protection — the relative window still
includes the security patches that motivated the original pin.

* fix(deps): bump gitpython and python-multipart for new advisories

- gitpython >=3.1.49 for GHSA-v87r-6q3f-2j67 (newline injection in
  config_writer().set_value() enables RCE via core.hooksPath).
- python-multipart >=0.0.27 for GHSA-pp6c-gr5w-3c5g (DoS via
  unbounded multipart part headers).

Both surfaced via pip-audit on this branch.
@greysonlalonde
Copy link
Copy Markdown
Contributor

Hey, this conflicts with our otel packages

@mislavivanda
Copy link
Copy Markdown
Contributor Author

Hey, this conflicts with our otel packages

@greysonlalonde Confirmed, sorry for the breakage. The SDK bump was the cause: Daytona 0.141+ transitively pulls opentelemetry-instrumentation-aiohttp-client>=0.59b0 whose lowest version requires opentelemetry-api==1.38, conflicting with CrewAI's ~=1.34.0 pin. There's no version of the aiohttp-client transitive that's compatible with CrewAI's OTel range.

I've reverted the pin to daytona~=0.140.0 and verified empirically that 0.140 already exposes every SDK method this PR uses (move_files, find_files, search_files, set_file_permissions, replace_in_files, get_file_info), so all the new actions, the append refactor, and the active_sandbox_id property still work. The wider OTel update would be a CrewAI-side change, separate from this PR.

Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
@greysonlalonde
Copy link
Copy Markdown
Contributor

Sorry, didn't mean to close this

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dac637b7-4b85-43f8-8556-87fd295e8bc9

📥 Commits

Reviewing files that changed from the base of the PR and between cf2fb45 and af0a799.

📒 Files selected for processing (8)
  • docs/ar/tools/ai-ml/daytona.mdx
  • docs/docs.json
  • docs/en/tools/ai-ml/daytona.mdx
  • docs/ko/tools/ai-ml/daytona.mdx
  • docs/pt-BR/tools/ai-ml/daytona.mdx
  • lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/README.md
  • lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_base_tool.py
  • lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py

📝 Walkthrough

Walkthrough

DaytonaFileTool is extended with six new file operations (exists, move, find, search, chmod, replace) via expanded FileAction type and schema. Append is refactored for server-side execution. DaytonaBaseTool exposes active_sandbox_id property for cross-tool sandbox sharing. Documentation updated across all languages with new examples and extended parameter tables.

Changes

Daytona File Tool Expansion

Layer / File(s) Summary
Type Definitions and Schema
lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py
FileAction literal expanded from 7 to 13 operations. DaytonaFileToolSchema made path optional and added mode, destination, pattern, replacement, paths, owner, group fields with action-specific validation.
Core Implementation and Helpers
lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py
_run method refactored to dispatch all 13 actions. Append reimplemented for server-side execution via temp file upload and cat >> redirection. New helpers _exists, _find, _search, _chmod return structured results. Tool description updated.
Public Sandbox ID Property
lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_base_tool.py
active_sandbox_id property added to report configured or lazily-created persistent sandbox ID, enabling sharing across tool instances.
Internal Documentation
lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/README.md
README updated with active_sandbox_id sharing pattern and expanded tool arguments list covering all 13 actions and parameter requirements.
English Documentation
docs/en/tools/ai-ml/daytona.mdx
Feature list expanded, persistent sandbox example updated to use active_sandbox_id, new "Searching, moving, and modifying files" section added, parameter table extended, workspace paths corrected, output examples show structured ExecutionArtifacts.
Localized Documentation
docs/ar/tools/ai-ml/daytona.mdx, docs/ko/tools/ai-ml/daytona.mdx, docs/pt-BR/tools/ai-ml/daytona.mdx
Arabic, Korean, and Portuguese-Brazil versions synchronized with English documentation: expanded capabilities, refactored sandbox-sharing examples, new operations section, extended parameter tables, corrected workspace paths.
Navigation Configuration
docs/docs.json
Tool navigation arrays updated to position daytona before e2bsandboxtools consistently and insert after codeinterpretertool in specified lists.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Whiskers twitching with delight,
New file ops make our tools so bright—
Sandbox sharing with active_id,
Server-side appends, oh what a rid!
Search, chmod, move with flair,
Documentation everywhere!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: improve Daytona sandbox tools' clearly summarizes the main changes—expanded capabilities for Daytona file operations, new actions, and documentation updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

@greysonlalonde greysonlalonde merged commit b9e71b3 into crewAIInc:main May 8, 2026
54 of 86 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants