pi-provider-opencode-console: los modelos de OpenCode Go al día sin esperar releases de pi

Publicado el 24 de October de 2026 en Herramientas

Para mi trabajo personal uso la suscripción de OpenCode Go como proveedor de modelos en pi. Y ahí había un detalle que me molestaba cada semana: cuando OpenCode cambiaba el catálogo de modelos de la suscripción, en pi seguía viendo la lista vieja hasta que salía una release nueva.

Repositorio de pi-provider-opencode-console

El problema: una lista de modelos congelada en el binario

pi no descubre modelos en tiempo de ejecución para sus providers incorporados. El catálogo vive en pi-ai, en un archivo generado en el build:

// This file is auto-generated by scripts/generate-models.ts
// Do not edit manually - run 'npm run generate-models' to update

Para un proveedor con API pública y catálogo estable eso está bien. Para una suscripción que añade y retira modelos cada pocas semanas, es una fricción constante: ves nombres nuevos en la web de OpenCode que no existen en /model, y modelos retirados que siguen ahí ocupando sitio.

La alternativa era editar models.json a mano, que es peor: lo mantienes tú, se desincroniza, y encima los overrides de modelos no siempre se comportan igual con providers de extensión.

La solución: OAuth por device code y catálogo en vivo

pi-provider-opencode-console es una extensión de pi que registra dos providers nuevos — opencode-console y opencode-go-console — con login OAuth 2.0 por device authorization grant (RFC 8628) y descubrimiento de modelos contra el catálogo real de OpenCode.

pi install npm:pi-provider-opencode-console

Los dos providers son deliberadamente distintos de los que trae pi de serie:

Provider Autenticación Catálogo de modelos
opencode / opencode-go (nativos) API key Estático, compilado en pi-ai
opencode-console / opencode-go-console (extensión) OAuth device code En vivo, del servidor

Así los providers nativos quedan intactos y tú eliges cuál usar según tengas API key o suscripción. No hay conflicto de nombres ni de credenciales.

Login

El flujo es el de toda la vida: pides el login, pi te da un código y una URL, apruebas en el navegador y listo.

/login opencode-go-console
# pi muestra un código de usuario y la URL de verificación
# apruebas en el navegador y la credencial queda en ~/.pi/agent/auth.json

Para la consola completa (la que absorbió Zen) es el mismo flujo:

/login opencode-console

Los dos comparten la sesión de device code, así que autenticarte en uno deja el otro listo. La credencial se guarda como oauth en auth.json, y el token de acceso se renueva solo: si quedan menos de cinco minutos para que caduque, la extensión lo refresca antes de la siguiente petición, con single-flight para que dos llamadas simultáneas no pidan dos tokens, y espeja el token rotado en la entrada hermana.

Una cosa importante: la extensión es solo OAuth. No ofrece el "Enter API key" genérico de pi. Si quieres acceso con API key y lista estática, esa es justo la razón por la que existen los providers nativos.

De dónde salen los modelos

Cada provider tiene su fuente:

  • opencode-go-console tira del catálogo público GET https://opencode.ai/inference/go/v1/models, la lista lite, y la enriquece con datos de models.dev descartando ids deshabilitados o retirados.
  • opencode-console tira del endpoint org-scoped GET {server}/api/config con Authorization: Bearer y x-org-id, así que cada organización ve los modelos que le corresponden.

Para refrescar sin volver a hacer login:

/opencode-go-console refresh

Y para ver qué hay detrás:

/opencode-go-console status    # método de auth, cuenta, org, caducidad del token
/opencode-go-console logout    # borra la credencial de Go, conserva la de Console

En el provider de consola hay además switch-org para cambiar de organización cuando la sesión no viene ya ligada a una desde el navegador. Si el grant pidió scoping de organización, ese switch-org no aplica: hay que volver a hacer login.

El detalle que hace que esto funcione bien

OpenCode no expone todos sus modelos por el mismo protocolo. Hay modelos que hablan anthropic-messages, otros openai-completions, otros openai-responses, y los Gemini van por google-generative-ai. La extensión enruta cada petición al wire API correcto según el modelo que hayas elegido, y normaliza la base URL por tipo de API antes de dejar que el SDK componga la suya:

Tipo de API Base normalizada
anthropic-messages /inference[/go]/anthropic
openai-completions /inference[/go]/openai/v1
openai-responses /inference[/go]/openai/v1
google-generative-ai /inference[/go]/google/v1beta

El streaming y el parseo los delega a las implementaciones de pi-ai, en vez de reimplementarlas. Eso significa que un modelo nuevo que hable un protocolo ya soportado funciona sin tocar la extensión, y que los bugs de streaming se arreglan donde toca: en pi-ai.

También inyecta las cabeceras de identidad por petición (x-opencode-org-id, x-opencode-client, x-opencode-request), que es lo que hace que la sesión sea reconocible como tuya en el lado de OpenCode.

Configuración

Solo dos variables de entorno, y normalmente ninguna:

Variable Por defecto Para qué
OPENCODE_CONSOLE_SERVER https://opencode.ai/console Consolas autoalojadas. Se persiste en auth.json al primer login.
PI_CODING_AGENT_DIR ~/.pi/agent El directorio de pi. Útil para probar con un entorno aislado.

Migración desde versiones viejas

La 2.0 rompió compatibilidad a propósito: se eliminó la autenticación por service key (sk-…). Si te queda una entrada de ese tipo en auth.json, está muerta y pi te dirá "Provider is not configured". Bórrala y haz el login por device code.

# si venías de la 1.x, revisa y limpia
cat ~/.pi/agent/auth.json

Mi caso de uso

Trabajo con pi en dos máquinas y con dos presupuestos distintos: la suscripción de OpenCode Go para lo personal y la de Claude para el trabajo (de eso hablo en pi-claude-bridge). En la máquina personal, esta extensión ha eliminado una clase entera de fricción: ya no hay un momento "a ver si esta semana sale la release que trae el modelo nuevo".

El catálogo que ves en /model es el que tienes contratado ahora mismo. Si OpenCode añade un modelo por la mañana, lo tengo en pi después de un refresh, sin actualizar nada.

Y si quieres saber qué tal rinde cada uno de esos modelos antes de elegirlo, aa-opencode cruza el catálogo con los benchmarks de Artificial Analysis.

Recursos