Доступно

Streaming: обработка SSE без потери результата

Как читать потоковые ответы Chat Completions, Responses и Messages, отменять запрос и подтверждать завершение по итоговой квитанции.

API Токенмоста работает

Базовый адрес — https://tokenmost.ru/v1. Создайте ключ в личном кабинете, выберите модель в каталоге и отправьте первый запрос. Методы, которые ещё не доступны, отмечены отдельно.

Как это устроено

При streaming сервер отправляет события Server-Sent Events по мере генерации. Частичный текст улучшает интерфейс, но не является доказательством завершения: клиент должен дождаться терминального события и итоговой квитанции.

Что потребуется

  • Рабочий непотоковый запрос к тому же endpoint и модели.
  • SSE-парсер, который сохраняет порядок событий и поддерживает отмену.
  • Раздельные состояния интерфейса: выполняется, завершено, отменено и неизвестный исход.

Порядок работы

  1. Добавьте stream: true к уже проверенному запросу.
  2. Читайте response.body как поток и разделяйте SSE-события по пустой строке.
  3. Обрабатывайте только известные типы событий и накапливайте текст по порядку.
  4. При отмене закрывайте reader и AbortController, не создавая автоматический повтор.
  5. Считайте запрос успешным только после терминального события и billing receipt.

Готовая конфигурация

Минимальный цикл чтения браузерного потока

const response = await fetch(url, { ...options, signal: controller.signal });
if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`);

const reader = response.body.getReader();
const decoder = new TextDecoder();
for (;;) {
  const { value, done } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value, { stream: true });
  // Передайте chunk в SSE-парсер; не делите JSON по сетевым чанкам.
}

Пример запроса

Укажите TOKENMOST_BASE_URL=https://tokenmost.ru/v1, ключ проекта и точный ID модели из каталога. Пример отправляет запрос в публичный API и может списать средства с баланса по тарифу модели.

curl -N "https://tokenmost.ru/v1/chat/completions" \
  -H "Authorization: Bearer $TOKENMOST_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: stream-example-0001" \
  -d '{
    "model": "MODEL_ID_FROM_CATALOG",
    "messages": [{"role": "user", "content": "Ответь по пунктам."}],
    "max_tokens": 128,
    "stream": true
  }'

Что учесть

Проверяйте streaming после обычного запроса. Частичный текст нельзя считать подтверждённым результатом без финального события и квитанции.

Сетевой chunk не равен SSE-событию

Один JSON может быть разрезан между чтениями, а несколько событий могут прийти одним chunk. Используйте буфер и разбирайте полные SSE-события, а не каждый value отдельно.

Терминальные события

Chat, Responses и Messages используют разные имена событий. Клиент должен понимать выбранный контракт и проверять финальную квитанцию, а не только маркер конца текста.

Отмена и неизвестный исход

Отмена до отправки освобождает резерв. Разрыв после начала генерации может оставить исход неизвестным; автоматический повтор с новым ключом запрещён.

Ошибки и диагностика

JSON parse error на части ответа

Буферизуйте данные до границы SSE-события; сетевой chunk не гарантирует полный JSON.

Текст повторяется

Не добавляйте итоговый объект поверх уже обработанных delta и учитывайте replay.

Интерфейс показывает успех слишком рано

Ждите терминальное событие и итоговую квитанцию биллинга.

Отмена не прекращает запрос

Передайте AbortSignal в fetch и закройте reader при отмене страницы или задачи.

Поток оборвался

Сохраните Idempotency-Key и проверьте историю; не создавайте новый платный запрос автоматически.

Источники и связанные инструкции

Читайте дальше

← Все инструкции