Skip to content

Стриминг (SSE)

Для отображения ответа по мере генерации используйте стриминговый эндпоинт. Сервер отвечает потоком событий Server-Sent Events.

POST /chat/stream

http
POST /chat/stream
X-API-Key: ak_your_api_key
Content-Type: application/json

Тело запроса идентично /chat/message:

json
{
  "message": "Расскажи подробнее об условиях доставки",
  "conversationId": "uuid",
  "userId": "user-123"
}

Формат событий

Каждое событие — строка data: {...}\n\n. Возможные типы:

chunk — фрагмент текста

json
{ "type": "chunk", "content": "Доставка" }
{ "type": "chunk", "content": " по городу" }
{ "type": "chunk", "content": " бесплатна..." }

done — завершение

json
{
  "type": "done",
  "conversationId": "uuid",
  "message": {
    "id": "uuid",
    "role": "assistant",
    "content": "Доставка по городу бесплатна при заказе от 2000 ₽...",
    "createdAt": "2024-01-01T12:00:00.000Z"
  },
  "suggestions": ["Как оформить заказ?", "Зоны доставки"]
}

error — ошибка

json
{ "type": "error", "message": "Лимит сообщений исчерпан" }

Пример (JavaScript)

js
async function streamMessage(text, conversationId, onChunk) {
  const res = await fetch('https://app.agent512.ru/api/chat/stream', {
    method: 'POST',
    headers: {
      'X-API-Key': 'ak_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ message: text, conversationId }),
  })

  const reader = res.body.getReader()
  const decoder = new TextDecoder()
  let buffer = ''

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split('\n\n')
    buffer = lines.pop() // неполная строка остаётся в буфере

    for (const line of lines) {
      if (!line.startsWith('data: ')) continue
      const event = JSON.parse(line.slice(6))

      if (event.type === 'chunk') {
        onChunk(event.content)
      } else if (event.type === 'done') {
        return event // возвращаем финальный результат
      }
    }
  }
}

// Использование
let fullText = ''
const result = await streamMessage(
  'Расскажи об услугах',
  null,
  (chunk) => {
    fullText += chunk
    document.getElementById('chat').textContent = fullText
  }
)
console.log('Диалог:', result.conversationId)

Пример (EventSource)

WARNING

EventSource не поддерживает POST-запросы. Используйте fetch с ReadableStream как в примере выше.