Chidori V3 is out, and it's the biggest change in the project's history. Chidori began as a reactive runtime exploring how to build durable, debuggable agents. V3 distills those ideas into a smaller, sharper core: a single Rust binary, agents authored in plain TypeScript, and replay as the foundation for tests, debugging, resume, and human-in-the-loop workflows.
The headline change: agents are now TypeScript, not Starlark. Earlier versions leaned on Starlark because a side-effect-free Python dialect made determinism easy to guarantee. But it also meant a language no one wrote in production, no real type checking, and no imports. V3 keeps the determinism guarantees and moves them into the runtime, so you can write agents in the language — and the editor — your team already uses.
Agents are TypeScript
An agent is a .ts file that exports an async agent(input, chidori) function. The input is your typed payload; the return value is JSON. The injected chidori object is the only way the agent touches the outside world.
import type { Chidori } from "chidori";
export async function agent(
input: { document: string },
chidori: Chidori,
) {
const summary = await chidori.prompt(
"Summarize in 3 bullets:\n" + input.document,
{ type: "summary" },
);
const actionItems = await chidori.prompt(
"Extract action items:\n" + summary,
{ type: "actions" },
);
return { summary, actionItems };
}Native async control flow, typed inputs, local imports, and editor tooling — with no template DSL, no YAML schema, and no graph builder.
Determinism is now a runtime policy
Starlark gave us determinism for free because it had no clocks, no randomness, and no I/O. TypeScript has all three, so V3 enforces determinism in the runtime instead. Durable runs execute under a policy: a fixed Date, a seeded Math.random, no host clock, and every side effect routed through a chidori host function the runtime logs, caches, and replays.
The payoff is the same as it always was. Given the same inputs and the same cached host-call results, an agent reproduces its output with zero LLM calls. Save a session's call log to disk and replay it later for free — to debug a failure locally, to assert behavior in a test, or to resume after a crash.
Streaming prompt progress
Prompts can label their output streams with a type so UIs can separate incremental progress from final answers:
const status = await chidori.prompt("Say what work is starting", {
type: "progress",
});
const answer = await chidori.prompt("Write the final answer", {
type: "final",
});With --stream or POST /sessions/stream, prompt calls emit prompt_start, prompt_delta, and prompt_end events carrying stream_id, seq, and prompt_type. Labels propagate through chidori.parallel(...) branches and chidori.callAgent(...) sub-agents too.
Sandboxed code execution
Generated or untrusted code runs through dedicated sandbox helpers — chidori.execJs, chidori.execPython, and chidori.execWasm — with strict time and memory limits, never directly in the agent runtime. Let a model write and run code without letting it touch your box.
One binary, two SDKs
The runtime is still a single Rust binary. Drive it three ways: chidori run for one-shot CLI, chidori serve for an HTTP server with a session API, and event-driven webhooks through the same agent(event, chidori) entry point. Try chidori demo for an interactive picker of runnable examples.
Both the TypeScript and Python SDKs are pure HTTP clients that talk to a running chidori serve instance — no native bindings, and the Python SDK has no dependencies at all.
Migrating from Starlark
Agents need to be rewritten in TypeScript — there's no automatic translation. The mapping is mechanical, though: module-level config() becomes per-call options on chidori.prompt(...), parallel([...]) becomes chidori.parallel([...]) over functions, and agent(name, ...) becomes chidori.callAgent("name.ts", ...). Your old .star files are archived under examples/legacy-starlark/ for reference; tool discovery and sub-agent dispatch now load .ts only.
Upgrading
$ cargo install chidori --version 3.0 $ chidori demo $ chidori run agents/summarizer.ts --input document="..."
Full notes are on the GitHub release. As always, the fastest way to flag a regression is to drop a minimal .ts file plus its session JSON in Discord — replay means we can reproduce your run on our box without spending a token.
