Skip to main content

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.

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.

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 through MeerkatMachine 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:
FactOwner
Session runtime admission and completionMeerkatMachine
Mob roster, wiring, flow, and task stateMobMachine / meerkat-mob
Auth lease lifecycleAuthMachine via runtime auth handles
Schedule and occurrence lifecyclemeerkat-schedule machines
Transcript contentSessionService and session stores
Provider request loweringProvider crates
Derived projections are allowed, but they must be rebuildable from the owner.

Typed Boundaries Beat String Folklore

Public APIs should expose domain handles such as session_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
When a subsystem is absent, the behavior should degrade explicitly. Hidden global state and implicit runtime reconstruction make recovery and testing harder.

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:
pub struct SessionId(uuid::Uuid);
pub struct AgentIdentity(String);
pub struct BlobId(uuid::Uuid);
This keeps member identity, runtime binding identity, sessions, blobs, and provider handles from being mixed accidentally.

Preserve Raw Provider Payloads Only Where They Are Truly Opaque

Tool arguments use Box<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:
ModeUse
SessionOwned(bindings)Runtime-backed surfaces with machine-owned handles and recovery semantics.
StandaloneEphemeralTests, browser runtime, and narrow embeddings without durable runtime services.
Do not silently fall back from runtime-backed behavior to standalone behavior.

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:
make check
make lint
make test
make agent-gate
Cargo remains the default backend. BuildBuddy accelerates the same lanes when explicitly enabled with MEERKAT_BUILDBUDDY=1.

See Also