> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orcbot.buzzchat.site/llms.txt
> Use this file to discover all available pages before exploring further.

# System Architecture

> OrcBot's multi-layer architecture with channels, memory, decision pipeline, and skill execution

OrcBot v2.1 is a production-ready autonomous AI agent built on a multi-layered architecture that separates concerns across channels, memory, reasoning, and execution.

## Architecture Diagram

The full system architecture from the README shows how all components interact:

```mermaid theme={null}
flowchart TB
    subgraph Channels[📡 Channels]
        TG[Telegram\nTelegraf]
        WA[WhatsApp\nBaileys]
        DC[Discord\ndiscord.js]
        GW[Gateway\nExpress + WS]
    end

    User((👤 User)) -->|message / command| Channels
    CLI[CLI / TUI\norcbot ui] -->|push task| Queue

    Channels -->|inbound → short memory\n+ push action| Queue[(🗂️ Action Queue\npriority · retry · TTL\ndependsOn · chaining)]

    subgraph AgentCore[🤖 Agent Core]
        Agent[Agent\naction loop]
        Sim[SimulationEngine\npre-task plan]
        DE[DecisionEngine\nprompt assembly\n+ LLM call]
        PR[PromptRouter\n8 modular helpers]
        PL[DecisionPipeline\nguardrails · dedup\nloop detection]
        Parser[ParserLayer\n3-tier JSON fallback]
    end

    Queue --> Agent
    Agent --> Sim
    Sim --> DE
    DE --> PR
    PR --> DE
    DE --> PL
    PL --> Parser
    Parser --> Agent

    subgraph MemorySystem[🧠 Memory System]
        MM[MemoryManager]
        SM[short memory\nstep observations]
        EP[episodic memory\nLLM summaries]
        VM[VectorMemory\nembedding index]
        LM[long memory\nMEMORY.md · LEARNING.md]
    end

    Agent <--> MM
    MM --> SM & EP & VM & LM
    DE -->|getRecentContext\nsemanticSearch| MM

    subgraph SkillLayer[⚙️ Skills]
        SM2[SkillsManager\nregistry · intent routing]
        CoreSkills[Core Skills\nweb_search · browser_navigate\nrun_command · deep_reason\nrecall_memory · delegate_task]
        Plugins[Dynamic Plugins\n~/.orcbot/plugins/\nhot-loaded]
    end

    Agent -->|execute tools| Skills
    Skills --> SM2
    SM2 --> CoreSkills & Plugins

    CoreSkills -->|search fallback chain| Browser[WebBrowser\nPlaywright stealth]
    Browser --> Search[(Serper → Google\n→ Bing → DDG)]

    DE -->|call| LLM[MultiLLM\nrouting + fallback]
    subgraph LLMProviders[🧠 LLM Providers]
        OAI[OpenAI\ngpt-4o / o1]
        GEM[Google Gemini]
        OR[OpenRouter\n200+ models]
    end
    LLM --> OAI & GEM & OR

    CoreSkills -->|3-tier channel detection| Channels
end
```

## Core Components

### 1. Channels Layer

**Purpose:** Handle inbound/outbound communication with users across platforms.

**Key files:**

* `src/channels/TelegramChannel.ts` — Telegram integration via Telegraf
* `src/channels/WhatsAppChannel.ts` — WhatsApp integration via Baileys
* `src/channels/DiscordChannel.ts` — Discord integration via discord.js
* `src/channels/Gateway.ts` — REST API + WebSocket gateway

**Flow:**

1. User sends message on a channel (e.g., Telegram)
2. Channel writes message to short-term memory
3. Channel pushes task to ActionQueue with metadata (source, chatId, userId)

### 2. Action Queue

**Purpose:** Durable priority queue for tasks with retry, TTL, and chaining support.

**Key file:** `src/memory/ActionQueue.ts`

**Features:**

* Priority-based execution (0-10, higher = more urgent)
* Automatic retry with exponential backoff
* Task dependencies (`dependsOn` field)
* TTL for completed/failed actions
* Atomic disk persistence via JSONAdapter

```typescript theme={null}
interface Action {
    id: string;
    payload: {
        description: string;
        source: string;  // 'telegram' | 'whatsapp' | 'autonomy' | etc.
        sourceId?: string;
        chatId?: string;
        userId?: string;
        isAdmin?: boolean;
        isHeartbeat?: boolean;
    };
    priority: number;
    status: 'pending' | 'running' | 'completed' | 'failed';
    dependsOn?: string[];  // IDs of prerequisite actions
}
```

