feat(integrations): add Daytona integration with sandbox lifecycle, code execution, and file tools#4987
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@greptile |
PR SummaryMedium Risk Overview Twelve tools cover sandbox lifecycle (create/list/get/start/stop/delete), in-sandbox run code (Python/JS/TS), execute command, file upload/download/list, and git clone. Most calls go straight to Daytona’s management and toolbox APIs; upload is proxied through The Daytona workflow block, tool registry, Notion branding shifts to a white card background and a fixed black icon fill (docs, blocks, catalog). Integration landing pages move the “Last updated” line below the CTAs with subtler styling. API validation baseline increments for the new upload route. Reviewed by Cursor Bugbot for commit abd1849. Configure here. |
|
@cursor review |
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e416012. Configure here.
Greptile SummaryThis PR adds a complete Daytona integration: 12 tools covering sandbox lifecycle (create/list/get/start/stop/delete), code execution (run Python/JS/TS, execute shell), file transfer (upload/download/list), and git clone. An internal route (
Confidence Score: 5/5Safe to merge — the Daytona integration is complete and all issues flagged in previous review rounds have been addressed. All 12 tools are correctly wired, API key visibility follows the user-only pattern throughout, the upload route pre-checks file size before downloading from storage, lifecycle endpoints tolerate empty response bodies via parseDaytonaJson, and zero-valued numeric params are preserved with the !== undefined && !== '' guard. The only new finding is a cosmetic regression in the NotionIcon fill attribute that was changed incidentally from currentColor to #000000. apps/sim/components/icons.tsx and apps/docs/components/icons.tsx — the NotionIcon fill hardcoding warrants a quick confirm that all rendering contexts (toolbar, dropdowns) still look correct on dark backgrounds. Important Files Changed
Sequence DiagramsequenceDiagram
participant W as Workflow Engine
participant UT as upload_file tool
participant IR as /api/tools/daytona/upload
participant S as File Storage
participant D as Daytona Toolbox API
W->>UT: invoke(apiKey, sandboxId, file, destinationPath)
UT->>IR: POST JSON body (apiKey, sandboxId, file ref, destinationPath)
IR->>IR: checkInternalAuth()
IR->>IR: processFilesToUserFiles()
IR->>IR: assertToolFileAccess(key, userId)
IR->>IR: guard: userFile.size ≤ 100MB?
IR->>S: downloadFileFromStorage(userFile)
S-->>IR: fileBuffer
IR->>IR: guard: fileBuffer.length ≤ 100MB?
IR->>D: "POST /toolbox/{sandboxId}/files/upload?path=... (multipart FormData, Bearer apiKey)"
D-->>IR: 200 OK
IR-->>UT: "{success, uploadedPath, name, size}"
UT-->>W: output
Reviews (8): Last reviewed commit: "fix(daytona): forward explicit zero cpu/..." | Re-trigger Greptile |
Greptile SummaryThis PR adds a Daytona integration with 12 tools covering the full sandbox lifecycle (create/list/get/start/stop/delete), code execution (run Python/JS/TS, execute shell), file transfer (upload/download/list), and git clone. A dedicated upload route at
Confidence Score: 3/5The integration is well-structured overall, but two issues in the upload route and the lifecycle tools (delete/start/stop) could cause real failures: large files are fully buffered before rejection, and response.json() is called unconditionally on responses that may carry no body. The upload route downloads the full file buffer from storage before applying the 100 MB size guard, even though userFile.size is already known — a file just over the limit consumes server memory unnecessarily. The delete (and start/stop) tools call response.json() without checking whether a body is present; if the Daytona API returns 204 for any of these operations the tool will throw a JSON parse error, leaving the user with a failure message even though the operation succeeded. apps/sim/app/api/tools/daytona/upload/route.ts (size check ordering) and apps/sim/tools/daytona/delete_sandbox.ts / start_sandbox.ts / stop_sandbox.ts (unconditional response.json() on lifecycle endpoints). Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as Client (Workflow Executor)
participant UploadRoute as /api/tools/daytona/upload
participant Storage as File Storage
participant DaytonaProxy as proxy.app.daytona.io/toolbox
participant DaytonaAPI as app.daytona.io/api
Note over Client,DaytonaAPI: Upload File (proxied through internal route)
Client->>UploadRoute: "POST {apiKey, sandboxId, file, destinationPath}"
UploadRoute->>UploadRoute: checkInternalAuth()
UploadRoute->>UploadRoute: parseRequest + validate contract
UploadRoute->>UploadRoute: assertToolFileAccess(userFile.key)
UploadRoute->>Storage: downloadFileFromStorage(userFile)
Storage-->>UploadRoute: fileBuffer (N bytes)
UploadRoute->>UploadRoute: "size check (> 100MB?)"
UploadRoute->>DaytonaProxy: "POST /toolbox/{sandboxId}/files/upload?path=..."
DaytonaProxy-->>UploadRoute: 200 OK
UploadRoute-->>Client: "{success, uploadedPath, name, size}"
Note over Client,DaytonaAPI: All other tools (direct external calls)
Client->>DaytonaAPI: POST /sandbox (create)
DaytonaAPI-->>Client: sandbox object
Client->>DaytonaProxy: "POST /toolbox/{id}/process/execute"
DaytonaProxy-->>Client: "{exitCode, result}"
Client->>DaytonaProxy: "GET /toolbox/{id}/files/download?path=..."
DaytonaProxy-->>Client: file bytes
Reviews (2): Last reviewed commit: "feat(integrations): add Daytona integrat..." | Re-trigger Greptile |
e416012 to
e9d30c7
Compare
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
|
@cursor review |
|
@greptile |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8230fbf. Configure here.
|
@greptile The two issues cited in the confidence score rationale are already fixed on the current head (8230fbf):
Please re-review the latest commit. |
…ode execution, and file tools
- Pre-check file size via userFile.size before downloading from storage in the upload route - Tolerate empty response bodies in delete/start/stop sandbox tools - Preserve explicit timeout 0 for run_code and execute_command - Default missing exitCode to -1 so unknown state is distinguishable from success - Reject blank sandbox IDs, clamp list limit to 1-200, trim destination path - Clarify that toolbox operations require the sandbox ID (not name) - Bump contract route baseline to 812 for the new daytona upload route
…y on empty lifecycle responses
8230fbf to
cee3094
Compare
|
@greptile |
|
@cursor review |
|
@cursor review |
|
@greptile |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit abd1849. Configure here.
Summary
Type of Change
Testing
Live-tested every operation end-to-end against the real Daytona API with a personal API key: sandbox create with labels/env, get, list with label filter and pagination, execute command (env/cwd/timeout), run code (Python and JavaScript), multipart upload, list files, download with byte-for-byte round-trip, git clone, stop/start lifecycle with state polling, delete. Also: typecheck clean, check:api-validation strict passes, tools/blocks structural test suites pass (196 tests).
Checklist