Content-routed coordination
for agent systems

Radia coordinates agents through immutable JSON records in a shared space. Workers declare which records they handle and claim matching work under renewable leases. The runtime provides durable delivery, content-scoped authorization and lineage without hard-coded agent-to-agent routing.

Work moves through a shared space as matching records An intake process publishes a scanned document without naming a worker. An OCR worker claims it by matching its contents and publishes extracted text back into the space. A summarizer then claims that result and returns a summary record. shared space records stay; claims move intake knows no workers 1 document { type: "scan", file: "page.png" } leased put OCR worker type = scan match + take 2 extracted_text { text: "…", parent: document } available ack result summarizer kind = extracted_text match 3 summary { text: "…", parent: extracted_text } new record every result returns to the same routing model
Publishers write records without choosing a destination. Workers claim what matches their declared patterns, and each result returns as another record that later workers can discover.
$ deno task dev
Starts a space and a web console on 127.0.0.1:7788. Nothing to install, no database to set up. Or skip even that: the playground boots the same runtime in this browser tab, storage and console included.

Routing without agent-to-agent wiring

Direct calls make each participant depend on the identity and interface of the next one. Adding a capability can require changes to every caller that might use it. This becomes difficult when agents are deployed independently or owned by different teams.

Radia stores work as records. A worker registers a pattern such as { kind: "document", match: { type: "scan" } } and claims records that match it. Publishers do not hold references to workers or choose a destination.

Starting a worker makes its pattern available to the space. If no eligible worker is running, matching records remain available until one can claim them.

Authorization by record content

A summarizer may be allowed to process public filings but barred from confidential ones. The restriction should hold for every worker implementation, including a faulty or compromised one.

A grant identifies a principal, an operation and a record kind. An optional pattern restricts the grant to records whose contents match it.

this agent can only ever claim public documents
{ "principal": "agent:summarizer",
  "kind": "document",
  "operations": ["take", "query"],
  "pattern": { "classification": "public" } }

The runtime applies the grant while selecting a claim. The worker receives only records that satisfy both its request and its grant.

This makes the payload part of the authorization decision, rather than leaving the check to agent code. Read about authorization →

Immutable records, mutable claim state

A completed worker does not update its input. It writes a result record that names the input as a parent. The original document remains unchanged.

the record written once what kind of thing it is its contents, as JSON a hash of those contents which records it came from who wrote it, and when its claim state the only moving part waiting, taken, or done who holds it right now until when how many attempts so far when it becomes claimable again
Immutable content preserves history. The runtime envelope can move through available, leased and consumed states without changing the record itself.

A result is another routable record. Downstream workers match it in the same way they match an initial request, and parent links preserve how each result was produced.

Follow one document through the whole system →

Getting started

One command starts a space with storage, a web console and a credential already provisioned. From there you can drive it from the shell.

post some work, claim it, answer it
$ deno task dev                     # space + console, in one process
$ deno task compile                 # -> ./radia; put it on your PATH
$ radia put document '{"type":"pdf","classification":"public"}'
$ radia take document --lease 30 --json > claim.json
$ radia ack - --result-kind summary --result '{"text":"..."}' < claim.json

Run it from the checkout: compile it as above, or deno run -A src/main.ts <verb> directly. The npm and pip packaging is built but unpublished, so nothing installs radia for you yet and npx radia does not work today.

The CLI, TypeScript and Python SDKs, web console and MCP adapter all use the public /v0 API. None has a private runtime interface.

A worker declares its patterns and supplies a handler:

summarizer.ts
import { RadiaClient } from "radia";
import { agentLoop } from "radia/loop";

await agentLoop(new RadiaClient(url, { token }), {
  name: "summarizer",
  patterns: [{ kind: "document", match: { type: "pdf" } }],
  handle: async (rec) => ({
    kind: "summary",
    body: { text: await summarize(rec.body) },
  }),
});

The loop claims matching work, renews the lease while the handler runs and settles the claim with the returned record. If the process exits before settlement, the lease expires and the record becomes claimable again.

What is built

Radia currently runs on SQLite and PGlite for embedded use and PostgreSQL for multiple runtime instances. The same storage contract suite covers all three adapters.

Coordination

Posting, querying, claiming and settling records, with fenced leases, retries, idempotency and dead-letter handling.

Authorization

Kind- and pattern-scoped grants, short-lived run credentials, OIDC sign-in, delegation and labels that propagate with derived data. Authorization →

Large payloads

Content-addressed artifacts for images and files, with optional encryption, retention and payload erasure.

Seeing what happened

An event log, lineage and graph queries, diagnostics, mined flows, a web console, a tamper-evident event chain and OTLP export. Inspection →

Workspaces

Versioned multi-file trees that agents can write, execute in a jail, serve to a browser and export as Git repositories. Workspaces are an extension over the public API. Workspaces →

Radia is not production-ready and has not been independently adopted. The packages are unpublished, several production-hardening tasks remain, and current use starts from a source checkout.