Conectar Pi a LiteLLM

Registrar un proxy LiteLLM autoalojado como proveedor de modelos en el agente Pi, sobre HTTP plano en la red local.

Ficha

Proxyhttp://192.168.68.108:4000
Extensiónnpm:pi-provider-litellm ^2.3.0
Proveedor Pilitellm
Modelogpt-5.6-sol — 922K ctx / 128K out
API keysk-xxxx
Pi0.84.4 (Homebrew)
Verificado2026-09-03

Esta key está rotada

La key de arriba queda anotada aquí sólo porque se va a borrar. Si en algún momento vuelve a estar viva, sácala de esta nota: un vault de Obsidian se sincroniza, se indexa y se respalda, y esto es una credencial en claro. Lo correcto es dejar aquí el nombre de la key y guardar el valor en auth.json o en un gestor de secretos.

Cómo encajan las piezas

Pi no habla con LiteLLM directamente: lo hace a través de la extensión pi-provider-litellm, que descubre el catálogo al arrancar y registra cada modelo como litellm/<modelo>.

pi  →  pi-provider-litellm  →  LiteLLM :4000  →  upstream
           settings.json         /model/info
           auth.json             /v1/models

La configuración se reparte entre dos ficheros a propósito: la URL en settings.json, la credencial en auth.json.


1. Localizar el proxy

LiteLLM escucha en el 4000 por defecto, pero conviene confirmarlo. /health/liveliness responde sin autenticación, así que sirve como sonda limpia:

for p in 4000 8000 3000 80 8080; do
  code=$(curl -s -o /dev/null -w '%{http_code}' -m 3 \
    "http://192.168.68.108:$p/health/liveliness")
  echo "port $p -> $code"
done
 
# port 4000 -> 200   ← aquí está
# port 8000 -> 000

/health/readiness dice además si el proxy tiene base de datos detrás, que es lo que habilita las virtual keys:

curl -s http://192.168.68.108:4000/health/readiness
# {"status":"healthy","db":"connected"}

La extensión intenta primero /model/info — el endpoint de administración, con metadatos ricos — y cae a /v1/models si recibe 401, 403 o 404.

B=http://192.168.68.108:4000
K=sk-xxxx
 
# catálogo básico (compatible OpenAI)
curl -s -H "Authorization: Bearer $K" "$B/v1/models"
 
# metadatos completos: ventana de contexto, costes, límites
curl -s -H "Authorization: Bearer $K" "$B/model/info"

Qué mirar

Si /model/info responde, la key tiene permisos de administración y el descubrimiento traerá ventana de contexto y costes reales. Un 401 ahí no es un fallo: es lo normal con una virtual key, y la extensión usará el catálogo básico.

3. Copia de seguridad

Antes de tocar nada

Un JSON mal formado en auth.json hace que Pi aborte la lectura de credenciales entera, no sólo la de LiteLLM.

cd ~/.pi/agent
cp settings.json settings.json.bak.$(date +%Y%m%d-%H%M%S)
cp auth.json     auth.json.bak.$(date +%Y%m%d-%H%M%S)

4. Registrar el proveedor

Bloque litellm al nivel superior de settings.json, junto a packages y theme:

{
  "packages": ["npm:pi-provider-litellm"],
 
  "litellm": {
    "providers": {
      "litellm": {
        "baseUrl": "http://192.168.68.108:4000",
        "displayName": "LiteLLM",
        "allowInsecureHttp": true
      }
    }
  }
}

Por qué allowInsecureHttp

La extensión rechaza cualquier http:// que no sea loopback. Una IP de LAN como 192.168.68.108 no lo es, así que sin esa bandera el proveedor ni siquiera se registra. Con localhost o 127.0.0.1 sobra.

La URL va sin el sufijo /v1: la extensión lo añade ella misma al construir el endpoint de chat.

5. Guardar la credencial

La key no va en settings.json. Va en auth.json, que Pi crea con permisos 0600 mientras que settings.json queda en 0644 — legible por cualquier cuenta de la máquina.

Vía normal, interactiva desde dentro de Pi:

/login litellm     → "Sign in with an API key"

A mano, con el formato exacto que genera ese comando:

