# purrpod/purrcat architecture

> Architecture diagram of the GitHub repository purrpod/purrcat, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/purrpod/purrcat
- Repository: https://github.com/purrpod/purrcat

## Overview

PurrCat is a local-first personal AI agent framework with desktop, web, and terminal interaction surfaces. A user enters chat or a task; the agent manages a session, executes model- and tool-backed work, and can retain or retrieve memories. The product also supports editable DAG workflows, proactive sensors, MCP and skill extensions, and agent evolution. The README documents these capabilities; sampled source confirms session management, model retry and key allocation, storage engines, sensor subprocesses, and desktop hosting. Some API-to-runtime wiring is not sampled, so uncertain links are omitted.

Main entry points: [`src/agent/agent.py`](https://github.com/purrpod/purrcat/blob/main/src/agent/agent.py) (Agent loop), [`src/server/api`](https://github.com/purrpod/purrcat/tree/main/src/server/api) (API routes), [`src/agent/manager.py`](https://github.com/purrpod/purrcat/blob/main/src/agent/manager.py) (Session manager), [`src/memory/purrmemo/core/memory_worker/worker_agent.py`](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/memory_worker/worker_agent.py) (Memory digestion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interaction["User interaction"]
  node_desktop["Desktop shell<br/>[main.js]"]
  node_webui["Web UI<br/>[App.tsx]"]
  node_api["API routes"]
end

subgraph group_runtime["Agent runtime"]
  node_entry["Python entry<br/>[main.py]"]
  node_sessions["Session manager<br/>[manager.py]"]
  node_agent["Agent loop<br/>[agent.py]"]
  node_sessionstore[("Session history<br/>[session_store.py]")]
  node_model["Model facade<br/>[model.py]"]
  node_keymanager["Key scheduling<br/>[key_manager.py]"]
  node_llm["LLM client<br/>[llm_client.py]"]
end

subgraph group_capabilities["Agent capabilities"]
  node_harness["Workflow engine<br/>[process.py]"]
  node_nodes["Workflow nodes"]
  node_toolset["Agent tools"]
end

subgraph group_memory["Memory system"]
  node_memoryclient["PurrMemo client<br/>[client.py]"]
  node_memoryworker["Memory digestion<br/>[worker_agent.py]"]
  node_eventstore[("Episodic store<br/>[event_engine.py]")]
  node_vectorstore[("Vector store<br/>[vector_engine.py]")]
  node_graphstore[("Knowledge graph<br/>[graph_engine.py]")]
end

subgraph group_extensions["Extensions and perception"]
  node_sensors["Sensor manager<br/>[manager.py]"]
  node_mcp["MCP sessions<br/>[session_manager.py]"]
  node_evolve["Agent evolution"]
  node_paradigm["Execution paradigms<br/>[paradigm_api.py]"]
end

node_user(("User"))
node_provider(("Model provider"))
node_sensorproc(("Sensor subprocesses"))

node_user -->|"uses"| node_desktop
node_user -->|"uses"| node_webui
node_user -.->|"requests"| node_api
node_desktop -->|"hosts backend"| node_api
node_webui -.->|"calls"| node_api
node_api -.->|"serves"| node_entry
node_entry -.->|"starts"| node_sessions
node_sessions -->|"creates"| node_agent
node_sessions -->|"loads and saves"| node_sessionstore
node_agent -->|"requests completion"| node_model
node_agent -->|"dispatches tools"| node_toolset
node_agent -.->|"runs workflows"| node_harness
node_harness -->|"executes"| node_nodes
node_model -.->|"allocates keys"| node_keymanager
node_model -.->|"calls"| node_llm
node_llm -->|"sends requests"| node_provider
node_agent -.->|"uses memory"| node_memoryclient
node_memoryclient -.->|"digests memories"| node_memoryworker
node_memoryworker -.->|"records events"| node_eventstore
node_memoryworker -.->|"stores embeddings"| node_vectorstore
node_memoryworker -.->|"updates relations"| node_graphstore
node_sensors -->|"launches and monitors"| node_sensorproc
node_sensorproc -->|"sends JSON-RPC"| node_sensors
node_toolset -.->|"calls MCP tools"| node_mcp
node_api -.->|"exposes evolution"| node_evolve
node_sessions -->|"resolves paradigm"| node_paradigm

click node_desktop "https://github.com/purrpod/purrcat/blob/main/electron/main.js"
click node_webui "https://github.com/purrpod/purrcat/blob/main/ui/src/App.tsx"
click node_api "https://github.com/purrpod/purrcat/tree/main/src/server/api"
click node_entry "https://github.com/purrpod/purrcat/blob/main/main.py"
click node_sessions "https://github.com/purrpod/purrcat/blob/main/src/agent/manager.py"
click node_agent "https://github.com/purrpod/purrcat/blob/main/src/agent/agent.py"
click node_sessionstore "https://github.com/purrpod/purrcat/blob/main/src/agent/session_store.py"
click node_harness "https://github.com/purrpod/purrcat/blob/main/src/harness/process.py"
click node_nodes "https://github.com/purrpod/purrcat/tree/main/src/harness/node"
click node_toolset "https://github.com/purrpod/purrcat/tree/main/src/tool"
click node_model "https://github.com/purrpod/purrcat/blob/main/src/model/facade/model.py"
click node_keymanager "https://github.com/purrpod/purrcat/blob/main/src/model/manager/key_manager.py"
click node_llm "https://github.com/purrpod/purrcat/blob/main/src/model/core/llm_client.py"
click node_memoryclient "https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/client.py"
click node_memoryworker "https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/memory_worker/worker_agent.py"
click node_eventstore "https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/event_engine.py"
click node_vectorstore "https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/vector_engine.py"
click node_graphstore "https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/graph_engine.py"
click node_sensors "https://github.com/purrpod/purrcat/blob/main/src/sensor/manager.py"
click node_mcp "https://github.com/purrpod/purrcat/blob/main/src/tool/callmcp/session_manager.py"
click node_evolve "https://github.com/purrpod/purrcat/tree/main/src/evolve"
click node_paradigm "https://github.com/purrpod/purrcat/blob/main/src/utils/paradigm_api.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_desktop,node_webui,node_api,node_user toneBlue
class node_entry,node_sessions,node_agent,node_sessionstore,node_model,node_keymanager,node_llm toneAmber
class node_harness,node_nodes,node_toolset toneMint
class node_memoryclient,node_memoryworker,node_eventstore,node_vectorstore,node_graphstore toneRose
class node_sensors,node_mcp,node_evolve,node_paradigm,node_provider,node_sensorproc toneIndigo
```

## Components

### User interaction

- [Desktop shell](https://github.com/purrpod/purrcat/blob/main/electron/main.js): `electron/main.js`
- [Web UI](https://github.com/purrpod/purrcat/blob/main/ui/src/App.tsx): `ui/src/App.tsx`
- [API routes](https://github.com/purrpod/purrcat/tree/main/src/server/api): `src/server/api`

### Agent runtime

- [Python entry](https://github.com/purrpod/purrcat/blob/main/main.py): `main.py`
- [Session manager](https://github.com/purrpod/purrcat/blob/main/src/agent/manager.py): `src/agent/manager.py`
- [Agent loop](https://github.com/purrpod/purrcat/blob/main/src/agent/agent.py): `src/agent/agent.py`
- [Session history](https://github.com/purrpod/purrcat/blob/main/src/agent/session_store.py): `src/agent/session_store.py`
- [Model facade](https://github.com/purrpod/purrcat/blob/main/src/model/facade/model.py): `src/model/facade/model.py`
- [Key scheduling](https://github.com/purrpod/purrcat/blob/main/src/model/manager/key_manager.py): `src/model/manager/key_manager.py`
- [LLM client](https://github.com/purrpod/purrcat/blob/main/src/model/core/llm_client.py): `src/model/core/llm_client.py`

### Agent capabilities

- [Workflow engine](https://github.com/purrpod/purrcat/blob/main/src/harness/process.py): `src/harness/process.py`
- [Workflow nodes](https://github.com/purrpod/purrcat/tree/main/src/harness/node): `src/harness/node`
- [Agent tools](https://github.com/purrpod/purrcat/tree/main/src/tool): `src/tool`

### Memory system

- [PurrMemo client](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/client.py): `src/memory/purrmemo/client.py`
- [Memory digestion](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/memory_worker/worker_agent.py): `src/memory/purrmemo/core/memory_worker/worker_agent.py`
- [Episodic store](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/event_engine.py): `src/memory/purrmemo/core/storage/event_engine.py`
- [Vector store](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/vector_engine.py): `src/memory/purrmemo/core/storage/vector_engine.py`
- [Knowledge graph](https://github.com/purrpod/purrcat/blob/main/src/memory/purrmemo/core/storage/graph_engine.py): `src/memory/purrmemo/core/storage/graph_engine.py`

### Extensions and perception

- [Sensor manager](https://github.com/purrpod/purrcat/blob/main/src/sensor/manager.py): `src/sensor/manager.py`
- [MCP sessions](https://github.com/purrpod/purrcat/blob/main/src/tool/callmcp/session_manager.py): `src/tool/callmcp/session_manager.py`
- [Agent evolution](https://github.com/purrpod/purrcat/tree/main/src/evolve): `src/evolve`
- [Execution paradigms](https://github.com/purrpod/purrcat/blob/main/src/utils/paradigm_api.py): `src/utils/paradigm_api.py`

### Other components

- **User**
- **Model provider**
- **Sensor subprocesses**

## Connections

- User → Desktop shell: uses
- User → Web UI: uses
- User → API routes: requests
- Desktop shell → API routes: hosts backend
- Web UI → API routes: calls
- API routes → Python entry: serves
- Python entry → Session manager: starts
- Session manager → Agent loop: creates
- Session manager → Session history: loads and saves
- Agent loop → Model facade: requests completion
- Agent loop → Agent tools: dispatches tools
- Agent loop → Workflow engine: runs workflows
- Workflow engine → Workflow nodes: executes
- Model facade → Key scheduling: allocates keys
- Model facade → LLM client: calls
- LLM client → Model provider: sends requests
- Agent loop → PurrMemo client: uses memory
- PurrMemo client → Memory digestion: digests memories
- Memory digestion → Episodic store: records events
- Memory digestion → Vector store: stores embeddings
- Memory digestion → Knowledge graph: updates relations
- Sensor manager → Sensor subprocesses: launches and monitors
- Sensor subprocesses → Sensor manager: sends JSON-RPC
- Agent tools → MCP sessions: calls MCP tools
- API routes → Agent evolution: exposes evolution
- Session manager → Execution paradigms: resolves paradigm
