En mi búsqueda por optimizar mi flujo de trabajo de programación, decidí integrar modelos de inteligencia artificial directamente en mi IDE para permitir la edición en línea de archivos, refactorización y autocompletado. Mi objetivo principal era conectar la API de OpenRouter para aprovechar el modelo gratuito deepseek/deepseek-r1:free utilizando la extensión Continue en VSCode/Cursor. Sin embargo, el camino estuvo lleno de pequeños obstáculos de configuración, errores de sintaxis en YAML y peculiaridades de la terminal de Windows que vale la pena documentar.
1. El problema inicial: Errores de análisis en config.yaml
Al intentar configurar inicialmente un proveedor alternativo (Moonshot) en la extensión Continue para verificar la conectividad, me topé de inmediato con un error persistente en la carga del asistente. La extensión fallaba al parsear el archivo de configuración, arrojando el siguiente rastreo de error en la consola:
at parseConfigYaml (c:\Users\DOSCLIC\.vscode\extensions\continue.continue-1.0.21-win32-x64\out\extension.js:178906:13)
Este error indicaba que el analizador sintáctico de la extensión esperaba una estructura de objeto específica en el archivo config.yaml, pero estaba recibiendo un valor nulo debido a una indentación incorrecta o a un esquema de propiedades no soportado por la versión de la extensión.
2. Entendiendo el esquema correcto de Continue
Tras analizar la documentación de referencia de Continue y contrastarla con un entorno local funcional (que utilizaba Ollama de forma nativa), identifiqué que la estructura del archivo config.yaml requiere una definición explícita de los modelos bajo un esquema específico (schema: v1).
La estructura base que demostró funcionar correctamente para otros proveedores sigue este patrón:
name: Local Assistant
version: 1.0.0
schema: v1
models:
- name: Moonshot Chat
provider: moonshot
model: moonshot-v1-8k
apiKey: sk-moonshot-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- name: Autodetect
provider: ollama
model: AUTODETECT
context:
- provider: code
- provider: docs
- provider: diff
- provider: terminal
- provider: problems
- provider: folder
- provider: codebase
3. Depurando la API de OpenRouter desde la terminal
Antes de escribir la configuración final en el archivo YAML, necesitaba asegurarme de que mi clave de API de OpenRouter funcionaba correctamente y no presentaba problemas de autenticación (como el molesto error 401 Unauthorized o No auth credentials found).
Intentar probar la API con comandos curl estándar de Linux en la consola de comandos de Windows (CMD) generó problemas de escape de caracteres y saltos de línea inválidos:
Para solucionar esto, tuve que adaptar la sintaxis de curl para el Símbolo del Sistema de Windows, unificando el comando en una sola línea y escapando correctamente las comillas dobles dentro del payload JSON.
Prueba fallida por cuota (Modelo de pago)
Al realizar la primera petición exitosa apuntando al modelo openai/gpt-4o, el servidor de OpenRouter respondió con un error de créditos insuficientes (código 402), lo cual confirmó que la autenticación era correcta pero requería saldo activo:
curl https://openrouter.ai/api/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-or-v1-xxxxxxxx" -d "{\"model\": \"openai/gpt-4o\", \"messages\": [{\"role\": \"user\", \"content\": \"What is the meaning of life?\"}]}"
{"error":{"message":"Insufficient credits. Add more using https://openrouter.ai/settings/credits","code":402}}
Prueba fallida por ID de modelo incorrecto
Posteriormente, intenté invocar el modelo gratuito usando el identificador corto deepseekr1:free, lo que resultó en un error de solicitud incorrecta (código 400):
{"error":{"message":"deepseekr1:free is not a valid model ID","code":400}}
Prueba exitosa con el ID de modelo completo
El punto de quiebre fue utilizar el espacio de nombres completo del creador del modelo tal como lo especifica el catálogo de OpenRouter: deepseek/deepseek-r1:free. Al ejecutar la petición con esta corrección, la API respondió de manera exitosa entregando el desglose de razonamiento (pensamiento interno del modelo) y la respuesta final estructurada.
curl https://openrouter.ai/api/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-or-v1-xxxxxxxx" -d "{\"model\": \"deepseek/deepseek-r1:free\", \"messages\": [{\"role\": \"user\", \"content\": \"What is the meaning of life?\"}]}"
{"id":"gen-1755098826-lgQNHc9x5dYy9lLASh1g","provider":"Chutes","model":"deepseek/deepseek-r1:free","object":"chat.completion","choices":[{"message":{"role":"assistant","content":"The question \"What is the meaning of life?\" is one of humanity's..."}}]}
4. La solución: Integración final en config.yaml para VSCode / Cursor
Una vez validada la API y el identificador exacto del modelo, procedí a plasmar esta configuración en el archivo de configuración de la extensión Continue. Para acceder a este archivo en Windows, la ruta habitual es:
C:\Users\[TuUsuario]\.vscode\extensions\continue.continue-[versión]\config\config.yaml
La estructura final y funcional para integrar OpenRouter junto con otros proveedores locales quedó configurada de la siguiente manera:
name: Local Assistant
version: 1.0.0
schema: v1
models:
- name: OpenRouter Assistant
provider: openrouter
model: deepseek/deepseek-r1:free
apiKey: sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
context:
- provider: code
- provider: docs
- provider: diff
- provider: terminal
- provider: problems
- provider: folder
- provider: codebase
config.yaml, es indispensable reiniciar por completo el IDE (VSCode o Cursor) para obligar a la extensión a recargar el archivo de configuración y evitar conflictos de caché con sesiones previas.
5. Lo que aprendí
- Los nombres de los modelos importan: En plataformas agregadoras como OpenRouter, no basta con usar el nombre comercial del modelo (como
deepseek-r1); siempre se debe incluir el namespace completo del creador (deepseek/deepseek-r1:free). - Sintaxis de terminal en Windows: Al depurar APIs con
curlen Windows CMD, los saltos de línea con barra invertida (\) fallan. Es obligatorio usar el acento circunflejo (^) o, mejor aún, escribir la instrucción en una sola línea y escapar las comillas internas del JSON con\". - Validación previa: Probar las credenciales y endpoints mediante herramientas externas o comandos directos de terminal antes de integrarlos en archivos de configuración complejos ahorra horas de depuración a ciegas dentro del IDE.
La historia detrás de la nota
A veces pasamos horas culpando a la extensión o al IDE cuando el verdadero problema es una comilla mal escapada en la terminal o un namespace incompleto en el archivo de configuración. Validar paso a paso es el mejor camino al éxito.