Update CLAUDE.md for multi-agent architecture

Add AgentRegistry, AgentConfig, delegate_to_agent, memory scoping,
and skills.py to architecture diagram, key files, and conventions.
Update test count to 124.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cora-start
PeninsulaInd 2026-02-17 10:14:53 -06:00
parent e5e9442e3d
commit 8a21990ba4
1 changed files with 21 additions and 9 deletions

View File

@ -18,13 +18,21 @@ The bot polls ClickUp for tasks, maps them to skills, and auto-executes or asks
``` ```
Gradio UI (ui.py) Gradio UI (ui.py)
Agent (agent.py) ← Memory (memory.py, 4-layer: identity/long-term/daily/semantic) AgentRegistry (agent_registry.py)
├── default agent ← AgentConfig (config.py)
├── writer agent
├── researcher agent
└── ops agent
Agent (agent.py) ← Memory (memory.py, 4-layer, per-agent scoping)
↓ ← Skills (skills.py, markdown skills with frontmatter)
LLM Adapter (llm.py) LLM Adapter (llm.py)
├── Chat brain: OpenRouter / Ollama / LM Studio ├── Chat brain: OpenRouter / Ollama / LM Studio (per-agent model override)
└── Execution brain: Claude Code CLI (subprocess) └── Execution brain: Claude Code CLI (subprocess)
Tool Registry (tools/__init__.py) ← auto-discovers tools in tools/ Tool Registry (tools/__init__.py) ← auto-discovers tools in tools/
├── delegate_task → execution brain
└── delegate_to_agent → cross-agent delegation (depth-limited)
Scheduler (scheduler.py) Scheduler (scheduler.py)
├── Poll loop: cron-based scheduled tasks ├── Poll loop: cron-based scheduled tasks
@ -40,7 +48,7 @@ NotificationBus (notifications.py) → Gradio / future Discord / Slack
# Run the app # Run the app
uv run python -m cheddahbot uv run python -m cheddahbot
# Run tests (118 tests, ~3s) # Run tests (124 tests)
uv run pytest uv run pytest
# Run tests verbose # Run tests verbose
@ -66,20 +74,22 @@ uv add --group test <package>
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `cheddahbot/__main__.py` | Entry point, wires all components | | `cheddahbot/__main__.py` | Entry point, multi-agent wiring |
| `cheddahbot/agent.py` | Core agentic loop (chat + tool execution) | | `cheddahbot/agent.py` | Core agentic loop (chat + tool execution) |
| `cheddahbot/agent_registry.py` | Multi-agent registry (named agents, default) |
| `cheddahbot/llm.py` | Two-brain LLM adapter | | `cheddahbot/llm.py` | Two-brain LLM adapter |
| `cheddahbot/config.py` | Dataclass config (env → YAML → defaults) | | `cheddahbot/config.py` | Config + AgentConfig dataclasses |
| `cheddahbot/db.py` | SQLite persistence (WAL, thread-safe) | | `cheddahbot/db.py` | SQLite persistence (WAL, thread-safe) |
| `cheddahbot/scheduler.py` | Three daemon threads: poll, heartbeat, ClickUp | | `cheddahbot/scheduler.py` | Three daemon threads: poll, heartbeat, ClickUp |
| `cheddahbot/clickup.py` | ClickUp REST API v2 client (httpx) | | `cheddahbot/clickup.py` | ClickUp REST API v2 client (httpx) |
| `cheddahbot/notifications.py` | UI-agnostic pub/sub notification bus | | `cheddahbot/notifications.py` | UI-agnostic pub/sub notification bus |
| `cheddahbot/memory.py` | 4-layer memory with semantic search | | `cheddahbot/memory.py` | 4-layer memory with semantic search + scoping |
| `cheddahbot/router.py` | System prompt builder | | `cheddahbot/router.py` | System prompt builder |
| `cheddahbot/ui.py` | Gradio web interface |
| `cheddahbot/skills.py` | Markdown skill registry (discovers skills/*.md) | | `cheddahbot/skills.py` | Markdown skill registry (discovers skills/*.md) |
| `cheddahbot/ui.py` | Gradio web interface |
| `cheddahbot/tools/` | Tool modules (auto-discovered) | | `cheddahbot/tools/` | Tool modules (auto-discovered) |
| `config.yaml` | Runtime configuration | | `cheddahbot/tools/delegate.py` | delegate_task + delegate_to_agent tools |
| `config.yaml` | Runtime configuration (incl. agents section) |
| `identity/SOUL.md` | Agent personality | | `identity/SOUL.md` | Agent personality |
| `identity/USER.md` | User profile | | `identity/USER.md` | User profile |
| `skills/` | Markdown skill files with YAML frontmatter | | `skills/` | Markdown skill files with YAML frontmatter |
@ -89,8 +99,10 @@ uv add --group test <package>
- **Config precedence**: env vars > config.yaml > dataclass defaults - **Config precedence**: env vars > config.yaml > dataclass defaults
- **ClickUp env vars**: `CLICKUP_API_TOKEN`, `CLICKUP_WORKSPACE_ID`, `CLICKUP_SPACE_ID` - **ClickUp env vars**: `CLICKUP_API_TOKEN`, `CLICKUP_WORKSPACE_ID`, `CLICKUP_SPACE_ID`
- **Tool registration**: Use the `@tool("name", "description", category="cat")` decorator in any file under `cheddahbot/tools/` — auto-discovered on startup - **Tool registration**: Use the `@tool("name", "description", category="cat")` decorator in any file under `cheddahbot/tools/` — auto-discovered on startup
- **Tool context**: Tools can accept `ctx: dict | None = None` to get `config`, `db`, `agent`, `memory` injected - **Tool context**: Tools can accept `ctx: dict | None = None` to get `config`, `db`, `agent`, `memory`, `agent_registry` injected
- **Skills**: `.md` files in `skills/` with YAML frontmatter (`name`, `description`, `tools`, `agents`). Files without frontmatter are data files (skipped by registry) - **Skills**: `.md` files in `skills/` with YAML frontmatter (`name`, `description`, `tools`, `agents`). Files without frontmatter are data files (skipped by registry)
- **Multi-agent**: Configure agents in `config.yaml` under `agents:` key. Each agent has `name`, `display_name`, `model` (override), `tools` (whitelist), `memory_scope`. First agent is the default. Use `delegate_to_agent` tool for cross-agent delegation (depth limit: 3).
- **Memory scoping**: Agents with `memory_scope` set use `memory/{scope}/` subdirectory. Empty scope = shared `memory/` root. Fallback search checks both scoped and shared directories.
- **Database**: SQLite with WAL mode, thread-local connections via `threading.local()` - **Database**: SQLite with WAL mode, thread-local connections via `threading.local()`
- **KV store**: Task state stored as JSON at `clickup:task:{id}:state` keys - **KV store**: Task state stored as JSON at `clickup:task:{id}:state` keys
- **ClickUp field mapping**: `Work Category` field (not `Task Type`) identifies task types like "Press Release", "Link Building". The `Client` field (not `Company`) holds the client name. - **ClickUp field mapping**: `Work Category` field (not `Task Type`) identifies task types like "Press Release", "Link Building". The `Client` field (not `Company`) holds the client name.