Update go version
This commit is contained in:
8
vendor/github.com/sashabaranov/go-openai/.codecov.yml
generated
vendored
8
vendor/github.com/sashabaranov/go-openai/.codecov.yml
generated
vendored
@@ -2,3 +2,11 @@ coverage:
|
||||
ignore:
|
||||
- "examples/**"
|
||||
- "internal/test/**"
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 2%
|
||||
patch:
|
||||
default:
|
||||
target: 80%
|
||||
|
||||
4
vendor/github.com/sashabaranov/go-openai/.gitignore
generated
vendored
4
vendor/github.com/sashabaranov/go-openai/.gitignore
generated
vendored
@@ -19,4 +19,6 @@
|
||||
.idea
|
||||
|
||||
# Generated by tests
|
||||
test.mp3
|
||||
test.mp3
|
||||
|
||||
.env
|
||||
|
||||
29
vendor/github.com/sashabaranov/go-openai/.golangci.yml
generated
vendored
29
vendor/github.com/sashabaranov/go-openai/.golangci.yml
generated
vendored
@@ -22,7 +22,7 @@ linters:
|
||||
- gocyclo
|
||||
- godot
|
||||
- gomoddirectives
|
||||
- gomodguard
|
||||
- gomodguard_v2
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- govet
|
||||
@@ -66,21 +66,20 @@ linters:
|
||||
paramsOnly: false
|
||||
underef:
|
||||
skipRecvDeref: false
|
||||
gomodguard:
|
||||
gomodguard_v2:
|
||||
blocked:
|
||||
modules:
|
||||
- github.com/golang/protobuf:
|
||||
recommendations:
|
||||
- google.golang.org/protobuf
|
||||
reason: see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules
|
||||
- github.com/satori/go.uuid:
|
||||
recommendations:
|
||||
- github.com/google/uuid
|
||||
reason: satori's package is not maintained
|
||||
- github.com/gofrs/uuid:
|
||||
recommendations:
|
||||
- github.com/google/uuid
|
||||
reason: 'see recommendation from dev-infra team: https://confluence.gtforge.com/x/gQI6Aw'
|
||||
- module: github.com/golang/protobuf
|
||||
recommendations:
|
||||
- google.golang.org/protobuf
|
||||
reason: see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules
|
||||
- module: github.com/satori/go.uuid
|
||||
recommendations:
|
||||
- github.com/google/uuid
|
||||
reason: satori's package is not maintained
|
||||
- module: github.com/gofrs/uuid
|
||||
recommendations:
|
||||
- github.com/google/uuid
|
||||
reason: 'see recommendation from dev-infra team: https://confluence.gtforge.com/x/gQI6Aw'
|
||||
govet:
|
||||
disable:
|
||||
- fieldalignment
|
||||
|
||||
983
vendor/github.com/sashabaranov/go-openai/README.md
generated
vendored
983
vendor/github.com/sashabaranov/go-openai/README.md
generated
vendored
File diff suppressed because it is too large
Load Diff
8
vendor/github.com/sashabaranov/go-openai/audio.go
generated
vendored
8
vendor/github.com/sashabaranov/go-openai/audio.go
generated
vendored
@@ -11,9 +11,13 @@ import (
|
||||
utils "github.com/sashabaranov/go-openai/internal"
|
||||
)
|
||||
|
||||
// Whisper Defines the models provided by OpenAI to use when processing audio with OpenAI.
|
||||
// Audio transcription models provided by OpenAI.
|
||||
const (
|
||||
Whisper1 = "whisper-1"
|
||||
Whisper1 = "whisper-1"
|
||||
GPT4oTranscribe = "gpt-4o-transcribe"
|
||||
GPT4oMiniTranscribe = "gpt-4o-mini-transcribe"
|
||||
GPT4oTranscribeDiarize = "gpt-4o-transcribe-diarize"
|
||||
GPTTranscribe = "gpt-transcribe"
|
||||
)
|
||||
|
||||
// Response formats; Whisper uses AudioResponseFormatJSON by default.
|
||||
|
||||
28
vendor/github.com/sashabaranov/go-openai/batch.go
generated
vendored
28
vendor/github.com/sashabaranov/go-openai/batch.go
generated
vendored
@@ -17,6 +17,7 @@ const (
|
||||
BatchEndpointChatCompletions BatchEndpoint = "/v1/chat/completions"
|
||||
BatchEndpointCompletions BatchEndpoint = "/v1/completions"
|
||||
BatchEndpointEmbeddings BatchEndpoint = "/v1/embeddings"
|
||||
BatchEndpointResponses BatchEndpoint = "/v1/responses"
|
||||
)
|
||||
|
||||
type BatchLineItem interface {
|
||||
@@ -54,6 +55,18 @@ type BatchEmbeddingRequest struct {
|
||||
URL BatchEndpoint `json:"url"`
|
||||
}
|
||||
|
||||
type BatchResponseRequest struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
Body CreateResponseRequest `json:"body"`
|
||||
Method string `json:"method"`
|
||||
URL BatchEndpoint `json:"url"`
|
||||
}
|
||||
|
||||
func (r BatchResponseRequest) MarshalBatchLineItem() []byte {
|
||||
marshal, _ := json.Marshal(r)
|
||||
return marshal
|
||||
}
|
||||
|
||||
func (r BatchEmbeddingRequest) MarshalBatchLineItem() []byte {
|
||||
marshal, _ := json.Marshal(r)
|
||||
return marshal
|
||||
@@ -146,7 +159,7 @@ func (r *UploadBatchFileRequest) AddChatCompletion(customerID string, body ChatC
|
||||
r.Lines = append(r.Lines, BatchChatCompletionRequest{
|
||||
CustomID: customerID,
|
||||
Body: body,
|
||||
Method: "POST",
|
||||
Method: http.MethodPost,
|
||||
URL: BatchEndpointChatCompletions,
|
||||
})
|
||||
}
|
||||
@@ -155,7 +168,7 @@ func (r *UploadBatchFileRequest) AddCompletion(customerID string, body Completio
|
||||
r.Lines = append(r.Lines, BatchCompletionRequest{
|
||||
CustomID: customerID,
|
||||
Body: body,
|
||||
Method: "POST",
|
||||
Method: http.MethodPost,
|
||||
URL: BatchEndpointCompletions,
|
||||
})
|
||||
}
|
||||
@@ -164,11 +177,20 @@ func (r *UploadBatchFileRequest) AddEmbedding(customerID string, body EmbeddingR
|
||||
r.Lines = append(r.Lines, BatchEmbeddingRequest{
|
||||
CustomID: customerID,
|
||||
Body: body,
|
||||
Method: "POST",
|
||||
Method: http.MethodPost,
|
||||
URL: BatchEndpointEmbeddings,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *UploadBatchFileRequest) AddResponse(customerID string, body CreateResponseRequest) {
|
||||
r.Lines = append(r.Lines, BatchResponseRequest{
|
||||
CustomID: customerID,
|
||||
Body: body,
|
||||
Method: http.MethodPost,
|
||||
URL: BatchEndpointResponses,
|
||||
})
|
||||
}
|
||||
|
||||
// UploadBatchFile — upload batch file.
|
||||
func (c *Client) UploadBatchFile(ctx context.Context, request UploadBatchFileRequest) (File, error) {
|
||||
if request.FileName == "" {
|
||||
|
||||
38
vendor/github.com/sashabaranov/go-openai/chat.go
generated
vendored
38
vendor/github.com/sashabaranov/go-openai/chat.go
generated
vendored
@@ -265,6 +265,7 @@ type ChatCompletionRequest struct {
|
||||
Messages []ChatCompletionMessage `json:"messages"`
|
||||
// MaxTokens The maximum number of tokens that can be generated in the chat completion.
|
||||
// This value can be used to control costs for text generated via API.
|
||||
//
|
||||
// Deprecated: use MaxCompletionTokens. Not compatible with o1-series models.
|
||||
// refs: https://platform.openai.com/docs/api-reference/chat/create#chat-create-max_tokens
|
||||
MaxTokens int `json:"max_tokens,omitempty"`
|
||||
@@ -274,7 +275,7 @@ type ChatCompletionRequest struct {
|
||||
Temperature float32 `json:"temperature,omitempty"`
|
||||
TopP float32 `json:"top_p,omitempty"`
|
||||
N int `json:"n,omitempty"`
|
||||
Stream bool `json:"stream,omitempty"`
|
||||
Stream bool `json:"stream"`
|
||||
Stop []string `json:"stop,omitempty"`
|
||||
PresencePenalty float32 `json:"presence_penalty,omitempty"`
|
||||
ResponseFormat *ChatCompletionResponseFormat `json:"response_format,omitempty"`
|
||||
@@ -346,12 +347,45 @@ type StreamOptions struct {
|
||||
type ToolType string
|
||||
|
||||
const (
|
||||
ToolTypeFunction ToolType = "function"
|
||||
ToolTypeFunction ToolType = "function"
|
||||
ToolTypeWebSearch ToolType = "web_search"
|
||||
ToolTypeWebSearchPreview ToolType = "web_search_preview"
|
||||
ToolTypeFileSearch ToolType = "file_search"
|
||||
ToolTypeComputer ToolType = "computer"
|
||||
ToolTypeComputerUsePreview ToolType = "computer_use_preview"
|
||||
ToolTypeComputerUse ToolType = "computer_use"
|
||||
ToolTypeCodeInterpreter ToolType = "code_interpreter"
|
||||
ToolTypeImageGeneration ToolType = "image_generation"
|
||||
ToolTypeMCP ToolType = "mcp"
|
||||
ToolTypeCustom ToolType = "custom"
|
||||
ToolTypeLocalShell ToolType = "local_shell"
|
||||
ToolTypeShell ToolType = "shell"
|
||||
ToolTypeApplyPatch ToolType = "apply_patch"
|
||||
ToolTypeToolSearch ToolType = "tool_search"
|
||||
)
|
||||
|
||||
type Tool struct {
|
||||
Type ToolType `json:"type"`
|
||||
Function *FunctionDefinition `json:"function,omitempty"`
|
||||
// Parameters contains Responses API tool properties that are serialized next to type.
|
||||
// For example: {"search_context_size": "low"} for a web search tool.
|
||||
Parameters map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the nested Chat Completions function format while also
|
||||
// supporting the inline properties used by built-in and function tools in the Responses API.
|
||||
func (t Tool) MarshalJSON() ([]byte, error) {
|
||||
tool := map[string]any{"type": t.Type}
|
||||
if t.Function != nil {
|
||||
tool["function"] = t.Function
|
||||
}
|
||||
for key, value := range t.Parameters {
|
||||
if key == "type" || key == "function" {
|
||||
return nil, errors.New("tool parameters cannot override type or function")
|
||||
}
|
||||
tool[key] = value
|
||||
}
|
||||
return json.Marshal(tool)
|
||||
}
|
||||
|
||||
type ToolChoice struct {
|
||||
|
||||
4
vendor/github.com/sashabaranov/go-openai/client.go
generated
vendored
4
vendor/github.com/sashabaranov/go-openai/client.go
generated
vendored
@@ -257,9 +257,9 @@ func withModel(model string) fullURLOption {
|
||||
}
|
||||
|
||||
var azureDeploymentsEndpoints = []string{
|
||||
"/completions",
|
||||
completionsSuffix,
|
||||
"/embeddings",
|
||||
"/chat/completions",
|
||||
chatCompletionsSuffix,
|
||||
"/audio/transcriptions",
|
||||
"/audio/translations",
|
||||
"/audio/speech",
|
||||
|
||||
65
vendor/github.com/sashabaranov/go-openai/completion.go
generated
vendored
65
vendor/github.com/sashabaranov/go-openai/completion.go
generated
vendored
@@ -5,10 +5,9 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GPT3 Defines the models provided by OpenAI to use when generating
|
||||
// completions from OpenAI.
|
||||
// GPT3 Models are designed for text-based tasks. For code-specific
|
||||
// tasks, please refer to the Codex series of models.
|
||||
const completionsSuffix = "/completions"
|
||||
|
||||
// Text generation and reasoning models provided by OpenAI.
|
||||
const (
|
||||
O1Mini = "o1-mini"
|
||||
O1Mini20240912 = "o1-mini-2024-09-12"
|
||||
@@ -20,8 +19,11 @@ const (
|
||||
O320250416 = "o3-2025-04-16"
|
||||
O3Mini = "o3-mini"
|
||||
O3Mini20250131 = "o3-mini-2025-01-31"
|
||||
O3Pro = "o3-pro"
|
||||
O3DeepResearch = "o3-deep-research"
|
||||
O4Mini = "o4-mini"
|
||||
O4Mini20250416 = "o4-mini-2025-04-16"
|
||||
O4MiniDeepResearch = "o4-mini-deep-research"
|
||||
GPT432K0613 = "gpt-4-32k-0613"
|
||||
GPT432K0314 = "gpt-4-32k-0314"
|
||||
GPT432K = "gpt-4-32k"
|
||||
@@ -52,7 +54,30 @@ const (
|
||||
GPT5 = "gpt-5"
|
||||
GPT5Mini = "gpt-5-mini"
|
||||
GPT5Nano = "gpt-5-nano"
|
||||
GPT5Pro = "gpt-5-pro"
|
||||
GPT5ChatLatest = "gpt-5-chat-latest"
|
||||
GPT5Codex = "gpt-5-codex"
|
||||
GPT5Dot1 = "gpt-5.1"
|
||||
GPT5Dot1ChatLatest = "gpt-5.1-chat-latest"
|
||||
GPT5Dot1Codex = "gpt-5.1-codex"
|
||||
GPT5Dot1CodexMini = "gpt-5.1-codex-mini"
|
||||
GPT5Dot1CodexMax = "gpt-5.1-codex-max"
|
||||
GPT5Dot2 = "gpt-5.2"
|
||||
GPT5Dot2ChatLatest = "gpt-5.2-chat-latest"
|
||||
GPT5Dot2Pro = "gpt-5.2-pro"
|
||||
GPT5Dot2Codex = "gpt-5.2-codex"
|
||||
GPT5Dot3ChatLatest = "gpt-5.3-chat-latest"
|
||||
GPT5Dot3Codex = "gpt-5.3-codex"
|
||||
GPT5Dot4 = "gpt-5.4"
|
||||
GPT5Dot4Mini = "gpt-5.4-mini"
|
||||
GPT5Dot4Nano = "gpt-5.4-nano"
|
||||
GPT5Dot4Pro = "gpt-5.4-pro"
|
||||
GPT5Dot5 = "gpt-5.5"
|
||||
GPT5Dot5Pro = "gpt-5.5-pro"
|
||||
GPT5Dot6 = "gpt-5.6"
|
||||
GPT5Dot6Sol = "gpt-5.6-sol"
|
||||
GPT5Dot6Terra = "gpt-5.6-terra"
|
||||
GPT5Dot6Luna = "gpt-5.6-luna"
|
||||
GPT3Dot5Turbo0125 = "gpt-3.5-turbo-0125"
|
||||
GPT3Dot5Turbo1106 = "gpt-3.5-turbo-1106"
|
||||
GPT3Dot5Turbo0613 = "gpt-3.5-turbo-0613"
|
||||
@@ -100,15 +125,18 @@ const (
|
||||
)
|
||||
|
||||
var disabledModelsForEndpoints = map[string]map[string]bool{
|
||||
"/completions": {
|
||||
completionsSuffix: {
|
||||
O1Mini: true,
|
||||
O1Mini20240912: true,
|
||||
O1Preview: true,
|
||||
O1Preview20240912: true,
|
||||
O3Mini: true,
|
||||
O3Mini20250131: true,
|
||||
O3Pro: true,
|
||||
O3DeepResearch: true,
|
||||
O4Mini: true,
|
||||
O4Mini20250416: true,
|
||||
O4MiniDeepResearch: true,
|
||||
O3: true,
|
||||
O320250416: true,
|
||||
GPT3Dot5Turbo: true,
|
||||
@@ -149,7 +177,30 @@ var disabledModelsForEndpoints = map[string]map[string]bool{
|
||||
GPT5: true,
|
||||
GPT5Mini: true,
|
||||
GPT5Nano: true,
|
||||
GPT5Pro: true,
|
||||
GPT5ChatLatest: true,
|
||||
GPT5Codex: true,
|
||||
GPT5Dot1: true,
|
||||
GPT5Dot1ChatLatest: true,
|
||||
GPT5Dot1Codex: true,
|
||||
GPT5Dot1CodexMini: true,
|
||||
GPT5Dot1CodexMax: true,
|
||||
GPT5Dot2: true,
|
||||
GPT5Dot2ChatLatest: true,
|
||||
GPT5Dot2Pro: true,
|
||||
GPT5Dot2Codex: true,
|
||||
GPT5Dot3ChatLatest: true,
|
||||
GPT5Dot3Codex: true,
|
||||
GPT5Dot4: true,
|
||||
GPT5Dot4Mini: true,
|
||||
GPT5Dot4Nano: true,
|
||||
GPT5Dot4Pro: true,
|
||||
GPT5Dot5: true,
|
||||
GPT5Dot5Pro: true,
|
||||
GPT5Dot6: true,
|
||||
GPT5Dot6Sol: true,
|
||||
GPT5Dot6Terra: true,
|
||||
GPT5Dot6Luna: true,
|
||||
},
|
||||
chatCompletionsSuffix: {
|
||||
CodexCodeDavinci002: true,
|
||||
@@ -218,7 +269,7 @@ type CompletionRequest struct {
|
||||
PresencePenalty float32 `json:"presence_penalty,omitempty"`
|
||||
Seed *int `json:"seed,omitempty"`
|
||||
Stop []string `json:"stop,omitempty"`
|
||||
Stream bool `json:"stream,omitempty"`
|
||||
Stream bool `json:"stream"`
|
||||
Suffix string `json:"suffix,omitempty"`
|
||||
Temperature float32 `json:"temperature,omitempty"`
|
||||
TopP float32 `json:"top_p,omitempty"`
|
||||
@@ -269,7 +320,7 @@ func (c *Client) CreateCompletion(
|
||||
return
|
||||
}
|
||||
|
||||
urlSuffix := "/completions"
|
||||
urlSuffix := completionsSuffix
|
||||
if !checkEndpointSupportsModel(urlSuffix, request.Model) {
|
||||
err = ErrCompletionUnsupportedModel
|
||||
return
|
||||
|
||||
7
vendor/github.com/sashabaranov/go-openai/config.go
generated
vendored
7
vendor/github.com/sashabaranov/go-openai/config.go
generated
vendored
@@ -3,6 +3,7 @@ package openai
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -70,7 +71,11 @@ func DefaultAzureConfig(apiKey, baseURL string) ClientConfig {
|
||||
APIType: APITypeAzure,
|
||||
APIVersion: "2023-05-15",
|
||||
AzureModelMapperFunc: func(model string) string {
|
||||
return regexp.MustCompile(`[.:]`).ReplaceAllString(model, "")
|
||||
// only 3.5 models have the "." stripped in their names
|
||||
if strings.Contains(model, "3.5") {
|
||||
return regexp.MustCompile(`[.:]`).ReplaceAllString(model, "")
|
||||
}
|
||||
return strings.ReplaceAll(model, ":", "")
|
||||
},
|
||||
|
||||
HTTPClient: &http.Client{},
|
||||
|
||||
1
vendor/github.com/sashabaranov/go-openai/fine_tunes.go
generated
vendored
1
vendor/github.com/sashabaranov/go-openai/fine_tunes.go
generated
vendored
@@ -111,6 +111,7 @@ func (c *Client) CreateFineTune(ctx context.Context, request FineTuneRequest) (r
|
||||
}
|
||||
|
||||
// CancelFineTune cancel a fine-tune job.
|
||||
//
|
||||
// Deprecated: On August 22nd, 2023, OpenAI announced the deprecation of the /v1/fine-tunes API.
|
||||
// This API will be officially deprecated on January 4th, 2024.
|
||||
// OpenAI recommends to migrate to the new fine tuning API implemented in fine_tuning_job.go.
|
||||
|
||||
41
vendor/github.com/sashabaranov/go-openai/image.go
generated
vendored
41
vendor/github.com/sashabaranov/go-openai/image.go
generated
vendored
@@ -18,7 +18,7 @@ const (
|
||||
CreateImageSize1792x1024 = "1792x1024"
|
||||
CreateImageSize1024x1792 = "1024x1792"
|
||||
|
||||
// gpt-image-1 supported only.
|
||||
// GPT Image models only.
|
||||
CreateImageSize1536x1024 = "1536x1024" // Landscape
|
||||
CreateImageSize1024x1536 = "1024x1536" // Portrait
|
||||
)
|
||||
@@ -30,16 +30,20 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
CreateImageModelDallE2 = "dall-e-2"
|
||||
CreateImageModelDallE3 = "dall-e-3"
|
||||
CreateImageModelGptImage1 = "gpt-image-1"
|
||||
CreateImageModelDallE2 = "dall-e-2"
|
||||
CreateImageModelDallE3 = "dall-e-3"
|
||||
CreateImageModelGptImage1 = "gpt-image-1"
|
||||
CreateImageModelGptImage1Mini = "gpt-image-1-mini"
|
||||
CreateImageModelGptImage1Dot5 = "gpt-image-1.5"
|
||||
CreateImageModelGptImage2 = "gpt-image-2"
|
||||
CreateImageModelChatGPTImageLatest = "chatgpt-image-latest"
|
||||
)
|
||||
|
||||
const (
|
||||
CreateImageQualityHD = "hd"
|
||||
CreateImageQualityStandard = "standard"
|
||||
|
||||
// gpt-image-1 only.
|
||||
// GPT Image models only.
|
||||
CreateImageQualityHigh = "high"
|
||||
CreateImageQualityMedium = "medium"
|
||||
CreateImageQualityLow = "low"
|
||||
@@ -52,18 +56,18 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
// gpt-image-1 only.
|
||||
// GPT Image models only.
|
||||
CreateImageBackgroundTransparent = "transparent"
|
||||
CreateImageBackgroundOpaque = "opaque"
|
||||
)
|
||||
|
||||
const (
|
||||
// gpt-image-1 only.
|
||||
// GPT Image models only.
|
||||
CreateImageModerationLow = "low"
|
||||
)
|
||||
|
||||
const (
|
||||
// gpt-image-1 only.
|
||||
// GPT Image models only.
|
||||
CreateImageOutputFormatPNG = "png"
|
||||
CreateImageOutputFormatJPEG = "jpeg"
|
||||
CreateImageOutputFormatWEBP = "webp"
|
||||
@@ -195,6 +199,27 @@ func (c *Client) CreateEditImage(ctx context.Context, request ImageEditRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Model != "" {
|
||||
err = builder.WriteField("model", request.Model)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if request.Quality != "" {
|
||||
err = builder.WriteField("quality", request.Quality)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if request.User != "" {
|
||||
err = builder.WriteField("user", request.User)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = builder.WriteField("n", strconv.Itoa(request.N))
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
19
vendor/github.com/sashabaranov/go-openai/internal/form_builder.go
generated
vendored
19
vendor/github.com/sashabaranov/go-openai/internal/form_builder.go
generated
vendored
@@ -3,6 +3,7 @@ package openai
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"net/textproto"
|
||||
"os"
|
||||
@@ -50,6 +51,19 @@ func (fb *DefaultFormBuilder) CreateFormFileReader(fieldname string, r io.Reader
|
||||
if f, ok := r.(interface{ ContentType() string }); ok {
|
||||
contentType = f.ContentType()
|
||||
}
|
||||
// The OpenAI API rejects the file part when Content-Type is
|
||||
// missing, so when the reader doesn't supply one and we can't
|
||||
// derive it from the filename extension, fall back to the same
|
||||
// default the stdlib's multipart.Writer.CreateFormFile uses.
|
||||
// See #1010.
|
||||
if contentType == "" {
|
||||
if ext := filepath.Ext(filename); ext != "" {
|
||||
contentType = mime.TypeByExtension(ext)
|
||||
}
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
}
|
||||
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set(
|
||||
@@ -60,10 +74,7 @@ func (fb *DefaultFormBuilder) CreateFormFileReader(fieldname string, r io.Reader
|
||||
escapeQuotes(filepath.Base(filename)),
|
||||
),
|
||||
)
|
||||
// content type is optional, but it can be set
|
||||
if contentType != "" {
|
||||
h.Set("Content-Type", contentType)
|
||||
}
|
||||
h.Set("Content-Type", contentType)
|
||||
|
||||
fieldWriter, err := fb.writer.CreatePart(h)
|
||||
if err != nil {
|
||||
|
||||
2
vendor/github.com/sashabaranov/go-openai/jsonschema/json.go
generated
vendored
2
vendor/github.com/sashabaranov/go-openai/jsonschema/json.go
generated
vendored
@@ -140,7 +140,7 @@ func reflectSchema(t reflect.Type, defs map[string]Definition) (*Definition, err
|
||||
return nil, err
|
||||
}
|
||||
d = *object
|
||||
case reflect.Ptr:
|
||||
case reflect.Pointer:
|
||||
definition, err := reflectSchema(t.Elem(), defs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
597
vendor/github.com/sashabaranov/go-openai/response.go
generated
vendored
Normal file
597
vendor/github.com/sashabaranov/go-openai/response.go
generated
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
package openai
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const responsesSuffix = "/responses"
|
||||
|
||||
var ErrResponseStreamNotSupported = errors.New(
|
||||
"streaming is not supported with this method, please use CreateResponseStream",
|
||||
)
|
||||
|
||||
// ResponseInclude identifies optional data to include in a response.
|
||||
type ResponseInclude string
|
||||
|
||||
const (
|
||||
ResponseIncludeFileSearchCallResults ResponseInclude = "file_search_call.results"
|
||||
ResponseIncludeWebSearchCallResults ResponseInclude = "web_search_call.results"
|
||||
ResponseIncludeWebSearchCallActionSources ResponseInclude = "web_search_call.action.sources"
|
||||
ResponseIncludeInputImageURL ResponseInclude = "message.input_image.image_url"
|
||||
ResponseIncludeComputerCallOutputImageURL ResponseInclude = "computer_call_output.output.image_url"
|
||||
ResponseIncludeCodeInterpreterCallOutputs ResponseInclude = "code_interpreter_call.outputs"
|
||||
ResponseIncludeReasoningEncryptedContent ResponseInclude = "reasoning.encrypted_content"
|
||||
ResponseIncludeMessageOutputTextLogprobs ResponseInclude = "message.output_text.logprobs"
|
||||
)
|
||||
|
||||
// ResponseStatus is the lifecycle status of a response.
|
||||
type ResponseStatus string
|
||||
|
||||
const (
|
||||
ResponseStatusQueued ResponseStatus = "queued"
|
||||
ResponseStatusInProgress ResponseStatus = "in_progress"
|
||||
ResponseStatusCompleted ResponseStatus = "completed"
|
||||
ResponseStatusFailed ResponseStatus = "failed"
|
||||
ResponseStatusIncomplete ResponseStatus = "incomplete"
|
||||
ResponseStatusCancelling ResponseStatus = "cancelling"
|
||||
ResponseStatusCancelled ResponseStatus = "cancelled"
|
||||
)
|
||||
|
||||
// ResponseTruncation controls how input that exceeds the context window is handled.
|
||||
type ResponseTruncation string
|
||||
|
||||
const (
|
||||
ResponseTruncationAuto ResponseTruncation = "auto"
|
||||
ResponseTruncationDisabled ResponseTruncation = "disabled"
|
||||
)
|
||||
|
||||
// ResponseTool is an alias for Tool. Responses API tool-specific properties can
|
||||
// be supplied through Tool.Parameters.
|
||||
type ResponseTool = Tool
|
||||
|
||||
// NewResponseFunctionTool converts a function definition to the inline function
|
||||
// tool representation expected by the Responses API.
|
||||
func NewResponseFunctionTool(function FunctionDefinition) ResponseTool {
|
||||
parameters := map[string]any{
|
||||
"name": function.Name,
|
||||
"parameters": function.Parameters,
|
||||
}
|
||||
if function.Description != "" {
|
||||
parameters["description"] = function.Description
|
||||
}
|
||||
if function.Strict {
|
||||
parameters["strict"] = true
|
||||
}
|
||||
return ResponseTool{Type: ToolTypeFunction, Parameters: parameters}
|
||||
}
|
||||
|
||||
// ResponseReasoning represents reasoning configuration for the Responses API.
|
||||
type ResponseReasoning struct {
|
||||
Effort string `json:"effort,omitempty"`
|
||||
GenerateSummary string `json:"generate_summary,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseStreamOptions controls Responses API streaming behavior.
|
||||
type ResponseStreamOptions struct {
|
||||
IncludeObfuscation *bool `json:"include_obfuscation,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseTextConfig controls plain-text or structured response output.
|
||||
type ResponseTextConfig struct {
|
||||
Format *ResponseTextFormat `json:"format,omitempty"`
|
||||
Verbosity string `json:"verbosity,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseTextFormat describes the requested output format.
|
||||
type ResponseTextFormat struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Schema any `json:"schema,omitempty"`
|
||||
Strict bool `json:"strict,omitempty"`
|
||||
}
|
||||
|
||||
// ResponsePrompt references a reusable prompt template.
|
||||
type ResponsePrompt struct {
|
||||
ID string `json:"id"`
|
||||
Variables map[string]any `json:"variables,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// ResponsePromptCacheOptions controls prompt cache creation.
|
||||
type ResponsePromptCacheOptions struct {
|
||||
Mode string `json:"mode,omitempty"`
|
||||
TTL string `json:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
// ResponsePromptCacheBreakpoint marks the end of a reusable prompt prefix.
|
||||
type ResponsePromptCacheBreakpoint struct {
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
|
||||
// CreateResponseRequest represents a request to the Responses API. Input may be
|
||||
// a string or a slice of response input items.
|
||||
type CreateResponseRequest struct {
|
||||
Background bool `json:"background,omitempty"`
|
||||
ContextManagement []any `json:"context_management,omitempty"`
|
||||
Conversation any `json:"conversation,omitempty"`
|
||||
Include []ResponseInclude `json:"include,omitempty"`
|
||||
Input any `json:"input"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
|
||||
MaxToolCalls int `json:"max_tool_calls,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
Model string `json:"model,omitempty"`
|
||||
Moderation any `json:"moderation,omitempty"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
|
||||
PreviousResponseID string `json:"previous_response_id,omitempty"`
|
||||
Prompt *ResponsePrompt `json:"prompt,omitempty"`
|
||||
PromptCacheKey string `json:"prompt_cache_key,omitempty"`
|
||||
PromptCacheOptions *ResponsePromptCacheOptions `json:"prompt_cache_options,omitempty"`
|
||||
PromptCacheRetention string `json:"prompt_cache_retention,omitempty"`
|
||||
Reasoning *ResponseReasoning `json:"reasoning,omitempty"`
|
||||
SafetyIdentifier string `json:"safety_identifier,omitempty"`
|
||||
ServiceTier string `json:"service_tier,omitempty"`
|
||||
Store *bool `json:"store,omitempty"`
|
||||
Stream bool `json:"stream,omitempty"`
|
||||
StreamOptions *ResponseStreamOptions `json:"stream_options,omitempty"`
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
Text *ResponseTextConfig `json:"text,omitempty"`
|
||||
ToolChoice any `json:"tool_choice,omitempty"`
|
||||
Tools []ResponseTool `json:"tools,omitempty"`
|
||||
TopLogprobs int `json:"top_logprobs,omitempty"`
|
||||
TopP *float32 `json:"top_p,omitempty"`
|
||||
Truncation ResponseTruncation `json:"truncation,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
ExtraBody map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// MarshalJSON merges ExtraBody into the request payload. ExtraBody values take
|
||||
// precedence over fields represented directly by CreateResponseRequest.
|
||||
func (r CreateResponseRequest) MarshalJSON() ([]byte, error) {
|
||||
type requestAlias CreateResponseRequest
|
||||
base, err := json.Marshal(requestAlias(r))
|
||||
if err != nil || len(r.ExtraBody) == 0 {
|
||||
return base, err
|
||||
}
|
||||
|
||||
var body map[string]any
|
||||
if err = json.Unmarshal(base, &body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for key, value := range r.ExtraBody {
|
||||
body[key] = value
|
||||
}
|
||||
return json.Marshal(body)
|
||||
}
|
||||
|
||||
// ResponseInputMessage is a message supplied as structured input.
|
||||
type ResponseInputMessage struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Role string `json:"role"`
|
||||
Content any `json:"content"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Phase string `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseInputText is a text content part in a structured input message.
|
||||
type ResponseInputText struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
PromptCacheBreakpoint *ResponsePromptCacheBreakpoint `json:"prompt_cache_breakpoint,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseInputImage is an image content part in a structured input message.
|
||||
type ResponseInputImage struct {
|
||||
Type string `json:"type"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
FileID string `json:"file_id,omitempty"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
PromptCacheBreakpoint *ResponsePromptCacheBreakpoint `json:"prompt_cache_breakpoint,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseInputFile is a file content part in a structured input message.
|
||||
type ResponseInputFile struct {
|
||||
Type string `json:"type"`
|
||||
FileData string `json:"file_data,omitempty"`
|
||||
FileID string `json:"file_id,omitempty"`
|
||||
FileURL string `json:"file_url,omitempty"`
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
PromptCacheBreakpoint *ResponsePromptCacheBreakpoint `json:"prompt_cache_breakpoint,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseFunctionCallOutput supplies the result of a prior function call.
|
||||
type ResponseFunctionCallOutput struct {
|
||||
Type string `json:"type"`
|
||||
CallID string `json:"call_id"`
|
||||
Output any `json:"output"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseError is an error embedded in an otherwise successful Responses API request.
|
||||
type ResponseError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// ResponseIncompleteDetails explains why a response did not complete.
|
||||
type ResponseIncompleteDetails struct {
|
||||
Reason string `json:"reason,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseConversation identifies the conversation associated with a response.
|
||||
type ResponseConversation struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// ResponseUsage reports token use for a response.
|
||||
type ResponseUsage struct {
|
||||
InputTokens int `json:"input_tokens"`
|
||||
InputTokensDetails *ResponseInputTokensDetails `json:"input_tokens_details,omitempty"`
|
||||
OutputTokens int `json:"output_tokens"`
|
||||
OutputTokensDetails *ResponseOutputTokensDetails `json:"output_tokens_details,omitempty"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
}
|
||||
|
||||
// ResponseInputTokensDetails is the input-token usage breakdown.
|
||||
type ResponseInputTokensDetails struct {
|
||||
CachedTokens int `json:"cached_tokens"`
|
||||
CacheWriteTokens int `json:"cache_write_tokens"`
|
||||
}
|
||||
|
||||
// ResponseOutputTokensDetails is the output-token usage breakdown.
|
||||
type ResponseOutputTokensDetails struct {
|
||||
ReasoningTokens int `json:"reasoning_tokens"`
|
||||
}
|
||||
|
||||
// ResponseAnnotation describes a citation or file annotation in output text.
|
||||
type ResponseAnnotation struct {
|
||||
Type string `json:"type"`
|
||||
FileID string `json:"file_id,omitempty"`
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Index int `json:"index,omitempty"`
|
||||
StartIndex int `json:"start_index,omitempty"`
|
||||
EndIndex int `json:"end_index,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseLogprob contains token log-probability information.
|
||||
type ResponseLogprob struct {
|
||||
Token string `json:"token"`
|
||||
Bytes []int64 `json:"bytes,omitempty"`
|
||||
Logprob float64 `json:"logprob"`
|
||||
TopLogprobs []ResponseLogprob `json:"top_logprobs,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseOutputContent is a text or refusal content part in an output message.
|
||||
type ResponseOutputContent struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Refusal string `json:"refusal,omitempty"`
|
||||
Annotations []ResponseAnnotation `json:"annotations,omitempty"`
|
||||
Logprobs []ResponseLogprob `json:"logprobs,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseSummaryPart is a reasoning summary content part.
|
||||
type ResponseSummaryPart struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// ResponseOutputItem contains the common fields shared by response output item variants.
|
||||
// The top-level Output field remains []any so new variants can be consumed without a library release.
|
||||
type ResponseOutputItem struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
Content []ResponseOutputContent `json:"content,omitempty"`
|
||||
CallID string `json:"call_id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Arguments string `json:"arguments,omitempty"`
|
||||
Summary []ResponseSummaryPart `json:"summary,omitempty"`
|
||||
Action any `json:"action,omitempty"`
|
||||
Results any `json:"results,omitempty"`
|
||||
Output any `json:"output,omitempty"`
|
||||
}
|
||||
|
||||
// CreateResponseResponse represents a response returned by the Responses API.
|
||||
type CreateResponseResponse struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Created int64 `json:"created_at"`
|
||||
CompletedAt *int64 `json:"completed_at,omitempty"`
|
||||
Status ResponseStatus `json:"status,omitempty"`
|
||||
Error *ResponseError `json:"error,omitempty"`
|
||||
IncompleteDetails *ResponseIncompleteDetails `json:"incomplete_details,omitempty"`
|
||||
Instructions any `json:"instructions,omitempty"`
|
||||
MaxOutputTokens *int `json:"max_output_tokens,omitempty"`
|
||||
MaxToolCalls *int `json:"max_tool_calls,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
Model string `json:"model"`
|
||||
Moderation any `json:"moderation,omitempty"`
|
||||
Output []any `json:"output"`
|
||||
OutputText string `json:"output_text,omitempty"`
|
||||
ParallelToolCalls bool `json:"parallel_tool_calls,omitempty"`
|
||||
PreviousResponseID string `json:"previous_response_id,omitempty"`
|
||||
Reasoning *ResponseReasoning `json:"reasoning,omitempty"`
|
||||
ServiceTier string `json:"service_tier,omitempty"`
|
||||
Store bool `json:"store,omitempty"`
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
Text *ResponseTextConfig `json:"text,omitempty"`
|
||||
ToolChoice any `json:"tool_choice,omitempty"`
|
||||
Tools []any `json:"tools,omitempty"`
|
||||
TopLogprobs int `json:"top_logprobs,omitempty"`
|
||||
TopP *float32 `json:"top_p,omitempty"`
|
||||
Truncation ResponseTruncation `json:"truncation,omitempty"`
|
||||
Usage *ResponseUsage `json:"usage,omitempty"`
|
||||
Background *bool `json:"background,omitempty"`
|
||||
Conversation *ResponseConversation `json:"conversation,omitempty"`
|
||||
Prompt *ResponsePrompt `json:"prompt,omitempty"`
|
||||
PromptCacheKey string `json:"prompt_cache_key,omitempty"`
|
||||
PromptCacheOptions *ResponsePromptCacheOptions `json:"prompt_cache_options,omitempty"`
|
||||
PromptCacheRetention string `json:"prompt_cache_retention,omitempty"`
|
||||
SafetyIdentifier string `json:"safety_identifier,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
|
||||
httpHeader
|
||||
}
|
||||
|
||||
// GetOutputText returns the aggregated text output. It uses the API's output_text
|
||||
// convenience field when present and otherwise extracts output_text content parts.
|
||||
func (r CreateResponseResponse) GetOutputText() string {
|
||||
if r.OutputText != "" {
|
||||
return r.OutputText
|
||||
}
|
||||
|
||||
var output strings.Builder
|
||||
for _, rawItem := range r.Output {
|
||||
data, err := json.Marshal(rawItem)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var item ResponseOutputItem
|
||||
if err = json.Unmarshal(data, &item); err != nil {
|
||||
continue
|
||||
}
|
||||
for _, content := range item.Content {
|
||||
if content.Type == "output_text" {
|
||||
output.WriteString(content.Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.String()
|
||||
}
|
||||
|
||||
// RetrieveResponseOptions controls optional data returned by RetrieveResponse.
|
||||
type RetrieveResponseOptions struct {
|
||||
Include []ResponseInclude
|
||||
IncludeObfuscation *bool
|
||||
StartingAfter *int
|
||||
}
|
||||
|
||||
// ResponseInputItemsListOptions controls pagination for ListResponseInputItems.
|
||||
type ResponseInputItemsListOptions struct {
|
||||
After string
|
||||
Include []ResponseInclude
|
||||
Limit int
|
||||
Order string
|
||||
}
|
||||
|
||||
// ResponseInputItemsList contains the input items for a response.
|
||||
type ResponseInputItemsList struct {
|
||||
Object string `json:"object"`
|
||||
Data []any `json:"data"`
|
||||
FirstID string `json:"first_id"`
|
||||
LastID string `json:"last_id"`
|
||||
HasMore bool `json:"has_more"`
|
||||
|
||||
httpHeader
|
||||
}
|
||||
|
||||
// ResponseDeleteResponse is returned after deleting a stored response.
|
||||
type ResponseDeleteResponse struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Deleted bool `json:"deleted"`
|
||||
|
||||
httpHeader
|
||||
}
|
||||
|
||||
// DeleteResponseResponse is kept as a descriptive alias for ResponseDeleteResponse.
|
||||
type DeleteResponseResponse = ResponseDeleteResponse
|
||||
|
||||
// ResponseInputTokensResponse reports the token count for response input.
|
||||
type ResponseInputTokensResponse struct {
|
||||
Object string `json:"object"`
|
||||
InputTokens int `json:"input_tokens"`
|
||||
|
||||
httpHeader
|
||||
}
|
||||
|
||||
// ResponseInputTokensRequest contains the response input whose tokens should be counted.
|
||||
type ResponseInputTokensRequest = CreateResponseRequest
|
||||
|
||||
// ResponseCompaction is a compacted response context.
|
||||
type ResponseCompaction struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
Output []any `json:"output"`
|
||||
Usage *ResponseUsage `json:"usage,omitempty"`
|
||||
|
||||
httpHeader
|
||||
}
|
||||
|
||||
// CompactResponseRequest contains the response context to compact.
|
||||
type CompactResponseRequest = CreateResponseRequest
|
||||
|
||||
// CreateResponse creates a non-streaming model response.
|
||||
func (c *Client) CreateResponse(
|
||||
ctx context.Context,
|
||||
request CreateResponseRequest,
|
||||
) (response CreateResponseResponse, err error) {
|
||||
if request.Stream {
|
||||
return response, ErrResponseStreamNotSupported
|
||||
}
|
||||
|
||||
req, err := c.newRequest(ctx, http.MethodPost, c.fullURL(responsesSuffix), withBody(request))
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// RetrieveResponse gets a stored response by ID.
|
||||
func (c *Client) RetrieveResponse(
|
||||
ctx context.Context,
|
||||
responseID string,
|
||||
options ...RetrieveResponseOptions,
|
||||
) (response CreateResponseResponse, err error) {
|
||||
values := url.Values{}
|
||||
if len(options) > 0 {
|
||||
for _, include := range options[0].Include {
|
||||
values.Add("include", string(include))
|
||||
}
|
||||
if options[0].IncludeObfuscation != nil {
|
||||
values.Set("include_obfuscation", strconv.FormatBool(*options[0].IncludeObfuscation))
|
||||
}
|
||||
if options[0].StartingAfter != nil {
|
||||
values.Set("starting_after", strconv.Itoa(*options[0].StartingAfter))
|
||||
}
|
||||
}
|
||||
|
||||
urlSuffix := responseResourceSuffix(responseID, "", values)
|
||||
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix))
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// GetResponse is an alias for RetrieveResponse.
|
||||
func (c *Client) GetResponse(
|
||||
ctx context.Context,
|
||||
responseID string,
|
||||
options ...RetrieveResponseOptions,
|
||||
) (CreateResponseResponse, error) {
|
||||
return c.RetrieveResponse(ctx, responseID, options...)
|
||||
}
|
||||
|
||||
// DeleteResponse deletes a stored response.
|
||||
func (c *Client) DeleteResponse(ctx context.Context, responseID string) (response ResponseDeleteResponse, err error) {
|
||||
urlSuffix := responseResourceSuffix(responseID, "", nil)
|
||||
req, err := c.newRequest(ctx, http.MethodDelete, c.fullURL(urlSuffix))
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// CancelResponse cancels a background response.
|
||||
func (c *Client) CancelResponse(ctx context.Context, responseID string) (response CreateResponseResponse, err error) {
|
||||
urlSuffix := responseResourceSuffix(responseID, "cancel", nil)
|
||||
req, err := c.newRequest(ctx, http.MethodPost, c.fullURL(urlSuffix))
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// ListResponseInputItems lists the input items for a response.
|
||||
func (c *Client) ListResponseInputItems(
|
||||
ctx context.Context,
|
||||
responseID string,
|
||||
options ...ResponseInputItemsListOptions,
|
||||
) (response ResponseInputItemsList, err error) {
|
||||
values := url.Values{}
|
||||
if len(options) > 0 {
|
||||
if options[0].After != "" {
|
||||
values.Set("after", options[0].After)
|
||||
}
|
||||
for _, include := range options[0].Include {
|
||||
values.Add("include", string(include))
|
||||
}
|
||||
if options[0].Limit != 0 {
|
||||
values.Set("limit", strconv.Itoa(options[0].Limit))
|
||||
}
|
||||
if options[0].Order != "" {
|
||||
values.Set("order", options[0].Order)
|
||||
}
|
||||
}
|
||||
|
||||
urlSuffix := responseResourceSuffix(responseID, "input_items", values)
|
||||
req, err := c.newRequest(ctx, http.MethodGet, c.fullURL(urlSuffix))
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// CountResponseInputTokens returns the number of input tokens a request would use.
|
||||
func (c *Client) CountResponseInputTokens(
|
||||
ctx context.Context,
|
||||
request ResponseInputTokensRequest,
|
||||
) (response ResponseInputTokensResponse, err error) {
|
||||
request.Stream = false
|
||||
request.StreamOptions = nil
|
||||
req, err := c.newRequest(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
c.fullURL(responsesSuffix+"/input_tokens"),
|
||||
withBody(request),
|
||||
)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// CompactResponse compacts a response context for use in a later request.
|
||||
func (c *Client) CompactResponse(
|
||||
ctx context.Context,
|
||||
request CompactResponseRequest,
|
||||
) (response ResponseCompaction, err error) {
|
||||
request.Stream = false
|
||||
request.StreamOptions = nil
|
||||
req, err := c.newRequest(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
c.fullURL(responsesSuffix+"/compact"),
|
||||
withBody(request),
|
||||
)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
err = c.sendRequest(req, &response)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func responseResourceSuffix(responseID, action string, values url.Values) string {
|
||||
suffix := fmt.Sprintf("%s/%s", responsesSuffix, url.PathEscape(responseID))
|
||||
if action != "" {
|
||||
suffix += "/" + action
|
||||
}
|
||||
if len(values) != 0 {
|
||||
suffix += "?" + values.Encode()
|
||||
}
|
||||
return suffix
|
||||
}
|
||||
131
vendor/github.com/sashabaranov/go-openai/response_stream.go
generated
vendored
Normal file
131
vendor/github.com/sashabaranov/go-openai/response_stream.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package openai
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ResponseStreamEventType identifies an event emitted while a response is generated.
|
||||
type ResponseStreamEventType string
|
||||
|
||||
const (
|
||||
ResponseStreamEventCreated ResponseStreamEventType = "response.created"
|
||||
ResponseStreamEventQueued ResponseStreamEventType = "response.queued"
|
||||
ResponseStreamEventInProgress ResponseStreamEventType = "response.in_progress"
|
||||
ResponseStreamEventCompleted ResponseStreamEventType = "response.completed"
|
||||
ResponseStreamEventFailed ResponseStreamEventType = "response.failed"
|
||||
ResponseStreamEventIncomplete ResponseStreamEventType = "response.incomplete"
|
||||
ResponseStreamEventOutputItemAdded ResponseStreamEventType = "response.output_item.added"
|
||||
ResponseStreamEventOutputItemDone ResponseStreamEventType = "response.output_item.done"
|
||||
ResponseStreamEventContentPartAdded ResponseStreamEventType = "response.content_part.added"
|
||||
ResponseStreamEventContentPartDone ResponseStreamEventType = "response.content_part.done"
|
||||
ResponseStreamEventOutputTextDelta ResponseStreamEventType = "response.output_text.delta"
|
||||
ResponseStreamEventOutputTextDone ResponseStreamEventType = "response.output_text.done"
|
||||
ResponseStreamEventOutputTextAnnotationAdded ResponseStreamEventType = "response.output_text.annotation.added"
|
||||
ResponseStreamEventRefusalDelta ResponseStreamEventType = "response.refusal.delta"
|
||||
ResponseStreamEventRefusalDone ResponseStreamEventType = "response.refusal.done"
|
||||
ResponseStreamEventFunctionArgumentsDelta ResponseStreamEventType = "response.function_call_arguments.delta"
|
||||
ResponseStreamEventFunctionArgumentsDone ResponseStreamEventType = "response.function_call_arguments.done"
|
||||
ResponseStreamEventReasoningSummaryTextDelta ResponseStreamEventType = "response.reasoning_summary_text.delta"
|
||||
ResponseStreamEventReasoningSummaryTextDone ResponseStreamEventType = "response.reasoning_summary_text.done"
|
||||
ResponseStreamEventReasoningSummaryPartAdded ResponseStreamEventType = "response.reasoning_summary_part.added"
|
||||
ResponseStreamEventReasoningSummaryPartDone ResponseStreamEventType = "response.reasoning_summary_part.done"
|
||||
ResponseStreamEventReasoningTextDelta ResponseStreamEventType = "response.reasoning_text.delta"
|
||||
ResponseStreamEventReasoningTextDone ResponseStreamEventType = "response.reasoning_text.done"
|
||||
ResponseStreamEventAudioDelta ResponseStreamEventType = "response.audio.delta"
|
||||
ResponseStreamEventAudioDone ResponseStreamEventType = "response.audio.done"
|
||||
ResponseStreamEventAudioTranscriptDelta ResponseStreamEventType = "response.audio.transcript.delta"
|
||||
ResponseStreamEventAudioTranscriptDone ResponseStreamEventType = "response.audio.transcript.done"
|
||||
ResponseStreamEventWebSearchInProgress ResponseStreamEventType = "response.web_search_call.in_progress"
|
||||
ResponseStreamEventWebSearchSearching ResponseStreamEventType = "response.web_search_call.searching"
|
||||
ResponseStreamEventWebSearchCompleted ResponseStreamEventType = "response.web_search_call.completed"
|
||||
ResponseStreamEventFileSearchInProgress ResponseStreamEventType = "response.file_search_call.in_progress"
|
||||
ResponseStreamEventFileSearchSearching ResponseStreamEventType = "response.file_search_call.searching"
|
||||
ResponseStreamEventFileSearchCompleted ResponseStreamEventType = "response.file_search_call.completed"
|
||||
ResponseStreamEventCodeInterpreterInProgress ResponseStreamEventType = "response.code_interpreter_call.in_progress"
|
||||
ResponseStreamEventCodeInterpreterInterpreting ResponseStreamEventType = "response.code_interpreter_call.interpreting"
|
||||
ResponseStreamEventCodeInterpreterCompleted ResponseStreamEventType = "response.code_interpreter_call.completed"
|
||||
ResponseStreamEventCodeInterpreterCodeDelta ResponseStreamEventType = "response.code_interpreter_call_code.delta"
|
||||
ResponseStreamEventCodeInterpreterCodeDone ResponseStreamEventType = "response.code_interpreter_call_code.done"
|
||||
ResponseStreamEventCustomToolInputDelta ResponseStreamEventType = "response.custom_tool_call_input.delta"
|
||||
ResponseStreamEventCustomToolInputDone ResponseStreamEventType = "response.custom_tool_call_input.done"
|
||||
ResponseStreamEventImageGenerationInProgress ResponseStreamEventType = "response.image_generation_call.in_progress"
|
||||
ResponseStreamEventImageGenerationGenerating ResponseStreamEventType = "response.image_generation_call.generating"
|
||||
ResponseStreamEventImageGenerationCompleted ResponseStreamEventType = "response.image_generation_call.completed"
|
||||
ResponseStreamEventImageGenerationPartialImage ResponseStreamEventType = "response.image_generation_call.partial_image"
|
||||
ResponseStreamEventMCPCallInProgress ResponseStreamEventType = "response.mcp_call.in_progress"
|
||||
ResponseStreamEventMCPCallCompleted ResponseStreamEventType = "response.mcp_call.completed"
|
||||
ResponseStreamEventMCPCallFailed ResponseStreamEventType = "response.mcp_call.failed"
|
||||
ResponseStreamEventMCPCallArgumentsDelta ResponseStreamEventType = "response.mcp_call_arguments.delta"
|
||||
ResponseStreamEventMCPCallArgumentsDone ResponseStreamEventType = "response.mcp_call_arguments.done"
|
||||
ResponseStreamEventMCPListToolsInProgress ResponseStreamEventType = "response.mcp_list_tools.in_progress"
|
||||
ResponseStreamEventMCPListToolsCompleted ResponseStreamEventType = "response.mcp_list_tools.completed"
|
||||
ResponseStreamEventMCPListToolsFailed ResponseStreamEventType = "response.mcp_list_tools.failed"
|
||||
ResponseStreamEventError ResponseStreamEventType = "error"
|
||||
)
|
||||
|
||||
// ResponseStreamEvent contains the common fields across Responses API SSE event variants.
|
||||
type ResponseStreamEvent struct {
|
||||
Type ResponseStreamEventType `json:"type"`
|
||||
SequenceNumber int `json:"sequence_number,omitempty"`
|
||||
Response *CreateResponseResponse `json:"response,omitempty"`
|
||||
Item *ResponseOutputItem `json:"item,omitempty"`
|
||||
Part *ResponseOutputContent `json:"part,omitempty"`
|
||||
Annotation *ResponseAnnotation `json:"annotation,omitempty"`
|
||||
ItemID string `json:"item_id,omitempty"`
|
||||
OutputIndex int `json:"output_index,omitempty"`
|
||||
ContentIndex int `json:"content_index,omitempty"`
|
||||
SummaryIndex int `json:"summary_index,omitempty"`
|
||||
Delta string `json:"delta,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Arguments string `json:"arguments,omitempty"`
|
||||
PartialImageB64 string `json:"partial_image_b64,omitempty"`
|
||||
PartialImageIndex int `json:"partial_image_index,omitempty"`
|
||||
Logprobs []ResponseLogprob `json:"logprobs,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Param any `json:"param,omitempty"`
|
||||
Error *ResponseError `json:"error,omitempty"`
|
||||
Obfuscation string `json:"obfuscation,omitempty"`
|
||||
Raw json.RawMessage `json:"-"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes known event fields and retains the complete event for
|
||||
// forward compatibility with event variants added by the API.
|
||||
func (e *ResponseStreamEvent) UnmarshalJSON(data []byte) error {
|
||||
type eventAlias ResponseStreamEvent
|
||||
if err := json.Unmarshal(data, (*eventAlias)(e)); err != nil {
|
||||
return err
|
||||
}
|
||||
e.Raw = append(e.Raw[:0], data...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResponseStream reads server-sent events from a streaming Responses API request.
|
||||
type ResponseStream struct {
|
||||
*streamReader[ResponseStreamEvent]
|
||||
}
|
||||
|
||||
// CreateResponseStream creates a response and streams its generation events.
|
||||
func (c *Client) CreateResponseStream(
|
||||
ctx context.Context,
|
||||
request CreateResponseRequest,
|
||||
) (stream *ResponseStream, err error) {
|
||||
request.Stream = true
|
||||
req, err := c.newRequest(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
c.fullURL(responsesSuffix),
|
||||
withBody(request),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader, err := sendRequestStream[ResponseStreamEvent](c, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ResponseStream{streamReader: reader}, nil
|
||||
}
|
||||
2
vendor/github.com/sashabaranov/go-openai/stream.go
generated
vendored
2
vendor/github.com/sashabaranov/go-openai/stream.go
generated
vendored
@@ -22,7 +22,7 @@ func (c *Client) CreateCompletionStream(
|
||||
ctx context.Context,
|
||||
request CompletionRequest,
|
||||
) (stream *CompletionStream, err error) {
|
||||
urlSuffix := "/completions"
|
||||
urlSuffix := completionsSuffix
|
||||
if !checkEndpointSupportsModel(urlSuffix, request.Model) {
|
||||
err = ErrCompletionUnsupportedModel
|
||||
return
|
||||
|
||||
10
vendor/github.com/sashabaranov/go-openai/stream_reader.go
generated
vendored
10
vendor/github.com/sashabaranov/go-openai/stream_reader.go
generated
vendored
@@ -17,7 +17,7 @@ var (
|
||||
)
|
||||
|
||||
type streamable interface {
|
||||
ChatCompletionStreamResponse | CompletionResponse
|
||||
ChatCompletionStreamResponse | CompletionResponse | ResponseStreamEvent
|
||||
}
|
||||
|
||||
type streamReader[T streamable] struct {
|
||||
@@ -64,7 +64,13 @@ func (stream *streamReader[T]) processLines() ([]byte, error) {
|
||||
rawLine, readErr := stream.reader.ReadBytes('\n')
|
||||
if readErr != nil || hasErrorPrefix {
|
||||
respErr := stream.unmarshalError()
|
||||
if respErr != nil {
|
||||
// respErr.Error can be nil even when respErr itself isn't:
|
||||
// any payload that round-trips through unmarshaler.Unmarshal
|
||||
// (an empty object, an aborted partial frame after context
|
||||
// cancellation, etc.) ends up as a non-nil *ErrorResponse with
|
||||
// a nil Error field. Wrapping that produced the famously
|
||||
// useless "error, <nil>" message in #1060.
|
||||
if respErr != nil && respErr.Error != nil {
|
||||
return nil, fmt.Errorf("error, %w", respErr.Error)
|
||||
}
|
||||
return nil, readErr
|
||||
|
||||
Reference in New Issue
Block a user