Streaming (SSE)

POST /v1/chat/completions with "stream": true streams the agent's answer as Server-Sent Events in OpenAI's chat.completion.chunk format. Stock OpenAI SDKs read it unchanged; the request fields are on the OpenAI-compatible API page.

bash
curl -N https://samreshuuu.ru/v1/chat/completions \ -H "Authorization: Bearer $SAMRESHUUU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "samreshu", "stream": true, "messages": [{ "role": "user", "content": "Give three short tips for naming a product card on a marketplace" }] }'

Chunks

Each frame is a data: line with one chunk. The first chunk carries delta: {"role": "assistant", "content": ""}, then delta.content carries the next piece of text; the first chunk with a finish_reason ends the answer, and data: [DONE] closes the stream. model in every chunk is the handle of the agent that answers.

bash
data: {"id":"chatcmpl-5f1c2d3e4a6b7c8d9e0f1a2b","object":"chat.completion.chunk","created":1790000000,"model":"samreshu","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]} data: {"id":"chatcmpl-5f1c2d3e4a6b7c8d9e0f1a2b","object":"chat.completion.chunk","created":1790000000,"model":"samreshu","choices":[{"index":0,"delta":{"content":"Here are the key points"},"finish_reason":null}]} data: {"id":"chatcmpl-5f1c2d3e4a6b7c8d9e0f1a2b","object":"chat.completion.chunk","created":1790000000,"model":"samreshu","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE]

Every 10 seconds, a long tool call included, an SSE comment starting with : ping arrives (a timestamp follows); parsers must skip lines starting with :. The stream carries no usage chunk: token counts come only in the non-streaming response.

Deltas are a live draft

The agent sometimes rewrites text mid-turn, so the concatenated deltas can differ from the answer it saved. When you need the authoritative text, send the same request without stream.

Tool events (opt-in)

With "tool_events": true the stream also carries samreshuuu.tool events between the chunks. They arrive as named SSE events (event: samreshuuu.tool). The official OpenAI SDKs do not filter by event name: they yield these frames as chunks without choices, so guard the loop (if not chunk.choices: continue). In the Node.js SDK read them only with for await over create({ stream: true }) or with your own SSE parser: the .stream() and runTools helpers expect every frame to be a chunk and break on these events. A raw SSE parser can dispatch on the event name.

bash
event: samreshuuu.tool data: {"type":"tool_started","tool_id":"call_7Hq2mXc9LpR4tVb1NsK8eW3d","tool_name":"connector_execute","iteration":1,"label":"Вызов сервиса"} event: samreshuuu.tool data: {"type":"tool_completed","tool_id":"call_7Hq2mXc9LpR4tVb1NsK8eW3d","tool_name":"connector_execute","iteration":1,"success":true,"duration_ms":842,"label":"Вызов сервиса"}

tool_started carries type, tool_id, tool_name, iteration and label (the tool's display name); tool_completed adds success and duration_ms. tool_id pairs the two events of one call. A call answered without running (a repeat served from the run's earlier result, a call refused before it ran) sends only tool_completed. The agent's internal end-of-turn tool does not appear in these events. The tool names are listed under Agents → Available tools.

Errors

Every error is one object: {"type":"error","error":{"type","code","message","param"},"request_id"}. A refusal before the turn starts is an ordinary HTTP error with that body (403 without chat:write, 404 for an unknown model, 402 for a spent weekly limit, 429 on rate limit). Once the stream has started the status line is already 200, so a failure arrives as a final chunk carrying the error object instead of choices; the Python openai client raises it as APIError. data: [DONE] follows and closes the stream. See Errors & Rate Limits.

bash
data: {"type":"error","error":{"type":"overloaded_error","code":"LLM_PROVIDER_UNAVAILABLE","message":"The model is temporarily unavailable. Please try again in a few minutes.","param":null},"request_id":"3f6c1b2a-8d4e-4f7a-9b0c-5e2d1a7c9f84"}

Disconnects and long turns

The turn runs inside your request: closing the stream stops it, and the turn is recorded as stopped, not as a failure. There is no cursor to resume a dropped stream; send the next message with the same session_id and model to continue the conversation. An EOF without data: [DONE] is not a finished answer.

Frequently asked questions

How do I stream an answer?

Send stream: true to POST /v1/chat/completions. The answer arrives as OpenAI chat.completion.chunk frames over Server-Sent Events and ends with data: [DONE].

How do I see which tools the agent calls?

Add tool_events: true to a streaming request. Named samreshuuu.tool events arrive beside the chunks, one when a call starts and one when it ends.

What happens if my connection drops?

Closing the stream stops the turn, and it is recorded as stopped, not failed. There is no replay cursor on /v1: continue the conversation with the same session_id and model.

How do I tell a failure from a normal end?

A failure after the stream started is a final chunk carrying an error object instead of choices; the Python openai client raises it as APIError, and data: [DONE] closes the stream. A normal end has finish_reason stop followed by data: [DONE].

Was this page helpful?