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 / input effect 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_source and update_source are 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_docs tool.
  • Inline forms are pure host-side generative UI: the form tool 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 same chidori.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.