# Thinking

> Both models reason before they answer. Choose how hard they think, and read the reasoning alongside the answer.

Source: https://www.lyber.ai/docs/capabilities/thinking/ · Markdown: https://www.lyber.ai/docs/md/capabilities/thinking.md

## Reasoning effort

Set `reasoning_effort` to trade speed and cost for depth. `none` turns reasoning off.

| Model | Accepted values |
| --- | --- |
| `minimax-m3.1-flash-abliterated` | `none` `low` `high` `max` |
| `deepseek-v4.1-flash-1017-abliterated` | `none` `low` `high` `xhigh` `max` |

Any other value, `medium` included, gets `400 unsupported_parameter`. The accepted values for each model are also listed in `lyber.reasoning_effort_options` from [`GET /v1/models`](https://www.lyber.ai/docs/api/models/).

Python (`main.py`):

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://lyber-paid-acceptance-gateway-production.up.railway.app/v1",
    api_key=os.environ["LYBER_API_KEY"],
)

response = client.chat.completions.create(
    model="minimax-m3.1-flash-abliterated",
    messages=[{"role": "user", "content": "Is 1,000,003 prime?"}],
    reasoning_effort="high",
    max_tokens=8192,
)
message = response.choices[0].message
print(getattr(message, "reasoning_content", None))  # the model's reasoning
print(message.content)                              # the answer
```

TypeScript (`main.ts`):

```ts
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://lyber-paid-acceptance-gateway-production.up.railway.app/v1",
  apiKey: process.env.LYBER_API_KEY,
});

const response = await client.chat.completions.create({
  model: "minimax-m3.1-flash-abliterated",
  messages: [{ role: "user", content: "Is 1,000,003 prime?" }],
  reasoning_effort: "high",
  max_tokens: 8192,
});
const message = response.choices[0].message as OpenAI.ChatCompletionMessage & { reasoning_content?: string };
console.log(message.reasoning_content); // the model's reasoning
console.log(message.content);           // the answer
```

curl (`request.sh`):

```bash
curl https://lyber-paid-acceptance-gateway-production.up.railway.app/v1/chat/completions \
  -H "Authorization: Bearer $LYBER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax-m3.1-flash-abliterated",
    "messages": [{"role": "user", "content": "Is 1,000,003 prime?"}],
    "reasoning_effort": "high",
    "max_tokens": 8192
  }'
```

## Reading the reasoning

The reasoning comes back as plain text in `message.reasoning_content`, or `delta.reasoning_content` when streaming, separate from the answer in `content`. Some runtimes name the field `reasoning`; read either. Lyber passes the model's text through unchanged.

In multi-turn conversations you can send an assistant turn's `reasoning_content` back with it, or leave it out.

## Thinking budget

The DeepSeek model also accepts `thinking_token_budget`, a cap on reasoning tokens. It must be no larger than `max_tokens` or 262,144, and can't be combined with `reasoning_effort: "none"`.

```json
{
  "model": "deepseek-v4.1-flash-1017-abliterated",
  "messages": [{"role": "user", "content": "Plan a three-step migration."}],
  "reasoning_effort": "high",
  "thinking_token_budget": 4096,
  "max_tokens": 8192
}
```

## Billing

Reasoning tokens are output tokens: they count toward `max_tokens` and bill at the output rate. When the runtime reports it, `usage.completion_tokens_details.reasoning_tokens` shows how many there were. If the reasoning uses the whole allowance, the answer stops with `finish_reason: "length"`; raise `max_tokens` or lower the effort.

> **Note:** The `reasoning` object and `thinking` fields used by some other APIs are not accepted on Chat Completions. On the [Responses API](https://www.lyber.ai/docs/api/responses/), `reasoning.effort` maps to `reasoning_effort`.
