Artificial Intelligence 5 min de lectura 13 de agosto de 2025

Integración API OpenRouter Cursor

Aprende a depurar la conexión con OpenRouter y a estructurar correctamente tu archivo config.yaml para usar DeepSeek R1 de forma gratuita en tu entorno de desarrollo.

Solución en "Dos Clics" (TL;DR)

Guía para integrar la API de OpenRouter en Cursor y la extensión Continue de VSCode, configurando modelos de inteligencia artificial mediante el archivo config.yaml.

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:

Error detectado: Failed to parse assistant: Expected object, received null
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:

Archivo config.yaml (Base)
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:

Error de consola: '-H' is not recognized as an internal or external command, operable program or batch file.

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:

Terminal (Windows CMD) - Error 402
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):

Terminal (Windows CMD) - Error 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.

Terminal (Windows CMD) - Petición Correcta
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:

Archivo config.yaml (Solución)
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
Consejo Práctico: Tras guardar los cambios en el archivo 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 curl en 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.