{
  "litellm": {
    "type": "api_key",
    "key": "sk-xxxx",
    "env": {
      "LITELLM_BASE_URL": "http://192.168.68.108:4000"
    }
  }
}
chmod 600 ~/.pi/agent/auth.json

6. Verificar

Dos comprobaciones, y hacen falta las dos: la primera dice que el descubrimiento funciona, la segunda que una petición real atraviesa el proxy.

pi --list-models | grep litellm
# litellm   gpt-5.6-sol   922K   128K   yes   yes
 
pi --provider litellm --model gpt-5.6-sol -p "Responde solo con: OK"
# OK

Si la primera lista el modelo pero la segunda falla, el problema está en el enrutado del proxy hacia el modelo upstream, no en la configuración de Pi.


De dónde sale cada valor

Orden de resolución, de mayor a menor prioridad:

DatoOrden
URL basesettings.json → $LITELLM_BASE_URL → login anterior en auth.json
API keyauth.json (el login) → $LITELLM_API_KEY_HELPER → $LITELLM_API_KEY
Cabecerasheaders en settings.json → $LITELLM_HEADERS

Para tokens de vida corta, LITELLM_API_KEY_HELPER apunta a un comando que imprime un bearer fresco; Pi lo reejecuta en cada petición en vez de cachearlo.

Hacerlo el modelo por defecto

Registrar el proveedor no cambia con qué modelo arranca Pi. Para eso, en settings.json:

"defaultProvider": "litellm",
"defaultModel": "gpt-5.6-sol"

Sin esto, /model dentro de Pi permite elegirlo sesión a sesión, que suele bastar si se alterna con un Ollama local.


Ficheros implicados

FicheroPapel¿Backup?
~/.pi/agent/settings.jsonConfiguración. Fuente de verdadSí
~/.pi/agent/auth.jsonCredenciales, modo 0600. Fuente de verdadSí
~/.pi/agent/models-store.jsonCaché de descubrimiento, la escribe Pi solaNo hace falta
~/.pi/agent/models.jsonProveedores estáticos (Ollama). No se toca—

models-store.json se regenera en cada refresco de /model; borrarla no rompe nada. Ollama vive en models.json con sus modelos escritos a mano, así que no pasa por el descubrimiento dinámico: son dos mecanismos distintos conviviendo, y por eso registrar LiteLLM no afecta a Ollama.

Revertir

cd ~/.pi/agent
cp settings.json.bak.<TIMESTAMP> settings.json
cp auth.json.bak.<TIMESTAMP>     auth.json

La entrada litellm que quede en models-store.json se ignora sin el proveedor registrado.


Seguridad

MCP y Skills vienen activados

Si el proxy expone /mcp-rest/tools/list o /claude-code/marketplace.json, la extensión registra esas herramientas y añade instrucciones al system prompt automáticamente. Es decir: el proxy puede inyectar instrucciones y ofrecer herramientas que el agente invocará. Trátalo como componente de confianza, o desactívalo dentro del bloque litellm (requiere reiniciar Pi):

"skills": { "enabled": false },
"mcp":    { "enabled": false }

El tráfico va en claro

Sobre HTTP la key viaja en la cabecera Authorization de cada petición, junto con todo el contenido de la conversación. Asumible en una LAN doméstica; deja de serlo en cuanto ese proxy salga de casa o la red se comparta.


Si algo falla

SíntomaCausa probable
El proveedor no aparece en --list-modelsFalta allowInsecureHttp, o la URL lleva /v1 de más
Aviso «no credentials» al arrancarNo hay entrada en auth.json ni variables de entorno
«discovered no models»El proxy devolvió lista vacía — verifica /model/info o /v1/models
«No models available», y al reiniciar desapareceCarrera conocida en Pi 0.84+. Se evita con "enabledModels": ["litellm/*"]
El descubrimiento tarda o expiraSube LITELLM_DISCOVERY_TIMEOUT_MS (5000 por defecto)
401 Token expiredKey rotatoria: configura LITELLM_API_KEY_HELPER

Para ver qué hace el descubrimiento en lugar de adivinar:

LITELLM_VERBOSE_DISCOVERY=1 pi --list-models