v0.3.0§shipped 30 August 2026§MIT OR Apache-2.0crates.io · docs.rs · rust 1.98+
sans-IO engine
zero default features
A Rust framework for building agents137-page knowledge base · grounded in source

The agent loop,
under control.

loopctl runs the part of an agent that is not intelligence: send the conversation, read the stream, call the tools, shrink the history, catch the loops, survive the failures, stop on command. You bring the model connection and your tools — it brings the rest, without a panic in sight.

CoreSans-IO state machinea pure brain, serializable mid-run
ProvidersFive familiesOpenAI · Anthropic · Gemini · Bedrock · compatible
PostureNo panicszero default features · deny(unsafe_op_in_unsafe_fn) culture
II. The whole point

Twenty lines, and the loop is somebody else's problem.

A complete, working agent from examples/hello-cli.rs — it runs with a mock connection, no API key. Swap the mock for an OpenAI, Anthropic, Gemini, Bedrock, or Ollama client and nothing else changes.

BareLoop is the default engine. Its run() does the entire round-trip: send the conversation, read the stream, execute tool calls, feed results back, repeat until the model gives a final answer.

The result is a typed Run — the final text, turn count, tool calls, token usage. When things go wrong you get a typed error, never a panic; even a tool that panics is caught and reported as a message the model can read.

walk through it, line by line →
III. The big idea

A brain that decides, hands that act.

The engine splits in two at a strict border. The brain — LoopMachine — is pure data: it never touches the network. The hands — BareLoop — do whatever the brain asked, then report back, with middleware, hooks, observers and managers standing guard over everything they touch. Hover any band to see it light up.

One brain. Two hands. A full staff.how loopctl runs an agent — every moving piece, one pictureThe brainLoopMachine · pure data · no I/Oholds the conversationcounts turns, watches contextdecides the next steptestable with no mocksThe handsBareLoop · the driver · all I/Ostreams from the modelruns the tools you wrotereports back — never decidespausable — save the brain mid-runa step — “do this next”the result — what happenedthe guardrails — opt-in machinerymiddlewaretimeouts · limits · redactionhooksallow · block · askobserverswatch every eventmanagersdetection · fallback · reflectionthe world — bring any modelopenaianthropicgeminibedrockollamamoonshotz.aiyour owntool calls & eventsmodel streams — the world answersthe brain never touches the world — the hands never decide
  1. i.

    Test the brain with no mocks

    Pure data in, pure data out. To check “after three identical tool results, does it detect a loop?” you feed a machine results and read what it says — no fake network, no flaky tests.

  2. ii.

    Pause a run, resume it elsewhere

    The brain serializes. Take a running agent, turn it into JSON, store it anywhere, and put it into a fresh body later — on another machine if you like.

  3. iii.

    Swap providers behind the model's back

    The brain never learns who the model is. The hands speak to it through one small trait, so OpenAI becomes a local Ollama and nothing upstream notices.

IV. Safety, in the box

Long runs die of small failures. These are the antidotes.

Every system below is opt-in, composable, and documented to the threshold — each one has a page in the knowledge base explaining exactly when it fires and what it costs.

V. The five ideas

What the crate believes, in five lines.

  1. i.
    You own the decisions — the framework owns the mechanics. Nothing is on that you did not turn on; no model is picked for you.
  2. ii.
    Bring your own model — five provider families out of the box, OpenAI-compatible profiles for the rest, or one trait — ApiClient — for your own.
  3. iii.
    Tools are plain Rust — a name, a description, a schema, an async function — or let #[derive(Tool)] write the scaffolding.
  4. iv.
    No panics. Ever. — the crate builds with panic = "deny"; a crashing tool becomes an error message the model can read and react to.
  5. v.
    Pay only for what you use — zero default features. Streaming, hooks, MCP, each provider — every one is an opt-in flag.
bring your own model

OpenAI ·Anthropic ·Google Gemini ·AWS Bedrock ·Azure OpenAI ·Ollama ·DeepSeek ·Moonshot ·xAI Grok ·Z.ai ·or implement one trait — ApiClient — and bring your own.