# Config-NaN - configuracion NaN Builders para LLMs

> Source: <https://gist.github.com/686f6c61/8c05e9e6a1fa6062f5a23f56edac46af>
> Published: 2026-07-11 08:02:45+00:00

| # NaN Builders LLMs.txt | |
| Documento autocontenido para configurar clientes, IDEs, agentes y SDKs contra la API de NaN Builders sin tener que abrir la documentacion durante la configuracion. | |
| Fuentes consultadas el 2026-07-11: | |
| - https://nan.builders/docs/getting-started | |
| - https://nan.builders/docs/api | |
| - https://nan.builders/docs/models | |
| - https://nan.builders/docs/examples | |
| ## Identidad del servicio | |
| NaN expone modelos de texto, vision, audio, embeddings, reranking e imagen mediante una API compatible con OpenAI, servida via LiteLLM para la parte LLM. Cualquier herramienta que acepte un `base URL` y una `API key` de tipo OpenAI-compatible deberia poder funcionar: Cursor, Cline, Continue, Aider, OpenCode/OpenCode-like, Open WebUI, Zed, SDK oficial de OpenAI, AI SDK, clientes HTTP, etc. | |
| Valores base: | |
| ``` txt | |
| Base URL: https://api.nan.builders/v1 | |
| Auth: Authorization: Bearer sk-tu-key-aqui | |
| Default chat model: qwen3.6 | |
| ``` | |
| Para el servicio enterprise de Helmcode, usa el host `api.helmcode.com`; los endpoints `/v1/...` son equivalentes. | |
| La API key se genera desde la plataforma de NaN, en ajustes de usuario, seccion "API Keys". La key es personal e intransferible. El soporte indicado en la documentacion es solo para temas tecnicos. | |
| ## Reglas de configuracion rapida | |
| Usa `qwen3.6` como modelo general por defecto: chat, streaming, vision, tool calling y reasoning activado por defecto. | |
| Usa `deepseek-v4-flash` si necesitas contexto muy largo, reasoning configurable con `reasoning_effort` y buen rendimiento general en texto. | |
| Usa `mimo-v2.5` si necesitas entrada omnimodal real: texto, imagen y audio. Su reasoning esta siempre activo, asi que reserva suficiente presupuesto de salida. | |
| Usa `gemma4` para chat multimodal con vision cuando quieras reasoning opt-in. | |
| Usa `qwen3-embedding` para embeddings de 4096 dimensiones. | |
| Usa `rerank` despues de recuperar documentos por embeddings, especialmente en RAG multilingue o busqueda de codigo. | |
| Usa `kokoro` para text-to-speech. | |
| Usa `whisper` para speech-to-text. | |
| Usa `flux-2-klein` para imagenes text-to-image e image-to-image; requiere tier inference. | |
| ## Modelos disponibles | |
| ### deepseek-v4-flash | |
| Modelo MoE de texto/chat. Especificacion documentada: | |
| - Parametros: 284B totales, 21B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 1M tokens. | |
| - Cuota mensual: 500M tokens por miembro. | |
| - Capacidades: chat, streaming SSE, tool calling, reasoning. | |
| - Control de reasoning: `reasoning_effort` con valores `low`, `medium`, `high`; default `medium`. | |
| - Enviar `reasoning_effort` como campo top-level del body, no dentro de `extra_body`. | |
| ### mimo-v2.5 | |
| Modelo MoE omnimodal. Especificacion documentada: | |
| - Parametros: 310B totales, 15B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 1M tokens. | |
| - Input: texto, imagen, audio. | |
| - Output: texto. | |
| - Cuota mensual: 500M tokens por miembro. | |
| - Licencia: MIT. | |
| - Capacidades: chat, streaming SSE, tool calling/function calling, reasoning, vision, audio input. | |
| - Reasoning: siempre activo; actualmente no se puede controlar por API con `reasoning_effort` ni con `enable_thinking`. | |
| - Recomendacion documentada: `max_tokens >= 300` como minimo para dejar margen al reasoning. | |
| ### gemma4 | |
| Modelo MoE de texto/chat multimodal con vision. | |
| - Parametros: 26B totales, 4B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 256K tokens. | |
| - Sampling por defecto: `temperature=0.6`, `top_p=0.95`. | |
| - Capacidades: chat, streaming SSE, vision/image input, reasoning mode, tool calling documentado en formato XML. | |
| - Reasoning: desactivado por defecto; se activa con `chat_template_kwargs.enable_thinking: true`. | |
| ### qwen3.6 | |
| Modelo principal de NaN para uso general. | |
| - Tipo: MoE, 35B total. | |
| - Activo por token: 3B. | |
| - Cuantizacion: FP8. | |
| - Contexto: 256K tokens. | |
| - Speculative decoding: MTP, aproximadamente 2x throughput. | |
| - Sampling por defecto: `temperature=0.6`, `top_p=0.95`. | |
| - Capacidades: chat, streaming SSE, vision/image input, tool calling, reasoning. | |
| - Reasoning: activo por defecto; se desactiva con `chat_template_kwargs.enable_thinking: false`. | |
| - La API documenta function calling OpenAI como validado especialmente con `qwen3.6`; si necesitas tool calling estable, usa este modelo primero y prueba el resto antes de depender de tools en produccion. | |
| ### qwen3-embedding | |
| Modelo de embeddings vectoriales. | |
| - Parametros: 8B. | |
| - Dimension: 4096. | |
| - Precision: Float32 en CPU. | |
| - RPM documentado del modelo: 60. | |
| - Batch size: 32. | |
| - Soporta mas de 100 idiomas, español incluido, y codigo. | |
| - Casos de uso: busqueda semantica, similitud cross-lingual, clasificacion, RAG. | |
| - Score documentado: MMTEB 70.58; similitud ES-EN documentada 0.915. | |
| ### rerank | |
| Modelo `Qwen3-Reranker-8B` para reranking semantico. | |
| - Parametros: 8B. | |
| - Precision: BF16. | |
| - Endpoints: `/v1/rerank` y `/v2/rerank`. | |
| - Idiomas: 100+. | |
| - Casos de uso: RAG embedding -> rerank -> LLM, busqueda cross-lingual, recuperacion de codigo, scoring query-documento. | |
| - Respuesta: documentos ordenados por `relevance_score` descendente, manteniendo `index` original. | |
| ### kokoro | |
| Modelo text-to-speech. | |
| - Version: v1.0. | |
| - Parametros: 82M. | |
| - Latencia: sub-segundo en CPU segun docs. | |
| - Voces: 67 voice packs. | |
| - RPM documentado: 15. | |
| - Voces destacadas: `af_heart` English female, `ef_dora` Spanish female, `em_alex` Spanish male. | |
| ### whisper | |
| Modelo speech-to-text. | |
| - Variante: large-v3. | |
| - Runtime documentado: CPU con CTranslate2 e INT8. | |
| - Tamaño aproximado: 3 GB INT8. | |
| - Velocidad: aproximadamente 1x realtime. | |
| - WER ES documentado: ~3.2%. | |
| - RPM documentado: 10. | |
| - Idiomas: 99+. | |
| - Capacidades: transcripcion, deteccion automatica de idioma, API OpenAI-compatible. | |
| - Limite por request: 25 MB. | |
| - Riesgo de timeout: audios de mas de 2 minutos pueden devolver 524. Divide en segmentos de 2 minutos o menos. | |
| - Formatos recomendados: OGG/Opus y MP3; evitan archivos enormes frente a WAV sin comprimir. | |
| ### flux-2-klein | |
| Modelo de imagen. | |
| - Tipo: diffusion/FLUX. | |
| - Endpoints: `/v1/images/generations` y `/v1/images/edits`. | |
| - Modalidades: text-to-image e image-to-image. | |
| - Resolucion: de 256 a 1536 px por lado, multiples de 16, aspect ratio entre 1:3 y 3:1. | |
| - Imagenes por request: `n` entre 1 y 4. | |
| - Output: URL temporal R2 de unos 60 minutos o `b64_json`. | |
| - Extensiones NaN: `seed` para reproducibilidad y `guidance` como guidance scale. | |
| - Cuota mensual: 100 requests por miembro. | |
| - Requiere tier inference. | |
| ## Endpoints | |
| ### Autenticacion | |
| Todas las peticiones deben incluir: | |
| ``` http | |
| Authorization: Bearer sk-tu-key-aqui | |
| ``` | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/models \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" | |
| ``` | |
| ### GET /v1/models | |
| Devuelve los modelos disponibles para la API key. | |
| Modelos publicados en la documentacion: | |
| ``` txt | |
| deepseek-v4-flash | |
| mimo-v2.5 | |
| qwen3.6 | |
| gemma4 | |
| qwen3-embedding | |
| rerank | |
| kokoro | |
| whisper | |
| flux-2-klein | |
| ``` | |
| Request: sin body, solo autenticacion. | |
| Respuesta compatible con OpenAI: | |
| ``` json | |
| { | |
| "object": "list", | |
| "data": [ | |
| { | |
| "id": "qwen3.6", | |
| "object": "model", | |
| "created": 1677610602, | |
| "owned_by": "openai" | |
| } | |
| ] | |
| } | |
| ``` | |
| ### POST /v1/chat/completions | |
| Endpoint principal para chat. Compatible con OpenAI Chat Completions. | |
| Modelos compatibles documentados: | |
| ``` txt | |
| deepseek-v4-flash | |
| mimo-v2.5 | |
| qwen3.6 | |
| gemma4 | |
| ``` | |
| Parametros principales: | |
| - `model` requerido: uno de los modelos anteriores. | |
| - `messages` requerido: array de mensajes `{role, content}`. | |
| - `content` puede ser string o array multimodal, por ejemplo partes `text`, `image_url` y, en `mimo-v2.5`, `input_audio`. | |
| - `max_tokens` opcional: limite de tokens generados. En modelos con reasoning, conviene dejar margen suficiente para evitar truncados. | |
| - `stream` opcional, default `false`; si es `true`, devuelve SSE. | |
| - `tools` opcional: function calling estilo OpenAI `{type:"function", function:{name, description, parameters}}`. | |
| - `tool_choice` opcional: control estandar OpenAI para seleccion de tool. | |
| - `temperature` opcional, default `0.6`. | |
| - `top_p` opcional, default `0.95`. | |
| - `response_format` opcional para structured outputs. | |
| - `chat_template_kwargs` opcional para `enable_thinking` en qwen/gemma. | |
| - `reasoning_effort` opcional para deepseek. | |
| Ejemplo minimo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/chat/completions \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "qwen3.6", | |
| "messages": [{"role": "user", "content": "Hola"}], | |
| "max_tokens": 200 | |
| }' | |
| ``` | |
| Respuesta sin streaming: | |
| ``` json | |
| { | |
| "id": "chatcmpl-...", | |
| "created": 1778258163, | |
| "model": "qwen3.6", | |
| "object": "chat.completion", | |
| "choices": [ | |
| { | |
| "finish_reason": "stop", | |
| "index": 0, | |
| "message": { | |
| "role": "assistant", | |
| "content": "...", | |
| "reasoning_content": "..." | |
| } | |
| } | |
| ], | |
| "usage": { | |
| "completion_tokens": 20, | |
| "prompt_tokens": 17, | |
| "total_tokens": 37 | |
| } | |
| } | |
| ``` | |
| Los clientes deben tolerar que `reasoning_content` exista o no exista segun modelo/configuracion. | |
| Streaming: | |
| - Enviar `stream: true`. | |
| - La respuesta llega como Server-Sent Events. | |
| - Cada chunk usa `data: {...}\n\n`. | |
| - El delta de texto esta en `choices[0].delta.content`. | |
| - El final llega como `data: [DONE]`. | |
| Tool calling: | |
| - `qwen3.6` tiene soporte documentado para function calling estandar OpenAI. | |
| - Cuando el modelo llama una tool, mira `choices[0].message.tool_calls`. | |
| - La estructura es `{id, type:"function", function:{name, arguments}}`. | |
| - `finish_reason` sera `tool_calls`. | |
| Vision: | |
| - `mimo-v2.5`, `qwen3.6` y `gemma4` aceptan imagenes como input. | |
| - Usa `content` como array de partes. | |
| Ejemplo de vision: | |
| ``` json | |
| { | |
| "model": "qwen3.6", | |
| "messages": [ | |
| { | |
| "role": "user", | |
| "content": [ | |
| {"type": "text", "text": "Que hay en esta imagen?"}, | |
| {"type": "image_url", "image_url": {"url": "https://example.com/foto.jpg"}} | |
| ] | |
| } | |
| ] | |
| } | |
| ``` | |
| Structured outputs: | |
| - `response_format: {"type": "json_object"}` fuerza JSON valido sin schema. | |
| - `response_format: {"type": "json_schema", "json_schema": {...}}` fuerza un JSON Schema. | |
| - Con `strict: true`, el modelo no debe emitir campos fuera del schema. | |
| - Funciona en `qwen3.6` y `gemma4`. | |
| Ejemplo de JSON Schema: | |
| ``` json | |
| { | |
| "model": "qwen3.6", | |
| "messages": [{"role": "user", "content": "Alice, 30 anos."}], | |
| "response_format": { | |
| "type": "json_schema", | |
| "json_schema": { | |
| "name": "user", | |
| "strict": true, | |
| "schema": { | |
| "type": "object", | |
| "properties": { | |
| "name": {"type": "string"}, | |
| "age": {"type": "integer"} | |
| }, | |
| "required": ["name", "age"], | |
| "additionalProperties": false | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| Reasoning por modelo: | |
| - `qwen3.6`: usa `chat_template_kwargs.enable_thinking`; activo por defecto. | |
| - `gemma4`: usa `chat_template_kwargs.enable_thinking`; desactivado por defecto. | |
| - `deepseek-v4-flash`: usa `reasoning_effort` top-level con `low`, `medium`, `high`; default `medium`. | |
| - `mimo-v2.5`: siempre activo y no configurable por API actualmente. | |
| Activar thinking en `gemma4` o desactivarlo en `qwen3.6`: | |
| ``` json | |
| { | |
| "model": "gemma4", | |
| "messages": [{"role": "user", "content": "Que es 2+2?"}], | |
| "chat_template_kwargs": {"enable_thinking": true} | |
| } | |
| ``` | |
| En SDKs OpenAI, los campos no estandar suelen ir en `extra_body`: | |
| ``` python | |
| from openai import OpenAI | |
| client = OpenAI( | |
| api_key="sk-tu-key-aqui", | |
| base_url="https://api.nan.builders/v1", | |
| ) | |
| response = client.chat.completions.create( | |
| model="gemma4", | |
| messages=[{"role": "user", "content": "Que es 2+2?"}], | |
| extra_body={"chat_template_kwargs": {"enable_thinking": True}}, | |
| ) | |
| ``` | |
| Ejemplo para DeepSeek reasoning: | |
| ``` json | |
| { | |
| "model": "deepseek-v4-flash", | |
| "messages": [{"role": "user", "content": "Resuelve paso a paso: 3x + 7 = 22"}], | |
| "reasoning_effort": "high" | |
| } | |
| ``` | |
| ### POST /v1/completions | |
| Endpoint legacy de text completion. Para conversaciones usa `/v1/chat/completions`. | |
| Modelo compatible documentado: `qwen3.6`. | |
| Parametros: | |
| - `model` requerido: `qwen3.6`. | |
| - `prompt` requerido. | |
| - `max_tokens` opcional. | |
| - `temperature` opcional, default `0.6`. | |
| - `top_p` opcional, default `0.95`. | |
| - `stream` opcional, default `false`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/completions \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "qwen3.6", | |
| "prompt": "The capital of France is", | |
| "max_tokens": 10 | |
| }' | |
| ``` | |
| Respuesta: | |
| ``` json | |
| { | |
| "id": "cmpl-...", | |
| "object": "text_completion", | |
| "created": 1778258166, | |
| "model": "qwen3.6", | |
| "choices": [ | |
| { | |
| "text": "...", | |
| "index": 0, | |
| "finish_reason": "stop", | |
| "logprobs": null | |
| } | |
| ], | |
| "usage": { | |
| "completion_tokens": 10, | |
| "prompt_tokens": 5, | |
| "total_tokens": 15 | |
| } | |
| } | |
| ``` | |
| ### POST /v1/embeddings | |
| Genera embeddings vectoriales. | |
| Modelo compatible: `qwen3-embedding`. | |
| Parametros: | |
| - `model` requerido: `qwen3-embedding`. | |
| - `input` requerido: string o array de strings. | |
| - `encoding_format` opcional: `"float"` por defecto o `"base64"`. | |
| Respuesta: | |
| - `object: "list"`. | |
| - `model: "qwen3-embedding"`. | |
| - `data[]` con `object: "embedding"`, `index` y `embedding`. | |
| - Vectores de 4096 dimensiones. | |
| - `usage` con tokens. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/embeddings \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "qwen3-embedding", | |
| "input": ["Hola mundo", "Hello world"], | |
| "encoding_format": "float" | |
| }' | |
| ``` | |
| ### POST /v1/rerank | |
| Reordena documentos por relevancia respecto a una query. | |
| Modelo compatible: `rerank`. | |
| Alias: `/v2/rerank`. | |
| Parametros: | |
| - `model` requerido: `rerank`. | |
| - `query` requerido. | |
| - `documents` requerido: array de strings. | |
| - `top_n` opcional: limita cuantos resultados devolver. | |
| Respuesta: | |
| - `id`. | |
| - `results[]` con `index`, `relevance_score` entre 0 y 1 y `document.text`. | |
| - `index` es la posicion original del documento de entrada. | |
| - `meta.billed_units.total_tokens` y `meta.tokens.input_tokens`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/rerank \ | |
| -H "Authorization: Bearer $NAN_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "rerank", | |
| "query": "What is the capital of France?", | |
| "documents": [ | |
| "Paris is the capital of France and home to the Eiffel Tower.", | |
| "Berlin is the capital of Germany.", | |
| "Madrid is the capital of Spain." | |
| ] | |
| }' | |
| ``` | |
| En el SDK OpenAI puedes usar `client.post(path="/rerank", cast_to=object, body={...})`, porque `rerank` no forma parte del cliente OpenAI estandar. | |
| ### POST /v1/audio/speech | |
| Text-to-speech. | |
| Modelo compatible: `kokoro`. | |
| Parametros: | |
| - `model` requerido: `kokoro`. | |
| - `input` requerido: texto a sintetizar. | |
| - `voice` requerido: por ejemplo `af_heart`, `ef_dora`, `em_alex`. | |
| - `response_format` opcional: `mp3` default, `wav`, `flac`, `aac`, `pcm`, `opus`. | |
| - `speed` opcional, default `1.0`. | |
| Respuesta: archivo binario de audio, sin envoltorio JSON. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/audio/speech \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "kokoro", | |
| "input": "Bienvenido a NaN.", | |
| "voice": "ef_dora", | |
| "response_format": "mp3" | |
| }' \ | |
| -o speech.mp3 | |
| ``` | |
| ### POST /v1/audio/transcriptions | |
| Speech-to-text. La peticion es `multipart/form-data`. | |
| Modelo compatible: `whisper`. | |
| Parametros: | |
| - `file` requerido: archivo de audio. | |
| - `model` requerido: `whisper`. | |
| - `language` opcional: codigo ISO-639-1 como `es` o `en`; si falta, se detecta automaticamente. | |
| - `response_format` opcional: `json` default o `verbose_json`. Otros valores pueden funcionar pero vuelven envueltos en JSON; recomienda usar solo estos dos. | |
| - `timestamp_granularities[]` opcional: solo con `verbose_json`; `word` para palabras o `segment` default. | |
| - `temperature` opcional. | |
| Respuesta `verbose_json`: | |
| - `text`. | |
| - `language`. | |
| - `task`. | |
| - `duration`. | |
| - `segments[]` con timestamps, tokens y metricas. | |
| - `words`, si se pidio granularidad por palabra, con `{word, start, end, probability}`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/audio/transcriptions \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -F "model=whisper" \ | |
| -F "file=@grabacion.mp3" \ | |
| -F "language=es" \ | |
| -F "response_format=verbose_json" | |
| ``` | |
| Limitaciones: | |
| - Maximo 25 MB por archivo. | |
| - Audios mayores de 2 minutos pueden devolver timeout 524. | |
| - Divide audios largos en trozos de 2 minutos o menos. | |
| - Usa MP3 u OGG/Opus para mejor compresion. | |
| La pagina de ejemplos tambien muestra `/v1/audio/translations` con `whisper` para traducir audio a ingles, usando multipart con `model=whisper` y `file=@grabacion.mp3`. | |
| ### POST /v1/responses | |
| Endpoint estilo OpenAI Responses. | |
| Modelos compatibles: `qwen3.6` y `gemma4`. | |
| Parametros: | |
| - `model` requerido: `qwen3.6` o `gemma4`. | |
| - `input` requerido: texto o array de mensajes en formato Responses. | |
| - `max_output_tokens` opcional; default documentado en `qwen3.6`: `65536`. | |
| - `temperature` opcional, default `0.6`. | |
| - `top_p` opcional, default `0.95`. | |
| - `instructions` opcional: instrucciones de sistema. | |
| Respuesta: | |
| - `output[]` puede incluir bloques `reasoning` en `qwen3.6`. | |
| - Tambien incluye bloques `message` con `content[]` de tipo `output_text`. | |
| - `usage` reporta `input_tokens`, `output_tokens` y `total_tokens`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/responses \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "qwen3.6", | |
| "input": "Hola, como estas?" | |
| }' | |
| ``` | |
| Nota de streaming: actualmente este endpoint entrega un unico evento `response.completed` al final, no chunks incrementales. Para streaming token a token usa `/v1/chat/completions` con `stream: true`. | |
| ### POST /v1/images/generations | |
| Text-to-image compatible con Images API de OpenAI. | |
| Modelo compatible: `flux-2-klein`. | |
| Body: JSON. | |
| Parametros: | |
| - `prompt` requerido. | |
| - `model` opcional, default `flux-2-klein`; modelo desconocido devuelve 404 `model_not_found`. | |
| - `n` opcional, entre 1 y 4, default 1; mayor que 4 devuelve 400. | |
| - `size` opcional: `"ANCHOxALTO"`, ambos lados divisibles por 16, entre 256 y 1536, aspect ratio entre 1:3 y 3:1. `"auto"` u omitido significa `1024x1024`. | |
| - `response_format` opcional: `"url"` default o `"b64_json"`. Las URL temporales de R2 duran unos 60 minutos. | |
| Parametros aceptados pero ignorados por compatibilidad con SDKs OpenAI: | |
| - `quality` | |
| - `style` | |
| - `background` | |
| - `moderation` | |
| - `output_format` | |
| - `output_compression` | |
| - `user` | |
| No soporta `stream: true`; devuelve 400. | |
| Extensiones NaN: | |
| - `seed`: seed base para reproducibilidad. Si `n > 1`, cada variante usa offset sobre esa seed. | |
| - `guidance`: guidance scale de FLUX. | |
| - En SDK OpenAI, pasarlas en `extra_body`. | |
| Respuesta: | |
| ``` json | |
| { | |
| "created": 1778258200, | |
| "data": [ | |
| {"url": "https://...r2.../image.png"} | |
| ] | |
| } | |
| ``` | |
| Con `response_format: "b64_json"`, cada elemento usa `{"b64_json": "..."}`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/images/generations \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "flux-2-klein", | |
| "prompt": "Un faro al atardecer sobre acantilados, estilo cinematico", | |
| "size": "1024x1024" | |
| }' | |
| ``` | |
| Python con `seed` y `guidance`: | |
| ``` python | |
| from openai import OpenAI | |
| client = OpenAI( | |
| api_key="sk-tu-key-aqui", | |
| base_url="https://api.nan.builders/v1", | |
| ) | |
| response = client.images.generate( | |
| model="flux-2-klein", | |
| prompt="Un faro al atardecer sobre acantilados, estilo cinematico", | |
| size="1024x1024", | |
| n=1, | |
| extra_body={"seed": 42, "guidance": 3.5}, | |
| ) | |
| print(response.data[0].url) | |
| ``` | |
| Limites de imagen: | |
| - No comparten los limites de chat/LiteLLM. | |
| - Rate limit de imagen: 1 request por segundo sostenido, burst hasta 3. | |
| - Al exceder rate limit: 429 `rate_limit_exceeded`. | |
| - Cuota mensual de imagen: 100 requests por usuario/mes. | |
| - 1 request cuenta igual aunque `n` sea mayor que 1. | |
| - Cuota de imagen independiente de la cuota de tokens de chat. | |
| - Requiere tier inference; tier community devuelve 403 `tier_restricted`. | |
| ### POST /v1/images/edits | |
| Image-to-image compatible con Images API de OpenAI. | |
| Modelo compatible: `flux-2-klein`. | |
| Peticion: `multipart/form-data`. | |
| Parametros: | |
| - `image` o `image[]` requerido: hasta 4 imagenes de referencia; las extras se descartan. | |
| - Formatos de referencia: PNG, JPEG o WebP. | |
| - Cada imagen debe pesar menos de 25 MB. | |
| - `prompt` requerido. | |
| - `model`, `n`, `size`, `response_format`: igual que en `/v1/images/generations`. | |
| - `seed` y `guidance`: aceptados como campos del form. | |
| No soporta `mask`; devuelve 400 porque Flux Klein no hace inpainting. | |
| Respuesta: igual que generaciones, `{"created": ..., "data": [{"url": "..."}]}` o `b64_json`. | |
| Ejemplo: | |
| ``` bash | |
| curl https://api.nan.builders/v1/images/edits \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -F "model=flux-2-klein" \ | |
| -F "image[]=@ref.png" \ | |
| -F "prompt=Convierte la escena en invierno con nieve" \ | |
| -F "size=1024x1024" | |
| ``` | |
| ## Errores | |
| Formato de error compatible con OpenAI: | |
| ``` json | |
| { | |
| "error": { | |
| "message": "...", | |
| "type": null, | |
| "param": null, | |
| "code": "..." | |
| } | |
| } | |
| ``` | |
| Codigos comunes: | |
| - 400: parametro invalido. En imagenes puede indicar `prompt`, `n`, `size`, `stream`, `mask` o `image`; filtro de seguridad usa `content_policy_violation`. | |
| - 401: `Authorization` ausente o invalido; `invalid_api_key`. | |
| - 403: tier sin acceso; `tier_restricted`, especialmente imagenes sin tier inference. | |
| - 404: modelo no existe; `model_not_found`. | |
| - 429: rate limit o concurrencia excedida; `rpm_limit`, `max_parallel_requests`, `rate_limit_exceeded`, `quota_exceeded` o `insufficient_quota`. | |
| - 500: error interno o upstream del modelo. | |
| - 524: timeout, tipico en audios grandes con `/v1/audio/transcriptions`. | |
| ## Rate limits y cuotas | |
| Limites generales por API key: | |
| - Requests por minuto: 60 rpm. | |
| - Paralelo maximo: 5 concurrentes. | |
| Tokens por minuto por modelo: | |
| - `deepseek-v4-flash`: 1.5M tpm. | |
| - `mimo-v2.5`: 1.5M tpm. | |
| - `qwen3.6`: 1.5M tpm. | |
| - `gemma4`: 1.5M tpm. | |
| Requests por minuto por modelo: | |
| - `rerank`: 1000 rpm. | |
| Cuotas: | |
| - `deepseek-v4-flash`: 500M tokens/mes por miembro. | |
| - `mimo-v2.5`: 500M tokens/mes por miembro. | |
| - Imagenes `flux-2-klein`: 100 requests/mes por usuario. | |
| ## SDKs y snippets de uso | |
| ### cURL chat | |
| ``` bash | |
| curl https://api.nan.builders/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -H "Authorization: Bearer sk-tu-key-aqui" \ | |
| -d '{ | |
| "model": "qwen3.6", | |
| "messages": [{"role": "user", "content": "Hola, como estas?"}], | |
| "max_tokens": 500 | |
| }' | |
| ``` | |
| ### Python OpenAI SDK | |
| Instalar: | |
| ``` bash | |
| pip install openai | |
| ``` | |
| Chat streaming: | |
| ``` python | |
| from openai import OpenAI | |
| client = OpenAI( | |
| api_key="sk-tu-key-aqui", | |
| base_url="https://api.nan.builders/v1", | |
| ) | |
| stream = client.chat.completions.create( | |
| model="qwen3.6", | |
| messages=[{"role": "user", "content": "Escribe un hola mundo en Rust"}], | |
| max_tokens=500, | |
| stream=True, | |
| ) | |
| for chunk in stream: | |
| content = chunk.choices[0].delta.content | |
| if content: | |
| print(content, end="", flush=True) | |
| ``` | |
| Embeddings: | |
| ``` python | |
| response = client.embeddings.create( | |
| model="qwen3-embedding", | |
| input=["Kubernetes pod scheduling", "Programacion de pods Kubernetes"], | |
| encoding_format="float", | |
| ) | |
| vectors = [item.embedding for item in response.data] | |
| assert len(vectors[0]) == 4096 | |
| ``` | |
| Rerank: | |
| ``` python | |
| response = client.post( | |
| path="/rerank", | |
| cast_to=object, | |
| body={ | |
| "model": "rerank", | |
| "query": "What is the capital of France?", | |
| "documents": [ | |
| "Paris is the capital of France.", | |
| "Berlin is the capital of Germany.", | |
| "Madrid is the capital of Spain.", | |
| ], | |
| }, | |
| ) | |
| ``` | |
| Text-to-speech: | |
| ``` python | |
| response = client.audio.speech.create( | |
| model="kokoro", | |
| voice="ef_dora", | |
| input="Hola, bienvenido a NaN builders.", | |
| speed=1.0, | |
| response_format="mp3", | |
| ) | |
| response.stream_to_file("output.mp3") | |
| ``` | |
| Speech-to-text: | |
| ``` python | |
| with open("grabacion.mp3", "rb") as f: | |
| result = client.audio.transcriptions.create( | |
| model="whisper", | |
| file=f, | |
| language="es", | |
| response_format="verbose_json", | |
| ) | |
| print(result.text) | |
| ``` | |
| ### Node.js OpenAI SDK | |
| Instalar: | |
| ``` bash | |
| npm install openai | |
| ``` | |
| Chat streaming: | |
| ``` js | |
| import OpenAI from "openai"; | |
| const client = new OpenAI({ | |
| apiKey: "sk-tu-key-aqui", | |
| baseURL: "https://api.nan.builders/v1", | |
| }); | |
| const stream = await client.chat.completions.create({ | |
| model: "qwen3.6", | |
| messages: [{ role: "user", content: "Escribe un hola mundo en Zig" }], | |
| max_tokens: 500, | |
| stream: true, | |
| }); | |
| for await (const chunk of stream) { | |
| const content = chunk.choices[0]?.delta?.content; | |
| if (content) process.stdout.write(content); | |
| } | |
| ``` | |
| Embeddings: | |
| ``` js | |
| const response = await client.embeddings.create({ | |
| model: "qwen3-embedding", | |
| input: ["Hello world", "Hola mundo"], | |
| encoding_format: "float", | |
| }); | |
| const vectors = response.data.map((item) => item.embedding); | |
| console.log(vectors[0].length); // 4096 | |
| ``` | |
| Text-to-speech: | |
| ``` js | |
| import fs from "fs"; | |
| const response = await client.audio.speech.create({ | |
| model: "kokoro", | |
| voice: "ef_dora", | |
| input: "Hola, bienvenido a NaN builders.", | |
| speed: 1.0, | |
| response_format: "mp3", | |
| }); | |
| const buffer = Buffer.from(await response.arrayBuffer()); | |
| fs.writeFileSync("output.mp3", buffer); | |
| ``` | |
| ## Configuracion de herramientas | |
| ### Variables de entorno genericas | |
| Muchos clientes OpenAI-compatible leen estas variables: | |
| ``` bash | |
| export OPENAI_BASE_URL="https://api.nan.builders/v1" | |
| export OPENAI_API_KEY="sk-tu-key-aqui" | |
| ``` | |
| Si el cliente usa `BASE_URL`, `OPENAI_API_BASE`, `OPENAI_API_URL` o `api_url`, pon siempre `https://api.nan.builders/v1`. | |
| ### OpenAI-compatible provider generico | |
| ``` js | |
| provider: { | |
| openai: { | |
| npm: "@ai-sdk/openai", | |
| name: "NaN", | |
| apiKey: "sk-tu-key-aqui", | |
| baseURL: "https://api.nan.builders/v1", | |
| model: "qwen3.6" | |
| } | |
| } | |
| ``` | |
| ### OpenCode / opencode.json | |
| Usa `@ai-sdk/openai-compatible`, base URL de NaN y define modelos. En algunas herramientas conviene usar `contextWindow: 500000` para modelos de 1M si la herramienta no tolera ventanas tan grandes; la capacidad documentada de `deepseek-v4-flash` y `mimo-v2.5` es 1M. | |
| ``` json | |
| { | |
| "$schema": "https://opencode.ai/config.json", | |
| "provider": { | |
| "nan": { | |
| "npm": "@ai-sdk/openai-compatible", | |
| "name": "NaN", | |
| "options": { | |
| "baseURL": "https://api.nan.builders/v1", | |
| "apiKey": "sk-tu-key-aqui" | |
| }, | |
| "models": { | |
| "qwen3.6": { | |
| "name": "Qwen 3.6", | |
| "contextWindow": 262144, | |
| "modalities": {"input": ["text", "image"], "output": ["text"]} | |
| }, | |
| "gemma4": { | |
| "name": "Gemma 4", | |
| "contextWindow": 262144, | |
| "modalities": {"input": ["text", "image"], "output": ["text"]} | |
| }, | |
| "deepseek-v4-flash": { | |
| "name": "DeepSeek V4 Flash", | |
| "contextWindow": 500000, | |
| "modalities": {"input": ["text"], "output": ["text"]} | |
| }, | |
| "mimo-v2.5": { | |
| "name": "Xiaomi MiMo V2.5", | |
| "contextWindow": 500000, | |
| "modalities": {"input": ["text", "image", "audio"], "output": ["text"]} | |
| } | |
| } | |
| } | |
| }, | |
| "compaction": { | |
| "auto": true, | |
| "prune": true, | |
| "reserved": 50000 | |
| } | |
| } | |
| ``` | |
| ### ~/.pi/agent/models.json | |
| ``` json | |
| { | |
| "providers": { | |
| "nan": { | |
| "baseUrl": "https://api.nan.builders/v1", | |
| "api": "openai-completions", | |
| "apiKey": "<api-key>", | |
| "compat": { | |
| "supportsDeveloperRole": true | |
| }, | |
| "models": [ | |
| { | |
| "id": "qwen3.6", | |
| "name": "Qwen 3.6", | |
| "reasoning": true, | |
| "input": ["text", "image"], | |
| "contextWindow": 262144, | |
| "maxTokens": 16384 | |
| }, | |
| { | |
| "id": "gemma4", | |
| "name": "Gemma 4", | |
| "reasoning": true, | |
| "input": ["text", "image"], | |
| "contextWindow": 262144, | |
| "maxTokens": 16384 | |
| } | |
| ] | |
| } | |
| } | |
| } | |
| ``` | |
| ### ~/.openclaw/openclaw.json | |
| ``` json | |
| { | |
| "models": { | |
| "providers": { | |
| "nan": { | |
| "baseUrl": "https://api.nan.builders/v1", | |
| "apiKey": "sk-...", | |
| "api": "openai-completions", | |
| "models": [ | |
| { | |
| "id": "qwen3.6", | |
| "name": "Qwen 3.6", | |
| "reasoning": true, | |
| "input": ["text", "image"], | |
| "contextWindow": 262144, | |
| "maxTokens": 65536 | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "agents": { | |
| "defaults": { | |
| "model": {"primary": "nan/qwen3.6"}, | |
| "models": { | |
| "nan/qwen3.6": { | |
| "params": { | |
| "maxTokens": 16000 | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| Explicacion practica: | |
| - `models.providers.nan.models[].maxTokens` indica la capacidad maxima configurada. | |
| - `agents.defaults.models["nan/..."].params.maxTokens` indica lo enviado por request. | |
| - Para `qwen3.6`, 16K suele ser buen balance. | |
| ### Zed settings.json | |
| Ruta habitual: `~/.config/zed/settings.json`. | |
| ``` json | |
| { | |
| "language_models": { | |
| "openai": { | |
| "api_url": "https://api.nan.builders/v1", | |
| "available_models": [ | |
| { | |
| "name": "qwen3.6", | |
| "display_name": "NaN Qwen 3.6", | |
| "max_tokens": 262144 | |
| } | |
| ] | |
| } | |
| }, | |
| "edit_predictions": { | |
| "open_ai_compatible_api": { | |
| "api_url": "https://api.nan.builders/v1", | |
| "model": "qwen3.6" | |
| } | |
| } | |
| } | |
| ``` | |
| ### Cursor | |
| Configura proveedor OpenAI-compatible: | |
| ``` txt | |
| Base URL: https://api.nan.builders/v1 | |
| API Key: sk-tu-key-aqui | |
| Model: qwen3.6 | |
| ``` | |
| ### Cline, Continue, Aider y clientes similares | |
| Usa las variables de entorno o la UI de proveedor OpenAI-compatible: | |
| ``` bash | |
| export OPENAI_BASE_URL="https://api.nan.builders/v1" | |
| export OPENAI_API_KEY="sk-tu-key-aqui" | |
| ``` | |
| Modelo recomendado por defecto: `qwen3.6`. | |
| Para vision: usa `qwen3.6`, `gemma4` o `mimo-v2.5`. | |
| Para audio input multimodal: usa `mimo-v2.5`. | |
| ## Recomendaciones operativas | |
| 1. Empieza con `qwen3.6` para validar que la key y el base URL funcionan. | |
| 2. Comprueba `/v1/models` antes de diagnosticar problemas de modelo. | |
| 3. En clientes que soporten razonamiento separado, conserva `reasoning_content` si existe, pero no falles si no existe. | |
| 4. En clientes con streaming, usa `/v1/chat/completions`, no `/v1/responses`, si necesitas tokens incrementales. | |
| 5. En RAG: usa `qwen3-embedding` para recuperar candidatos, `rerank` para reordenarlos y despues `qwen3.6` o `deepseek-v4-flash` para responder. | |
| 6. En Whisper, trocea audios largos antes de mandarlos para evitar 524. | |
| 7. En imagenes, recuerda que la cuota es por request, no por imagen generada dentro del request. |
