Playground
A live agent in this tab — journaled, rewindable, branchable, able to rewrite its own code, with every version kept as history.
Loading the wasm engine…
It runs on the wasm engine in this tab — every turn journaled, rewindable, branchable.
Under the hood
- This chat is a chidori agent — the source below — executed by the pure-Rust engine compiled to WebAssembly, entirely in this tab.
- Every
chidori.prompt / tool / inputeffect is journaled: the conversation auto-saves each turn, survives a reload, and Replay offline repaints it — cards and all — with zero live calls. - Rewind and branch (the controls under any message you sent) are journal operations: rewinding truncates the effect journal just before that turn's
chidori.input()and replays the shorter journal; branching stashes the full blob first, so every timeline is just another durable blob you can switch back to. - The agent can rewrite itself:
read_sourceandupdate_sourceare ordinary tools — and the editor below edits the same live program by hand. An accepted edit is validated by replaying this conversation's journal against the new code, then hot-swapped in (modify-and-resume: same journal, new program) — an edit that would change already-journaled effect calls is rejected as divergence. - Every version that runs is history: each accepted rewrite becomes a commit in the implementation history below — a content-addressed, git-like chain recorded alongside the journal, each version anchored to the turns that executed under it. The same mechanism records every run's source history on disk (
chidori history). - Docs answers are grounded: these docs are indexed at build time, retrieved into the model's context, and exposed as the
search_docstool. - Inline forms are pure host-side generative UI: the
formtool takes a JSON Schema, the journaled result is rendered by react-jsonschema-form (so replays repaint the form), and submitting sends/form <id> {…}through the samechidori.input()as any message — the runtime itself knows nothing about forms, and rewinding past a submission makes the form fillable again.
agent.ts — the program running this chat, editable
type Decision = { tool?: string; args?: unknown; reply?: string };
type Message = { role: string; content: string };
const transcript: Message[] = [];
function emit(event: unknown): void {
console.log(JSON.stringify(event));
}
async function turn(userText: string): Promise<void> {
transcript.push({ role: 'user', content: userText });
emit({ kind: 'user', text: userText });
for (let hop = 0; hop < 6; hop++) {
// The host answers with one JSON decision: {tool, args} or {reply}.
const raw = await chidori.prompt(JSON.stringify(transcript), {
protocol: 'chat-v1',
});
let decision: Decision;
try {
decision = JSON.parse(String(raw)) as Decision;
} catch (err) {
decision = { reply: String(raw) };
}
if (decision.tool) {
let result: unknown;
try {
result = await chidori.tool(decision.tool, decision.args);
} catch (err) {
result = { error: String(err) };
}
emit({ kind: 'tool', name: decision.tool, args: decision.args, result });
transcript.push({
role: 'tool',
content: JSON.stringify({ name: decision.tool, result }),
});
continue;
}
const reply = decision.reply ? String(decision.reply) : '\u2026';
emit({ kind: 'assistant', text: reply });
transcript.push({ role: 'assistant', content: reply });
return;
}
const bail = 'I hit the tool-call limit for this turn \u2014 ask me to continue.';
emit({ kind: 'assistant', text: bail });
transcript.push({ role: 'assistant', content: bail });
}
async function main(): Promise<void> {
for (;;) {
const text = await chidori.input('message');
await turn(String(text));
}
}
main();
Implementation history
The journal records what this chat did; this chain records what the agent was — every source version that ran, as git-like commits anchored to the turns executed under each. Ask the agent to rewrite its code (or edit it under the hood) to grow the chain; diff any two versions; restore an old one and the journal replays against it. Timelines (⑂) are branch heads over this one shared history — the same model chidori history shows for a persisted run.
No versions recorded yet — send a message to record the starting implementation, then ask the agent to rewrite its code (or edit it under the hood) to grow the chain.