Files
openai/chat_stream.go
T
zeekayandHanzo Dev 2e39f0248d Go 1.27.1, and the code it can say more simply
Modules declare go 1.27.1 and the build images follow. go fix applied the
modernizers, and the stream request helper is now a generic method on
Client; omitzero is not applied, since it changes what the JSON says.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 19:23:22 -07:00

108 lines
3.9 KiB
Go

package openai
import (
"context"
"net/http"
)
type ChatCompletionStreamChoiceDelta struct {
Content string `json:"content,omitempty"`
ReasoningContent string `json:"reasoning_content,omitempty"`
Role string `json:"role,omitempty"`
FunctionCall *FunctionCall `json:"function_call,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
Refusal string `json:"refusal,omitempty"`
}
type ChatCompletionStreamChoiceLogprobs struct {
Content []ChatCompletionTokenLogprob `json:"content,omitempty"`
Refusal []ChatCompletionTokenLogprob `json:"refusal,omitempty"`
}
type ChatCompletionTokenLogprob struct {
Token string `json:"token"`
Bytes []int64 `json:"bytes,omitempty"`
Logprob float64 `json:"logprob,omitempty"`
TopLogprobs []ChatCompletionTokenLogprobTopLogprob `json:"top_logprobs"`
}
type ChatCompletionTokenLogprobTopLogprob struct {
Token string `json:"token"`
Bytes []int64 `json:"bytes"`
Logprob float64 `json:"logprob"`
}
type ChatCompletionStreamChoice struct {
Index int `json:"index"`
Delta ChatCompletionStreamChoiceDelta `json:"delta"`
Logprobs *ChatCompletionStreamChoiceLogprobs `json:"logprobs,omitempty"`
FinishReason FinishReason `json:"finish_reason"`
ContentFilterResults ContentFilterResults `json:"content_filter_results,omitempty"`
}
type PromptFilterResult struct {
Index int `json:"index"`
ContentFilterResults ContentFilterResults `json:"content_filter_results,omitempty"`
}
type ChatCompletionStreamResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []ChatCompletionStreamChoice `json:"choices"`
SystemFingerprint string `json:"system_fingerprint"`
PromptAnnotations []PromptAnnotation `json:"prompt_annotations,omitempty"`
PromptFilterResults []PromptFilterResult `json:"prompt_filter_results,omitempty"`
// An optional field that will only be present when you set stream_options: {"include_usage": true} in your request.
// When present, it contains a null value except for the last chunk which contains the token usage statistics
// for the entire request.
Usage *Usage `json:"usage,omitempty"`
}
// ChatCompletionStream
// Note: Perhaps it is more elegant to abstract Stream using generics.
type ChatCompletionStream struct {
*streamReader[ChatCompletionStreamResponse]
}
// CreateChatCompletionStream — API call to create a chat completion w/ streaming
// support. It sets whether to stream back partial progress. If set, tokens will be
// sent as data-only server-sent events as they become available, with the
// stream terminated by a data: [DONE] message.
func (c *Client) CreateChatCompletionStream(
ctx context.Context,
request ChatCompletionRequest,
) (stream *ChatCompletionStream, err error) {
urlSuffix := chatCompletionsSuffix
if !checkEndpointSupportsModel(urlSuffix, request.Model) {
err = ErrChatCompletionInvalidModel
return
}
request.Stream = true
reasoningValidator := NewReasoningValidator()
if err = reasoningValidator.Validate(request); err != nil {
return
}
req, err := c.newRequest(
ctx,
http.MethodPost,
c.fullURL(urlSuffix, withModel(request.Model)),
withBody(request),
)
if err != nil {
return nil, err
}
resp, err := c.sendRequestStream[ChatCompletionStreamResponse](req)
if err != nil {
return
}
stream = &ChatCompletionStream{
streamReader: resp,
}
return
}