An agent harness for voice and text, written in Rust.
A speech model holds the conversation. Anything that needs a fact or an action goes to a backend agent, which runs the searches and tool calls and sends the answer back with its sources. The goal is an agent that answers fast and can show where every fact came from.
Proof of concept. Two of my other projects run on it. Sources
A support call, step by step
Made-up callEach step shows what the caller hears, what the backend is doing, and the events Tokebak logs for it. From step 3 on, you can cut in as the caller.
- Question
CallerCan I still return the hiking boots from order 2187?
AgentLet me check.
hand-offBackendGets the request. The speech model hands off anything that needs a fact, and it is told never to guess while it waits.
- voice.delegation
- Policy search
- Early update
- Order lookup
- Answer
Step 1 of 5: Question. Caller: Can I still return the hiking boots from order 2187? Agent: Let me check. Backend: Gets the request. The speech model hands off anything that needs a fact, and it is told never to guess while it waits.
How it’s built
The whole harness can run as one Rust process. Voice goes through OpenAI’s Live API over WebRTC, so audio travels from the browser to OpenAI and never through the server. The backend agent calls OpenAI’s Responses API or another configured model. Typed chat uses the same backend, tools and conversation as voice, so a caller can switch between talking and typing in the middle of a task.
- Agents
- Each agent is a folder:
bot.json,AGENT.mdfor the main prompt,tools.json, and aSKILL.mdper procedure that loads only when it applies. New versions are staged, then activated; a conversation keeps the version it started with. - Tools
- Written in JavaScript and run in QuickJS, with their inputs checked against JSON Schema. Writes keep a receipt through cancellation and restarts, so a retried request doesn’t repeat one. MCP servers can supply tools too.
- Knowledge
- SQLite full-text search per agent, with optional local embeddings. Pages are fetched and indexed ahead of time, never during a call.
- Citations
- Written answers cite passages and tool results by ID. A citation that doesn’t resolve shows as “Source unavailable” instead of getting a number.
- Trace
- Every model request, search, tool call and voice event goes into the trace, with token usage and cost estimates, and the trace exports as OpenTelemetry.
- Longer work
- Jobs that take a while can go to other agents over A2A or ACP, or to local subagents. Their results land in the conversation when they’re ready.
What runs on it
icitte, my voice, Markdown and Canvas workspace for projects and ideas, uses Tokebak for its conversations, voice and delegated tasks. FamilyOS, the private household system 3pew is part of, runs its assistant on it. Both pin a specific Tokebak commit rather than tracking the main branch.
The repository’s sample stores, with made-up customers and orders, are there to give it realistic work to do.
What isn’t built yet
A citation shows where a sentence came from. It doesn’t check that the sentence is right: an answer could say 60 days while citing the 30-day policy, and nothing in the runtime would flag it. Checking claims against their sources, and correcting the caller when something wrong was already said, is planned and not built. The hard part is running that check without making the caller wait for it.
There’s no speed result yet either. The lab times first token, first audio and the finished task separately, but nothing measured so far says how fast it is in production.
Sources
Last checked .
- Status
- Proof of concept. The README still calls the current build a local POC, and icitte and FamilyOS run pinned revisions of it. Checking claims against their sources isn't built, and there are no production speed measurements.
Tokebak READMEREADME at 6989d9a (private)
What it is, the voice and backend split, agent folders, JavaScript tools, SQLite search, citations, the trace, and the optional background workers.
Read, not run: no calls, benchmarks or audio tests were made for this page.
Direction, contracts and voice runtimedocs/direction.md, docs/contracts.md, ADR 0039 and src/runtime/live.rs at 6989d9a (private)
The goal, the hand-off, the cited early update, discarding an answer when the caller speaks again, and the event names in the demo.
Describes the code path. How the voice sounds and how long each step takes are not shown here.
icitte and FamilyOSicitte README at e32ae79; FamilyOS infra/tokebak at 6bf9a5c (both private)
Both run on a pinned Tokebak commit.
Shows that they depend on it, not how much either one is used.