### 3. Agent Core (Action Loop)

**Purpose:** Orchestrate the ReAct reasoning loop (see [agent-loop.mdx](./agent-loop.mdx)).

**Key file:** `src/core/Agent.ts` (lines 67-797)

**Responsibilities:**

* Pop next action from queue
* Run SimulationEngine (pre-task planning)
* Call DecisionEngine in a loop (reason → tool calls → observations)
* Execute skills via SkillsManager
* Write observations to memory
* Terminate when task is complete

### 4. Decision Engine

**Purpose:** Assemble prompts and call LLM with retry logic and guardrails (see [decision-pipeline.mdx](./decision-pipeline.mdx)).

**Key file:** `src/core/DecisionEngine.ts`

**Components:**

* **PromptRouter** — Selectively activates 8 modular prompt helpers based on task intent
* **DecisionPipeline** — Applies guardrails (deduplication, loop detection, safety checks)
* **ParserLayer** — Normalizes LLM output to structured JSON with 3-tier fallback
* **ContextCompactor** — Automatically compacts prompt when context overflow occurs

### 5. Memory System

**Purpose:** Multi-tier memory storage with consolidation and semantic search (see [memory-system.mdx](./memory-system.mdx)).

**Key file:** `src/memory/MemoryManager.ts`

**Memory Types:**

* **Short-term** — Recent step observations (last \~20 entries)
* **Episodic** — LLM-summarized conversation batches
* **Long-term** — Persistent markdown files (JOURNAL.md, LEARNING.md, USER.md)
* **Vector** — Semantic embeddings for full-history search

### 6. Skills System

**Purpose:** Extensible tool registry with hot-reloadable plugins (see [skills-system.mdx](./skills-system.mdx)).

**Key file:** `src/core/SkillsManager.ts`

**Features:**

* Core skills registered at startup (web\_search, browser\_navigate, run\_command, etc.)
* Dynamic TypeScript/JavaScript plugins loaded from `~/.orcbot/plugins/`
* SKILL.md agent skills (agentskills.io format) with progressive disclosure
* Intent-based skill routing
* Admin-only elevated skills

### 7. Multi-LLM Provider

**Purpose:** Abstract LLM provider routing with automatic fallback.

**Key file:** `src/core/MultiLLM.ts`

**Supported Providers:**

* OpenAI (GPT-4o, o1)
* Google Gemini
* AWS Bedrock
* OpenRouter (200+ models)
* NVIDIA NIM
* Local Ollama

**Features:**

* Automatic provider selection based on model prefix (e.g., `gemini-2.0-flash` → Google)
* Fallback chain on rate limits or errors
* Native tool calling for OpenAI and Google
* Token tracking and cost estimation

## Data Flow Example

Here's a complete flow for a user request:

```
1. User: "Search for latest AI news" (via Telegram)
   ↓
2. TelegramChannel receives message
   ↓
3. TelegramChannel.saveMemory({ type: 'short', content: 'User: Search for latest AI news', metadata: { source: 'telegram', chatId: 123 } })
   ↓
4. TelegramChannel.pushTask("Search for latest AI news", priority: 5, { source: 'telegram', chatId: 123 })
   ↓
5. ActionQueue persists action to disk
   ↓
6. Agent.runActionLoop() pops action
   ↓
7. SimulationEngine creates pre-task plan: "I'll use web_search to find news, then summarize"
   ↓
8. DecisionEngine.decide() — Step 1
   - Assembles prompt (task + short memory + episodic + skills list)
   - Calls MultiLLM with tool definitions
   - LLM responds: {"tool": "web_search", "query": "latest AI news 2025"}
   ↓
9. DecisionPipeline validates tool call (no loops, dedup pass)
   ↓
10. Agent executes web_search skill
    ↓
11. web_search calls WebBrowser → Serper API → returns news results
    ↓
12. Agent.saveMemory({ type: 'short', content: 'Observation: Tool web_search returned 10 articles...', metadata: { actionId, step: 1 } })
    ↓
13. DecisionEngine.decide() — Step 2
    - Sees search results in memory
    - LLM responds: {"tool": "send_telegram", "chatId": 123, "message": "Here are the latest AI news..."}
    ↓
14. Agent executes send_telegram skill
    ↓
15. TelegramChannel.sendMessage(123, "Here are the latest AI news...")
    ↓
16. Agent.saveMemory({ type: 'short', content: 'Assistant sent Telegram message to 123', metadata: { role: 'assistant' } })
    ↓
17. DecisionEngine.decide() — Step 3
    - LLM responds: {"completed": true, "summary": "Successfully searched and delivered news"}
    ↓
18. Agent marks action as completed
    ↓
19. MemoryManager.consolidate() (if threshold reached)
    - Summarizes old short-term memories into episodic entry
```

