From 94d54c1e19d0d58875f56058042e06410b23ac49 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:33:36 +0000 Subject: [PATCH 1/4] fix(api): docs updates --- .stats.yml | 4 ++-- aliases.go | 2 ++ conversations/aliases.go | 2 ++ file.go | 27 +++++++++++++-------------- realtime/aliases.go | 2 ++ responses/aliases.go | 2 ++ shared/shared.go | 6 ++++++ webhooks/aliases.go | 2 ++ 8 files changed, 31 insertions(+), 16 deletions(-) diff --git a/.stats.yml b/.stats.yml index fb11b5c3..b9802c0b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 123 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a4bb37d110a22c2888f53e21281434686a6fffa3e672a40f2503ad9bd2759063.yml -openapi_spec_hash: 2d59eefb494dff4eea8c3d008c7e2070 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a3c45d9bd3bb25bf4eaa49b7fb473a00038293dec659ffaa44f624ded884abf4.yml +openapi_spec_hash: 9c20aaf786a0700dabd13d9865481c9e config_hash: 50ee3382a63c021a9f821a935950e926 diff --git a/aliases.go b/aliases.go index a9b15fe3..3a8e5633 100644 --- a/aliases.go +++ b/aliases.go @@ -371,6 +371,8 @@ const ReasoningGenerateSummaryDetailed = shared.ReasoningGenerateSummaryDetailed // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // +// `concise` is only supported for `computer-use-preview` models. +// // This is an alias to an internal type. type ReasoningSummary = shared.ReasoningSummary diff --git a/conversations/aliases.go b/conversations/aliases.go index 632bc070..a790e593 100644 --- a/conversations/aliases.go +++ b/conversations/aliases.go @@ -371,6 +371,8 @@ const ReasoningGenerateSummaryDetailed = shared.ReasoningGenerateSummaryDetailed // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // +// `concise` is only supported for `computer-use-preview` models. +// // This is an alias to an internal type. type ReasoningSummary = shared.ReasoningSummary diff --git a/file.go b/file.go index bf152b01..7a3d7aec 100644 --- a/file.go +++ b/file.go @@ -47,20 +47,19 @@ func NewFileService(opts ...option.RequestOption) (r FileService) { // up to 512 MB, and the size of all files uploaded by one organization can be up // to 1 TB. // -// The Assistants API supports files up to 2 million tokens and of specific file -// types. See the -// [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for -// details. -// -// The Fine-tuning API only supports `.jsonl` files. The input also has certain -// required formats for fine-tuning -// [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or -// [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) -// models. -// -// The Batch API only supports `.jsonl` files up to 200 MB in size. The input also -// has a specific required -// [format](https://platform.openai.com/docs/api-reference/batch/request-input). +// - The Assistants API supports files up to 2 million tokens and of specific file +// types. See the +// [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) +// for details. +// - The Fine-tuning API only supports `.jsonl` files. The input also has certain +// required formats for fine-tuning +// [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) +// or +// [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) +// models. +// - The Batch API only supports `.jsonl` files up to 200 MB in size. The input +// also has a specific required +// [format](https://platform.openai.com/docs/api-reference/batch/request-input). // // Please [contact us](https://help.openai.com/) if you need to increase these // storage limits. diff --git a/realtime/aliases.go b/realtime/aliases.go index 4d943004..1a4d6fef 100644 --- a/realtime/aliases.go +++ b/realtime/aliases.go @@ -371,6 +371,8 @@ const ReasoningGenerateSummaryDetailed = shared.ReasoningGenerateSummaryDetailed // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // +// `concise` is only supported for `computer-use-preview` models. +// // This is an alias to an internal type. type ReasoningSummary = shared.ReasoningSummary diff --git a/responses/aliases.go b/responses/aliases.go index 2db81bef..06ebfd07 100644 --- a/responses/aliases.go +++ b/responses/aliases.go @@ -371,6 +371,8 @@ const ReasoningGenerateSummaryDetailed = shared.ReasoningGenerateSummaryDetailed // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // +// `concise` is only supported for `computer-use-preview` models. +// // This is an alias to an internal type. type ReasoningSummary = shared.ReasoningSummary diff --git a/shared/shared.go b/shared/shared.go index d162c9c5..b99c9c9f 100644 --- a/shared/shared.go +++ b/shared/shared.go @@ -769,6 +769,8 @@ type Reasoning struct { // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // + // `concise` is only supported for `computer-use-preview` models. + // // Any of "auto", "concise", "detailed". Summary ReasoningSummary `json:"summary,nullable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -812,6 +814,8 @@ const ( // A summary of the reasoning performed by the model. This can be useful for // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. +// +// `concise` is only supported for `computer-use-preview` models. type ReasoningSummary string const ( @@ -850,6 +854,8 @@ type ReasoningParam struct { // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // + // `concise` is only supported for `computer-use-preview` models. + // // Any of "auto", "concise", "detailed". Summary ReasoningSummary `json:"summary,omitzero"` paramObj diff --git a/webhooks/aliases.go b/webhooks/aliases.go index 488550ee..42b8546a 100644 --- a/webhooks/aliases.go +++ b/webhooks/aliases.go @@ -371,6 +371,8 @@ const ReasoningGenerateSummaryDetailed = shared.ReasoningGenerateSummaryDetailed // debugging and understanding the model's reasoning process. One of `auto`, // `concise`, or `detailed`. // +// `concise` is only supported for `computer-use-preview` models. +// // This is an alias to an internal type. type ReasoningSummary = shared.ReasoningSummary From cf50c53f779784e1ee73b7d815456afaa3e1c447 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 00:54:02 +0000 Subject: [PATCH 2/4] feat(api): remove InputAudio from ResponseInputContent Removes the type `InputAudio` from `ResponseInputContent`. This parameter was non-functional and has now been removed. Please note that this is not a feature removal; it was never supported by the Responses API. While this is technically a backward-incompatible change due to the type removal, it reflects the intended behavior and has no functional impact. --- .stats.yml | 4 +-- responses/response.go | 75 +++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/.stats.yml b/.stats.yml index b9802c0b..d52cd214 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 123 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a3c45d9bd3bb25bf4eaa49b7fb473a00038293dec659ffaa44f624ded884abf4.yml -openapi_spec_hash: 9c20aaf786a0700dabd13d9865481c9e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-f68f718cd45ac3f9336603601bccc38a718af44d0b26601031de3d0a71b7ce2f.yml +openapi_spec_hash: 1560717860bba4105936647dde8f618d config_hash: 50ee3382a63c021a9f821a935950e926 diff --git a/responses/response.go b/responses/response.go index d69bdc27..894ac110 100644 --- a/responses/response.go +++ b/responses/response.go @@ -223,6 +223,8 @@ func (r *ComputerToolParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// A custom tool that processes input using a specified format. Learn more about +// [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) type CustomTool struct { // The name of the custom tool, used to identify it in tool calls. Name string `json:"name,required"` @@ -258,6 +260,9 @@ func (r CustomTool) ToParam() CustomToolParam { return param.Override[CustomToolParam](json.RawMessage(r.RawJSON())) } +// A custom tool that processes input using a specified format. Learn more about +// [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) +// // The properties Name, Type are required. type CustomToolParam struct { // The name of the custom tool, used to identify it in tool calls. @@ -5708,8 +5713,7 @@ func (r *ResponseInputAudioInputAudioParam) UnmarshalJSON(data []byte) error { } // ResponseInputContentUnion contains all possible properties and values from -// [ResponseInputText], [ResponseInputImage], [ResponseInputFile], -// [ResponseInputAudio]. +// [ResponseInputText], [ResponseInputImage], [ResponseInputFile]. // // Use the [ResponseInputContentUnion.AsAny] method to switch on the variant. // @@ -5717,7 +5721,7 @@ func (r *ResponseInputAudioInputAudioParam) UnmarshalJSON(data []byte) error { type ResponseInputContentUnion struct { // This field is from variant [ResponseInputText]. Text string `json:"text"` - // Any of "input_text", "input_image", "input_file", "input_audio". + // Any of "input_text", "input_image", "input_file". Type string `json:"type"` // This field is from variant [ResponseInputImage]. Detail ResponseInputImageDetail `json:"detail"` @@ -5730,19 +5734,16 @@ type ResponseInputContentUnion struct { FileURL string `json:"file_url"` // This field is from variant [ResponseInputFile]. Filename string `json:"filename"` - // This field is from variant [ResponseInputAudio]. - InputAudio ResponseInputAudioInputAudio `json:"input_audio"` - JSON struct { - Text respjson.Field - Type respjson.Field - Detail respjson.Field - FileID respjson.Field - ImageURL respjson.Field - FileData respjson.Field - FileURL respjson.Field - Filename respjson.Field - InputAudio respjson.Field - raw string + JSON struct { + Text respjson.Field + Type respjson.Field + Detail respjson.Field + FileID respjson.Field + ImageURL respjson.Field + FileData respjson.Field + FileURL respjson.Field + Filename respjson.Field + raw string } `json:"-"` } @@ -5756,7 +5757,6 @@ type anyResponseInputContent interface { func (ResponseInputText) implResponseInputContentUnion() {} func (ResponseInputImage) implResponseInputContentUnion() {} func (ResponseInputFile) implResponseInputContentUnion() {} -func (ResponseInputAudio) implResponseInputContentUnion() {} // Use the following switch statement to find the correct variant // @@ -5764,7 +5764,6 @@ func (ResponseInputAudio) implResponseInputContentUnion() {} // case responses.ResponseInputText: // case responses.ResponseInputImage: // case responses.ResponseInputFile: -// case responses.ResponseInputAudio: // default: // fmt.Errorf("no variant present") // } @@ -5776,8 +5775,6 @@ func (u ResponseInputContentUnion) AsAny() anyResponseInputContent { return u.AsInputImage() case "input_file": return u.AsInputFile() - case "input_audio": - return u.AsInputAudio() } return nil } @@ -5797,11 +5794,6 @@ func (u ResponseInputContentUnion) AsInputFile() (v ResponseInputFile) { return } -func (u ResponseInputContentUnion) AsInputAudio() (v ResponseInputAudio) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return -} - // Returns the unmodified JSON received from the API func (u ResponseInputContentUnion) RawJSON() string { return u.JSON.raw } @@ -5831,12 +5823,6 @@ func ResponseInputContentParamOfInputImage(detail ResponseInputImageDetail) Resp return ResponseInputContentUnionParam{OfInputImage: &inputImage} } -func ResponseInputContentParamOfInputAudio(inputAudio ResponseInputAudioInputAudioParam) ResponseInputContentUnionParam { - var variant ResponseInputAudioParam - variant.InputAudio = inputAudio - return ResponseInputContentUnionParam{OfInputAudio: &variant} -} - // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. @@ -5844,12 +5830,11 @@ type ResponseInputContentUnionParam struct { OfInputText *ResponseInputTextParam `json:",omitzero,inline"` OfInputImage *ResponseInputImageParam `json:",omitzero,inline"` OfInputFile *ResponseInputFileParam `json:",omitzero,inline"` - OfInputAudio *ResponseInputAudioParam `json:",omitzero,inline"` paramUnion } func (u ResponseInputContentUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfInputText, u.OfInputImage, u.OfInputFile, u.OfInputAudio) + return param.MarshalUnion(u, u.OfInputText, u.OfInputImage, u.OfInputFile) } func (u *ResponseInputContentUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) @@ -5862,8 +5847,6 @@ func (u *ResponseInputContentUnionParam) asAny() any { return u.OfInputImage } else if !param.IsOmitted(u.OfInputFile) { return u.OfInputFile - } else if !param.IsOmitted(u.OfInputAudio) { - return u.OfInputAudio } return nil } @@ -5916,14 +5899,6 @@ func (u ResponseInputContentUnionParam) GetFilename() *string { return nil } -// Returns a pointer to the underlying variant's property, if present. -func (u ResponseInputContentUnionParam) GetInputAudio() *ResponseInputAudioInputAudioParam { - if vt := u.OfInputAudio; vt != nil { - return &vt.InputAudio - } - return nil -} - // Returns a pointer to the underlying variant's property, if present. func (u ResponseInputContentUnionParam) GetType() *string { if vt := u.OfInputText; vt != nil { @@ -5932,8 +5907,6 @@ func (u ResponseInputContentUnionParam) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfInputFile; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfInputAudio; vt != nil { - return (*string)(&vt.Type) } return nil } @@ -5948,6 +5921,15 @@ func (u ResponseInputContentUnionParam) GetFileID() *string { return nil } +func init() { + apijson.RegisterUnion[ResponseInputContentUnionParam]( + "type", + apijson.Discriminator[ResponseInputTextParam]("input_text"), + apijson.Discriminator[ResponseInputImageParam]("input_image"), + apijson.Discriminator[ResponseInputFileParam]("input_file"), + ) +} + // A file input to the model. type ResponseInputFile struct { // The type of the input item. Always `input_file`. @@ -13581,6 +13563,7 @@ func (r *ToolImageGenerationInputImageMask) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// A tool that allows the model to execute shell commands in a local environment. type ToolLocalShell struct { // The type of the local shell tool. Always `local_shell`. Type constant.LocalShell `json:"type,required"` @@ -14513,6 +14496,8 @@ func NewToolLocalShellParam() ToolLocalShellParam { } } +// A tool that allows the model to execute shell commands in a local environment. +// // This struct has a constant value, construct it with [NewToolLocalShellParam]. type ToolLocalShellParam struct { // The type of the local shell tool. Always `local_shell`. From dffa08ece6c860ae1f87a01a5b8c26f18ce7ab2b Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 28 Oct 2025 03:51:26 -0700 Subject: [PATCH 3/4] feat(azure): allow passing custom scopes (#541) Co-authored-by: ripark --- azure/azure.go | 64 +++++++++++++++++++++++++++++++------------ azure/example_test.go | 26 ++++++++++++++++++ 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/azure/azure.go b/azure/azure.go index 354081c4..f82e451c 100644 --- a/azure/azure.go +++ b/azure/azure.go @@ -91,30 +91,60 @@ func WithEndpoint(endpoint string, apiVersion string) option.RequestOption { }) } +type tokenCredentialConfig struct { + Scopes []string +} + +// TokenCredentialOption is the type for any options that can be used to customize +// [WithTokenCredential], including things like using custom scopes. +type TokenCredentialOption func(*tokenCredentialConfig) error + +// WithTokenCredentialScopes overrides the default scope used when requesting access tokens. +func WithTokenCredentialScopes(scopes []string) func(*tokenCredentialConfig) error { + return func(tc *tokenCredentialConfig) error { + tc.Scopes = scopes + return nil + } +} + // WithTokenCredential configures this client to authenticate using an [Azure Identity] TokenCredential. // This function should be paired with a call to [WithEndpoint] to point to your Azure OpenAI instance. // // [Azure Identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity -func WithTokenCredential(tokenCredential azcore.TokenCredential) option.RequestOption { - bearerTokenPolicy := runtime.NewBearerTokenPolicy(tokenCredential, []string{"https://cognitiveservices.azure.com/.default"}, nil) - - // add in a middleware that uses the bearer token generated from the token credential - return option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) { - pipeline := runtime.NewPipeline("azopenai-extensions", version, runtime.PipelineOptions{}, &policy.ClientOptions{ - InsecureAllowCredentialWithHTTP: true, // allow for plain HTTP proxies, etc.. - PerRetryPolicies: []policy.Policy{ - bearerTokenPolicy, - policyAdapter(next), - }, - }) - - req2, err := runtime.NewRequestFromRequest(req) +func WithTokenCredential(tokenCredential azcore.TokenCredential, options ...TokenCredentialOption) option.RequestOption { + return requestconfig.RequestOptionFunc(func(rc *requestconfig.RequestConfig) error { + tc := &tokenCredentialConfig{ + Scopes: []string{"https://cognitiveservices.azure.com/.default"}, + } - if err != nil { - return nil, err + for _, option := range options { + if err := option(tc); err != nil { + return err + } } - return pipeline.Do(req2) + bearerTokenPolicy := runtime.NewBearerTokenPolicy(tokenCredential, tc.Scopes, nil) + + // add in a middleware that uses the bearer token generated from the token credential + middlewareOption := option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) { + pipeline := runtime.NewPipeline("azopenai-extensions", version, runtime.PipelineOptions{}, &policy.ClientOptions{ + InsecureAllowCredentialWithHTTP: true, // allow for plain HTTP proxies, etc.. + PerRetryPolicies: []policy.Policy{ + bearerTokenPolicy, + policyAdapter(next), + }, + }) + + req2, err := runtime.NewRequestFromRequest(req) + + if err != nil { + return nil, err + } + + return pipeline.Do(req2) + }) + + return middlewareOption.Apply(rc) }) } diff --git a/azure/example_test.go b/azure/example_test.go index 211d6de1..057f94ec 100644 --- a/azure/example_test.go +++ b/azure/example_test.go @@ -45,3 +45,29 @@ func Example_authentication() { _ = client } } + +func Example_authentication_custom_scopes() { + // Custom scopes can also be passed, if needed, when using Azure OpenAI endpoints. + const azureOpenAIEndpoint = "https://.openai.azure.com" + const azureOpenAIAPIVersion = "" + + // For a full list of credential types look at the documentation for the Azure Identity + // package: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity + tokenCredential, err := azidentity.NewDefaultAzureCredential(nil) + + if err != nil { + fmt.Printf("Failed to create TokenCredential: %s\n", err) + return + } + + client := openai.NewClient( + azure.WithEndpoint(azureOpenAIEndpoint, azureOpenAIAPIVersion), + azure.WithTokenCredential(tokenCredential, + // This is an example of a custom scope. See documentation for your service + // endpoint for the proper value to pass. + azure.WithTokenCredentialScopes([]string{"your-custom-scope"}), + ), + ) + + _ = client +} From 89f8bde10a3b1a6106fe93ba54c72ffc1ccee673 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:51:48 +0000 Subject: [PATCH 4/4] release: 3.7.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a25092c4..27d2fbbc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.6.1" + ".": "3.7.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ff42f1c4..e3568b5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 3.7.0 (2025-10-28) + +Full Changelog: [v3.6.1...v3.7.0](https://github.com/openai/openai-go/compare/v3.6.1...v3.7.0) + +### Features + +* **api:** remove InputAudio from ResponseInputContent ([cf50c53](https://github.com/openai/openai-go/commit/cf50c53f779784e1ee73b7d815456afaa3e1c447)) +* **azure:** allow passing custom scopes ([#541](https://github.com/openai/openai-go/issues/541)) ([dffa08e](https://github.com/openai/openai-go/commit/dffa08ece6c860ae1f87a01a5b8c26f18ce7ab2b)) + + +### Bug Fixes + +* **api:** docs updates ([94d54c1](https://github.com/openai/openai-go/commit/94d54c1e19d0d58875f56058042e06410b23ac49)) + ## 3.6.1 (2025-10-20) Full Changelog: [v3.6.0...v3.6.1](https://github.com/openai/openai-go/compare/v3.6.0...v3.6.1) diff --git a/README.md b/README.md index 941848f7..409bb3d5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Or to pin the version: ```sh -go get -u 'github.com/openai/openai-go/v2@v3.6.1' +go get -u 'github.com/openai/openai-go/v2@v3.7.0' ``` diff --git a/internal/version.go b/internal/version.go index 5dfe2f7f..5cf3a1ef 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "3.6.1" // x-release-please-version +const PackageVersion = "3.7.0" // x-release-please-version