How it’s built · Iterative code generation
Code Morph Lab
A model that writes code once and stops is guessing. Code Morph Lab makes it run what it wrote, read what went wrong and try again, and it shows every step: each tool call, each diff, each run. The loop works in HTML, rendered in a sandbox, and in Python, run in the browser through WebAssembly.
- 6workspace tools the model can call
- 2runtimes: HTML and Python (Pyodide)
- 4error kinds, classified before retrying
- 0backend of its own: it runs in the browser
One iteration
- GoalA plain-language description, or code handed over from another app.
- EditThe model lists, reads, writes, edits and deletes files in its workspace.
- Run
run_programrenders the page or runs the Python, capturing console output and uncaught errors. - ClassifyThe failure is sorted into syntax, runtime, timeout or missing file, with a file and line where one can be found.
- RetryA compact report goes back to the model, until the run is clean or the iteration cap is reached.
Design decisions
The loop knows nothing about the UI
The morph loop is pure orchestration: the model call and the runner are passed in. The same loop drives a real model in the app and a scripted stub in the tests.
Feedback the model can use
Raw stderr is noisy. The report leads with the error kind and location, then the tail of stderr and stdout, trimmed to a budget, so a long traceback does not crowd out the code.
Watch it think
Assistant text and tool-call arguments stream into the workspace while the model is still responding, so a stalled or confused generation is visible straight away.
Sessions are kept and can be forked
Every run is saved with its iterations and file snapshots. A session that nearly worked can be forked with a refined goal instead of starting again, or exported as JSON.
Working with the other apps
Code Morph Lab is where generations go to be improved. A page from the Prompt Gallery or an image from the SVG bench can be sent here with its original prompt kept separate from the requested change. When the session finishes, Send back returns the result, and the Prompt Gallery files it as a new variant beside the original. Nothing is overwritten.
Problems worth solving
- Specific before general. A missing import can report both “file not found” and a syntax error. The classifier checks for missing files first, so the model is told the actually useful fact.
- Telling the model when to stop. Models will happily loop on an error they cannot fix. The instructions require the model to explain and stop instead, and the iteration cap backs that up.
- Slow first runs. Pyodide takes a few seconds to start from cold, so Python runs get a longer timeout than HTML runs, and a cold start is not mistaken for a hang.