Repository navigation
feat(computer-use): add Claude draws guide - #25
Merged
Merged
Conversation
Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
There was a problem hiding this comment.
All reported issues were addressed across 6 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
The setup section offers PowerShell alternatives for venv activation and copying .env, but the workflow step then told everyone to `source .env`, which PowerShell has no command for and could not read anyway: .env is a POSIX shell file of `export` lines. Mark the sourcing step as macOS/Linux and add the $env: equivalents beside it, so the Windows path stays unbroken end to end. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
draw.py does `from daytona import Sandbox, SessionExecuteRequest`, but the project only listed daytona-toolsets, so the install worked purely because the toolset happens to pull daytona in. Declare it directly, pinned to the same >=0.223.0,<0.224.0 range daytona-toolsets requires so the two cannot disagree. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
…html py-modules ships draw.py alone, so a non-editable `pip install .` puts the module in site-packages without the paint.html it uploads at runtime, and the run died on a bare FileNotFoundError from read_bytes deep inside a live sandbox. The example is meant to run from its checkout — the README's setup is clone, cd, `pip install -e .`, `python draw.py` — so keep the module-only layout and make that contract explicit instead of inventing package data for a single module: say it in pyproject.toml, and check for the file at the top of main() so the non-editable case exits with a sentence that names the fix, before a sandbox is created for a run that cannot work. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
DaytonaComputer deletes the sandbox as this exception unwinds, so the log the message pointed at was gone before anyone could open it — the error named a path that no longer existed and told the reader nothing about why Chromium never came up. Read the tail of chromium.log while the sandbox is still alive and inline it in the RuntimeError. The read is best effort and bounded: a sandbox too broken to run tail reports that in place of the log rather than replacing the timeout with a second failure. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
…roke A second non-shift pointerdown overwrote state.pointerId and state.lastPoint, so the stroke already in progress was abandoned mid-gesture: its anchor jumped to the new pointer, and the pointer that still held the capture could no longer end anything, because endStroke only releases against the recorded pointerId. Reproduced with two real CDP touch pointers: the anchor moved from (300,250) to (900,550) and a second stroke op was opened. Return early when a stroke is already live, before any capture is taken, so the extra down owns nothing. Verified the anchor and the op log now hold steady and the first pointer stays the owner. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
Clear nulled lastPoint but left drawing true, so a Clear reached with the pointer still down — a second touch on the button, or the keyboard activating it mid-drag — left a live stroke with no anchor, and the next pointermove called segment(null, point) and threw "Cannot read properties of null". Truncating ops in the same handler also pulled out the entry endStroke later closes. Call endStroke() first so the stroke is closed and the capture released before the state is reset. Confirmed against the pre-fix page: two TypeErrors on the next move, none after. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
The getter froze only the object it returned, so lastPoint was handed out as the live anchor and ops.slice() copied the array but not the records in it. The documented read-only surface was neither read-only — writing state.lastPoint.x reached straight into the page's anchor — nor a snapshot, since a held copy drifted as drawing continued. Copy points and op records explicitly and freeze every level. Verified against the pre-fix page: poking a snapshot moved the real anchor to -12345; it is now inert, and a held snapshot stays put while the live state moves on. Signed-off-by: Mislav Ivanda <mislavivanda454@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
python/computer-use/claude-draws: Claude draws on a sketchpad in a Daytona sandbox desktop, using the Anthropic SDK's computer toolset through thedaytona-toolsetsdriver.draw.py: creates a sandbox, uploadspaint.htmland opens it in Chromium on the sandbox desktop. It then runs the Anthropic tool runner with a fixed drawing task and prints the token totals at the end.paint.html: a self-contained canvas sketchpad with no external assets. It has a horizontally scrolling, labelled palette, brush sizes, a caption field, and shift-click straight lines.pyproject.toml,.env.example, and a root README entry.The docs page for this guide is already live and links to this directory: https://www.daytona.io/docs/en/guides/claude/claude-draws-daytona-sandbox/
Dependencies
daytona-toolsetsis added in feat(daytona-claude-toolsets): add computer and browser toolset drivers integrations#84.pip install -e .resolves it from PyPI once that PR is released.Testing
Summary by cubic
Adds the Claude Draws guide: Claude draws on a canvas sketchpad opened in a Daytona sandbox desktop, driven through the Anthropic SDK's computer toolset via
daytona-toolsets.draw.pycreates the sandbox, uploads and openspaint.htmlin Chromium, runs the drawing loop, and prints token totals; it fails fast whenpaint.htmlis missing and inlines the Chromium log tail into the startup timeout error.paint.htmlis a self-contained sketchpad with a labelled, horizontally scrolling palette, brush sizes, a caption field, and shift-click straight lines.window.paintsnapshot.daytona-toolsets; it resolves from PyPI once feat(daytona-claude-toolsets): add computer and browser toolset drivers integrations#84 is released.daytonais now declared directly, pinned to the same range.$env:variables, not justsource .env.Written for commit e8a15e4. Summary will update on new commits.