Architecture¶
Principles¶
Cognitia is built on Clean Architecture and SOLID:
- Protocol-driven: all contracts are
typing.Protocolwith@runtime_checkable. No abstract classes. - ISP: each Protocol contains no more than 5 methods.
- DIP: consumers depend on Protocols, not on concrete implementations.
- Immutable types: all domain objects are frozen dataclasses. Mutation through creating a new instance.
- No domain leak: the library knows nothing about the business application. Grep
freedom_agentacrosssrc/— 0 matches.
Layers¶
┌──────────────────────────────────────────────────────────┐
│ Business Application (your_app) │
│ Knows about cognitia. Implements concrete providers. │
├──────────────────────────────────────────────────────────┤
│ cognitia (library) │
│ bootstrap | context | runtime (claude/thin/cli/deep) │
│ policy | session | tools | memory | skills | routing │
│ memory_bank | orchestration | hooks | observability │
├──────────────────────────────────────────────────────────┤
│ External Dependencies (LLM API, DB, MCP) │
└──────────────────────────────────────────────────────────┘
Packages¶
| Package | Purpose | Dependencies |
|---|---|---|
bootstrap | Facade: CognitiaStack.create(), capabilities wiring | core |
context | System prompt assembly with token budget | core |
session | SessionManager, Rehydrator (history management) | memory |
memory | Message, fact, goal storage (InMemory, Postgres, SQLite) | core |
memory_bank | Long-term file-based memory (FS, DB) | core |
todo | Checklists / task tracking (InMemory, FS, DB) | core |
tools | Sandbox isolation, builtin tools, web, thinking | core |
orchestration | Planning, subagents, team mode, message bus | core |
policy | ToolPolicy (deny/allow), ToolSelector (budget) | core |
routing | KeywordRoleRouter (auto role-switching) | core |
skills | SkillRegistry, LoadedSkill, SkillSpec, McpServerSpec; YAML loader helper in skills.loader | core |
runtime | AgentRuntime (Claude SDK, ThinRuntime, CLI, DeepAgents) | extras |
resilience | Circuit breaker for external calls | core |
observability | Structured JSON logging | structlog |
hooks | Lifecycle hooks (pre/post turn) | core |
commands | CommandRegistry (slash-commands) | core |
Protocol Map¶
MessageStore ─────┐
FactStore ────────┤
GoalStore ────────┤── memory providers (InMemory, Postgres, SQLite)
SummaryStore ─────┤
SessionStateStore ┘
MemoryBankProvider ── memory_bank providers (FS, DB)
TodoProvider ──────── todo providers (InMemory, FS, DB)
SandboxProvider ───── sandbox providers (Local, E2B, Docker)
WebProvider ────────── web providers (Httpx)
AgentRuntime ──────── runtime (ClaudeCode, Thin, CLI, DeepAgents)
PlanStore ─────────── plan stores (InMemory)
PlannerMode ───────── planners (Thin, DeepAgents)
SubagentOrchestrator ── subagent orchestrators (Thin, DeepAgents, Claude)
TeamOrchestrator ────── team orchestrators (DeepAgents, Claude)
Dependency Direction¶
graph TD
A[Your Application] --> B[Agent Facade]
B --> C[14 Protocols]
C --> D[Implementations]
D --> E[External Dependencies]
style A fill:#f3e8ff,stroke:#7c3aed
style B fill:#ede9fe,stroke:#7c3aed
style C fill:#ddd6fe,stroke:#7c3aed
style D fill:#c4b5fd,stroke:#7c3aed
style E fill:#a78bfa,stroke:#7c3aed Dependencies always point inward (Infrastructure → Application → Domain). The domain layer has zero external dependencies. Your application code depends only on Protocols — never on concrete implementations.
Design Decisions¶
Why Protocols over ABC?¶
typing.Protocolsupports structural subtyping — no inheritance required- Implementations don't need to explicitly inherit from the protocol
- Enables duck typing with static type checking
@runtime_checkablefor runtime validation where needed
Why Frozen Dataclasses?¶
- Immutability prevents accidental state mutation
- Thread-safe by design
- Hashable — can be used in sets and as dict keys
- Forces explicit state transitions through new instance creation
Why ≤5 Methods per Protocol (ISP)?¶
- Small interfaces are easier to implement and test
- Reduces coupling between components
- Each protocol represents a single responsibility
- Mix-and-match: implement only the protocols you need