diff --git a/docs/_index.md b/docs/_index.md index c566d42..1dd137f 100644 --- a/docs/_index.md +++ b/docs/_index.md @@ -15,6 +15,7 @@ Overview of research topics and notes. | Topic | Status | Last Updated | |-------|--------|--------------| | [OpenCode Usage & Parallelization](./opencode-usage.md) | Active | 2025-03-27 | +| [Hermes Setup](./hermes-setup.md) | In Progress | 2026-03-27 | ### More topics... diff --git a/docs/hermes-setup.md b/docs/hermes-setup.md new file mode 100644 index 0000000..4de3598 --- /dev/null +++ b/docs/hermes-setup.md @@ -0,0 +1,342 @@ +# Hermes Setup Guide for Kugetsu + +**Date:** 2026-03-27 +**Status:** In Progress +**Related Issue:** #1 + +## Summary + +Guide for setting up Hermes as the orchestration layer for Kugetsu's multi-agent parallel workflow. Hermes manages OpenCode coding agents that work in isolated git worktrees, communicating via Gitea issues and PRs. + +## 1. Installation + +### Recommended: curl (One-Liner) + +```bash +curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-setup +``` + +The `--skip-setup` flag skips the interactive setup wizard, ideal for CI environments. + +**What it installs:** +- `uv` (fast Python package manager) +- Python 3.11 via uv +- Node.js v22 LTS (for browser tools & WhatsApp bridge) +- ripgrep (fast file search) +- ffmpeg (TTS/audio) +- Clones repo to `~/.hermes/hermes-agent/` +- Creates venv, installs deps, sets up `hermes` symlink in `~/.local/bin/` +- Creates config templates in `~/.hermes/` + +### Verification + +```bash +hermes version # Check command exists +hermes doctor # Full diagnostics +source ~/.bashrc # Reload shell if hermes not found +``` + +### Alternative Methods + +| Method | Command | Best For | +|--------|---------|----------| +| **curl** | `curl -fsSL ... \| bash` | **Recommended** — fresh machines, CI | +| **Manual/Source** | `git clone` + `uv venv` + `uv pip install -e ".[all]"` | Full control, developers | +| **Nix** | `nix develop` or NixOS module | Nix/NixOS users, declarative configs | +| **Docker** | Not for installation | Docker is a *terminal backend* for sandboxing | + +### Prerequisites + +Only `git` and `curl` are required. All other dependencies are installed by the script. + +## 2. Configuration (API Key Auth) + +### Directory Structure + +``` +~/.hermes/ +├── config.yaml # Non-secret settings (model, provider, terminal, etc.) +├── .env # API keys and secrets +├── auth.json # OAuth tokens (Nous Portal, Codex, etc.) +├── SOUL.md # Agent identity +├── memories/ # Persistent memory +├── skills/ # Agent skills +├── sessions/ # Gateway sessions +└── logs/ # Error and gateway logs +``` + +### CLI Configuration + +Set API keys directly via the CLI (auto-routes to `~/.hermes/.env`): + +```bash +hermes config set OPENROUTER_API_KEY sk-or-... +hermes config set ANTHROPIC_API_KEY sk-ant-... +hermes config set OPENAI_API_KEY sk-... + +hermes config set model.provider openrouter +hermes config set model.default anthropic/claude-opus-4.6 + +hermes config # View current config +hermes config edit # Edit config.yaml +hermes config check # Validate configuration +``` + +### Supported Providers (API Key Auth) + +| Provider | Env Var | Config Provider | Notes | +|----------|---------|-----------------|-------| +| **OpenRouter** | `OPENROUTER_API_KEY` | `openrouter` | Recommended default | +| **OpenAI** | `OPENAI_API_KEY` | `openai` | | +| **Anthropic** | `ANTHROPIC_API_KEY` | `anthropic` | | +| **OpenAI-Compatible** | `OPENAI_API_KEY` + `OPENAI_BASE_URL` | `custom` | vLLM, SGLang, llama.cpp, LocalAI, Jan, Ollama | +| **Ollama** | `OPENAI_API_KEY=ollama` + `OPENAI_BASE_URL` | `custom` | Local models (no API key) | +| **DeepSeek** | `DEEPSEEK_API_KEY` | `custom` + base_url | | +| **Together AI** | `OPENAI_API_KEY` | `custom` + base_url | | +| **Groq** | `OPENAI_API_KEY` | `custom` + base_url | | +| **Fireworks AI** | `OPENAI_API_KEY` | `custom` + base_url | | + +### Example Configs + +**OpenRouter (Recommended):** +```bash +# ~/.hermes/.env +OPENROUTER_API_KEY=sk-or-v1-... +LLM_MODEL=anthropic/claude-opus-4.6 +``` + +```yaml +# ~/.hermes/config.yaml +model: + provider: "openrouter" + default: "anthropic/claude-opus-4.6" +``` + +**Ollama (Local):** +```bash +# ~/.hermes/.env +OPENAI_BASE_URL=http://localhost:11434/v1 +OPENAI_API_KEY=ollama +LLM_MODEL=llama3.1:70b +``` + +```yaml +# ~/.hermes/config.yaml +model: + provider: "custom" + default: "llama3.1:70b" + base_url: "http://localhost:11434/v1" +``` + +**Anthropic Direct:** +```bash +# ~/.hermes/.env +ANTHROPIC_API_KEY=sk-ant-... +``` + +```yaml +# ~/.hermes/config.yaml +model: + provider: "anthropic" + default: "claude-sonnet-4-6" +``` + +### Quick-Start Template + +```bash +# ~/.hermes/.env (create this) +OPENROUTER_API_KEY=your-key-here +LLM_MODEL=anthropic/claude-opus-4.6 + +# ~/.hermes/config.yaml (minimal) +model: + provider: "openrouter" + default: "anthropic/claude-opus-4.6" +``` + +## 3. OpenCode Integration + +### How Hermes Delegates to OpenCode + +Hermes does **NOT** have a native agent-to-agent protocol. Delegation happens via terminal/process spawning: + +``` +Hermes (orchestrator) + └── terminal(command="opencode run 'task'", workdir="...") + └── OpenCode subprocess (child process) + └── Executes autonomously +``` + +### delegate_task vs terminal(opencode run) + +| Pattern | Command | Concurrency Limit | Context | +|---------|---------|-------------------|---------| +| `delegate_task()` | Native LLM subagent | **Max 3** (hard schema limit) | Fresh isolated context | +| `terminal(opencode run)` | CLI subprocess wrapper | **No hard cap** | Streams output via process() | + +For Kugetsu's parallel workflow, prefer `terminal(opencode run ...)` for coding agents since we need more than 3 concurrent agents. + +### Example Delegation Commands + +```bash +# One-shot task (blocks until complete) +terminal(command="opencode run 'Fix issue #1: add retry logic'", workdir="/tmp/issue-1") + +# Background TUI (interactive, returns session_id) +terminal(command="opencode", workdir="~/project", background=true, pty=true) + +# Monitor background session +process(action="poll", session_id="") +process(action="log", session_id="") +process(action="submit", session_id="", data="Continue work...") + +# Kill session +process(action="kill", session_id="") +``` + +### Kugetsu's Gitea-Based Communication Hub + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Hermes (Orchestrator/PM) │ +│ - terminal(opencode run ...) for OpenCode agents │ +│ - delegate_task() for LLM subagents (max 3) │ +└─────────────────────────────────────────────────────────────┘ + │ (CLI subprocess) + ▼ +┌──────────────────────┐ +│ OpenCode Subagent │ +│ - Works in isolated │ +│ git worktree │ +│ - Posts findings to │ +│ Gitea via curl │ +└──────────────────────┘ + │ (Gitea API) + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Gitea (Communication Hub) │ +│ - Issues as task tickets │ +│ - Comments as progress updates │ +│ - PRs as code deliverables │ +└─────────────────────────────────────────────────────────────┘ +``` + +## 4. Git Worktree Isolation (Per-Issue) + +### Why Worktrees? + +Running multiple agents on the same repo can cause: +- **File conflicts** when agents edit the same files +- **Branch state confusion** when agents checkout different branches +- **Lost work** if one agent's changes get overwritten + +Each issue gets its own worktree so any agent can jump into the right context. + +### Manual Setup + +```bash +# Create worktree for an issue +git worktree add -b fix/issue-{N}-title ../kugetsu-issue-{N} main + +# List worktrees +git worktree list + +# Remove worktree (after PR merged) +git worktree remove ../kugetsu-issue-{N} +git branch -D fix/issue-{N}-title +``` + +### opencode-worktree Skill + +Kugetsu provides an automated skill at `skills/opencode-worktree/`: + +```bash +# Source the script +. skills/opencode-worktree/opencode-worktree.sh + +# Create session with purpose tag +. opencode-worktree.sh refactor-auth +# Creates: session-{timestamp}-{random6}-refactor-auth + +# Cleanup all session-* worktrees +. opencode-worktree.sh --cleanup + +# Cleanup specific worktree +. opencode-worktree.sh --cleanup session-20260327-134524-9c1e3f-refactor-auth +``` + +### Hermes Built-in Worktree Isolation + +Hermes has native support via config: + +```yaml +# ~/.hermes/config.yaml +worktree: true # Always create a worktree per session +``` + +Each CLI session creates a fresh worktree under `.worktrees/` with its own branch. Clean worktrees are removed on exit; dirty ones are kept for manual recovery. + +### Branch Hygiene + +**Always use explicit base when creating branches:** + +```bash +# WRONG - depends on current HEAD +git checkout -b fix/issue-{N}-title + +# CORRECT - always from main explicitly +git checkout -b fix/issue-{N}-title main +``` + +**Detect contamination:** + +```bash +# Check for commits beyond main +git log main..HEAD --oneline +# If non-empty, branch is contaminated +``` + +**Fix contamination:** + +```bash +git rebase --onto main wrong-base my-branch +git push --force-with-lease origin my-branch +``` + +## 5. Workflow Summary + +``` +1. Setup Hermes + curl -fsSL .../install.sh | bash -s -- --skip-setup + hermes config set OPENROUTER_API_KEY ... + hermes config set model.provider openrouter + +2. For Each Issue: Create Isolated Worktree + git worktree add -b docs/issue-{N}-title ../kugetsu-issue-{N} main + +3. Agent Works in Worktree + cd ../kugetsu-issue-{N} + opencode run "Research/fix issue #{N}" + +4. Agent Posts to Gitea + curl -X POST .../issues/{N}/comments -d @/tmp/findings-{N}.md + +5. User Reviews on Gitea + Comments on issues/PRs + +6. Cleanup After Merge + git worktree remove ../kugetsu-issue-{N} + git branch -D docs/issue-{N}-title +``` + +## References + +- [Hermes Agent GitHub](https://github.com/nousresearch/hermes-agent) +- [Hermes Agent Docs](https://hermes-agent.nousresearch.com) +- [Kugetsu Architecture](./kugetsu-architecture.md) +- [OpenCode Usage](./opencode-usage.md) +- [Subagent Workflow](./SUBAGENT_WORKFLOW.md) + +## Status History + +- 2026-03-27: Initial draft from issue #1 research