● OPEN SOURCEChidori + Tael · Rust binaries · Apache 2.0

Deterministic AI agents
you can replay,
trace, and ship.

Chidori is a Rust agent runtime. You write agents in plain TypeScript, so every LLM call, tool invocation, and HTTP request runs through a host function the runtime logs, caches, and replays. Save a session once; replay it later, for free.

0
tokens on replay
1
binary to install
OTLP
traces out of the box
$ chidori run agents/researcher.ts
OTLP → tael
● live span graphnodes: 0edges: 0
0.0s
12.6s
session: 7f3a…9c2espans: 0 · OTLP :4317replay cost: $0.00
chidori.prompt() chidori.tool() chidori.callAgent() chidori.execWasm() chidori.parallel() chidori.input() chidori.template() chidori.memory() chidori.checkpoint() replay() serve() span.emit() chidori.prompt() chidori.tool() chidori.callAgent() chidori.execWasm() chidori.parallel() chidori.input() chidori.template() chidori.memory() chidori.checkpoint() replay() serve() span.emit()
§ chidori — the framework

Agents you can reproduce.

Most agent frameworks ship a DSL or a YAML schema. Chidori runs ordinary TypeScript, with a fixed set of host functions on the chidori object for every side effect. Because each call is logged and replayed from a checkpoint, any past run reproduces its output for free.

01stable

Agents are TypeScript

Agents are plain async TypeScript: native control flow, typed inputs, imports, and editor tooling. No YAML, no template DSL, no graph builder.

export async function agent(
  input: { question: string },
  chidori: Chidori,
) {
  const qs = await chidori.prompt(
    "3 queries for: " + input.question,
    { type: "json" },
  );
  return chidori.parallel(
    qs.map((q) => () => chidori.tool("search", { q })),
  );
}
02stable

Deterministic execution

Durable runs use fixed Date and seeded Math.random. Every side effect goes through a host function on the chidori object the runtime logs, caches, and replays.

// every side effect is a host call:
//   chidori.prompt(), chidori.tool(),
//   chidori.parallel(), chidori.input()
//
// each logged with a seq number,
// inputs, and result — so replay
// returns cached results, no LLM spend.
03stable

Zero-cost checkpoint & replay

Save a session's call log to disk and replay it later for identical output — zero LLM spend. Debug production locally without burning a token.

$ chidori run agent.ts \
    --replay session.json

  [cache] prompt  hit
  [cache] tool    hit
  [cache] prompt  hit
  → identical output · $0.00
04stable

Human-in-the-loop

chidori.input() pauses execution and persists the run. When the human responds, the agent resumes from the saved state at the point it paused — no special state machine.

const answer = await chidori.input(
  "Approve resume from 0x4a1?",
  { type: "approval", choices: ["yes", "no"] },
);

if (answer !== "yes") {
  return { status: "rejected" };
}
05stable

Sub-agents as a call

Any .ts file is an agent, and any agent can call another with chidori.callAgent(). Sub-agents share the session and call log, and stream their own labelled spans — compose specialists without inventing a DAG.

const draft = await chidori.callAgent(
  "writer.ts",
  { topic: question, notes: results },
);
const review = await chidori.callAgent(
  "critic.ts",
  { draft, bar: "rigorous" },
);
return { draft, review };
06stable

Sandboxed code execution

chidori.execJs / execPython / execWasm run agent-written code inside a sandbox with strict time and memory limits. Let an LLM write and run code without letting it touch your box.

// agent writes + runs code safely
const result = await chidori.execPython(
  await chidori.prompt("Write python to…"),
  { timeoutMs: 2000 },
);
// sandboxed · no net · no fs
07stable

OTEL, out of the box

Every host function call — prompt, tool, callAgent, exec — is emitted as an OpenTelemetry span. Point it at Tael, Jaeger, Tempo, or Honeycomb by setting one env var.

OTEL_EXPORTER_OTLP_ENDPOINT=\
  http://localhost:4317

# every prompt/tool/agent/exec
# arrives as a span.
# zero extra config.
§ how it works

Write one function. Run it. Replay it.

01

Write one function

An agent is a .ts file that exports async function agent(input, chidori). The input is your typed payload; the return value is JSON output. Prompts, tools, parallel fan-out, and human input are ordinary calls on the chidori object.

// agents/researcher.ts
import type { Chidori } from "chidori";

export async function agent(
  input: { question: string },
  chidori: Chidori,
) {
  const queries = await chidori.prompt(
    "3 search queries for: " + input.question,
    { type: "json" },
  );
  const answer = await chidori.parallel(
    queries.map((q) => () =>
      chidori.tool("web_search", { query: q })),
  );
  return { answer, queries };
}
02

Run it or serve it

chidori run executes once from the CLI. chidori serve turns the same file into an HTTP server — every incoming request becomes an event passed to agent(event, chidori). Webhooks, chat, alerts — same primitive.

$ chidori run agents/researcher.ts \
    --input question="OTel SDK choice"

$ chidori serve agents/researcher.ts --port 8080

$ curl -X POST localhost:8080/sessions \
    -d '{"input": {"question": "..."}}'
03

Replay for free, forever

Every run produces a session log — an ordered record of every host function call with its inputs and result. Feed it back in and the agent re-runs with cached results. Zero tokens, identical output.

# save a live session
$ curl localhost:8080/sessions/<id>/checkpoint \
    > session.json

# replay later — zero LLM spend
$ curl -X POST localhost:8080/sessions \
    -d @session.json

→ identical output · cost: $0.00
§ tael — the observability plane

Telemetry an agent can read.

No dashboards. No browsers. Tael ingests OpenTelemetry over OTLP, stores it in an embedded columnar database, and returns JSON by default — so your agents can query, monitor, and annotate production telemetry themselves.

OTLP ingestion
Accepts traces from any OpenTelemetry-instrumented app. Standard protocol, no proprietary SDKs.
CLI-first querying
Every command returns structured JSON. Pipe it, diff it, feed it to an agent. Human tables on demand.
Cross-signal correlation
Pull every span, log, and metric for a trace ID with one command. No stitching required.
Anomaly detection
Surface services with error-rate or latency regressions against a rolling baseline.
Trace annotations
Agents leave comments on traces — a durable audit trail of what was investigated and why.
Interactive TUI
Live trace feed and waterfall visualization, all inside the terminal.
$ tael anomalies --since 1h --format json | jq
[
  {
    "service": "researcher-agent",
    "metric": "latency.p95",
    "baseline_ms": 1180,
    "current_ms": 4210,
    "severity": "high",
    "first_seen": "14:02:31Z",
    "trace_ids": ["0x4a1c2e", "0x4a2f11"]
  },
  {
    "service": "writer-agent",
    "metric": "errors.rate",
    "baseline": 0.003,
    "current": 0.041,
    "severity": "medium",
    "sample_trace": "0x5b8a03"
  }
]
$ tael correlate --trace 0x4a1c2e
→ 14 spans · 3 logs · 2 metric series
→ hand off to chidori agent? [y/N]
§ blog

From the engineering log.

view all →
§ thesis

Tools for human + AI work.

You already have the hardest part — the goal, the context, the judgment. The bottleneck is how much you can hold at once. Agents extend your reach: delegate to AI that remembers its work, recovers from failures, and tells you exactly what it did.

Chidori and Tael are the building blocks. Open source. Deterministic. Built to be boring, so the agents running on top of them can afford to be interesting.