Meerkat is built as infrastructure, not as a single assistant application. The runtime should be easy to embed, strict about semantic ownership, and honest about which surface owns which behavior.Documentation Index
Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt
Use this file to discover all available pages before exploring further.
Principles
The Agent Loop Is A Primitive
The agent loop is provider-neutral. It owns messages, tool calls, streaming assembly, retryable/fatal error classification, and transcript updates. It does not own CLI policy, REST transport details, OAuth flows, or mob orchestration. That split lets the same loop run behind a CLI command, an RPC server, a Rust embedding, a mob member, or a browser runtime.Surfaces Are Adapters
CLI, REST, JSON-RPC, MCP, Python, TypeScript, and Web SDKs should expose the same underlying concepts with surface-appropriate ergonomics. A surface may own transport details, but it should not create a second semantic model for sessions, tools, auth, live channels, or mobs. Runtime-backed surfaces enter throughMeerkatMachine and consume
SessionRuntimeBindings. Standalone embeddings use
RuntimeBuildMode::StandaloneEphemeral explicitly.
One Semantic Fact, One Owner
State that changes what the system is needs a clear owner:| Fact | Owner |
|---|---|
| Session runtime admission and completion | MeerkatMachine |
| Mob roster, wiring, flow, and task state | MobMachine / meerkat-mob |
| Auth lease lifecycle | AuthMachine via runtime auth handles |
| Schedule and occurrence lifecycle | meerkat-schedule machines |
| Transcript content | SessionService and session stores |
| Provider request lowering | Provider crates |
Typed Boundaries Beat String Folklore
Public APIs should expose domain handles such assession_id,
AgentIdentity, blob_id, mob_id, and job_id. Internal raw identities and
provider-specific handles should stay behind typed wrappers unless they are part
of an explicit contract.
Provider capabilities come from catalogs and profiles, not from substring
matching. If a model supports realtime, images, web search, or compaction, that
fact should be represented in a typed profile.
Composition Over Hidden Defaults
Optional subsystems are injected through traits and handles:- provider clients
- tool dispatchers
- session stores
- memory stores
- hook engines
- skill engines
- comms runtimes
- runtime bindings
Rust Implementation Style
Keep Core I/O-Free
meerkat-core defines shared types and contracts. Network, filesystem, OAuth,
SQLite, MCP, and provider-specific behavior live in satellite crates.
This keeps core tests fast and lets embedders choose the pieces they need.
Use Newtypes For Domain Identity
Primitive strings and UUIDs should become semantic types at boundaries:Preserve Raw Provider Payloads Only Where They Are Truly Opaque
Tool arguments useBox<RawValue> so the runtime can pass provider-emitted JSON
to the dispatcher without reparsing or reserializing it. Provider metadata that
Meerkat understands should be typed instead of left as arbitrary
serde_json::Value.
Prefer Explicit Runtime Modes
Runtime-backed and standalone execution are different contracts:| Mode | Use |
|---|---|
SessionOwned(bindings) | Runtime-backed surfaces with machine-owned handles and recovery semantics. |
StandaloneEphemeral | Tests, browser runtime, and narrow embeddings without durable runtime services. |
Make Generated Surfaces Checkable
Schemas, SDK wrappers, machine specs, and generated kernels are checked into the repo and verified by gates. Generated files should be reproducible, and drift should fail locally before it reaches CI.Operational Bias
Meerkat favors boring, repeatable commands:MEERKAT_BUILDBUDDY=1.
