Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Then follow the guide's own README to install dependencies and run it.
| [Amp Code Coding Agent](typescript/amp/amp-sdk) | Coding agent powered by the Amp Code CLI. |
| [Claude Two-Agent System](typescript/anthropic/multi-agent-claude-sdk) | Two-agent Claude system coordinating work across sandboxes. |
| [Claude Coding Agent](typescript/anthropic/single-claude-agent-sdk) | Single Claude Code agent you drive from the CLI. |
| [Claude Draws](typescript/computer-use/claude-draws) | Claude drawing on a browser sketchpad in a sandbox desktop, via the Anthropic computer toolset. |
| [Brainbase Universal Harness API](typescript/brainbase/universal-harness-api) | Background coding agent on any harness via Brainbase's Universal Harness API, running in Daytona sandboxes. |
| [Devin CLI Coding Agent](typescript/cognition/devin-cli) | Coding agent powered by Cognition's Devin CLI. |
| [Convex AI App Builder](typescript/convex/ai-app-builder) | AI app builder on the Daytona Convex component — LLM-generated apps run in sandboxes with live build state and iframe previews. |
Expand Down
2 changes: 2 additions & 0 deletions python/computer-use/claude-draws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This example opens a canvas sketchpad in a Chromium window on a Daytona sandbox desktop and lets Claude draw in it with the mouse, through the Anthropic SDK's computer toolset.

A [TypeScript version](../../../typescript/computer-use/claude-draws) of this example is also available.

## What you will build

