feat: add Daytona Code Mode isolate driver#645
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughAdds a Daytona-backed IsolateDriver implementation and package, plus README and Code Mode documentation updates to document installation, configuration options ( ChangesDaytona Isolate Driver
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
packages/typescript/ai-isolate-daytona/tests/wrap-code.test.ts (1)
1-276: ⚡ Quick winMove this unit test file to be colocated with the source module.
wrap-code.test.tsshould sit alongsidesrc/wrap-code.tsrather than undertests/to match the repo’s unit test placement rule.As per coding guidelines: "Define unit tests in
*.test.tsfiles alongside source files".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/typescript/ai-isolate-daytona/tests/wrap-code.test.ts` around lines 1 - 276, The test file wrap-code.test.ts is currently under tests/ but must be colocated with its module; move the entire wrap-code.test.ts so it sits next to src/wrap-code.ts, update any import paths if necessary (ensure imports like '../src/wrap-code' still resolve from the new location or change them to './wrap-code'), and run the test suite to verify nothing breaks; keep the test filename and contents unchanged aside from import path fixes and ensure test runner picks up the colocated *.test.ts file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/code-mode/code-mode-isolates.md`:
- Around line 230-239: The fenced diagram block starting with the lines "Driver
(your server) Daytona sandbox" is missing a fence language and
triggers MD040; update the triple-backtick fence that surrounds that ASCII
diagram to include a language label (e.g., change ``` to ```text) so the code
block is explicitly marked as plain text and will satisfy markdown linting.
In `@packages/typescript/ai-isolate-daytona/package.json`:
- Around line 1-59: Add the required packageManager field to this package.json
to pin pnpm to the repo standard: add "packageManager": "pnpm@10.17.0" at the
top-level of the JSON (near other root keys such as "name" and "version") so the
manifest explicitly declares pnpm@10.17.0 for consistent lockfile/tooling
behavior.
In `@packages/typescript/ai-isolate-daytona/README.md`:
- Around line 62-70: The fenced diagram block in the README is unlabeled and
triggers MD040; update the opening triple-backtick fence for the diagram (the
block starting with "Host process Daytona sandbox") to
include a language label (e.g., change ``` to ```text) so the block becomes a
labeled code fence and satisfies the markdown linter.
In `@packages/typescript/ai-isolate-daytona/src/isolate-driver.ts`:
- Around line 130-133: The timeoutAfter helper currently creates an uncancelled
timer; change timeoutAfter(milliseconds) to return both a promise and a cancel
function (e.g., { promise, cancel } or [promise, cancel]) where cancel calls
clearTimeout on the stored timer id; then update the Promise.race call sites
that race timeoutAfter() with work (the two Promise.race usages) to call the
cancel function when the work branch wins so the pending timer is cleared and
not left accumulating.
---
Nitpick comments:
In `@packages/typescript/ai-isolate-daytona/tests/wrap-code.test.ts`:
- Around line 1-276: The test file wrap-code.test.ts is currently under tests/
but must be colocated with its module; move the entire wrap-code.test.ts so it
sits next to src/wrap-code.ts, update any import paths if necessary (ensure
imports like '../src/wrap-code' still resolve from the new location or change
them to './wrap-code'), and run the test suite to verify nothing breaks; keep
the test filename and contents unchanged aside from import path fixes and ensure
test runner picks up the colocated *.test.ts file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6f9da31f-ab9d-49c6-afaa-7116d73a5dc0
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
.changeset/daytona-isolate-driver.mddocs/code-mode/code-mode-isolates.mddocs/code-mode/code-mode.mdpackages/typescript/ai-isolate-daytona/README.mdpackages/typescript/ai-isolate-daytona/package.jsonpackages/typescript/ai-isolate-daytona/src/index.tspackages/typescript/ai-isolate-daytona/src/isolate-driver.tspackages/typescript/ai-isolate-daytona/src/types.tspackages/typescript/ai-isolate-daytona/src/wrap-code.tspackages/typescript/ai-isolate-daytona/tests/isolate-driver.test.tspackages/typescript/ai-isolate-daytona/tests/live.test.tspackages/typescript/ai-isolate-daytona/tests/wrap-code.test.tspackages/typescript/ai-isolate-daytona/tsconfig.jsonpackages/typescript/ai-isolate-daytona/vite.config.ts
| { | ||
| "name": "@tanstack/ai-isolate-daytona", | ||
| "version": "0.0.1", | ||
| "description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.", | ||
| "author": "", | ||
| "license": "MIT", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/TanStack/ai.git", | ||
| "directory": "packages/typescript/ai-isolate-daytona" | ||
| }, | ||
| "type": "module", | ||
| "module": "./dist/esm/index.js", | ||
| "types": "./dist/esm/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/esm/index.d.ts", | ||
| "import": "./dist/esm/index.js" | ||
| } | ||
| }, | ||
| "sideEffects": false, | ||
| "engines": { | ||
| "node": ">=18" | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "src" | ||
| ], | ||
| "scripts": { | ||
| "build": "vite build", | ||
| "clean": "premove ./build ./dist", | ||
| "lint:fix": "eslint ./src --fix", | ||
| "test:build": "publint --strict", | ||
| "test:eslint": "eslint ./src", | ||
| "test:live": "vitest --run tests/live.test.ts", | ||
| "test:lib": "vitest --passWithNoTests", | ||
| "test:lib:dev": "pnpm test:lib --watch", | ||
| "test:types": "tsc" | ||
| }, | ||
| "keywords": [ | ||
| "ai", | ||
| "ai-sdk", | ||
| "typescript", | ||
| "tanstack", | ||
| "code-mode", | ||
| "daytona", | ||
| "sandbox", | ||
| "isolate", | ||
| "code-execution" | ||
| ], | ||
| "peerDependencies": { | ||
| "@tanstack/ai-code-mode": "workspace:*" | ||
| }, | ||
| "devDependencies": { | ||
| "@daytona/sdk": "^0.180.0", | ||
| "@tanstack/ai-code-mode": "workspace:*", | ||
| "@vitest/coverage-v8": "4.0.14" | ||
| } | ||
| } |
There was a problem hiding this comment.
Add packageManager to pin pnpm version.
This manifest does not declare the required package manager pin, which can lead to inconsistent lockfile/tooling behavior across contributors.
Suggested fix
{
"name": "`@tanstack/ai-isolate-daytona`",
"version": "0.0.1",
+ "packageManager": "pnpm@10.17.0",
"description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.",As per coding guidelines "**/package.json: Use pnpm@10.17.0 as the package manager for this repository".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { | |
| "name": "@tanstack/ai-isolate-daytona", | |
| "version": "0.0.1", | |
| "description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.", | |
| "author": "", | |
| "license": "MIT", | |
| "repository": { | |
| "type": "git", | |
| "url": "git+https://github.com/TanStack/ai.git", | |
| "directory": "packages/typescript/ai-isolate-daytona" | |
| }, | |
| "type": "module", | |
| "module": "./dist/esm/index.js", | |
| "types": "./dist/esm/index.d.ts", | |
| "exports": { | |
| ".": { | |
| "types": "./dist/esm/index.d.ts", | |
| "import": "./dist/esm/index.js" | |
| } | |
| }, | |
| "sideEffects": false, | |
| "engines": { | |
| "node": ">=18" | |
| }, | |
| "files": [ | |
| "dist", | |
| "src" | |
| ], | |
| "scripts": { | |
| "build": "vite build", | |
| "clean": "premove ./build ./dist", | |
| "lint:fix": "eslint ./src --fix", | |
| "test:build": "publint --strict", | |
| "test:eslint": "eslint ./src", | |
| "test:live": "vitest --run tests/live.test.ts", | |
| "test:lib": "vitest --passWithNoTests", | |
| "test:lib:dev": "pnpm test:lib --watch", | |
| "test:types": "tsc" | |
| }, | |
| "keywords": [ | |
| "ai", | |
| "ai-sdk", | |
| "typescript", | |
| "tanstack", | |
| "code-mode", | |
| "daytona", | |
| "sandbox", | |
| "isolate", | |
| "code-execution" | |
| ], | |
| "peerDependencies": { | |
| "@tanstack/ai-code-mode": "workspace:*" | |
| }, | |
| "devDependencies": { | |
| "@daytona/sdk": "^0.180.0", | |
| "@tanstack/ai-code-mode": "workspace:*", | |
| "@vitest/coverage-v8": "4.0.14" | |
| } | |
| } | |
| { | |
| "name": "`@tanstack/ai-isolate-daytona`", | |
| "version": "0.0.1", | |
| "packageManager": "pnpm@10.17.0", | |
| "description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.", | |
| "author": "", | |
| "license": "MIT", | |
| "repository": { | |
| "type": "git", | |
| "url": "git+https://github.com/TanStack/ai.git", | |
| "directory": "packages/typescript/ai-isolate-daytona" | |
| }, | |
| "type": "module", | |
| "module": "./dist/esm/index.js", | |
| "types": "./dist/esm/index.d.ts", | |
| "exports": { | |
| ".": { | |
| "types": "./dist/esm/index.d.ts", | |
| "import": "./dist/esm/index.js" | |
| } | |
| }, | |
| "sideEffects": false, | |
| "engines": { | |
| "node": ">=18" | |
| }, | |
| "files": [ | |
| "dist", | |
| "src" | |
| ], | |
| "scripts": { | |
| "build": "vite build", | |
| "clean": "premove ./build ./dist", | |
| "lint:fix": "eslint ./src --fix", | |
| "test:build": "publint --strict", | |
| "test:eslint": "eslint ./src", | |
| "test:live": "vitest --run tests/live.test.ts", | |
| "test:lib": "vitest --passWithNoTests", | |
| "test:lib:dev": "pnpm test:lib --watch", | |
| "test:types": "tsc" | |
| }, | |
| "keywords": [ | |
| "ai", | |
| "ai-sdk", | |
| "typescript", | |
| "tanstack", | |
| "code-mode", | |
| "daytona", | |
| "sandbox", | |
| "isolate", | |
| "code-execution" | |
| ], | |
| "peerDependencies": { | |
| "`@tanstack/ai-code-mode`": "workspace:*" | |
| }, | |
| "devDependencies": { | |
| "`@daytona/sdk`": "^0.180.0", | |
| "`@tanstack/ai-code-mode`": "workspace:*", | |
| "`@vitest/coverage-v8`": "4.0.14" | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/typescript/ai-isolate-daytona/package.json` around lines 1 - 59, Add
the required packageManager field to this package.json to pin pnpm to the repo
standard: add "packageManager": "pnpm@10.17.0" at the top-level of the JSON
(near other root keys such as "name" and "version") so the manifest explicitly
declares pnpm@10.17.0 for consistent lockfile/tooling behavior.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/ai-isolate-daytona/src/isolate-driver.ts (1)
130-146:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTimer type should be
ReturnType<typeof setTimeout>for Node.js compatibility.In Node.js,
setTimeoutreturns aTimeoutobject rather than anumber. Usingnumberhere is incorrect for the Node.js runtime, though it works at runtime sinceclearTimeoutaccepts both types. The past review's proposed fix correctly usedReturnType<typeof setTimeout>.🔧 Proposed fix
async function withTimeout<T>( promise: Promise<T>, milliseconds: number, ): Promise<T | undefined> { - let timer: number | undefined + let timer: ReturnType<typeof setTimeout> | undefined const timeout = new Promise<undefined>((resolve) => { timer = setTimeout(resolve, milliseconds) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ai-isolate-daytona/src/isolate-driver.ts` around lines 130 - 146, The timer variable in withTimeout is typed as number which is incorrect for Node.js; change the type of timer to ReturnType<typeof setTimeout> (and adjust the timeout Promise factory to assign timer via setTimeout) so clearTimeout receives the proper type — update the declaration "let timer: number | undefined" to use ReturnType<typeof setTimeout> and ensure other uses (timer !== undefined, clearTimeout(timer)) remain valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@packages/ai-isolate-daytona/src/isolate-driver.ts`:
- Around line 130-146: The timer variable in withTimeout is typed as number
which is incorrect for Node.js; change the type of timer to ReturnType<typeof
setTimeout> (and adjust the timeout Promise factory to assign timer via
setTimeout) so clearTimeout receives the proper type — update the declaration
"let timer: number | undefined" to use ReturnType<typeof setTimeout> and ensure
other uses (timer !== undefined, clearTimeout(timer)) remain valid.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: fb620614-05cd-4438-99d6-bc837bb9abb5
📒 Files selected for processing (3)
docs/code-mode/code-mode-isolates.mdpackages/ai-isolate-daytona/README.mdpackages/ai-isolate-daytona/src/isolate-driver.ts
✅ Files skipped from review due to trivial changes (2)
- packages/ai-isolate-daytona/README.md
- docs/code-mode/code-mode-isolates.md
Changes
This adds
@tanstack/ai-isolate-daytona, a Code Mode isolate driver for caller-owned Daytona sandboxes.The driver sends wrapped Code Mode programs to
sandbox.process.codeRun, reads the marker envelope from Daytona stdout/result, and keeps TanStack tool implementations on the host. When generated code calls anexternal_*tool, Daytona returnsneed_tools; the host runs the matchingToolBinding.executecallbacks and replays the program with the tool results.A few details matter here:
createContextis a logical Code Mode context. It does not create or delete Daytona sandboxes.timeoutis a total execution budget in milliseconds. Daytona receives the remaining budget as a per-call seconds timeout.maxToolRoundscounts host tool callback rounds, not rawcodeRuncalls.The PR also updates the Code Mode isolate docs and adds a changeset for the new package.
Test plan
pnpm test:prpnpm test:e2eDAYTONA_LIVE_TEST=1 DAYTONA_API_KEY=<redacted> pnpm --filter @tanstack/ai-isolate-daytona test:liveI also ran the narrower package checks while developing:
pnpm --filter @tanstack/ai-isolate-daytona test:lib -- --run tests/isolate-driver.test.ts tests/wrap-code.test.ts tests/live.test.tspnpm --filter @tanstack/ai-isolate-daytona test:typespnpm --filter @tanstack/ai-isolate-daytona test:eslintpnpm --filter @tanstack/ai-isolate-daytona buildpnpm --filter @tanstack/ai-isolate-daytona test:buildNotes:
finally.examples/ts-svelte-chat/.svelte-kit/tsconfig.jsonwarning during several commands. The commands still passed.Checklist
pnpm run test:pr.Release impact
Summary by CodeRabbit
New Features
Documentation