Files
Cortex-Inara/CLAUDE.md
Scott Idem ed472ce9a0 feat: Intelligence Layer Phase 1 — orchestrator service
Adds the Gemini API orchestrator (ReAct tool loop → Claude responder):

Orchestrator engine + router:
- orchestrator_engine.py: Gemini API tool loop, Claude CLI handoff
- routers/orchestrator.py: POST /orchestrate (async job queue), GET /orchestrate/{job_id}

Tools (cortex/tools/):
- web.py: DuckDuckGo web search (no key required)
- ae_knowledge.py: ae_journal_search + ae_journal_entry_create (AE V3 API)
- ae_tasks.py: ae_task_list (reads agents_sync Kanban filesystem)
- files.py: file_read (path-allowlisted to safe dirs)

Config + deps:
- config.py: orchestrator, DuckDuckGo, and AE API settings
- requirements.txt: google-genai, duckduckgo-search
- .env.default: reference config with all new keys documented

Docs:
- CLAUDE.md, README.md, documentation/ added to repo
- Port references updated 7331 → 8000 throughout
- Default model updated to gemini-2.5-flash

Tested: ae_task_list, ae_journal_search, web_search all working end-to-end.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 19:37:49 -04:00

172 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md — Cortex / Inara Project
This file is loaded automatically by Claude Code when working in this directory.
Read it before touching any files.
---
## Identity & Context
- **Project:** Cortex (dispatcher) + Inara (resident agent)
- **Owner:** Scott Idem (One Sky IT / Danger Zone)
- **Machine context:** See `~/CLAUDE.md` for fleet identity (`scott_lpt` = General Manager)
- **Named after:** The 'verse-wide communications network (Firefly)
---
## Directory Map
```
Cortex_and_Inara_dev/
cortex/ ← FastAPI service (the dispatcher)
main.py ← App entry point, router registration
config.py ← All settings (pydantic-settings, reads .env)
llm_client.py ← Claude CLI + Gemini CLI subprocess backends
orchestrator_engine.py ← Gemini API ReAct tool loop → Claude handoff
context_loader.py ← Loads Inara's system prompt from inara/ files
session_store.py ← In-memory + file session persistence
session_logger.py ← Writes session turns to inara/sessions/
memory_distiller.py ← Short/mid/long distill jobs (APScheduler)
scheduler.py ← APScheduler setup
event_bus.py ← Internal SSE pub/sub (NC Talk → browser)
routers/
chat.py ← POST /chat (streaming SSE)
orchestrator.py ← POST /orchestrate, GET /orchestrate/{job_id}
auth.py ← GET /auth/status (Claude + Gemini CLI token checks)
distill.py ← POST /distill/*, GET /distill/status
files.py ← GET /files (inara/ file browser)
nextcloud_talk.py ← POST /webhook/nextcloud (NC Talk bot)
google_chat.py ← POST /webhook/google (Google Chat — stub)
tools/
__init__.py ← Tool registry (Gemini FunctionDeclarations + dispatcher)
web.py ← DuckDuckGo web_search tool
static/ ← Single-page web UI (index.html, style.css, app.js)
data/sessions/ ← Persisted session JSON files
inara/ ← Inara identity, memory, context files
IDENTITY.md ← Who Inara is
SOUL.md ← Values, personality, voice
PROTOCOLS.md ← Behavioral rules
CONTEXT_TIERS.md ← What each tier (13) includes in the system prompt
USER.md ← Scott's profile (loaded into context)
HELP.md ← In-app help content (rendered in UI)
MEMORY.md ← Persistent facts (written by distiller or manually)
MEMORY_SHORT.md ← Rolling short-term memory (auto-distilled daily)
MEMORY_MID.md ← Mid-term memory (auto-distilled weekly)
MEMORY_LONG.md ← Long-term memory (auto-distilled monthly)
sessions/ ← Session turn logs (YYYY-MM-DD_<id>.md)
docs/ ← Integration reference docs
NEXTCLOUD_TALK_BOT.md
documentation/ ← Architecture decisions and agent task list
TODO__Agents.md ← READ THIS FIRST — active task list
ARCH__Intelligence_Layer.md ← Orchestrator, dev agent, knowledge architecture
docker-compose.yml ← Docker deployment
.env.default ← Reference config (copy to .env, fill in secrets)
README.md ← Project orientation
```
---
## Run Commands
```bash
# Start (Docker)
docker compose up -d
# Restart service (after any Python change)
sudo systemctl restart cortex
# Syntax check a file before restarting
python3 -m py_compile cortex/<file>.py
# Syntax check all routers
for f in cortex/routers/*.py cortex/tools/*.py cortex/orchestrator_engine.py; do
python3 -m py_compile "$f" && echo "OK: $f"
done
# Install/update dependencies
cd cortex && .venv/bin/pip install -r requirements.txt
# Logs
journalctl -u cortex -f
# Web UI (local)
http://localhost:8000
# Swagger docs
http://localhost:8000/docs
```
---
## Key Design Decisions
### Two-Brain Architecture (Orchestrator / Responder)
- **Gemini API** (`orchestrator_engine.py`) — runs the ReAct tool loop; handles tool calling, planning, research
- **Claude CLI** (`llm_client.py`) — produces all user-facing responses; receives enriched context from Gemini
- **Direct chat** bypasses the orchestrator entirely — `POST /chat` goes straight to Claude (faster)
- **Orchestrated tasks** go to `POST /orchestrate` — returns a job_id, result is polled
### LLM Backends
- `llm_client.py` manages Claude CLI (`claude --print`) and Gemini CLI (`gemini -p`) subprocesses
- `orchestrator_engine.py` uses the Gemini **API** (google-genai SDK) — completely separate from the Gemini CLI
- Claude OAuth token is read live from `~/.claude/.credentials.json` (never rely on stale env var)
### Tool Strategy
- Orchestrator tools live in `cortex/tools/` — separate from the `ae_*` MCP tools
- **Do not modify** the `ae_*` MCP server to support orchestrator needs; add new tools to `cortex/tools/` instead
- Tools are registered in `cortex/tools/__init__.py` as both Gemini FunctionDeclarations and Python callables
### Context / Memory
- `context_loader.py` assembles Inara's system prompt from `inara/` files based on tier (13)
- Tier 1 = minimal (identity only); Tier 2 = standard (+ memory + user profile); Tier 3 = full
- Memory files are written by the distiller or manually — do not delete them
### Security / Safety
- **Never `rm`** — move files to `~/tmp/gemini_trash`
- **Never commit secrets** — `.env` is gitignored; use `.env.default` as the reference
- `NEXTCLOUD_TALK_BOT_SECRET` and `GEMINI_API_KEY` live in `.env` only
- Cortex should only be accessible via WireGuard — never internet-exposed without VPN
---
## Adding a New Tool
1. Implement the tool function in `cortex/tools/<domain>.py`
- Must be `async def`; use `asyncio.to_thread` for blocking calls
- Return a plain string result
2. Add a `FunctionDeclaration` and register it in `cortex/tools/__init__.py`
3. Syntax check: `python3 -m py_compile cortex/tools/<domain>.py`
4. Restart Cortex
## Adding a New Router
1. Create `cortex/routers/<name>.py` with `router = APIRouter()`
2. Import and register in `cortex/main.py`
3. Syntax check, restart
---
## Active Tasks
See `documentation/TODO__Agents.md` for the current task list.
High priority items as of 2026-03-18:
- Ollama backend (third LLM option — local, no API cost)
- NC Talk integration stabilization
- Knowledge consolidation (markdown → AE Journals)
---
## Related Docs
| File | Purpose |
|---|---|
| `documentation/TODO__Agents.md` | Active task list — read before starting work |
| `documentation/ARCH__Intelligence_Layer.md` | Full architecture design |
| `~/agents_sync/projects/CORTEX.md` | High-level project vision and phases |
| `~/agents_sync/CLAUDE.md` | Fleet coordination rules |
| `~/CLAUDE.md` | Machine identity (`scott_lpt`) |