Skip to main content

Architecture Overview

CIRI is a local-first, multi-agent orchestration system built on LangChain and LangGraph. Its core design principle is extensibility: every capability can be added, modified, or replaced at runtime without restarting.


Core Module Map

ModuleFileResponsibility
CLI Entrypointsrc/__main__.pyRich terminal UI, Prompt Toolkit REPL, interrupt rendering, startup sequence
Copilot Graphsrc/copilot.pyAssembles the LangGraph agent with all middlewares and subagents
Controllersrc/controller.pyThread management, graph execution, streaming
Backendsrc/backend.pyCiriBackend — subprocess execution, streaming output callbacks
Databasesrc/db.pyCopilotDatabase — SQLite threads table, thread CRUD
Serializerssrc/serializers.pyLLMConfig — multi-provider model initialization
Middlewaressrc/middlewares/Context injection, safety gates, dynamic capability loading
Subagentssrc/subagents/5 built-in specialists (web_researcher, builders, trainer)
Toolkitssrc/toolkit/Core tools: web crawler, script executor, human follow-up
Skillssrc/skills/17 built-in domain playbooks
Utilssrc/utils.pyApp dirs, browser detection, gitignore parsing, harness discovery

Startup Sequence


Middleware Stack

The middleware stack wraps every LLM call, injecting context and enforcing safety:

User Message
→ InjectNamesMiddleware (tool + skill + subagent registry)
→ MemoryMiddleware (workspace .md files)
→ SkillsMiddleware (domain playbooks)
→ SubAgentMiddleware (delegation routing)
→ ToolkitInjectionMiddleware (MCP server tools)
→ HumanInTheLoopMiddleware (approval gates)
→ TodoListMiddleware (task tracking)
→ AnthropicPromptCachingMiddleware (token caching, Anthropic only)
→ LLM Call
→ ToolRetryMiddleware (retry on failure, skip GraphInterrupt)
→ PatchToolCallsMiddleware (normalize cross-provider tool call format)
→ SummarizationMiddleware (compress long contexts)

Full Middleware Reference


Two-Level Core Harness

Skills, toolkits, subagents, and memory all follow a two-level discovery pattern:

~/.local/share/ciri/     ← Core harness (global, all projects)
└── skills/ toolkits/ subagents/ memory/

<project>/.ciri/ ← Project harness (this workspace only)
└── skills/ toolkits/ subagents/ memory/

Core harness always loads first. Project harness supplements or overrides on a name-basis.

Core Harness Architecture


Data Persistence

DataLocationTechnology
Conversation threads~/.ciri/data/ciri.dbSQLite (threads table)
LangGraph checkpointsSame databaseLangGraph AsyncSqliteSaver
LangGraph storeSame databaseAsyncSqliteStore
Workspace memory.ciri/memory/*.mdPlain markdown files
User settings.ciri/settings.jsonJSON
API keys~/.ciri/.env + OS keychaindotenv + keyring

The SQLite database supports resume-from-checkpoint — Ciri can continue any thread from exactly where it left off after a restart.

Thread persistence is handled by a local SQLite database.


Streaming Architecture

Ciri streams responses in real time using LangGraph's dual-mode streaming:

["updates", "messages"]
updates → node state changes + GraphInterrupt signals
messages → AIMessageChunk tokens (token-by-token text streaming)

The CopilotController.run() method yields these events to the CLI, which renders them via Rich as they arrive.


Design Goals

  1. Autonomy — High agency to plan and execute multi-step tasks across any domain
  2. Self-Evolution — Permanent capability expansion via Skills, Toolkits, and SubAgents
  3. Workspace-Awareness — Deep integration with local files, memory, and domain context
  4. Safety — Mandatory Human-in-the-Loop for consequential actions
  5. Extensibility — Every layer is pluggable: LLM provider, middleware, subagent, skill
  6. Local-First — No cloud dependency for core function; all data stored locally