# OpenAI-совместимый API

samreshuuu предоставляет drop-in эндпоинт `chat/completions`. Если вы уже используете OpenAI SDK, поменяйте base URL и API-ключ — больше ничего.

- **Base URL:** `https://api.samreshuuu.ru/v1`
- **Авторизация:** API-ключ со scope `chat` (см. [Аутентификацию](/docs/authentication))

## Drop-in пример

**Python**

```python
from openai import OpenAI

client = OpenAI(
    api_key="sk-org-your_api_key",
    base_url="https://api.samreshuuu.ru/v1",
)

resp = client.chat.completions.create(
    model="samreshuuu",
    messages=[{"role": "user", "content": "Summarize this contract"}],
)
print(resp.choices[0].message.content)
```

**Node.js**

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-org-your_api_key",
  baseURL: "https://api.samreshuuu.ru/v1",
});

const resp = await client.chat.completions.create({
  model: "samreshuuu",
  messages: [{ role: "user", content: "Summarize this contract" }],
});
console.log(resp.choices[0].message.content);
```

**cURL**

```bash
curl https://api.samreshuuu.ru/v1/chat/completions \
  -H "Authorization: Bearer sk-org-your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "samreshuuu",
    "messages": [{"role": "user", "content": "Summarize this contract"}]
  }'
```

**О поле model**

Параметр `model` требуется OpenAI SDK, но игнорируется сервером — модель выбирает платформа. Передайте любую строку-заглушку. Параметры сэмплирования, такие как `temperature` и `max_tokens`, принимаются ради совместимости, но не учитываются этим эндпоинтом.

## Поля запроса

<ParamTable
    rows={[
        { name: "messages", type: "array", required: true, description: "Сообщения чата. Последнее сообщение пользователя задаёт текущий ход; предыдущие считаются историей." },
        { name: "stream", type: "boolean", description: "Если true — стримит фреймы OpenAI chat.completion.chunk. По умолчанию false." },
        { name: "session_id", type: "string", description: "Передайте session_id, чтобы продолжить предыдущий разговор. Опустите для нового." },
        { name: "max_iterations", type: "integer", description: "Лимит цикла агента, 1–50. По умолчанию 25." },
        { name: "stream_options", type: "object", description: "Дополнения стриминга. Установите { \"include_tool_progress\": true }, чтобы также получать именованные SSE-события tool.progress. По умолчанию выключено." },
    ]}
/>

**Этот ключ действует от имени всего кабинета продавца**

API-ключ со scope `chat` управляет тем же агентом, что и рабочее пространство — модель имеет доступ ко всему реестру инструментов, включая коннекторы к кабинету продавца и инструмент `terminal`. Относитесь к ключу как к учётным данным аккаунта: выдавайте отдельный ключ на интеграцию, храните только на сервере и ротируйте при утечке. Режима только-для-чтения у этого эндпоинта нет.

## Стриминг

Установите `stream: true`, чтобы получать Server-Sent Events в формате чанков OpenAI, завершаемые финальным фреймом `data: [DONE]`.

```bash
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Here"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
```

### Прогресс инструментов (opt-in)

Передайте `stream_options: { "include_tool_progress": true }` (или заголовок `X-Hermes-Tool-Progress: 1`), чтобы получать именованные SSE-события `tool.progress`, чередующиеся со стандартными чанками. Они живут в отдельном канале событий, поэтому строгие OpenAI-клиенты, читающие только `chat.completion.chunk`, их игнорируют — и никогда не сохраняют в историю. Когда опция выключена, поток байт идентичен обычному ответу OpenAI.

```bash
event: tool.progress
data: {"type":"tool.started","tool_name":"connector","label":"MoySklad","iteration":1}

event: tool.progress
data: {"type":"tool.completed","tool_name":"connector","label":"MoySklad","success":true,"duration_ms":842}
```

**Многоходовые диалоги**

Передавайте один и тот же `session_id` между запросами, чтобы сохранять контекст. Первый ответ создаёт сессию; используйте её id в следующем вызове.