## Configuration

All configuration is centralized in `ConfigManager` (`src/config/ConfigManager.ts`), which loads from:

1. Environment variables
2. Local `./orcbot.config.yaml`
3. Home `~/orcbot.config.yaml`
4. Global `~/.orcbot/orcbot.config.yaml`

Key settings:

```yaml theme={null}
# LLM Provider
modelName: gpt-4o
llmProvider: openai  # or 'google', 'openrouter', 'bedrock'
openaiApiKey: sk-...

# Channels
telegramToken: 1234567890:ABC...
whatsappEnabled: true
discordToken: MTk4...

# Memory Limits
memoryContextLimit: 20
memoryEpisodicLimit: 5
memoryConsolidationThreshold: 30

# Action Loop
maxStepsPerAction: 15
maxMessagesPerAction: 10

# Autonomy
autonomyEnabled: true
autonomyInterval: 3600000  # 1 hour in ms
autonomyAllowedChannels: ['telegram']

# Skills
safeMode: false  # Disable run_command and file write if true
pluginAllowList: []  # Empty = all plugins allowed
pluginDenyList: []   # Block specific plugins
```

## Security Architecture

**Local-First Design:**

* All memory, logs, and profiles stored in `~/.orcbot/`
* No hidden uploads or telemetry
* Secrets loaded from config (never hardcoded)

**Access Control:**

* Admin-only elevated skills (run\_command, write\_file, manage\_config)
* Cross-channel send blocking (non-admin tasks can't send to other channels)
* Plugin allow/deny lists
* Safe mode to disable dangerous operations

**Information Boundaries:**

* Non-admin tasks don't see journal/learning/episodic context (prevents cross-user leakage)
* Session scoping (per-channel-peer by default, configurable to main/per-peer)
* Memory deduplication prevents repeated storage of identical events

## Performance Optimizations

**Token Reduction:**

* Compact skills prompt (names + usage only after step 1)
* Step history compaction (preserve first N + last M, summarize middle)
* Aggressive pruning of large tool outputs in history
* Per-action prompt caching (core instructions cached per action)

**Latency Reduction:**

* Parallel async retrieval (semantic recall + episodic + RAG run concurrently)
* Context assembly caching (recent/episodic/extended cached for 5-30s)
* Vector memory background indexing (runs every 5 minutes)

**Reliability:**

* Atomic disk writes with `.bak` backups (JSONAdapter)
* Action queue persistence (survives crashes)
* LLM retry with exponential backoff
* Automatic context compaction on overflow
* Circuit breaker pattern in browser operations

## Extension Points

**Adding a New Channel:**

1. Implement `BaseChannel` interface in `src/channels/`
2. Call `agent.pushTask()` for inbound messages
3. Register channel skills (e.g., `send_slack`, `react_slack`)
4. Add channel detection logic to `skills-system`

**Adding a New Skill:**

1. Register via `agent.skills.registerSkill()` (for core skills)
2. Or drop a `.ts` file in `~/.orcbot/plugins/` (for dynamic plugins)
3. Skill interface:

```typescript theme={null}
{
  name: 'my_skill',
  description: 'What it does and when to use it',
  usage: 'my_skill(arg1, arg2)',
  handler: async (args) => { /* impl */ }
}
```

**Adding a New LLM Provider:**

1. Add provider logic in `MultiLLM.ts`
2. Implement `callWithTools()` for native tool calling (optional)
3. Add model prefix detection (e.g., `claude-` → Anthropic)
4. Update config schema

## Further Reading

* [Agent Loop (ReAct)](./agent-loop.mdx) — Step-by-step reasoning process
* [Memory System](./memory-system.mdx) — Multi-tier storage and consolidation
* [Decision Pipeline](./decision-pipeline.mdx) — Guardrails and safety layers
* [Skills System](./skills-system.mdx) — Tool registry and plugin architecture
