# litellm

Proxy LLM multi-modèles sur storage-01 (`:4000`) — point d'entrée unique pour Hermes, n8n, Open WebUI et ask-agent. Route vers llama-server (gpu-01) ou l'API Anthropic.

## Ce que fait le rôle

- venv `/opt/litellm/venv` avec `litellm[proxy]`, user système `litellm`
- Config `/etc/litellm/config.yaml` : alias `hermes-default`, `qwen3-8b`, `system`, `monitor`, `claude…`
- Service systemd + scripts utilitaires :
  - `/usr/local/bin/ask-agent` — délégation inter-agents (texte → profil system/monitor/brain)
  - `/usr/local/bin/hermes-switch` — bascule l'alias `hermes-default` entre qwen (local) et claude (API), puis restart litellm
  - `/usr/local/bin/funk-cluster` — orchestration start/stop/status du homelab
  - `/usr/local/bin/llm-heartbeat` (+ service `llm-heartbeat`) — garde chaud le tuyau
    LiteLLM↔llama-server : petit appel à `hermes-default` toutes les `llm_heartbeat_interval` s.
    Empêche la connexion keep-alive de devenir périmée → supprime le 502 « 1ʳᵉ demande après
    une pause » (cf. `admin/incidents-llm-gpu.md`). Logge les échecs (`journalctl -u llm-heartbeat`).

## Variables principales

| Variable | Défaut |
|---|---|
| `litellm_host` / `litellm_port` | `0.0.0.0` / 4000 |
| `litellm_master_key` | `lm-studio` (clé API attendue par les clients) |
| `litellm_local_llm_base_url` | `http://192.168.10.20:1234/v1` |
| `litellm_anthropic_api_key` | `{{ vault_anthropic_api_key }}` |
| `llm_heartbeat_enabled` | `true` |
| `llm_heartbeat_interval` | `15` (s — doit rester < à l'idle keep-alive du llama-server) |
| `llm_heartbeat_model` / `llm_heartbeat_timeout` | `hermes-default` / `20` |

## Timeouts & résilience (anti-502 « connexion périmée »)

`litellm_settings` : `request_timeout: 20` (court → un socket périmé échoue vite) + `num_retries: 2`
(rejoue sur une connexion neuve). Combiné au **heartbeat** (connexion jamais inactive) et au
retry côté STT-server : la chaîne tolère les blips et les redémarrages de llama-server.
⚠️ `request_timeout` est global → si `hermes-default` passe sur **Claude** (raisonnement long), le remonter.

## Caveat

- L'alias `hermes-default` est **ce que Hermes consomme** — changer le modèle derrière l'alias ne nécessite pas de reconfigurer Hermes
- `hermes-switch` modifie `/etc/litellm/config.yaml` **en dehors d'Ansible** : un `--tags litellm` réécrit la config et peut écraser un switch manuel vers claude
- Le **heartbeat** appelle `hermes-default` en continu : si tu bascules sur Claude (API facturée), pense à `llm_heartbeat_enabled: false` pour ne pas générer de coût en arrière-plan
