Gyblosdocs
Buyers

Use Gyblos from your code

Run the local buyer and point OpenAI or Anthropic clients at it to chat with a Gyblos seller.

View Markdown

The buyer is a small server on your own computer, at http://127.0.0.1:4031. It speaks the OpenAI and Anthropic APIs, so programs written for those services can use a Gyblos seller by changing their base URL. For each request it gets a signed free quote from the seller and streams the answer back over a direct peer-to-peer connection.

What works today

FeatureBeta status
Whole conversations: system message, history, new messageYes, up to 1024 messages
OpenAI POST /v1/chat/completions and Anthropic POST /v1/messagesYes, whole answers and streaming
GET /v1/modelsYes, the model your buyer asks for
Free offersYes
Tools (function calling), both formats, whole answers and streamingYes, see Tools
Claude CodeOnly with a seller on a larger model
Cursor agent modeNo: it calls from Cursor's cloud
Images, structured output, several answersNot yet: refused with a clear 400 error
Paid offersOutside this guide

A seller serves each buyer up to 30 answers per minute by default. An answer is at most 4096 tokens unless you raise the buyer's limit (up to 32768); a longer request is served up to that limit and ends with finish reason length.

Your prompt reaches the seller you configured, whose machine runs the model and can read it. Do not send passwords, keys or other secrets.

Before you start

  • An invitation with a private relay token.
  • The NodeId and owner wallet of the seller you will use, from a source you trust (the seller prints both with gyblos doctor). The seller must be registered; the buyer checks its identity on Solana devnet.
  • Git, Node.js 24.22.1 or later, and pnpm 10 (corepack enable provides it).

In the beta the buyer runs from the source repository; the installer and the npm package contain the seller only.

Install and configure

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

buyer:init asks for the seller's NodeId and owner wallet, shows the settings (model qwen3-0.6b, answers up to 4096 tokens, free quotes only) and saves them after you confirm. It sends nothing to the seller or the chain. pnpm buyer:init --advanced also sets the model, the answer limit and the endpoints.

Start the buyer

Type the relay token without showing it, then start the buyer in the same terminal:

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

Leave it running. In another terminal, check that it answers:

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

The list names the one model your buyer asks for; use that name as model in your requests. For a quick conversation in the terminal instead, run pnpm buyer:chat, which starts its own buyer.

Send a conversation

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?"}
    ]
  }'

OpenAI SDK

Use base URL http://127.0.0.1:4031/v1. The free buyer does not check the API key, but the SDK needs a non-empty one.

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 ?? '');

Anthropic SDK

Use base URL http://127.0.0.1:4031 (without /v1). max_tokens is required, as with Anthropic.

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);

Tools

Send tools as each API defines them. When the model wants a tool, the answer ends with finish_reason: "tool_calls" (Anthropic: stop_reason: "tool_use") and carries the call. Your program runs the tool and sends the result back in the next request, with the whole conversation:

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);

With the Anthropic SDK, send tools with input_schema, read the tool_use blocks and answer with tool_result blocks, as with Anthropic. The buyer asks only sellers that serve tools; if none does, it answers 503 and says so.

The default model, qwen3:0.6b, handles simple calls like this one. Agents that send many tools and long instructions, such as Claude Code, need a seller on a larger model through the OpenAI or Anthropic engine.

Options and errors

Options that clients send by default and that do not change the answer are accepted and ignored, such as temperature, top_p, user, metadata, stream_options and, in the Anthropic format, thinking (thinking is always off). Options that would change it are refused unless they hold their neutral value: response_format (text), n (1), stop and stop_sequences, and logprobs. Images are always refused.

AnswerMeaning
400The request uses something not supported yet; the message and param name it.
503No seller is available right now. With Retry-After, the seller failed recently or hit its per-minute limit: the OpenAI and Anthropic SDKs wait and retry on their own.
504The seller did not answer in time.

Errors use each API's own shape, so SDKs raise their usual exceptions.

On this page