Playground
A chidori agent running entirely in this tab — ask it about chidori, or hand it a tool. Reload mid-conversation and it resumes; every effect is journaled.
Loading the wasm engine…
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. - Docs answers are grounded: these docs are indexed at build time, retrieved into the model's context, and exposed as the
search_docstool.
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();