In a conversation, the second request is often a small change: “make it a bar chart”, “add Q4”. Writing the whole screen again costs tokens and time. In edit mode the model writes only what changes.
The four edits
| Edit | Written as | Meaning |
|---|---|---|
| Replace | k3 = Stat("MRR", "$415k") |
A statement with an existing id replaces it |
| Patch | k3.value = "$415k" |
Set one prop, by its schema name |
| Append | kpis += k5 |
Add a child, or a table row |
| Delete | k2 = null |
Remove a statement |
A patch is the cheapest: changing one value costs about 9 tokens instead of re-emitting the statement.
trend.type = bar
rev += |Oct|468000
note = Callout("October is a projection.", tone:info)
root += noteHow to run an edit turn
Give the model the current program
toEditSource prints the program in a canonical form in which every part has an id, so everything can be addressed.
import { library, prompt } from "@gistui/catalog";
import { toEditSource } from "@gistui/core";
const current = toEditSource(shownProgram, library);
const system = prompt({ mode: "edit" }).text;
const messages = [
{ role: "user", content: `Current UI:\n${current}\n\nRequest: make the chart a bar chart` },
];Render the edit as it streams
createEditStream is a stream seeded with the current program, so the change shows live.
import { createEditStream } from "@gistui/core";
const stream = createEditStream(shownProgram, library);
for await (const chunk of modelText) stream.push(chunk);
stream.end();Keep the merged program
merge applies an edit and returns the new program, canonical and with unused statements removed. Store it as the new current program.
import { merge } from "@gistui/core";
const { source, errors } = merge(shownProgram, editText, library);Rules worth knowing
- The last definition of an id wins.
- A patch addresses a prop by name, even one that was written positionally.
- A patch or append whose target does not exist is ignored and reported as
patch-target-missing. - Re-declaring a
$statevariable in an edit keeps its current value on screen. - Statements that nothing uses after an edit are dropped from the merged program.
The same mechanism powers repair
When repairStream fixes a finished answer on the server, it appends the repairs as edits to the end of the stream. The renderer applies them like any other edit, so only what changed re-renders. See Autofix and repair.