# Usar Gyblos desde tu código

Inicia el comprador local y apunta clientes de OpenAI o Anthropic a él para conversar con un vendedor de Gyblos.

Source: https://docs.gyblos.com/es/buyers/use-from-code

El comprador es un pequeño servidor en tu propio computador, en `http://127.0.0.1:4031`. Habla las API de
OpenAI y Anthropic, así que los programas hechos para esos servicios pueden usar un vendedor de Gyblos
cambiando su URL base. En cada pedido obtiene una cotización gratuita firmada del vendedor y devuelve la
respuesta en streaming por una conexión directa entre pares.

## Qué funciona hoy

| Función                                                                   | Estado en la beta                              |
| ------------------------------------------------------------------------- | ---------------------------------------------- |
| Conversaciones completas: mensaje de sistema, historial y mensaje nuevo   | Sí, hasta 1024 mensajes                        |
| `POST /v1/chat/completions` de OpenAI y `POST /v1/messages` de Anthropic  | Sí, respuestas completas y en streaming        |
| `GET /v1/models`                                                          | Sí, el modelo que pide tu comprador            |
| Ofertas gratuitas                                                         | Sí                                             |
| Herramientas (function calling), ambos formatos, completas y en streaming | Sí, ver [Herramientas](#herramientas)          |
| Claude Code                                                               | Solo con un vendedor de un modelo más grande   |
| Modo agente de Cursor                                                     | No: llama desde la nube de Cursor              |
| Imágenes, salida estructurada, varias respuestas                          | Todavía no: se rechazan con un error 400 claro |
| Ofertas de pago                                                           | Fuera de esta guía                             |

Por defecto, un vendedor atiende a cada comprador hasta **30 respuestas por minuto**. Una respuesta tiene
como máximo **4096 tokens**, salvo que subas el límite del comprador (hasta 32768); un pedido más largo se
atiende hasta ese límite y termina con el motivo `length`.

Tu mensaje llega al vendedor que configuraste, cuyo equipo ejecuta el modelo y puede leerlo. No envíes
contraseñas, claves ni otros secretos.

## Antes de empezar

- Una invitación con un **token de relay** privado.
- El **NodeId** y la **wallet dueña** del vendedor que usarás, de una fuente en la que confíes (el vendedor
  muestra ambos con `gyblos doctor`). El vendedor debe estar registrado; el comprador verifica su identidad
  en Solana devnet.
- Git, [Node.js](https://nodejs.org) 24.22.1 o posterior y pnpm 10 (`corepack enable` lo instala).

En la beta, el comprador se ejecuta desde el repositorio de código; el instalador y el paquete de npm
contienen solo el vendedor.

## Instalar y configurar

```sh
git clone https://github.com/Gyblos/gyblos-node.git
cd gyblos-node
pnpm install --frozen-lockfile
pnpm buyer:init
```

`buyer:init` pide el NodeId y la wallet dueña del vendedor, muestra la configuración (modelo `qwen3-0.6b`,
respuestas de hasta 4096 tokens, solo cotizaciones gratuitas) y la guarda cuando confirmas. No envía nada al
vendedor ni a la cadena. `pnpm buyer:init --advanced` permite además elegir el modelo, el límite de
respuesta y los endpoints.

## Iniciar el comprador

Escribe el token de relay sin que se muestre y luego inicia el comprador en la misma terminal:

```sh
read -rs GYBLOS_RELAY_TOKEN && export GYBLOS_RELAY_TOKEN
pnpm buyer:free
```

Déjalo corriendo. En otra terminal, comprueba que responde:

```sh
curl http://127.0.0.1:4031/v1/models
```

La lista nombra el único modelo que pide tu comprador; usa ese nombre como `model` en tus pedidos. Si
prefieres una conversación rápida en la terminal, ejecuta `pnpm buyer:chat`, que inicia su propio comprador.

## Enviar una conversación

```sh
curl http://127.0.0.1:4031/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{
    "model": "qwen3-0.6b",
    "messages": [
      {"role": "system", "content": "Answer in one short sentence."},
      {"role": "user", "content": "My name is Ana."},
      {"role": "assistant", "content": "Nice to meet you, Ana!"},
      {"role": "user", "content": "What is my name?"}
    ]
  }'
```

### SDK de OpenAI

Usa la URL base `http://127.0.0.1:4031/v1`. El comprador gratuito no revisa la clave de API, pero el SDK
necesita una que no esté vacía.

```js
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://127.0.0.1:4031/v1',
  apiKey: 'local',
});
const stream = await client.chat.completions.create({
  model: 'qwen3-0.6b',
  stream: true,
  messages: [
    { role: 'system', content: 'Be brief.' },
    { role: 'user', content: 'My dog is called Rocky.' },
    { role: 'assistant', content: 'Got it: your dog is Rocky.' },
    { role: 'user', content: "What is my dog's name?" },
  ],
});
for await (const chunk of stream)
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
```

### SDK de Anthropic

Usa la URL base `http://127.0.0.1:4031` (sin `/v1`). `max_tokens` es obligatorio, igual que con Anthropic.

```js
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  baseURL: 'http://127.0.0.1:4031',
  apiKey: 'local',
});
const message = await client.messages.create({
  model: 'qwen3-0.6b',
  max_tokens: 200,
  system: 'Be brief.',
  messages: [
    { role: 'user', content: 'My dog is called Rocky.' },
    { role: 'assistant', content: 'Got it: your dog is Rocky.' },
    { role: 'user', content: "What is my dog's name?" },
  ],
});
console.log(message.content[0].text);
```

## Herramientas

Envía `tools` tal como lo define cada API. Cuando el modelo quiere usar una herramienta, la respuesta
termina con `finish_reason: "tool_calls"` (en Anthropic, `stop_reason: "tool_use"`) y trae la llamada. Tu
programa ejecuta la herramienta y devuelve el resultado en el siguiente pedido, con la conversación completa:

```js
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://127.0.0.1:4031/v1',
  apiKey: 'local',
});
const tools = [
  {
    type: 'function',
    function: {
      name: 'get_time',
      description: 'Current local time in a city',
      parameters: {
        type: 'object',
        properties: { city: { type: 'string' } },
        required: ['city'],
      },
    },
  },
];
const messages = [
  { role: 'user', content: 'What time is it in Santiago? Use the tool.' },
];
const first = await client.chat.completions.create({
  model: 'qwen3-0.6b',
  messages,
  tools,
});
const call = first.choices[0].message.tool_calls[0];
// Run the tool yourself, then send its result back.
messages.push(first.choices[0].message, {
  role: 'tool',
  tool_call_id: call.id,
  content: '15:42',
});
const second = await client.chat.completions.create({
  model: 'qwen3-0.6b',
  messages,
  tools,
});
console.log(second.choices[0].message.content);
```

Con el SDK de Anthropic, envía `tools` con `input_schema`, lee los bloques `tool_use` y responde con bloques
`tool_result`, igual que con Anthropic. El comprador solo le pregunta a vendedores que sirven herramientas;
si ninguno lo hace, responde 503 y lo dice.

El modelo por defecto, qwen3:0.6b, resuelve llamadas simples como esta. Los agentes que envían muchas
herramientas e instrucciones largas, como Claude Code, necesitan un vendedor con un modelo más grande, a
través del motor OpenAI o Anthropic.

## Opciones y errores

Las opciones que los clientes envían por defecto y que no cambian la respuesta se aceptan y se ignoran, como
`temperature`, `top_p`, `user`, `metadata`, `stream_options` y, en el formato de Anthropic, `thinking`
(el razonamiento siempre está apagado). Las que sí la cambiarían se rechazan salvo que tengan su valor
neutro: `response_format` (`text`), `n` (1), `stop` y `stop_sequences`, y `logprobs`. Las imágenes siempre
se rechazan.

| Respuesta | Significado                                                                                                                                                                   |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400       | El pedido usa algo que todavía no se admite; el mensaje y `param` lo nombran.                                                                                                 |
| 503       | No hay un vendedor disponible ahora. Con `Retry-After`, el vendedor falló hace poco o llegó a su límite por minuto: los SDK de OpenAI y Anthropic esperan y reintentan solos. |
| 504       | El vendedor no respondió a tiempo.                                                                                                                                            |

Los errores usan la forma de cada API, así que los SDK lanzan sus excepciones habituales.