- A sandbox desktop at 1280x800, created and deleted by `DaytonaComputer` from the [`daytona-claude-toolsets`](https://pypi.org/project/daytona-claude-toolsets/) package.
Expand Down
4 changes: 2 additions & 2 deletions python/computer-use/claude-draws/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ dependencies = [
# `draw.py` imports `daytona` itself, so it is declared here rather than relied on as a
# transitive dependency. Same range `daytona-claude-toolsets` pins, so the two cannot disagree.
"daytona>=0.223.0,<0.224.0",
# Floor: the release that ships `anthropic.tools.computer` (computer_toolset_20260801).
"anthropic>=1.9.0",
# Floor: the first release that ships `anthropic.tools.computer` (computer_toolset_20260801).
"anthropic>=1.12.0",
]

[tool.setuptools]
Expand Down
14 changes: 14 additions & 0 deletions typescript/computer-use/claude-draws/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Required: Daytona API key, from https://app.daytona.io/dashboard/keys
DAYTONA_API_KEY=

# Required: Anthropic API key, from https://console.anthropic.com/settings/keys
ANTHROPIC_API_KEY=

# Optional: override the model the drawing loop uses
# MODEL=claude-sonnet-5-5

# Optional: cap the number of model/tool iterations (default: 120)
# MAX_TURNS=120

# Optional: save a final desktop screenshot after the model finishes
# OUTPUT_PATH=./claude-draws.png
15 changes: 15 additions & 0 deletions typescript/computer-use/claude-draws/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Dependencies
node_modules/

# Environment variables
.env

# Build output
dist/

# Logs
*.log

# OS generated files
.DS_Store
Thumbs.db
87 changes: 87 additions & 0 deletions typescript/computer-use/claude-draws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Claude Draws on Daytona

This example opens a canvas sketchpad in a Chromium window on a Daytona sandbox desktop and lets Claude draw in it with the mouse, through the Anthropic SDK's computer toolset.

The [Python version](../../../python/computer-use/claude-draws) of this example is also available.

## What you will build

- A sandbox desktop at 1280x800, created and deleted by `DaytonaComputer` from the [`@daytona/claude-toolsets`](https://www.npmjs.com/package/@daytona/claude-toolsets) package.
- A self-contained HTML sketchpad, `paint.html`, uploaded into the sandbox and opened in a visible Chromium window with no tab strip or omnibox.
- A drawing loop where `client.beta.messages.toolRunner` hands the computer toolset to the model, which takes screenshots, scrolls the color palette, picks swatches by name, and drags the mouse to draw.
- An unattended `confirm` callback that logs every action the model takes and approves it, because the desktop is a throwaway sandbox.

## Requirements

- Node.js 20 or higher on your machine.
- A Daytona account and API key.
- An Anthropic API key.

## Setup

```bash
git clone https://github.com/daytona/guides.git
cd guides/typescript/computer-use/claude-draws
npm install
cp .env.example .env # macOS/Linux
# Windows PowerShell: Copy-Item .env.example .env
# edit .env with your Daytona and Anthropic API keys
```

On macOS and Linux, load and export `.env` in the shell as shown below. PowerShell users can set the variables with `$env:` instead.

Environment variables:

- `DAYTONA_API_KEY`: required. Get it from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys).
- `ANTHROPIC_API_KEY`: required, for the model loop.
- `MODEL`: optional, the model the drawing loop uses. Defaults to `claude-sonnet-5-5`.
- `MAX_TURNS`: optional, maximum model/tool iterations. Defaults to `120`.
- `OUTPUT_PATH`: optional path for a final PNG screenshot after the model finishes.

## Workflow

1. Put your keys in `.env` and run the script:

```bash
set -a; source .env; set +a # macOS/Linux
npm run start
```

On Windows PowerShell, set them in the session instead:

```powershell
$env:DAYTONA_API_KEY = "<your-daytona-key>"
$env:ANTHROPIC_API_KEY = "<your-anthropic-key>"
npm run start
```

2. Watch the run in your terminal. Each line is one step of the loop:

```text
sandbox 7f3c…, screen 1280x800
sketchpad open at file:///tmp/claude-draws/paint.html; handing the desktop to the model
[confirm] screenshot {}
[screenshot] {}
[text] I can see the sketchpad. The palette along the bottom…
[confirm] scroll {"coordinate":[640,720],"scroll_direction":"right","scroll_amount":3}
```

3. The last line totals what the drawing loop cost, summed over every assistant turn:

```text
tokens: 412905 input, 6124 output
```

Screenshots dominate the input count: the model takes one after most actions, and each is billed as an image. Cache and server-tool counters are reported separately by the API and are not folded into these two numbers.

`src/draw.ts` creates the sandbox, starts its desktop, uploads `paint.html`, and launches Chromium through an async Daytona process session — a foreground GUI process never returns, so a synchronous command would block until the browser exits. It waits for Chromium's loopback debugging port to answer before handing the desktop to the model, then prints the model's text and tool calls until the task finishes. The sandbox is deleted when the run ends.

The task prompt is fixed, in `TASK` at the top of `src/draw.ts`. It targets colors by their visible label (`orange`, `teal`, `rose`), never by position, because the palette scrolls horizontally and swatch coordinates are not stable. It also keeps the model inside the drawing band, roughly 120 to 620 pixels from the top, where the floating docks do not intercept clicks. Edit `TASK` to draw something else, and keep both of those constraints.

Model-driven GUI runs are not deterministic: the same prompt will not produce the same picture twice, and the model can misread the screen or miss a swatch. Treat the result as a demo of the loop, not as a reproducible render.

## Files

- `src/draw.ts`: creates the sandbox, uploads and opens the sketchpad, and runs the model's drawing loop.
- `paint.html`: the self-contained sketchpad — canvas, brush sizes, a 38-color palette, and a caption box, with no external assets. It also exposes a small read-only `window.paint` inspection surface (pixel probes, the selected color, a log of the strokes drawn) so a run can be checked from the devtools console or a browser test instead of by eye.
- `.env.example`: environment variable template.
24 changes: 24 additions & 0 deletions typescript/computer-use/claude-draws/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "claude-draws",
"version": "0.1.0",
"private": true,
"description": "Let Claude draw on a canvas sketchpad in a Daytona sandbox desktop",
"type": "module",
"engines": {
"node": ">=20"
},
"scripts": {
"start": "tsx src/draw.ts",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@anthropic-ai/sdk": ">=0.132.0",
"@daytona/claude-toolsets": "^1.0.0",
"@daytona/sdk": "^0.223.0"
},
"devDependencies": {
"@types/node": "^24.0.0",
"tsx": "^4.20.0",
"typescript": "^5.9.0"
}
}
Loading
Loading