Introduction
This crate exposes an async stream API for the widely-used OpenAI chat completion API and the Responses API.
Supported features:
- Stream generation
- Tool calls
- Reasoning content (Qwen3, Deepseek R1, etc)
- Token usage in the chat completion stream (via
stream_options.include_usage) - Responses API (stream + non-stream, tool calls, reasoning)
This crate is built on top of
reqwestandserde_json.
use ;
use ;
let chat_client = init;
// create and pin the stream
let stream = chat_client
.chat_completion_stream
.await
.unwrap;
pin_mut!;
// buffer for the new message
let mut message = new;
// consume the stream
while let Some = stream.next.await
Token usage
OpenAI-compatible streaming APIs only report token usage when the request sets
stream_options.include_usage. Use the params builder convenience:
let mut params = new;
params.max_tokens.include_usage;
The server then sends a final chunk with empty choices and a top-level usage object, which
chat_completion_stream surfaces as a ChatCompletionStreamEvent::Usage(ChatCompletionUsage)
event, yielded after the final delta and right before [DONE]. Consumers should treat it as the
latest (authoritative) token count for the call. ChatCompletionUsage mirrors ResponseUsage:
all fields are optional (Option<u64> + #[serde(default)]), so partial provider responses
deserialize; DeepSeek-specific extras are ignored.
Responses API
The Responses API is supported via
responses() (non-stream) and responses_stream() (SSE event stream). The endpoint is
{base_url}/responses — for DeepSeek use https://api.deepseek.com, for OpenAI use
https://api.openai.com/v1 (the base URL must not end with /).
The stream yields typed ResponsesStreamEvents and terminates on response.completed /
response.incomplete / response.failed (no data: [DONE]). See examples/responses.rs
and examples/responses_tool.rs for runnable examples.
Notice
Copyright 2025, Mengxiao Lin.
This is a part of nah project. nah means "Not A
Human". Source code is available under MPL-2.0.