# Hermes Config Update Procedure

## Structure

The Hermes config at `~/.hermes/config.yaml` has two critical sections for local models:

### custom_providers
```yaml
custom_providers:
- api_key_env: ''
  base_url: http://127.0.0.1:9292/v1
  models:
  - context_length: 131072
    description: Human-readable description
    id: model-id  # must match llama-swap model key
    name: Display Name
  name: Local LLM (llama-swap)
```

- The `id` field must exactly match the model key in `~/.config/llama-swap/config.yaml`
- The `context_length` must match the `-c` value in llama-swap
- The order of models in the list doesn't matter

### fallback_providers
```yaml
fallback_providers:
- model: model-id
  provider: custom:local-llm-(llama-swap)
```

### agent.environment_hint
Update the model count when adding/removing models:
```yaml
agent:
  environment_hint: "Debian 13 server, 11GB VRAM RTX 2080 Ti, N local models via llama-swap :9292, ..."
```

## Editing (Python — SAFE method)

```python
import yaml

with open('/home/rurouni/.hermes/config.yaml', 'r') as f:
    cfg = yaml.safe_load(f)

# Edit models
for cp in cfg.get('custom_providers', []):
    if 'llama-swap' in cp.get('name', '').lower():
        existing = {m['id'] for m in cp['models']}
        new_model = {'context_length': 131072, 'description': '...', 'id': 'model-id', 'name': 'Display Name'}
        if new_model['id'] not in existing:
            cp['models'].append(new_model)

# Update fallbacks
cfg['fallback_providers'].append({'model': 'model-id', 'provider': 'custom:local-llm-(llama-swap)'})

# CRITICAL: EXACTLY these kwargs — a typo destroys the file
with open('/home/rurouni/.hermes/config.yaml', 'w') as f:
    yaml.dump(cfg, f, default_flow_style=False, sort_keys=False, width=1000)

# ALWAYS validate
import yaml
yaml.safe_load(open('/home/rurouni/.hermes/config.yaml'))
print("Valid YAML")
```

The exact kwargs are: `default_flow_style=False, sort_keys=False, width=1000`.
A typo (`default_flow_state` instead of `default_flow_style`) will SILENTLY EMPTY the file.

## Recovery from Empty Config

If the config file becomes empty:
1. Restore from the most recent backup:
   ```bash
   cp ~/.hermes/config.yaml.bak-20260619-223108 ~/.hermes/config.yaml
   ```
   Or from a state snapshot:
   ```bash
   ls ~/.hermes/state-snapshots/*/config.yaml
   cp ~/.hermes/state-snapshots/<most-recent>/config.yaml ~/.hermes/config.yaml
   ```
2. Re-apply lost changes (new models, provider edits)
3. Validate: `python3 -c "import yaml; yaml.safe_load(open('/home/rurouni/.hermes/config.yaml'))" && echo OK`
4. Restart gateway: kill old process, start new one
5. Verify: `curl -s :18789/v1/models` should return API key error (alive), not connection refused (dead)

## Gateway Restart

```bash
kill $(pgrep -f "hermes.*gateway.run") 2>/dev/null
sleep 3
cd /home/rurouni && /home/rurouni/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run
# ^ use background=true, not nohup
sleep 5
curl -s :18789/v1/models  # should return {"error":{"message":"Invalid API key"...}}
```
