Skip to content

feat: add Daytona sandbox#681

Open
tyaroshko wants to merge 15 commits intomainfrom
feat/add-daytona-sandbox
Open

feat: add Daytona sandbox#681
tyaroshko wants to merge 15 commits intomainfrom
feat/add-daytona-sandbox

Conversation

@tyaroshko
Copy link
Copy Markdown
Collaborator

@tyaroshko tyaroshko commented Apr 7, 2026

Note

Medium Risk
Introduces a new sandbox provider and centralizes code-execution logic in a new shared base class; mistakes could impact sandbox lifecycle, file handling, and command execution across both Daytona and E2B.

Overview
Adds Daytona as a new sandbox backend option, including a Daytona API-key connection (cached SDK client), a DaytonaInterpreterTool, and a full DaytonaSandbox implementation with retry/backoff, file ops, shell execution, optional reconnect by sandbox_id, and export via dynamiq.sandboxes.

Refactors the existing E2B code-interpreter tool by extracting shared execution/file-upload/download/persistent-session logic into a new BaseCodeInterpreterTool and CodeInterpreterInputSchema, converting E2BInterpreterTool into a thin adapter and reusing the same retry/error-handling model.

Makes sandbox tooling more backend-agnostic by templating shell-tool docs with {base_path} at runtime and generalizing SandboxConnectionError messages to include a provider name.

Reviewed by Cursor Bugbot for commit df54248. Bugbot is set up for automated code reviews on this repo. Configure here.

@tyaroshko tyaroshko requested a review from a team as a code owner April 7, 2026 02:46
@tyaroshko tyaroshko changed the title chore: add Daytona sandbox feat: add Daytona sandbox Apr 7, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
dynamiq/connections
   connections.py75415080%18–23, 64, 85, 109, 181–184, 290, 292–300, 327, 329–331, 372, 519, 521–523, 574, 576–579, 644–645, 647–648, 655–656, 658–659, 674–675, 677, 703, 705, 717, 719–721, 794–796, 841, 856–858, 860, 865–866, 966, 1019, 1064–1065, 1076, 1175–1176, 1209–1210, 1246–1247, 1295–1296, 1298, 1301–1302, 1307, 1312, 1319–1320, 1323–1327, 1362–1363, 1365–1366, 1368–1369, 1371, 1379, 1387–1388, 1390–1393, 1395–1396, 1398, 1401, 1408, 1410, 1419–1420, 1422, 1511, 1513, 1544–1545, 1547, 1578–1579, 1653, 1655, 1659, 1685, 1689, 1691, 1742–1752, 1755, 1803, 1805–1806, 1808–1809, 1817, 1819, 1824–1825, 1827–1828, 1830, 1832
dynamiq/nodes/tools
   code_interpreter.py37514561%78, 98–102, 104–105, 107, 109, 140, 154, 162, 175, 189–190, 192–193, 213–221, 223, 269, 277, 331, 336, 341, 348, 355, 360, 365, 370, 375, 380, 385, 419, 428, 433–434, 463–473, 490, 495–496, 539, 550–552, 567–574, 579, 604–605, 609, 611–612, 614–618, 622–624, 652, 668–669, 672–676, 712, 715, 722, 740, 746–749, 756–759, 761, 763, 765–768, 771–772, 774–776, 779–782, 785, 787, 789–792, 794, 797–799, 802–809, 818, 848–849, 853–855, 866
   daytona_sandbox.py841779%35, 38–42, 61, 67–68, 79, 83–84, 95–96, 99, 122–123
   e2b_sandbox.py1088025%29, 36, 39–42, 47–48, 50–54, 56, 58–61, 63–64, 66–69, 71–77, 79, 81–84, 94–95, 97–101, 103–106, 108–111, 114–119, 121–122, 125–127, 130, 133–135, 137–138, 141, 144–150, 154–157
dynamiq/sandboxes
   base.py1332978%80, 127, 145, 169, 189, 214, 219, 222, 238–242, 260, 279, 288, 304, 331, 333–338, 340, 342–343, 345, 356
   daytona.py2145474%66, 70–74, 79, 87, 91, 100–101, 112, 160, 167, 180–182, 230–231, 237–239, 245, 253, 257, 259–261, 265–273, 275–278, 311, 328–332, 357–358, 364–365, 369, 375–376
   e2b.py21915330%78, 87, 92, 107–116, 136–142, 146–157, 171–172, 174, 176–177, 179–182, 185–192, 195–199, 203–209, 213, 215, 226–227, 231, 238, 242, 244, 255–257, 259–261, 269–271, 273, 291–292, 294–297, 299–300, 305–307, 312–314, 338, 340–341, 343–350, 352–358, 369–371, 373, 375–378, 381–384, 386, 388–390, 394–402, 406–408, 446–450, 452–454, 456, 460–461, 465, 471, 473
   e2b_desktop.py6183%15
   exceptions.py5340%5–7
dynamiq/sandboxes/tools
   shell.py682464%88, 93–96, 105–107, 155, 157–166, 171–175
TOTAL27221894567% 

Tests Skipped Failures Errors Time
1575 1 💤 0 ❌ 0 🔥 2m 3s ⏱️

@tyaroshko tyaroshko added the run-integration-tests-with-creds Trigger integration tests with credentials (optional) label Apr 7, 2026
Copy link
Copy Markdown
Contributor

@mykhailobuleshnyi mykhailobuleshnyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit df54248. Configure here.


try:
process = sandbox.commands.run(command, background=True, envs=env or {}, cwd=cwd or "/home/user")
process = sandbox.commands.run(command, background=True, envs=env or {}, cwd=cwd)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E2B shell command loses default working directory fallback

Low Severity

The old E2BInterpreterTool._execute_shell_command passed cwd=cwd or "/home/user" as a safety fallback. The refactored version passes cwd=cwd directly. While the base class currently always provides a non-None cwd via input_data.cwd or self.output_dir, passing None to the E2B SDK (if this method is ever called directly or the base logic changes) could lead to unexpected behavior since the E2B SDK may not default to a sensible directory.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit df54248. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-integration-tests-with-creds Trigger integration tests with credentials (optional)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants