From d76ac151d7dbcef7abda136de4624bd593e522ff Mon Sep 17 00:00:00 2001 From: Jacob Zimmerman Date: Mon, 24 Feb 2025 09:59:52 -0500 Subject: [PATCH] examples and stuff work --- README.md | 66 +- aliases.go | 118 +- api.md | 18 +- audio.go | 18 +- audiospeech.go | 44 +- audiospeech_test.go | 10 +- audiotranscription.go | 64 +- audiotranscription_test.go | 14 +- audiotranslation.go | 50 +- audiotranslation_test.go | 10 +- batch.go | 264 ++- batch_test.go | 14 +- beta.go | 10 +- betaassistant.go | 2544 ++++++++++--------------- betaassistant_test.go | 104 +- betathread.go | 928 ++++----- betathread_test.go | 202 +- betathreadmessage.go | 2253 ++++++++-------------- betathreadmessage_test.go | 36 +- betathreadrun.go | 681 +++---- betathreadrun_test.go | 90 +- betathreadrunstep.go | 2044 +++++++------------- betathreadrunstep_test.go | 12 +- betavectorstore.go | 689 +++---- betavectorstore_test.go | 42 +- betavectorstorefile.go | 213 +-- betavectorstorefile_test.go | 18 +- betavectorstorefilebatch.go | 163 +- betavectorstorefilebatch_test.go | 18 +- chat.go | 6 +- chatcompletion.go | 2049 +++++++++----------- chatcompletion_test.go | 141 +- chatcompletionmessage.go | 25 +- chatcompletionmessage_test.go | 6 +- client.go | 28 +- client_test.go | 126 +- completion.go | 347 ++-- completion_test.go | 47 +- embedding.go | 192 +- embedding_test.go | 13 +- field.go | 76 +- file.go | 181 +- file_test.go | 12 +- finetuning.go | 6 +- finetuningjob.go | 1497 ++++++--------- finetuningjob_test.go | 102 +- finetuningjobcheckpoint.go | 125 +- finetuningjobcheckpoint_test.go | 4 +- image.go | 197 +- image_test.go | 44 +- internal/apierror/apierror.go | 43 +- internal/apifield/metadata.go | 27 + internal/apiform/encoder.go | 9 +- internal/apiform/richparam.go | 27 + internal/apijson/decoder.go | 8 +- internal/apijson/encoder.go | 2 +- internal/apijson/field.go | 18 - internal/apijson/json_test.go | 12 +- internal/apijson/port.go | 2 +- internal/apijson/subfield.go | 45 + internal/apiquery/encoder.go | 10 +- internal/apiquery/query_test.go | 13 + internal/apiquery/richparam.go | 29 + internal/encoding/json/decode.go | 1324 +++++++++++++ internal/encoding/json/encode.go | 1349 +++++++++++++ internal/encoding/json/fold.go | 48 + internal/encoding/json/indent.go | 182 ++ internal/encoding/json/scanner.go | 610 ++++++ internal/encoding/json/shims/shims.go | 111 ++ internal/encoding/json/stream.go | 512 +++++ internal/encoding/json/tables.go | 218 +++ internal/encoding/json/tags.go | 38 + internal/param/field.go | 4 +- model.go | 85 +- moderation.go | 578 +++--- moderation_test.go | 7 +- packages/pagination/pagination.go | 68 +- packages/param/encoder.go | 115 ++ packages/param/encoder_test.go | 84 + packages/param/metadata.go | 9 + packages/param/param.go | 212 +++ packages/resp/resp.go | 47 + paginationauto_test.go | 2 +- paginationmanual_test.go | 2 +- shared/constant/constants.go | 282 +++ shared/shared.go | 195 +- upload.go | 118 +- upload_test.go | 12 +- uploadpart.go | 63 +- uploadpart_test.go | 2 +- usage_test.go | 15 +- 91 files changed, 12207 insertions(+), 10291 deletions(-) create mode 100644 internal/apifield/metadata.go create mode 100644 internal/apiform/richparam.go create mode 100644 internal/apijson/subfield.go create mode 100644 internal/apiquery/richparam.go create mode 100644 internal/encoding/json/decode.go create mode 100644 internal/encoding/json/encode.go create mode 100644 internal/encoding/json/fold.go create mode 100644 internal/encoding/json/indent.go create mode 100644 internal/encoding/json/scanner.go create mode 100644 internal/encoding/json/shims/shims.go create mode 100644 internal/encoding/json/stream.go create mode 100644 internal/encoding/json/tables.go create mode 100644 internal/encoding/json/tags.go create mode 100644 packages/param/encoder.go create mode 100644 packages/param/encoder_test.go create mode 100644 packages/param/metadata.go create mode 100644 packages/param/param.go create mode 100644 packages/resp/resp.go create mode 100644 shared/constant/constants.go diff --git a/README.md b/README.md index 0b6e133..ff44021 100644 --- a/README.md +++ b/README.md @@ -51,11 +51,14 @@ func main() { option.WithAPIKey("My API Key"), // defaults to os.LookupEnv("OPENAI_API_KEY") ) chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err != nil { panic(err.Error()) @@ -167,7 +170,7 @@ You can use `.ListAutoPaging()` methods to iterate through items across all page ```go iter := client.FineTuning.Jobs.ListAutoPaging(context.TODO(), openai.FineTuningJobListParams{ - Limit: openai.F(int64(20)), + Limit: openai.Int(20), }) // Automatically fetches more pages as needed. for iter.Next() { @@ -184,7 +187,7 @@ with additional helper methods like `.GetNextPage()`, e.g.: ```go page, err := client.FineTuning.Jobs.List(context.TODO(), openai.FineTuningJobListParams{ - Limit: openai.F(int64(20)), + Limit: openai.Int(20), }) for page != nil { for _, job := range page.Data { @@ -208,8 +211,8 @@ To handle errors, we recommend that you use the `errors.As` pattern: ```go _, err := client.FineTuning.Jobs.New(context.TODO(), openai.FineTuningJobNewParams{ - Model: openai.F(openai.FineTuningJobNewParamsModelBabbage002), - TrainingFile: openai.F("file-abc123"), + Model: "babbage-002", + TrainingFile: openai.String("file-abc123"), }) if err != nil { var apierr *openai.Error @@ -238,11 +241,14 @@ defer cancel() client.Chat.Completions.New( ctx, openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }, // This sets the per-retry timeout option.WithRequestTimeout(20*time.Second), @@ -267,19 +273,19 @@ which can be used to wrap any `io.Reader` with the appropriate file name and con file, err := os.Open("input.jsonl") openai.FileNewParams{ File: openai.F[io.Reader](file), - Purpose: openai.F(openai.FilePurposeFineTune), + Purpose: openai.FilePurposeFineTune, } // A file from a string openai.FileNewParams{ File: openai.F[io.Reader](strings.NewReader("my file contents")), - Purpose: openai.F(openai.FilePurposeFineTune), + Purpose: openai.FilePurposeFineTune, } // With a custom filename and contentType openai.FileNewParams{ File: openai.FileParam(strings.NewReader(`{"hello": "foo"}`), "file.go", "application/json"), - Purpose: openai.F(openai.FilePurposeFineTune), + Purpose: openai.FilePurposeFineTune, } ``` @@ -301,11 +307,14 @@ client := openai.NewClient( client.Chat.Completions.New( context.TODO(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }, option.WithMaxRetries(5), ) @@ -322,11 +331,14 @@ var response *http.Response chatCompletion, err := client.Chat.Completions.New( context.TODO(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }, option.WithResponseInto(&response), ) diff --git a/aliases.go b/aliases.go index eae9b38..297840d 100644 --- a/aliases.go +++ b/aliases.go @@ -3,10 +3,21 @@ package openai import ( + "time" + "github.com/openai/openai-go/internal/apierror" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" + "github.com/openai/openai-go/shared/constant" ) +// aliased to make param.APIUnion private when embedding +type apiunion = param.APIUnion + +// aliased to make param.APIObject private when embedding +type apiobject = param.APIObject + type Error = apierror.Error // This is an alias to an internal type. @@ -52,35 +63,98 @@ type MetadataParam = shared.MetadataParam // This is an alias to an internal type. type ResponseFormatJSONObjectParam = shared.ResponseFormatJSONObjectParam -// The type of response format being defined: `json_object` -// -// This is an alias to an internal type. -type ResponseFormatJSONObjectType = shared.ResponseFormatJSONObjectType - -// This is an alias to an internal value. -const ResponseFormatJSONObjectTypeJSONObject = shared.ResponseFormatJSONObjectTypeJSONObject - // This is an alias to an internal type. type ResponseFormatJSONSchemaParam = shared.ResponseFormatJSONSchemaParam // This is an alias to an internal type. type ResponseFormatJSONSchemaJSONSchemaParam = shared.ResponseFormatJSONSchemaJSONSchemaParam -// The type of response format being defined: `json_schema` -// -// This is an alias to an internal type. -type ResponseFormatJSONSchemaType = shared.ResponseFormatJSONSchemaType - -// This is an alias to an internal value. -const ResponseFormatJSONSchemaTypeJSONSchema = shared.ResponseFormatJSONSchemaTypeJSONSchema - // This is an alias to an internal type. type ResponseFormatTextParam = shared.ResponseFormatTextParam -// The type of response format being defined: `text` -// -// This is an alias to an internal type. -type ResponseFormatTextType = shared.ResponseFormatTextType +// Internal helpers for converting from response to param types -// This is an alias to an internal value. -const ResponseFormatTextTypeText = shared.ResponseFormatTextTypeText +func newString(value string) param.String { + res := param.NeverOmitted[param.String]() + res.V = value + return res +} + +func newInt(value int64) param.Int { + res := param.NeverOmitted[param.Int]() + res.V = value + return res +} + +func newBool(value bool) param.Bool { + res := param.NeverOmitted[param.Bool]() + res.V = value + return res +} + +func newFloat(value float64) param.Float { + res := param.NeverOmitted[param.Float]() + res.V = value + return res +} + +func newDatetime(value time.Time) param.Datetime { + res := param.NeverOmitted[param.Datetime]() + res.V = value + return res +} + +func newDate(value time.Time) param.Date { + res := param.NeverOmitted[param.Date]() + res.V = value + return res +} + +func toParamString(value string, meta resp.Field) param.String { + if !meta.IsMissing() { + return newString(value) + } + return param.String{} +} + +func toParamInt(value int64, meta resp.Field) param.Int { + if !meta.IsMissing() { + return newInt(value) + } + return param.Int{} +} + +func toParamBool(value bool, meta resp.Field) param.Bool { + if !meta.IsMissing() { + return newBool(value) + } + return param.Bool{} +} + +func toParamFloat(value float64, meta resp.Field) param.Float { + if !meta.IsMissing() { + return newFloat(value) + } + return param.Float{} +} + +func toParamDatetime(value time.Time, meta resp.Field) param.Datetime { + if !meta.IsMissing() { + return newDatetime(value) + } + return param.Datetime{} +} + +func toParamDate(value time.Time, meta resp.Field) param.Date { + if !meta.IsMissing() { + return newDate(value) + } + return param.Date{} +} + +func ptrToConstant[T constant.Constant[T]](c T) *T { + if param.IsOmitted(c) { + c = c.Default() + } + return &c +} diff --git a/api.md b/api.md index 304da15..b650d34 100644 --- a/api.md +++ b/api.md @@ -245,7 +245,7 @@ Params Types: Response Types: -- openai.FileChunkingStrategy +- openai.FileChunkingStrategyUnion - openai.OtherFileChunkingStrategyObject - openai.StaticFileChunkingStrategy - openai.StaticFileChunkingStrategyObject @@ -300,8 +300,8 @@ Response Types: - openai.Assistant - openai.AssistantDeleted -- openai.AssistantStreamEvent -- openai.AssistantTool +- openai.AssistantStreamEventUnion +- openai.AssistantToolUnion - openai.CodeInterpreterTool - openai.FileSearchTool - openai.FunctionTool @@ -376,8 +376,8 @@ Response Types: - openai.RunStepDelta - openai.RunStepDeltaEvent - openai.RunStepDeltaMessageDelta -- openai.ToolCall -- openai.ToolCallDelta +- openai.ToolCallUnion +- openai.ToolCallDeltaUnion - openai.ToolCallDeltaObject - openai.ToolCallsStepDetails @@ -399,8 +399,8 @@ Params Types: Response Types: -- openai.Annotation -- openai.AnnotationDelta +- openai.AnnotationUnion +- openai.AnnotationDeltaUnion - openai.FileCitationAnnotation - openai.FileCitationDeltaAnnotation - openai.FilePathAnnotation @@ -414,8 +414,8 @@ Response Types: - openai.ImageURLDelta - openai.ImageURLDeltaBlock - openai.Message -- openai.MessageContent -- openai.MessageContentDelta +- openai.MessageContentUnion +- openai.MessageContentDeltaUnion - openai.MessageDeleted - openai.MessageDelta - openai.MessageDeltaEvent diff --git a/audio.go b/audio.go index 9728598..84bb311 100644 --- a/audio.go +++ b/audio.go @@ -14,16 +14,16 @@ import ( // the [NewAudioService] method instead. type AudioService struct { Options []option.RequestOption - Transcriptions *AudioTranscriptionService - Translations *AudioTranslationService - Speech *AudioSpeechService + Transcriptions AudioTranscriptionService + Translations AudioTranslationService + Speech AudioSpeechService } // NewAudioService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewAudioService(opts ...option.RequestOption) (r *AudioService) { - r = &AudioService{} +func NewAudioService(opts ...option.RequestOption) (r AudioService) { + r = AudioService{} r.Options = opts r.Transcriptions = NewAudioTranscriptionService(opts...) r.Translations = NewAudioTranslationService(opts...) @@ -48,11 +48,3 @@ const ( AudioResponseFormatVerboseJSON AudioResponseFormat = "verbose_json" AudioResponseFormatVTT AudioResponseFormat = "vtt" ) - -func (r AudioResponseFormat) IsKnown() bool { - switch r { - case AudioResponseFormatJSON, AudioResponseFormatText, AudioResponseFormatSRT, AudioResponseFormatVerboseJSON, AudioResponseFormatVTT: - return true - } - return false -} diff --git a/audiospeech.go b/audiospeech.go index 38f6f74..69e7647 100644 --- a/audiospeech.go +++ b/audiospeech.go @@ -6,10 +6,9 @@ import ( "context" "net/http" - "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" ) // AudioSpeechService contains methods and other services that help with @@ -25,8 +24,8 @@ type AudioSpeechService struct { // NewAudioSpeechService generates a new service that applies the given options to // each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewAudioSpeechService(opts ...option.RequestOption) (r *AudioSpeechService) { - r = &AudioSpeechService{} +func NewAudioSpeechService(opts ...option.RequestOption) (r AudioSpeechService) { + r = AudioSpeechService{} r.Options = opts return } @@ -49,25 +48,34 @@ const ( type AudioSpeechNewParams struct { // The text to generate audio for. The maximum length is 4096 characters. - Input param.Field[string] `json:"input,required"` + Input param.String `json:"input,omitzero,required"` // One of the available [TTS models](https://platform.openai.com/docs/models#tts): // `tts-1` or `tts-1-hd` - Model param.Field[SpeechModel] `json:"model,required"` + Model SpeechModel `json:"model,omitzero,required"` // The voice to use when generating the audio. Supported voices are `alloy`, `ash`, // `coral`, `echo`, `fable`, `onyx`, `nova`, `sage` and `shimmer`. Previews of the // voices are available in the // [Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech#voice-options). - Voice param.Field[AudioSpeechNewParamsVoice] `json:"voice,required"` + // + // Any of "alloy", "ash", "coral", "echo", "fable", "onyx", "nova", "sage", + // "shimmer" + Voice AudioSpeechNewParamsVoice `json:"voice,omitzero,required"` // The format to audio in. Supported formats are `mp3`, `opus`, `aac`, `flac`, // `wav`, and `pcm`. - ResponseFormat param.Field[AudioSpeechNewParamsResponseFormat] `json:"response_format"` + // + // Any of "mp3", "opus", "aac", "flac", "wav", "pcm" + ResponseFormat AudioSpeechNewParamsResponseFormat `json:"response_format,omitzero"` // The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is // the default. - Speed param.Field[float64] `json:"speed"` + Speed param.Float `json:"speed,omitzero"` + apiobject } +func (f AudioSpeechNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AudioSpeechNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow AudioSpeechNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // The voice to use when generating the audio. Supported voices are `alloy`, `ash`, @@ -88,14 +96,6 @@ const ( AudioSpeechNewParamsVoiceShimmer AudioSpeechNewParamsVoice = "shimmer" ) -func (r AudioSpeechNewParamsVoice) IsKnown() bool { - switch r { - case AudioSpeechNewParamsVoiceAlloy, AudioSpeechNewParamsVoiceAsh, AudioSpeechNewParamsVoiceCoral, AudioSpeechNewParamsVoiceEcho, AudioSpeechNewParamsVoiceFable, AudioSpeechNewParamsVoiceOnyx, AudioSpeechNewParamsVoiceNova, AudioSpeechNewParamsVoiceSage, AudioSpeechNewParamsVoiceShimmer: - return true - } - return false -} - // The format to audio in. Supported formats are `mp3`, `opus`, `aac`, `flac`, // `wav`, and `pcm`. type AudioSpeechNewParamsResponseFormat string @@ -108,11 +108,3 @@ const ( AudioSpeechNewParamsResponseFormatWAV AudioSpeechNewParamsResponseFormat = "wav" AudioSpeechNewParamsResponseFormatPCM AudioSpeechNewParamsResponseFormat = "pcm" ) - -func (r AudioSpeechNewParamsResponseFormat) IsKnown() bool { - switch r { - case AudioSpeechNewParamsResponseFormatMP3, AudioSpeechNewParamsResponseFormatOpus, AudioSpeechNewParamsResponseFormatAAC, AudioSpeechNewParamsResponseFormatFLAC, AudioSpeechNewParamsResponseFormatWAV, AudioSpeechNewParamsResponseFormatPCM: - return true - } - return false -} diff --git a/audiospeech_test.go b/audiospeech_test.go index 4672869..144763c 100644 --- a/audiospeech_test.go +++ b/audiospeech_test.go @@ -27,11 +27,11 @@ func TestAudioSpeechNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) resp, err := client.Audio.Speech.New(context.TODO(), openai.AudioSpeechNewParams{ - Input: openai.F("input"), - Model: openai.F(openai.SpeechModelTTS1), - Voice: openai.F(openai.AudioSpeechNewParamsVoiceAlloy), - ResponseFormat: openai.F(openai.AudioSpeechNewParamsResponseFormatMP3), - Speed: openai.F(0.250000), + Input: openai.String("input"), + Model: openai.SpeechModelTTS1, + Voice: openai.AudioSpeechNewParamsVoiceAlloy, + ResponseFormat: openai.AudioSpeechNewParamsResponseFormatMP3, + Speed: openai.Float(0.25), }) if err != nil { var apierr *openai.Error diff --git a/audiotranscription.go b/audiotranscription.go index 15f5bd6..a7a199b 100644 --- a/audiotranscription.go +++ b/audiotranscription.go @@ -11,9 +11,10 @@ import ( "github.com/openai/openai-go/internal/apiform" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" ) // AudioTranscriptionService contains methods and other services that help with @@ -29,17 +30,22 @@ type AudioTranscriptionService struct { // NewAudioTranscriptionService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewAudioTranscriptionService(opts ...option.RequestOption) (r *AudioTranscriptionService) { - r = &AudioTranscriptionService{} +func NewAudioTranscriptionService(opts ...option.RequestOption) (r AudioTranscriptionService) { + r = AudioTranscriptionService{} r.Options = opts return } // Transcribes audio into the input language. func (r *AudioTranscriptionService) New(ctx context.Context, body AudioTranscriptionNewParams, opts ...option.RequestOption) (res *Transcription, err error) { + var env apijson.UnionUnmarshaler[Transcription] opts = append(r.Options[:], opts...) path := "audio/transcriptions" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &env, opts...) + if err != nil { + return + } + res = &env.Value return } @@ -47,58 +53,56 @@ func (r *AudioTranscriptionService) New(ctx context.Context, body AudioTranscrip // input. type Transcription struct { // The transcribed text. - Text string `json:"text,required"` - JSON transcriptionJSON `json:"-"` + Text string `json:"text,omitzero,required"` + JSON struct { + Text resp.Field + raw string + } `json:"-"` } -// transcriptionJSON contains the JSON metadata for the struct [Transcription] -type transcriptionJSON struct { - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Transcription) UnmarshalJSON(data []byte) (err error) { +func (r Transcription) RawJSON() string { return r.JSON.raw } +func (r *Transcription) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r transcriptionJSON) RawJSON() string { - return r.raw -} - type AudioTranscriptionNewParams struct { // The audio file object (not file name) to transcribe, in one of these formats: // flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm. - File param.Field[io.Reader] `json:"file,required" format:"binary"` + File io.Reader `json:"file,omitzero,required" format:"binary"` // ID of the model to use. Only `whisper-1` (which is powered by our open source // Whisper V2 model) is currently available. - Model param.Field[AudioModel] `json:"model,required"` + Model AudioModel `json:"model,omitzero,required"` // The language of the input audio. Supplying the input language in // [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) // format will improve accuracy and latency. - Language param.Field[string] `json:"language"` + Language param.String `json:"language,omitzero"` // An optional text to guide the model's style or continue a previous audio // segment. The // [prompt](https://platform.openai.com/docs/guides/speech-to-text#prompting) // should match the audio language. - Prompt param.Field[string] `json:"prompt"` + Prompt param.String `json:"prompt,omitzero"` // The format of the output, in one of these options: `json`, `text`, `srt`, // `verbose_json`, or `vtt`. - ResponseFormat param.Field[AudioResponseFormat] `json:"response_format"` + // + // Any of "json", "text", "srt", "verbose_json", "vtt" + ResponseFormat AudioResponseFormat `json:"response_format,omitzero"` // The sampling temperature, between 0 and 1. Higher values like 0.8 will make the // output more random, while lower values like 0.2 will make it more focused and // deterministic. If set to 0, the model will use // [log probability](https://en.wikipedia.org/wiki/Log_probability) to // automatically increase the temperature until certain thresholds are hit. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // The timestamp granularities to populate for this transcription. // `response_format` must be set `verbose_json` to use timestamp granularities. // Either or both of these options are supported: `word`, or `segment`. Note: There // is no additional latency for segment timestamps, but generating word timestamps // incurs additional latency. - TimestampGranularities param.Field[[]AudioTranscriptionNewParamsTimestampGranularity] `json:"timestamp_granularities"` + TimestampGranularities []string `json:"timestamp_granularities,omitzero"` + apiobject } +func (f AudioTranscriptionNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AudioTranscriptionNewParams) MarshalMultipart() (data []byte, contentType string, err error) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) @@ -114,17 +118,9 @@ func (r AudioTranscriptionNewParams) MarshalMultipart() (data []byte, contentTyp return buf.Bytes(), writer.FormDataContentType(), nil } -type AudioTranscriptionNewParamsTimestampGranularity string +type AudioTranscriptionNewParamsTimestampGranularity = string const ( AudioTranscriptionNewParamsTimestampGranularityWord AudioTranscriptionNewParamsTimestampGranularity = "word" AudioTranscriptionNewParamsTimestampGranularitySegment AudioTranscriptionNewParamsTimestampGranularity = "segment" ) - -func (r AudioTranscriptionNewParamsTimestampGranularity) IsKnown() bool { - switch r { - case AudioTranscriptionNewParamsTimestampGranularityWord, AudioTranscriptionNewParamsTimestampGranularitySegment: - return true - } - return false -} diff --git a/audiotranscription_test.go b/audiotranscription_test.go index 3547baa..d1e82c0 100644 --- a/audiotranscription_test.go +++ b/audiotranscription_test.go @@ -28,13 +28,13 @@ func TestAudioTranscriptionNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Audio.Transcriptions.New(context.TODO(), openai.AudioTranscriptionNewParams{ - File: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Model: openai.F(openai.AudioModelWhisper1), - Language: openai.F("language"), - Prompt: openai.F("prompt"), - ResponseFormat: openai.F(openai.AudioResponseFormatJSON), - Temperature: openai.F(0.000000), - TimestampGranularities: openai.F([]openai.AudioTranscriptionNewParamsTimestampGranularity{openai.AudioTranscriptionNewParamsTimestampGranularityWord}), + File: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Model: openai.AudioModelWhisper1, + Language: openai.String("language"), + Prompt: openai.String("prompt"), + ResponseFormat: openai.AudioResponseFormatJSON, + Temperature: openai.Float(0), + TimestampGranularities: []string{"word"}, }) if err != nil { var apierr *openai.Error diff --git a/audiotranslation.go b/audiotranslation.go index 6b423f0..233f584 100644 --- a/audiotranslation.go +++ b/audiotranslation.go @@ -11,9 +11,10 @@ import ( "github.com/openai/openai-go/internal/apiform" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" ) // AudioTranslationService contains methods and other services that help with @@ -29,63 +30,66 @@ type AudioTranslationService struct { // NewAudioTranslationService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewAudioTranslationService(opts ...option.RequestOption) (r *AudioTranslationService) { - r = &AudioTranslationService{} +func NewAudioTranslationService(opts ...option.RequestOption) (r AudioTranslationService) { + r = AudioTranslationService{} r.Options = opts return } // Translates audio into English. func (r *AudioTranslationService) New(ctx context.Context, body AudioTranslationNewParams, opts ...option.RequestOption) (res *Translation, err error) { + var env apijson.UnionUnmarshaler[Translation] opts = append(r.Options[:], opts...) path := "audio/translations" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &env, opts...) + if err != nil { + return + } + res = &env.Value return } type Translation struct { - Text string `json:"text,required"` - JSON translationJSON `json:"-"` + Text string `json:"text,omitzero,required"` + JSON struct { + Text resp.Field + raw string + } `json:"-"` } -// translationJSON contains the JSON metadata for the struct [Translation] -type translationJSON struct { - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Translation) UnmarshalJSON(data []byte) (err error) { +func (r Translation) RawJSON() string { return r.JSON.raw } +func (r *Translation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r translationJSON) RawJSON() string { - return r.raw -} - type AudioTranslationNewParams struct { // The audio file object (not file name) translate, in one of these formats: flac, // mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm. - File param.Field[io.Reader] `json:"file,required" format:"binary"` + File io.Reader `json:"file,omitzero,required" format:"binary"` // ID of the model to use. Only `whisper-1` (which is powered by our open source // Whisper V2 model) is currently available. - Model param.Field[AudioModel] `json:"model,required"` + Model AudioModel `json:"model,omitzero,required"` // An optional text to guide the model's style or continue a previous audio // segment. The // [prompt](https://platform.openai.com/docs/guides/speech-to-text#prompting) // should be in English. - Prompt param.Field[string] `json:"prompt"` + Prompt param.String `json:"prompt,omitzero"` // The format of the output, in one of these options: `json`, `text`, `srt`, // `verbose_json`, or `vtt`. - ResponseFormat param.Field[AudioResponseFormat] `json:"response_format"` + // + // Any of "json", "text", "srt", "verbose_json", "vtt" + ResponseFormat AudioResponseFormat `json:"response_format,omitzero"` // The sampling temperature, between 0 and 1. Higher values like 0.8 will make the // output more random, while lower values like 0.2 will make it more focused and // deterministic. If set to 0, the model will use // [log probability](https://en.wikipedia.org/wiki/Log_probability) to // automatically increase the temperature until certain thresholds are hit. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` + apiobject } +func (f AudioTranslationNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AudioTranslationNewParams) MarshalMultipart() (data []byte, contentType string, err error) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) diff --git a/audiotranslation_test.go b/audiotranslation_test.go index ae27737..70ebf19 100644 --- a/audiotranslation_test.go +++ b/audiotranslation_test.go @@ -28,11 +28,11 @@ func TestAudioTranslationNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Audio.Translations.New(context.TODO(), openai.AudioTranslationNewParams{ - File: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Model: openai.F(openai.AudioModelWhisper1), - Prompt: openai.F("prompt"), - ResponseFormat: openai.F(openai.AudioResponseFormatJSON), - Temperature: openai.F(0.000000), + File: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Model: openai.AudioModelWhisper1, + Prompt: openai.String("prompt"), + ResponseFormat: openai.AudioResponseFormatJSON, + Temperature: openai.Float(0), }) if err != nil { var apierr *openai.Error diff --git a/batch.go b/batch.go index 1930340..a2cbbc9 100644 --- a/batch.go +++ b/batch.go @@ -11,11 +11,13 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" + "github.com/openai/openai-go/shared/constant" ) // BatchService contains methods and other services that help with interacting with @@ -31,8 +33,8 @@ type BatchService struct { // NewBatchService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewBatchService(opts ...option.RequestOption) (r *BatchService) { - r = &BatchService{} +func NewBatchService(opts ...option.RequestOption) (r BatchService) { + r = BatchService{} r.Options = opts return } @@ -95,103 +97,86 @@ func (r *BatchService) Cancel(ctx context.Context, batchID string, opts ...optio } type Batch struct { - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The time frame within which the batch should be processed. - CompletionWindow string `json:"completion_window,required"` + CompletionWindow string `json:"completion_window,omitzero,required"` // The Unix timestamp (in seconds) for when the batch was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The OpenAI API endpoint used by the batch. - Endpoint string `json:"endpoint,required"` + Endpoint string `json:"endpoint,omitzero,required"` // The ID of the input file for the batch. - InputFileID string `json:"input_file_id,required"` + InputFileID string `json:"input_file_id,omitzero,required"` // The object type, which is always `batch`. - Object BatchObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "batch". + Object constant.Batch `json:"object,required"` // The current status of the batch. - Status BatchStatus `json:"status,required"` + // + // Any of "validating", "failed", "in_progress", "finalizing", "completed", + // "expired", "cancelling", "cancelled" + Status string `json:"status,omitzero,required"` // The Unix timestamp (in seconds) for when the batch was cancelled. - CancelledAt int64 `json:"cancelled_at"` + CancelledAt int64 `json:"cancelled_at,omitzero"` // The Unix timestamp (in seconds) for when the batch started cancelling. - CancellingAt int64 `json:"cancelling_at"` + CancellingAt int64 `json:"cancelling_at,omitzero"` // The Unix timestamp (in seconds) for when the batch was completed. - CompletedAt int64 `json:"completed_at"` + CompletedAt int64 `json:"completed_at,omitzero"` // The ID of the file containing the outputs of requests with errors. - ErrorFileID string `json:"error_file_id"` - Errors BatchErrors `json:"errors"` + ErrorFileID string `json:"error_file_id,omitzero"` + Errors BatchErrors `json:"errors,omitzero"` // The Unix timestamp (in seconds) for when the batch expired. - ExpiredAt int64 `json:"expired_at"` + ExpiredAt int64 `json:"expired_at,omitzero"` // The Unix timestamp (in seconds) for when the batch will expire. - ExpiresAt int64 `json:"expires_at"` + ExpiresAt int64 `json:"expires_at,omitzero"` // The Unix timestamp (in seconds) for when the batch failed. - FailedAt int64 `json:"failed_at"` + FailedAt int64 `json:"failed_at,omitzero"` // The Unix timestamp (in seconds) for when the batch started finalizing. - FinalizingAt int64 `json:"finalizing_at"` + FinalizingAt int64 `json:"finalizing_at,omitzero"` // The Unix timestamp (in seconds) for when the batch started processing. - InProgressAt int64 `json:"in_progress_at"` + InProgressAt int64 `json:"in_progress_at,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,nullable"` // The ID of the file containing the outputs of successfully executed requests. - OutputFileID string `json:"output_file_id"` + OutputFileID string `json:"output_file_id,omitzero"` // The request counts for different statuses within the batch. - RequestCounts BatchRequestCounts `json:"request_counts"` - JSON batchJSON `json:"-"` + RequestCounts BatchRequestCounts `json:"request_counts,omitzero"` + JSON struct { + ID resp.Field + CompletionWindow resp.Field + CreatedAt resp.Field + Endpoint resp.Field + InputFileID resp.Field + Object resp.Field + Status resp.Field + CancelledAt resp.Field + CancellingAt resp.Field + CompletedAt resp.Field + ErrorFileID resp.Field + Errors resp.Field + ExpiredAt resp.Field + ExpiresAt resp.Field + FailedAt resp.Field + FinalizingAt resp.Field + InProgressAt resp.Field + Metadata resp.Field + OutputFileID resp.Field + RequestCounts resp.Field + raw string + } `json:"-"` } -// batchJSON contains the JSON metadata for the struct [Batch] -type batchJSON struct { - ID apijson.Field - CompletionWindow apijson.Field - CreatedAt apijson.Field - Endpoint apijson.Field - InputFileID apijson.Field - Object apijson.Field - Status apijson.Field - CancelledAt apijson.Field - CancellingAt apijson.Field - CompletedAt apijson.Field - ErrorFileID apijson.Field - Errors apijson.Field - ExpiredAt apijson.Field - ExpiresAt apijson.Field - FailedAt apijson.Field - FinalizingAt apijson.Field - InProgressAt apijson.Field - Metadata apijson.Field - OutputFileID apijson.Field - RequestCounts apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Batch) UnmarshalJSON(data []byte) (err error) { +func (r Batch) RawJSON() string { return r.JSON.raw } +func (r *Batch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r batchJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `batch`. -type BatchObject string - -const ( - BatchObjectBatch BatchObject = "batch" -) - -func (r BatchObject) IsKnown() bool { - switch r { - case BatchObjectBatch: - return true - } - return false -} - // The current status of the batch. -type BatchStatus string +type BatchStatus = string const ( BatchStatusValidating BatchStatus = "validating" @@ -204,105 +189,79 @@ const ( BatchStatusCancelled BatchStatus = "cancelled" ) -func (r BatchStatus) IsKnown() bool { - switch r { - case BatchStatusValidating, BatchStatusFailed, BatchStatusInProgress, BatchStatusFinalizing, BatchStatusCompleted, BatchStatusExpired, BatchStatusCancelling, BatchStatusCancelled: - return true - } - return false -} - type BatchErrors struct { - Data []BatchError `json:"data"` + Data []BatchError `json:"data,omitzero"` // The object type, which is always `list`. - Object string `json:"object"` - JSON batchErrorsJSON `json:"-"` + Object string `json:"object,omitzero"` + JSON struct { + Data resp.Field + Object resp.Field + raw string + } `json:"-"` } -// batchErrorsJSON contains the JSON metadata for the struct [BatchErrors] -type batchErrorsJSON struct { - Data apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *BatchErrors) UnmarshalJSON(data []byte) (err error) { +func (r BatchErrors) RawJSON() string { return r.JSON.raw } +func (r *BatchErrors) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r batchErrorsJSON) RawJSON() string { - return r.raw -} - type BatchError struct { // An error code identifying the error type. - Code string `json:"code"` + Code string `json:"code,omitzero"` // The line number of the input file where the error occurred, if applicable. - Line int64 `json:"line,nullable"` + Line int64 `json:"line,omitzero,nullable"` // A human-readable message providing more details about the error. - Message string `json:"message"` + Message string `json:"message,omitzero"` // The name of the parameter that caused the error, if applicable. - Param string `json:"param,nullable"` - JSON batchErrorJSON `json:"-"` + Param string `json:"param,omitzero,nullable"` + JSON struct { + Code resp.Field + Line resp.Field + Message resp.Field + Param resp.Field + raw string + } `json:"-"` } -// batchErrorJSON contains the JSON metadata for the struct [BatchError] -type batchErrorJSON struct { - Code apijson.Field - Line apijson.Field - Message apijson.Field - Param apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *BatchError) UnmarshalJSON(data []byte) (err error) { +func (r BatchError) RawJSON() string { return r.JSON.raw } +func (r *BatchError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r batchErrorJSON) RawJSON() string { - return r.raw -} - // The request counts for different statuses within the batch. type BatchRequestCounts struct { // Number of requests that have been completed successfully. - Completed int64 `json:"completed,required"` + Completed int64 `json:"completed,omitzero,required"` // Number of requests that have failed. - Failed int64 `json:"failed,required"` + Failed int64 `json:"failed,omitzero,required"` // Total number of requests in the batch. - Total int64 `json:"total,required"` - JSON batchRequestCountsJSON `json:"-"` + Total int64 `json:"total,omitzero,required"` + JSON struct { + Completed resp.Field + Failed resp.Field + Total resp.Field + raw string + } `json:"-"` } -// batchRequestCountsJSON contains the JSON metadata for the struct -// [BatchRequestCounts] -type batchRequestCountsJSON struct { - Completed apijson.Field - Failed apijson.Field - Total apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *BatchRequestCounts) UnmarshalJSON(data []byte) (err error) { +func (r BatchRequestCounts) RawJSON() string { return r.JSON.raw } +func (r *BatchRequestCounts) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r batchRequestCountsJSON) RawJSON() string { - return r.raw -} - type BatchNewParams struct { // The time frame within which the batch should be processed. Currently only `24h` // is supported. - CompletionWindow param.Field[BatchNewParamsCompletionWindow] `json:"completion_window,required"` + // + // Any of "24h" + CompletionWindow BatchNewParamsCompletionWindow `json:"completion_window,required"` // The endpoint to be used for all requests in the batch. Currently // `/v1/chat/completions`, `/v1/embeddings`, and `/v1/completions` are supported. // Note that `/v1/embeddings` batches are also restricted to a maximum of 50,000 // embedding inputs across all requests in the batch. - Endpoint param.Field[BatchNewParamsEndpoint] `json:"endpoint,required"` + // + // Any of "/v1/chat/completions", "/v1/embeddings", "/v1/completions" + Endpoint BatchNewParamsEndpoint `json:"endpoint,omitzero,required"` // The ID of an uploaded file that contains requests for the new batch. // // See [upload file](https://platform.openai.com/docs/api-reference/files/create) @@ -312,18 +271,22 @@ type BatchNewParams struct { // [JSONL file](https://platform.openai.com/docs/api-reference/batch/request-input), // and must be uploaded with the purpose `batch`. The file can contain up to 50,000 // requests, and can be up to 200 MB in size. - InputFileID param.Field[string] `json:"input_file_id,required"` + InputFileID param.String `json:"input_file_id,omitzero,required"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject } +func (f BatchNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BatchNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BatchNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // The time frame within which the batch should be processed. Currently only `24h` @@ -334,14 +297,6 @@ const ( BatchNewParamsCompletionWindow24h BatchNewParamsCompletionWindow = "24h" ) -func (r BatchNewParamsCompletionWindow) IsKnown() bool { - switch r { - case BatchNewParamsCompletionWindow24h: - return true - } - return false -} - // The endpoint to be used for all requests in the batch. Currently // `/v1/chat/completions`, `/v1/embeddings`, and `/v1/completions` are supported. // Note that `/v1/embeddings` batches are also restricted to a maximum of 50,000 @@ -354,25 +309,20 @@ const ( BatchNewParamsEndpointV1Completions BatchNewParamsEndpoint = "/v1/completions" ) -func (r BatchNewParamsEndpoint) IsKnown() bool { - switch r { - case BatchNewParamsEndpointV1ChatCompletions, BatchNewParamsEndpointV1Embeddings, BatchNewParamsEndpointV1Completions: - return true - } - return false -} - type BatchListParams struct { // A cursor for use in pagination. `after` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` + apiobject } +func (f BatchListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BatchListParams]'s query parameters as `url.Values`. func (r BatchListParams) URLQuery() (v url.Values) { return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ diff --git a/batch_test.go b/batch_test.go index 6b8ecd4..af77ac6 100644 --- a/batch_test.go +++ b/batch_test.go @@ -27,12 +27,12 @@ func TestBatchNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Batches.New(context.TODO(), openai.BatchNewParams{ - CompletionWindow: openai.F(openai.BatchNewParamsCompletionWindow24h), - Endpoint: openai.F(openai.BatchNewParamsEndpointV1ChatCompletions), - InputFileID: openai.F("input_file_id"), - Metadata: openai.F(shared.MetadataParam{ + CompletionWindow: openai.BatchNewParamsCompletionWindow24h, + Endpoint: openai.BatchNewParamsEndpointV1ChatCompletions, + InputFileID: openai.String("input_file_id"), + Metadata: shared.MetadataParam{ "foo": "string", - }), + }, }) if err != nil { var apierr *openai.Error @@ -78,8 +78,8 @@ func TestBatchListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Batches.List(context.TODO(), openai.BatchListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), + After: openai.String("after"), + Limit: openai.Int(0), }) if err != nil { var apierr *openai.Error diff --git a/beta.go b/beta.go index b5c4db0..65e2b43 100644 --- a/beta.go +++ b/beta.go @@ -14,16 +14,16 @@ import ( // the [NewBetaService] method instead. type BetaService struct { Options []option.RequestOption - VectorStores *BetaVectorStoreService - Assistants *BetaAssistantService - Threads *BetaThreadService + VectorStores BetaVectorStoreService + Assistants BetaAssistantService + Threads BetaThreadService } // NewBetaService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewBetaService(opts ...option.RequestOption) (r *BetaService) { - r = &BetaService{} +func NewBetaService(opts ...option.RequestOption) (r BetaService) { + r = BetaService{} r.Options = opts r.VectorStores = NewBetaVectorStoreService(opts...) r.Assistants = NewBetaAssistantService(opts...) diff --git a/betaassistant.go b/betaassistant.go index e5f42d7..b23c453 100644 --- a/betaassistant.go +++ b/betaassistant.go @@ -4,20 +4,21 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" "net/url" - "reflect" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/shared/constant" ) // BetaAssistantService contains methods and other services that help with @@ -33,8 +34,8 @@ type BetaAssistantService struct { // NewBetaAssistantService generates a new service that applies the given options // to each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewBetaAssistantService(opts ...option.RequestOption) (r *BetaAssistantService) { - r = &BetaAssistantService{} +func NewBetaAssistantService(opts ...option.RequestOption) (r BetaAssistantService) { + r = BetaAssistantService{} r.Options = opts return } @@ -113,465 +114,523 @@ func (r *BetaAssistantService) Delete(ctx context.Context, assistantID string, o // Represents an `assistant` that can call the model and use tools. type Assistant struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the assistant was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The description of the assistant. The maximum length is 512 characters. - Description string `json:"description,required,nullable"` + Description string `json:"description,omitzero,required,nullable"` // The system instructions that the assistant uses. The maximum length is 256,000 // characters. - Instructions string `json:"instructions,required,nullable"` + Instructions string `json:"instructions,omitzero,required,nullable"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // ID of the model to use. You can use the // [List models](https://platform.openai.com/docs/api-reference/models/list) API to // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The name of the assistant. The maximum length is 256 characters. - Name string `json:"name,required,nullable"` + Name string `json:"name,omitzero,required,nullable"` // The object type, which is always `assistant`. - Object AssistantObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "assistant". + Object constant.Assistant `json:"object,required"` // A list of tool enabled on the assistant. There can be a maximum of 128 tools per // assistant. Tools can be of types `code_interpreter`, `file_search`, or // `function`. - Tools []AssistantTool `json:"tools,required"` + Tools []AssistantToolUnion `json:"tools,omitzero,required"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. - Temperature float64 `json:"temperature,nullable"` + Temperature float64 `json:"temperature,omitzero,nullable"` // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. - ToolResources AssistantToolResources `json:"tool_resources,nullable"` + ToolResources AssistantToolResources `json:"tool_resources,omitzero,nullable"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or temperature but not both. - TopP float64 `json:"top_p,nullable"` - JSON assistantJSON `json:"-"` + TopP float64 `json:"top_p,omitzero,nullable"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + Description resp.Field + Instructions resp.Field + Metadata resp.Field + Model resp.Field + Name resp.Field + Object resp.Field + Tools resp.Field + Temperature resp.Field + ToolResources resp.Field + TopP resp.Field + raw string + } `json:"-"` } -// assistantJSON contains the JSON metadata for the struct [Assistant] -type assistantJSON struct { - ID apijson.Field - CreatedAt apijson.Field - Description apijson.Field - Instructions apijson.Field - Metadata apijson.Field - Model apijson.Field - Name apijson.Field - Object apijson.Field - Tools apijson.Field - Temperature apijson.Field - ToolResources apijson.Field - TopP apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Assistant) UnmarshalJSON(data []byte) (err error) { +func (r Assistant) RawJSON() string { return r.JSON.raw } +func (r *Assistant) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `assistant`. -type AssistantObject string - -const ( - AssistantObjectAssistant AssistantObject = "assistant" -) - -func (r AssistantObject) IsKnown() bool { - switch r { - case AssistantObjectAssistant: - return true - } - return false -} - // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. type AssistantToolResources struct { - CodeInterpreter AssistantToolResourcesCodeInterpreter `json:"code_interpreter"` - FileSearch AssistantToolResourcesFileSearch `json:"file_search"` - JSON assistantToolResourcesJSON `json:"-"` + CodeInterpreter AssistantToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch AssistantToolResourcesFileSearch `json:"file_search,omitzero"` + JSON struct { + CodeInterpreter resp.Field + FileSearch resp.Field + raw string + } `json:"-"` } -// assistantToolResourcesJSON contains the JSON metadata for the struct -// [AssistantToolResources] -type assistantToolResourcesJSON struct { - CodeInterpreter apijson.Field - FileSearch apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantToolResources) UnmarshalJSON(data []byte) (err error) { +func (r AssistantToolResources) RawJSON() string { return r.JSON.raw } +func (r *AssistantToolResources) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantToolResourcesJSON) RawJSON() string { - return r.raw -} - type AssistantToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter“ tool. There can be a maximum of 20 files // associated with the tool. - FileIDs []string `json:"file_ids"` - JSON assistantToolResourcesCodeInterpreterJSON `json:"-"` + FileIDs []string `json:"file_ids,omitzero"` + JSON struct { + FileIDs resp.Field + raw string + } `json:"-"` } -// assistantToolResourcesCodeInterpreterJSON contains the JSON metadata for the -// struct [AssistantToolResourcesCodeInterpreter] -type assistantToolResourcesCodeInterpreterJSON struct { - FileIDs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantToolResourcesCodeInterpreter) UnmarshalJSON(data []byte) (err error) { +func (r AssistantToolResourcesCodeInterpreter) RawJSON() string { return r.JSON.raw } +func (r *AssistantToolResourcesCodeInterpreter) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantToolResourcesCodeInterpreterJSON) RawJSON() string { - return r.raw -} - type AssistantToolResourcesFileSearch struct { // The ID of the // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this assistant. There can be a maximum of 1 vector store attached to // the assistant. - VectorStoreIDs []string `json:"vector_store_ids"` - JSON assistantToolResourcesFileSearchJSON `json:"-"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` + JSON struct { + VectorStoreIDs resp.Field + raw string + } `json:"-"` } -// assistantToolResourcesFileSearchJSON contains the JSON metadata for the struct -// [AssistantToolResourcesFileSearch] -type assistantToolResourcesFileSearchJSON struct { - VectorStoreIDs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantToolResourcesFileSearch) UnmarshalJSON(data []byte) (err error) { +func (r AssistantToolResourcesFileSearch) RawJSON() string { return r.JSON.raw } +func (r *AssistantToolResourcesFileSearch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantToolResourcesFileSearchJSON) RawJSON() string { - return r.raw -} - type AssistantDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object AssistantDeletedObject `json:"object,required"` - JSON assistantDeletedJSON `json:"-"` + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as "assistant.deleted". + Object constant.AssistantDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// assistantDeletedJSON contains the JSON metadata for the struct -// [AssistantDeleted] -type assistantDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantDeleted) UnmarshalJSON(data []byte) (err error) { +func (r AssistantDeleted) RawJSON() string { return r.JSON.raw } +func (r *AssistantDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantDeletedJSON) RawJSON() string { - return r.raw +type AssistantStreamEventUnion struct { + // This field is a union of + // [Thread,Run,RunStep,RunStepDeltaEvent,Message,MessageDeltaEvent,shared.ErrorObject] + Data AssistantStreamEventUnionData `json:"data"` + Event string `json:"event"` + Enabled bool `json:"enabled"` + JSON struct { + Data resp.Field + Event resp.Field + Enabled resp.Field + raw string + } `json:"-"` } -type AssistantDeletedObject string - -const ( - AssistantDeletedObjectAssistantDeleted AssistantDeletedObject = "assistant.deleted" -) - -func (r AssistantDeletedObject) IsKnown() bool { - switch r { - case AssistantDeletedObjectAssistantDeleted: - return true +// note: this function is generated only for discriminated unions +func (u AssistantStreamEventUnion) Variant() (res struct { + OfThreadCreated *AssistantStreamEventThreadCreated + OfThreadRunCreated *AssistantStreamEventThreadRunCreated + OfThreadRunQueued *AssistantStreamEventThreadRunQueued + OfThreadRunInProgress *AssistantStreamEventThreadRunInProgress + OfThreadRunRequiresAction *AssistantStreamEventThreadRunRequiresAction + OfThreadRunCompleted *AssistantStreamEventThreadRunCompleted + OfThreadRunIncomplete *AssistantStreamEventThreadRunIncomplete + OfThreadRunFailed *AssistantStreamEventThreadRunFailed + OfThreadRunCancelling *AssistantStreamEventThreadRunCancelling + OfThreadRunCancelled *AssistantStreamEventThreadRunCancelled + OfThreadRunExpired *AssistantStreamEventThreadRunExpired + OfThreadRunStepCreated *AssistantStreamEventThreadRunStepCreated + OfThreadRunStepInProgress *AssistantStreamEventThreadRunStepInProgress + OfThreadRunStepDelta *AssistantStreamEventThreadRunStepDelta + OfThreadRunStepCompleted *AssistantStreamEventThreadRunStepCompleted + OfThreadRunStepFailed *AssistantStreamEventThreadRunStepFailed + OfThreadRunStepCancelled *AssistantStreamEventThreadRunStepCancelled + OfThreadRunStepExpired *AssistantStreamEventThreadRunStepExpired + OfThreadMessageCreated *AssistantStreamEventThreadMessageCreated + OfThreadMessageInProgress *AssistantStreamEventThreadMessageInProgress + OfThreadMessageDelta *AssistantStreamEventThreadMessageDelta + OfThreadMessageCompleted *AssistantStreamEventThreadMessageCompleted + OfThreadMessageIncomplete *AssistantStreamEventThreadMessageIncomplete + OfErrorEvent *AssistantStreamEventErrorEvent +}) { + switch u.Event { + case "thread.created": + v := u.AsThreadCreated() + res.OfThreadCreated = &v + case "thread.run.created": + v := u.AsThreadRunCreated() + res.OfThreadRunCreated = &v + case "thread.run.queued": + v := u.AsThreadRunQueued() + res.OfThreadRunQueued = &v + case "thread.run.in_progress": + v := u.AsThreadRunInProgress() + res.OfThreadRunInProgress = &v + case "thread.run.requires_action": + v := u.AsThreadRunRequiresAction() + res.OfThreadRunRequiresAction = &v + case "thread.run.completed": + v := u.AsThreadRunCompleted() + res.OfThreadRunCompleted = &v + case "thread.run.incomplete": + v := u.AsThreadRunIncomplete() + res.OfThreadRunIncomplete = &v + case "thread.run.failed": + v := u.AsThreadRunFailed() + res.OfThreadRunFailed = &v + case "thread.run.cancelling": + v := u.AsThreadRunCancelling() + res.OfThreadRunCancelling = &v + case "thread.run.cancelled": + v := u.AsThreadRunCancelled() + res.OfThreadRunCancelled = &v + case "thread.run.expired": + v := u.AsThreadRunExpired() + res.OfThreadRunExpired = &v + case "thread.run.step.created": + v := u.AsThreadRunStepCreated() + res.OfThreadRunStepCreated = &v + case "thread.run.step.in_progress": + v := u.AsThreadRunStepInProgress() + res.OfThreadRunStepInProgress = &v + case "thread.run.step.delta": + v := u.AsThreadRunStepDelta() + res.OfThreadRunStepDelta = &v + case "thread.run.step.completed": + v := u.AsThreadRunStepCompleted() + res.OfThreadRunStepCompleted = &v + case "thread.run.step.failed": + v := u.AsThreadRunStepFailed() + res.OfThreadRunStepFailed = &v + case "thread.run.step.cancelled": + v := u.AsThreadRunStepCancelled() + res.OfThreadRunStepCancelled = &v + case "thread.run.step.expired": + v := u.AsThreadRunStepExpired() + res.OfThreadRunStepExpired = &v + case "thread.message.created": + v := u.AsThreadMessageCreated() + res.OfThreadMessageCreated = &v + case "thread.message.in_progress": + v := u.AsThreadMessageInProgress() + res.OfThreadMessageInProgress = &v + case "thread.message.delta": + v := u.AsThreadMessageDelta() + res.OfThreadMessageDelta = &v + case "thread.message.completed": + v := u.AsThreadMessageCompleted() + res.OfThreadMessageCompleted = &v + case "thread.message.incomplete": + v := u.AsThreadMessageIncomplete() + res.OfThreadMessageIncomplete = &v + case "error": + v := u.AsErrorEvent() + res.OfErrorEvent = &v } - return false + return } -// Represents an event emitted when streaming a Run. -// -// Each event in a server-sent events stream has an `event` and `data` property: -// -// ``` -// event: thread.created -// data: {"id": "thread_123", "object": "thread", ...} -// ``` -// -// We emit events whenever a new object is created, transitions to a new state, or -// is being streamed in parts (deltas). For example, we emit `thread.run.created` -// when a new run is created, `thread.run.completed` when a run completes, and so -// on. When an Assistant chooses to create a message during a run, we emit a -// `thread.message.created event`, a `thread.message.in_progress` event, many -// `thread.message.delta` events, and finally a `thread.message.completed` event. -// -// We may add additional events over time, so we recommend handling unknown events -// gracefully in your code. See the -// [Assistants API quickstart](https://platform.openai.com/docs/assistants/overview) -// to learn how to integrate the Assistants API with streaming. -type AssistantStreamEvent struct { - // This field can have the runtime type of [Thread], [Run], [RunStep], - // [RunStepDeltaEvent], [Message], [MessageDeltaEvent], [shared.ErrorObject]. - Data interface{} `json:"data,required"` - Event AssistantStreamEventEvent `json:"event,required"` - // Whether to enable input audio transcription. - Enabled bool `json:"enabled"` - JSON assistantStreamEventJSON `json:"-"` - union AssistantStreamEventUnion +func (u AssistantStreamEventUnion) WhichKind() string { + return u.Event } -// assistantStreamEventJSON contains the JSON metadata for the struct -// [AssistantStreamEvent] -type assistantStreamEventJSON struct { - Data apijson.Field - Event apijson.Field - Enabled apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u AssistantStreamEventUnion) AsThreadCreated() (v AssistantStreamEventThreadCreated) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r assistantStreamEventJSON) RawJSON() string { - return r.raw +func (u AssistantStreamEventUnion) AsThreadRunCreated() (v AssistantStreamEventThreadRunCreated) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *AssistantStreamEvent) UnmarshalJSON(data []byte) (err error) { - *r = AssistantStreamEvent{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) +func (u AssistantStreamEventUnion) AsThreadRunQueued() (v AssistantStreamEventThreadRunQueued) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// AsUnion returns a [AssistantStreamEventUnion] interface which you can cast to -// the specific types for more type safety. -// -// Possible runtime types of the union are [AssistantStreamEventThreadCreated], -// [AssistantStreamEventThreadRunCreated], [AssistantStreamEventThreadRunQueued], -// [AssistantStreamEventThreadRunInProgress], -// [AssistantStreamEventThreadRunRequiresAction], -// [AssistantStreamEventThreadRunCompleted], -// [AssistantStreamEventThreadRunIncomplete], -// [AssistantStreamEventThreadRunFailed], -// [AssistantStreamEventThreadRunCancelling], -// [AssistantStreamEventThreadRunCancelled], -// [AssistantStreamEventThreadRunExpired], -// [AssistantStreamEventThreadRunStepCreated], -// [AssistantStreamEventThreadRunStepInProgress], -// [AssistantStreamEventThreadRunStepDelta], -// [AssistantStreamEventThreadRunStepCompleted], -// [AssistantStreamEventThreadRunStepFailed], -// [AssistantStreamEventThreadRunStepCancelled], -// [AssistantStreamEventThreadRunStepExpired], -// [AssistantStreamEventThreadMessageCreated], -// [AssistantStreamEventThreadMessageInProgress], -// [AssistantStreamEventThreadMessageDelta], -// [AssistantStreamEventThreadMessageCompleted], -// [AssistantStreamEventThreadMessageIncomplete], [AssistantStreamEventErrorEvent]. -func (r AssistantStreamEvent) AsUnion() AssistantStreamEventUnion { - return r.union +func (u AssistantStreamEventUnion) AsThreadRunInProgress() (v AssistantStreamEventThreadRunInProgress) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Represents an event emitted when streaming a Run. -// -// Each event in a server-sent events stream has an `event` and `data` property: -// -// ``` -// event: thread.created -// data: {"id": "thread_123", "object": "thread", ...} -// ``` -// -// We emit events whenever a new object is created, transitions to a new state, or -// is being streamed in parts (deltas). For example, we emit `thread.run.created` -// when a new run is created, `thread.run.completed` when a run completes, and so -// on. When an Assistant chooses to create a message during a run, we emit a -// `thread.message.created event`, a `thread.message.in_progress` event, many -// `thread.message.delta` events, and finally a `thread.message.completed` event. -// -// We may add additional events over time, so we recommend handling unknown events -// gracefully in your code. See the -// [Assistants API quickstart](https://platform.openai.com/docs/assistants/overview) -// to learn how to integrate the Assistants API with streaming. -// -// Union satisfied by [AssistantStreamEventThreadCreated], -// [AssistantStreamEventThreadRunCreated], [AssistantStreamEventThreadRunQueued], -// [AssistantStreamEventThreadRunInProgress], -// [AssistantStreamEventThreadRunRequiresAction], -// [AssistantStreamEventThreadRunCompleted], -// [AssistantStreamEventThreadRunIncomplete], -// [AssistantStreamEventThreadRunFailed], -// [AssistantStreamEventThreadRunCancelling], -// [AssistantStreamEventThreadRunCancelled], -// [AssistantStreamEventThreadRunExpired], -// [AssistantStreamEventThreadRunStepCreated], -// [AssistantStreamEventThreadRunStepInProgress], -// [AssistantStreamEventThreadRunStepDelta], -// [AssistantStreamEventThreadRunStepCompleted], -// [AssistantStreamEventThreadRunStepFailed], -// [AssistantStreamEventThreadRunStepCancelled], -// [AssistantStreamEventThreadRunStepExpired], -// [AssistantStreamEventThreadMessageCreated], -// [AssistantStreamEventThreadMessageInProgress], -// [AssistantStreamEventThreadMessageDelta], -// [AssistantStreamEventThreadMessageCompleted], -// [AssistantStreamEventThreadMessageIncomplete] or -// [AssistantStreamEventErrorEvent]. -type AssistantStreamEventUnion interface { - implementsAssistantStreamEvent() +func (u AssistantStreamEventUnion) AsThreadRunRequiresAction() (v AssistantStreamEventThreadRunRequiresAction) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*AssistantStreamEventUnion)(nil)).Elem(), - "event", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadCreated{}), - DiscriminatorValue: "thread.created", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunCreated{}), - DiscriminatorValue: "thread.run.created", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunQueued{}), - DiscriminatorValue: "thread.run.queued", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunInProgress{}), - DiscriminatorValue: "thread.run.in_progress", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunRequiresAction{}), - DiscriminatorValue: "thread.run.requires_action", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunCompleted{}), - DiscriminatorValue: "thread.run.completed", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunIncomplete{}), - DiscriminatorValue: "thread.run.incomplete", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunFailed{}), - DiscriminatorValue: "thread.run.failed", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunCancelling{}), - DiscriminatorValue: "thread.run.cancelling", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunCancelled{}), - DiscriminatorValue: "thread.run.cancelled", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunExpired{}), - DiscriminatorValue: "thread.run.expired", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepCreated{}), - DiscriminatorValue: "thread.run.step.created", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepInProgress{}), - DiscriminatorValue: "thread.run.step.in_progress", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepDelta{}), - DiscriminatorValue: "thread.run.step.delta", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepCompleted{}), - DiscriminatorValue: "thread.run.step.completed", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepFailed{}), - DiscriminatorValue: "thread.run.step.failed", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepCancelled{}), - DiscriminatorValue: "thread.run.step.cancelled", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadRunStepExpired{}), - DiscriminatorValue: "thread.run.step.expired", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadMessageCreated{}), - DiscriminatorValue: "thread.message.created", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadMessageInProgress{}), - DiscriminatorValue: "thread.message.in_progress", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadMessageDelta{}), - DiscriminatorValue: "thread.message.delta", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadMessageCompleted{}), - DiscriminatorValue: "thread.message.completed", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventThreadMessageIncomplete{}), - DiscriminatorValue: "thread.message.incomplete", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantStreamEventErrorEvent{}), - DiscriminatorValue: "error", - }, - ) +func (u AssistantStreamEventUnion) AsThreadRunCompleted() (v AssistantStreamEventThreadRunCompleted) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunIncomplete() (v AssistantStreamEventThreadRunIncomplete) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunFailed() (v AssistantStreamEventThreadRunFailed) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunCancelling() (v AssistantStreamEventThreadRunCancelling) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunCancelled() (v AssistantStreamEventThreadRunCancelled) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunExpired() (v AssistantStreamEventThreadRunExpired) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepCreated() (v AssistantStreamEventThreadRunStepCreated) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepInProgress() (v AssistantStreamEventThreadRunStepInProgress) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepDelta() (v AssistantStreamEventThreadRunStepDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepCompleted() (v AssistantStreamEventThreadRunStepCompleted) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepFailed() (v AssistantStreamEventThreadRunStepFailed) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepCancelled() (v AssistantStreamEventThreadRunStepCancelled) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadRunStepExpired() (v AssistantStreamEventThreadRunStepExpired) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadMessageCreated() (v AssistantStreamEventThreadMessageCreated) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadMessageInProgress() (v AssistantStreamEventThreadMessageInProgress) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadMessageDelta() (v AssistantStreamEventThreadMessageDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadMessageCompleted() (v AssistantStreamEventThreadMessageCompleted) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsThreadMessageIncomplete() (v AssistantStreamEventThreadMessageIncomplete) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) AsErrorEvent() (v AssistantStreamEventErrorEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantStreamEventUnion) RawJSON() string { return u.JSON.raw } + +func (r *AssistantStreamEventUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type AssistantStreamEventUnionData struct { + ID string `json:"id"` + CreatedAt int64 `json:"created_at"` + Metadata shared.Metadata `json:"metadata"` + Object string `json:"object"` + ToolResources ThreadToolResources `json:"tool_resources"` + AssistantID string `json:"assistant_id"` + CancelledAt int64 `json:"cancelled_at"` + CompletedAt int64 `json:"completed_at"` + ExpiresAt int64 `json:"expires_at"` + FailedAt int64 `json:"failed_at"` + // This field is a union of [RunIncompleteDetails,MessageIncompleteDetails] + IncompleteDetails AssistantStreamEventUnionDataIncompleteDetails `json:"incomplete_details"` + Instructions string `json:"instructions"` + // This field is a union of [RunLastError,RunStepLastError] + LastError AssistantStreamEventUnionDataLastError `json:"last_error"` + MaxCompletionTokens int64 `json:"max_completion_tokens"` + MaxPromptTokens int64 `json:"max_prompt_tokens"` + Model string `json:"model"` + ParallelToolCalls bool `json:"parallel_tool_calls"` + RequiredAction RunRequiredAction `json:"required_action"` + StartedAt int64 `json:"started_at"` + Status string `json:"status"` + ThreadID string `json:"thread_id"` + ToolChoice AssistantToolChoiceOptionUnion `json:"tool_choice"` + Tools []AssistantToolUnion `json:"tools"` + TruncationStrategy RunTruncationStrategy `json:"truncation_strategy"` + Usage RunUsage `json:"usage"` + Temperature float64 `json:"temperature"` + TopP float64 `json:"top_p"` + ExpiredAt int64 `json:"expired_at"` + RunID string `json:"run_id"` + StepDetails RunStepStepDetailsUnion `json:"step_details"` + Type string `json:"type"` + // This field is a union of [RunStepDelta,MessageDelta] + Delta AssistantStreamEventUnionDataDelta `json:"delta"` + Attachments []MessageAttachment `json:"attachments"` + Content []MessageContentUnion `json:"content"` + IncompleteAt int64 `json:"incomplete_at"` + Role string `json:"role"` + Code string `json:"code"` + Message string `json:"message"` + Param string `json:"param"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + Metadata resp.Field + Object resp.Field + ToolResources resp.Field + AssistantID resp.Field + CancelledAt resp.Field + CompletedAt resp.Field + ExpiresAt resp.Field + FailedAt resp.Field + IncompleteDetails resp.Field + Instructions resp.Field + LastError resp.Field + MaxCompletionTokens resp.Field + MaxPromptTokens resp.Field + Model resp.Field + ParallelToolCalls resp.Field + RequiredAction resp.Field + StartedAt resp.Field + Status resp.Field + ThreadID resp.Field + ToolChoice resp.Field + Tools resp.Field + TruncationStrategy resp.Field + Usage resp.Field + Temperature resp.Field + TopP resp.Field + ExpiredAt resp.Field + RunID resp.Field + StepDetails resp.Field + Type resp.Field + Delta resp.Field + Attachments resp.Field + Content resp.Field + IncompleteAt resp.Field + Role resp.Field + Code resp.Field + Message resp.Field + Param resp.Field + raw string + } `json:"-"` +} + +func (r *AssistantStreamEventUnionData) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type AssistantStreamEventUnionDataIncompleteDetails struct { + Reason string `json:"reason"` + JSON struct { + Reason resp.Field + raw string + } `json:"-"` +} + +func (r *AssistantStreamEventUnionDataIncompleteDetails) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type AssistantStreamEventUnionDataLastError struct { + Code string `json:"code"` + Message string `json:"message"` + JSON struct { + Code resp.Field + Message resp.Field + raw string + } `json:"-"` +} + +func (r *AssistantStreamEventUnionDataLastError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type AssistantStreamEventUnionDataDelta struct { + StepDetails RunStepDeltaStepDetailsUnion `json:"step_details"` + Content []MessageContentDeltaUnion `json:"content"` + Role string `json:"role"` + JSON struct { + StepDetails resp.Field + Content resp.Field + Role resp.Field + raw string + } `json:"-"` +} + +func (r *AssistantStreamEventUnionDataDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // Occurs when a new @@ -580,1285 +639,684 @@ func init() { type AssistantStreamEventThreadCreated struct { // Represents a thread that contains // [messages](https://platform.openai.com/docs/api-reference/messages). - Data Thread `json:"data,required"` - Event AssistantStreamEventThreadCreatedEvent `json:"event,required"` + Data Thread `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.created". + Event constant.ThreadCreated `json:"event,required"` // Whether to enable input audio transcription. - Enabled bool `json:"enabled"` - JSON assistantStreamEventThreadCreatedJSON `json:"-"` + Enabled bool `json:"enabled,omitzero"` + JSON struct { + Data resp.Field + Event resp.Field + Enabled resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadCreatedJSON contains the JSON metadata for the struct -// [AssistantStreamEventThreadCreated] -type assistantStreamEventThreadCreatedJSON struct { - Data apijson.Field - Event apijson.Field - Enabled apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadCreated) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadCreated) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadCreated) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadCreatedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadCreated) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadCreatedEvent string - -const ( - AssistantStreamEventThreadCreatedEventThreadCreated AssistantStreamEventThreadCreatedEvent = "thread.created" -) - -func (r AssistantStreamEventThreadCreatedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadCreatedEventThreadCreated: - return true - } - return false -} - // Occurs when a new // [run](https://platform.openai.com/docs/api-reference/runs/object) is created. type AssistantStreamEventThreadRunCreated struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunCreatedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunCreatedJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.run.created". + Event constant.ThreadRunCreated `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunCreatedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunCreated] -type assistantStreamEventThreadRunCreatedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunCreated) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunCreated) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunCreated) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunCreatedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunCreated) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunCreatedEvent string - -const ( - AssistantStreamEventThreadRunCreatedEventThreadRunCreated AssistantStreamEventThreadRunCreatedEvent = "thread.run.created" -) - -func (r AssistantStreamEventThreadRunCreatedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunCreatedEventThreadRunCreated: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // moves to a `queued` status. type AssistantStreamEventThreadRunQueued struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunQueuedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunQueuedJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.run.queued". + Event constant.ThreadRunQueued `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunQueuedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunQueued] -type assistantStreamEventThreadRunQueuedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunQueued) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunQueued) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunQueued) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunQueuedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunQueued) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunQueuedEvent string - -const ( - AssistantStreamEventThreadRunQueuedEventThreadRunQueued AssistantStreamEventThreadRunQueuedEvent = "thread.run.queued" -) - -func (r AssistantStreamEventThreadRunQueuedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunQueuedEventThreadRunQueued: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // moves to an `in_progress` status. type AssistantStreamEventThreadRunInProgress struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunInProgressEvent `json:"event,required"` - JSON assistantStreamEventThreadRunInProgressJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.in_progress". + Event constant.ThreadRunInProgress `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunInProgressJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunInProgress] -type assistantStreamEventThreadRunInProgressJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunInProgress) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunInProgress) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunInProgress) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunInProgressJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunInProgress) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunInProgressEvent string - -const ( - AssistantStreamEventThreadRunInProgressEventThreadRunInProgress AssistantStreamEventThreadRunInProgressEvent = "thread.run.in_progress" -) - -func (r AssistantStreamEventThreadRunInProgressEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunInProgressEventThreadRunInProgress: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // moves to a `requires_action` status. type AssistantStreamEventThreadRunRequiresAction struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunRequiresActionEvent `json:"event,required"` - JSON assistantStreamEventThreadRunRequiresActionJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.requires_action". + Event constant.ThreadRunRequiresAction `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunRequiresActionJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadRunRequiresAction] -type assistantStreamEventThreadRunRequiresActionJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunRequiresAction) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunRequiresAction) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunRequiresAction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunRequiresActionJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunRequiresAction) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunRequiresActionEvent string - -const ( - AssistantStreamEventThreadRunRequiresActionEventThreadRunRequiresAction AssistantStreamEventThreadRunRequiresActionEvent = "thread.run.requires_action" -) - -func (r AssistantStreamEventThreadRunRequiresActionEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunRequiresActionEventThreadRunRequiresAction: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // is completed. type AssistantStreamEventThreadRunCompleted struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunCompletedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunCompletedJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.completed". + Event constant.ThreadRunCompleted `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunCompletedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunCompleted] -type assistantStreamEventThreadRunCompletedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunCompleted) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunCompleted) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunCompleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunCompletedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunCompleted) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunCompletedEvent string - -const ( - AssistantStreamEventThreadRunCompletedEventThreadRunCompleted AssistantStreamEventThreadRunCompletedEvent = "thread.run.completed" -) - -func (r AssistantStreamEventThreadRunCompletedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunCompletedEventThreadRunCompleted: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // ends with status `incomplete`. type AssistantStreamEventThreadRunIncomplete struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunIncompleteEvent `json:"event,required"` - JSON assistantStreamEventThreadRunIncompleteJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.incomplete". + Event constant.ThreadRunIncomplete `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunIncompleteJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunIncomplete] -type assistantStreamEventThreadRunIncompleteJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunIncomplete) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunIncomplete) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunIncomplete) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunIncompleteJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunIncomplete) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunIncompleteEvent string - -const ( - AssistantStreamEventThreadRunIncompleteEventThreadRunIncomplete AssistantStreamEventThreadRunIncompleteEvent = "thread.run.incomplete" -) - -func (r AssistantStreamEventThreadRunIncompleteEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunIncompleteEventThreadRunIncomplete: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // fails. type AssistantStreamEventThreadRunFailed struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunFailedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunFailedJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.run.failed". + Event constant.ThreadRunFailed `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunFailedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunFailed] -type assistantStreamEventThreadRunFailedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunFailed) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunFailed) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunFailed) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunFailedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunFailed) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunFailedEvent string - -const ( - AssistantStreamEventThreadRunFailedEventThreadRunFailed AssistantStreamEventThreadRunFailedEvent = "thread.run.failed" -) - -func (r AssistantStreamEventThreadRunFailedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunFailedEventThreadRunFailed: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // moves to a `cancelling` status. type AssistantStreamEventThreadRunCancelling struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunCancellingEvent `json:"event,required"` - JSON assistantStreamEventThreadRunCancellingJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.cancelling". + Event constant.ThreadRunCancelling `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunCancellingJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunCancelling] -type assistantStreamEventThreadRunCancellingJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunCancelling) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunCancelling) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunCancelling) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunCancellingJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunCancelling) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunCancellingEvent string - -const ( - AssistantStreamEventThreadRunCancellingEventThreadRunCancelling AssistantStreamEventThreadRunCancellingEvent = "thread.run.cancelling" -) - -func (r AssistantStreamEventThreadRunCancellingEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunCancellingEventThreadRunCancelling: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // is cancelled. type AssistantStreamEventThreadRunCancelled struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunCancelledEvent `json:"event,required"` - JSON assistantStreamEventThreadRunCancelledJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.cancelled". + Event constant.ThreadRunCancelled `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunCancelledJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunCancelled] -type assistantStreamEventThreadRunCancelledJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunCancelled) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunCancelled) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunCancelled) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunCancelledJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunCancelled) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunCancelledEvent string - -const ( - AssistantStreamEventThreadRunCancelledEventThreadRunCancelled AssistantStreamEventThreadRunCancelledEvent = "thread.run.cancelled" -) - -func (r AssistantStreamEventThreadRunCancelledEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunCancelledEventThreadRunCancelled: - return true - } - return false -} - // Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object) // expires. type AssistantStreamEventThreadRunExpired struct { // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Run `json:"data,required"` - Event AssistantStreamEventThreadRunExpiredEvent `json:"event,required"` - JSON assistantStreamEventThreadRunExpiredJSON `json:"-"` + Data Run `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.run.expired". + Event constant.ThreadRunExpired `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunExpiredJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunExpired] -type assistantStreamEventThreadRunExpiredJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunExpired) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunExpired) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunExpired) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunExpiredJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunExpired) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunExpiredEvent string - -const ( - AssistantStreamEventThreadRunExpiredEventThreadRunExpired AssistantStreamEventThreadRunExpiredEvent = "thread.run.expired" -) - -func (r AssistantStreamEventThreadRunExpiredEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunExpiredEventThreadRunExpired: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // is created. type AssistantStreamEventThreadRunStepCreated struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepCreatedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepCreatedJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.created". + Event constant.ThreadRunStepCreated `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepCreatedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunStepCreated] -type assistantStreamEventThreadRunStepCreatedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepCreated) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepCreated) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepCreated) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepCreatedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepCreated) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepCreatedEvent string - -const ( - AssistantStreamEventThreadRunStepCreatedEventThreadRunStepCreated AssistantStreamEventThreadRunStepCreatedEvent = "thread.run.step.created" -) - -func (r AssistantStreamEventThreadRunStepCreatedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepCreatedEventThreadRunStepCreated: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // moves to an `in_progress` state. type AssistantStreamEventThreadRunStepInProgress struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepInProgressEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepInProgressJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.in_progress". + Event constant.ThreadRunStepInProgress `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepInProgressJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadRunStepInProgress] -type assistantStreamEventThreadRunStepInProgressJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepInProgress) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepInProgress) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepInProgress) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepInProgressJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepInProgress) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepInProgressEvent string - -const ( - AssistantStreamEventThreadRunStepInProgressEventThreadRunStepInProgress AssistantStreamEventThreadRunStepInProgressEvent = "thread.run.step.in_progress" -) - -func (r AssistantStreamEventThreadRunStepInProgressEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepInProgressEventThreadRunStepInProgress: - return true - } - return false -} - // Occurs when parts of a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // are being streamed. type AssistantStreamEventThreadRunStepDelta struct { // Represents a run step delta i.e. any changed fields on a run step during // streaming. - Data RunStepDeltaEvent `json:"data,required"` - Event AssistantStreamEventThreadRunStepDeltaEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepDeltaJSON `json:"-"` + Data RunStepDeltaEvent `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.delta". + Event constant.ThreadRunStepDelta `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepDeltaJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunStepDelta] -type assistantStreamEventThreadRunStepDeltaJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepDelta) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepDelta) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepDeltaJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepDelta) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepDeltaEvent string - -const ( - AssistantStreamEventThreadRunStepDeltaEventThreadRunStepDelta AssistantStreamEventThreadRunStepDeltaEvent = "thread.run.step.delta" -) - -func (r AssistantStreamEventThreadRunStepDeltaEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepDeltaEventThreadRunStepDelta: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // is completed. type AssistantStreamEventThreadRunStepCompleted struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepCompletedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepCompletedJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.completed". + Event constant.ThreadRunStepCompleted `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepCompletedJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadRunStepCompleted] -type assistantStreamEventThreadRunStepCompletedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepCompleted) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepCompleted) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepCompleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepCompletedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepCompleted) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepCompletedEvent string - -const ( - AssistantStreamEventThreadRunStepCompletedEventThreadRunStepCompleted AssistantStreamEventThreadRunStepCompletedEvent = "thread.run.step.completed" -) - -func (r AssistantStreamEventThreadRunStepCompletedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepCompletedEventThreadRunStepCompleted: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // fails. type AssistantStreamEventThreadRunStepFailed struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepFailedEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepFailedJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.failed". + Event constant.ThreadRunStepFailed `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepFailedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunStepFailed] -type assistantStreamEventThreadRunStepFailedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepFailed) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepFailed) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepFailed) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepFailedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepFailed) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepFailedEvent string - -const ( - AssistantStreamEventThreadRunStepFailedEventThreadRunStepFailed AssistantStreamEventThreadRunStepFailedEvent = "thread.run.step.failed" -) - -func (r AssistantStreamEventThreadRunStepFailedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepFailedEventThreadRunStepFailed: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // is cancelled. type AssistantStreamEventThreadRunStepCancelled struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepCancelledEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepCancelledJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.cancelled". + Event constant.ThreadRunStepCancelled `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepCancelledJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadRunStepCancelled] -type assistantStreamEventThreadRunStepCancelledJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepCancelled) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepCancelled) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepCancelled) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepCancelledJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepCancelled) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepCancelledEvent string - -const ( - AssistantStreamEventThreadRunStepCancelledEventThreadRunStepCancelled AssistantStreamEventThreadRunStepCancelledEvent = "thread.run.step.cancelled" -) - -func (r AssistantStreamEventThreadRunStepCancelledEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepCancelledEventThreadRunStepCancelled: - return true - } - return false -} - // Occurs when a // [run step](https://platform.openai.com/docs/api-reference/run-steps/step-object) // expires. type AssistantStreamEventThreadRunStepExpired struct { // Represents a step in execution of a run. - Data RunStep `json:"data,required"` - Event AssistantStreamEventThreadRunStepExpiredEvent `json:"event,required"` - JSON assistantStreamEventThreadRunStepExpiredJSON `json:"-"` + Data RunStep `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.run.step.expired". + Event constant.ThreadRunStepExpired `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadRunStepExpiredJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadRunStepExpired] -type assistantStreamEventThreadRunStepExpiredJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadRunStepExpired) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadRunStepExpired) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadRunStepExpired) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadRunStepExpiredJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadRunStepExpired) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadRunStepExpiredEvent string - -const ( - AssistantStreamEventThreadRunStepExpiredEventThreadRunStepExpired AssistantStreamEventThreadRunStepExpiredEvent = "thread.run.step.expired" -) - -func (r AssistantStreamEventThreadRunStepExpiredEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadRunStepExpiredEventThreadRunStepExpired: - return true - } - return false -} - // Occurs when a // [message](https://platform.openai.com/docs/api-reference/messages/object) is // created. type AssistantStreamEventThreadMessageCreated struct { // Represents a message within a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Message `json:"data,required"` - Event AssistantStreamEventThreadMessageCreatedEvent `json:"event,required"` - JSON assistantStreamEventThreadMessageCreatedJSON `json:"-"` + Data Message `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.created". + Event constant.ThreadMessageCreated `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadMessageCreatedJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadMessageCreated] -type assistantStreamEventThreadMessageCreatedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadMessageCreated) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadMessageCreated) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadMessageCreated) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadMessageCreatedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadMessageCreated) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadMessageCreatedEvent string - -const ( - AssistantStreamEventThreadMessageCreatedEventThreadMessageCreated AssistantStreamEventThreadMessageCreatedEvent = "thread.message.created" -) - -func (r AssistantStreamEventThreadMessageCreatedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadMessageCreatedEventThreadMessageCreated: - return true - } - return false -} - // Occurs when a // [message](https://platform.openai.com/docs/api-reference/messages/object) moves // to an `in_progress` state. type AssistantStreamEventThreadMessageInProgress struct { // Represents a message within a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Message `json:"data,required"` - Event AssistantStreamEventThreadMessageInProgressEvent `json:"event,required"` - JSON assistantStreamEventThreadMessageInProgressJSON `json:"-"` + Data Message `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.in_progress". + Event constant.ThreadMessageInProgress `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadMessageInProgressJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadMessageInProgress] -type assistantStreamEventThreadMessageInProgressJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadMessageInProgress) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadMessageInProgress) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadMessageInProgress) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadMessageInProgressJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadMessageInProgress) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadMessageInProgressEvent string - -const ( - AssistantStreamEventThreadMessageInProgressEventThreadMessageInProgress AssistantStreamEventThreadMessageInProgressEvent = "thread.message.in_progress" -) - -func (r AssistantStreamEventThreadMessageInProgressEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadMessageInProgressEventThreadMessageInProgress: - return true - } - return false -} - // Occurs when parts of a // [Message](https://platform.openai.com/docs/api-reference/messages/object) are // being streamed. type AssistantStreamEventThreadMessageDelta struct { // Represents a message delta i.e. any changed fields on a message during // streaming. - Data MessageDeltaEvent `json:"data,required"` - Event AssistantStreamEventThreadMessageDeltaEvent `json:"event,required"` - JSON assistantStreamEventThreadMessageDeltaJSON `json:"-"` + Data MessageDeltaEvent `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.delta". + Event constant.ThreadMessageDelta `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadMessageDeltaJSON contains the JSON metadata for the -// struct [AssistantStreamEventThreadMessageDelta] -type assistantStreamEventThreadMessageDeltaJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadMessageDelta) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadMessageDelta) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadMessageDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadMessageDeltaJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadMessageDelta) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadMessageDeltaEvent string - -const ( - AssistantStreamEventThreadMessageDeltaEventThreadMessageDelta AssistantStreamEventThreadMessageDeltaEvent = "thread.message.delta" -) - -func (r AssistantStreamEventThreadMessageDeltaEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadMessageDeltaEventThreadMessageDelta: - return true - } - return false -} - // Occurs when a // [message](https://platform.openai.com/docs/api-reference/messages/object) is // completed. type AssistantStreamEventThreadMessageCompleted struct { // Represents a message within a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Message `json:"data,required"` - Event AssistantStreamEventThreadMessageCompletedEvent `json:"event,required"` - JSON assistantStreamEventThreadMessageCompletedJSON `json:"-"` + Data Message `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.completed". + Event constant.ThreadMessageCompleted `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadMessageCompletedJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadMessageCompleted] -type assistantStreamEventThreadMessageCompletedJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadMessageCompleted) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadMessageCompleted) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadMessageCompleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadMessageCompletedJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadMessageCompleted) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadMessageCompletedEvent string - -const ( - AssistantStreamEventThreadMessageCompletedEventThreadMessageCompleted AssistantStreamEventThreadMessageCompletedEvent = "thread.message.completed" -) - -func (r AssistantStreamEventThreadMessageCompletedEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadMessageCompletedEventThreadMessageCompleted: - return true - } - return false -} - // Occurs when a // [message](https://platform.openai.com/docs/api-reference/messages/object) ends // before it is completed. type AssistantStreamEventThreadMessageIncomplete struct { // Represents a message within a // [thread](https://platform.openai.com/docs/api-reference/threads). - Data Message `json:"data,required"` - Event AssistantStreamEventThreadMessageIncompleteEvent `json:"event,required"` - JSON assistantStreamEventThreadMessageIncompleteJSON `json:"-"` + Data Message `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.incomplete". + Event constant.ThreadMessageIncomplete `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventThreadMessageIncompleteJSON contains the JSON metadata for -// the struct [AssistantStreamEventThreadMessageIncomplete] -type assistantStreamEventThreadMessageIncompleteJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventThreadMessageIncomplete) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventThreadMessageIncomplete) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventThreadMessageIncomplete) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventThreadMessageIncompleteJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventThreadMessageIncomplete) implementsAssistantStreamEvent() {} - -type AssistantStreamEventThreadMessageIncompleteEvent string - -const ( - AssistantStreamEventThreadMessageIncompleteEventThreadMessageIncomplete AssistantStreamEventThreadMessageIncompleteEvent = "thread.message.incomplete" -) - -func (r AssistantStreamEventThreadMessageIncompleteEvent) IsKnown() bool { - switch r { - case AssistantStreamEventThreadMessageIncompleteEventThreadMessageIncomplete: - return true - } - return false -} - // Occurs when an // [error](https://platform.openai.com/docs/guides/error-codes#api-errors) occurs. // This can happen due to an internal server error or a timeout. type AssistantStreamEventErrorEvent struct { - Data shared.ErrorObject `json:"data,required"` - Event AssistantStreamEventErrorEventEvent `json:"event,required"` - JSON assistantStreamEventErrorEventJSON `json:"-"` + Data shared.ErrorObject `json:"data,omitzero,required"` + // This field can be elided, and will be automatically set as "error". + Event constant.Error `json:"event,required"` + JSON struct { + Data resp.Field + Event resp.Field + raw string + } `json:"-"` } -// assistantStreamEventErrorEventJSON contains the JSON metadata for the struct -// [AssistantStreamEventErrorEvent] -type assistantStreamEventErrorEventJSON struct { - Data apijson.Field - Event apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantStreamEventErrorEvent) UnmarshalJSON(data []byte) (err error) { +func (r AssistantStreamEventErrorEvent) RawJSON() string { return r.JSON.raw } +func (r *AssistantStreamEventErrorEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantStreamEventErrorEventJSON) RawJSON() string { - return r.raw -} - -func (r AssistantStreamEventErrorEvent) implementsAssistantStreamEvent() {} - -type AssistantStreamEventErrorEventEvent string - -const ( - AssistantStreamEventErrorEventEventError AssistantStreamEventErrorEventEvent = "error" -) - -func (r AssistantStreamEventErrorEventEvent) IsKnown() bool { - switch r { - case AssistantStreamEventErrorEventEventError: - return true - } - return false -} - -type AssistantStreamEventEvent string - -const ( - AssistantStreamEventEventThreadCreated AssistantStreamEventEvent = "thread.created" - AssistantStreamEventEventThreadRunCreated AssistantStreamEventEvent = "thread.run.created" - AssistantStreamEventEventThreadRunQueued AssistantStreamEventEvent = "thread.run.queued" - AssistantStreamEventEventThreadRunInProgress AssistantStreamEventEvent = "thread.run.in_progress" - AssistantStreamEventEventThreadRunRequiresAction AssistantStreamEventEvent = "thread.run.requires_action" - AssistantStreamEventEventThreadRunCompleted AssistantStreamEventEvent = "thread.run.completed" - AssistantStreamEventEventThreadRunIncomplete AssistantStreamEventEvent = "thread.run.incomplete" - AssistantStreamEventEventThreadRunFailed AssistantStreamEventEvent = "thread.run.failed" - AssistantStreamEventEventThreadRunCancelling AssistantStreamEventEvent = "thread.run.cancelling" - AssistantStreamEventEventThreadRunCancelled AssistantStreamEventEvent = "thread.run.cancelled" - AssistantStreamEventEventThreadRunExpired AssistantStreamEventEvent = "thread.run.expired" - AssistantStreamEventEventThreadRunStepCreated AssistantStreamEventEvent = "thread.run.step.created" - AssistantStreamEventEventThreadRunStepInProgress AssistantStreamEventEvent = "thread.run.step.in_progress" - AssistantStreamEventEventThreadRunStepDelta AssistantStreamEventEvent = "thread.run.step.delta" - AssistantStreamEventEventThreadRunStepCompleted AssistantStreamEventEvent = "thread.run.step.completed" - AssistantStreamEventEventThreadRunStepFailed AssistantStreamEventEvent = "thread.run.step.failed" - AssistantStreamEventEventThreadRunStepCancelled AssistantStreamEventEvent = "thread.run.step.cancelled" - AssistantStreamEventEventThreadRunStepExpired AssistantStreamEventEvent = "thread.run.step.expired" - AssistantStreamEventEventThreadMessageCreated AssistantStreamEventEvent = "thread.message.created" - AssistantStreamEventEventThreadMessageInProgress AssistantStreamEventEvent = "thread.message.in_progress" - AssistantStreamEventEventThreadMessageDelta AssistantStreamEventEvent = "thread.message.delta" - AssistantStreamEventEventThreadMessageCompleted AssistantStreamEventEvent = "thread.message.completed" - AssistantStreamEventEventThreadMessageIncomplete AssistantStreamEventEvent = "thread.message.incomplete" - AssistantStreamEventEventError AssistantStreamEventEvent = "error" -) - -func (r AssistantStreamEventEvent) IsKnown() bool { - switch r { - case AssistantStreamEventEventThreadCreated, AssistantStreamEventEventThreadRunCreated, AssistantStreamEventEventThreadRunQueued, AssistantStreamEventEventThreadRunInProgress, AssistantStreamEventEventThreadRunRequiresAction, AssistantStreamEventEventThreadRunCompleted, AssistantStreamEventEventThreadRunIncomplete, AssistantStreamEventEventThreadRunFailed, AssistantStreamEventEventThreadRunCancelling, AssistantStreamEventEventThreadRunCancelled, AssistantStreamEventEventThreadRunExpired, AssistantStreamEventEventThreadRunStepCreated, AssistantStreamEventEventThreadRunStepInProgress, AssistantStreamEventEventThreadRunStepDelta, AssistantStreamEventEventThreadRunStepCompleted, AssistantStreamEventEventThreadRunStepFailed, AssistantStreamEventEventThreadRunStepCancelled, AssistantStreamEventEventThreadRunStepExpired, AssistantStreamEventEventThreadMessageCreated, AssistantStreamEventEventThreadMessageInProgress, AssistantStreamEventEventThreadMessageDelta, AssistantStreamEventEventThreadMessageCompleted, AssistantStreamEventEventThreadMessageIncomplete, AssistantStreamEventEventError: - return true - } - return false -} - -type AssistantTool struct { - // The type of tool being defined: `code_interpreter` - Type AssistantToolType `json:"type,required"` - // This field can have the runtime type of [FileSearchToolFileSearch]. - FileSearch interface{} `json:"file_search"` +type AssistantToolUnion struct { + Type string `json:"type"` + FileSearch FileSearchToolFileSearch `json:"file_search"` Function shared.FunctionDefinition `json:"function"` - JSON assistantToolJSON `json:"-"` - union AssistantToolUnion + JSON struct { + Type resp.Field + FileSearch resp.Field + Function resp.Field + raw string + } `json:"-"` } -// assistantToolJSON contains the JSON metadata for the struct [AssistantTool] -type assistantToolJSON struct { - Type apijson.Field - FileSearch apijson.Field - Function apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r assistantToolJSON) RawJSON() string { - return r.raw -} - -func (r *AssistantTool) UnmarshalJSON(data []byte) (err error) { - *r = AssistantTool{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u AssistantToolUnion) Variant() (res struct { + OfCodeInterpreter *CodeInterpreterTool + OfFileSearch *FileSearchTool + OfFunction *FunctionTool +}) { + switch u.Type { + case "code_interpreter": + v := u.AsCodeInterpreter() + res.OfCodeInterpreter = &v + case "file_search": + v := u.AsFileSearch() + res.OfFileSearch = &v + case "function": + v := u.AsFunction() + res.OfFunction = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [AssistantToolUnion] interface which you can cast to the -// specific types for more type safety. +func (u AssistantToolUnion) WhichKind() string { + return u.Type +} + +func (u AssistantToolUnion) AsCodeInterpreter() (v CodeInterpreterTool) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantToolUnion) AsFileSearch() (v FileSearchTool) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantToolUnion) AsFunction() (v FunctionTool) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantToolUnion) RawJSON() string { return u.JSON.raw } + +func (r *AssistantToolUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this AssistantToolUnion to a AssistantToolUnionParam. // -// Possible runtime types of the union are [CodeInterpreterTool], [FileSearchTool], -// [FunctionTool]. -func (r AssistantTool) AsUnion() AssistantToolUnion { - return r.union +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// AssistantToolUnionParam.IsOverridden() +func (r AssistantToolUnion) ToParam() AssistantToolUnionParam { + return param.Override[AssistantToolUnionParam](r.RawJSON()) } -// Union satisfied by [CodeInterpreterTool], [FileSearchTool] or [FunctionTool]. -type AssistantToolUnion interface { - implementsAssistantTool() +func NewAssistantToolOfFunction(function shared.FunctionDefinitionParam) AssistantToolUnionParam { + var variant FunctionToolParam + variant.Function = function + return AssistantToolUnionParam{OfFunction: &variant} } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*AssistantToolUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterTool{}), - DiscriminatorValue: "code_interpreter", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileSearchTool{}), - DiscriminatorValue: "file_search", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FunctionTool{}), - DiscriminatorValue: "function", - }, - ) +// Only one field can be non-zero +type AssistantToolUnionParam struct { + OfCodeInterpreter *CodeInterpreterToolParam + OfFileSearch *FileSearchToolParam + OfFunction *FunctionToolParam + apiunion } -// The type of tool being defined: `code_interpreter` -type AssistantToolType string +func (u AssistantToolUnionParam) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } -const ( - AssistantToolTypeCodeInterpreter AssistantToolType = "code_interpreter" - AssistantToolTypeFileSearch AssistantToolType = "file_search" - AssistantToolTypeFunction AssistantToolType = "function" -) +func (u AssistantToolUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[AssistantToolUnionParam](u.OfCodeInterpreter, u.OfFileSearch, u.OfFunction) +} -func (r AssistantToolType) IsKnown() bool { - switch r { - case AssistantToolTypeCodeInterpreter, AssistantToolTypeFileSearch, AssistantToolTypeFunction: - return true +func (u AssistantToolUnionParam) GetFileSearch() *FileSearchToolFileSearchParam { + if vt := u.OfFileSearch; vt != nil { + return &vt.FileSearch } - return false + return nil } -type AssistantToolParam struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[AssistantToolType] `json:"type,required"` - FileSearch param.Field[interface{}] `json:"file_search"` - Function param.Field[shared.FunctionDefinitionParam] `json:"function"` +func (u AssistantToolUnionParam) GetFunction() *shared.FunctionDefinitionParam { + if vt := u.OfFunction; vt != nil { + return &vt.Function + } + return nil } -func (r AssistantToolParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r AssistantToolParam) implementsAssistantToolUnionParam() {} - -// Satisfied by [CodeInterpreterToolParam], [FileSearchToolParam], -// [FunctionToolParam], [AssistantToolParam]. -type AssistantToolUnionParam interface { - implementsAssistantToolUnionParam() +func (u AssistantToolUnionParam) GetType() *string { + if vt := u.OfCodeInterpreter; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearch; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFunction; vt != nil { + return (*string)(&vt.Type) + } + return nil } type CodeInterpreterTool struct { // The type of tool being defined: `code_interpreter` - Type CodeInterpreterToolType `json:"type,required"` - JSON codeInterpreterToolJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "code_interpreter". + Type constant.CodeInterpreter `json:"type,required"` + JSON struct { + Type resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolJSON contains the JSON metadata for the struct -// [CodeInterpreterTool] -type codeInterpreterToolJSON struct { - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterTool) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterTool) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterTool) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterTool) implementsAssistantTool() {} - -func (r CodeInterpreterTool) implementsMessageAttachmentsTool() {} - -// The type of tool being defined: `code_interpreter` -type CodeInterpreterToolType string - -const ( - CodeInterpreterToolTypeCodeInterpreter CodeInterpreterToolType = "code_interpreter" -) - -func (r CodeInterpreterToolType) IsKnown() bool { - switch r { - case CodeInterpreterToolTypeCodeInterpreter: - return true - } - return false +// ToParam converts this CodeInterpreterTool to a CodeInterpreterToolParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// CodeInterpreterToolParam.IsOverridden() +func (r CodeInterpreterTool) ToParam() CodeInterpreterToolParam { + return param.Override[CodeInterpreterToolParam](r.RawJSON()) } type CodeInterpreterToolParam struct { // The type of tool being defined: `code_interpreter` - Type param.Field[CodeInterpreterToolType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "code_interpreter". + Type constant.CodeInterpreter `json:"type,required"` + apiobject } +func (f CodeInterpreterToolParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r CodeInterpreterToolParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow CodeInterpreterToolParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r CodeInterpreterToolParam) implementsAssistantToolUnionParam() {} - -func (r CodeInterpreterToolParam) implementsBetaThreadNewParamsMessagesAttachmentsToolUnion() {} - -func (r CodeInterpreterToolParam) implementsBetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion() { -} - -func (r CodeInterpreterToolParam) implementsBetaThreadNewAndRunParamsToolUnion() {} - -func (r CodeInterpreterToolParam) implementsBetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion() { -} - -func (r CodeInterpreterToolParam) implementsBetaThreadMessageNewParamsAttachmentsToolUnion() {} - type FileSearchTool struct { // The type of tool being defined: `file_search` - Type FileSearchToolType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` // Overrides for the file search tool. - FileSearch FileSearchToolFileSearch `json:"file_search"` - JSON fileSearchToolJSON `json:"-"` + FileSearch FileSearchToolFileSearch `json:"file_search,omitzero"` + JSON struct { + Type resp.Field + FileSearch resp.Field + raw string + } `json:"-"` } -// fileSearchToolJSON contains the JSON metadata for the struct [FileSearchTool] -type fileSearchToolJSON struct { - Type apijson.Field - FileSearch apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchTool) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchTool) RawJSON() string { return r.JSON.raw } +func (r *FileSearchTool) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolJSON) RawJSON() string { - return r.raw -} - -func (r FileSearchTool) implementsAssistantTool() {} - -// The type of tool being defined: `file_search` -type FileSearchToolType string - -const ( - FileSearchToolTypeFileSearch FileSearchToolType = "file_search" -) - -func (r FileSearchToolType) IsKnown() bool { - switch r { - case FileSearchToolTypeFileSearch: - return true - } - return false +// ToParam converts this FileSearchTool to a FileSearchToolParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// FileSearchToolParam.IsOverridden() +func (r FileSearchTool) ToParam() FileSearchToolParam { + return param.Override[FileSearchToolParam](r.RawJSON()) } // Overrides for the file search tool. @@ -1871,34 +1329,26 @@ type FileSearchToolFileSearch struct { // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - MaxNumResults int64 `json:"max_num_results"` + MaxNumResults int64 `json:"max_num_results,omitzero"` // The ranking options for the file search. If not specified, the file search tool // will use the `auto` ranker and a score_threshold of 0. // // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - RankingOptions FileSearchToolFileSearchRankingOptions `json:"ranking_options"` - JSON fileSearchToolFileSearchJSON `json:"-"` + RankingOptions FileSearchToolFileSearchRankingOptions `json:"ranking_options,omitzero"` + JSON struct { + MaxNumResults resp.Field + RankingOptions resp.Field + raw string + } `json:"-"` } -// fileSearchToolFileSearchJSON contains the JSON metadata for the struct -// [FileSearchToolFileSearch] -type fileSearchToolFileSearchJSON struct { - MaxNumResults apijson.Field - RankingOptions apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolFileSearch) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolFileSearch) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolFileSearch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolFileSearchJSON) RawJSON() string { - return r.raw -} - // The ranking options for the file search. If not specified, the file search tool // will use the `auto` ranker and a score_threshold of 0. // @@ -1908,62 +1358,50 @@ func (r fileSearchToolFileSearchJSON) RawJSON() string { type FileSearchToolFileSearchRankingOptions struct { // The score threshold for the file search. All values must be a floating point // number between 0 and 1. - ScoreThreshold float64 `json:"score_threshold,required"` + ScoreThreshold float64 `json:"score_threshold,omitzero,required"` // The ranker to use for the file search. If not specified will use the `auto` // ranker. - Ranker FileSearchToolFileSearchRankingOptionsRanker `json:"ranker"` - JSON fileSearchToolFileSearchRankingOptionsJSON `json:"-"` + // + // Any of "auto", "default_2024_08_21" + Ranker string `json:"ranker,omitzero"` + JSON struct { + ScoreThreshold resp.Field + Ranker resp.Field + raw string + } `json:"-"` } -// fileSearchToolFileSearchRankingOptionsJSON contains the JSON metadata for the -// struct [FileSearchToolFileSearchRankingOptions] -type fileSearchToolFileSearchRankingOptionsJSON struct { - ScoreThreshold apijson.Field - Ranker apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolFileSearchRankingOptions) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolFileSearchRankingOptions) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolFileSearchRankingOptions) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolFileSearchRankingOptionsJSON) RawJSON() string { - return r.raw -} - // The ranker to use for the file search. If not specified will use the `auto` // ranker. -type FileSearchToolFileSearchRankingOptionsRanker string +type FileSearchToolFileSearchRankingOptionsRanker = string const ( FileSearchToolFileSearchRankingOptionsRankerAuto FileSearchToolFileSearchRankingOptionsRanker = "auto" FileSearchToolFileSearchRankingOptionsRankerDefault2024_08_21 FileSearchToolFileSearchRankingOptionsRanker = "default_2024_08_21" ) -func (r FileSearchToolFileSearchRankingOptionsRanker) IsKnown() bool { - switch r { - case FileSearchToolFileSearchRankingOptionsRankerAuto, FileSearchToolFileSearchRankingOptionsRankerDefault2024_08_21: - return true - } - return false -} - type FileSearchToolParam struct { // The type of tool being defined: `file_search` - Type param.Field[FileSearchToolType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` // Overrides for the file search tool. - FileSearch param.Field[FileSearchToolFileSearchParam] `json:"file_search"` + FileSearch FileSearchToolFileSearchParam `json:"file_search,omitzero"` + apiobject } +func (f FileSearchToolParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FileSearchToolParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FileSearchToolParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r FileSearchToolParam) implementsAssistantToolUnionParam() {} - -func (r FileSearchToolParam) implementsBetaThreadNewAndRunParamsToolUnion() {} - // Overrides for the file search tool. type FileSearchToolFileSearchParam struct { // The maximum number of results the file search tool should output. The default is @@ -1974,18 +1412,22 @@ type FileSearchToolFileSearchParam struct { // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - MaxNumResults param.Field[int64] `json:"max_num_results"` + MaxNumResults param.Int `json:"max_num_results,omitzero"` // The ranking options for the file search. If not specified, the file search tool // will use the `auto` ranker and a score_threshold of 0. // // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - RankingOptions param.Field[FileSearchToolFileSearchRankingOptionsParam] `json:"ranking_options"` + RankingOptions FileSearchToolFileSearchRankingOptionsParam `json:"ranking_options,omitzero"` + apiobject } +func (f FileSearchToolFileSearchParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FileSearchToolFileSearchParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FileSearchToolFileSearchParam + return param.MarshalObject(r, (*shadow)(&r)) } // The ranking options for the file search. If not specified, the file search tool @@ -1997,121 +1439,124 @@ func (r FileSearchToolFileSearchParam) MarshalJSON() (data []byte, err error) { type FileSearchToolFileSearchRankingOptionsParam struct { // The score threshold for the file search. All values must be a floating point // number between 0 and 1. - ScoreThreshold param.Field[float64] `json:"score_threshold,required"` + ScoreThreshold param.Float `json:"score_threshold,omitzero,required"` // The ranker to use for the file search. If not specified will use the `auto` // ranker. - Ranker param.Field[FileSearchToolFileSearchRankingOptionsRanker] `json:"ranker"` + // + // Any of "auto", "default_2024_08_21" + Ranker string `json:"ranker,omitzero"` + apiobject +} + +func (f FileSearchToolFileSearchRankingOptionsParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FileSearchToolFileSearchRankingOptionsParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FileSearchToolFileSearchRankingOptionsParam + return param.MarshalObject(r, (*shadow)(&r)) } type FunctionTool struct { - Function shared.FunctionDefinition `json:"function,required"` + Function shared.FunctionDefinition `json:"function,omitzero,required"` // The type of tool being defined: `function` - Type FunctionToolType `json:"type,required"` - JSON functionToolJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + JSON struct { + Function resp.Field + Type resp.Field + raw string + } `json:"-"` } -// functionToolJSON contains the JSON metadata for the struct [FunctionTool] -type functionToolJSON struct { - Function apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FunctionTool) UnmarshalJSON(data []byte) (err error) { +func (r FunctionTool) RawJSON() string { return r.JSON.raw } +func (r *FunctionTool) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r functionToolJSON) RawJSON() string { - return r.raw -} - -func (r FunctionTool) implementsAssistantTool() {} - -// The type of tool being defined: `function` -type FunctionToolType string - -const ( - FunctionToolTypeFunction FunctionToolType = "function" -) - -func (r FunctionToolType) IsKnown() bool { - switch r { - case FunctionToolTypeFunction: - return true - } - return false +// ToParam converts this FunctionTool to a FunctionToolParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// FunctionToolParam.IsOverridden() +func (r FunctionTool) ToParam() FunctionToolParam { + return param.Override[FunctionToolParam](r.RawJSON()) } type FunctionToolParam struct { - Function param.Field[shared.FunctionDefinitionParam] `json:"function,required"` + Function shared.FunctionDefinitionParam `json:"function,omitzero,required"` // The type of tool being defined: `function` - Type param.Field[FunctionToolType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + apiobject } +func (f FunctionToolParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FunctionToolParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FunctionToolParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r FunctionToolParam) implementsAssistantToolUnionParam() {} - -func (r FunctionToolParam) implementsBetaThreadNewAndRunParamsToolUnion() {} - type BetaAssistantNewParams struct { // ID of the model to use. You can use the // [List models](https://platform.openai.com/docs/api-reference/models/list) API to // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. - Model param.Field[ChatModel] `json:"model,required"` + Model ChatModel `json:"model,omitzero,required"` // The description of the assistant. The maximum length is 512 characters. - Description param.Field[string] `json:"description"` + Description param.String `json:"description,omitzero"` // The system instructions that the assistant uses. The maximum length is 256,000 // characters. - Instructions param.Field[string] `json:"instructions"` + Instructions param.String `json:"instructions,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // The name of the assistant. The maximum length is 256 characters. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` // **o1 and o3-mini models only** // // Constrains effort on reasoning for // [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently // supported values are `low`, `medium`, and `high`. Reducing reasoning effort can // result in faster responses and fewer tokens used on reasoning in a response. - ReasoningEffort param.Field[BetaAssistantNewParamsReasoningEffort] `json:"reasoning_effort"` + // + // Any of "low", "medium", "high" + ReasoningEffort BetaAssistantNewParamsReasoningEffort `json:"reasoning_effort,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. - ToolResources param.Field[BetaAssistantNewParamsToolResources] `json:"tool_resources"` + ToolResources BetaAssistantNewParamsToolResources `json:"tool_resources,omitzero"` // A list of tool enabled on the assistant. There can be a maximum of 128 tools per // assistant. Tools can be of types `code_interpreter`, `file_search`, or // `function`. - Tools param.Field[[]AssistantToolUnionParam] `json:"tools"` + Tools []AssistantToolUnionParam `json:"tools,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or temperature but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` + apiobject } +func (f BetaAssistantNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaAssistantNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // **o1 and o3-mini models only** @@ -2128,36 +1573,40 @@ const ( BetaAssistantNewParamsReasoningEffortHigh BetaAssistantNewParamsReasoningEffort = "high" ) -func (r BetaAssistantNewParamsReasoningEffort) IsKnown() bool { - switch r { - case BetaAssistantNewParamsReasoningEffortLow, BetaAssistantNewParamsReasoningEffortMedium, BetaAssistantNewParamsReasoningEffortHigh: - return true - } - return false -} - // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. type BetaAssistantNewParamsToolResources struct { - CodeInterpreter param.Field[BetaAssistantNewParamsToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaAssistantNewParamsToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaAssistantNewParamsToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaAssistantNewParamsToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject +} + +func (f BetaAssistantNewParamsToolResources) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantNewParamsToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantNewParamsToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantNewParamsToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaAssistantNewParamsToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantNewParamsToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantNewParamsToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantNewParamsToolResourcesFileSearch struct { @@ -2165,90 +1614,108 @@ type BetaAssistantNewParamsToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this assistant. There can be a maximum of 1 vector store attached to // the assistant. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` // A helper to create a // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // with file_ids and attach it to this assistant. There can be a maximum of 1 // vector store attached to the assistant. - VectorStores param.Field[[]BetaAssistantNewParamsToolResourcesFileSearchVectorStore] `json:"vector_stores"` + VectorStores []BetaAssistantNewParamsToolResourcesFileSearchVectorStore `json:"vector_stores,omitzero"` + apiobject +} + +func (f BetaAssistantNewParamsToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantNewParamsToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantNewParamsToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantNewParamsToolResourcesFileSearchVectorStore struct { // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs to // add to the vector store. There can be a maximum of 10000 files in a vector // store. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject +} + +func (f BetaAssistantNewParamsToolResourcesFileSearchVectorStore) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantNewParamsToolResourcesFileSearchVectorStore) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantNewParamsToolResourcesFileSearchVectorStore + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantUpdateParams struct { // The description of the assistant. The maximum length is 512 characters. - Description param.Field[string] `json:"description"` + Description param.String `json:"description,omitzero"` // The system instructions that the assistant uses. The maximum length is 256,000 // characters. - Instructions param.Field[string] `json:"instructions"` + Instructions param.String `json:"instructions,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // ID of the model to use. You can use the // [List models](https://platform.openai.com/docs/api-reference/models/list) API to // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. - Model param.Field[BetaAssistantUpdateParamsModel] `json:"model"` + Model string `json:"model,omitzero"` // The name of the assistant. The maximum length is 256 characters. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` // **o1 and o3-mini models only** // // Constrains effort on reasoning for // [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently // supported values are `low`, `medium`, and `high`. Reducing reasoning effort can // result in faster responses and fewer tokens used on reasoning in a response. - ReasoningEffort param.Field[BetaAssistantUpdateParamsReasoningEffort] `json:"reasoning_effort"` + // + // Any of "low", "medium", "high" + ReasoningEffort BetaAssistantUpdateParamsReasoningEffort `json:"reasoning_effort,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. - ToolResources param.Field[BetaAssistantUpdateParamsToolResources] `json:"tool_resources"` + ToolResources BetaAssistantUpdateParamsToolResources `json:"tool_resources,omitzero"` // A list of tool enabled on the assistant. There can be a maximum of 128 tools per // assistant. Tools can be of types `code_interpreter`, `file_search`, or // `function`. - Tools param.Field[[]AssistantToolUnionParam] `json:"tools"` + Tools []AssistantToolUnionParam `json:"tools,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or temperature but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` + apiobject } +func (f BetaAssistantUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaAssistantUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } // ID of the model to use. You can use the @@ -2256,7 +1723,7 @@ func (r BetaAssistantUpdateParams) MarshalJSON() (data []byte, err error) { // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. -type BetaAssistantUpdateParamsModel string +type BetaAssistantUpdateParamsModel = string const ( BetaAssistantUpdateParamsModelO3Mini BetaAssistantUpdateParamsModel = "o3-mini" @@ -2289,14 +1756,6 @@ const ( BetaAssistantUpdateParamsModelGPT3_5Turbo16k0613 BetaAssistantUpdateParamsModel = "gpt-3.5-turbo-16k-0613" ) -func (r BetaAssistantUpdateParamsModel) IsKnown() bool { - switch r { - case BetaAssistantUpdateParamsModelO3Mini, BetaAssistantUpdateParamsModelO3Mini2025_01_31, BetaAssistantUpdateParamsModelO1, BetaAssistantUpdateParamsModelO1_2024_12_17, BetaAssistantUpdateParamsModelGPT4o, BetaAssistantUpdateParamsModelGPT4o2024_11_20, BetaAssistantUpdateParamsModelGPT4o2024_08_06, BetaAssistantUpdateParamsModelGPT4o2024_05_13, BetaAssistantUpdateParamsModelGPT4oMini, BetaAssistantUpdateParamsModelGPT4oMini2024_07_18, BetaAssistantUpdateParamsModelGPT4Turbo, BetaAssistantUpdateParamsModelGPT4Turbo2024_04_09, BetaAssistantUpdateParamsModelGPT4_0125Preview, BetaAssistantUpdateParamsModelGPT4TurboPreview, BetaAssistantUpdateParamsModelGPT4_1106Preview, BetaAssistantUpdateParamsModelGPT4VisionPreview, BetaAssistantUpdateParamsModelGPT4, BetaAssistantUpdateParamsModelGPT4_0314, BetaAssistantUpdateParamsModelGPT4_0613, BetaAssistantUpdateParamsModelGPT4_32k, BetaAssistantUpdateParamsModelGPT4_32k0314, BetaAssistantUpdateParamsModelGPT4_32k0613, BetaAssistantUpdateParamsModelGPT3_5Turbo, BetaAssistantUpdateParamsModelGPT3_5Turbo16k, BetaAssistantUpdateParamsModelGPT3_5Turbo0613, BetaAssistantUpdateParamsModelGPT3_5Turbo1106, BetaAssistantUpdateParamsModelGPT3_5Turbo0125, BetaAssistantUpdateParamsModelGPT3_5Turbo16k0613: - return true - } - return false -} - // **o1 and o3-mini models only** // // Constrains effort on reasoning for @@ -2311,25 +1770,23 @@ const ( BetaAssistantUpdateParamsReasoningEffortHigh BetaAssistantUpdateParamsReasoningEffort = "high" ) -func (r BetaAssistantUpdateParamsReasoningEffort) IsKnown() bool { - switch r { - case BetaAssistantUpdateParamsReasoningEffortLow, BetaAssistantUpdateParamsReasoningEffortMedium, BetaAssistantUpdateParamsReasoningEffortHigh: - return true - } - return false -} - // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. type BetaAssistantUpdateParamsToolResources struct { - CodeInterpreter param.Field[BetaAssistantUpdateParamsToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaAssistantUpdateParamsToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaAssistantUpdateParamsToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaAssistantUpdateParamsToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject +} + +func (f BetaAssistantUpdateParamsToolResources) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantUpdateParamsToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantUpdateParamsToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantUpdateParamsToolResourcesCodeInterpreter struct { @@ -2337,11 +1794,17 @@ type BetaAssistantUpdateParamsToolResourcesCodeInterpreter struct { // [file](https://platform.openai.com/docs/api-reference/files) IDs made available // to the `code_interpreter` tool. There can be a maximum of 20 files associated // with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaAssistantUpdateParamsToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantUpdateParamsToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantUpdateParamsToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantUpdateParamsToolResourcesFileSearch struct { @@ -2349,11 +1812,17 @@ type BetaAssistantUpdateParamsToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this assistant. There can be a maximum of 1 vector store attached to // the assistant. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` + apiobject +} + +func (f BetaAssistantUpdateParamsToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaAssistantUpdateParamsToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaAssistantUpdateParamsToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaAssistantListParams struct { @@ -2361,20 +1830,25 @@ type BetaAssistantListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaAssistantListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaAssistantListParamsOrder `query:"order,omitzero"` + apiobject } +func (f BetaAssistantListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaAssistantListParams]'s query parameters as // `url.Values`. func (r BetaAssistantListParams) URLQuery() (v url.Values) { @@ -2392,11 +1866,3 @@ const ( BetaAssistantListParamsOrderAsc BetaAssistantListParamsOrder = "asc" BetaAssistantListParamsOrderDesc BetaAssistantListParamsOrder = "desc" ) - -func (r BetaAssistantListParamsOrder) IsKnown() bool { - switch r { - case BetaAssistantListParamsOrderAsc, BetaAssistantListParamsOrderDesc: - return true - } - return false -} diff --git a/betaassistant_test.go b/betaassistant_test.go index 3131e3c..32d29b6 100644 --- a/betaassistant_test.go +++ b/betaassistant_test.go @@ -27,36 +27,36 @@ func TestBetaAssistantNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.Assistants.New(context.TODO(), openai.BetaAssistantNewParams{ - Model: openai.F(openai.ChatModelO3Mini), - Description: openai.F("description"), - Instructions: openai.F("instructions"), - Metadata: openai.F(shared.MetadataParam{ + Model: openai.ChatModelO3Mini, + Description: openai.String("description"), + Instructions: openai.String("instructions"), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Name: openai.F("name"), - ReasoningEffort: openai.F(openai.BetaAssistantNewParamsReasoningEffortLow), - Temperature: openai.F(1.000000), - ToolResources: openai.F(openai.BetaAssistantNewParamsToolResources{ - CodeInterpreter: openai.F(openai.BetaAssistantNewParamsToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaAssistantNewParamsToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - VectorStores: openai.F([]openai.BetaAssistantNewParamsToolResourcesFileSearchVectorStore{{ - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), - FileIDs: openai.F([]string{"string"}), - Metadata: openai.F(shared.MetadataParam{ + }, + Name: openai.String("name"), + ReasoningEffort: openai.BetaAssistantNewParamsReasoningEffortLow, + Temperature: openai.Float(1), + ToolResources: openai.BetaAssistantNewParamsToolResources{ + CodeInterpreter: openai.BetaAssistantNewParamsToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaAssistantNewParamsToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + VectorStores: []openai.BetaAssistantNewParamsToolResourcesFileSearchVectorStore{{ + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, + FileIDs: []string{"string"}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - }), - }), - Tools: openai.F([]openai.AssistantToolUnionParam{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - TopP: openai.F(1.000000), + }, + }}, + }, + }, + Tools: []openai.AssistantToolUnionParam{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + TopP: openai.Float(1), }) if err != nil { var apierr *openai.Error @@ -105,27 +105,27 @@ func TestBetaAssistantUpdateWithOptionalParams(t *testing.T) { context.TODO(), "assistant_id", openai.BetaAssistantUpdateParams{ - Description: openai.F("description"), - Instructions: openai.F("instructions"), - Metadata: openai.F(shared.MetadataParam{ + Description: openai.String("description"), + Instructions: openai.String("instructions"), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Model: openai.F(openai.BetaAssistantUpdateParamsModelO3Mini), - Name: openai.F("name"), - ReasoningEffort: openai.F(openai.BetaAssistantUpdateParamsReasoningEffortLow), - Temperature: openai.F(1.000000), - ToolResources: openai.F(openai.BetaAssistantUpdateParamsToolResources{ - CodeInterpreter: openai.F(openai.BetaAssistantUpdateParamsToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaAssistantUpdateParamsToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - }), - }), - Tools: openai.F([]openai.AssistantToolUnionParam{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - TopP: openai.F(1.000000), + }, + Model: "o3-mini", + Name: openai.String("name"), + ReasoningEffort: openai.BetaAssistantUpdateParamsReasoningEffortLow, + Temperature: openai.Float(1), + ToolResources: openai.BetaAssistantUpdateParamsToolResources{ + CodeInterpreter: openai.BetaAssistantUpdateParamsToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaAssistantUpdateParamsToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + }, + }, + Tools: []openai.AssistantToolUnionParam{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + TopP: openai.Float(1), }, ) if err != nil { @@ -150,10 +150,10 @@ func TestBetaAssistantListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.Assistants.List(context.TODO(), openai.BetaAssistantListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaAssistantListParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Limit: openai.Int(0), + Order: openai.BetaAssistantListParamsOrderAsc, }) if err != nil { var apierr *openai.Error diff --git a/betathread.go b/betathread.go index 88a9d18..108cb89 100644 --- a/betathread.go +++ b/betathread.go @@ -4,18 +4,19 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" - "reflect" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/packages/ssestream" "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/shared/constant" ) // BetaThreadService contains methods and other services that help with interacting @@ -26,15 +27,15 @@ import ( // the [NewBetaThreadService] method instead. type BetaThreadService struct { Options []option.RequestOption - Runs *BetaThreadRunService - Messages *BetaThreadMessageService + Runs BetaThreadRunService + Messages BetaThreadMessageService } // NewBetaThreadService generates a new service that applies the given options to // each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewBetaThreadService(opts ...option.RequestOption) (r *BetaThreadService) { - r = &BetaThreadService{} +func NewBetaThreadService(opts ...option.RequestOption) (r BetaThreadService) { + r = BetaThreadService{} r.Options = opts r.Runs = NewBetaThreadRunService(opts...) r.Messages = NewBetaThreadMessageService(opts...) @@ -99,7 +100,7 @@ func (r *BetaThreadService) NewAndRun(ctx context.Context, body BetaThreadNewAnd } // Create a thread and run it in one request. -func (r *BetaThreadService) NewAndRunStreaming(ctx context.Context, body BetaThreadNewAndRunParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEvent]) { +func (r *BetaThreadService) NewAndRunStreaming(ctx context.Context, body BetaThreadNewAndRunParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEventUnion]) { var ( raw *http.Response err error @@ -108,39 +109,40 @@ func (r *BetaThreadService) NewAndRunStreaming(ctx context.Context, body BetaThr opts = append([]option.RequestOption{option.WithHeader("OpenAI-Beta", "assistants=v2"), option.WithJSONSet("stream", true)}, opts...) path := "threads/runs" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &raw, opts...) - return ssestream.NewStream[AssistantStreamEvent](ssestream.NewDecoder(raw), err) + return ssestream.NewStream[AssistantStreamEventUnion](ssestream.NewDecoder(raw), err) } // Specifies a tool the model should use. Use to force the model to call a specific // tool. type AssistantToolChoice struct { // The type of the tool. If type is `function`, the function name must be set - Type AssistantToolChoiceType `json:"type,required"` - Function AssistantToolChoiceFunction `json:"function"` - JSON assistantToolChoiceJSON `json:"-"` + // + // Any of "function", "code_interpreter", "file_search" + Type string `json:"type,omitzero,required"` + Function AssistantToolChoiceFunction `json:"function,omitzero"` + JSON struct { + Type resp.Field + Function resp.Field + raw string + } `json:"-"` } -// assistantToolChoiceJSON contains the JSON metadata for the struct -// [AssistantToolChoice] -type assistantToolChoiceJSON struct { - Type apijson.Field - Function apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantToolChoice) UnmarshalJSON(data []byte) (err error) { +func (r AssistantToolChoice) RawJSON() string { return r.JSON.raw } +func (r *AssistantToolChoice) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantToolChoiceJSON) RawJSON() string { - return r.raw +// ToParam converts this AssistantToolChoice to a AssistantToolChoiceParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// AssistantToolChoiceParam.IsOverridden() +func (r AssistantToolChoice) ToParam() AssistantToolChoiceParam { + return param.Override[AssistantToolChoiceParam](r.RawJSON()) } -func (r AssistantToolChoice) implementsAssistantToolChoiceOptionUnion() {} - // The type of the tool. If type is `function`, the function name must be set -type AssistantToolChoiceType string +type AssistantToolChoiceType = string const ( AssistantToolChoiceTypeFunction AssistantToolChoiceType = "function" @@ -148,92 +150,104 @@ const ( AssistantToolChoiceTypeFileSearch AssistantToolChoiceType = "file_search" ) -func (r AssistantToolChoiceType) IsKnown() bool { - switch r { - case AssistantToolChoiceTypeFunction, AssistantToolChoiceTypeCodeInterpreter, AssistantToolChoiceTypeFileSearch: - return true - } - return false -} - // Specifies a tool the model should use. Use to force the model to call a specific // tool. type AssistantToolChoiceParam struct { // The type of the tool. If type is `function`, the function name must be set - Type param.Field[AssistantToolChoiceType] `json:"type,required"` - Function param.Field[AssistantToolChoiceFunctionParam] `json:"function"` + // + // Any of "function", "code_interpreter", "file_search" + Type string `json:"type,omitzero,required"` + Function AssistantToolChoiceFunctionParam `json:"function,omitzero"` + apiobject } +func (f AssistantToolChoiceParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AssistantToolChoiceParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow AssistantToolChoiceParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r AssistantToolChoiceParam) implementsAssistantToolChoiceOptionUnionParam() {} - type AssistantToolChoiceFunction struct { // The name of the function to call. - Name string `json:"name,required"` - JSON assistantToolChoiceFunctionJSON `json:"-"` + Name string `json:"name,omitzero,required"` + JSON struct { + Name resp.Field + raw string + } `json:"-"` } -// assistantToolChoiceFunctionJSON contains the JSON metadata for the struct -// [AssistantToolChoiceFunction] -type assistantToolChoiceFunctionJSON struct { - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *AssistantToolChoiceFunction) UnmarshalJSON(data []byte) (err error) { +func (r AssistantToolChoiceFunction) RawJSON() string { return r.JSON.raw } +func (r *AssistantToolChoiceFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r assistantToolChoiceFunctionJSON) RawJSON() string { - return r.raw +// ToParam converts this AssistantToolChoiceFunction to a +// AssistantToolChoiceFunctionParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// AssistantToolChoiceFunctionParam.IsOverridden() +func (r AssistantToolChoiceFunction) ToParam() AssistantToolChoiceFunctionParam { + return param.Override[AssistantToolChoiceFunctionParam](r.RawJSON()) } type AssistantToolChoiceFunctionParam struct { // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` + apiobject } +func (f AssistantToolChoiceFunctionParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AssistantToolChoiceFunctionParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow AssistantToolChoiceFunctionParam + return param.MarshalObject(r, (*shadow)(&r)) } -// Controls which (if any) tool is called by the model. `none` means the model will -// not call any tools and instead generates a message. `auto` is the default value -// and means the model can pick between generating a message or calling one or more -// tools. `required` means the model must call one or more tools before responding -// to the user. Specifying a particular tool like `{"type": "file_search"}` or -// `{"type": "function", "function": {"name": "my_function"}}` forces the model to -// call that tool. +type AssistantToolChoiceOptionUnion struct { + OfString string `json:",inline"` + Type string `json:"type"` + Function AssistantToolChoiceFunction `json:"function"` + JSON struct { + OfString resp.Field + Type resp.Field + Function resp.Field + raw string + } `json:"-"` +} + +func (u AssistantToolChoiceOptionUnion) AsAuto() (v string) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantToolChoiceOptionUnion) AsAssistantToolChoice() (v AssistantToolChoice) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u AssistantToolChoiceOptionUnion) RawJSON() string { return u.JSON.raw } + +func (r *AssistantToolChoiceOptionUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this AssistantToolChoiceOptionUnion to a +// AssistantToolChoiceOptionUnionParam. // -// Union satisfied by [AssistantToolChoiceOptionAuto] or [AssistantToolChoice]. -type AssistantToolChoiceOptionUnion interface { - implementsAssistantToolChoiceOptionUnion() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*AssistantToolChoiceOptionUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(AssistantToolChoiceOptionAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantToolChoice{}), - }, - ) +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// AssistantToolChoiceOptionUnionParam.IsOverridden() +func (r AssistantToolChoiceOptionUnion) ToParam() AssistantToolChoiceOptionUnionParam { + return param.Override[AssistantToolChoiceOptionUnionParam](r.RawJSON()) } // `none` means the model will not call any tools and instead generates a message. // `auto` means the model can pick between generating a message or calling one or // more tools. `required` means the model must call one or more tools before // responding to the user. -type AssistantToolChoiceOptionAuto string +type AssistantToolChoiceOptionAuto = string const ( AssistantToolChoiceOptionAutoNone AssistantToolChoiceOptionAuto = "none" @@ -241,223 +255,174 @@ const ( AssistantToolChoiceOptionAutoRequired AssistantToolChoiceOptionAuto = "required" ) -func (r AssistantToolChoiceOptionAuto) IsKnown() bool { - switch r { - case AssistantToolChoiceOptionAutoNone, AssistantToolChoiceOptionAutoAuto, AssistantToolChoiceOptionAutoRequired: - return true - } - return false +func NewAssistantToolChoiceOptionOfAssistantToolChoice(type_ string) AssistantToolChoiceOptionUnionParam { + var variant AssistantToolChoiceParam + variant.Type = type_ + return AssistantToolChoiceOptionUnionParam{OfAssistantToolChoice: &variant} } -func (r AssistantToolChoiceOptionAuto) implementsAssistantToolChoiceOptionUnion() {} +// Only one field can be non-zero +type AssistantToolChoiceOptionUnionParam struct { + // Check if union is this variant with !param.IsOmitted(union.OfAuto) + OfAuto string + OfAssistantToolChoice *AssistantToolChoiceParam + apiunion +} -func (r AssistantToolChoiceOptionAuto) implementsAssistantToolChoiceOptionUnionParam() {} +func (u AssistantToolChoiceOptionUnionParam) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() +} -// Controls which (if any) tool is called by the model. `none` means the model will -// not call any tools and instead generates a message. `auto` is the default value -// and means the model can pick between generating a message or calling one or more -// tools. `required` means the model must call one or more tools before responding -// to the user. Specifying a particular tool like `{"type": "file_search"}` or -// `{"type": "function", "function": {"name": "my_function"}}` forces the model to -// call that tool. -// -// Satisfied by [AssistantToolChoiceOptionAuto], [AssistantToolChoiceParam]. -type AssistantToolChoiceOptionUnionParam interface { - implementsAssistantToolChoiceOptionUnionParam() +func (u AssistantToolChoiceOptionUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[AssistantToolChoiceOptionUnionParam](u.OfAuto, u.OfAssistantToolChoice) +} + +func (u AssistantToolChoiceOptionUnionParam) GetType() *string { + if vt := u.OfAssistantToolChoice; vt != nil { + return &vt.Type + } + return nil +} + +func (u AssistantToolChoiceOptionUnionParam) GetFunction() *AssistantToolChoiceFunctionParam { + if vt := u.OfAssistantToolChoice; vt != nil { + return &vt.Function + } + return nil } // Represents a thread that contains // [messages](https://platform.openai.com/docs/api-reference/messages). type Thread struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the thread was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // The object type, which is always `thread`. - Object ThreadObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "thread". + Object constant.Thread `json:"object,required"` // A set of resources that are made available to the assistant's tools in this // thread. The resources are specific to the type of tool. For example, the // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. - ToolResources ThreadToolResources `json:"tool_resources,required,nullable"` - JSON threadJSON `json:"-"` + ToolResources ThreadToolResources `json:"tool_resources,omitzero,required,nullable"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + Metadata resp.Field + Object resp.Field + ToolResources resp.Field + raw string + } `json:"-"` } -// threadJSON contains the JSON metadata for the struct [Thread] -type threadJSON struct { - ID apijson.Field - CreatedAt apijson.Field - Metadata apijson.Field - Object apijson.Field - ToolResources apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Thread) UnmarshalJSON(data []byte) (err error) { +func (r Thread) RawJSON() string { return r.JSON.raw } +func (r *Thread) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r threadJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `thread`. -type ThreadObject string - -const ( - ThreadObjectThread ThreadObject = "thread" -) - -func (r ThreadObject) IsKnown() bool { - switch r { - case ThreadObjectThread: - return true - } - return false -} - // A set of resources that are made available to the assistant's tools in this // thread. The resources are specific to the type of tool. For example, the // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. type ThreadToolResources struct { - CodeInterpreter ThreadToolResourcesCodeInterpreter `json:"code_interpreter"` - FileSearch ThreadToolResourcesFileSearch `json:"file_search"` - JSON threadToolResourcesJSON `json:"-"` + CodeInterpreter ThreadToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch ThreadToolResourcesFileSearch `json:"file_search,omitzero"` + JSON struct { + CodeInterpreter resp.Field + FileSearch resp.Field + raw string + } `json:"-"` } -// threadToolResourcesJSON contains the JSON metadata for the struct -// [ThreadToolResources] -type threadToolResourcesJSON struct { - CodeInterpreter apijson.Field - FileSearch apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ThreadToolResources) UnmarshalJSON(data []byte) (err error) { +func (r ThreadToolResources) RawJSON() string { return r.JSON.raw } +func (r *ThreadToolResources) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r threadToolResourcesJSON) RawJSON() string { - return r.raw -} - type ThreadToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs []string `json:"file_ids"` - JSON threadToolResourcesCodeInterpreterJSON `json:"-"` + FileIDs []string `json:"file_ids,omitzero"` + JSON struct { + FileIDs resp.Field + raw string + } `json:"-"` } -// threadToolResourcesCodeInterpreterJSON contains the JSON metadata for the struct -// [ThreadToolResourcesCodeInterpreter] -type threadToolResourcesCodeInterpreterJSON struct { - FileIDs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ThreadToolResourcesCodeInterpreter) UnmarshalJSON(data []byte) (err error) { +func (r ThreadToolResourcesCodeInterpreter) RawJSON() string { return r.JSON.raw } +func (r *ThreadToolResourcesCodeInterpreter) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r threadToolResourcesCodeInterpreterJSON) RawJSON() string { - return r.raw -} - type ThreadToolResourcesFileSearch struct { // The // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this thread. There can be a maximum of 1 vector store attached to // the thread. - VectorStoreIDs []string `json:"vector_store_ids"` - JSON threadToolResourcesFileSearchJSON `json:"-"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` + JSON struct { + VectorStoreIDs resp.Field + raw string + } `json:"-"` } -// threadToolResourcesFileSearchJSON contains the JSON metadata for the struct -// [ThreadToolResourcesFileSearch] -type threadToolResourcesFileSearchJSON struct { - VectorStoreIDs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ThreadToolResourcesFileSearch) UnmarshalJSON(data []byte) (err error) { +func (r ThreadToolResourcesFileSearch) RawJSON() string { return r.JSON.raw } +func (r *ThreadToolResourcesFileSearch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r threadToolResourcesFileSearchJSON) RawJSON() string { - return r.raw -} - type ThreadDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object ThreadDeletedObject `json:"object,required"` - JSON threadDeletedJSON `json:"-"` + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as "thread.deleted". + Object constant.ThreadDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// threadDeletedJSON contains the JSON metadata for the struct [ThreadDeleted] -type threadDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ThreadDeleted) UnmarshalJSON(data []byte) (err error) { +func (r ThreadDeleted) RawJSON() string { return r.JSON.raw } +func (r *ThreadDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r threadDeletedJSON) RawJSON() string { - return r.raw -} - -type ThreadDeletedObject string - -const ( - ThreadDeletedObjectThreadDeleted ThreadDeletedObject = "thread.deleted" -) - -func (r ThreadDeletedObject) IsKnown() bool { - switch r { - case ThreadDeletedObjectThreadDeleted: - return true - } - return false -} - type BetaThreadNewParams struct { // A list of [messages](https://platform.openai.com/docs/api-reference/messages) to // start the thread with. - Messages param.Field[[]BetaThreadNewParamsMessage] `json:"messages"` + Messages []BetaThreadNewParamsMessage `json:"messages,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // A set of resources that are made available to the assistant's tools in this // thread. The resources are specific to the type of tool. For example, the // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. - ToolResources param.Field[BetaThreadNewParamsToolResources] `json:"tool_resources"` + ToolResources BetaThreadNewParamsToolResources `json:"tool_resources,omitzero"` + apiobject } +func (f BetaThreadNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewParamsMessage struct { @@ -465,27 +430,33 @@ type BetaThreadNewParamsMessage struct { // images can be passed with `image_url` or `image_file`. Image types are only // supported on // [Vision-compatible models](https://platform.openai.com/docs/models). - Content param.Field[[]MessageContentPartParamUnion] `json:"content,required"` + Content []MessageContentPartParamUnion `json:"content,omitzero,required"` // The role of the entity that is creating the message. Allowed values include: // // - `user`: Indicates the message is sent by an actual user and should be used in // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. - Role param.Field[BetaThreadNewParamsMessagesRole] `json:"role,required"` + // + // Any of "user", "assistant" + Role string `json:"role,omitzero,required"` // A list of files attached to the message, and the tools they should be added to. - Attachments param.Field[[]BetaThreadNewParamsMessagesAttachment] `json:"attachments"` + Attachments []BetaThreadNewParamsMessagesAttachment `json:"attachments,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject } +func (f BetaThreadNewParamsMessage) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadNewParamsMessage) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsMessage + return param.MarshalObject(r, (*shadow)(&r)) } // The role of the entity that is creating the message. Allowed values include: @@ -494,92 +465,69 @@ func (r BetaThreadNewParamsMessage) MarshalJSON() (data []byte, err error) { // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. -type BetaThreadNewParamsMessagesRole string +type BetaThreadNewParamsMessagesRole = string const ( BetaThreadNewParamsMessagesRoleUser BetaThreadNewParamsMessagesRole = "user" BetaThreadNewParamsMessagesRoleAssistant BetaThreadNewParamsMessagesRole = "assistant" ) -func (r BetaThreadNewParamsMessagesRole) IsKnown() bool { - switch r { - case BetaThreadNewParamsMessagesRoleUser, BetaThreadNewParamsMessagesRoleAssistant: - return true - } - return false -} - type BetaThreadNewParamsMessagesAttachment struct { // The ID of the file to attach to the message. - FileID param.Field[string] `json:"file_id"` + FileID param.String `json:"file_id,omitzero"` // The tools to add this file to. - Tools param.Field[[]BetaThreadNewParamsMessagesAttachmentsToolUnion] `json:"tools"` + Tools []BetaThreadNewParamsMessagesAttachmentsToolUnion `json:"tools,omitzero"` + apiobject +} + +func (f BetaThreadNewParamsMessagesAttachment) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewParamsMessagesAttachment) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsMessagesAttachment + return param.MarshalObject(r, (*shadow)(&r)) } -type BetaThreadNewParamsMessagesAttachmentsTool struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[BetaThreadNewParamsMessagesAttachmentsToolsType] `json:"type,required"` +// Only one field can be non-zero +type BetaThreadNewParamsMessagesAttachmentsToolUnion struct { + OfCodeInterpreter *CodeInterpreterToolParam + OfFileSearch *BetaThreadNewParamsMessagesAttachmentsToolsFileSearch + apiunion } -func (r BetaThreadNewParamsMessagesAttachmentsTool) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u BetaThreadNewParamsMessagesAttachmentsToolUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r BetaThreadNewParamsMessagesAttachmentsTool) implementsBetaThreadNewParamsMessagesAttachmentsToolUnion() { +func (u BetaThreadNewParamsMessagesAttachmentsToolUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[BetaThreadNewParamsMessagesAttachmentsToolUnion](u.OfCodeInterpreter, u.OfFileSearch) } -// Satisfied by [CodeInterpreterToolParam], -// [BetaThreadNewParamsMessagesAttachmentsToolsFileSearch], -// [BetaThreadNewParamsMessagesAttachmentsTool]. -type BetaThreadNewParamsMessagesAttachmentsToolUnion interface { - implementsBetaThreadNewParamsMessagesAttachmentsToolUnion() +func (u BetaThreadNewParamsMessagesAttachmentsToolUnion) GetType() *string { + if vt := u.OfCodeInterpreter; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearch; vt != nil { + return (*string)(&vt.Type) + } + return nil } type BetaThreadNewParamsMessagesAttachmentsToolsFileSearch struct { // The type of tool being defined: `file_search` - Type param.Field[BetaThreadNewParamsMessagesAttachmentsToolsFileSearchType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + apiobject +} + +func (f BetaThreadNewParamsMessagesAttachmentsToolsFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewParamsMessagesAttachmentsToolsFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r BetaThreadNewParamsMessagesAttachmentsToolsFileSearch) implementsBetaThreadNewParamsMessagesAttachmentsToolUnion() { -} - -// The type of tool being defined: `file_search` -type BetaThreadNewParamsMessagesAttachmentsToolsFileSearchType string - -const ( - BetaThreadNewParamsMessagesAttachmentsToolsFileSearchTypeFileSearch BetaThreadNewParamsMessagesAttachmentsToolsFileSearchType = "file_search" -) - -func (r BetaThreadNewParamsMessagesAttachmentsToolsFileSearchType) IsKnown() bool { - switch r { - case BetaThreadNewParamsMessagesAttachmentsToolsFileSearchTypeFileSearch: - return true - } - return false -} - -// The type of tool being defined: `code_interpreter` -type BetaThreadNewParamsMessagesAttachmentsToolsType string - -const ( - BetaThreadNewParamsMessagesAttachmentsToolsTypeCodeInterpreter BetaThreadNewParamsMessagesAttachmentsToolsType = "code_interpreter" - BetaThreadNewParamsMessagesAttachmentsToolsTypeFileSearch BetaThreadNewParamsMessagesAttachmentsToolsType = "file_search" -) - -func (r BetaThreadNewParamsMessagesAttachmentsToolsType) IsKnown() bool { - switch r { - case BetaThreadNewParamsMessagesAttachmentsToolsTypeCodeInterpreter, BetaThreadNewParamsMessagesAttachmentsToolsTypeFileSearch: - return true - } - return false + type shadow BetaThreadNewParamsMessagesAttachmentsToolsFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } // A set of resources that are made available to the assistant's tools in this @@ -587,23 +535,33 @@ func (r BetaThreadNewParamsMessagesAttachmentsToolsType) IsKnown() bool { // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. type BetaThreadNewParamsToolResources struct { - CodeInterpreter param.Field[BetaThreadNewParamsToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaThreadNewParamsToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaThreadNewParamsToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaThreadNewParamsToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject } +func (f BetaThreadNewParamsToolResources) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadNewParamsToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewParamsToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaThreadNewParamsToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewParamsToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewParamsToolResourcesFileSearch struct { @@ -611,37 +569,49 @@ type BetaThreadNewParamsToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this thread. There can be a maximum of 1 vector store attached to // the thread. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` // A helper to create a // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // with file_ids and attach it to this thread. There can be a maximum of 1 vector // store attached to the thread. - VectorStores param.Field[[]BetaThreadNewParamsToolResourcesFileSearchVectorStore] `json:"vector_stores"` + VectorStores []BetaThreadNewParamsToolResourcesFileSearchVectorStore `json:"vector_stores,omitzero"` + apiobject +} + +func (f BetaThreadNewParamsToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewParamsToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewParamsToolResourcesFileSearchVectorStore struct { // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs to // add to the vector store. There can be a maximum of 10000 files in a vector // store. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject +} + +func (f BetaThreadNewParamsToolResourcesFileSearchVectorStore) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewParamsToolResourcesFileSearchVectorStore) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewParamsToolResourcesFileSearchVectorStore + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadUpdateParams struct { @@ -651,16 +621,20 @@ type BetaThreadUpdateParams struct { // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // A set of resources that are made available to the assistant's tools in this // thread. The resources are specific to the type of tool. For example, the // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. - ToolResources param.Field[BetaThreadUpdateParamsToolResources] `json:"tool_resources"` + ToolResources BetaThreadUpdateParamsToolResources `json:"tool_resources,omitzero"` + apiobject } +func (f BetaThreadUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } // A set of resources that are made available to the assistant's tools in this @@ -668,23 +642,35 @@ func (r BetaThreadUpdateParams) MarshalJSON() (data []byte, err error) { // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. type BetaThreadUpdateParamsToolResources struct { - CodeInterpreter param.Field[BetaThreadUpdateParamsToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaThreadUpdateParamsToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaThreadUpdateParamsToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaThreadUpdateParamsToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject +} + +func (f BetaThreadUpdateParamsToolResources) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadUpdateParamsToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadUpdateParamsToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadUpdateParamsToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaThreadUpdateParamsToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadUpdateParamsToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadUpdateParamsToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadUpdateParamsToolResourcesFileSearch struct { @@ -692,56 +678,62 @@ type BetaThreadUpdateParamsToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this thread. There can be a maximum of 1 vector store attached to // the thread. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` + apiobject +} + +func (f BetaThreadUpdateParamsToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadUpdateParamsToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadUpdateParamsToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParams struct { // The ID of the // [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to // execute this run. - AssistantID param.Field[string] `json:"assistant_id,required"` + AssistantID param.String `json:"assistant_id,omitzero,required"` // Override the default system message of the assistant. This is useful for // modifying the behavior on a per-run basis. - Instructions param.Field[string] `json:"instructions"` + Instructions param.String `json:"instructions,omitzero"` // The maximum number of completion tokens that may be used over the course of the // run. The run will make a best effort to use only the number of completion tokens // specified, across multiple turns of the run. If the run exceeds the number of // completion tokens specified, the run will end with status `incomplete`. See // `incomplete_details` for more info. - MaxCompletionTokens param.Field[int64] `json:"max_completion_tokens"` + MaxCompletionTokens param.Int `json:"max_completion_tokens,omitzero"` // The maximum number of prompt tokens that may be used over the course of the run. // The run will make a best effort to use only the number of prompt tokens // specified, across multiple turns of the run. If the run exceeds the number of // prompt tokens specified, the run will end with status `incomplete`. See // `incomplete_details` for more info. - MaxPromptTokens param.Field[int64] `json:"max_prompt_tokens"` + MaxPromptTokens param.Int `json:"max_prompt_tokens,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to // be used to execute this run. If a value is provided here, it will override the // model associated with the assistant. If not, the model associated with the // assistant will be used. - Model param.Field[ChatModel] `json:"model"` + Model ChatModel `json:"model,omitzero"` // Whether to enable // [parallel function calling](https://platform.openai.com/docs/guides/function-calling#configuring-parallel-function-calling) // during tool use. - ParallelToolCalls param.Field[bool] `json:"parallel_tool_calls"` + ParallelToolCalls param.Bool `json:"parallel_tool_calls,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // Options to create a new thread. If no thread is provided when running a request, // an empty thread will be created. - Thread param.Field[BetaThreadNewAndRunParamsThread] `json:"thread"` + Thread BetaThreadNewAndRunParamsThread `json:"thread,omitzero"` // Controls which (if any) tool is called by the model. `none` means the model will // not call any tools and instead generates a message. `auto` is the default value // and means the model can pick between generating a message or calling one or more @@ -749,28 +741,32 @@ type BetaThreadNewAndRunParams struct { // to the user. Specifying a particular tool like `{"type": "file_search"}` or // `{"type": "function", "function": {"name": "my_function"}}` forces the model to // call that tool. - ToolChoice param.Field[AssistantToolChoiceOptionUnionParam] `json:"tool_choice"` + ToolChoice AssistantToolChoiceOptionUnionParam `json:"tool_choice,omitzero"` // A set of resources that are used by the assistant's tools. The resources are // specific to the type of tool. For example, the `code_interpreter` tool requires // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. - ToolResources param.Field[BetaThreadNewAndRunParamsToolResources] `json:"tool_resources"` + ToolResources BetaThreadNewAndRunParamsToolResources `json:"tool_resources,omitzero"` // Override the tools the assistant can use for this run. This is useful for // modifying the behavior on a per-run basis. - Tools param.Field[[]BetaThreadNewAndRunParamsToolUnion] `json:"tools"` + Tools []BetaThreadNewAndRunParamsToolUnion `json:"tools,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or temperature but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` // Controls for how a thread will be truncated prior to the run. Use this to // control the intial context window of the run. - TruncationStrategy param.Field[BetaThreadNewAndRunParamsTruncationStrategy] `json:"truncation_strategy"` + TruncationStrategy BetaThreadNewAndRunParamsTruncationStrategy `json:"truncation_strategy,omitzero"` + apiobject } +func (f BetaThreadNewAndRunParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadNewAndRunParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParams + return param.MarshalObject(r, (*shadow)(&r)) } // Options to create a new thread. If no thread is provided when running a request, @@ -778,23 +774,27 @@ func (r BetaThreadNewAndRunParams) MarshalJSON() (data []byte, err error) { type BetaThreadNewAndRunParamsThread struct { // A list of [messages](https://platform.openai.com/docs/api-reference/messages) to // start the thread with. - Messages param.Field[[]BetaThreadNewAndRunParamsThreadMessage] `json:"messages"` + Messages []BetaThreadNewAndRunParamsThreadMessage `json:"messages,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // A set of resources that are made available to the assistant's tools in this // thread. The resources are specific to the type of tool. For example, the // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. - ToolResources param.Field[BetaThreadNewAndRunParamsThreadToolResources] `json:"tool_resources"` + ToolResources BetaThreadNewAndRunParamsThreadToolResources `json:"tool_resources,omitzero"` + apiobject } +func (f BetaThreadNewAndRunParamsThread) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadNewAndRunParamsThread) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThread + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsThreadMessage struct { @@ -802,27 +802,35 @@ type BetaThreadNewAndRunParamsThreadMessage struct { // images can be passed with `image_url` or `image_file`. Image types are only // supported on // [Vision-compatible models](https://platform.openai.com/docs/models). - Content param.Field[[]MessageContentPartParamUnion] `json:"content,required"` + Content []MessageContentPartParamUnion `json:"content,omitzero,required"` // The role of the entity that is creating the message. Allowed values include: // // - `user`: Indicates the message is sent by an actual user and should be used in // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. - Role param.Field[BetaThreadNewAndRunParamsThreadMessagesRole] `json:"role,required"` + // + // Any of "user", "assistant" + Role string `json:"role,omitzero,required"` // A list of files attached to the message, and the tools they should be added to. - Attachments param.Field[[]BetaThreadNewAndRunParamsThreadMessagesAttachment] `json:"attachments"` + Attachments []BetaThreadNewAndRunParamsThreadMessagesAttachment `json:"attachments,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadMessage) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadMessage) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadMessage + return param.MarshalObject(r, (*shadow)(&r)) } // The role of the entity that is creating the message. Allowed values include: @@ -831,92 +839,69 @@ func (r BetaThreadNewAndRunParamsThreadMessage) MarshalJSON() (data []byte, err // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. -type BetaThreadNewAndRunParamsThreadMessagesRole string +type BetaThreadNewAndRunParamsThreadMessagesRole = string const ( BetaThreadNewAndRunParamsThreadMessagesRoleUser BetaThreadNewAndRunParamsThreadMessagesRole = "user" BetaThreadNewAndRunParamsThreadMessagesRoleAssistant BetaThreadNewAndRunParamsThreadMessagesRole = "assistant" ) -func (r BetaThreadNewAndRunParamsThreadMessagesRole) IsKnown() bool { - switch r { - case BetaThreadNewAndRunParamsThreadMessagesRoleUser, BetaThreadNewAndRunParamsThreadMessagesRoleAssistant: - return true - } - return false -} - type BetaThreadNewAndRunParamsThreadMessagesAttachment struct { // The ID of the file to attach to the message. - FileID param.Field[string] `json:"file_id"` + FileID param.String `json:"file_id,omitzero"` // The tools to add this file to. - Tools param.Field[[]BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion] `json:"tools"` + Tools []BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion `json:"tools,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadMessagesAttachment) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadMessagesAttachment) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadMessagesAttachment + return param.MarshalObject(r, (*shadow)(&r)) } -type BetaThreadNewAndRunParamsThreadMessagesAttachmentsTool struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType] `json:"type,required"` +// Only one field can be non-zero +type BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion struct { + OfCodeInterpreter *CodeInterpreterToolParam + OfFileSearch *BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch + apiunion } -func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsTool) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsTool) implementsBetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion() { +func (u BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion](u.OfCodeInterpreter, u.OfFileSearch) } -// Satisfied by [CodeInterpreterToolParam], -// [BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch], -// [BetaThreadNewAndRunParamsThreadMessagesAttachmentsTool]. -type BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion interface { - implementsBetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion() +func (u BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion) GetType() *string { + if vt := u.OfCodeInterpreter; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearch; vt != nil { + return (*string)(&vt.Type) + } + return nil } type BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch struct { // The type of tool being defined: `file_search` - Type param.Field[BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch) implementsBetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion() { -} - -// The type of tool being defined: `file_search` -type BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchType string - -const ( - BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchTypeFileSearch BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchType = "file_search" -) - -func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchType) IsKnown() bool { - switch r { - case BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearchTypeFileSearch: - return true - } - return false -} - -// The type of tool being defined: `code_interpreter` -type BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType string - -const ( - BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsTypeCodeInterpreter BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType = "code_interpreter" - BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsTypeFileSearch BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType = "file_search" -) - -func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType) IsKnown() bool { - switch r { - case BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsTypeCodeInterpreter, BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsTypeFileSearch: - return true - } - return false + type shadow BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } // A set of resources that are made available to the assistant's tools in this @@ -924,23 +909,35 @@ func (r BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolsType) IsKnown() b // `code_interpreter` tool requires a list of file IDs, while the `file_search` // tool requires a list of vector store IDs. type BetaThreadNewAndRunParamsThreadToolResources struct { - CodeInterpreter param.Field[BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaThreadNewAndRunParamsThreadToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaThreadNewAndRunParamsThreadToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadToolResources) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsThreadToolResourcesFileSearch struct { @@ -948,37 +945,49 @@ type BetaThreadNewAndRunParamsThreadToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this thread. There can be a maximum of 1 vector store attached to // the thread. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` // A helper to create a // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // with file_ids and attach it to this thread. There can be a maximum of 1 vector // store attached to the thread. - VectorStores param.Field[[]BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore] `json:"vector_stores"` + VectorStores []BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore `json:"vector_stores,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore struct { // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs to // add to the vector store. There can be a maximum of 10000 files in a vector // store. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore + return param.MarshalObject(r, (*shadow)(&r)) } // A set of resources that are used by the assistant's tools. The resources are @@ -986,23 +995,35 @@ func (r BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore) Marsh // a list of file IDs, while the `file_search` tool requires a list of vector store // IDs. type BetaThreadNewAndRunParamsToolResources struct { - CodeInterpreter param.Field[BetaThreadNewAndRunParamsToolResourcesCodeInterpreter] `json:"code_interpreter"` - FileSearch param.Field[BetaThreadNewAndRunParamsToolResourcesFileSearch] `json:"file_search"` + CodeInterpreter BetaThreadNewAndRunParamsToolResourcesCodeInterpreter `json:"code_interpreter,omitzero"` + FileSearch BetaThreadNewAndRunParamsToolResourcesFileSearch `json:"file_search,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsToolResources) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsToolResources) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsToolResources + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsToolResourcesCodeInterpreter struct { // A list of [file](https://platform.openai.com/docs/api-reference/files) IDs made // available to the `code_interpreter` tool. There can be a maximum of 20 files // associated with the tool. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsToolResourcesCodeInterpreter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsToolResourcesCodeInterpreter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsToolResourcesCodeInterpreter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadNewAndRunParamsToolResourcesFileSearch struct { @@ -1010,47 +1031,56 @@ type BetaThreadNewAndRunParamsToolResourcesFileSearch struct { // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // attached to this assistant. There can be a maximum of 1 vector store attached to // the assistant. - VectorStoreIDs param.Field[[]string] `json:"vector_store_ids"` + VectorStoreIDs []string `json:"vector_store_ids,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsToolResourcesFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsToolResourcesFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsToolResourcesFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } -type BetaThreadNewAndRunParamsTool struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[BetaThreadNewAndRunParamsToolsType] `json:"type,required"` - FileSearch param.Field[interface{}] `json:"file_search"` - Function param.Field[shared.FunctionDefinitionParam] `json:"function"` +// Only one field can be non-zero +type BetaThreadNewAndRunParamsToolUnion struct { + OfCodeInterpreterTool *CodeInterpreterToolParam + OfFileSearchTool *FileSearchToolParam + OfFunctionTool *FunctionToolParam + apiunion } -func (r BetaThreadNewAndRunParamsTool) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u BetaThreadNewAndRunParamsToolUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u BetaThreadNewAndRunParamsToolUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[BetaThreadNewAndRunParamsToolUnion](u.OfCodeInterpreterTool, u.OfFileSearchTool, u.OfFunctionTool) } -func (r BetaThreadNewAndRunParamsTool) implementsBetaThreadNewAndRunParamsToolUnion() {} - -// Satisfied by [CodeInterpreterToolParam], [FileSearchToolParam], -// [FunctionToolParam], [BetaThreadNewAndRunParamsTool]. -type BetaThreadNewAndRunParamsToolUnion interface { - implementsBetaThreadNewAndRunParamsToolUnion() -} - -// The type of tool being defined: `code_interpreter` -type BetaThreadNewAndRunParamsToolsType string - -const ( - BetaThreadNewAndRunParamsToolsTypeCodeInterpreter BetaThreadNewAndRunParamsToolsType = "code_interpreter" - BetaThreadNewAndRunParamsToolsTypeFileSearch BetaThreadNewAndRunParamsToolsType = "file_search" - BetaThreadNewAndRunParamsToolsTypeFunction BetaThreadNewAndRunParamsToolsType = "function" -) - -func (r BetaThreadNewAndRunParamsToolsType) IsKnown() bool { - switch r { - case BetaThreadNewAndRunParamsToolsTypeCodeInterpreter, BetaThreadNewAndRunParamsToolsTypeFileSearch, BetaThreadNewAndRunParamsToolsTypeFunction: - return true +func (u BetaThreadNewAndRunParamsToolUnion) GetFileSearch() *FileSearchToolFileSearchParam { + if vt := u.OfFileSearchTool; vt != nil { + return &vt.FileSearch } - return false + return nil +} + +func (u BetaThreadNewAndRunParamsToolUnion) GetFunction() *shared.FunctionDefinitionParam { + if vt := u.OfFunctionTool; vt != nil { + return &vt.Function + } + return nil +} + +func (u BetaThreadNewAndRunParamsToolUnion) GetType() *string { + if vt := u.OfCodeInterpreterTool; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearchTool; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFunctionTool; vt != nil { + return (*string)(&vt.Type) + } + return nil } // Controls for how a thread will be truncated prior to the run. Use this to @@ -1060,31 +1090,31 @@ type BetaThreadNewAndRunParamsTruncationStrategy struct { // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. - Type param.Field[BetaThreadNewAndRunParamsTruncationStrategyType] `json:"type,required"` + // + // Any of "auto", "last_messages" + Type string `json:"type,omitzero,required"` // The number of most recent messages from the thread when constructing the context // for the run. - LastMessages param.Field[int64] `json:"last_messages"` + LastMessages param.Int `json:"last_messages,omitzero"` + apiobject +} + +func (f BetaThreadNewAndRunParamsTruncationStrategy) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadNewAndRunParamsTruncationStrategy) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadNewAndRunParamsTruncationStrategy + return param.MarshalObject(r, (*shadow)(&r)) } // The truncation strategy to use for the thread. The default is `auto`. If set to // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. -type BetaThreadNewAndRunParamsTruncationStrategyType string +type BetaThreadNewAndRunParamsTruncationStrategyType = string const ( BetaThreadNewAndRunParamsTruncationStrategyTypeAuto BetaThreadNewAndRunParamsTruncationStrategyType = "auto" BetaThreadNewAndRunParamsTruncationStrategyTypeLastMessages BetaThreadNewAndRunParamsTruncationStrategyType = "last_messages" ) - -func (r BetaThreadNewAndRunParamsTruncationStrategyType) IsKnown() bool { - switch r { - case BetaThreadNewAndRunParamsTruncationStrategyTypeAuto, BetaThreadNewAndRunParamsTruncationStrategyTypeLastMessages: - return true - } - return false -} diff --git a/betathread_test.go b/betathread_test.go index b3f0cc8..c059e06 100644 --- a/betathread_test.go +++ b/betathread_test.go @@ -27,39 +27,41 @@ func TestBetaThreadNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.Threads.New(context.TODO(), openai.BetaThreadNewParams{ - Messages: openai.F([]openai.BetaThreadNewParamsMessage{{ - Content: openai.F([]openai.MessageContentPartParamUnion{openai.ImageFileContentBlockParam{ImageFile: openai.F(openai.ImageFileParam{FileID: openai.F("file_id"), Detail: openai.F(openai.ImageFileDetailAuto)}), Type: openai.F(openai.ImageFileContentBlockTypeImageFile)}}), - Role: openai.F(openai.BetaThreadNewParamsMessagesRoleUser), - Attachments: openai.F([]openai.BetaThreadNewParamsMessagesAttachment{{ - FileID: openai.F("file_id"), - Tools: openai.F([]openai.BetaThreadNewParamsMessagesAttachmentsToolUnion{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - }}), - Metadata: openai.F(shared.MetadataParam{ + Messages: []openai.BetaThreadNewParamsMessage{{ + Content: []openai.MessageContentPartParamUnion{{ + OfImageFile: &openai.ImageFileContentBlockParam{ImageFile: openai.ImageFileParam{FileID: openai.String("file_id"), Detail: "auto"}}, + }}, + Role: "user", + Attachments: []openai.BetaThreadNewParamsMessagesAttachment{{ + FileID: openai.String("file_id"), + Tools: []openai.BetaThreadNewParamsMessagesAttachmentsToolUnion{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - Metadata: openai.F(shared.MetadataParam{ + }, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - ToolResources: openai.F(openai.BetaThreadNewParamsToolResources{ - CodeInterpreter: openai.F(openai.BetaThreadNewParamsToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaThreadNewParamsToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - VectorStores: openai.F([]openai.BetaThreadNewParamsToolResourcesFileSearchVectorStore{{ - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), - FileIDs: openai.F([]string{"string"}), - Metadata: openai.F(shared.MetadataParam{ + }, + ToolResources: openai.BetaThreadNewParamsToolResources{ + CodeInterpreter: openai.BetaThreadNewParamsToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaThreadNewParamsToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + VectorStores: []openai.BetaThreadNewParamsToolResourcesFileSearchVectorStore{{ + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, + FileIDs: []string{"string"}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - }), - }), + }, + }}, + }, + }, }) if err != nil { var apierr *openai.Error @@ -108,17 +110,17 @@ func TestBetaThreadUpdateWithOptionalParams(t *testing.T) { context.TODO(), "thread_id", openai.BetaThreadUpdateParams{ - Metadata: openai.F(shared.MetadataParam{ + Metadata: shared.MetadataParam{ "foo": "string", - }), - ToolResources: openai.F(openai.BetaThreadUpdateParamsToolResources{ - CodeInterpreter: openai.F(openai.BetaThreadUpdateParamsToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaThreadUpdateParamsToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - }), - }), + }, + ToolResources: openai.BetaThreadUpdateParamsToolResources{ + CodeInterpreter: openai.BetaThreadUpdateParamsToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaThreadUpdateParamsToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + }, + }, }, ) if err != nil { @@ -165,68 +167,72 @@ func TestBetaThreadNewAndRunWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.Threads.NewAndRun(context.TODO(), openai.BetaThreadNewAndRunParams{ - AssistantID: openai.F("assistant_id"), - Instructions: openai.F("instructions"), - MaxCompletionTokens: openai.F(int64(256)), - MaxPromptTokens: openai.F(int64(256)), - Metadata: openai.F(shared.MetadataParam{ + AssistantID: openai.String("assistant_id"), + Instructions: openai.String("instructions"), + MaxCompletionTokens: openai.Int(256), + MaxPromptTokens: openai.Int(256), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Model: openai.F(openai.ChatModelO3Mini), - ParallelToolCalls: openai.F(true), - Temperature: openai.F(1.000000), - Thread: openai.F(openai.BetaThreadNewAndRunParamsThread{ - Messages: openai.F([]openai.BetaThreadNewAndRunParamsThreadMessage{{ - Content: openai.F([]openai.MessageContentPartParamUnion{openai.ImageFileContentBlockParam{ImageFile: openai.F(openai.ImageFileParam{FileID: openai.F("file_id"), Detail: openai.F(openai.ImageFileDetailAuto)}), Type: openai.F(openai.ImageFileContentBlockTypeImageFile)}}), - Role: openai.F(openai.BetaThreadNewAndRunParamsThreadMessagesRoleUser), - Attachments: openai.F([]openai.BetaThreadNewAndRunParamsThreadMessagesAttachment{{ - FileID: openai.F("file_id"), - Tools: openai.F([]openai.BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - }}), - Metadata: openai.F(shared.MetadataParam{ + }, + Model: openai.ChatModelO3Mini, + ParallelToolCalls: openai.Bool(true), + Temperature: openai.Float(1), + Thread: openai.BetaThreadNewAndRunParamsThread{ + Messages: []openai.BetaThreadNewAndRunParamsThreadMessage{{ + Content: []openai.MessageContentPartParamUnion{{ + OfImageFile: &openai.ImageFileContentBlockParam{ImageFile: openai.ImageFileParam{FileID: openai.String("file_id"), Detail: "auto"}}, + }}, + Role: "user", + Attachments: []openai.BetaThreadNewAndRunParamsThreadMessagesAttachment{{ + FileID: openai.String("file_id"), + Tools: []openai.BetaThreadNewAndRunParamsThreadMessagesAttachmentsToolUnion{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - Metadata: openai.F(shared.MetadataParam{ + }, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - ToolResources: openai.F(openai.BetaThreadNewAndRunParamsThreadToolResources{ - CodeInterpreter: openai.F(openai.BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaThreadNewAndRunParamsThreadToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - VectorStores: openai.F([]openai.BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore{{ - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), - FileIDs: openai.F([]string{"string"}), - Metadata: openai.F(shared.MetadataParam{ + }, + ToolResources: openai.BetaThreadNewAndRunParamsThreadToolResources{ + CodeInterpreter: openai.BetaThreadNewAndRunParamsThreadToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaThreadNewAndRunParamsThreadToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + VectorStores: []openai.BetaThreadNewAndRunParamsThreadToolResourcesFileSearchVectorStore{{ + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, + FileIDs: []string{"string"}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - }), - }), - }), - ToolChoice: openai.F[openai.AssistantToolChoiceOptionUnionParam](openai.AssistantToolChoiceOptionAuto(openai.AssistantToolChoiceOptionAutoNone)), - ToolResources: openai.F(openai.BetaThreadNewAndRunParamsToolResources{ - CodeInterpreter: openai.F(openai.BetaThreadNewAndRunParamsToolResourcesCodeInterpreter{ - FileIDs: openai.F([]string{"string"}), - }), - FileSearch: openai.F(openai.BetaThreadNewAndRunParamsToolResourcesFileSearch{ - VectorStoreIDs: openai.F([]string{"string"}), - }), - }), - Tools: openai.F([]openai.BetaThreadNewAndRunParamsToolUnion{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - TopP: openai.F(1.000000), - TruncationStrategy: openai.F(openai.BetaThreadNewAndRunParamsTruncationStrategy{ - Type: openai.F(openai.BetaThreadNewAndRunParamsTruncationStrategyTypeAuto), - LastMessages: openai.F(int64(1)), - }), + }, + }}, + }, + }, + }, + ToolChoice: openai.AssistantToolChoiceOptionUnionParam{ + OfAuto: "none", + }, + ToolResources: openai.BetaThreadNewAndRunParamsToolResources{ + CodeInterpreter: openai.BetaThreadNewAndRunParamsToolResourcesCodeInterpreter{ + FileIDs: []string{"string"}, + }, + FileSearch: openai.BetaThreadNewAndRunParamsToolResourcesFileSearch{ + VectorStoreIDs: []string{"string"}, + }, + }, + Tools: []openai.BetaThreadNewAndRunParamsToolUnion{{ + OfCodeInterpreterTool: &openai.CodeInterpreterToolParam{}, + }}, + TopP: openai.Float(1), + TruncationStrategy: openai.BetaThreadNewAndRunParamsTruncationStrategy{ + Type: "auto", + LastMessages: openai.Int(1), + }, }) if err != nil { var apierr *openai.Error diff --git a/betathreadmessage.go b/betathreadmessage.go index a62d134..0de44c3 100644 --- a/betathreadmessage.go +++ b/betathreadmessage.go @@ -4,20 +4,21 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" "net/url" - "reflect" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/shared/constant" ) // BetaThreadMessageService contains methods and other services that help with @@ -33,8 +34,8 @@ type BetaThreadMessageService struct { // NewBetaThreadMessageService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewBetaThreadMessageService(opts ...option.RequestOption) (r *BetaThreadMessageService) { - r = &BetaThreadMessageService{} +func NewBetaThreadMessageService(opts ...option.RequestOption) (r BetaThreadMessageService) { + r = BetaThreadMessageService{} r.Options = opts return } @@ -130,527 +131,325 @@ func (r *BetaThreadMessageService) Delete(ctx context.Context, threadID string, return } -// A citation within the message that points to a specific quote from a specific -// File associated with the assistant or the message. Generated when the assistant -// uses the "file_search" tool to search files. -type Annotation struct { - EndIndex int64 `json:"end_index,required"` - StartIndex int64 `json:"start_index,required"` - // The text in the message content that needs to be replaced. - Text string `json:"text,required"` - // Always `file_citation`. - Type AnnotationType `json:"type,required"` - // This field can have the runtime type of [FileCitationAnnotationFileCitation]. - FileCitation interface{} `json:"file_citation"` - // This field can have the runtime type of [FilePathAnnotationFilePath]. - FilePath interface{} `json:"file_path"` - JSON annotationJSON `json:"-"` - union AnnotationUnion +type AnnotationUnion struct { + EndIndex int64 `json:"end_index"` + FileCitation FileCitationAnnotationFileCitation `json:"file_citation"` + StartIndex int64 `json:"start_index"` + Text string `json:"text"` + Type string `json:"type"` + FilePath FilePathAnnotationFilePath `json:"file_path"` + JSON struct { + EndIndex resp.Field + FileCitation resp.Field + StartIndex resp.Field + Text resp.Field + Type resp.Field + FilePath resp.Field + raw string + } `json:"-"` } -// annotationJSON contains the JSON metadata for the struct [Annotation] -type annotationJSON struct { - EndIndex apijson.Field - StartIndex apijson.Field - Text apijson.Field - Type apijson.Field - FileCitation apijson.Field - FilePath apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r annotationJSON) RawJSON() string { - return r.raw -} - -func (r *Annotation) UnmarshalJSON(data []byte) (err error) { - *r = Annotation{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u AnnotationUnion) Variant() (res struct { + OfFileCitation *FileCitationAnnotation + OfFilePath *FilePathAnnotation +}) { + switch u.Type { + case "file_citation": + v := u.AsFileCitation() + res.OfFileCitation = &v + case "file_path": + v := u.AsFilePath() + res.OfFilePath = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [AnnotationUnion] interface which you can cast to the specific -// types for more type safety. -// -// Possible runtime types of the union are [FileCitationAnnotation], -// [FilePathAnnotation]. -func (r Annotation) AsUnion() AnnotationUnion { - return r.union +func (u AnnotationUnion) WhichKind() string { + return u.Type } -// A citation within the message that points to a specific quote from a specific -// File associated with the assistant or the message. Generated when the assistant -// uses the "file_search" tool to search files. -// -// Union satisfied by [FileCitationAnnotation] or [FilePathAnnotation]. -type AnnotationUnion interface { - implementsAnnotation() +func (u AnnotationUnion) AsFileCitation() (v FileCitationAnnotation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*AnnotationUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileCitationAnnotation{}), - DiscriminatorValue: "file_citation", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FilePathAnnotation{}), - DiscriminatorValue: "file_path", - }, - ) +func (u AnnotationUnion) AsFilePath() (v FilePathAnnotation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Always `file_citation`. -type AnnotationType string +func (u AnnotationUnion) RawJSON() string { return u.JSON.raw } -const ( - AnnotationTypeFileCitation AnnotationType = "file_citation" - AnnotationTypeFilePath AnnotationType = "file_path" -) +func (r *AnnotationUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r AnnotationType) IsKnown() bool { - switch r { - case AnnotationTypeFileCitation, AnnotationTypeFilePath: - return true +type AnnotationDeltaUnion struct { + Index int64 `json:"index"` + Type string `json:"type"` + EndIndex int64 `json:"end_index"` + FileCitation FileCitationDeltaAnnotationFileCitation `json:"file_citation"` + StartIndex int64 `json:"start_index"` + Text string `json:"text"` + FilePath FilePathDeltaAnnotationFilePath `json:"file_path"` + JSON struct { + Index resp.Field + Type resp.Field + EndIndex resp.Field + FileCitation resp.Field + StartIndex resp.Field + Text resp.Field + FilePath resp.Field + raw string + } `json:"-"` +} + +// note: this function is generated only for discriminated unions +func (u AnnotationDeltaUnion) Variant() (res struct { + OfFileCitation *FileCitationDeltaAnnotation + OfFilePath *FilePathDeltaAnnotation +}) { + switch u.Type { + case "file_citation": + v := u.AsFileCitation() + res.OfFileCitation = &v + case "file_path": + v := u.AsFilePath() + res.OfFilePath = &v } - return false + return } -// A citation within the message that points to a specific quote from a specific -// File associated with the assistant or the message. Generated when the assistant -// uses the "file_search" tool to search files. -type AnnotationDelta struct { - // The index of the annotation in the text content part. - Index int64 `json:"index,required"` - // Always `file_citation`. - Type AnnotationDeltaType `json:"type,required"` - EndIndex int64 `json:"end_index"` - // This field can have the runtime type of - // [FileCitationDeltaAnnotationFileCitation]. - FileCitation interface{} `json:"file_citation"` - // This field can have the runtime type of [FilePathDeltaAnnotationFilePath]. - FilePath interface{} `json:"file_path"` - StartIndex int64 `json:"start_index"` - // The text in the message content that needs to be replaced. - Text string `json:"text"` - JSON annotationDeltaJSON `json:"-"` - union AnnotationDeltaUnion +func (u AnnotationDeltaUnion) WhichKind() string { + return u.Type } -// annotationDeltaJSON contains the JSON metadata for the struct [AnnotationDelta] -type annotationDeltaJSON struct { - Index apijson.Field - Type apijson.Field - EndIndex apijson.Field - FileCitation apijson.Field - FilePath apijson.Field - StartIndex apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u AnnotationDeltaUnion) AsFileCitation() (v FileCitationDeltaAnnotation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r annotationDeltaJSON) RawJSON() string { - return r.raw +func (u AnnotationDeltaUnion) AsFilePath() (v FilePathDeltaAnnotation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *AnnotationDelta) UnmarshalJSON(data []byte) (err error) { - *r = AnnotationDelta{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) -} +func (u AnnotationDeltaUnion) RawJSON() string { return u.JSON.raw } -// AsUnion returns a [AnnotationDeltaUnion] interface which you can cast to the -// specific types for more type safety. -// -// Possible runtime types of the union are [FileCitationDeltaAnnotation], -// [FilePathDeltaAnnotation]. -func (r AnnotationDelta) AsUnion() AnnotationDeltaUnion { - return r.union -} - -// A citation within the message that points to a specific quote from a specific -// File associated with the assistant or the message. Generated when the assistant -// uses the "file_search" tool to search files. -// -// Union satisfied by [FileCitationDeltaAnnotation] or [FilePathDeltaAnnotation]. -type AnnotationDeltaUnion interface { - implementsAnnotationDelta() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*AnnotationDeltaUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileCitationDeltaAnnotation{}), - DiscriminatorValue: "file_citation", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FilePathDeltaAnnotation{}), - DiscriminatorValue: "file_path", - }, - ) -} - -// Always `file_citation`. -type AnnotationDeltaType string - -const ( - AnnotationDeltaTypeFileCitation AnnotationDeltaType = "file_citation" - AnnotationDeltaTypeFilePath AnnotationDeltaType = "file_path" -) - -func (r AnnotationDeltaType) IsKnown() bool { - switch r { - case AnnotationDeltaTypeFileCitation, AnnotationDeltaTypeFilePath: - return true - } - return false +func (r *AnnotationDeltaUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // A citation within the message that points to a specific quote from a specific // File associated with the assistant or the message. Generated when the assistant // uses the "file_search" tool to search files. type FileCitationAnnotation struct { - EndIndex int64 `json:"end_index,required"` - FileCitation FileCitationAnnotationFileCitation `json:"file_citation,required"` - StartIndex int64 `json:"start_index,required"` + EndIndex int64 `json:"end_index,omitzero,required"` + FileCitation FileCitationAnnotationFileCitation `json:"file_citation,omitzero,required"` + StartIndex int64 `json:"start_index,omitzero,required"` // The text in the message content that needs to be replaced. - Text string `json:"text,required"` + Text string `json:"text,omitzero,required"` // Always `file_citation`. - Type FileCitationAnnotationType `json:"type,required"` - JSON fileCitationAnnotationJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "file_citation". + Type constant.FileCitation `json:"type,required"` + JSON struct { + EndIndex resp.Field + FileCitation resp.Field + StartIndex resp.Field + Text resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fileCitationAnnotationJSON contains the JSON metadata for the struct -// [FileCitationAnnotation] -type fileCitationAnnotationJSON struct { - EndIndex apijson.Field - FileCitation apijson.Field - StartIndex apijson.Field - Text apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileCitationAnnotation) UnmarshalJSON(data []byte) (err error) { +func (r FileCitationAnnotation) RawJSON() string { return r.JSON.raw } +func (r *FileCitationAnnotation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileCitationAnnotationJSON) RawJSON() string { - return r.raw -} - -func (r FileCitationAnnotation) implementsAnnotation() {} - type FileCitationAnnotationFileCitation struct { // The ID of the specific File the citation is from. - FileID string `json:"file_id,required"` - JSON fileCitationAnnotationFileCitationJSON `json:"-"` + FileID string `json:"file_id,omitzero,required"` + JSON struct { + FileID resp.Field + raw string + } `json:"-"` } -// fileCitationAnnotationFileCitationJSON contains the JSON metadata for the struct -// [FileCitationAnnotationFileCitation] -type fileCitationAnnotationFileCitationJSON struct { - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileCitationAnnotationFileCitation) UnmarshalJSON(data []byte) (err error) { +func (r FileCitationAnnotationFileCitation) RawJSON() string { return r.JSON.raw } +func (r *FileCitationAnnotationFileCitation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileCitationAnnotationFileCitationJSON) RawJSON() string { - return r.raw -} - -// Always `file_citation`. -type FileCitationAnnotationType string - -const ( - FileCitationAnnotationTypeFileCitation FileCitationAnnotationType = "file_citation" -) - -func (r FileCitationAnnotationType) IsKnown() bool { - switch r { - case FileCitationAnnotationTypeFileCitation: - return true - } - return false -} - // A citation within the message that points to a specific quote from a specific // File associated with the assistant or the message. Generated when the assistant // uses the "file_search" tool to search files. type FileCitationDeltaAnnotation struct { // The index of the annotation in the text content part. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `file_citation`. - Type FileCitationDeltaAnnotationType `json:"type,required"` - EndIndex int64 `json:"end_index"` - FileCitation FileCitationDeltaAnnotationFileCitation `json:"file_citation"` - StartIndex int64 `json:"start_index"` + // + // This field can be elided, and will be automatically set as "file_citation". + Type constant.FileCitation `json:"type,required"` + EndIndex int64 `json:"end_index,omitzero"` + FileCitation FileCitationDeltaAnnotationFileCitation `json:"file_citation,omitzero"` + StartIndex int64 `json:"start_index,omitzero"` // The text in the message content that needs to be replaced. - Text string `json:"text"` - JSON fileCitationDeltaAnnotationJSON `json:"-"` + Text string `json:"text,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + EndIndex resp.Field + FileCitation resp.Field + StartIndex resp.Field + Text resp.Field + raw string + } `json:"-"` } -// fileCitationDeltaAnnotationJSON contains the JSON metadata for the struct -// [FileCitationDeltaAnnotation] -type fileCitationDeltaAnnotationJSON struct { - Index apijson.Field - Type apijson.Field - EndIndex apijson.Field - FileCitation apijson.Field - StartIndex apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileCitationDeltaAnnotation) UnmarshalJSON(data []byte) (err error) { +func (r FileCitationDeltaAnnotation) RawJSON() string { return r.JSON.raw } +func (r *FileCitationDeltaAnnotation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileCitationDeltaAnnotationJSON) RawJSON() string { - return r.raw -} - -func (r FileCitationDeltaAnnotation) implementsAnnotationDelta() {} - -// Always `file_citation`. -type FileCitationDeltaAnnotationType string - -const ( - FileCitationDeltaAnnotationTypeFileCitation FileCitationDeltaAnnotationType = "file_citation" -) - -func (r FileCitationDeltaAnnotationType) IsKnown() bool { - switch r { - case FileCitationDeltaAnnotationTypeFileCitation: - return true - } - return false -} - type FileCitationDeltaAnnotationFileCitation struct { // The ID of the specific File the citation is from. - FileID string `json:"file_id"` + FileID string `json:"file_id,omitzero"` // The specific quote in the file. - Quote string `json:"quote"` - JSON fileCitationDeltaAnnotationFileCitationJSON `json:"-"` + Quote string `json:"quote,omitzero"` + JSON struct { + FileID resp.Field + Quote resp.Field + raw string + } `json:"-"` } -// fileCitationDeltaAnnotationFileCitationJSON contains the JSON metadata for the -// struct [FileCitationDeltaAnnotationFileCitation] -type fileCitationDeltaAnnotationFileCitationJSON struct { - FileID apijson.Field - Quote apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileCitationDeltaAnnotationFileCitation) UnmarshalJSON(data []byte) (err error) { +func (r FileCitationDeltaAnnotationFileCitation) RawJSON() string { return r.JSON.raw } +func (r *FileCitationDeltaAnnotationFileCitation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileCitationDeltaAnnotationFileCitationJSON) RawJSON() string { - return r.raw -} - // A URL for the file that's generated when the assistant used the // `code_interpreter` tool to generate a file. type FilePathAnnotation struct { - EndIndex int64 `json:"end_index,required"` - FilePath FilePathAnnotationFilePath `json:"file_path,required"` - StartIndex int64 `json:"start_index,required"` + EndIndex int64 `json:"end_index,omitzero,required"` + FilePath FilePathAnnotationFilePath `json:"file_path,omitzero,required"` + StartIndex int64 `json:"start_index,omitzero,required"` // The text in the message content that needs to be replaced. - Text string `json:"text,required"` + Text string `json:"text,omitzero,required"` // Always `file_path`. - Type FilePathAnnotationType `json:"type,required"` - JSON filePathAnnotationJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "file_path". + Type constant.FilePath `json:"type,required"` + JSON struct { + EndIndex resp.Field + FilePath resp.Field + StartIndex resp.Field + Text resp.Field + Type resp.Field + raw string + } `json:"-"` } -// filePathAnnotationJSON contains the JSON metadata for the struct -// [FilePathAnnotation] -type filePathAnnotationJSON struct { - EndIndex apijson.Field - FilePath apijson.Field - StartIndex apijson.Field - Text apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FilePathAnnotation) UnmarshalJSON(data []byte) (err error) { +func (r FilePathAnnotation) RawJSON() string { return r.JSON.raw } +func (r *FilePathAnnotation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r filePathAnnotationJSON) RawJSON() string { - return r.raw -} - -func (r FilePathAnnotation) implementsAnnotation() {} - type FilePathAnnotationFilePath struct { // The ID of the file that was generated. - FileID string `json:"file_id,required"` - JSON filePathAnnotationFilePathJSON `json:"-"` + FileID string `json:"file_id,omitzero,required"` + JSON struct { + FileID resp.Field + raw string + } `json:"-"` } -// filePathAnnotationFilePathJSON contains the JSON metadata for the struct -// [FilePathAnnotationFilePath] -type filePathAnnotationFilePathJSON struct { - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FilePathAnnotationFilePath) UnmarshalJSON(data []byte) (err error) { +func (r FilePathAnnotationFilePath) RawJSON() string { return r.JSON.raw } +func (r *FilePathAnnotationFilePath) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r filePathAnnotationFilePathJSON) RawJSON() string { - return r.raw -} - -// Always `file_path`. -type FilePathAnnotationType string - -const ( - FilePathAnnotationTypeFilePath FilePathAnnotationType = "file_path" -) - -func (r FilePathAnnotationType) IsKnown() bool { - switch r { - case FilePathAnnotationTypeFilePath: - return true - } - return false -} - // A URL for the file that's generated when the assistant used the // `code_interpreter` tool to generate a file. type FilePathDeltaAnnotation struct { // The index of the annotation in the text content part. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `file_path`. - Type FilePathDeltaAnnotationType `json:"type,required"` - EndIndex int64 `json:"end_index"` - FilePath FilePathDeltaAnnotationFilePath `json:"file_path"` - StartIndex int64 `json:"start_index"` + // + // This field can be elided, and will be automatically set as "file_path". + Type constant.FilePath `json:"type,required"` + EndIndex int64 `json:"end_index,omitzero"` + FilePath FilePathDeltaAnnotationFilePath `json:"file_path,omitzero"` + StartIndex int64 `json:"start_index,omitzero"` // The text in the message content that needs to be replaced. - Text string `json:"text"` - JSON filePathDeltaAnnotationJSON `json:"-"` + Text string `json:"text,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + EndIndex resp.Field + FilePath resp.Field + StartIndex resp.Field + Text resp.Field + raw string + } `json:"-"` } -// filePathDeltaAnnotationJSON contains the JSON metadata for the struct -// [FilePathDeltaAnnotation] -type filePathDeltaAnnotationJSON struct { - Index apijson.Field - Type apijson.Field - EndIndex apijson.Field - FilePath apijson.Field - StartIndex apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FilePathDeltaAnnotation) UnmarshalJSON(data []byte) (err error) { +func (r FilePathDeltaAnnotation) RawJSON() string { return r.JSON.raw } +func (r *FilePathDeltaAnnotation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r filePathDeltaAnnotationJSON) RawJSON() string { - return r.raw -} - -func (r FilePathDeltaAnnotation) implementsAnnotationDelta() {} - -// Always `file_path`. -type FilePathDeltaAnnotationType string - -const ( - FilePathDeltaAnnotationTypeFilePath FilePathDeltaAnnotationType = "file_path" -) - -func (r FilePathDeltaAnnotationType) IsKnown() bool { - switch r { - case FilePathDeltaAnnotationTypeFilePath: - return true - } - return false -} - type FilePathDeltaAnnotationFilePath struct { // The ID of the file that was generated. - FileID string `json:"file_id"` - JSON filePathDeltaAnnotationFilePathJSON `json:"-"` + FileID string `json:"file_id,omitzero"` + JSON struct { + FileID resp.Field + raw string + } `json:"-"` } -// filePathDeltaAnnotationFilePathJSON contains the JSON metadata for the struct -// [FilePathDeltaAnnotationFilePath] -type filePathDeltaAnnotationFilePathJSON struct { - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FilePathDeltaAnnotationFilePath) UnmarshalJSON(data []byte) (err error) { +func (r FilePathDeltaAnnotationFilePath) RawJSON() string { return r.JSON.raw } +func (r *FilePathDeltaAnnotationFilePath) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r filePathDeltaAnnotationFilePathJSON) RawJSON() string { - return r.raw -} - type ImageFile struct { // The [File](https://platform.openai.com/docs/api-reference/files) ID of the image // in the message content. Set `purpose="vision"` when uploading the File if you // need to later display the file content. - FileID string `json:"file_id,required"` + FileID string `json:"file_id,omitzero,required"` // Specifies the detail level of the image if specified by the user. `low` uses // fewer tokens, you can opt in to high resolution using `high`. - Detail ImageFileDetail `json:"detail"` - JSON imageFileJSON `json:"-"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` + JSON struct { + FileID resp.Field + Detail resp.Field + raw string + } `json:"-"` } -// imageFileJSON contains the JSON metadata for the struct [ImageFile] -type imageFileJSON struct { - FileID apijson.Field - Detail apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageFile) UnmarshalJSON(data []byte) (err error) { +func (r ImageFile) RawJSON() string { return r.JSON.raw } +func (r *ImageFile) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageFileJSON) RawJSON() string { - return r.raw +// ToParam converts this ImageFile to a ImageFileParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ImageFileParam.IsOverridden() +func (r ImageFile) ToParam() ImageFileParam { + return param.Override[ImageFileParam](r.RawJSON()) } // Specifies the detail level of the image if specified by the user. `low` uses // fewer tokens, you can opt in to high resolution using `high`. -type ImageFileDetail string +type ImageFileDetail = string const ( ImageFileDetailAuto ImageFileDetail = "auto" @@ -658,115 +457,98 @@ const ( ImageFileDetailHigh ImageFileDetail = "high" ) -func (r ImageFileDetail) IsKnown() bool { - switch r { - case ImageFileDetailAuto, ImageFileDetailLow, ImageFileDetailHigh: - return true - } - return false -} - type ImageFileParam struct { // The [File](https://platform.openai.com/docs/api-reference/files) ID of the image // in the message content. Set `purpose="vision"` when uploading the File if you // need to later display the file content. - FileID param.Field[string] `json:"file_id,required"` + FileID param.String `json:"file_id,omitzero,required"` // Specifies the detail level of the image if specified by the user. `low` uses // fewer tokens, you can opt in to high resolution using `high`. - Detail param.Field[ImageFileDetail] `json:"detail"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` + apiobject } +func (f ImageFileParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageFileParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ImageFileParam + return param.MarshalObject(r, (*shadow)(&r)) } // References an image [File](https://platform.openai.com/docs/api-reference/files) // in the content of a message. type ImageFileContentBlock struct { - ImageFile ImageFile `json:"image_file,required"` + ImageFile ImageFile `json:"image_file,omitzero,required"` // Always `image_file`. - Type ImageFileContentBlockType `json:"type,required"` - JSON imageFileContentBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image_file". + Type constant.ImageFile `json:"type,required"` + JSON struct { + ImageFile resp.Field + Type resp.Field + raw string + } `json:"-"` } -// imageFileContentBlockJSON contains the JSON metadata for the struct -// [ImageFileContentBlock] -type imageFileContentBlockJSON struct { - ImageFile apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageFileContentBlock) UnmarshalJSON(data []byte) (err error) { +func (r ImageFileContentBlock) RawJSON() string { return r.JSON.raw } +func (r *ImageFileContentBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageFileContentBlockJSON) RawJSON() string { - return r.raw -} - -func (r ImageFileContentBlock) implementsMessageContent() {} - -// Always `image_file`. -type ImageFileContentBlockType string - -const ( - ImageFileContentBlockTypeImageFile ImageFileContentBlockType = "image_file" -) - -func (r ImageFileContentBlockType) IsKnown() bool { - switch r { - case ImageFileContentBlockTypeImageFile: - return true - } - return false +// ToParam converts this ImageFileContentBlock to a ImageFileContentBlockParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ImageFileContentBlockParam.IsOverridden() +func (r ImageFileContentBlock) ToParam() ImageFileContentBlockParam { + return param.Override[ImageFileContentBlockParam](r.RawJSON()) } // References an image [File](https://platform.openai.com/docs/api-reference/files) // in the content of a message. type ImageFileContentBlockParam struct { - ImageFile param.Field[ImageFileParam] `json:"image_file,required"` + ImageFile ImageFileParam `json:"image_file,omitzero,required"` // Always `image_file`. - Type param.Field[ImageFileContentBlockType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "image_file". + Type constant.ImageFile `json:"type,required"` + apiobject } +func (f ImageFileContentBlockParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageFileContentBlockParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ImageFileContentBlockParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ImageFileContentBlockParam) implementsMessageContentPartParamUnion() {} - type ImageFileDelta struct { // Specifies the detail level of the image if specified by the user. `low` uses // fewer tokens, you can opt in to high resolution using `high`. - Detail ImageFileDeltaDetail `json:"detail"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` // The [File](https://platform.openai.com/docs/api-reference/files) ID of the image // in the message content. Set `purpose="vision"` when uploading the File if you // need to later display the file content. - FileID string `json:"file_id"` - JSON imageFileDeltaJSON `json:"-"` + FileID string `json:"file_id,omitzero"` + JSON struct { + Detail resp.Field + FileID resp.Field + raw string + } `json:"-"` } -// imageFileDeltaJSON contains the JSON metadata for the struct [ImageFileDelta] -type imageFileDeltaJSON struct { - Detail apijson.Field - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageFileDelta) UnmarshalJSON(data []byte) (err error) { +func (r ImageFileDelta) RawJSON() string { return r.JSON.raw } +func (r *ImageFileDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageFileDeltaJSON) RawJSON() string { - return r.raw -} - // Specifies the detail level of the image if specified by the user. `low` uses // fewer tokens, you can opt in to high resolution using `high`. -type ImageFileDeltaDetail string +type ImageFileDeltaDetail = string const ( ImageFileDeltaDetailAuto ImageFileDeltaDetail = "auto" @@ -774,89 +556,62 @@ const ( ImageFileDeltaDetailHigh ImageFileDeltaDetail = "high" ) -func (r ImageFileDeltaDetail) IsKnown() bool { - switch r { - case ImageFileDeltaDetailAuto, ImageFileDeltaDetailLow, ImageFileDeltaDetailHigh: - return true - } - return false -} - // References an image [File](https://platform.openai.com/docs/api-reference/files) // in the content of a message. type ImageFileDeltaBlock struct { // The index of the content part in the message. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `image_file`. - Type ImageFileDeltaBlockType `json:"type,required"` - ImageFile ImageFileDelta `json:"image_file"` - JSON imageFileDeltaBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image_file". + Type constant.ImageFile `json:"type,required"` + ImageFile ImageFileDelta `json:"image_file,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + ImageFile resp.Field + raw string + } `json:"-"` } -// imageFileDeltaBlockJSON contains the JSON metadata for the struct -// [ImageFileDeltaBlock] -type imageFileDeltaBlockJSON struct { - Index apijson.Field - Type apijson.Field - ImageFile apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageFileDeltaBlock) UnmarshalJSON(data []byte) (err error) { +func (r ImageFileDeltaBlock) RawJSON() string { return r.JSON.raw } +func (r *ImageFileDeltaBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageFileDeltaBlockJSON) RawJSON() string { - return r.raw -} - -func (r ImageFileDeltaBlock) implementsMessageContentDelta() {} - -// Always `image_file`. -type ImageFileDeltaBlockType string - -const ( - ImageFileDeltaBlockTypeImageFile ImageFileDeltaBlockType = "image_file" -) - -func (r ImageFileDeltaBlockType) IsKnown() bool { - switch r { - case ImageFileDeltaBlockTypeImageFile: - return true - } - return false -} - type ImageURL struct { // The external URL of the image, must be a supported image types: jpeg, jpg, png, // gif, webp. - URL string `json:"url,required" format:"uri"` + URL string `json:"url,omitzero,required" format:"uri"` // Specifies the detail level of the image. `low` uses fewer tokens, you can opt in // to high resolution using `high`. Default value is `auto` - Detail ImageURLDetail `json:"detail"` - JSON imageURLJSON `json:"-"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` + JSON struct { + URL resp.Field + Detail resp.Field + raw string + } `json:"-"` } -// imageURLJSON contains the JSON metadata for the struct [ImageURL] -type imageURLJSON struct { - URL apijson.Field - Detail apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageURL) UnmarshalJSON(data []byte) (err error) { +func (r ImageURL) RawJSON() string { return r.JSON.raw } +func (r *ImageURL) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageURLJSON) RawJSON() string { - return r.raw +// ToParam converts this ImageURL to a ImageURLParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ImageURLParam.IsOverridden() +func (r ImageURL) ToParam() ImageURLParam { + return param.Override[ImageURLParam](r.RawJSON()) } // Specifies the detail level of the image. `low` uses fewer tokens, you can opt in // to high resolution using `high`. Default value is `auto` -type ImageURLDetail string +type ImageURLDetail = string const ( ImageURLDetailAuto ImageURLDetail = "auto" @@ -864,111 +619,94 @@ const ( ImageURLDetailHigh ImageURLDetail = "high" ) -func (r ImageURLDetail) IsKnown() bool { - switch r { - case ImageURLDetailAuto, ImageURLDetailLow, ImageURLDetailHigh: - return true - } - return false -} - type ImageURLParam struct { // The external URL of the image, must be a supported image types: jpeg, jpg, png, // gif, webp. - URL param.Field[string] `json:"url,required" format:"uri"` + URL param.String `json:"url,omitzero,required" format:"uri"` // Specifies the detail level of the image. `low` uses fewer tokens, you can opt in // to high resolution using `high`. Default value is `auto` - Detail param.Field[ImageURLDetail] `json:"detail"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` + apiobject } +func (f ImageURLParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageURLParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ImageURLParam + return param.MarshalObject(r, (*shadow)(&r)) } // References an image URL in the content of a message. type ImageURLContentBlock struct { - ImageURL ImageURL `json:"image_url,required"` + ImageURL ImageURL `json:"image_url,omitzero,required"` // The type of the content part. - Type ImageURLContentBlockType `json:"type,required"` - JSON imageURLContentBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image_url". + Type constant.ImageURL `json:"type,required"` + JSON struct { + ImageURL resp.Field + Type resp.Field + raw string + } `json:"-"` } -// imageURLContentBlockJSON contains the JSON metadata for the struct -// [ImageURLContentBlock] -type imageURLContentBlockJSON struct { - ImageURL apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageURLContentBlock) UnmarshalJSON(data []byte) (err error) { +func (r ImageURLContentBlock) RawJSON() string { return r.JSON.raw } +func (r *ImageURLContentBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageURLContentBlockJSON) RawJSON() string { - return r.raw -} - -func (r ImageURLContentBlock) implementsMessageContent() {} - -// The type of the content part. -type ImageURLContentBlockType string - -const ( - ImageURLContentBlockTypeImageURL ImageURLContentBlockType = "image_url" -) - -func (r ImageURLContentBlockType) IsKnown() bool { - switch r { - case ImageURLContentBlockTypeImageURL: - return true - } - return false +// ToParam converts this ImageURLContentBlock to a ImageURLContentBlockParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ImageURLContentBlockParam.IsOverridden() +func (r ImageURLContentBlock) ToParam() ImageURLContentBlockParam { + return param.Override[ImageURLContentBlockParam](r.RawJSON()) } // References an image URL in the content of a message. type ImageURLContentBlockParam struct { - ImageURL param.Field[ImageURLParam] `json:"image_url,required"` + ImageURL ImageURLParam `json:"image_url,omitzero,required"` // The type of the content part. - Type param.Field[ImageURLContentBlockType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "image_url". + Type constant.ImageURL `json:"type,required"` + apiobject } +func (f ImageURLContentBlockParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageURLContentBlockParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ImageURLContentBlockParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ImageURLContentBlockParam) implementsMessageContentPartParamUnion() {} - type ImageURLDelta struct { // Specifies the detail level of the image. `low` uses fewer tokens, you can opt in // to high resolution using `high`. - Detail ImageURLDeltaDetail `json:"detail"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` // The URL of the image, must be a supported image types: jpeg, jpg, png, gif, // webp. - URL string `json:"url"` - JSON imageURLDeltaJSON `json:"-"` + URL string `json:"url,omitzero"` + JSON struct { + Detail resp.Field + URL resp.Field + raw string + } `json:"-"` } -// imageURLDeltaJSON contains the JSON metadata for the struct [ImageURLDelta] -type imageURLDeltaJSON struct { - Detail apijson.Field - URL apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageURLDelta) UnmarshalJSON(data []byte) (err error) { +func (r ImageURLDelta) RawJSON() string { return r.JSON.raw } +func (r *ImageURLDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageURLDeltaJSON) RawJSON() string { - return r.raw -} - // Specifies the detail level of the image. `low` uses fewer tokens, you can opt in // to high resolution using `high`. -type ImageURLDeltaDetail string +type ImageURLDeltaDetail = string const ( ImageURLDeltaDetailAuto ImageURLDeltaDetail = "auto" @@ -976,296 +714,177 @@ const ( ImageURLDeltaDetailHigh ImageURLDeltaDetail = "high" ) -func (r ImageURLDeltaDetail) IsKnown() bool { - switch r { - case ImageURLDeltaDetailAuto, ImageURLDeltaDetailLow, ImageURLDeltaDetailHigh: - return true - } - return false -} - // References an image URL in the content of a message. type ImageURLDeltaBlock struct { // The index of the content part in the message. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `image_url`. - Type ImageURLDeltaBlockType `json:"type,required"` - ImageURL ImageURLDelta `json:"image_url"` - JSON imageURLDeltaBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image_url". + Type constant.ImageURL `json:"type,required"` + ImageURL ImageURLDelta `json:"image_url,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + ImageURL resp.Field + raw string + } `json:"-"` } -// imageURLDeltaBlockJSON contains the JSON metadata for the struct -// [ImageURLDeltaBlock] -type imageURLDeltaBlockJSON struct { - Index apijson.Field - Type apijson.Field - ImageURL apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImageURLDeltaBlock) UnmarshalJSON(data []byte) (err error) { +func (r ImageURLDeltaBlock) RawJSON() string { return r.JSON.raw } +func (r *ImageURLDeltaBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageURLDeltaBlockJSON) RawJSON() string { - return r.raw -} - -func (r ImageURLDeltaBlock) implementsMessageContentDelta() {} - -// Always `image_url`. -type ImageURLDeltaBlockType string - -const ( - ImageURLDeltaBlockTypeImageURL ImageURLDeltaBlockType = "image_url" -) - -func (r ImageURLDeltaBlockType) IsKnown() bool { - switch r { - case ImageURLDeltaBlockTypeImageURL: - return true - } - return false -} - // Represents a message within a // [thread](https://platform.openai.com/docs/api-reference/threads). type Message struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // If applicable, the ID of the // [assistant](https://platform.openai.com/docs/api-reference/assistants) that // authored this message. - AssistantID string `json:"assistant_id,required,nullable"` + AssistantID string `json:"assistant_id,omitzero,required,nullable"` // A list of files attached to the message, and the tools they were added to. - Attachments []MessageAttachment `json:"attachments,required,nullable"` + Attachments []MessageAttachment `json:"attachments,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the message was completed. - CompletedAt int64 `json:"completed_at,required,nullable"` + CompletedAt int64 `json:"completed_at,omitzero,required,nullable"` // The content of the message in array of text and/or images. - Content []MessageContent `json:"content,required"` + Content []MessageContentUnion `json:"content,omitzero,required"` // The Unix timestamp (in seconds) for when the message was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The Unix timestamp (in seconds) for when the message was marked as incomplete. - IncompleteAt int64 `json:"incomplete_at,required,nullable"` + IncompleteAt int64 `json:"incomplete_at,omitzero,required,nullable"` // On an incomplete message, details about why the message is incomplete. - IncompleteDetails MessageIncompleteDetails `json:"incomplete_details,required,nullable"` + IncompleteDetails MessageIncompleteDetails `json:"incomplete_details,omitzero,required,nullable"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // The object type, which is always `thread.message`. - Object MessageObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "thread.message". + Object constant.ThreadMessage `json:"object,required"` // The entity that produced the message. One of `user` or `assistant`. - Role MessageRole `json:"role,required"` + // + // Any of "user", "assistant" + Role string `json:"role,omitzero,required"` // The ID of the [run](https://platform.openai.com/docs/api-reference/runs) // associated with the creation of this message. Value is `null` when messages are // created manually using the create message or create thread endpoints. - RunID string `json:"run_id,required,nullable"` + RunID string `json:"run_id,omitzero,required,nullable"` // The status of the message, which can be either `in_progress`, `incomplete`, or // `completed`. - Status MessageStatus `json:"status,required"` + // + // Any of "in_progress", "incomplete", "completed" + Status string `json:"status,omitzero,required"` // The [thread](https://platform.openai.com/docs/api-reference/threads) ID that // this message belongs to. - ThreadID string `json:"thread_id,required"` - JSON messageJSON `json:"-"` + ThreadID string `json:"thread_id,omitzero,required"` + JSON struct { + ID resp.Field + AssistantID resp.Field + Attachments resp.Field + CompletedAt resp.Field + Content resp.Field + CreatedAt resp.Field + IncompleteAt resp.Field + IncompleteDetails resp.Field + Metadata resp.Field + Object resp.Field + Role resp.Field + RunID resp.Field + Status resp.Field + ThreadID resp.Field + raw string + } `json:"-"` } -// messageJSON contains the JSON metadata for the struct [Message] -type messageJSON struct { - ID apijson.Field - AssistantID apijson.Field - Attachments apijson.Field - CompletedAt apijson.Field - Content apijson.Field - CreatedAt apijson.Field - IncompleteAt apijson.Field - IncompleteDetails apijson.Field - Metadata apijson.Field - Object apijson.Field - Role apijson.Field - RunID apijson.Field - Status apijson.Field - ThreadID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Message) UnmarshalJSON(data []byte) (err error) { +func (r Message) RawJSON() string { return r.JSON.raw } +func (r *Message) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageJSON) RawJSON() string { - return r.raw -} - type MessageAttachment struct { // The ID of the file to attach to the message. - FileID string `json:"file_id"` + FileID string `json:"file_id,omitzero"` // The tools to add this file to. - Tools []MessageAttachmentsTool `json:"tools"` - JSON messageAttachmentJSON `json:"-"` + Tools []MessageAttachmentsToolsUnion `json:"tools,omitzero"` + JSON struct { + FileID resp.Field + Tools resp.Field + raw string + } `json:"-"` } -// messageAttachmentJSON contains the JSON metadata for the struct -// [MessageAttachment] -type messageAttachmentJSON struct { - FileID apijson.Field - Tools apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageAttachment) UnmarshalJSON(data []byte) (err error) { +func (r MessageAttachment) RawJSON() string { return r.JSON.raw } +func (r *MessageAttachment) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageAttachmentJSON) RawJSON() string { - return r.raw +type MessageAttachmentsToolsUnion struct { + Type string `json:"type"` + JSON struct { + Type resp.Field + raw string + } `json:"-"` } -type MessageAttachmentsTool struct { - // The type of tool being defined: `code_interpreter` - Type MessageAttachmentsToolsType `json:"type,required"` - JSON messageAttachmentsToolJSON `json:"-"` - union MessageAttachmentsToolsUnion +func (u MessageAttachmentsToolsUnion) AsCodeInterpreterTool() (v CodeInterpreterTool) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// messageAttachmentsToolJSON contains the JSON metadata for the struct -// [MessageAttachmentsTool] -type messageAttachmentsToolJSON struct { - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u MessageAttachmentsToolsUnion) AsFileSearchTool() (v MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r messageAttachmentsToolJSON) RawJSON() string { - return r.raw -} +func (u MessageAttachmentsToolsUnion) RawJSON() string { return u.JSON.raw } -func (r *MessageAttachmentsTool) UnmarshalJSON(data []byte) (err error) { - *r = MessageAttachmentsTool{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) -} - -// AsUnion returns a [MessageAttachmentsToolsUnion] interface which you can cast to -// the specific types for more type safety. -// -// Possible runtime types of the union are [CodeInterpreterTool], -// [MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly]. -func (r MessageAttachmentsTool) AsUnion() MessageAttachmentsToolsUnion { - return r.union -} - -// Union satisfied by [CodeInterpreterTool] or -// [MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly]. -type MessageAttachmentsToolsUnion interface { - implementsMessageAttachmentsTool() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*MessageAttachmentsToolsUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterTool{}), - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly{}), - }, - ) +func (r *MessageAttachmentsToolsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } type MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly struct { // The type of tool being defined: `file_search` - Type MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyType `json:"type,required"` - JSON messageAttachmentsToolsAssistantToolsFileSearchTypeOnlyJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + JSON struct { + Type resp.Field + raw string + } `json:"-"` } -// messageAttachmentsToolsAssistantToolsFileSearchTypeOnlyJSON contains the JSON -// metadata for the struct -// [MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly] -type messageAttachmentsToolsAssistantToolsFileSearchTypeOnlyJSON struct { - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly) UnmarshalJSON(data []byte) (err error) { +func (r MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly) RawJSON() string { return r.JSON.raw } +func (r *MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageAttachmentsToolsAssistantToolsFileSearchTypeOnlyJSON) RawJSON() string { - return r.raw -} - -func (r MessageAttachmentsToolsAssistantToolsFileSearchTypeOnly) implementsMessageAttachmentsTool() {} - -// The type of tool being defined: `file_search` -type MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyType string - -const ( - MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyTypeFileSearch MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyType = "file_search" -) - -func (r MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyType) IsKnown() bool { - switch r { - case MessageAttachmentsToolsAssistantToolsFileSearchTypeOnlyTypeFileSearch: - return true - } - return false -} - -// The type of tool being defined: `code_interpreter` -type MessageAttachmentsToolsType string - -const ( - MessageAttachmentsToolsTypeCodeInterpreter MessageAttachmentsToolsType = "code_interpreter" - MessageAttachmentsToolsTypeFileSearch MessageAttachmentsToolsType = "file_search" -) - -func (r MessageAttachmentsToolsType) IsKnown() bool { - switch r { - case MessageAttachmentsToolsTypeCodeInterpreter, MessageAttachmentsToolsTypeFileSearch: - return true - } - return false -} - // On an incomplete message, details about why the message is incomplete. type MessageIncompleteDetails struct { // The reason the message is incomplete. - Reason MessageIncompleteDetailsReason `json:"reason,required"` - JSON messageIncompleteDetailsJSON `json:"-"` + // + // Any of "content_filter", "max_tokens", "run_cancelled", "run_expired", + // "run_failed" + Reason string `json:"reason,omitzero,required"` + JSON struct { + Reason resp.Field + raw string + } `json:"-"` } -// messageIncompleteDetailsJSON contains the JSON metadata for the struct -// [MessageIncompleteDetails] -type messageIncompleteDetailsJSON struct { - Reason apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageIncompleteDetails) UnmarshalJSON(data []byte) (err error) { +func (r MessageIncompleteDetails) RawJSON() string { return r.JSON.raw } +func (r *MessageIncompleteDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageIncompleteDetailsJSON) RawJSON() string { - return r.raw -} - // The reason the message is incomplete. -type MessageIncompleteDetailsReason string +type MessageIncompleteDetailsReason = string const ( MessageIncompleteDetailsReasonContentFilter MessageIncompleteDetailsReason = "content_filter" @@ -1275,48 +894,17 @@ const ( MessageIncompleteDetailsReasonRunFailed MessageIncompleteDetailsReason = "run_failed" ) -func (r MessageIncompleteDetailsReason) IsKnown() bool { - switch r { - case MessageIncompleteDetailsReasonContentFilter, MessageIncompleteDetailsReasonMaxTokens, MessageIncompleteDetailsReasonRunCancelled, MessageIncompleteDetailsReasonRunExpired, MessageIncompleteDetailsReasonRunFailed: - return true - } - return false -} - -// The object type, which is always `thread.message`. -type MessageObject string - -const ( - MessageObjectThreadMessage MessageObject = "thread.message" -) - -func (r MessageObject) IsKnown() bool { - switch r { - case MessageObjectThreadMessage: - return true - } - return false -} - // The entity that produced the message. One of `user` or `assistant`. -type MessageRole string +type MessageRole = string const ( MessageRoleUser MessageRole = "user" MessageRoleAssistant MessageRole = "assistant" ) -func (r MessageRole) IsKnown() bool { - switch r { - case MessageRoleUser, MessageRoleAssistant: - return true - } - return false -} - // The status of the message, which can be either `in_progress`, `incomplete`, or // `completed`. -type MessageStatus string +type MessageStatus = string const ( MessageStatusInProgress MessageStatus = "in_progress" @@ -1324,659 +912,448 @@ const ( MessageStatusCompleted MessageStatus = "completed" ) -func (r MessageStatus) IsKnown() bool { - switch r { - case MessageStatusInProgress, MessageStatusIncomplete, MessageStatusCompleted: - return true +type MessageContentUnion struct { + ImageFile ImageFile `json:"image_file"` + Type string `json:"type"` + ImageURL ImageURL `json:"image_url"` + Text Text `json:"text"` + Refusal string `json:"refusal"` + JSON struct { + ImageFile resp.Field + Type resp.Field + ImageURL resp.Field + Text resp.Field + Refusal resp.Field + raw string + } `json:"-"` +} + +// note: this function is generated only for discriminated unions +func (u MessageContentUnion) Variant() (res struct { + OfImageFile *ImageFileContentBlock + OfImageURL *ImageURLContentBlock + OfText *TextContentBlock + OfRefusal *RefusalContentBlock +}) { + switch u.Type { + case "image_file": + v := u.AsImageFile() + res.OfImageFile = &v + case "image_url": + v := u.AsImageURL() + res.OfImageURL = &v + case "text": + v := u.AsText() + res.OfText = &v + case "refusal": + v := u.AsRefusal() + res.OfRefusal = &v } - return false + return } -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -type MessageContent struct { - // Always `image_file`. - Type MessageContentType `json:"type,required"` - ImageFile ImageFile `json:"image_file"` - ImageURL ImageURL `json:"image_url"` - Refusal string `json:"refusal"` - Text Text `json:"text"` - JSON messageContentJSON `json:"-"` - union MessageContentUnion +func (u MessageContentUnion) WhichKind() string { + return u.Type } -// messageContentJSON contains the JSON metadata for the struct [MessageContent] -type messageContentJSON struct { - Type apijson.Field - ImageFile apijson.Field - ImageURL apijson.Field - Refusal apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u MessageContentUnion) AsImageFile() (v ImageFileContentBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r messageContentJSON) RawJSON() string { - return r.raw +func (u MessageContentUnion) AsImageURL() (v ImageURLContentBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *MessageContent) UnmarshalJSON(data []byte) (err error) { - *r = MessageContent{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) +func (u MessageContentUnion) AsText() (v TextContentBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// AsUnion returns a [MessageContentUnion] interface which you can cast to the -// specific types for more type safety. -// -// Possible runtime types of the union are [ImageFileContentBlock], -// [ImageURLContentBlock], [TextContentBlock], [RefusalContentBlock]. -func (r MessageContent) AsUnion() MessageContentUnion { - return r.union +func (u MessageContentUnion) AsRefusal() (v RefusalContentBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -// -// Union satisfied by [ImageFileContentBlock], [ImageURLContentBlock], -// [TextContentBlock] or [RefusalContentBlock]. -type MessageContentUnion interface { - implementsMessageContent() -} +func (u MessageContentUnion) RawJSON() string { return u.JSON.raw } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*MessageContentUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ImageFileContentBlock{}), - DiscriminatorValue: "image_file", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ImageURLContentBlock{}), - DiscriminatorValue: "image_url", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(TextContentBlock{}), - DiscriminatorValue: "text", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(RefusalContentBlock{}), - DiscriminatorValue: "refusal", - }, - ) -} - -// Always `image_file`. -type MessageContentType string - -const ( - MessageContentTypeImageFile MessageContentType = "image_file" - MessageContentTypeImageURL MessageContentType = "image_url" - MessageContentTypeText MessageContentType = "text" - MessageContentTypeRefusal MessageContentType = "refusal" -) - -func (r MessageContentType) IsKnown() bool { - switch r { - case MessageContentTypeImageFile, MessageContentTypeImageURL, MessageContentTypeText, MessageContentTypeRefusal: - return true - } - return false -} - -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -type MessageContentDelta struct { - // The index of the content part in the message. - Index int64 `json:"index,required"` - // Always `image_file`. - Type MessageContentDeltaType `json:"type,required"` - ImageFile ImageFileDelta `json:"image_file"` - ImageURL ImageURLDelta `json:"image_url"` - Refusal string `json:"refusal"` - Text TextDelta `json:"text"` - JSON messageContentDeltaJSON `json:"-"` - union MessageContentDeltaUnion -} - -// messageContentDeltaJSON contains the JSON metadata for the struct -// [MessageContentDelta] -type messageContentDeltaJSON struct { - Index apijson.Field - Type apijson.Field - ImageFile apijson.Field - ImageURL apijson.Field - Refusal apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r messageContentDeltaJSON) RawJSON() string { - return r.raw -} - -func (r *MessageContentDelta) UnmarshalJSON(data []byte) (err error) { - *r = MessageContentDelta{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) -} - -// AsUnion returns a [MessageContentDeltaUnion] interface which you can cast to the -// specific types for more type safety. -// -// Possible runtime types of the union are [ImageFileDeltaBlock], [TextDeltaBlock], -// [RefusalDeltaBlock], [ImageURLDeltaBlock]. -func (r MessageContentDelta) AsUnion() MessageContentDeltaUnion { - return r.union -} - -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -// -// Union satisfied by [ImageFileDeltaBlock], [TextDeltaBlock], [RefusalDeltaBlock] -// or [ImageURLDeltaBlock]. -type MessageContentDeltaUnion interface { - implementsMessageContentDelta() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*MessageContentDeltaUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ImageFileDeltaBlock{}), - DiscriminatorValue: "image_file", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(TextDeltaBlock{}), - DiscriminatorValue: "text", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(RefusalDeltaBlock{}), - DiscriminatorValue: "refusal", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ImageURLDeltaBlock{}), - DiscriminatorValue: "image_url", - }, - ) -} - -// Always `image_file`. -type MessageContentDeltaType string - -const ( - MessageContentDeltaTypeImageFile MessageContentDeltaType = "image_file" - MessageContentDeltaTypeText MessageContentDeltaType = "text" - MessageContentDeltaTypeRefusal MessageContentDeltaType = "refusal" - MessageContentDeltaTypeImageURL MessageContentDeltaType = "image_url" -) - -func (r MessageContentDeltaType) IsKnown() bool { - switch r { - case MessageContentDeltaTypeImageFile, MessageContentDeltaTypeText, MessageContentDeltaTypeRefusal, MessageContentDeltaTypeImageURL: - return true - } - return false -} - -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -type MessageContentPartParam struct { - // Always `image_file`. - Type param.Field[MessageContentPartParamType] `json:"type,required"` - ImageFile param.Field[ImageFileParam] `json:"image_file"` - ImageURL param.Field[ImageURLParam] `json:"image_url"` - // Text content to be sent to the model - Text param.Field[string] `json:"text"` -} - -func (r MessageContentPartParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r MessageContentPartParam) implementsMessageContentPartParamUnion() {} - -// References an image [File](https://platform.openai.com/docs/api-reference/files) -// in the content of a message. -// -// Satisfied by [ImageFileContentBlockParam], [ImageURLContentBlockParam], -// [TextContentBlockParam], [MessageContentPartParam]. -type MessageContentPartParamUnion interface { - implementsMessageContentPartParamUnion() -} - -// Always `image_file`. -type MessageContentPartParamType string - -const ( - MessageContentPartParamTypeImageFile MessageContentPartParamType = "image_file" - MessageContentPartParamTypeImageURL MessageContentPartParamType = "image_url" - MessageContentPartParamTypeText MessageContentPartParamType = "text" -) - -func (r MessageContentPartParamType) IsKnown() bool { - switch r { - case MessageContentPartParamTypeImageFile, MessageContentPartParamTypeImageURL, MessageContentPartParamTypeText: - return true - } - return false -} - -type MessageDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object MessageDeletedObject `json:"object,required"` - JSON messageDeletedJSON `json:"-"` -} - -// messageDeletedJSON contains the JSON metadata for the struct [MessageDeleted] -type messageDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageDeleted) UnmarshalJSON(data []byte) (err error) { +func (r *MessageContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageDeletedJSON) RawJSON() string { - return r.raw +type MessageContentDeltaUnion struct { + Index int64 `json:"index"` + Type string `json:"type"` + ImageFile ImageFileDelta `json:"image_file"` + Text TextDelta `json:"text"` + Refusal string `json:"refusal"` + ImageURL ImageURLDelta `json:"image_url"` + JSON struct { + Index resp.Field + Type resp.Field + ImageFile resp.Field + Text resp.Field + Refusal resp.Field + ImageURL resp.Field + raw string + } `json:"-"` } -type MessageDeletedObject string - -const ( - MessageDeletedObjectThreadMessageDeleted MessageDeletedObject = "thread.message.deleted" -) - -func (r MessageDeletedObject) IsKnown() bool { - switch r { - case MessageDeletedObjectThreadMessageDeleted: - return true +// note: this function is generated only for discriminated unions +func (u MessageContentDeltaUnion) Variant() (res struct { + OfImageFile *ImageFileDeltaBlock + OfText *TextDeltaBlock + OfRefusal *RefusalDeltaBlock + OfImageURL *ImageURLDeltaBlock +}) { + switch u.Type { + case "image_file": + v := u.AsImageFile() + res.OfImageFile = &v + case "text": + v := u.AsText() + res.OfText = &v + case "refusal": + v := u.AsRefusal() + res.OfRefusal = &v + case "image_url": + v := u.AsImageURL() + res.OfImageURL = &v } - return false + return +} + +func (u MessageContentDeltaUnion) WhichKind() string { + return u.Type +} + +func (u MessageContentDeltaUnion) AsImageFile() (v ImageFileDeltaBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageContentDeltaUnion) AsText() (v TextDeltaBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageContentDeltaUnion) AsRefusal() (v RefusalDeltaBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageContentDeltaUnion) AsImageURL() (v ImageURLDeltaBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageContentDeltaUnion) RawJSON() string { return u.JSON.raw } + +func (r *MessageContentDeltaUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +func NewMessageContentPartParamOfImageFile(imageFile ImageFileParam) MessageContentPartParamUnion { + var image_file ImageFileContentBlockParam + image_file.ImageFile = imageFile + return MessageContentPartParamUnion{OfImageFile: &image_file} +} + +func NewMessageContentPartParamOfImageURL(imageURL ImageURLParam) MessageContentPartParamUnion { + var image_url ImageURLContentBlockParam + image_url.ImageURL = imageURL + return MessageContentPartParamUnion{OfImageURL: &image_url} +} + +func NewMessageContentPartParamOfText(text string) MessageContentPartParamUnion { + var variant TextContentBlockParam + variant.Text = newString(text) + return MessageContentPartParamUnion{OfText: &variant} +} + +// Only one field can be non-zero +type MessageContentPartParamUnion struct { + OfImageFile *ImageFileContentBlockParam + OfImageURL *ImageURLContentBlockParam + OfText *TextContentBlockParam + apiunion +} + +func (u MessageContentPartParamUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u MessageContentPartParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[MessageContentPartParamUnion](u.OfImageFile, u.OfImageURL, u.OfText) +} + +func (u MessageContentPartParamUnion) GetImageFile() *ImageFileParam { + if vt := u.OfImageFile; vt != nil { + return &vt.ImageFile + } + return nil +} + +func (u MessageContentPartParamUnion) GetImageURL() *ImageURLParam { + if vt := u.OfImageURL; vt != nil { + return &vt.ImageURL + } + return nil +} + +func (u MessageContentPartParamUnion) GetText() *string { + if vt := u.OfText; vt != nil && !vt.Text.IsOmitted() { + return &vt.Text.V + } + return nil +} + +func (u MessageContentPartParamUnion) GetType() *string { + if vt := u.OfImageFile; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfImageURL; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type MessageDeleted struct { + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as + // "thread.message.deleted". + Object constant.ThreadMessageDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` +} + +func (r MessageDeleted) RawJSON() string { return r.JSON.raw } +func (r *MessageDeleted) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The delta containing the fields that have changed on the Message. type MessageDelta struct { // The content of the message in array of text and/or images. - Content []MessageContentDelta `json:"content"` + Content []MessageContentDeltaUnion `json:"content,omitzero"` // The entity that produced the message. One of `user` or `assistant`. - Role MessageDeltaRole `json:"role"` - JSON messageDeltaJSON `json:"-"` + // + // Any of "user", "assistant" + Role string `json:"role,omitzero"` + JSON struct { + Content resp.Field + Role resp.Field + raw string + } `json:"-"` } -// messageDeltaJSON contains the JSON metadata for the struct [MessageDelta] -type messageDeltaJSON struct { - Content apijson.Field - Role apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageDelta) UnmarshalJSON(data []byte) (err error) { +func (r MessageDelta) RawJSON() string { return r.JSON.raw } +func (r *MessageDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageDeltaJSON) RawJSON() string { - return r.raw -} - // The entity that produced the message. One of `user` or `assistant`. -type MessageDeltaRole string +type MessageDeltaRole = string const ( MessageDeltaRoleUser MessageDeltaRole = "user" MessageDeltaRoleAssistant MessageDeltaRole = "assistant" ) -func (r MessageDeltaRole) IsKnown() bool { - switch r { - case MessageDeltaRoleUser, MessageDeltaRoleAssistant: - return true - } - return false -} - // Represents a message delta i.e. any changed fields on a message during // streaming. type MessageDeltaEvent struct { // The identifier of the message, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The delta containing the fields that have changed on the Message. - Delta MessageDelta `json:"delta,required"` + Delta MessageDelta `json:"delta,omitzero,required"` // The object type, which is always `thread.message.delta`. - Object MessageDeltaEventObject `json:"object,required"` - JSON messageDeltaEventJSON `json:"-"` + // + // This field can be elided, and will be automatically set as + // "thread.message.delta". + Object constant.ThreadMessageDelta `json:"object,required"` + JSON struct { + ID resp.Field + Delta resp.Field + Object resp.Field + raw string + } `json:"-"` } -// messageDeltaEventJSON contains the JSON metadata for the struct -// [MessageDeltaEvent] -type messageDeltaEventJSON struct { - ID apijson.Field - Delta apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageDeltaEvent) UnmarshalJSON(data []byte) (err error) { +func (r MessageDeltaEvent) RawJSON() string { return r.JSON.raw } +func (r *MessageDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageDeltaEventJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `thread.message.delta`. -type MessageDeltaEventObject string - -const ( - MessageDeltaEventObjectThreadMessageDelta MessageDeltaEventObject = "thread.message.delta" -) - -func (r MessageDeltaEventObject) IsKnown() bool { - switch r { - case MessageDeltaEventObjectThreadMessageDelta: - return true - } - return false -} - // The refusal content generated by the assistant. type RefusalContentBlock struct { - Refusal string `json:"refusal,required"` + Refusal string `json:"refusal,omitzero,required"` // Always `refusal`. - Type RefusalContentBlockType `json:"type,required"` - JSON refusalContentBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "refusal". + Type constant.Refusal `json:"type,required"` + JSON struct { + Refusal resp.Field + Type resp.Field + raw string + } `json:"-"` } -// refusalContentBlockJSON contains the JSON metadata for the struct -// [RefusalContentBlock] -type refusalContentBlockJSON struct { - Refusal apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RefusalContentBlock) UnmarshalJSON(data []byte) (err error) { +func (r RefusalContentBlock) RawJSON() string { return r.JSON.raw } +func (r *RefusalContentBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r refusalContentBlockJSON) RawJSON() string { - return r.raw -} - -func (r RefusalContentBlock) implementsMessageContent() {} - -// Always `refusal`. -type RefusalContentBlockType string - -const ( - RefusalContentBlockTypeRefusal RefusalContentBlockType = "refusal" -) - -func (r RefusalContentBlockType) IsKnown() bool { - switch r { - case RefusalContentBlockTypeRefusal: - return true - } - return false -} - // The refusal content that is part of a message. type RefusalDeltaBlock struct { // The index of the refusal part in the message. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `refusal`. - Type RefusalDeltaBlockType `json:"type,required"` - Refusal string `json:"refusal"` - JSON refusalDeltaBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "refusal". + Type constant.Refusal `json:"type,required"` + Refusal string `json:"refusal,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + Refusal resp.Field + raw string + } `json:"-"` } -// refusalDeltaBlockJSON contains the JSON metadata for the struct -// [RefusalDeltaBlock] -type refusalDeltaBlockJSON struct { - Index apijson.Field - Type apijson.Field - Refusal apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RefusalDeltaBlock) UnmarshalJSON(data []byte) (err error) { +func (r RefusalDeltaBlock) RawJSON() string { return r.JSON.raw } +func (r *RefusalDeltaBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r refusalDeltaBlockJSON) RawJSON() string { - return r.raw -} - -func (r RefusalDeltaBlock) implementsMessageContentDelta() {} - -// Always `refusal`. -type RefusalDeltaBlockType string - -const ( - RefusalDeltaBlockTypeRefusal RefusalDeltaBlockType = "refusal" -) - -func (r RefusalDeltaBlockType) IsKnown() bool { - switch r { - case RefusalDeltaBlockTypeRefusal: - return true - } - return false -} - type Text struct { - Annotations []Annotation `json:"annotations,required"` + Annotations []AnnotationUnion `json:"annotations,omitzero,required"` // The data that makes up the text. - Value string `json:"value,required"` - JSON textJSON `json:"-"` + Value string `json:"value,omitzero,required"` + JSON struct { + Annotations resp.Field + Value resp.Field + raw string + } `json:"-"` } -// textJSON contains the JSON metadata for the struct [Text] -type textJSON struct { - Annotations apijson.Field - Value apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Text) UnmarshalJSON(data []byte) (err error) { +func (r Text) RawJSON() string { return r.JSON.raw } +func (r *Text) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r textJSON) RawJSON() string { - return r.raw -} - // The text content that is part of a message. type TextContentBlock struct { - Text Text `json:"text,required"` + Text Text `json:"text,omitzero,required"` // Always `text`. - Type TextContentBlockType `json:"type,required"` - JSON textContentBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "text". + Type constant.Text `json:"type,required"` + JSON struct { + Text resp.Field + Type resp.Field + raw string + } `json:"-"` } -// textContentBlockJSON contains the JSON metadata for the struct -// [TextContentBlock] -type textContentBlockJSON struct { - Text apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *TextContentBlock) UnmarshalJSON(data []byte) (err error) { +func (r TextContentBlock) RawJSON() string { return r.JSON.raw } +func (r *TextContentBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r textContentBlockJSON) RawJSON() string { - return r.raw -} - -func (r TextContentBlock) implementsMessageContent() {} - -// Always `text`. -type TextContentBlockType string - -const ( - TextContentBlockTypeText TextContentBlockType = "text" -) - -func (r TextContentBlockType) IsKnown() bool { - switch r { - case TextContentBlockTypeText: - return true - } - return false -} - // The text content that is part of a message. type TextContentBlockParam struct { // Text content to be sent to the model - Text param.Field[string] `json:"text,required"` + Text param.String `json:"text,omitzero,required"` // Always `text`. - Type param.Field[TextContentBlockParamType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "text". + Type constant.Text `json:"type,required"` + apiobject } +func (f TextContentBlockParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r TextContentBlockParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r TextContentBlockParam) implementsMessageContentPartParamUnion() {} - -// Always `text`. -type TextContentBlockParamType string - -const ( - TextContentBlockParamTypeText TextContentBlockParamType = "text" -) - -func (r TextContentBlockParamType) IsKnown() bool { - switch r { - case TextContentBlockParamTypeText: - return true - } - return false + type shadow TextContentBlockParam + return param.MarshalObject(r, (*shadow)(&r)) } type TextDelta struct { - Annotations []AnnotationDelta `json:"annotations"` + Annotations []AnnotationDeltaUnion `json:"annotations,omitzero"` // The data that makes up the text. - Value string `json:"value"` - JSON textDeltaJSON `json:"-"` + Value string `json:"value,omitzero"` + JSON struct { + Annotations resp.Field + Value resp.Field + raw string + } `json:"-"` } -// textDeltaJSON contains the JSON metadata for the struct [TextDelta] -type textDeltaJSON struct { - Annotations apijson.Field - Value apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *TextDelta) UnmarshalJSON(data []byte) (err error) { +func (r TextDelta) RawJSON() string { return r.JSON.raw } +func (r *TextDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r textDeltaJSON) RawJSON() string { - return r.raw -} - // The text content that is part of a message. type TextDeltaBlock struct { // The index of the content part in the message. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `text`. - Type TextDeltaBlockType `json:"type,required"` - Text TextDelta `json:"text"` - JSON textDeltaBlockJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "text". + Type constant.Text `json:"type,required"` + Text TextDelta `json:"text,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + Text resp.Field + raw string + } `json:"-"` } -// textDeltaBlockJSON contains the JSON metadata for the struct [TextDeltaBlock] -type textDeltaBlockJSON struct { - Index apijson.Field - Type apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *TextDeltaBlock) UnmarshalJSON(data []byte) (err error) { +func (r TextDeltaBlock) RawJSON() string { return r.JSON.raw } +func (r *TextDeltaBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r textDeltaBlockJSON) RawJSON() string { - return r.raw -} - -func (r TextDeltaBlock) implementsMessageContentDelta() {} - -// Always `text`. -type TextDeltaBlockType string - -const ( - TextDeltaBlockTypeText TextDeltaBlockType = "text" -) - -func (r TextDeltaBlockType) IsKnown() bool { - switch r { - case TextDeltaBlockTypeText: - return true - } - return false -} - type BetaThreadMessageNewParams struct { // An array of content parts with a defined type, each can be of type `text` or // images can be passed with `image_url` or `image_file`. Image types are only // supported on // [Vision-compatible models](https://platform.openai.com/docs/models). - Content param.Field[[]MessageContentPartParamUnion] `json:"content,required"` + Content []MessageContentPartParamUnion `json:"content,omitzero,required"` // The role of the entity that is creating the message. Allowed values include: // // - `user`: Indicates the message is sent by an actual user and should be used in // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. - Role param.Field[BetaThreadMessageNewParamsRole] `json:"role,required"` + // + // Any of "user", "assistant" + Role BetaThreadMessageNewParamsRole `json:"role,omitzero,required"` // A list of files attached to the message, and the tools they should be added to. - Attachments param.Field[[]BetaThreadMessageNewParamsAttachment] `json:"attachments"` + Attachments []BetaThreadMessageNewParamsAttachment `json:"attachments,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject } +func (f BetaThreadMessageNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadMessageNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadMessageNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // The role of the entity that is creating the message. Allowed values include: @@ -1992,85 +1369,62 @@ const ( BetaThreadMessageNewParamsRoleAssistant BetaThreadMessageNewParamsRole = "assistant" ) -func (r BetaThreadMessageNewParamsRole) IsKnown() bool { - switch r { - case BetaThreadMessageNewParamsRoleUser, BetaThreadMessageNewParamsRoleAssistant: - return true - } - return false -} - type BetaThreadMessageNewParamsAttachment struct { // The ID of the file to attach to the message. - FileID param.Field[string] `json:"file_id"` + FileID param.String `json:"file_id,omitzero"` // The tools to add this file to. - Tools param.Field[[]BetaThreadMessageNewParamsAttachmentsToolUnion] `json:"tools"` + Tools []BetaThreadMessageNewParamsAttachmentsToolUnion `json:"tools,omitzero"` + apiobject +} + +func (f BetaThreadMessageNewParamsAttachment) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadMessageNewParamsAttachment) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadMessageNewParamsAttachment + return param.MarshalObject(r, (*shadow)(&r)) } -type BetaThreadMessageNewParamsAttachmentsTool struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[BetaThreadMessageNewParamsAttachmentsToolsType] `json:"type,required"` +// Only one field can be non-zero +type BetaThreadMessageNewParamsAttachmentsToolUnion struct { + OfCodeInterpreter *CodeInterpreterToolParam + OfFileSearch *BetaThreadMessageNewParamsAttachmentsToolsFileSearch + apiunion } -func (r BetaThreadMessageNewParamsAttachmentsTool) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u BetaThreadMessageNewParamsAttachmentsToolUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r BetaThreadMessageNewParamsAttachmentsTool) implementsBetaThreadMessageNewParamsAttachmentsToolUnion() { +func (u BetaThreadMessageNewParamsAttachmentsToolUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[BetaThreadMessageNewParamsAttachmentsToolUnion](u.OfCodeInterpreter, u.OfFileSearch) } -// Satisfied by [CodeInterpreterToolParam], -// [BetaThreadMessageNewParamsAttachmentsToolsFileSearch], -// [BetaThreadMessageNewParamsAttachmentsTool]. -type BetaThreadMessageNewParamsAttachmentsToolUnion interface { - implementsBetaThreadMessageNewParamsAttachmentsToolUnion() +func (u BetaThreadMessageNewParamsAttachmentsToolUnion) GetType() *string { + if vt := u.OfCodeInterpreter; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearch; vt != nil { + return (*string)(&vt.Type) + } + return nil } type BetaThreadMessageNewParamsAttachmentsToolsFileSearch struct { // The type of tool being defined: `file_search` - Type param.Field[BetaThreadMessageNewParamsAttachmentsToolsFileSearchType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + apiobject +} + +func (f BetaThreadMessageNewParamsAttachmentsToolsFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadMessageNewParamsAttachmentsToolsFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r BetaThreadMessageNewParamsAttachmentsToolsFileSearch) implementsBetaThreadMessageNewParamsAttachmentsToolUnion() { -} - -// The type of tool being defined: `file_search` -type BetaThreadMessageNewParamsAttachmentsToolsFileSearchType string - -const ( - BetaThreadMessageNewParamsAttachmentsToolsFileSearchTypeFileSearch BetaThreadMessageNewParamsAttachmentsToolsFileSearchType = "file_search" -) - -func (r BetaThreadMessageNewParamsAttachmentsToolsFileSearchType) IsKnown() bool { - switch r { - case BetaThreadMessageNewParamsAttachmentsToolsFileSearchTypeFileSearch: - return true - } - return false -} - -// The type of tool being defined: `code_interpreter` -type BetaThreadMessageNewParamsAttachmentsToolsType string - -const ( - BetaThreadMessageNewParamsAttachmentsToolsTypeCodeInterpreter BetaThreadMessageNewParamsAttachmentsToolsType = "code_interpreter" - BetaThreadMessageNewParamsAttachmentsToolsTypeFileSearch BetaThreadMessageNewParamsAttachmentsToolsType = "file_search" -) - -func (r BetaThreadMessageNewParamsAttachmentsToolsType) IsKnown() bool { - switch r { - case BetaThreadMessageNewParamsAttachmentsToolsTypeCodeInterpreter, BetaThreadMessageNewParamsAttachmentsToolsTypeFileSearch: - return true - } - return false + type shadow BetaThreadMessageNewParamsAttachmentsToolsFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadMessageUpdateParams struct { @@ -2080,11 +1434,15 @@ type BetaThreadMessageUpdateParams struct { // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject } +func (f BetaThreadMessageUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadMessageUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadMessageUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadMessageListParams struct { @@ -2092,22 +1450,27 @@ type BetaThreadMessageListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaThreadMessageListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaThreadMessageListParamsOrder `query:"order,omitzero"` // Filter messages by the run ID that generated them. - RunID param.Field[string] `query:"run_id"` + RunID param.String `query:"run_id,omitzero"` + apiobject } +func (f BetaThreadMessageListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaThreadMessageListParams]'s query parameters as // `url.Values`. func (r BetaThreadMessageListParams) URLQuery() (v url.Values) { @@ -2125,11 +1488,3 @@ const ( BetaThreadMessageListParamsOrderAsc BetaThreadMessageListParamsOrder = "asc" BetaThreadMessageListParamsOrderDesc BetaThreadMessageListParamsOrder = "desc" ) - -func (r BetaThreadMessageListParamsOrder) IsKnown() bool { - switch r { - case BetaThreadMessageListParamsOrderAsc, BetaThreadMessageListParamsOrderDesc: - return true - } - return false -} diff --git a/betathreadmessage_test.go b/betathreadmessage_test.go index 9f99567..f8406bc 100644 --- a/betathreadmessage_test.go +++ b/betathreadmessage_test.go @@ -30,17 +30,19 @@ func TestBetaThreadMessageNewWithOptionalParams(t *testing.T) { context.TODO(), "thread_id", openai.BetaThreadMessageNewParams{ - Content: openai.F([]openai.MessageContentPartParamUnion{openai.ImageFileContentBlockParam{ImageFile: openai.F(openai.ImageFileParam{FileID: openai.F("file_id"), Detail: openai.F(openai.ImageFileDetailAuto)}), Type: openai.F(openai.ImageFileContentBlockTypeImageFile)}}), - Role: openai.F(openai.BetaThreadMessageNewParamsRoleUser), - Attachments: openai.F([]openai.BetaThreadMessageNewParamsAttachment{{ - FileID: openai.F("file_id"), - Tools: openai.F([]openai.BetaThreadMessageNewParamsAttachmentsToolUnion{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - }}), - Metadata: openai.F(shared.MetadataParam{ + Content: []openai.MessageContentPartParamUnion{{ + OfImageFile: &openai.ImageFileContentBlockParam{ImageFile: openai.ImageFileParam{FileID: openai.String("file_id"), Detail: "auto"}}, + }}, + Role: openai.BetaThreadMessageNewParamsRoleUser, + Attachments: []openai.BetaThreadMessageNewParamsAttachment{{ + FileID: openai.String("file_id"), + Tools: []openai.BetaThreadMessageNewParamsAttachmentsToolUnion{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), + }, }, ) if err != nil { @@ -95,9 +97,9 @@ func TestBetaThreadMessageUpdateWithOptionalParams(t *testing.T) { "thread_id", "message_id", openai.BetaThreadMessageUpdateParams{ - Metadata: openai.F(shared.MetadataParam{ + Metadata: shared.MetadataParam{ "foo": "string", - }), + }, }, ) if err != nil { @@ -125,11 +127,11 @@ func TestBetaThreadMessageListWithOptionalParams(t *testing.T) { context.TODO(), "thread_id", openai.BetaThreadMessageListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaThreadMessageListParamsOrderAsc), - RunID: openai.F("run_id"), + After: openai.String("after"), + Before: openai.String("before"), + Limit: openai.Int(0), + Order: openai.BetaThreadMessageListParamsOrderAsc, + RunID: openai.String("run_id"), }, ) if err != nil { diff --git a/betathreadrun.go b/betathreadrun.go index 4aaab61..6ba1e4f 100644 --- a/betathreadrun.go +++ b/betathreadrun.go @@ -11,12 +11,14 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/packages/ssestream" "github.com/openai/openai-go/shared" + "github.com/openai/openai-go/shared/constant" ) // BetaThreadRunService contains methods and other services that help with @@ -27,14 +29,14 @@ import ( // the [NewBetaThreadRunService] method instead. type BetaThreadRunService struct { Options []option.RequestOption - Steps *BetaThreadRunStepService + Steps BetaThreadRunStepService } // NewBetaThreadRunService generates a new service that applies the given options // to each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewBetaThreadRunService(opts ...option.RequestOption) (r *BetaThreadRunService) { - r = &BetaThreadRunService{} +func NewBetaThreadRunService(opts ...option.RequestOption) (r BetaThreadRunService) { + r = BetaThreadRunService{} r.Options = opts r.Steps = NewBetaThreadRunStepService(opts...) return @@ -54,7 +56,7 @@ func (r *BetaThreadRunService) New(ctx context.Context, threadID string, params } // Create a run. -func (r *BetaThreadRunService) NewStreaming(ctx context.Context, threadID string, params BetaThreadRunNewParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEvent]) { +func (r *BetaThreadRunService) NewStreaming(ctx context.Context, threadID string, params BetaThreadRunNewParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEventUnion]) { var ( raw *http.Response err error @@ -67,7 +69,7 @@ func (r *BetaThreadRunService) NewStreaming(ctx context.Context, threadID string } path := fmt.Sprintf("threads/%s/runs", threadID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &raw, opts...) - return ssestream.NewStream[AssistantStreamEvent](ssestream.NewDecoder(raw), err) + return ssestream.NewStream[AssistantStreamEventUnion](ssestream.NewDecoder(raw), err) } // Retrieves a run. @@ -172,7 +174,7 @@ func (r *BetaThreadRunService) SubmitToolOutputs(ctx context.Context, threadID s // `submit_tool_outputs`, this endpoint can be used to submit the outputs from the // tool calls once they're all completed. All outputs must be submitted in a single // request. -func (r *BetaThreadRunService) SubmitToolOutputsStreaming(ctx context.Context, threadID string, runID string, body BetaThreadRunSubmitToolOutputsParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEvent]) { +func (r *BetaThreadRunService) SubmitToolOutputsStreaming(ctx context.Context, threadID string, runID string, body BetaThreadRunSubmitToolOutputsParams, opts ...option.RequestOption) (stream *ssestream.Stream[AssistantStreamEventUnion]) { var ( raw *http.Response err error @@ -189,7 +191,7 @@ func (r *BetaThreadRunService) SubmitToolOutputsStreaming(ctx context.Context, t } path := fmt.Sprintf("threads/%s/runs/%s/submit_tool_outputs", threadID, runID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &raw, opts...) - return ssestream.NewStream[AssistantStreamEvent](ssestream.NewDecoder(raw), err) + return ssestream.NewStream[AssistantStreamEventUnion](ssestream.NewDecoder(raw), err) } // Tool call objects @@ -198,138 +200,113 @@ type RequiredActionFunctionToolCall struct { // outputs in using the // [Submit tool outputs to run](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) // endpoint. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The function definition. - Function RequiredActionFunctionToolCallFunction `json:"function,required"` + Function RequiredActionFunctionToolCallFunction `json:"function,omitzero,required"` // The type of tool call the output is required for. For now, this is always // `function`. - Type RequiredActionFunctionToolCallType `json:"type,required"` - JSON requiredActionFunctionToolCallJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + JSON struct { + ID resp.Field + Function resp.Field + Type resp.Field + raw string + } `json:"-"` } -// requiredActionFunctionToolCallJSON contains the JSON metadata for the struct -// [RequiredActionFunctionToolCall] -type requiredActionFunctionToolCallJSON struct { - ID apijson.Field - Function apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RequiredActionFunctionToolCall) UnmarshalJSON(data []byte) (err error) { +func (r RequiredActionFunctionToolCall) RawJSON() string { return r.JSON.raw } +func (r *RequiredActionFunctionToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r requiredActionFunctionToolCallJSON) RawJSON() string { - return r.raw -} - // The function definition. type RequiredActionFunctionToolCallFunction struct { // The arguments that the model expects you to pass to the function. - Arguments string `json:"arguments,required"` + Arguments string `json:"arguments,omitzero,required"` // The name of the function. - Name string `json:"name,required"` - JSON requiredActionFunctionToolCallFunctionJSON `json:"-"` + Name string `json:"name,omitzero,required"` + JSON struct { + Arguments resp.Field + Name resp.Field + raw string + } `json:"-"` } -// requiredActionFunctionToolCallFunctionJSON contains the JSON metadata for the -// struct [RequiredActionFunctionToolCallFunction] -type requiredActionFunctionToolCallFunctionJSON struct { - Arguments apijson.Field - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RequiredActionFunctionToolCallFunction) UnmarshalJSON(data []byte) (err error) { +func (r RequiredActionFunctionToolCallFunction) RawJSON() string { return r.JSON.raw } +func (r *RequiredActionFunctionToolCallFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r requiredActionFunctionToolCallFunctionJSON) RawJSON() string { - return r.raw -} - -// The type of tool call the output is required for. For now, this is always -// `function`. -type RequiredActionFunctionToolCallType string - -const ( - RequiredActionFunctionToolCallTypeFunction RequiredActionFunctionToolCallType = "function" -) - -func (r RequiredActionFunctionToolCallType) IsKnown() bool { - switch r { - case RequiredActionFunctionToolCallTypeFunction: - return true - } - return false -} - // Represents an execution run on a // [thread](https://platform.openai.com/docs/api-reference/threads). type Run struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The ID of the // [assistant](https://platform.openai.com/docs/api-reference/assistants) used for // execution of this run. - AssistantID string `json:"assistant_id,required"` + AssistantID string `json:"assistant_id,omitzero,required"` // The Unix timestamp (in seconds) for when the run was cancelled. - CancelledAt int64 `json:"cancelled_at,required,nullable"` + CancelledAt int64 `json:"cancelled_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run was completed. - CompletedAt int64 `json:"completed_at,required,nullable"` + CompletedAt int64 `json:"completed_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The Unix timestamp (in seconds) for when the run will expire. - ExpiresAt int64 `json:"expires_at,required,nullable"` + ExpiresAt int64 `json:"expires_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run failed. - FailedAt int64 `json:"failed_at,required,nullable"` + FailedAt int64 `json:"failed_at,omitzero,required,nullable"` // Details on why the run is incomplete. Will be `null` if the run is not // incomplete. - IncompleteDetails RunIncompleteDetails `json:"incomplete_details,required,nullable"` + IncompleteDetails RunIncompleteDetails `json:"incomplete_details,omitzero,required,nullable"` // The instructions that the // [assistant](https://platform.openai.com/docs/api-reference/assistants) used for // this run. - Instructions string `json:"instructions,required"` + Instructions string `json:"instructions,omitzero,required"` // The last error associated with this run. Will be `null` if there are no errors. - LastError RunLastError `json:"last_error,required,nullable"` + LastError RunLastError `json:"last_error,omitzero,required,nullable"` // The maximum number of completion tokens specified to have been used over the // course of the run. - MaxCompletionTokens int64 `json:"max_completion_tokens,required,nullable"` + MaxCompletionTokens int64 `json:"max_completion_tokens,omitzero,required,nullable"` // The maximum number of prompt tokens specified to have been used over the course // of the run. - MaxPromptTokens int64 `json:"max_prompt_tokens,required,nullable"` + MaxPromptTokens int64 `json:"max_prompt_tokens,omitzero,required,nullable"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // The model that the // [assistant](https://platform.openai.com/docs/api-reference/assistants) used for // this run. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always `thread.run`. - Object RunObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "thread.run". + Object constant.ThreadRun `json:"object,required"` // Whether to enable // [parallel function calling](https://platform.openai.com/docs/guides/function-calling#configuring-parallel-function-calling) // during tool use. - ParallelToolCalls bool `json:"parallel_tool_calls,required"` + ParallelToolCalls bool `json:"parallel_tool_calls,omitzero,required"` // Details on the action required to continue the run. Will be `null` if no action // is required. - RequiredAction RunRequiredAction `json:"required_action,required,nullable"` + RequiredAction RunRequiredAction `json:"required_action,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run was started. - StartedAt int64 `json:"started_at,required,nullable"` + StartedAt int64 `json:"started_at,omitzero,required,nullable"` // The status of the run, which can be either `queued`, `in_progress`, // `requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, // `incomplete`, or `expired`. - Status RunStatus `json:"status,required"` + // + // Any of "queued", "in_progress", "requires_action", "cancelling", "cancelled", + // "failed", "completed", "incomplete", "expired" + Status RunStatus `json:"status,omitzero,required"` // The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) // that was executed on as a part of this run. - ThreadID string `json:"thread_id,required"` + ThreadID string `json:"thread_id,omitzero,required"` // Controls which (if any) tool is called by the model. `none` means the model will // not call any tools and instead generates a message. `auto` is the default value // and means the model can pick between generating a message or calling one or more @@ -337,133 +314,107 @@ type Run struct { // to the user. Specifying a particular tool like `{"type": "file_search"}` or // `{"type": "function", "function": {"name": "my_function"}}` forces the model to // call that tool. - ToolChoice AssistantToolChoiceOptionUnion `json:"tool_choice,required,nullable"` + ToolChoice AssistantToolChoiceOptionUnion `json:"tool_choice,omitzero,required,nullable"` // The list of tools that the // [assistant](https://platform.openai.com/docs/api-reference/assistants) used for // this run. - Tools []AssistantTool `json:"tools,required"` + Tools []AssistantToolUnion `json:"tools,omitzero,required"` // Controls for how a thread will be truncated prior to the run. Use this to // control the intial context window of the run. - TruncationStrategy RunTruncationStrategy `json:"truncation_strategy,required,nullable"` + TruncationStrategy RunTruncationStrategy `json:"truncation_strategy,omitzero,required,nullable"` // Usage statistics related to the run. This value will be `null` if the run is not // in a terminal state (i.e. `in_progress`, `queued`, etc.). - Usage RunUsage `json:"usage,required,nullable"` + Usage RunUsage `json:"usage,omitzero,required,nullable"` // The sampling temperature used for this run. If not set, defaults to 1. - Temperature float64 `json:"temperature,nullable"` + Temperature float64 `json:"temperature,omitzero,nullable"` // The nucleus sampling value used for this run. If not set, defaults to 1. - TopP float64 `json:"top_p,nullable"` - JSON runJSON `json:"-"` + TopP float64 `json:"top_p,omitzero,nullable"` + JSON struct { + ID resp.Field + AssistantID resp.Field + CancelledAt resp.Field + CompletedAt resp.Field + CreatedAt resp.Field + ExpiresAt resp.Field + FailedAt resp.Field + IncompleteDetails resp.Field + Instructions resp.Field + LastError resp.Field + MaxCompletionTokens resp.Field + MaxPromptTokens resp.Field + Metadata resp.Field + Model resp.Field + Object resp.Field + ParallelToolCalls resp.Field + RequiredAction resp.Field + StartedAt resp.Field + Status resp.Field + ThreadID resp.Field + ToolChoice resp.Field + Tools resp.Field + TruncationStrategy resp.Field + Usage resp.Field + Temperature resp.Field + TopP resp.Field + raw string + } `json:"-"` } -// runJSON contains the JSON metadata for the struct [Run] -type runJSON struct { - ID apijson.Field - AssistantID apijson.Field - CancelledAt apijson.Field - CompletedAt apijson.Field - CreatedAt apijson.Field - ExpiresAt apijson.Field - FailedAt apijson.Field - IncompleteDetails apijson.Field - Instructions apijson.Field - LastError apijson.Field - MaxCompletionTokens apijson.Field - MaxPromptTokens apijson.Field - Metadata apijson.Field - Model apijson.Field - Object apijson.Field - ParallelToolCalls apijson.Field - RequiredAction apijson.Field - StartedAt apijson.Field - Status apijson.Field - ThreadID apijson.Field - ToolChoice apijson.Field - Tools apijson.Field - TruncationStrategy apijson.Field - Usage apijson.Field - Temperature apijson.Field - TopP apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Run) UnmarshalJSON(data []byte) (err error) { +func (r Run) RawJSON() string { return r.JSON.raw } +func (r *Run) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runJSON) RawJSON() string { - return r.raw -} - // Details on why the run is incomplete. Will be `null` if the run is not // incomplete. type RunIncompleteDetails struct { // The reason why the run is incomplete. This will point to which specific token // limit was reached over the course of the run. - Reason RunIncompleteDetailsReason `json:"reason"` - JSON runIncompleteDetailsJSON `json:"-"` + // + // Any of "max_completion_tokens", "max_prompt_tokens" + Reason string `json:"reason,omitzero"` + JSON struct { + Reason resp.Field + raw string + } `json:"-"` } -// runIncompleteDetailsJSON contains the JSON metadata for the struct -// [RunIncompleteDetails] -type runIncompleteDetailsJSON struct { - Reason apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunIncompleteDetails) UnmarshalJSON(data []byte) (err error) { +func (r RunIncompleteDetails) RawJSON() string { return r.JSON.raw } +func (r *RunIncompleteDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runIncompleteDetailsJSON) RawJSON() string { - return r.raw -} - // The reason why the run is incomplete. This will point to which specific token // limit was reached over the course of the run. -type RunIncompleteDetailsReason string +type RunIncompleteDetailsReason = string const ( RunIncompleteDetailsReasonMaxCompletionTokens RunIncompleteDetailsReason = "max_completion_tokens" RunIncompleteDetailsReasonMaxPromptTokens RunIncompleteDetailsReason = "max_prompt_tokens" ) -func (r RunIncompleteDetailsReason) IsKnown() bool { - switch r { - case RunIncompleteDetailsReasonMaxCompletionTokens, RunIncompleteDetailsReasonMaxPromptTokens: - return true - } - return false -} - // The last error associated with this run. Will be `null` if there are no errors. type RunLastError struct { // One of `server_error`, `rate_limit_exceeded`, or `invalid_prompt`. - Code RunLastErrorCode `json:"code,required"` + // + // Any of "server_error", "rate_limit_exceeded", "invalid_prompt" + Code string `json:"code,omitzero,required"` // A human-readable description of the error. - Message string `json:"message,required"` - JSON runLastErrorJSON `json:"-"` + Message string `json:"message,omitzero,required"` + JSON struct { + Code resp.Field + Message resp.Field + raw string + } `json:"-"` } -// runLastErrorJSON contains the JSON metadata for the struct [RunLastError] -type runLastErrorJSON struct { - Code apijson.Field - Message apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunLastError) UnmarshalJSON(data []byte) (err error) { +func (r RunLastError) RawJSON() string { return r.JSON.raw } +func (r *RunLastError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runLastErrorJSON) RawJSON() string { - return r.raw -} - // One of `server_error`, `rate_limit_exceeded`, or `invalid_prompt`. -type RunLastErrorCode string +type RunLastErrorCode = string const ( RunLastErrorCodeServerError RunLastErrorCode = "server_error" @@ -471,94 +422,43 @@ const ( RunLastErrorCodeInvalidPrompt RunLastErrorCode = "invalid_prompt" ) -func (r RunLastErrorCode) IsKnown() bool { - switch r { - case RunLastErrorCodeServerError, RunLastErrorCodeRateLimitExceeded, RunLastErrorCodeInvalidPrompt: - return true - } - return false -} - -// The object type, which is always `thread.run`. -type RunObject string - -const ( - RunObjectThreadRun RunObject = "thread.run" -) - -func (r RunObject) IsKnown() bool { - switch r { - case RunObjectThreadRun: - return true - } - return false -} - // Details on the action required to continue the run. Will be `null` if no action // is required. type RunRequiredAction struct { // Details on the tool outputs needed for this run to continue. - SubmitToolOutputs RunRequiredActionSubmitToolOutputs `json:"submit_tool_outputs,required"` + SubmitToolOutputs RunRequiredActionSubmitToolOutputs `json:"submit_tool_outputs,omitzero,required"` // For now, this is always `submit_tool_outputs`. - Type RunRequiredActionType `json:"type,required"` - JSON runRequiredActionJSON `json:"-"` + // + // This field can be elided, and will be automatically set as + // "submit_tool_outputs". + Type constant.SubmitToolOutputs `json:"type,required"` + JSON struct { + SubmitToolOutputs resp.Field + Type resp.Field + raw string + } `json:"-"` } -// runRequiredActionJSON contains the JSON metadata for the struct -// [RunRequiredAction] -type runRequiredActionJSON struct { - SubmitToolOutputs apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunRequiredAction) UnmarshalJSON(data []byte) (err error) { +func (r RunRequiredAction) RawJSON() string { return r.JSON.raw } +func (r *RunRequiredAction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runRequiredActionJSON) RawJSON() string { - return r.raw -} - // Details on the tool outputs needed for this run to continue. type RunRequiredActionSubmitToolOutputs struct { // A list of the relevant tool calls. - ToolCalls []RequiredActionFunctionToolCall `json:"tool_calls,required"` - JSON runRequiredActionSubmitToolOutputsJSON `json:"-"` + ToolCalls []RequiredActionFunctionToolCall `json:"tool_calls,omitzero,required"` + JSON struct { + ToolCalls resp.Field + raw string + } `json:"-"` } -// runRequiredActionSubmitToolOutputsJSON contains the JSON metadata for the struct -// [RunRequiredActionSubmitToolOutputs] -type runRequiredActionSubmitToolOutputsJSON struct { - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunRequiredActionSubmitToolOutputs) UnmarshalJSON(data []byte) (err error) { +func (r RunRequiredActionSubmitToolOutputs) RawJSON() string { return r.JSON.raw } +func (r *RunRequiredActionSubmitToolOutputs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runRequiredActionSubmitToolOutputsJSON) RawJSON() string { - return r.raw -} - -// For now, this is always `submit_tool_outputs`. -type RunRequiredActionType string - -const ( - RunRequiredActionTypeSubmitToolOutputs RunRequiredActionType = "submit_tool_outputs" -) - -func (r RunRequiredActionType) IsKnown() bool { - switch r { - case RunRequiredActionTypeSubmitToolOutputs: - return true - } - return false -} - // Controls for how a thread will be truncated prior to the run. Use this to // control the intial context window of the run. type RunTruncationStrategy struct { @@ -566,78 +466,57 @@ type RunTruncationStrategy struct { // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. - Type RunTruncationStrategyType `json:"type,required"` + // + // Any of "auto", "last_messages" + Type string `json:"type,omitzero,required"` // The number of most recent messages from the thread when constructing the context // for the run. - LastMessages int64 `json:"last_messages,nullable"` - JSON runTruncationStrategyJSON `json:"-"` + LastMessages int64 `json:"last_messages,omitzero,nullable"` + JSON struct { + Type resp.Field + LastMessages resp.Field + raw string + } `json:"-"` } -// runTruncationStrategyJSON contains the JSON metadata for the struct -// [RunTruncationStrategy] -type runTruncationStrategyJSON struct { - Type apijson.Field - LastMessages apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunTruncationStrategy) UnmarshalJSON(data []byte) (err error) { +func (r RunTruncationStrategy) RawJSON() string { return r.JSON.raw } +func (r *RunTruncationStrategy) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runTruncationStrategyJSON) RawJSON() string { - return r.raw -} - // The truncation strategy to use for the thread. The default is `auto`. If set to // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. -type RunTruncationStrategyType string +type RunTruncationStrategyType = string const ( RunTruncationStrategyTypeAuto RunTruncationStrategyType = "auto" RunTruncationStrategyTypeLastMessages RunTruncationStrategyType = "last_messages" ) -func (r RunTruncationStrategyType) IsKnown() bool { - switch r { - case RunTruncationStrategyTypeAuto, RunTruncationStrategyTypeLastMessages: - return true - } - return false -} - // Usage statistics related to the run. This value will be `null` if the run is not // in a terminal state (i.e. `in_progress`, `queued`, etc.). type RunUsage struct { // Number of completion tokens used over the course of the run. - CompletionTokens int64 `json:"completion_tokens,required"` + CompletionTokens int64 `json:"completion_tokens,omitzero,required"` // Number of prompt tokens used over the course of the run. - PromptTokens int64 `json:"prompt_tokens,required"` + PromptTokens int64 `json:"prompt_tokens,omitzero,required"` // Total number of tokens used (prompt + completion). - TotalTokens int64 `json:"total_tokens,required"` - JSON runUsageJSON `json:"-"` + TotalTokens int64 `json:"total_tokens,omitzero,required"` + JSON struct { + CompletionTokens resp.Field + PromptTokens resp.Field + TotalTokens resp.Field + raw string + } `json:"-"` } -// runUsageJSON contains the JSON metadata for the struct [RunUsage] -type runUsageJSON struct { - CompletionTokens apijson.Field - PromptTokens apijson.Field - TotalTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunUsage) UnmarshalJSON(data []byte) (err error) { +func (r RunUsage) RawJSON() string { return r.JSON.raw } +func (r *RunUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runUsageJSON) RawJSON() string { - return r.raw -} - // The status of the run, which can be either `queued`, `in_progress`, // `requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, // `incomplete`, or `expired`. @@ -655,19 +534,11 @@ const ( RunStatusExpired RunStatus = "expired" ) -func (r RunStatus) IsKnown() bool { - switch r { - case RunStatusQueued, RunStatusInProgress, RunStatusRequiresAction, RunStatusCancelling, RunStatusCancelled, RunStatusFailed, RunStatusCompleted, RunStatusIncomplete, RunStatusExpired: - return true - } - return false -} - type BetaThreadRunNewParams struct { // The ID of the // [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to // execute this run. - AssistantID param.Field[string] `json:"assistant_id,required"` + AssistantID param.String `json:"assistant_id,omitzero,required"` // A list of additional fields to include in the response. Currently the only // supported value is `step_details.tool_calls[*].file_search.results[*].content` // to fetch the file search result content. @@ -675,56 +546,58 @@ type BetaThreadRunNewParams struct { // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - Include param.Field[[]RunStepInclude] `query:"include"` + Include []RunStepInclude `query:"include,omitzero"` // Appends additional instructions at the end of the instructions for the run. This // is useful for modifying the behavior on a per-run basis without overriding other // instructions. - AdditionalInstructions param.Field[string] `json:"additional_instructions"` + AdditionalInstructions param.String `json:"additional_instructions,omitzero"` // Adds additional messages to the thread before creating the run. - AdditionalMessages param.Field[[]BetaThreadRunNewParamsAdditionalMessage] `json:"additional_messages"` + AdditionalMessages []BetaThreadRunNewParamsAdditionalMessage `json:"additional_messages,omitzero"` // Overrides the // [instructions](https://platform.openai.com/docs/api-reference/assistants/createAssistant) // of the assistant. This is useful for modifying the behavior on a per-run basis. - Instructions param.Field[string] `json:"instructions"` + Instructions param.String `json:"instructions,omitzero"` // The maximum number of completion tokens that may be used over the course of the // run. The run will make a best effort to use only the number of completion tokens // specified, across multiple turns of the run. If the run exceeds the number of // completion tokens specified, the run will end with status `incomplete`. See // `incomplete_details` for more info. - MaxCompletionTokens param.Field[int64] `json:"max_completion_tokens"` + MaxCompletionTokens param.Int `json:"max_completion_tokens,omitzero"` // The maximum number of prompt tokens that may be used over the course of the run. // The run will make a best effort to use only the number of prompt tokens // specified, across multiple turns of the run. If the run exceeds the number of // prompt tokens specified, the run will end with status `incomplete`. See // `incomplete_details` for more info. - MaxPromptTokens param.Field[int64] `json:"max_prompt_tokens"` + MaxPromptTokens param.Int `json:"max_prompt_tokens,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to // be used to execute this run. If a value is provided here, it will override the // model associated with the assistant. If not, the model associated with the // assistant will be used. - Model param.Field[ChatModel] `json:"model"` + Model ChatModel `json:"model,omitzero"` // Whether to enable // [parallel function calling](https://platform.openai.com/docs/guides/function-calling#configuring-parallel-function-calling) // during tool use. - ParallelToolCalls param.Field[bool] `json:"parallel_tool_calls"` + ParallelToolCalls param.Bool `json:"parallel_tool_calls,omitzero"` // **o1 and o3-mini models only** // // Constrains effort on reasoning for // [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently // supported values are `low`, `medium`, and `high`. Reducing reasoning effort can // result in faster responses and fewer tokens used on reasoning in a response. - ReasoningEffort param.Field[BetaThreadRunNewParamsReasoningEffort] `json:"reasoning_effort"` + // + // Any of "low", "medium", "high" + ReasoningEffort BetaThreadRunNewParamsReasoningEffort `json:"reasoning_effort,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // Controls which (if any) tool is called by the model. `none` means the model will // not call any tools and instead generates a message. `auto` is the default value // and means the model can pick between generating a message or calling one or more @@ -732,23 +605,27 @@ type BetaThreadRunNewParams struct { // to the user. Specifying a particular tool like `{"type": "file_search"}` or // `{"type": "function", "function": {"name": "my_function"}}` forces the model to // call that tool. - ToolChoice param.Field[AssistantToolChoiceOptionUnionParam] `json:"tool_choice"` + ToolChoice AssistantToolChoiceOptionUnionParam `json:"tool_choice,omitzero"` // Override the tools the assistant can use for this run. This is useful for // modifying the behavior on a per-run basis. - Tools param.Field[[]AssistantToolUnionParam] `json:"tools"` + Tools []AssistantToolUnionParam `json:"tools,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or temperature but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` // Controls for how a thread will be truncated prior to the run. Use this to // control the intial context window of the run. - TruncationStrategy param.Field[BetaThreadRunNewParamsTruncationStrategy] `json:"truncation_strategy"` + TruncationStrategy BetaThreadRunNewParamsTruncationStrategy `json:"truncation_strategy,omitzero"` + apiobject } +func (f BetaThreadRunNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadRunNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // URLQuery serializes [BetaThreadRunNewParams]'s query parameters as `url.Values`. @@ -764,27 +641,35 @@ type BetaThreadRunNewParamsAdditionalMessage struct { // images can be passed with `image_url` or `image_file`. Image types are only // supported on // [Vision-compatible models](https://platform.openai.com/docs/models). - Content param.Field[[]MessageContentPartParamUnion] `json:"content,required"` + Content []MessageContentPartParamUnion `json:"content,omitzero,required"` // The role of the entity that is creating the message. Allowed values include: // // - `user`: Indicates the message is sent by an actual user and should be used in // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. - Role param.Field[BetaThreadRunNewParamsAdditionalMessagesRole] `json:"role,required"` + // + // Any of "user", "assistant" + Role string `json:"role,omitzero,required"` // A list of files attached to the message, and the tools they should be added to. - Attachments param.Field[[]BetaThreadRunNewParamsAdditionalMessagesAttachment] `json:"attachments"` + Attachments []BetaThreadRunNewParamsAdditionalMessagesAttachment `json:"attachments,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject +} + +func (f BetaThreadRunNewParamsAdditionalMessage) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunNewParamsAdditionalMessage) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunNewParamsAdditionalMessage + return param.MarshalObject(r, (*shadow)(&r)) } // The role of the entity that is creating the message. Allowed values include: @@ -793,92 +678,69 @@ func (r BetaThreadRunNewParamsAdditionalMessage) MarshalJSON() (data []byte, err // most cases to represent user-generated messages. // - `assistant`: Indicates the message is generated by the assistant. Use this // value to insert messages from the assistant into the conversation. -type BetaThreadRunNewParamsAdditionalMessagesRole string +type BetaThreadRunNewParamsAdditionalMessagesRole = string const ( BetaThreadRunNewParamsAdditionalMessagesRoleUser BetaThreadRunNewParamsAdditionalMessagesRole = "user" BetaThreadRunNewParamsAdditionalMessagesRoleAssistant BetaThreadRunNewParamsAdditionalMessagesRole = "assistant" ) -func (r BetaThreadRunNewParamsAdditionalMessagesRole) IsKnown() bool { - switch r { - case BetaThreadRunNewParamsAdditionalMessagesRoleUser, BetaThreadRunNewParamsAdditionalMessagesRoleAssistant: - return true - } - return false -} - type BetaThreadRunNewParamsAdditionalMessagesAttachment struct { // The ID of the file to attach to the message. - FileID param.Field[string] `json:"file_id"` + FileID param.String `json:"file_id,omitzero"` // The tools to add this file to. - Tools param.Field[[]BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion] `json:"tools"` + Tools []BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion `json:"tools,omitzero"` + apiobject +} + +func (f BetaThreadRunNewParamsAdditionalMessagesAttachment) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunNewParamsAdditionalMessagesAttachment) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunNewParamsAdditionalMessagesAttachment + return param.MarshalObject(r, (*shadow)(&r)) } -type BetaThreadRunNewParamsAdditionalMessagesAttachmentsTool struct { - // The type of tool being defined: `code_interpreter` - Type param.Field[BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsType] `json:"type,required"` +// Only one field can be non-zero +type BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion struct { + OfCodeInterpreter *CodeInterpreterToolParam + OfFileSearch *BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch + apiunion } -func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsTool) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsTool) implementsBetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion() { +func (u BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion](u.OfCodeInterpreter, u.OfFileSearch) } -// Satisfied by [CodeInterpreterToolParam], -// [BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch], -// [BetaThreadRunNewParamsAdditionalMessagesAttachmentsTool]. -type BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion interface { - implementsBetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion() +func (u BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion) GetType() *string { + if vt := u.OfCodeInterpreter; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfFileSearch; vt != nil { + return (*string)(&vt.Type) + } + return nil } type BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch struct { // The type of tool being defined: `file_search` - Type param.Field[BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + apiobject +} + +func (f BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch) implementsBetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion() { -} - -// The type of tool being defined: `file_search` -type BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchType string - -const ( - BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchTypeFileSearch BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchType = "file_search" -) - -func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchType) IsKnown() bool { - switch r { - case BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearchTypeFileSearch: - return true - } - return false -} - -// The type of tool being defined: `code_interpreter` -type BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsType string - -const ( - BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsTypeCodeInterpreter BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsType = "code_interpreter" - BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsTypeFileSearch BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsType = "file_search" -) - -func (r BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsType) IsKnown() bool { - switch r { - case BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsTypeCodeInterpreter, BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsTypeFileSearch: - return true - } - return false + type shadow BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolsFileSearch + return param.MarshalObject(r, (*shadow)(&r)) } // **o1 and o3-mini models only** @@ -895,14 +757,6 @@ const ( BetaThreadRunNewParamsReasoningEffortHigh BetaThreadRunNewParamsReasoningEffort = "high" ) -func (r BetaThreadRunNewParamsReasoningEffort) IsKnown() bool { - switch r { - case BetaThreadRunNewParamsReasoningEffortLow, BetaThreadRunNewParamsReasoningEffortMedium, BetaThreadRunNewParamsReasoningEffortHigh: - return true - } - return false -} - // Controls for how a thread will be truncated prior to the run. Use this to // control the intial context window of the run. type BetaThreadRunNewParamsTruncationStrategy struct { @@ -910,35 +764,35 @@ type BetaThreadRunNewParamsTruncationStrategy struct { // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. - Type param.Field[BetaThreadRunNewParamsTruncationStrategyType] `json:"type,required"` + // + // Any of "auto", "last_messages" + Type string `json:"type,omitzero,required"` // The number of most recent messages from the thread when constructing the context // for the run. - LastMessages param.Field[int64] `json:"last_messages"` + LastMessages param.Int `json:"last_messages,omitzero"` + apiobject +} + +func (f BetaThreadRunNewParamsTruncationStrategy) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunNewParamsTruncationStrategy) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunNewParamsTruncationStrategy + return param.MarshalObject(r, (*shadow)(&r)) } // The truncation strategy to use for the thread. The default is `auto`. If set to // `last_messages`, the thread will be truncated to the n most recent messages in // the thread. When set to `auto`, messages in the middle of the thread will be // dropped to fit the context length of the model, `max_prompt_tokens`. -type BetaThreadRunNewParamsTruncationStrategyType string +type BetaThreadRunNewParamsTruncationStrategyType = string const ( BetaThreadRunNewParamsTruncationStrategyTypeAuto BetaThreadRunNewParamsTruncationStrategyType = "auto" BetaThreadRunNewParamsTruncationStrategyTypeLastMessages BetaThreadRunNewParamsTruncationStrategyType = "last_messages" ) -func (r BetaThreadRunNewParamsTruncationStrategyType) IsKnown() bool { - switch r { - case BetaThreadRunNewParamsTruncationStrategyTypeAuto, BetaThreadRunNewParamsTruncationStrategyTypeLastMessages: - return true - } - return false -} - type BetaThreadRunUpdateParams struct { // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and @@ -946,11 +800,15 @@ type BetaThreadRunUpdateParams struct { // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` + apiobject } +func (f BetaThreadRunUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaThreadRunUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadRunListParams struct { @@ -958,20 +816,25 @@ type BetaThreadRunListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaThreadRunListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaThreadRunListParamsOrder `query:"order,omitzero"` + apiobject } +func (f BetaThreadRunListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaThreadRunListParams]'s query parameters as // `url.Values`. func (r BetaThreadRunListParams) URLQuery() (v url.Values) { @@ -990,31 +853,35 @@ const ( BetaThreadRunListParamsOrderDesc BetaThreadRunListParamsOrder = "desc" ) -func (r BetaThreadRunListParamsOrder) IsKnown() bool { - switch r { - case BetaThreadRunListParamsOrderAsc, BetaThreadRunListParamsOrderDesc: - return true - } - return false -} - type BetaThreadRunSubmitToolOutputsParams struct { // A list of tools for which the outputs are being submitted. - ToolOutputs param.Field[[]BetaThreadRunSubmitToolOutputsParamsToolOutput] `json:"tool_outputs,required"` + ToolOutputs []BetaThreadRunSubmitToolOutputsParamsToolOutput `json:"tool_outputs,omitzero,required"` + apiobject +} + +func (f BetaThreadRunSubmitToolOutputsParams) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunSubmitToolOutputsParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunSubmitToolOutputsParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaThreadRunSubmitToolOutputsParamsToolOutput struct { // The output of the tool call to be submitted to continue the run. - Output param.Field[string] `json:"output"` + Output param.String `json:"output,omitzero"` // The ID of the tool call in the `required_action` object within the run object // the output is being submitted for. - ToolCallID param.Field[string] `json:"tool_call_id"` + ToolCallID param.String `json:"tool_call_id,omitzero"` + apiobject +} + +func (f BetaThreadRunSubmitToolOutputsParamsToolOutput) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaThreadRunSubmitToolOutputsParamsToolOutput) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaThreadRunSubmitToolOutputsParamsToolOutput + return param.MarshalObject(r, (*shadow)(&r)) } diff --git a/betathreadrun_test.go b/betathreadrun_test.go index e228f4e..572cfe0 100644 --- a/betathreadrun_test.go +++ b/betathreadrun_test.go @@ -30,41 +30,45 @@ func TestBetaThreadRunNewWithOptionalParams(t *testing.T) { context.TODO(), "thread_id", openai.BetaThreadRunNewParams{ - AssistantID: openai.F("assistant_id"), - Include: openai.F([]openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}), - AdditionalInstructions: openai.F("additional_instructions"), - AdditionalMessages: openai.F([]openai.BetaThreadRunNewParamsAdditionalMessage{{ - Content: openai.F([]openai.MessageContentPartParamUnion{openai.ImageFileContentBlockParam{ImageFile: openai.F(openai.ImageFileParam{FileID: openai.F("file_id"), Detail: openai.F(openai.ImageFileDetailAuto)}), Type: openai.F(openai.ImageFileContentBlockTypeImageFile)}}), - Role: openai.F(openai.BetaThreadRunNewParamsAdditionalMessagesRoleUser), - Attachments: openai.F([]openai.BetaThreadRunNewParamsAdditionalMessagesAttachment{{ - FileID: openai.F("file_id"), - Tools: openai.F([]openai.BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - }}), - Metadata: openai.F(shared.MetadataParam{ + AssistantID: openai.String("assistant_id"), + Include: []openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}, + AdditionalInstructions: openai.String("additional_instructions"), + AdditionalMessages: []openai.BetaThreadRunNewParamsAdditionalMessage{{ + Content: []openai.MessageContentPartParamUnion{{ + OfImageFile: &openai.ImageFileContentBlockParam{ImageFile: openai.ImageFileParam{FileID: openai.String("file_id"), Detail: "auto"}}, + }}, + Role: "user", + Attachments: []openai.BetaThreadRunNewParamsAdditionalMessagesAttachment{{ + FileID: openai.String("file_id"), + Tools: []openai.BetaThreadRunNewParamsAdditionalMessagesAttachmentsToolUnion{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + }}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - }}), - Instructions: openai.F("instructions"), - MaxCompletionTokens: openai.F(int64(256)), - MaxPromptTokens: openai.F(int64(256)), - Metadata: openai.F(shared.MetadataParam{ + }, + }}, + Instructions: openai.String("instructions"), + MaxCompletionTokens: openai.Int(256), + MaxPromptTokens: openai.Int(256), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Model: openai.F(openai.ChatModelO3Mini), - ParallelToolCalls: openai.F(true), - ReasoningEffort: openai.F(openai.BetaThreadRunNewParamsReasoningEffortLow), - Temperature: openai.F(1.000000), - ToolChoice: openai.F[openai.AssistantToolChoiceOptionUnionParam](openai.AssistantToolChoiceOptionAuto(openai.AssistantToolChoiceOptionAutoNone)), - Tools: openai.F([]openai.AssistantToolUnionParam{openai.CodeInterpreterToolParam{ - Type: openai.F(openai.CodeInterpreterToolTypeCodeInterpreter), - }}), - TopP: openai.F(1.000000), - TruncationStrategy: openai.F(openai.BetaThreadRunNewParamsTruncationStrategy{ - Type: openai.F(openai.BetaThreadRunNewParamsTruncationStrategyTypeAuto), - LastMessages: openai.F(int64(1)), - }), + }, + Model: openai.ChatModelO3Mini, + ParallelToolCalls: openai.Bool(true), + ReasoningEffort: openai.BetaThreadRunNewParamsReasoningEffortLow, + Temperature: openai.Float(1), + ToolChoice: openai.AssistantToolChoiceOptionUnionParam{ + OfAuto: "none", + }, + Tools: []openai.AssistantToolUnionParam{{ + OfCodeInterpreter: &openai.CodeInterpreterToolParam{}, + }}, + TopP: openai.Float(1), + TruncationStrategy: openai.BetaThreadRunNewParamsTruncationStrategy{ + Type: "auto", + LastMessages: openai.Int(1), + }, }, ) if err != nil { @@ -119,9 +123,9 @@ func TestBetaThreadRunUpdateWithOptionalParams(t *testing.T) { "thread_id", "run_id", openai.BetaThreadRunUpdateParams{ - Metadata: openai.F(shared.MetadataParam{ + Metadata: shared.MetadataParam{ "foo": "string", - }), + }, }, ) if err != nil { @@ -149,10 +153,10 @@ func TestBetaThreadRunListWithOptionalParams(t *testing.T) { context.TODO(), "thread_id", openai.BetaThreadRunListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaThreadRunListParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Limit: openai.Int(0), + Order: openai.BetaThreadRunListParamsOrderAsc, }, ) if err != nil { @@ -207,10 +211,10 @@ func TestBetaThreadRunSubmitToolOutputsWithOptionalParams(t *testing.T) { "thread_id", "run_id", openai.BetaThreadRunSubmitToolOutputsParams{ - ToolOutputs: openai.F([]openai.BetaThreadRunSubmitToolOutputsParamsToolOutput{{ - Output: openai.F("output"), - ToolCallID: openai.F("tool_call_id"), - }}), + ToolOutputs: []openai.BetaThreadRunSubmitToolOutputsParamsToolOutput{{ + Output: openai.String("output"), + ToolCallID: openai.String("tool_call_id"), + }}, }, ) if err != nil { diff --git a/betathreadrunstep.go b/betathreadrunstep.go index 8fdc27c..1a86fce 100644 --- a/betathreadrunstep.go +++ b/betathreadrunstep.go @@ -4,20 +4,21 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" "net/url" - "reflect" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/shared/constant" ) // BetaThreadRunStepService contains methods and other services that help with @@ -33,8 +34,8 @@ type BetaThreadRunStepService struct { // NewBetaThreadRunStepService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewBetaThreadRunStepService(opts ...option.RequestOption) (r *BetaThreadRunStepService) { - r = &BetaThreadRunStepService{} +func NewBetaThreadRunStepService(opts ...option.RequestOption) (r BetaThreadRunStepService) { + r = BetaThreadRunStepService{} r.Options = opts return } @@ -94,1158 +95,683 @@ func (r *BetaThreadRunStepService) ListAutoPaging(ctx context.Context, threadID // Text output from the Code Interpreter tool call as part of a run step. type CodeInterpreterLogs struct { // The index of the output in the outputs array. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `logs`. - Type CodeInterpreterLogsType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "logs". + Type constant.Logs `json:"type,required"` // The text output from the Code Interpreter tool call. - Logs string `json:"logs"` - JSON codeInterpreterLogsJSON `json:"-"` + Logs string `json:"logs,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + Logs resp.Field + raw string + } `json:"-"` } -// codeInterpreterLogsJSON contains the JSON metadata for the struct -// [CodeInterpreterLogs] -type codeInterpreterLogsJSON struct { - Index apijson.Field - Type apijson.Field - Logs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterLogs) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterLogs) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterLogs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterLogsJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterLogs) implementsCodeInterpreterToolCallDeltaCodeInterpreterOutput() {} - -// Always `logs`. -type CodeInterpreterLogsType string - -const ( - CodeInterpreterLogsTypeLogs CodeInterpreterLogsType = "logs" -) - -func (r CodeInterpreterLogsType) IsKnown() bool { - switch r { - case CodeInterpreterLogsTypeLogs: - return true - } - return false -} - type CodeInterpreterOutputImage struct { // The index of the output in the outputs array. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Always `image`. - Type CodeInterpreterOutputImageType `json:"type,required"` - Image CodeInterpreterOutputImageImage `json:"image"` - JSON codeInterpreterOutputImageJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image". + Type constant.Image `json:"type,required"` + Image CodeInterpreterOutputImageImage `json:"image,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + Image resp.Field + raw string + } `json:"-"` } -// codeInterpreterOutputImageJSON contains the JSON metadata for the struct -// [CodeInterpreterOutputImage] -type codeInterpreterOutputImageJSON struct { - Index apijson.Field - Type apijson.Field - Image apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterOutputImage) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterOutputImage) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterOutputImage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterOutputImageJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterOutputImage) implementsCodeInterpreterToolCallDeltaCodeInterpreterOutput() {} - -// Always `image`. -type CodeInterpreterOutputImageType string - -const ( - CodeInterpreterOutputImageTypeImage CodeInterpreterOutputImageType = "image" -) - -func (r CodeInterpreterOutputImageType) IsKnown() bool { - switch r { - case CodeInterpreterOutputImageTypeImage: - return true - } - return false -} - type CodeInterpreterOutputImageImage struct { // The [file](https://platform.openai.com/docs/api-reference/files) ID of the // image. - FileID string `json:"file_id"` - JSON codeInterpreterOutputImageImageJSON `json:"-"` + FileID string `json:"file_id,omitzero"` + JSON struct { + FileID resp.Field + raw string + } `json:"-"` } -// codeInterpreterOutputImageImageJSON contains the JSON metadata for the struct -// [CodeInterpreterOutputImageImage] -type codeInterpreterOutputImageImageJSON struct { - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterOutputImageImage) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterOutputImageImage) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterOutputImageImage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterOutputImageImageJSON) RawJSON() string { - return r.raw -} - // Details of the Code Interpreter tool call the run step was involved in. type CodeInterpreterToolCall struct { // The ID of the tool call. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Code Interpreter tool call definition. - CodeInterpreter CodeInterpreterToolCallCodeInterpreter `json:"code_interpreter,required"` + CodeInterpreter CodeInterpreterToolCallCodeInterpreter `json:"code_interpreter,omitzero,required"` // The type of tool call. This is always going to be `code_interpreter` for this // type of tool call. - Type CodeInterpreterToolCallType `json:"type,required"` - JSON codeInterpreterToolCallJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "code_interpreter". + Type constant.CodeInterpreter `json:"type,required"` + JSON struct { + ID resp.Field + CodeInterpreter resp.Field + Type resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallJSON contains the JSON metadata for the struct -// [CodeInterpreterToolCall] -type codeInterpreterToolCallJSON struct { - ID apijson.Field - CodeInterpreter apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCall) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCall) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterToolCall) implementsToolCall() {} - // The Code Interpreter tool call definition. type CodeInterpreterToolCallCodeInterpreter struct { // The input to the Code Interpreter tool call. - Input string `json:"input,required"` + Input string `json:"input,omitzero,required"` // The outputs from the Code Interpreter tool call. Code Interpreter can output one // or more items, including text (`logs`) or images (`image`). Each of these are // represented by a different object type. - Outputs []CodeInterpreterToolCallCodeInterpreterOutput `json:"outputs,required"` - JSON codeInterpreterToolCallCodeInterpreterJSON `json:"-"` + Outputs []CodeInterpreterToolCallCodeInterpreterOutputsUnion `json:"outputs,omitzero,required"` + JSON struct { + Input resp.Field + Outputs resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallCodeInterpreterJSON contains the JSON metadata for the -// struct [CodeInterpreterToolCallCodeInterpreter] -type codeInterpreterToolCallCodeInterpreterJSON struct { - Input apijson.Field - Outputs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallCodeInterpreter) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallCodeInterpreter) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallCodeInterpreter) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallCodeInterpreterJSON) RawJSON() string { - return r.raw +type CodeInterpreterToolCallCodeInterpreterOutputsUnion struct { + Logs string `json:"logs"` + Type string `json:"type"` + Image CodeInterpreterToolCallCodeInterpreterOutputsImageImage `json:"image"` + JSON struct { + Logs resp.Field + Type resp.Field + Image resp.Field + raw string + } `json:"-"` } -// Text output from the Code Interpreter tool call as part of a run step. -type CodeInterpreterToolCallCodeInterpreterOutput struct { - // Always `logs`. - Type CodeInterpreterToolCallCodeInterpreterOutputsType `json:"type,required"` - // This field can have the runtime type of - // [CodeInterpreterToolCallCodeInterpreterOutputsImageImage]. - Image interface{} `json:"image"` - // The text output from the Code Interpreter tool call. - Logs string `json:"logs"` - JSON codeInterpreterToolCallCodeInterpreterOutputJSON `json:"-"` - union CodeInterpreterToolCallCodeInterpreterOutputsUnion -} - -// codeInterpreterToolCallCodeInterpreterOutputJSON contains the JSON metadata for -// the struct [CodeInterpreterToolCallCodeInterpreterOutput] -type codeInterpreterToolCallCodeInterpreterOutputJSON struct { - Type apijson.Field - Image apijson.Field - Logs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r codeInterpreterToolCallCodeInterpreterOutputJSON) RawJSON() string { - return r.raw -} - -func (r *CodeInterpreterToolCallCodeInterpreterOutput) UnmarshalJSON(data []byte) (err error) { - *r = CodeInterpreterToolCallCodeInterpreterOutput{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u CodeInterpreterToolCallCodeInterpreterOutputsUnion) Variant() (res struct { + OfLogs *CodeInterpreterToolCallCodeInterpreterOutputsLogs + OfImage *CodeInterpreterToolCallCodeInterpreterOutputsImage +}) { + switch u.Type { + case "logs": + v := u.AsLogs() + res.OfLogs = &v + case "image": + v := u.AsImage() + res.OfImage = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [CodeInterpreterToolCallCodeInterpreterOutputsUnion] interface -// which you can cast to the specific types for more type safety. -// -// Possible runtime types of the union are -// [CodeInterpreterToolCallCodeInterpreterOutputsLogs], -// [CodeInterpreterToolCallCodeInterpreterOutputsImage]. -func (r CodeInterpreterToolCallCodeInterpreterOutput) AsUnion() CodeInterpreterToolCallCodeInterpreterOutputsUnion { - return r.union +func (u CodeInterpreterToolCallCodeInterpreterOutputsUnion) WhichKind() string { + return u.Type } -// Text output from the Code Interpreter tool call as part of a run step. -// -// Union satisfied by [CodeInterpreterToolCallCodeInterpreterOutputsLogs] or -// [CodeInterpreterToolCallCodeInterpreterOutputsImage]. -type CodeInterpreterToolCallCodeInterpreterOutputsUnion interface { - implementsCodeInterpreterToolCallCodeInterpreterOutput() +func (u CodeInterpreterToolCallCodeInterpreterOutputsUnion) AsLogs() (v CodeInterpreterToolCallCodeInterpreterOutputsLogs) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*CodeInterpreterToolCallCodeInterpreterOutputsUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterToolCallCodeInterpreterOutputsLogs{}), - DiscriminatorValue: "logs", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterToolCallCodeInterpreterOutputsImage{}), - DiscriminatorValue: "image", - }, - ) +func (u CodeInterpreterToolCallCodeInterpreterOutputsUnion) AsImage() (v CodeInterpreterToolCallCodeInterpreterOutputsImage) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u CodeInterpreterToolCallCodeInterpreterOutputsUnion) RawJSON() string { return u.JSON.raw } + +func (r *CodeInterpreterToolCallCodeInterpreterOutputsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // Text output from the Code Interpreter tool call as part of a run step. type CodeInterpreterToolCallCodeInterpreterOutputsLogs struct { // The text output from the Code Interpreter tool call. - Logs string `json:"logs,required"` + Logs string `json:"logs,omitzero,required"` // Always `logs`. - Type CodeInterpreterToolCallCodeInterpreterOutputsLogsType `json:"type,required"` - JSON codeInterpreterToolCallCodeInterpreterOutputsLogsJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "logs". + Type constant.Logs `json:"type,required"` + JSON struct { + Logs resp.Field + Type resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallCodeInterpreterOutputsLogsJSON contains the JSON metadata -// for the struct [CodeInterpreterToolCallCodeInterpreterOutputsLogs] -type codeInterpreterToolCallCodeInterpreterOutputsLogsJSON struct { - Logs apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallCodeInterpreterOutputsLogs) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallCodeInterpreterOutputsLogs) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallCodeInterpreterOutputsLogs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallCodeInterpreterOutputsLogsJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterToolCallCodeInterpreterOutputsLogs) implementsCodeInterpreterToolCallCodeInterpreterOutput() { -} - -// Always `logs`. -type CodeInterpreterToolCallCodeInterpreterOutputsLogsType string - -const ( - CodeInterpreterToolCallCodeInterpreterOutputsLogsTypeLogs CodeInterpreterToolCallCodeInterpreterOutputsLogsType = "logs" -) - -func (r CodeInterpreterToolCallCodeInterpreterOutputsLogsType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallCodeInterpreterOutputsLogsTypeLogs: - return true - } - return false -} - type CodeInterpreterToolCallCodeInterpreterOutputsImage struct { - Image CodeInterpreterToolCallCodeInterpreterOutputsImageImage `json:"image,required"` + Image CodeInterpreterToolCallCodeInterpreterOutputsImageImage `json:"image,omitzero,required"` // Always `image`. - Type CodeInterpreterToolCallCodeInterpreterOutputsImageType `json:"type,required"` - JSON codeInterpreterToolCallCodeInterpreterOutputsImageJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "image". + Type constant.Image `json:"type,required"` + JSON struct { + Image resp.Field + Type resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallCodeInterpreterOutputsImageJSON contains the JSON -// metadata for the struct [CodeInterpreterToolCallCodeInterpreterOutputsImage] -type codeInterpreterToolCallCodeInterpreterOutputsImageJSON struct { - Image apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallCodeInterpreterOutputsImage) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallCodeInterpreterOutputsImage) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallCodeInterpreterOutputsImage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallCodeInterpreterOutputsImageJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterToolCallCodeInterpreterOutputsImage) implementsCodeInterpreterToolCallCodeInterpreterOutput() { -} - type CodeInterpreterToolCallCodeInterpreterOutputsImageImage struct { // The [file](https://platform.openai.com/docs/api-reference/files) ID of the // image. - FileID string `json:"file_id,required"` - JSON codeInterpreterToolCallCodeInterpreterOutputsImageImageJSON `json:"-"` + FileID string `json:"file_id,omitzero,required"` + JSON struct { + FileID resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallCodeInterpreterOutputsImageImageJSON contains the JSON -// metadata for the struct -// [CodeInterpreterToolCallCodeInterpreterOutputsImageImage] -type codeInterpreterToolCallCodeInterpreterOutputsImageImageJSON struct { - FileID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallCodeInterpreterOutputsImageImage) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallCodeInterpreterOutputsImageImage) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallCodeInterpreterOutputsImageImage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallCodeInterpreterOutputsImageImageJSON) RawJSON() string { - return r.raw -} - -// Always `image`. -type CodeInterpreterToolCallCodeInterpreterOutputsImageType string - -const ( - CodeInterpreterToolCallCodeInterpreterOutputsImageTypeImage CodeInterpreterToolCallCodeInterpreterOutputsImageType = "image" -) - -func (r CodeInterpreterToolCallCodeInterpreterOutputsImageType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallCodeInterpreterOutputsImageTypeImage: - return true - } - return false -} - -// Always `logs`. -type CodeInterpreterToolCallCodeInterpreterOutputsType string - -const ( - CodeInterpreterToolCallCodeInterpreterOutputsTypeLogs CodeInterpreterToolCallCodeInterpreterOutputsType = "logs" - CodeInterpreterToolCallCodeInterpreterOutputsTypeImage CodeInterpreterToolCallCodeInterpreterOutputsType = "image" -) - -func (r CodeInterpreterToolCallCodeInterpreterOutputsType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallCodeInterpreterOutputsTypeLogs, CodeInterpreterToolCallCodeInterpreterOutputsTypeImage: - return true - } - return false -} - -// The type of tool call. This is always going to be `code_interpreter` for this -// type of tool call. -type CodeInterpreterToolCallType string - -const ( - CodeInterpreterToolCallTypeCodeInterpreter CodeInterpreterToolCallType = "code_interpreter" -) - -func (r CodeInterpreterToolCallType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallTypeCodeInterpreter: - return true - } - return false -} - // Details of the Code Interpreter tool call the run step was involved in. type CodeInterpreterToolCallDelta struct { // The index of the tool call in the tool calls array. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // The type of tool call. This is always going to be `code_interpreter` for this // type of tool call. - Type CodeInterpreterToolCallDeltaType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "code_interpreter". + Type constant.CodeInterpreter `json:"type,required"` // The ID of the tool call. - ID string `json:"id"` + ID string `json:"id,omitzero"` // The Code Interpreter tool call definition. - CodeInterpreter CodeInterpreterToolCallDeltaCodeInterpreter `json:"code_interpreter"` - JSON codeInterpreterToolCallDeltaJSON `json:"-"` + CodeInterpreter CodeInterpreterToolCallDeltaCodeInterpreter `json:"code_interpreter,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + ID resp.Field + CodeInterpreter resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallDeltaJSON contains the JSON metadata for the struct -// [CodeInterpreterToolCallDelta] -type codeInterpreterToolCallDeltaJSON struct { - Index apijson.Field - Type apijson.Field - ID apijson.Field - CodeInterpreter apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallDelta) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallDelta) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallDeltaJSON) RawJSON() string { - return r.raw -} - -func (r CodeInterpreterToolCallDelta) implementsToolCallDelta() {} - -// The type of tool call. This is always going to be `code_interpreter` for this -// type of tool call. -type CodeInterpreterToolCallDeltaType string - -const ( - CodeInterpreterToolCallDeltaTypeCodeInterpreter CodeInterpreterToolCallDeltaType = "code_interpreter" -) - -func (r CodeInterpreterToolCallDeltaType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallDeltaTypeCodeInterpreter: - return true - } - return false -} - // The Code Interpreter tool call definition. type CodeInterpreterToolCallDeltaCodeInterpreter struct { // The input to the Code Interpreter tool call. - Input string `json:"input"` + Input string `json:"input,omitzero"` // The outputs from the Code Interpreter tool call. Code Interpreter can output one // or more items, including text (`logs`) or images (`image`). Each of these are // represented by a different object type. - Outputs []CodeInterpreterToolCallDeltaCodeInterpreterOutput `json:"outputs"` - JSON codeInterpreterToolCallDeltaCodeInterpreterJSON `json:"-"` + Outputs []CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion `json:"outputs,omitzero"` + JSON struct { + Input resp.Field + Outputs resp.Field + raw string + } `json:"-"` } -// codeInterpreterToolCallDeltaCodeInterpreterJSON contains the JSON metadata for -// the struct [CodeInterpreterToolCallDeltaCodeInterpreter] -type codeInterpreterToolCallDeltaCodeInterpreterJSON struct { - Input apijson.Field - Outputs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CodeInterpreterToolCallDeltaCodeInterpreter) UnmarshalJSON(data []byte) (err error) { +func (r CodeInterpreterToolCallDeltaCodeInterpreter) RawJSON() string { return r.JSON.raw } +func (r *CodeInterpreterToolCallDeltaCodeInterpreter) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r codeInterpreterToolCallDeltaCodeInterpreterJSON) RawJSON() string { - return r.raw +type CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion struct { + Index int64 `json:"index"` + Type string `json:"type"` + Logs string `json:"logs"` + Image CodeInterpreterOutputImageImage `json:"image"` + JSON struct { + Index resp.Field + Type resp.Field + Logs resp.Field + Image resp.Field + raw string + } `json:"-"` } -// Text output from the Code Interpreter tool call as part of a run step. -type CodeInterpreterToolCallDeltaCodeInterpreterOutput struct { - // The index of the output in the outputs array. - Index int64 `json:"index,required"` - // Always `logs`. - Type CodeInterpreterToolCallDeltaCodeInterpreterOutputsType `json:"type,required"` - // This field can have the runtime type of [CodeInterpreterOutputImageImage]. - Image interface{} `json:"image"` - // The text output from the Code Interpreter tool call. - Logs string `json:"logs"` - JSON codeInterpreterToolCallDeltaCodeInterpreterOutputJSON `json:"-"` - union CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion -} - -// codeInterpreterToolCallDeltaCodeInterpreterOutputJSON contains the JSON metadata -// for the struct [CodeInterpreterToolCallDeltaCodeInterpreterOutput] -type codeInterpreterToolCallDeltaCodeInterpreterOutputJSON struct { - Index apijson.Field - Type apijson.Field - Image apijson.Field - Logs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r codeInterpreterToolCallDeltaCodeInterpreterOutputJSON) RawJSON() string { - return r.raw -} - -func (r *CodeInterpreterToolCallDeltaCodeInterpreterOutput) UnmarshalJSON(data []byte) (err error) { - *r = CodeInterpreterToolCallDeltaCodeInterpreterOutput{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) Variant() (res struct { + OfLogs *CodeInterpreterLogs + OfImage *CodeInterpreterOutputImage +}) { + switch u.Type { + case "logs": + v := u.AsLogs() + res.OfLogs = &v + case "image": + v := u.AsImage() + res.OfImage = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion] -// interface which you can cast to the specific types for more type safety. -// -// Possible runtime types of the union are [CodeInterpreterLogs], -// [CodeInterpreterOutputImage]. -func (r CodeInterpreterToolCallDeltaCodeInterpreterOutput) AsUnion() CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion { - return r.union +func (u CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) WhichKind() string { + return u.Type } -// Text output from the Code Interpreter tool call as part of a run step. -// -// Union satisfied by [CodeInterpreterLogs] or [CodeInterpreterOutputImage]. -type CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion interface { - implementsCodeInterpreterToolCallDeltaCodeInterpreterOutput() +func (u CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) AsLogs() (v CodeInterpreterLogs) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterLogs{}), - DiscriminatorValue: "logs", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterOutputImage{}), - DiscriminatorValue: "image", - }, - ) +func (u CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) AsImage() (v CodeInterpreterOutputImage) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Always `logs`. -type CodeInterpreterToolCallDeltaCodeInterpreterOutputsType string +func (u CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) RawJSON() string { return u.JSON.raw } -const ( - CodeInterpreterToolCallDeltaCodeInterpreterOutputsTypeLogs CodeInterpreterToolCallDeltaCodeInterpreterOutputsType = "logs" - CodeInterpreterToolCallDeltaCodeInterpreterOutputsTypeImage CodeInterpreterToolCallDeltaCodeInterpreterOutputsType = "image" -) - -func (r CodeInterpreterToolCallDeltaCodeInterpreterOutputsType) IsKnown() bool { - switch r { - case CodeInterpreterToolCallDeltaCodeInterpreterOutputsTypeLogs, CodeInterpreterToolCallDeltaCodeInterpreterOutputsTypeImage: - return true - } - return false +func (r *CodeInterpreterToolCallDeltaCodeInterpreterOutputsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } type FileSearchToolCall struct { // The ID of the tool call object. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // For now, this is always going to be an empty object. - FileSearch FileSearchToolCallFileSearch `json:"file_search,required"` + FileSearch FileSearchToolCallFileSearch `json:"file_search,omitzero,required"` // The type of tool call. This is always going to be `file_search` for this type of // tool call. - Type FileSearchToolCallType `json:"type,required"` - JSON fileSearchToolCallJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` + JSON struct { + ID resp.Field + FileSearch resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallJSON contains the JSON metadata for the struct -// [FileSearchToolCall] -type fileSearchToolCallJSON struct { - ID apijson.Field - FileSearch apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCall) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCall) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallJSON) RawJSON() string { - return r.raw -} - -func (r FileSearchToolCall) implementsToolCall() {} - // For now, this is always going to be an empty object. type FileSearchToolCallFileSearch struct { // The ranking options for the file search. - RankingOptions FileSearchToolCallFileSearchRankingOptions `json:"ranking_options"` + RankingOptions FileSearchToolCallFileSearchRankingOptions `json:"ranking_options,omitzero"` // The results of the file search. - Results []FileSearchToolCallFileSearchResult `json:"results"` - JSON fileSearchToolCallFileSearchJSON `json:"-"` + Results []FileSearchToolCallFileSearchResult `json:"results,omitzero"` + JSON struct { + RankingOptions resp.Field + Results resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallFileSearchJSON contains the JSON metadata for the struct -// [FileSearchToolCallFileSearch] -type fileSearchToolCallFileSearchJSON struct { - RankingOptions apijson.Field - Results apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCallFileSearch) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCallFileSearch) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCallFileSearch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallFileSearchJSON) RawJSON() string { - return r.raw -} - // The ranking options for the file search. type FileSearchToolCallFileSearchRankingOptions struct { // The ranker used for the file search. - Ranker FileSearchToolCallFileSearchRankingOptionsRanker `json:"ranker,required"` + // + // This field can be elided, and will be automatically set as "default_2024_08_21". + Ranker constant.Default2024_08_21 `json:"ranker,required"` // The score threshold for the file search. All values must be a floating point // number between 0 and 1. - ScoreThreshold float64 `json:"score_threshold,required"` - JSON fileSearchToolCallFileSearchRankingOptionsJSON `json:"-"` + ScoreThreshold float64 `json:"score_threshold,omitzero,required"` + JSON struct { + Ranker resp.Field + ScoreThreshold resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallFileSearchRankingOptionsJSON contains the JSON metadata for -// the struct [FileSearchToolCallFileSearchRankingOptions] -type fileSearchToolCallFileSearchRankingOptionsJSON struct { - Ranker apijson.Field - ScoreThreshold apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCallFileSearchRankingOptions) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCallFileSearchRankingOptions) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCallFileSearchRankingOptions) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallFileSearchRankingOptionsJSON) RawJSON() string { - return r.raw -} - -// The ranker used for the file search. -type FileSearchToolCallFileSearchRankingOptionsRanker string - -const ( - FileSearchToolCallFileSearchRankingOptionsRankerDefault2024_08_21 FileSearchToolCallFileSearchRankingOptionsRanker = "default_2024_08_21" -) - -func (r FileSearchToolCallFileSearchRankingOptionsRanker) IsKnown() bool { - switch r { - case FileSearchToolCallFileSearchRankingOptionsRankerDefault2024_08_21: - return true - } - return false -} - // A result instance of the file search. type FileSearchToolCallFileSearchResult struct { // The ID of the file that result was found in. - FileID string `json:"file_id,required"` + FileID string `json:"file_id,omitzero,required"` // The name of the file that result was found in. - FileName string `json:"file_name,required"` + FileName string `json:"file_name,omitzero,required"` // The score of the result. All values must be a floating point number between 0 // and 1. - Score float64 `json:"score,required"` + Score float64 `json:"score,omitzero,required"` // The content of the result that was found. The content is only included if // requested via the include query parameter. - Content []FileSearchToolCallFileSearchResultsContent `json:"content"` - JSON fileSearchToolCallFileSearchResultJSON `json:"-"` + Content []FileSearchToolCallFileSearchResultsContent `json:"content,omitzero"` + JSON struct { + FileID resp.Field + FileName resp.Field + Score resp.Field + Content resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallFileSearchResultJSON contains the JSON metadata for the struct -// [FileSearchToolCallFileSearchResult] -type fileSearchToolCallFileSearchResultJSON struct { - FileID apijson.Field - FileName apijson.Field - Score apijson.Field - Content apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCallFileSearchResult) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCallFileSearchResult) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCallFileSearchResult) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallFileSearchResultJSON) RawJSON() string { - return r.raw -} - type FileSearchToolCallFileSearchResultsContent struct { // The text content of the file. - Text string `json:"text"` + Text string `json:"text,omitzero"` // The type of the content. - Type FileSearchToolCallFileSearchResultsContentType `json:"type"` - JSON fileSearchToolCallFileSearchResultsContentJSON `json:"-"` + // + // Any of "text" + Type string `json:"type"` + JSON struct { + Text resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallFileSearchResultsContentJSON contains the JSON metadata for -// the struct [FileSearchToolCallFileSearchResultsContent] -type fileSearchToolCallFileSearchResultsContentJSON struct { - Text apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCallFileSearchResultsContent) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCallFileSearchResultsContent) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCallFileSearchResultsContent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallFileSearchResultsContentJSON) RawJSON() string { - return r.raw -} - // The type of the content. -type FileSearchToolCallFileSearchResultsContentType string +type FileSearchToolCallFileSearchResultsContentType = string const ( FileSearchToolCallFileSearchResultsContentTypeText FileSearchToolCallFileSearchResultsContentType = "text" ) -func (r FileSearchToolCallFileSearchResultsContentType) IsKnown() bool { - switch r { - case FileSearchToolCallFileSearchResultsContentTypeText: - return true - } - return false -} - -// The type of tool call. This is always going to be `file_search` for this type of -// tool call. -type FileSearchToolCallType string - -const ( - FileSearchToolCallTypeFileSearch FileSearchToolCallType = "file_search" -) - -func (r FileSearchToolCallType) IsKnown() bool { - switch r { - case FileSearchToolCallTypeFileSearch: - return true - } - return false -} - type FileSearchToolCallDelta struct { // For now, this is always going to be an empty object. - FileSearch interface{} `json:"file_search,required"` + FileSearch interface{} `json:"file_search,omitzero,required"` // The index of the tool call in the tool calls array. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // The type of tool call. This is always going to be `file_search` for this type of // tool call. - Type FileSearchToolCallDeltaType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "file_search". + Type constant.FileSearch `json:"type,required"` // The ID of the tool call object. - ID string `json:"id"` - JSON fileSearchToolCallDeltaJSON `json:"-"` + ID string `json:"id,omitzero"` + JSON struct { + FileSearch resp.Field + Index resp.Field + Type resp.Field + ID resp.Field + raw string + } `json:"-"` } -// fileSearchToolCallDeltaJSON contains the JSON metadata for the struct -// [FileSearchToolCallDelta] -type fileSearchToolCallDeltaJSON struct { - FileSearch apijson.Field - Index apijson.Field - Type apijson.Field - ID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileSearchToolCallDelta) UnmarshalJSON(data []byte) (err error) { +func (r FileSearchToolCallDelta) RawJSON() string { return r.JSON.raw } +func (r *FileSearchToolCallDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileSearchToolCallDeltaJSON) RawJSON() string { - return r.raw -} - -func (r FileSearchToolCallDelta) implementsToolCallDelta() {} - -// The type of tool call. This is always going to be `file_search` for this type of -// tool call. -type FileSearchToolCallDeltaType string - -const ( - FileSearchToolCallDeltaTypeFileSearch FileSearchToolCallDeltaType = "file_search" -) - -func (r FileSearchToolCallDeltaType) IsKnown() bool { - switch r { - case FileSearchToolCallDeltaTypeFileSearch: - return true - } - return false -} - type FunctionToolCall struct { // The ID of the tool call object. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The definition of the function that was called. - Function FunctionToolCallFunction `json:"function,required"` + Function FunctionToolCallFunction `json:"function,omitzero,required"` // The type of tool call. This is always going to be `function` for this type of // tool call. - Type FunctionToolCallType `json:"type,required"` - JSON functionToolCallJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + JSON struct { + ID resp.Field + Function resp.Field + Type resp.Field + raw string + } `json:"-"` } -// functionToolCallJSON contains the JSON metadata for the struct -// [FunctionToolCall] -type functionToolCallJSON struct { - ID apijson.Field - Function apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FunctionToolCall) UnmarshalJSON(data []byte) (err error) { +func (r FunctionToolCall) RawJSON() string { return r.JSON.raw } +func (r *FunctionToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r functionToolCallJSON) RawJSON() string { - return r.raw -} - -func (r FunctionToolCall) implementsToolCall() {} - // The definition of the function that was called. type FunctionToolCallFunction struct { // The arguments passed to the function. - Arguments string `json:"arguments,required"` + Arguments string `json:"arguments,omitzero,required"` // The name of the function. - Name string `json:"name,required"` + Name string `json:"name,omitzero,required"` // The output of the function. This will be `null` if the outputs have not been // [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) // yet. - Output string `json:"output,required,nullable"` - JSON functionToolCallFunctionJSON `json:"-"` + Output string `json:"output,omitzero,required,nullable"` + JSON struct { + Arguments resp.Field + Name resp.Field + Output resp.Field + raw string + } `json:"-"` } -// functionToolCallFunctionJSON contains the JSON metadata for the struct -// [FunctionToolCallFunction] -type functionToolCallFunctionJSON struct { - Arguments apijson.Field - Name apijson.Field - Output apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FunctionToolCallFunction) UnmarshalJSON(data []byte) (err error) { +func (r FunctionToolCallFunction) RawJSON() string { return r.JSON.raw } +func (r *FunctionToolCallFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r functionToolCallFunctionJSON) RawJSON() string { - return r.raw -} - -// The type of tool call. This is always going to be `function` for this type of -// tool call. -type FunctionToolCallType string - -const ( - FunctionToolCallTypeFunction FunctionToolCallType = "function" -) - -func (r FunctionToolCallType) IsKnown() bool { - switch r { - case FunctionToolCallTypeFunction: - return true - } - return false -} - type FunctionToolCallDelta struct { // The index of the tool call in the tool calls array. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // The type of tool call. This is always going to be `function` for this type of // tool call. - Type FunctionToolCallDeltaType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` // The ID of the tool call object. - ID string `json:"id"` + ID string `json:"id,omitzero"` // The definition of the function that was called. - Function FunctionToolCallDeltaFunction `json:"function"` - JSON functionToolCallDeltaJSON `json:"-"` + Function FunctionToolCallDeltaFunction `json:"function,omitzero"` + JSON struct { + Index resp.Field + Type resp.Field + ID resp.Field + Function resp.Field + raw string + } `json:"-"` } -// functionToolCallDeltaJSON contains the JSON metadata for the struct -// [FunctionToolCallDelta] -type functionToolCallDeltaJSON struct { - Index apijson.Field - Type apijson.Field - ID apijson.Field - Function apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FunctionToolCallDelta) UnmarshalJSON(data []byte) (err error) { +func (r FunctionToolCallDelta) RawJSON() string { return r.JSON.raw } +func (r *FunctionToolCallDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r functionToolCallDeltaJSON) RawJSON() string { - return r.raw -} - -func (r FunctionToolCallDelta) implementsToolCallDelta() {} - -// The type of tool call. This is always going to be `function` for this type of -// tool call. -type FunctionToolCallDeltaType string - -const ( - FunctionToolCallDeltaTypeFunction FunctionToolCallDeltaType = "function" -) - -func (r FunctionToolCallDeltaType) IsKnown() bool { - switch r { - case FunctionToolCallDeltaTypeFunction: - return true - } - return false -} - // The definition of the function that was called. type FunctionToolCallDeltaFunction struct { // The arguments passed to the function. - Arguments string `json:"arguments"` + Arguments string `json:"arguments,omitzero"` // The name of the function. - Name string `json:"name"` + Name string `json:"name,omitzero"` // The output of the function. This will be `null` if the outputs have not been // [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) // yet. - Output string `json:"output,nullable"` - JSON functionToolCallDeltaFunctionJSON `json:"-"` + Output string `json:"output,omitzero,nullable"` + JSON struct { + Arguments resp.Field + Name resp.Field + Output resp.Field + raw string + } `json:"-"` } -// functionToolCallDeltaFunctionJSON contains the JSON metadata for the struct -// [FunctionToolCallDeltaFunction] -type functionToolCallDeltaFunctionJSON struct { - Arguments apijson.Field - Name apijson.Field - Output apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FunctionToolCallDeltaFunction) UnmarshalJSON(data []byte) (err error) { +func (r FunctionToolCallDeltaFunction) RawJSON() string { return r.JSON.raw } +func (r *FunctionToolCallDeltaFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r functionToolCallDeltaFunctionJSON) RawJSON() string { - return r.raw -} - // Details of the message creation by the run step. type MessageCreationStepDetails struct { - MessageCreation MessageCreationStepDetailsMessageCreation `json:"message_creation,required"` + MessageCreation MessageCreationStepDetailsMessageCreation `json:"message_creation,omitzero,required"` // Always `message_creation`. - Type MessageCreationStepDetailsType `json:"type,required"` - JSON messageCreationStepDetailsJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "message_creation". + Type constant.MessageCreation `json:"type,required"` + JSON struct { + MessageCreation resp.Field + Type resp.Field + raw string + } `json:"-"` } -// messageCreationStepDetailsJSON contains the JSON metadata for the struct -// [MessageCreationStepDetails] -type messageCreationStepDetailsJSON struct { - MessageCreation apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageCreationStepDetails) UnmarshalJSON(data []byte) (err error) { +func (r MessageCreationStepDetails) RawJSON() string { return r.JSON.raw } +func (r *MessageCreationStepDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageCreationStepDetailsJSON) RawJSON() string { - return r.raw -} - -func (r MessageCreationStepDetails) implementsRunStepStepDetails() {} - type MessageCreationStepDetailsMessageCreation struct { // The ID of the message that was created by this run step. - MessageID string `json:"message_id,required"` - JSON messageCreationStepDetailsMessageCreationJSON `json:"-"` + MessageID string `json:"message_id,omitzero,required"` + JSON struct { + MessageID resp.Field + raw string + } `json:"-"` } -// messageCreationStepDetailsMessageCreationJSON contains the JSON metadata for the -// struct [MessageCreationStepDetailsMessageCreation] -type messageCreationStepDetailsMessageCreationJSON struct { - MessageID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *MessageCreationStepDetailsMessageCreation) UnmarshalJSON(data []byte) (err error) { +func (r MessageCreationStepDetailsMessageCreation) RawJSON() string { return r.JSON.raw } +func (r *MessageCreationStepDetailsMessageCreation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r messageCreationStepDetailsMessageCreationJSON) RawJSON() string { - return r.raw -} - -// Always `message_creation`. -type MessageCreationStepDetailsType string - -const ( - MessageCreationStepDetailsTypeMessageCreation MessageCreationStepDetailsType = "message_creation" -) - -func (r MessageCreationStepDetailsType) IsKnown() bool { - switch r { - case MessageCreationStepDetailsTypeMessageCreation: - return true - } - return false -} - // Represents a step in execution of a run. type RunStep struct { // The identifier of the run step, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The ID of the // [assistant](https://platform.openai.com/docs/api-reference/assistants) // associated with the run step. - AssistantID string `json:"assistant_id,required"` + AssistantID string `json:"assistant_id,omitzero,required"` // The Unix timestamp (in seconds) for when the run step was cancelled. - CancelledAt int64 `json:"cancelled_at,required,nullable"` + CancelledAt int64 `json:"cancelled_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run step completed. - CompletedAt int64 `json:"completed_at,required,nullable"` + CompletedAt int64 `json:"completed_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run step was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The Unix timestamp (in seconds) for when the run step expired. A step is // considered expired if the parent run is expired. - ExpiredAt int64 `json:"expired_at,required,nullable"` + ExpiredAt int64 `json:"expired_at,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the run step failed. - FailedAt int64 `json:"failed_at,required,nullable"` + FailedAt int64 `json:"failed_at,omitzero,required,nullable"` // The last error associated with this run step. Will be `null` if there are no // errors. - LastError RunStepLastError `json:"last_error,required,nullable"` + LastError RunStepLastError `json:"last_error,omitzero,required,nullable"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // The object type, which is always `thread.run.step`. - Object RunStepObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "thread.run.step". + Object constant.ThreadRunStep `json:"object,required"` // The ID of the [run](https://platform.openai.com/docs/api-reference/runs) that // this run step is a part of. - RunID string `json:"run_id,required"` + RunID string `json:"run_id,omitzero,required"` // The status of the run step, which can be either `in_progress`, `cancelled`, // `failed`, `completed`, or `expired`. - Status RunStepStatus `json:"status,required"` + // + // Any of "in_progress", "cancelled", "failed", "completed", "expired" + Status string `json:"status,omitzero,required"` // The details of the run step. - StepDetails RunStepStepDetails `json:"step_details,required"` + StepDetails RunStepStepDetailsUnion `json:"step_details,omitzero,required"` // The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) // that was run. - ThreadID string `json:"thread_id,required"` + ThreadID string `json:"thread_id,omitzero,required"` // The type of run step, which can be either `message_creation` or `tool_calls`. - Type RunStepType `json:"type,required"` + // + // Any of "message_creation", "tool_calls" + Type string `json:"type,omitzero,required"` // Usage statistics related to the run step. This value will be `null` while the // run step's status is `in_progress`. - Usage RunStepUsage `json:"usage,required,nullable"` - JSON runStepJSON `json:"-"` + Usage RunStepUsage `json:"usage,omitzero,required,nullable"` + JSON struct { + ID resp.Field + AssistantID resp.Field + CancelledAt resp.Field + CompletedAt resp.Field + CreatedAt resp.Field + ExpiredAt resp.Field + FailedAt resp.Field + LastError resp.Field + Metadata resp.Field + Object resp.Field + RunID resp.Field + Status resp.Field + StepDetails resp.Field + ThreadID resp.Field + Type resp.Field + Usage resp.Field + raw string + } `json:"-"` } -// runStepJSON contains the JSON metadata for the struct [RunStep] -type runStepJSON struct { - ID apijson.Field - AssistantID apijson.Field - CancelledAt apijson.Field - CompletedAt apijson.Field - CreatedAt apijson.Field - ExpiredAt apijson.Field - FailedAt apijson.Field - LastError apijson.Field - Metadata apijson.Field - Object apijson.Field - RunID apijson.Field - Status apijson.Field - StepDetails apijson.Field - ThreadID apijson.Field - Type apijson.Field - Usage apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStep) UnmarshalJSON(data []byte) (err error) { +func (r RunStep) RawJSON() string { return r.JSON.raw } +func (r *RunStep) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepJSON) RawJSON() string { - return r.raw -} - // The last error associated with this run step. Will be `null` if there are no // errors. type RunStepLastError struct { // One of `server_error` or `rate_limit_exceeded`. - Code RunStepLastErrorCode `json:"code,required"` + // + // Any of "server_error", "rate_limit_exceeded" + Code string `json:"code,omitzero,required"` // A human-readable description of the error. - Message string `json:"message,required"` - JSON runStepLastErrorJSON `json:"-"` + Message string `json:"message,omitzero,required"` + JSON struct { + Code resp.Field + Message resp.Field + raw string + } `json:"-"` } -// runStepLastErrorJSON contains the JSON metadata for the struct -// [RunStepLastError] -type runStepLastErrorJSON struct { - Code apijson.Field - Message apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepLastError) UnmarshalJSON(data []byte) (err error) { +func (r RunStepLastError) RawJSON() string { return r.JSON.raw } +func (r *RunStepLastError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepLastErrorJSON) RawJSON() string { - return r.raw -} - // One of `server_error` or `rate_limit_exceeded`. -type RunStepLastErrorCode string +type RunStepLastErrorCode = string const ( RunStepLastErrorCodeServerError RunStepLastErrorCode = "server_error" RunStepLastErrorCodeRateLimitExceeded RunStepLastErrorCode = "rate_limit_exceeded" ) -func (r RunStepLastErrorCode) IsKnown() bool { - switch r { - case RunStepLastErrorCodeServerError, RunStepLastErrorCodeRateLimitExceeded: - return true - } - return false -} - -// The object type, which is always `thread.run.step`. -type RunStepObject string - -const ( - RunStepObjectThreadRunStep RunStepObject = "thread.run.step" -) - -func (r RunStepObject) IsKnown() bool { - switch r { - case RunStepObjectThreadRunStep: - return true - } - return false -} - // The status of the run step, which can be either `in_progress`, `cancelled`, // `failed`, `completed`, or `expired`. -type RunStepStatus string +type RunStepStatus = string const ( RunStepStatusInProgress RunStepStatus = "in_progress" @@ -1255,665 +781,379 @@ const ( RunStepStatusExpired RunStepStatus = "expired" ) -func (r RunStepStatus) IsKnown() bool { - switch r { - case RunStepStatusInProgress, RunStepStatusCancelled, RunStepStatusFailed, RunStepStatusCompleted, RunStepStatusExpired: - return true +type RunStepStepDetailsUnion struct { + MessageCreation MessageCreationStepDetailsMessageCreation `json:"message_creation"` + Type string `json:"type"` + ToolCalls []ToolCallUnion `json:"tool_calls"` + JSON struct { + MessageCreation resp.Field + Type resp.Field + ToolCalls resp.Field + raw string + } `json:"-"` +} + +// note: this function is generated only for discriminated unions +func (u RunStepStepDetailsUnion) Variant() (res struct { + OfMessageCreation *MessageCreationStepDetails + OfToolCalls *ToolCallsStepDetails +}) { + switch u.Type { + case "message_creation": + v := u.AsMessageCreation() + res.OfMessageCreation = &v + case "tool_calls": + v := u.AsToolCalls() + res.OfToolCalls = &v } - return false + return } -// The details of the run step. -type RunStepStepDetails struct { - // Always `message_creation`. - Type RunStepStepDetailsType `json:"type,required"` - // This field can have the runtime type of - // [MessageCreationStepDetailsMessageCreation]. - MessageCreation interface{} `json:"message_creation"` - // This field can have the runtime type of [[]ToolCall]. - ToolCalls interface{} `json:"tool_calls"` - JSON runStepStepDetailsJSON `json:"-"` - union RunStepStepDetailsUnion +func (u RunStepStepDetailsUnion) WhichKind() string { + return u.Type } -// runStepStepDetailsJSON contains the JSON metadata for the struct -// [RunStepStepDetails] -type runStepStepDetailsJSON struct { - Type apijson.Field - MessageCreation apijson.Field - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u RunStepStepDetailsUnion) AsMessageCreation() (v MessageCreationStepDetails) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r runStepStepDetailsJSON) RawJSON() string { - return r.raw +func (u RunStepStepDetailsUnion) AsToolCalls() (v ToolCallsStepDetails) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *RunStepStepDetails) UnmarshalJSON(data []byte) (err error) { - *r = RunStepStepDetails{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) -} +func (u RunStepStepDetailsUnion) RawJSON() string { return u.JSON.raw } -// AsUnion returns a [RunStepStepDetailsUnion] interface which you can cast to the -// specific types for more type safety. -// -// Possible runtime types of the union are [MessageCreationStepDetails], -// [ToolCallsStepDetails]. -func (r RunStepStepDetails) AsUnion() RunStepStepDetailsUnion { - return r.union -} - -// The details of the run step. -// -// Union satisfied by [MessageCreationStepDetails] or [ToolCallsStepDetails]. -type RunStepStepDetailsUnion interface { - implementsRunStepStepDetails() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*RunStepStepDetailsUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(MessageCreationStepDetails{}), - DiscriminatorValue: "message_creation", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolCallsStepDetails{}), - DiscriminatorValue: "tool_calls", - }, - ) -} - -// Always `message_creation`. -type RunStepStepDetailsType string - -const ( - RunStepStepDetailsTypeMessageCreation RunStepStepDetailsType = "message_creation" - RunStepStepDetailsTypeToolCalls RunStepStepDetailsType = "tool_calls" -) - -func (r RunStepStepDetailsType) IsKnown() bool { - switch r { - case RunStepStepDetailsTypeMessageCreation, RunStepStepDetailsTypeToolCalls: - return true - } - return false +func (r *RunStepStepDetailsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The type of run step, which can be either `message_creation` or `tool_calls`. -type RunStepType string +type RunStepType = string const ( RunStepTypeMessageCreation RunStepType = "message_creation" RunStepTypeToolCalls RunStepType = "tool_calls" ) -func (r RunStepType) IsKnown() bool { - switch r { - case RunStepTypeMessageCreation, RunStepTypeToolCalls: - return true - } - return false -} - // Usage statistics related to the run step. This value will be `null` while the // run step's status is `in_progress`. type RunStepUsage struct { // Number of completion tokens used over the course of the run step. - CompletionTokens int64 `json:"completion_tokens,required"` + CompletionTokens int64 `json:"completion_tokens,omitzero,required"` // Number of prompt tokens used over the course of the run step. - PromptTokens int64 `json:"prompt_tokens,required"` + PromptTokens int64 `json:"prompt_tokens,omitzero,required"` // Total number of tokens used (prompt + completion). - TotalTokens int64 `json:"total_tokens,required"` - JSON runStepUsageJSON `json:"-"` + TotalTokens int64 `json:"total_tokens,omitzero,required"` + JSON struct { + CompletionTokens resp.Field + PromptTokens resp.Field + TotalTokens resp.Field + raw string + } `json:"-"` } -// runStepUsageJSON contains the JSON metadata for the struct [RunStepUsage] -type runStepUsageJSON struct { - CompletionTokens apijson.Field - PromptTokens apijson.Field - TotalTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepUsage) UnmarshalJSON(data []byte) (err error) { +func (r RunStepUsage) RawJSON() string { return r.JSON.raw } +func (r *RunStepUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepUsageJSON) RawJSON() string { - return r.raw -} - // The delta containing the fields that have changed on the run step. type RunStepDelta struct { // The details of the run step. - StepDetails RunStepDeltaStepDetails `json:"step_details"` - JSON runStepDeltaJSON `json:"-"` + StepDetails RunStepDeltaStepDetailsUnion `json:"step_details,omitzero"` + JSON struct { + StepDetails resp.Field + raw string + } `json:"-"` } -// runStepDeltaJSON contains the JSON metadata for the struct [RunStepDelta] -type runStepDeltaJSON struct { - StepDetails apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepDelta) UnmarshalJSON(data []byte) (err error) { +func (r RunStepDelta) RawJSON() string { return r.JSON.raw } +func (r *RunStepDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepDeltaJSON) RawJSON() string { - return r.raw +type RunStepDeltaStepDetailsUnion struct { + Type string `json:"type"` + MessageCreation RunStepDeltaMessageDeltaMessageCreation `json:"message_creation"` + ToolCalls []ToolCallDeltaUnion `json:"tool_calls"` + JSON struct { + Type resp.Field + MessageCreation resp.Field + ToolCalls resp.Field + raw string + } `json:"-"` } -// The details of the run step. -type RunStepDeltaStepDetails struct { - // Always `message_creation`. - Type RunStepDeltaStepDetailsType `json:"type,required"` - // This field can have the runtime type of - // [RunStepDeltaMessageDeltaMessageCreation]. - MessageCreation interface{} `json:"message_creation"` - // This field can have the runtime type of [[]ToolCallDelta]. - ToolCalls interface{} `json:"tool_calls"` - JSON runStepDeltaStepDetailsJSON `json:"-"` - union RunStepDeltaStepDetailsUnion -} - -// runStepDeltaStepDetailsJSON contains the JSON metadata for the struct -// [RunStepDeltaStepDetails] -type runStepDeltaStepDetailsJSON struct { - Type apijson.Field - MessageCreation apijson.Field - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r runStepDeltaStepDetailsJSON) RawJSON() string { - return r.raw -} - -func (r *RunStepDeltaStepDetails) UnmarshalJSON(data []byte) (err error) { - *r = RunStepDeltaStepDetails{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u RunStepDeltaStepDetailsUnion) Variant() (res struct { + OfMessageCreation *RunStepDeltaMessageDelta + OfToolCalls *ToolCallDeltaObject +}) { + switch u.Type { + case "message_creation": + v := u.AsMessageCreation() + res.OfMessageCreation = &v + case "tool_calls": + v := u.AsToolCalls() + res.OfToolCalls = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [RunStepDeltaStepDetailsUnion] interface which you can cast to -// the specific types for more type safety. -// -// Possible runtime types of the union are [RunStepDeltaMessageDelta], -// [ToolCallDeltaObject]. -func (r RunStepDeltaStepDetails) AsUnion() RunStepDeltaStepDetailsUnion { - return r.union +func (u RunStepDeltaStepDetailsUnion) WhichKind() string { + return u.Type } -// The details of the run step. -// -// Union satisfied by [RunStepDeltaMessageDelta] or [ToolCallDeltaObject]. -type RunStepDeltaStepDetailsUnion interface { - implementsRunStepDeltaStepDetails() +func (u RunStepDeltaStepDetailsUnion) AsMessageCreation() (v RunStepDeltaMessageDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*RunStepDeltaStepDetailsUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(RunStepDeltaMessageDelta{}), - DiscriminatorValue: "message_creation", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolCallDeltaObject{}), - DiscriminatorValue: "tool_calls", - }, - ) +func (u RunStepDeltaStepDetailsUnion) AsToolCalls() (v ToolCallDeltaObject) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Always `message_creation`. -type RunStepDeltaStepDetailsType string +func (u RunStepDeltaStepDetailsUnion) RawJSON() string { return u.JSON.raw } -const ( - RunStepDeltaStepDetailsTypeMessageCreation RunStepDeltaStepDetailsType = "message_creation" - RunStepDeltaStepDetailsTypeToolCalls RunStepDeltaStepDetailsType = "tool_calls" -) - -func (r RunStepDeltaStepDetailsType) IsKnown() bool { - switch r { - case RunStepDeltaStepDetailsTypeMessageCreation, RunStepDeltaStepDetailsTypeToolCalls: - return true - } - return false +func (r *RunStepDeltaStepDetailsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // Represents a run step delta i.e. any changed fields on a run step during // streaming. type RunStepDeltaEvent struct { // The identifier of the run step, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The delta containing the fields that have changed on the run step. - Delta RunStepDelta `json:"delta,required"` + Delta RunStepDelta `json:"delta,omitzero,required"` // The object type, which is always `thread.run.step.delta`. - Object RunStepDeltaEventObject `json:"object,required"` - JSON runStepDeltaEventJSON `json:"-"` + // + // This field can be elided, and will be automatically set as + // "thread.run.step.delta". + Object constant.ThreadRunStepDelta `json:"object,required"` + JSON struct { + ID resp.Field + Delta resp.Field + Object resp.Field + raw string + } `json:"-"` } -// runStepDeltaEventJSON contains the JSON metadata for the struct -// [RunStepDeltaEvent] -type runStepDeltaEventJSON struct { - ID apijson.Field - Delta apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepDeltaEvent) UnmarshalJSON(data []byte) (err error) { +func (r RunStepDeltaEvent) RawJSON() string { return r.JSON.raw } +func (r *RunStepDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepDeltaEventJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `thread.run.step.delta`. -type RunStepDeltaEventObject string - -const ( - RunStepDeltaEventObjectThreadRunStepDelta RunStepDeltaEventObject = "thread.run.step.delta" -) - -func (r RunStepDeltaEventObject) IsKnown() bool { - switch r { - case RunStepDeltaEventObjectThreadRunStepDelta: - return true - } - return false -} - // Details of the message creation by the run step. type RunStepDeltaMessageDelta struct { // Always `message_creation`. - Type RunStepDeltaMessageDeltaType `json:"type,required"` - MessageCreation RunStepDeltaMessageDeltaMessageCreation `json:"message_creation"` - JSON runStepDeltaMessageDeltaJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "message_creation". + Type constant.MessageCreation `json:"type,required"` + MessageCreation RunStepDeltaMessageDeltaMessageCreation `json:"message_creation,omitzero"` + JSON struct { + Type resp.Field + MessageCreation resp.Field + raw string + } `json:"-"` } -// runStepDeltaMessageDeltaJSON contains the JSON metadata for the struct -// [RunStepDeltaMessageDelta] -type runStepDeltaMessageDeltaJSON struct { - Type apijson.Field - MessageCreation apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepDeltaMessageDelta) UnmarshalJSON(data []byte) (err error) { +func (r RunStepDeltaMessageDelta) RawJSON() string { return r.JSON.raw } +func (r *RunStepDeltaMessageDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepDeltaMessageDeltaJSON) RawJSON() string { - return r.raw -} - -func (r RunStepDeltaMessageDelta) implementsRunStepDeltaStepDetails() {} - -// Always `message_creation`. -type RunStepDeltaMessageDeltaType string - -const ( - RunStepDeltaMessageDeltaTypeMessageCreation RunStepDeltaMessageDeltaType = "message_creation" -) - -func (r RunStepDeltaMessageDeltaType) IsKnown() bool { - switch r { - case RunStepDeltaMessageDeltaTypeMessageCreation: - return true - } - return false -} - type RunStepDeltaMessageDeltaMessageCreation struct { // The ID of the message that was created by this run step. - MessageID string `json:"message_id"` - JSON runStepDeltaMessageDeltaMessageCreationJSON `json:"-"` + MessageID string `json:"message_id,omitzero"` + JSON struct { + MessageID resp.Field + raw string + } `json:"-"` } -// runStepDeltaMessageDeltaMessageCreationJSON contains the JSON metadata for the -// struct [RunStepDeltaMessageDeltaMessageCreation] -type runStepDeltaMessageDeltaMessageCreationJSON struct { - MessageID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *RunStepDeltaMessageDeltaMessageCreation) UnmarshalJSON(data []byte) (err error) { +func (r RunStepDeltaMessageDeltaMessageCreation) RawJSON() string { return r.JSON.raw } +func (r *RunStepDeltaMessageDeltaMessageCreation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r runStepDeltaMessageDeltaMessageCreationJSON) RawJSON() string { - return r.raw -} - type RunStepInclude string const ( RunStepIncludeStepDetailsToolCallsFileSearchResultsContent RunStepInclude = "step_details.tool_calls[*].file_search.results[*].content" ) -func (r RunStepInclude) IsKnown() bool { - switch r { - case RunStepIncludeStepDetailsToolCallsFileSearchResultsContent: - return true +type ToolCallUnion struct { + ID string `json:"id"` + CodeInterpreter CodeInterpreterToolCallCodeInterpreter `json:"code_interpreter"` + Type string `json:"type"` + FileSearch FileSearchToolCallFileSearch `json:"file_search"` + Function FunctionToolCallFunction `json:"function"` + JSON struct { + ID resp.Field + CodeInterpreter resp.Field + Type resp.Field + FileSearch resp.Field + Function resp.Field + raw string + } `json:"-"` +} + +// note: this function is generated only for discriminated unions +func (u ToolCallUnion) Variant() (res struct { + OfCodeInterpreter *CodeInterpreterToolCall + OfFileSearch *FileSearchToolCall + OfFunction *FunctionToolCall +}) { + switch u.Type { + case "code_interpreter": + v := u.AsCodeInterpreter() + res.OfCodeInterpreter = &v + case "file_search": + v := u.AsFileSearch() + res.OfFileSearch = &v + case "function": + v := u.AsFunction() + res.OfFunction = &v } - return false + return } -// Details of the Code Interpreter tool call the run step was involved in. -type ToolCall struct { - // The ID of the tool call. - ID string `json:"id,required"` - // The type of tool call. This is always going to be `code_interpreter` for this - // type of tool call. - Type ToolCallType `json:"type,required"` - // This field can have the runtime type of - // [CodeInterpreterToolCallCodeInterpreter]. - CodeInterpreter interface{} `json:"code_interpreter"` - // This field can have the runtime type of [FileSearchToolCallFileSearch]. - FileSearch interface{} `json:"file_search"` - // This field can have the runtime type of [FunctionToolCallFunction]. - Function interface{} `json:"function"` - JSON toolCallJSON `json:"-"` - union ToolCallUnion +func (u ToolCallUnion) WhichKind() string { + return u.Type } -// toolCallJSON contains the JSON metadata for the struct [ToolCall] -type toolCallJSON struct { - ID apijson.Field - Type apijson.Field - CodeInterpreter apijson.Field - FileSearch apijson.Field - Function apijson.Field - raw string - ExtraFields map[string]apijson.Field +func (u ToolCallUnion) AsCodeInterpreter() (v CodeInterpreterToolCall) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r toolCallJSON) RawJSON() string { - return r.raw +func (u ToolCallUnion) AsFileSearch() (v FileSearchToolCall) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *ToolCall) UnmarshalJSON(data []byte) (err error) { - *r = ToolCall{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +func (u ToolCallUnion) AsFunction() (v FunctionToolCall) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ToolCallUnion) RawJSON() string { return u.JSON.raw } + +func (r *ToolCallUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ToolCallDeltaUnion struct { + Index int64 `json:"index"` + Type string `json:"type"` + ID string `json:"id"` + CodeInterpreter CodeInterpreterToolCallDeltaCodeInterpreter `json:"code_interpreter"` + FileSearch interface{} `json:"file_search"` + Function FunctionToolCallDeltaFunction `json:"function"` + JSON struct { + Index resp.Field + Type resp.Field + ID resp.Field + CodeInterpreter resp.Field + FileSearch resp.Field + Function resp.Field + raw string + } `json:"-"` +} + +// note: this function is generated only for discriminated unions +func (u ToolCallDeltaUnion) Variant() (res struct { + OfCodeInterpreter *CodeInterpreterToolCallDelta + OfFileSearch *FileSearchToolCallDelta + OfFunction *FunctionToolCallDelta +}) { + switch u.Type { + case "code_interpreter": + v := u.AsCodeInterpreter() + res.OfCodeInterpreter = &v + case "file_search": + v := u.AsFileSearch() + res.OfFileSearch = &v + case "function": + v := u.AsFunction() + res.OfFunction = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [ToolCallUnion] interface which you can cast to the specific -// types for more type safety. -// -// Possible runtime types of the union are [CodeInterpreterToolCall], -// [FileSearchToolCall], [FunctionToolCall]. -func (r ToolCall) AsUnion() ToolCallUnion { - return r.union +func (u ToolCallDeltaUnion) WhichKind() string { + return u.Type } -// Details of the Code Interpreter tool call the run step was involved in. -// -// Union satisfied by [CodeInterpreterToolCall], [FileSearchToolCall] or -// [FunctionToolCall]. -type ToolCallUnion interface { - implementsToolCall() +func (u ToolCallDeltaUnion) AsCodeInterpreter() (v CodeInterpreterToolCallDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*ToolCallUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterToolCall{}), - DiscriminatorValue: "code_interpreter", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileSearchToolCall{}), - DiscriminatorValue: "file_search", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FunctionToolCall{}), - DiscriminatorValue: "function", - }, - ) +func (u ToolCallDeltaUnion) AsFileSearch() (v FileSearchToolCallDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// The type of tool call. This is always going to be `code_interpreter` for this -// type of tool call. -type ToolCallType string - -const ( - ToolCallTypeCodeInterpreter ToolCallType = "code_interpreter" - ToolCallTypeFileSearch ToolCallType = "file_search" - ToolCallTypeFunction ToolCallType = "function" -) - -func (r ToolCallType) IsKnown() bool { - switch r { - case ToolCallTypeCodeInterpreter, ToolCallTypeFileSearch, ToolCallTypeFunction: - return true - } - return false +func (u ToolCallDeltaUnion) AsFunction() (v FunctionToolCallDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Details of the Code Interpreter tool call the run step was involved in. -type ToolCallDelta struct { - // The index of the tool call in the tool calls array. - Index int64 `json:"index,required"` - // The type of tool call. This is always going to be `code_interpreter` for this - // type of tool call. - Type ToolCallDeltaType `json:"type,required"` - // The ID of the tool call. - ID string `json:"id"` - // This field can have the runtime type of - // [CodeInterpreterToolCallDeltaCodeInterpreter]. - CodeInterpreter interface{} `json:"code_interpreter"` - // This field can have the runtime type of [interface{}]. - FileSearch interface{} `json:"file_search"` - // This field can have the runtime type of [FunctionToolCallDeltaFunction]. - Function interface{} `json:"function"` - JSON toolCallDeltaJSON `json:"-"` - union ToolCallDeltaUnion -} +func (u ToolCallDeltaUnion) RawJSON() string { return u.JSON.raw } -// toolCallDeltaJSON contains the JSON metadata for the struct [ToolCallDelta] -type toolCallDeltaJSON struct { - Index apijson.Field - Type apijson.Field - ID apijson.Field - CodeInterpreter apijson.Field - FileSearch apijson.Field - Function apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r toolCallDeltaJSON) RawJSON() string { - return r.raw -} - -func (r *ToolCallDelta) UnmarshalJSON(data []byte) (err error) { - *r = ToolCallDelta{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err - } - return apijson.Port(r.union, &r) -} - -// AsUnion returns a [ToolCallDeltaUnion] interface which you can cast to the -// specific types for more type safety. -// -// Possible runtime types of the union are [CodeInterpreterToolCallDelta], -// [FileSearchToolCallDelta], [FunctionToolCallDelta]. -func (r ToolCallDelta) AsUnion() ToolCallDeltaUnion { - return r.union -} - -// Details of the Code Interpreter tool call the run step was involved in. -// -// Union satisfied by [CodeInterpreterToolCallDelta], [FileSearchToolCallDelta] or -// [FunctionToolCallDelta]. -type ToolCallDeltaUnion interface { - implementsToolCallDelta() -} - -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*ToolCallDeltaUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(CodeInterpreterToolCallDelta{}), - DiscriminatorValue: "code_interpreter", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileSearchToolCallDelta{}), - DiscriminatorValue: "file_search", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FunctionToolCallDelta{}), - DiscriminatorValue: "function", - }, - ) -} - -// The type of tool call. This is always going to be `code_interpreter` for this -// type of tool call. -type ToolCallDeltaType string - -const ( - ToolCallDeltaTypeCodeInterpreter ToolCallDeltaType = "code_interpreter" - ToolCallDeltaTypeFileSearch ToolCallDeltaType = "file_search" - ToolCallDeltaTypeFunction ToolCallDeltaType = "function" -) - -func (r ToolCallDeltaType) IsKnown() bool { - switch r { - case ToolCallDeltaTypeCodeInterpreter, ToolCallDeltaTypeFileSearch, ToolCallDeltaTypeFunction: - return true - } - return false +func (r *ToolCallDeltaUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // Details of the tool call. type ToolCallDeltaObject struct { // Always `tool_calls`. - Type ToolCallDeltaObjectType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "tool_calls". + Type constant.ToolCalls `json:"type,required"` // An array of tool calls the run step was involved in. These can be associated // with one of three types of tools: `code_interpreter`, `file_search`, or // `function`. - ToolCalls []ToolCallDelta `json:"tool_calls"` - JSON toolCallDeltaObjectJSON `json:"-"` + ToolCalls []ToolCallDeltaUnion `json:"tool_calls,omitzero"` + JSON struct { + Type resp.Field + ToolCalls resp.Field + raw string + } `json:"-"` } -// toolCallDeltaObjectJSON contains the JSON metadata for the struct -// [ToolCallDeltaObject] -type toolCallDeltaObjectJSON struct { - Type apijson.Field - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ToolCallDeltaObject) UnmarshalJSON(data []byte) (err error) { +func (r ToolCallDeltaObject) RawJSON() string { return r.JSON.raw } +func (r *ToolCallDeltaObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r toolCallDeltaObjectJSON) RawJSON() string { - return r.raw -} - -func (r ToolCallDeltaObject) implementsRunStepDeltaStepDetails() {} - -// Always `tool_calls`. -type ToolCallDeltaObjectType string - -const ( - ToolCallDeltaObjectTypeToolCalls ToolCallDeltaObjectType = "tool_calls" -) - -func (r ToolCallDeltaObjectType) IsKnown() bool { - switch r { - case ToolCallDeltaObjectTypeToolCalls: - return true - } - return false -} - // Details of the tool call. type ToolCallsStepDetails struct { // An array of tool calls the run step was involved in. These can be associated // with one of three types of tools: `code_interpreter`, `file_search`, or // `function`. - ToolCalls []ToolCall `json:"tool_calls,required"` + ToolCalls []ToolCallUnion `json:"tool_calls,omitzero,required"` // Always `tool_calls`. - Type ToolCallsStepDetailsType `json:"type,required"` - JSON toolCallsStepDetailsJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "tool_calls". + Type constant.ToolCalls `json:"type,required"` + JSON struct { + ToolCalls resp.Field + Type resp.Field + raw string + } `json:"-"` } -// toolCallsStepDetailsJSON contains the JSON metadata for the struct -// [ToolCallsStepDetails] -type toolCallsStepDetailsJSON struct { - ToolCalls apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ToolCallsStepDetails) UnmarshalJSON(data []byte) (err error) { +func (r ToolCallsStepDetails) RawJSON() string { return r.JSON.raw } +func (r *ToolCallsStepDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r toolCallsStepDetailsJSON) RawJSON() string { - return r.raw -} - -func (r ToolCallsStepDetails) implementsRunStepStepDetails() {} - -// Always `tool_calls`. -type ToolCallsStepDetailsType string - -const ( - ToolCallsStepDetailsTypeToolCalls ToolCallsStepDetailsType = "tool_calls" -) - -func (r ToolCallsStepDetailsType) IsKnown() bool { - switch r { - case ToolCallsStepDetailsTypeToolCalls: - return true - } - return false -} - type BetaThreadRunStepGetParams struct { // A list of additional fields to include in the response. Currently the only // supported value is `step_details.tool_calls[*].file_search.results[*].content` @@ -1922,9 +1162,12 @@ type BetaThreadRunStepGetParams struct { // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - Include param.Field[[]RunStepInclude] `query:"include"` + Include []RunStepInclude `query:"include,omitzero"` + apiobject } +func (f BetaThreadRunStepGetParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaThreadRunStepGetParams]'s query parameters as // `url.Values`. func (r BetaThreadRunStepGetParams) URLQuery() (v url.Values) { @@ -1939,12 +1182,12 @@ type BetaThreadRunStepListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // A list of additional fields to include in the response. Currently the only // supported value is `step_details.tool_calls[*].file_search.results[*].content` // to fetch the file search result content. @@ -1952,15 +1195,20 @@ type BetaThreadRunStepListParams struct { // See the // [file search tool documentation](https://platform.openai.com/docs/assistants/tools/file-search#customizing-file-search-settings) // for more information. - Include param.Field[[]RunStepInclude] `query:"include"` + Include []RunStepInclude `query:"include,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaThreadRunStepListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaThreadRunStepListParamsOrder `query:"order,omitzero"` + apiobject } +func (f BetaThreadRunStepListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaThreadRunStepListParams]'s query parameters as // `url.Values`. func (r BetaThreadRunStepListParams) URLQuery() (v url.Values) { @@ -1978,11 +1226,3 @@ const ( BetaThreadRunStepListParamsOrderAsc BetaThreadRunStepListParamsOrder = "asc" BetaThreadRunStepListParamsOrderDesc BetaThreadRunStepListParamsOrder = "desc" ) - -func (r BetaThreadRunStepListParamsOrder) IsKnown() bool { - switch r { - case BetaThreadRunStepListParamsOrderAsc, BetaThreadRunStepListParamsOrderDesc: - return true - } - return false -} diff --git a/betathreadrunstep_test.go b/betathreadrunstep_test.go index cbae844..7da3a8e 100644 --- a/betathreadrunstep_test.go +++ b/betathreadrunstep_test.go @@ -31,7 +31,7 @@ func TestBetaThreadRunStepGetWithOptionalParams(t *testing.T) { "run_id", "step_id", openai.BetaThreadRunStepGetParams{ - Include: openai.F([]openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}), + Include: []openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}, }, ) if err != nil { @@ -60,11 +60,11 @@ func TestBetaThreadRunStepListWithOptionalParams(t *testing.T) { "thread_id", "run_id", openai.BetaThreadRunStepListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Include: openai.F([]openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaThreadRunStepListParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Include: []openai.RunStepInclude{openai.RunStepIncludeStepDetailsToolCallsFileSearchResultsContent}, + Limit: openai.Int(0), + Order: openai.BetaThreadRunStepListParamsOrderAsc, }, ) if err != nil { diff --git a/betavectorstore.go b/betavectorstore.go index 8f7930b..65328f0 100644 --- a/betavectorstore.go +++ b/betavectorstore.go @@ -4,20 +4,21 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" "net/url" - "reflect" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/shared/constant" ) // BetaVectorStoreService contains methods and other services that help with @@ -28,15 +29,15 @@ import ( // the [NewBetaVectorStoreService] method instead. type BetaVectorStoreService struct { Options []option.RequestOption - Files *BetaVectorStoreFileService - FileBatches *BetaVectorStoreFileBatchService + Files BetaVectorStoreFileService + FileBatches BetaVectorStoreFileBatchService } // NewBetaVectorStoreService generates a new service that applies the given options // to each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewBetaVectorStoreService(opts ...option.RequestOption) (r *BetaVectorStoreService) { - r = &BetaVectorStoreService{} +func NewBetaVectorStoreService(opts ...option.RequestOption) (r BetaVectorStoreService) { + r = BetaVectorStoreService{} r.Options = opts r.Files = NewBetaVectorStoreFileService(opts...) r.FileBatches = NewBetaVectorStoreFileBatchService(opts...) @@ -118,148 +119,98 @@ func (r *BetaVectorStoreService) Delete(ctx context.Context, vectorStoreID strin // `800` and `chunk_overlap_tokens` of `400`. type AutoFileChunkingStrategyParam struct { // Always `auto`. - Type param.Field[AutoFileChunkingStrategyParamType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "auto". + Type constant.Auto `json:"type,required"` + apiobject } +func (f AutoFileChunkingStrategyParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r AutoFileChunkingStrategyParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow AutoFileChunkingStrategyParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r AutoFileChunkingStrategyParam) implementsFileChunkingStrategyParamUnion() {} - -// Always `auto`. -type AutoFileChunkingStrategyParamType string - -const ( - AutoFileChunkingStrategyParamTypeAuto AutoFileChunkingStrategyParamType = "auto" -) - -func (r AutoFileChunkingStrategyParamType) IsKnown() bool { - switch r { - case AutoFileChunkingStrategyParamTypeAuto: - return true - } - return false -} - -// The strategy used to chunk the file. -type FileChunkingStrategy struct { - // Always `static`. - Type FileChunkingStrategyType `json:"type,required"` +type FileChunkingStrategyUnion struct { Static StaticFileChunkingStrategy `json:"static"` - JSON fileChunkingStrategyJSON `json:"-"` - union FileChunkingStrategyUnion + Type string `json:"type"` + JSON struct { + Static resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fileChunkingStrategyJSON contains the JSON metadata for the struct -// [FileChunkingStrategy] -type fileChunkingStrategyJSON struct { - Type apijson.Field - Static apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r fileChunkingStrategyJSON) RawJSON() string { - return r.raw -} - -func (r *FileChunkingStrategy) UnmarshalJSON(data []byte) (err error) { - *r = FileChunkingStrategy{} - err = apijson.UnmarshalRoot(data, &r.union) - if err != nil { - return err +// note: this function is generated only for discriminated unions +func (u FileChunkingStrategyUnion) Variant() (res struct { + OfStatic *StaticFileChunkingStrategyObject + OfOther *OtherFileChunkingStrategyObject +}) { + switch u.Type { + case "static": + v := u.AsStatic() + res.OfStatic = &v + case "other": + v := u.AsOther() + res.OfOther = &v } - return apijson.Port(r.union, &r) + return } -// AsUnion returns a [FileChunkingStrategyUnion] interface which you can cast to -// the specific types for more type safety. -// -// Possible runtime types of the union are [StaticFileChunkingStrategyObject], -// [OtherFileChunkingStrategyObject]. -func (r FileChunkingStrategy) AsUnion() FileChunkingStrategyUnion { - return r.union +func (u FileChunkingStrategyUnion) WhichKind() string { + return u.Type } -// The strategy used to chunk the file. -// -// Union satisfied by [StaticFileChunkingStrategyObject] or -// [OtherFileChunkingStrategyObject]. -type FileChunkingStrategyUnion interface { - implementsFileChunkingStrategy() +func (u FileChunkingStrategyUnion) AsStatic() (v StaticFileChunkingStrategyObject) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FileChunkingStrategyUnion)(nil)).Elem(), - "type", - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(StaticFileChunkingStrategyObject{}), - DiscriminatorValue: "static", - }, - apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(OtherFileChunkingStrategyObject{}), - DiscriminatorValue: "other", - }, - ) +func (u FileChunkingStrategyUnion) AsOther() (v OtherFileChunkingStrategyObject) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Always `static`. -type FileChunkingStrategyType string +func (u FileChunkingStrategyUnion) RawJSON() string { return u.JSON.raw } -const ( - FileChunkingStrategyTypeStatic FileChunkingStrategyType = "static" - FileChunkingStrategyTypeOther FileChunkingStrategyType = "other" -) +func (r *FileChunkingStrategyUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r FileChunkingStrategyType) IsKnown() bool { - switch r { - case FileChunkingStrategyTypeStatic, FileChunkingStrategyTypeOther: - return true +func NewFileChunkingStrategyParamOfStatic(static StaticFileChunkingStrategyParam) FileChunkingStrategyParamUnion { + var variant StaticFileChunkingStrategyObjectParam + variant.Static = static + return FileChunkingStrategyParamUnion{OfStatic: &variant} +} + +// Only one field can be non-zero +type FileChunkingStrategyParamUnion struct { + OfAuto *AutoFileChunkingStrategyParam + OfStatic *StaticFileChunkingStrategyObjectParam + apiunion +} + +func (u FileChunkingStrategyParamUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u FileChunkingStrategyParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FileChunkingStrategyParamUnion](u.OfAuto, u.OfStatic) +} + +func (u FileChunkingStrategyParamUnion) GetStatic() *StaticFileChunkingStrategyParam { + if vt := u.OfStatic; vt != nil { + return &vt.Static } - return false + return nil } -// The chunking strategy used to chunk the file(s). If not set, will use the `auto` -// strategy. Only applicable if `file_ids` is non-empty. -type FileChunkingStrategyParam struct { - // Always `auto`. - Type param.Field[FileChunkingStrategyParamType] `json:"type,required"` - Static param.Field[StaticFileChunkingStrategyParam] `json:"static"` -} - -func (r FileChunkingStrategyParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r FileChunkingStrategyParam) implementsFileChunkingStrategyParamUnion() {} - -// The chunking strategy used to chunk the file(s). If not set, will use the `auto` -// strategy. Only applicable if `file_ids` is non-empty. -// -// Satisfied by [AutoFileChunkingStrategyParam], -// [StaticFileChunkingStrategyObjectParam], [FileChunkingStrategyParam]. -type FileChunkingStrategyParamUnion interface { - implementsFileChunkingStrategyParamUnion() -} - -// Always `auto`. -type FileChunkingStrategyParamType string - -const ( - FileChunkingStrategyParamTypeAuto FileChunkingStrategyParamType = "auto" - FileChunkingStrategyParamTypeStatic FileChunkingStrategyParamType = "static" -) - -func (r FileChunkingStrategyParamType) IsKnown() bool { - switch r { - case FileChunkingStrategyParamTypeAuto, FileChunkingStrategyParamTypeStatic: - return true +func (u FileChunkingStrategyParamUnion) GetType() *string { + if vt := u.OfAuto; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfStatic; vt != nil { + return (*string)(&vt.Type) } - return false + return nil } // This is returned when the chunking strategy is unknown. Typically, this is @@ -267,265 +218,190 @@ func (r FileChunkingStrategyParamType) IsKnown() bool { // introduced in the API. type OtherFileChunkingStrategyObject struct { // Always `other`. - Type OtherFileChunkingStrategyObjectType `json:"type,required"` - JSON otherFileChunkingStrategyObjectJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "other". + Type constant.Other `json:"type,required"` + JSON struct { + Type resp.Field + raw string + } `json:"-"` } -// otherFileChunkingStrategyObjectJSON contains the JSON metadata for the struct -// [OtherFileChunkingStrategyObject] -type otherFileChunkingStrategyObjectJSON struct { - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *OtherFileChunkingStrategyObject) UnmarshalJSON(data []byte) (err error) { +func (r OtherFileChunkingStrategyObject) RawJSON() string { return r.JSON.raw } +func (r *OtherFileChunkingStrategyObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r otherFileChunkingStrategyObjectJSON) RawJSON() string { - return r.raw -} - -func (r OtherFileChunkingStrategyObject) implementsFileChunkingStrategy() {} - -// Always `other`. -type OtherFileChunkingStrategyObjectType string - -const ( - OtherFileChunkingStrategyObjectTypeOther OtherFileChunkingStrategyObjectType = "other" -) - -func (r OtherFileChunkingStrategyObjectType) IsKnown() bool { - switch r { - case OtherFileChunkingStrategyObjectTypeOther: - return true - } - return false -} - type StaticFileChunkingStrategy struct { // The number of tokens that overlap between chunks. The default value is `400`. // // Note that the overlap must not exceed half of `max_chunk_size_tokens`. - ChunkOverlapTokens int64 `json:"chunk_overlap_tokens,required"` + ChunkOverlapTokens int64 `json:"chunk_overlap_tokens,omitzero,required"` // The maximum number of tokens in each chunk. The default value is `800`. The // minimum value is `100` and the maximum value is `4096`. - MaxChunkSizeTokens int64 `json:"max_chunk_size_tokens,required"` - JSON staticFileChunkingStrategyJSON `json:"-"` + MaxChunkSizeTokens int64 `json:"max_chunk_size_tokens,omitzero,required"` + JSON struct { + ChunkOverlapTokens resp.Field + MaxChunkSizeTokens resp.Field + raw string + } `json:"-"` } -// staticFileChunkingStrategyJSON contains the JSON metadata for the struct -// [StaticFileChunkingStrategy] -type staticFileChunkingStrategyJSON struct { - ChunkOverlapTokens apijson.Field - MaxChunkSizeTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *StaticFileChunkingStrategy) UnmarshalJSON(data []byte) (err error) { +func (r StaticFileChunkingStrategy) RawJSON() string { return r.JSON.raw } +func (r *StaticFileChunkingStrategy) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r staticFileChunkingStrategyJSON) RawJSON() string { - return r.raw +// ToParam converts this StaticFileChunkingStrategy to a +// StaticFileChunkingStrategyParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// StaticFileChunkingStrategyParam.IsOverridden() +func (r StaticFileChunkingStrategy) ToParam() StaticFileChunkingStrategyParam { + return param.Override[StaticFileChunkingStrategyParam](r.RawJSON()) } type StaticFileChunkingStrategyParam struct { // The number of tokens that overlap between chunks. The default value is `400`. // // Note that the overlap must not exceed half of `max_chunk_size_tokens`. - ChunkOverlapTokens param.Field[int64] `json:"chunk_overlap_tokens,required"` + ChunkOverlapTokens param.Int `json:"chunk_overlap_tokens,omitzero,required"` // The maximum number of tokens in each chunk. The default value is `800`. The // minimum value is `100` and the maximum value is `4096`. - MaxChunkSizeTokens param.Field[int64] `json:"max_chunk_size_tokens,required"` + MaxChunkSizeTokens param.Int `json:"max_chunk_size_tokens,omitzero,required"` + apiobject } +func (f StaticFileChunkingStrategyParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r StaticFileChunkingStrategyParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow StaticFileChunkingStrategyParam + return param.MarshalObject(r, (*shadow)(&r)) } type StaticFileChunkingStrategyObject struct { - Static StaticFileChunkingStrategy `json:"static,required"` + Static StaticFileChunkingStrategy `json:"static,omitzero,required"` // Always `static`. - Type StaticFileChunkingStrategyObjectType `json:"type,required"` - JSON staticFileChunkingStrategyObjectJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "static". + Type constant.Static `json:"type,required"` + JSON struct { + Static resp.Field + Type resp.Field + raw string + } `json:"-"` } -// staticFileChunkingStrategyObjectJSON contains the JSON metadata for the struct -// [StaticFileChunkingStrategyObject] -type staticFileChunkingStrategyObjectJSON struct { - Static apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *StaticFileChunkingStrategyObject) UnmarshalJSON(data []byte) (err error) { +func (r StaticFileChunkingStrategyObject) RawJSON() string { return r.JSON.raw } +func (r *StaticFileChunkingStrategyObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r staticFileChunkingStrategyObjectJSON) RawJSON() string { - return r.raw -} - -func (r StaticFileChunkingStrategyObject) implementsFileChunkingStrategy() {} - -// Always `static`. -type StaticFileChunkingStrategyObjectType string - -const ( - StaticFileChunkingStrategyObjectTypeStatic StaticFileChunkingStrategyObjectType = "static" -) - -func (r StaticFileChunkingStrategyObjectType) IsKnown() bool { - switch r { - case StaticFileChunkingStrategyObjectTypeStatic: - return true - } - return false -} - type StaticFileChunkingStrategyObjectParam struct { - Static param.Field[StaticFileChunkingStrategyParam] `json:"static,required"` + Static StaticFileChunkingStrategyParam `json:"static,omitzero,required"` // Always `static`. - Type param.Field[StaticFileChunkingStrategyObjectParamType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "static". + Type constant.Static `json:"type,required"` + apiobject +} + +func (f StaticFileChunkingStrategyObjectParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r StaticFileChunkingStrategyObjectParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r StaticFileChunkingStrategyObjectParam) implementsFileChunkingStrategyParamUnion() {} - -// Always `static`. -type StaticFileChunkingStrategyObjectParamType string - -const ( - StaticFileChunkingStrategyObjectParamTypeStatic StaticFileChunkingStrategyObjectParamType = "static" -) - -func (r StaticFileChunkingStrategyObjectParamType) IsKnown() bool { - switch r { - case StaticFileChunkingStrategyObjectParamTypeStatic: - return true - } - return false + type shadow StaticFileChunkingStrategyObjectParam + return param.MarshalObject(r, (*shadow)(&r)) } // A vector store is a collection of processed files can be used by the // `file_search` tool. type VectorStore struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the vector store was created. - CreatedAt int64 `json:"created_at,required"` - FileCounts VectorStoreFileCounts `json:"file_counts,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` + FileCounts VectorStoreFileCounts `json:"file_counts,omitzero,required"` // The Unix timestamp (in seconds) for when the vector store was last active. - LastActiveAt int64 `json:"last_active_at,required,nullable"` + LastActiveAt int64 `json:"last_active_at,omitzero,required,nullable"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata shared.Metadata `json:"metadata,required,nullable"` + Metadata shared.Metadata `json:"metadata,omitzero,required,nullable"` // The name of the vector store. - Name string `json:"name,required"` + Name string `json:"name,omitzero,required"` // The object type, which is always `vector_store`. - Object VectorStoreObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "vector_store". + Object constant.VectorStore `json:"object,required"` // The status of the vector store, which can be either `expired`, `in_progress`, or // `completed`. A status of `completed` indicates that the vector store is ready // for use. - Status VectorStoreStatus `json:"status,required"` + // + // Any of "expired", "in_progress", "completed" + Status string `json:"status,omitzero,required"` // The total number of bytes used by the files in the vector store. - UsageBytes int64 `json:"usage_bytes,required"` + UsageBytes int64 `json:"usage_bytes,omitzero,required"` // The expiration policy for a vector store. - ExpiresAfter VectorStoreExpiresAfter `json:"expires_after"` + ExpiresAfter VectorStoreExpiresAfter `json:"expires_after,omitzero"` // The Unix timestamp (in seconds) for when the vector store will expire. - ExpiresAt int64 `json:"expires_at,nullable"` - JSON vectorStoreJSON `json:"-"` + ExpiresAt int64 `json:"expires_at,omitzero,nullable"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + FileCounts resp.Field + LastActiveAt resp.Field + Metadata resp.Field + Name resp.Field + Object resp.Field + Status resp.Field + UsageBytes resp.Field + ExpiresAfter resp.Field + ExpiresAt resp.Field + raw string + } `json:"-"` } -// vectorStoreJSON contains the JSON metadata for the struct [VectorStore] -type vectorStoreJSON struct { - ID apijson.Field - CreatedAt apijson.Field - FileCounts apijson.Field - LastActiveAt apijson.Field - Metadata apijson.Field - Name apijson.Field - Object apijson.Field - Status apijson.Field - UsageBytes apijson.Field - ExpiresAfter apijson.Field - ExpiresAt apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStore) UnmarshalJSON(data []byte) (err error) { +func (r VectorStore) RawJSON() string { return r.JSON.raw } +func (r *VectorStore) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreJSON) RawJSON() string { - return r.raw -} - type VectorStoreFileCounts struct { // The number of files that were cancelled. - Cancelled int64 `json:"cancelled,required"` + Cancelled int64 `json:"cancelled,omitzero,required"` // The number of files that have been successfully processed. - Completed int64 `json:"completed,required"` + Completed int64 `json:"completed,omitzero,required"` // The number of files that have failed to process. - Failed int64 `json:"failed,required"` + Failed int64 `json:"failed,omitzero,required"` // The number of files that are currently being processed. - InProgress int64 `json:"in_progress,required"` + InProgress int64 `json:"in_progress,omitzero,required"` // The total number of files. - Total int64 `json:"total,required"` - JSON vectorStoreFileCountsJSON `json:"-"` + Total int64 `json:"total,omitzero,required"` + JSON struct { + Cancelled resp.Field + Completed resp.Field + Failed resp.Field + InProgress resp.Field + Total resp.Field + raw string + } `json:"-"` } -// vectorStoreFileCountsJSON contains the JSON metadata for the struct -// [VectorStoreFileCounts] -type vectorStoreFileCountsJSON struct { - Cancelled apijson.Field - Completed apijson.Field - Failed apijson.Field - InProgress apijson.Field - Total apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFileCounts) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFileCounts) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFileCounts) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileCountsJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `vector_store`. -type VectorStoreObject string - -const ( - VectorStoreObjectVectorStore VectorStoreObject = "vector_store" -) - -func (r VectorStoreObject) IsKnown() bool { - switch r { - case VectorStoreObjectVectorStore: - return true - } - return false -} - // The status of the vector store, which can be either `expired`, `in_progress`, or // `completed`. A status of `completed` indicates that the vector store is ready // for use. -type VectorStoreStatus string +type VectorStoreStatus = string const ( VectorStoreStatusExpired VectorStoreStatus = "expired" @@ -533,195 +409,137 @@ const ( VectorStoreStatusCompleted VectorStoreStatus = "completed" ) -func (r VectorStoreStatus) IsKnown() bool { - switch r { - case VectorStoreStatusExpired, VectorStoreStatusInProgress, VectorStoreStatusCompleted: - return true - } - return false -} - // The expiration policy for a vector store. type VectorStoreExpiresAfter struct { // Anchor timestamp after which the expiration policy applies. Supported anchors: // `last_active_at`. - Anchor VectorStoreExpiresAfterAnchor `json:"anchor,required"` + // + // This field can be elided, and will be automatically set as "last_active_at". + Anchor constant.LastActiveAt `json:"anchor,required"` // The number of days after the anchor time that the vector store will expire. - Days int64 `json:"days,required"` - JSON vectorStoreExpiresAfterJSON `json:"-"` + Days int64 `json:"days,omitzero,required"` + JSON struct { + Anchor resp.Field + Days resp.Field + raw string + } `json:"-"` } -// vectorStoreExpiresAfterJSON contains the JSON metadata for the struct -// [VectorStoreExpiresAfter] -type vectorStoreExpiresAfterJSON struct { - Anchor apijson.Field - Days apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreExpiresAfter) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreExpiresAfter) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreExpiresAfter) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreExpiresAfterJSON) RawJSON() string { - return r.raw -} - -// Anchor timestamp after which the expiration policy applies. Supported anchors: -// `last_active_at`. -type VectorStoreExpiresAfterAnchor string - -const ( - VectorStoreExpiresAfterAnchorLastActiveAt VectorStoreExpiresAfterAnchor = "last_active_at" -) - -func (r VectorStoreExpiresAfterAnchor) IsKnown() bool { - switch r { - case VectorStoreExpiresAfterAnchorLastActiveAt: - return true - } - return false -} - type VectorStoreDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object VectorStoreDeletedObject `json:"object,required"` - JSON vectorStoreDeletedJSON `json:"-"` + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as + // "vector_store.deleted". + Object constant.VectorStoreDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// vectorStoreDeletedJSON contains the JSON metadata for the struct -// [VectorStoreDeleted] -type vectorStoreDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreDeleted) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreDeleted) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreDeletedJSON) RawJSON() string { - return r.raw -} - -type VectorStoreDeletedObject string - -const ( - VectorStoreDeletedObjectVectorStoreDeleted VectorStoreDeletedObject = "vector_store.deleted" -) - -func (r VectorStoreDeletedObject) IsKnown() bool { - switch r { - case VectorStoreDeletedObjectVectorStoreDeleted: - return true - } - return false -} - type BetaVectorStoreNewParams struct { // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` // The expiration policy for a vector store. - ExpiresAfter param.Field[BetaVectorStoreNewParamsExpiresAfter] `json:"expires_after"` + ExpiresAfter BetaVectorStoreNewParamsExpiresAfter `json:"expires_after,omitzero"` // A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that // the vector store should use. Useful for tools like `file_search` that can access // files. - FileIDs param.Field[[]string] `json:"file_ids"` + FileIDs []string `json:"file_ids,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // The name of the vector store. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` + apiobject } +func (f BetaVectorStoreNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaVectorStoreNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaVectorStoreNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // The expiration policy for a vector store. type BetaVectorStoreNewParamsExpiresAfter struct { // Anchor timestamp after which the expiration policy applies. Supported anchors: // `last_active_at`. - Anchor param.Field[BetaVectorStoreNewParamsExpiresAfterAnchor] `json:"anchor,required"` + // + // This field can be elided, and will be automatically set as "last_active_at". + Anchor constant.LastActiveAt `json:"anchor,required"` // The number of days after the anchor time that the vector store will expire. - Days param.Field[int64] `json:"days,required"` + Days param.Int `json:"days,omitzero,required"` + apiobject +} + +func (f BetaVectorStoreNewParamsExpiresAfter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaVectorStoreNewParamsExpiresAfter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -// Anchor timestamp after which the expiration policy applies. Supported anchors: -// `last_active_at`. -type BetaVectorStoreNewParamsExpiresAfterAnchor string - -const ( - BetaVectorStoreNewParamsExpiresAfterAnchorLastActiveAt BetaVectorStoreNewParamsExpiresAfterAnchor = "last_active_at" -) - -func (r BetaVectorStoreNewParamsExpiresAfterAnchor) IsKnown() bool { - switch r { - case BetaVectorStoreNewParamsExpiresAfterAnchorLastActiveAt: - return true - } - return false + type shadow BetaVectorStoreNewParamsExpiresAfter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaVectorStoreUpdateParams struct { // The expiration policy for a vector store. - ExpiresAfter param.Field[BetaVectorStoreUpdateParamsExpiresAfter] `json:"expires_after"` + ExpiresAfter BetaVectorStoreUpdateParamsExpiresAfter `json:"expires_after,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // The name of the vector store. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` + apiobject } +func (f BetaVectorStoreUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaVectorStoreUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaVectorStoreUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } // The expiration policy for a vector store. type BetaVectorStoreUpdateParamsExpiresAfter struct { // Anchor timestamp after which the expiration policy applies. Supported anchors: // `last_active_at`. - Anchor param.Field[BetaVectorStoreUpdateParamsExpiresAfterAnchor] `json:"anchor,required"` + // + // This field can be elided, and will be automatically set as "last_active_at". + Anchor constant.LastActiveAt `json:"anchor,required"` // The number of days after the anchor time that the vector store will expire. - Days param.Field[int64] `json:"days,required"` + Days param.Int `json:"days,omitzero,required"` + apiobject +} + +func (f BetaVectorStoreUpdateParamsExpiresAfter) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r BetaVectorStoreUpdateParamsExpiresAfter) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -// Anchor timestamp after which the expiration policy applies. Supported anchors: -// `last_active_at`. -type BetaVectorStoreUpdateParamsExpiresAfterAnchor string - -const ( - BetaVectorStoreUpdateParamsExpiresAfterAnchorLastActiveAt BetaVectorStoreUpdateParamsExpiresAfterAnchor = "last_active_at" -) - -func (r BetaVectorStoreUpdateParamsExpiresAfterAnchor) IsKnown() bool { - switch r { - case BetaVectorStoreUpdateParamsExpiresAfterAnchorLastActiveAt: - return true - } - return false + type shadow BetaVectorStoreUpdateParamsExpiresAfter + return param.MarshalObject(r, (*shadow)(&r)) } type BetaVectorStoreListParams struct { @@ -729,20 +547,25 @@ type BetaVectorStoreListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaVectorStoreListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaVectorStoreListParamsOrder `query:"order,omitzero"` + apiobject } +func (f BetaVectorStoreListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaVectorStoreListParams]'s query parameters as // `url.Values`. func (r BetaVectorStoreListParams) URLQuery() (v url.Values) { @@ -760,11 +583,3 @@ const ( BetaVectorStoreListParamsOrderAsc BetaVectorStoreListParamsOrder = "asc" BetaVectorStoreListParamsOrderDesc BetaVectorStoreListParamsOrder = "desc" ) - -func (r BetaVectorStoreListParamsOrder) IsKnown() bool { - switch r { - case BetaVectorStoreListParamsOrderAsc, BetaVectorStoreListParamsOrderDesc: - return true - } - return false -} diff --git a/betavectorstore_test.go b/betavectorstore_test.go index a845765..ec49333 100644 --- a/betavectorstore_test.go +++ b/betavectorstore_test.go @@ -27,18 +27,17 @@ func TestBetaVectorStoreNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.VectorStores.New(context.TODO(), openai.BetaVectorStoreNewParams{ - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), - ExpiresAfter: openai.F(openai.BetaVectorStoreNewParamsExpiresAfter{ - Anchor: openai.F(openai.BetaVectorStoreNewParamsExpiresAfterAnchorLastActiveAt), - Days: openai.F(int64(1)), - }), - FileIDs: openai.F([]string{"string"}), - Metadata: openai.F(shared.MetadataParam{ + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, + ExpiresAfter: openai.BetaVectorStoreNewParamsExpiresAfter{ + Days: openai.Int(1), + }, + FileIDs: []string{"string"}, + Metadata: shared.MetadataParam{ "foo": "string", - }), - Name: openai.F("name"), + }, + Name: openai.String("name"), }) if err != nil { var apierr *openai.Error @@ -87,14 +86,13 @@ func TestBetaVectorStoreUpdateWithOptionalParams(t *testing.T) { context.TODO(), "vector_store_id", openai.BetaVectorStoreUpdateParams{ - ExpiresAfter: openai.F(openai.BetaVectorStoreUpdateParamsExpiresAfter{ - Anchor: openai.F(openai.BetaVectorStoreUpdateParamsExpiresAfterAnchorLastActiveAt), - Days: openai.F(int64(1)), - }), - Metadata: openai.F(shared.MetadataParam{ + ExpiresAfter: openai.BetaVectorStoreUpdateParamsExpiresAfter{ + Days: openai.Int(1), + }, + Metadata: shared.MetadataParam{ "foo": "string", - }), - Name: openai.F("name"), + }, + Name: openai.String("name"), }, ) if err != nil { @@ -119,10 +117,10 @@ func TestBetaVectorStoreListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Beta.VectorStores.List(context.TODO(), openai.BetaVectorStoreListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaVectorStoreListParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Limit: openai.Int(0), + Order: openai.BetaVectorStoreListParamsOrderAsc, }) if err != nil { var apierr *openai.Error diff --git a/betavectorstorefile.go b/betavectorstorefile.go index a4cdc5c..3a803dc 100644 --- a/betavectorstorefile.go +++ b/betavectorstorefile.go @@ -11,10 +11,12 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // BetaVectorStoreFileService contains methods and other services that help with @@ -30,8 +32,8 @@ type BetaVectorStoreFileService struct { // NewBetaVectorStoreFileService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewBetaVectorStoreFileService(opts ...option.RequestOption) (r *BetaVectorStoreFileService) { - r = &BetaVectorStoreFileService{} +func NewBetaVectorStoreFileService(opts ...option.RequestOption) (r BetaVectorStoreFileService) { + r = BetaVectorStoreFileService{} r.Options = opts return } @@ -118,82 +120,73 @@ func (r *BetaVectorStoreFileService) Delete(ctx context.Context, vectorStoreID s // A list of files attached to a vector store. type VectorStoreFile struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the vector store file was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The last error associated with this vector store file. Will be `null` if there // are no errors. - LastError VectorStoreFileLastError `json:"last_error,required,nullable"` + LastError VectorStoreFileLastError `json:"last_error,omitzero,required,nullable"` // The object type, which is always `vector_store.file`. - Object VectorStoreFileObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "vector_store.file". + Object constant.VectorStoreFile `json:"object,required"` // The status of the vector store file, which can be either `in_progress`, // `completed`, `cancelled`, or `failed`. The status `completed` indicates that the // vector store file is ready for use. - Status VectorStoreFileStatus `json:"status,required"` + // + // Any of "in_progress", "completed", "cancelled", "failed" + Status string `json:"status,omitzero,required"` // The total vector store usage in bytes. Note that this may be different from the // original file size. - UsageBytes int64 `json:"usage_bytes,required"` + UsageBytes int64 `json:"usage_bytes,omitzero,required"` // The ID of the // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // that the [File](https://platform.openai.com/docs/api-reference/files) is // attached to. - VectorStoreID string `json:"vector_store_id,required"` + VectorStoreID string `json:"vector_store_id,omitzero,required"` // The strategy used to chunk the file. - ChunkingStrategy FileChunkingStrategy `json:"chunking_strategy"` - JSON vectorStoreFileJSON `json:"-"` + ChunkingStrategy FileChunkingStrategyUnion `json:"chunking_strategy,omitzero"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + LastError resp.Field + Object resp.Field + Status resp.Field + UsageBytes resp.Field + VectorStoreID resp.Field + ChunkingStrategy resp.Field + raw string + } `json:"-"` } -// vectorStoreFileJSON contains the JSON metadata for the struct [VectorStoreFile] -type vectorStoreFileJSON struct { - ID apijson.Field - CreatedAt apijson.Field - LastError apijson.Field - Object apijson.Field - Status apijson.Field - UsageBytes apijson.Field - VectorStoreID apijson.Field - ChunkingStrategy apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFile) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFile) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFile) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileJSON) RawJSON() string { - return r.raw -} - // The last error associated with this vector store file. Will be `null` if there // are no errors. type VectorStoreFileLastError struct { // One of `server_error` or `rate_limit_exceeded`. - Code VectorStoreFileLastErrorCode `json:"code,required"` + // + // Any of "server_error", "unsupported_file", "invalid_file" + Code string `json:"code,omitzero,required"` // A human-readable description of the error. - Message string `json:"message,required"` - JSON vectorStoreFileLastErrorJSON `json:"-"` + Message string `json:"message,omitzero,required"` + JSON struct { + Code resp.Field + Message resp.Field + raw string + } `json:"-"` } -// vectorStoreFileLastErrorJSON contains the JSON metadata for the struct -// [VectorStoreFileLastError] -type vectorStoreFileLastErrorJSON struct { - Code apijson.Field - Message apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFileLastError) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFileLastError) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFileLastError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileLastErrorJSON) RawJSON() string { - return r.raw -} - // One of `server_error` or `rate_limit_exceeded`. -type VectorStoreFileLastErrorCode string +type VectorStoreFileLastErrorCode = string const ( VectorStoreFileLastErrorCodeServerError VectorStoreFileLastErrorCode = "server_error" @@ -201,33 +194,10 @@ const ( VectorStoreFileLastErrorCodeInvalidFile VectorStoreFileLastErrorCode = "invalid_file" ) -func (r VectorStoreFileLastErrorCode) IsKnown() bool { - switch r { - case VectorStoreFileLastErrorCodeServerError, VectorStoreFileLastErrorCodeUnsupportedFile, VectorStoreFileLastErrorCodeInvalidFile: - return true - } - return false -} - -// The object type, which is always `vector_store.file`. -type VectorStoreFileObject string - -const ( - VectorStoreFileObjectVectorStoreFile VectorStoreFileObject = "vector_store.file" -) - -func (r VectorStoreFileObject) IsKnown() bool { - switch r { - case VectorStoreFileObjectVectorStoreFile: - return true - } - return false -} - // The status of the vector store file, which can be either `in_progress`, // `completed`, `cancelled`, or `failed`. The status `completed` indicates that the // vector store file is ready for use. -type VectorStoreFileStatus string +type VectorStoreFileStatus = string const ( VectorStoreFileStatusInProgress VectorStoreFileStatus = "in_progress" @@ -236,65 +206,41 @@ const ( VectorStoreFileStatusFailed VectorStoreFileStatus = "failed" ) -func (r VectorStoreFileStatus) IsKnown() bool { - switch r { - case VectorStoreFileStatusInProgress, VectorStoreFileStatusCompleted, VectorStoreFileStatusCancelled, VectorStoreFileStatusFailed: - return true - } - return false -} - type VectorStoreFileDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object VectorStoreFileDeletedObject `json:"object,required"` - JSON vectorStoreFileDeletedJSON `json:"-"` + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as + // "vector_store.file.deleted". + Object constant.VectorStoreFileDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// vectorStoreFileDeletedJSON contains the JSON metadata for the struct -// [VectorStoreFileDeleted] -type vectorStoreFileDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFileDeleted) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFileDeleted) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFileDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileDeletedJSON) RawJSON() string { - return r.raw -} - -type VectorStoreFileDeletedObject string - -const ( - VectorStoreFileDeletedObjectVectorStoreFileDeleted VectorStoreFileDeletedObject = "vector_store.file.deleted" -) - -func (r VectorStoreFileDeletedObject) IsKnown() bool { - switch r { - case VectorStoreFileDeletedObjectVectorStoreFileDeleted: - return true - } - return false -} - type BetaVectorStoreFileNewParams struct { // A [File](https://platform.openai.com/docs/api-reference/files) ID that the // vector store should use. Useful for tools like `file_search` that can access // files. - FileID param.Field[string] `json:"file_id,required"` + FileID param.String `json:"file_id,omitzero,required"` // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` + apiobject } +func (f BetaVectorStoreFileNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaVectorStoreFileNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaVectorStoreFileNewParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaVectorStoreFileListParams struct { @@ -302,22 +248,29 @@ type BetaVectorStoreFileListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`. - Filter param.Field[BetaVectorStoreFileListParamsFilter] `query:"filter"` + // + // Any of "in_progress", "completed", "failed", "cancelled" + Filter BetaVectorStoreFileListParamsFilter `query:"filter,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaVectorStoreFileListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaVectorStoreFileListParamsOrder `query:"order,omitzero"` + apiobject } +func (f BetaVectorStoreFileListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [BetaVectorStoreFileListParams]'s query parameters as // `url.Values`. func (r BetaVectorStoreFileListParams) URLQuery() (v url.Values) { @@ -337,14 +290,6 @@ const ( BetaVectorStoreFileListParamsFilterCancelled BetaVectorStoreFileListParamsFilter = "cancelled" ) -func (r BetaVectorStoreFileListParamsFilter) IsKnown() bool { - switch r { - case BetaVectorStoreFileListParamsFilterInProgress, BetaVectorStoreFileListParamsFilterCompleted, BetaVectorStoreFileListParamsFilterFailed, BetaVectorStoreFileListParamsFilterCancelled: - return true - } - return false -} - // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. type BetaVectorStoreFileListParamsOrder string @@ -353,11 +298,3 @@ const ( BetaVectorStoreFileListParamsOrderAsc BetaVectorStoreFileListParamsOrder = "asc" BetaVectorStoreFileListParamsOrderDesc BetaVectorStoreFileListParamsOrder = "desc" ) - -func (r BetaVectorStoreFileListParamsOrder) IsKnown() bool { - switch r { - case BetaVectorStoreFileListParamsOrderAsc, BetaVectorStoreFileListParamsOrderDesc: - return true - } - return false -} diff --git a/betavectorstorefile_test.go b/betavectorstorefile_test.go index edeb5dc..ba24b7e 100644 --- a/betavectorstorefile_test.go +++ b/betavectorstorefile_test.go @@ -29,10 +29,10 @@ func TestBetaVectorStoreFileNewWithOptionalParams(t *testing.T) { context.TODO(), "vs_abc123", openai.BetaVectorStoreFileNewParams{ - FileID: openai.F("file_id"), - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), + FileID: openai.String("file_id"), + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, }, ) if err != nil { @@ -86,11 +86,11 @@ func TestBetaVectorStoreFileListWithOptionalParams(t *testing.T) { context.TODO(), "vector_store_id", openai.BetaVectorStoreFileListParams{ - After: openai.F("after"), - Before: openai.F("before"), - Filter: openai.F(openai.BetaVectorStoreFileListParamsFilterInProgress), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaVectorStoreFileListParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Filter: openai.BetaVectorStoreFileListParamsFilterInProgress, + Limit: openai.Int(0), + Order: openai.BetaVectorStoreFileListParamsOrderAsc, }, ) if err != nil { diff --git a/betavectorstorefilebatch.go b/betavectorstorefilebatch.go index cf888d9..0d5e1a9 100644 --- a/betavectorstorefilebatch.go +++ b/betavectorstorefilebatch.go @@ -11,10 +11,12 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // BetaVectorStoreFileBatchService contains methods and other services that help @@ -30,8 +32,8 @@ type BetaVectorStoreFileBatchService struct { // NewBetaVectorStoreFileBatchService generates a new service that applies the // given options to each request. These options are applied after the parent // client's options (if there is one), and before any request-specific options. -func NewBetaVectorStoreFileBatchService(opts ...option.RequestOption) (r *BetaVectorStoreFileBatchService) { - r = &BetaVectorStoreFileBatchService{} +func NewBetaVectorStoreFileBatchService(opts ...option.RequestOption) (r BetaVectorStoreFileBatchService) { + r = BetaVectorStoreFileBatchService{} r.Options = opts return } @@ -118,97 +120,71 @@ func (r *BetaVectorStoreFileBatchService) ListFilesAutoPaging(ctx context.Contex // A batch of files attached to a vector store. type VectorStoreFileBatch struct { // The identifier, which can be referenced in API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the vector store files batch was // created. - CreatedAt int64 `json:"created_at,required"` - FileCounts VectorStoreFileBatchFileCounts `json:"file_counts,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` + FileCounts VectorStoreFileBatchFileCounts `json:"file_counts,omitzero,required"` // The object type, which is always `vector_store.file_batch`. - Object VectorStoreFileBatchObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as + // "vector_store.files_batch". + Object constant.VectorStoreFilesBatch `json:"object,required"` // The status of the vector store files batch, which can be either `in_progress`, // `completed`, `cancelled` or `failed`. - Status VectorStoreFileBatchStatus `json:"status,required"` + // + // Any of "in_progress", "completed", "cancelled", "failed" + Status string `json:"status,omitzero,required"` // The ID of the // [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) // that the [File](https://platform.openai.com/docs/api-reference/files) is // attached to. - VectorStoreID string `json:"vector_store_id,required"` - JSON vectorStoreFileBatchJSON `json:"-"` + VectorStoreID string `json:"vector_store_id,omitzero,required"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + FileCounts resp.Field + Object resp.Field + Status resp.Field + VectorStoreID resp.Field + raw string + } `json:"-"` } -// vectorStoreFileBatchJSON contains the JSON metadata for the struct -// [VectorStoreFileBatch] -type vectorStoreFileBatchJSON struct { - ID apijson.Field - CreatedAt apijson.Field - FileCounts apijson.Field - Object apijson.Field - Status apijson.Field - VectorStoreID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFileBatch) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFileBatch) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFileBatch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileBatchJSON) RawJSON() string { - return r.raw -} - type VectorStoreFileBatchFileCounts struct { // The number of files that where cancelled. - Cancelled int64 `json:"cancelled,required"` + Cancelled int64 `json:"cancelled,omitzero,required"` // The number of files that have been processed. - Completed int64 `json:"completed,required"` + Completed int64 `json:"completed,omitzero,required"` // The number of files that have failed to process. - Failed int64 `json:"failed,required"` + Failed int64 `json:"failed,omitzero,required"` // The number of files that are currently being processed. - InProgress int64 `json:"in_progress,required"` + InProgress int64 `json:"in_progress,omitzero,required"` // The total number of files. - Total int64 `json:"total,required"` - JSON vectorStoreFileBatchFileCountsJSON `json:"-"` + Total int64 `json:"total,omitzero,required"` + JSON struct { + Cancelled resp.Field + Completed resp.Field + Failed resp.Field + InProgress resp.Field + Total resp.Field + raw string + } `json:"-"` } -// vectorStoreFileBatchFileCountsJSON contains the JSON metadata for the struct -// [VectorStoreFileBatchFileCounts] -type vectorStoreFileBatchFileCountsJSON struct { - Cancelled apijson.Field - Completed apijson.Field - Failed apijson.Field - InProgress apijson.Field - Total apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *VectorStoreFileBatchFileCounts) UnmarshalJSON(data []byte) (err error) { +func (r VectorStoreFileBatchFileCounts) RawJSON() string { return r.JSON.raw } +func (r *VectorStoreFileBatchFileCounts) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r vectorStoreFileBatchFileCountsJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `vector_store.file_batch`. -type VectorStoreFileBatchObject string - -const ( - VectorStoreFileBatchObjectVectorStoreFilesBatch VectorStoreFileBatchObject = "vector_store.files_batch" -) - -func (r VectorStoreFileBatchObject) IsKnown() bool { - switch r { - case VectorStoreFileBatchObjectVectorStoreFilesBatch: - return true - } - return false -} - // The status of the vector store files batch, which can be either `in_progress`, // `completed`, `cancelled` or `failed`. -type VectorStoreFileBatchStatus string +type VectorStoreFileBatchStatus = string const ( VectorStoreFileBatchStatusInProgress VectorStoreFileBatchStatus = "in_progress" @@ -217,26 +193,22 @@ const ( VectorStoreFileBatchStatusFailed VectorStoreFileBatchStatus = "failed" ) -func (r VectorStoreFileBatchStatus) IsKnown() bool { - switch r { - case VectorStoreFileBatchStatusInProgress, VectorStoreFileBatchStatusCompleted, VectorStoreFileBatchStatusCancelled, VectorStoreFileBatchStatusFailed: - return true - } - return false -} - type BetaVectorStoreFileBatchNewParams struct { // A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that // the vector store should use. Useful for tools like `file_search` that can access // files. - FileIDs param.Field[[]string] `json:"file_ids,required"` + FileIDs []string `json:"file_ids,omitzero,required"` // The chunking strategy used to chunk the file(s). If not set, will use the `auto` // strategy. Only applicable if `file_ids` is non-empty. - ChunkingStrategy param.Field[FileChunkingStrategyParamUnion] `json:"chunking_strategy"` + ChunkingStrategy FileChunkingStrategyParamUnion `json:"chunking_strategy,omitzero"` + apiobject } +func (f BetaVectorStoreFileBatchNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r BetaVectorStoreFileBatchNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow BetaVectorStoreFileBatchNewParams + return param.MarshalObject(r, (*shadow)(&r)) } type BetaVectorStoreFileBatchListFilesParams struct { @@ -244,20 +216,29 @@ type BetaVectorStoreFileBatchListFilesParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A cursor for use in pagination. `before` is an object ID that defines your place // in the list. For instance, if you make a list request and receive 100 objects, // starting with obj_foo, your subsequent call can include before=obj_foo in order // to fetch the previous page of the list. - Before param.Field[string] `query:"before"` + Before param.String `query:"before,omitzero"` // Filter by file status. One of `in_progress`, `completed`, `failed`, `cancelled`. - Filter param.Field[BetaVectorStoreFileBatchListFilesParamsFilter] `query:"filter"` + // + // Any of "in_progress", "completed", "failed", "cancelled" + Filter BetaVectorStoreFileBatchListFilesParamsFilter `query:"filter,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 100, and the default is 20. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[BetaVectorStoreFileBatchListFilesParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order BetaVectorStoreFileBatchListFilesParamsOrder `query:"order,omitzero"` + apiobject +} + +func (f BetaVectorStoreFileBatchListFilesParams) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } // URLQuery serializes [BetaVectorStoreFileBatchListFilesParams]'s query parameters @@ -279,14 +260,6 @@ const ( BetaVectorStoreFileBatchListFilesParamsFilterCancelled BetaVectorStoreFileBatchListFilesParamsFilter = "cancelled" ) -func (r BetaVectorStoreFileBatchListFilesParamsFilter) IsKnown() bool { - switch r { - case BetaVectorStoreFileBatchListFilesParamsFilterInProgress, BetaVectorStoreFileBatchListFilesParamsFilterCompleted, BetaVectorStoreFileBatchListFilesParamsFilterFailed, BetaVectorStoreFileBatchListFilesParamsFilterCancelled: - return true - } - return false -} - // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. type BetaVectorStoreFileBatchListFilesParamsOrder string @@ -295,11 +268,3 @@ const ( BetaVectorStoreFileBatchListFilesParamsOrderAsc BetaVectorStoreFileBatchListFilesParamsOrder = "asc" BetaVectorStoreFileBatchListFilesParamsOrderDesc BetaVectorStoreFileBatchListFilesParamsOrder = "desc" ) - -func (r BetaVectorStoreFileBatchListFilesParamsOrder) IsKnown() bool { - switch r { - case BetaVectorStoreFileBatchListFilesParamsOrderAsc, BetaVectorStoreFileBatchListFilesParamsOrderDesc: - return true - } - return false -} diff --git a/betavectorstorefilebatch_test.go b/betavectorstorefilebatch_test.go index 28848f1..05a5d5e 100644 --- a/betavectorstorefilebatch_test.go +++ b/betavectorstorefilebatch_test.go @@ -29,10 +29,10 @@ func TestBetaVectorStoreFileBatchNewWithOptionalParams(t *testing.T) { context.TODO(), "vs_abc123", openai.BetaVectorStoreFileBatchNewParams{ - FileIDs: openai.F([]string{"string"}), - ChunkingStrategy: openai.F[openai.FileChunkingStrategyParamUnion](openai.AutoFileChunkingStrategyParam{ - Type: openai.F(openai.AutoFileChunkingStrategyParamTypeAuto), - }), + FileIDs: []string{"string"}, + ChunkingStrategy: openai.FileChunkingStrategyParamUnion{ + OfAuto: &openai.AutoFileChunkingStrategyParam{}, + }, }, ) if err != nil { @@ -113,11 +113,11 @@ func TestBetaVectorStoreFileBatchListFilesWithOptionalParams(t *testing.T) { "vector_store_id", "batch_id", openai.BetaVectorStoreFileBatchListFilesParams{ - After: openai.F("after"), - Before: openai.F("before"), - Filter: openai.F(openai.BetaVectorStoreFileBatchListFilesParamsFilterInProgress), - Limit: openai.F(int64(0)), - Order: openai.F(openai.BetaVectorStoreFileBatchListFilesParamsOrderAsc), + After: openai.String("after"), + Before: openai.String("before"), + Filter: openai.BetaVectorStoreFileBatchListFilesParamsFilterInProgress, + Limit: openai.Int(0), + Order: openai.BetaVectorStoreFileBatchListFilesParamsOrderAsc, }, ) if err != nil { diff --git a/chat.go b/chat.go index 0a050eb..856396e 100644 --- a/chat.go +++ b/chat.go @@ -14,14 +14,14 @@ import ( // the [NewChatService] method instead. type ChatService struct { Options []option.RequestOption - Completions *ChatCompletionService + Completions ChatCompletionService } // NewChatService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewChatService(opts ...option.RequestOption) (r *ChatService) { - r = &ChatService{} +func NewChatService(opts ...option.RequestOption) (r ChatService) { + r = ChatService{} r.Options = opts r.Completions = NewChatCompletionService(opts...) return diff --git a/chatcompletion.go b/chatcompletion.go index 78f8cb3..2741dde 100644 --- a/chatcompletion.go +++ b/chatcompletion.go @@ -11,12 +11,14 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/packages/ssestream" "github.com/openai/openai-go/shared" + "github.com/openai/openai-go/shared/constant" ) // ChatCompletionService contains methods and other services that help with @@ -27,14 +29,14 @@ import ( // the [NewChatCompletionService] method instead. type ChatCompletionService struct { Options []option.RequestOption - Messages *ChatCompletionMessageService + Messages ChatCompletionMessageService } // NewChatCompletionService generates a new service that applies the given options // to each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewChatCompletionService(opts ...option.RequestOption) (r *ChatCompletionService) { - r = &ChatCompletionService{} +func NewChatCompletionService(opts ...option.RequestOption) (r ChatCompletionService) { + r = ChatCompletionService{} r.Options = opts r.Messages = NewChatCompletionMessageService(opts...) return @@ -148,50 +150,47 @@ func (r *ChatCompletionService) Delete(ctx context.Context, completionID string, // input. type ChatCompletion struct { // A unique identifier for the chat completion. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // A list of chat completion choices. Can be more than one if `n` is greater // than 1. - Choices []ChatCompletionChoice `json:"choices,required"` + Choices []ChatCompletionChoice `json:"choices,omitzero,required"` // The Unix timestamp (in seconds) of when the chat completion was created. - Created int64 `json:"created,required"` + Created int64 `json:"created,omitzero,required"` // The model used for the chat completion. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always `chat.completion`. - Object ChatCompletionObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "chat.completion". + Object constant.ChatCompletion `json:"object,required"` // The service tier used for processing the request. - ServiceTier ChatCompletionServiceTier `json:"service_tier,nullable"` + // + // Any of "scale", "default" + ServiceTier string `json:"service_tier,omitzero,nullable"` // This fingerprint represents the backend configuration that the model runs with. // // Can be used in conjunction with the `seed` request parameter to understand when // backend changes have been made that might impact determinism. - SystemFingerprint string `json:"system_fingerprint"` + SystemFingerprint string `json:"system_fingerprint,omitzero"` // Usage statistics for the completion request. - Usage CompletionUsage `json:"usage"` - JSON chatCompletionJSON `json:"-"` + Usage CompletionUsage `json:"usage,omitzero"` + JSON struct { + ID resp.Field + Choices resp.Field + Created resp.Field + Model resp.Field + Object resp.Field + ServiceTier resp.Field + SystemFingerprint resp.Field + Usage resp.Field + raw string + } `json:"-"` } -// chatCompletionJSON contains the JSON metadata for the struct [ChatCompletion] -type chatCompletionJSON struct { - ID apijson.Field - Choices apijson.Field - Created apijson.Field - Model apijson.Field - Object apijson.Field - ServiceTier apijson.Field - SystemFingerprint apijson.Field - Usage apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletion) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletion) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionJSON) RawJSON() string { - return r.raw -} - type ChatCompletionChoice struct { // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum @@ -199,42 +198,36 @@ type ChatCompletionChoice struct { // content was omitted due to a flag from our content filters, `tool_calls` if the // model called a tool, or `function_call` (deprecated) if the model called a // function. - FinishReason ChatCompletionChoicesFinishReason `json:"finish_reason,required"` + // + // Any of "stop", "length", "tool_calls", "content_filter", "function_call" + FinishReason string `json:"finish_reason,omitzero,required"` // The index of the choice in the list of choices. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Log probability information for the choice. - Logprobs ChatCompletionChoicesLogprobs `json:"logprobs,required,nullable"` + Logprobs ChatCompletionChoicesLogprobs `json:"logprobs,omitzero,required,nullable"` // A chat completion message generated by the model. - Message ChatCompletionMessage `json:"message,required"` - JSON chatCompletionChoiceJSON `json:"-"` + Message ChatCompletionMessage `json:"message,omitzero,required"` + JSON struct { + FinishReason resp.Field + Index resp.Field + Logprobs resp.Field + Message resp.Field + raw string + } `json:"-"` } -// chatCompletionChoiceJSON contains the JSON metadata for the struct -// [ChatCompletionChoice] -type chatCompletionChoiceJSON struct { - FinishReason apijson.Field - Index apijson.Field - Logprobs apijson.Field - Message apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChoice) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChoice) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChoice) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChoiceJSON) RawJSON() string { - return r.raw -} - // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum // number of tokens specified in the request was reached, `content_filter` if // content was omitted due to a flag from our content filters, `tool_calls` if the // model called a tool, or `function_call` (deprecated) if the model called a // function. -type ChatCompletionChoicesFinishReason string +type ChatCompletionChoicesFinishReason = string const ( ChatCompletionChoicesFinishReasonStop ChatCompletionChoicesFinishReason = "stop" @@ -244,169 +237,121 @@ const ( ChatCompletionChoicesFinishReasonFunctionCall ChatCompletionChoicesFinishReason = "function_call" ) -func (r ChatCompletionChoicesFinishReason) IsKnown() bool { - switch r { - case ChatCompletionChoicesFinishReasonStop, ChatCompletionChoicesFinishReasonLength, ChatCompletionChoicesFinishReasonToolCalls, ChatCompletionChoicesFinishReasonContentFilter, ChatCompletionChoicesFinishReasonFunctionCall: - return true - } - return false -} - // Log probability information for the choice. type ChatCompletionChoicesLogprobs struct { // A list of message content tokens with log probability information. - Content []ChatCompletionTokenLogprob `json:"content,required,nullable"` + Content []ChatCompletionTokenLogprob `json:"content,omitzero,required,nullable"` // A list of message refusal tokens with log probability information. - Refusal []ChatCompletionTokenLogprob `json:"refusal,required,nullable"` - JSON chatCompletionChoicesLogprobsJSON `json:"-"` + Refusal []ChatCompletionTokenLogprob `json:"refusal,omitzero,required,nullable"` + JSON struct { + Content resp.Field + Refusal resp.Field + raw string + } `json:"-"` } -// chatCompletionChoicesLogprobsJSON contains the JSON metadata for the struct -// [ChatCompletionChoicesLogprobs] -type chatCompletionChoicesLogprobsJSON struct { - Content apijson.Field - Refusal apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChoicesLogprobs) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChoicesLogprobs) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChoicesLogprobs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChoicesLogprobsJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `chat.completion`. -type ChatCompletionObject string - -const ( - ChatCompletionObjectChatCompletion ChatCompletionObject = "chat.completion" -) - -func (r ChatCompletionObject) IsKnown() bool { - switch r { - case ChatCompletionObjectChatCompletion: - return true - } - return false -} - // The service tier used for processing the request. -type ChatCompletionServiceTier string +type ChatCompletionServiceTier = string const ( ChatCompletionServiceTierScale ChatCompletionServiceTier = "scale" ChatCompletionServiceTierDefault ChatCompletionServiceTier = "default" ) -func (r ChatCompletionServiceTier) IsKnown() bool { - switch r { - case ChatCompletionServiceTierScale, ChatCompletionServiceTierDefault: - return true - } - return false -} - // Messages sent by the model in response to user messages. type ChatCompletionAssistantMessageParam struct { // The role of the messages author, in this case `assistant`. - Role param.Field[ChatCompletionAssistantMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "assistant". + Role constant.Assistant `json:"role,required"` // Data about a previous audio response from the model. // [Learn more](https://platform.openai.com/docs/guides/audio). - Audio param.Field[ChatCompletionAssistantMessageParamAudio] `json:"audio"` + Audio ChatCompletionAssistantMessageParamAudio `json:"audio,omitzero"` // The contents of the assistant message. Required unless `tool_calls` or // `function_call` is specified. - Content param.Field[[]ChatCompletionAssistantMessageParamContentUnion] `json:"content"` + Content []ChatCompletionAssistantMessageParamContentUnion `json:"content,omitzero"` // Deprecated and replaced by `tool_calls`. The name and arguments of a function // that should be called, as generated by the model. // // Deprecated: deprecated - FunctionCall param.Field[ChatCompletionAssistantMessageParamFunctionCall] `json:"function_call"` + FunctionCall ChatCompletionAssistantMessageParamFunctionCall `json:"function_call,omitzero"` // An optional name for the participant. Provides the model information to // differentiate between participants of the same role. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` // The refusal message by the assistant. - Refusal param.Field[string] `json:"refusal"` + Refusal param.String `json:"refusal,omitzero"` // The tool calls generated by the model, such as function calls. - ToolCalls param.Field[[]ChatCompletionMessageToolCallParam] `json:"tool_calls"` + ToolCalls []ChatCompletionMessageToolCallParam `json:"tool_calls,omitzero"` + apiobject +} + +func (f ChatCompletionAssistantMessageParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionAssistantMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionAssistantMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `assistant`. -type ChatCompletionAssistantMessageParamRole string - -const ( - ChatCompletionAssistantMessageParamRoleAssistant ChatCompletionAssistantMessageParamRole = "assistant" -) - -func (r ChatCompletionAssistantMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionAssistantMessageParamRoleAssistant: - return true - } - return false + type shadow ChatCompletionAssistantMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } // Data about a previous audio response from the model. // [Learn more](https://platform.openai.com/docs/guides/audio). type ChatCompletionAssistantMessageParamAudio struct { // Unique identifier for a previous audio response from the model. - ID param.Field[string] `json:"id,required"` + ID param.String `json:"id,omitzero,required"` + apiobject +} + +func (f ChatCompletionAssistantMessageParamAudio) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionAssistantMessageParamAudio) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionAssistantMessageParamAudio + return param.MarshalObject(r, (*shadow)(&r)) } -// Learn about -// [text inputs](https://platform.openai.com/docs/guides/text-generation). -type ChatCompletionAssistantMessageParamContent struct { - // The type of the content part. - Type param.Field[ChatCompletionAssistantMessageParamContentType] `json:"type,required"` - // The refusal message generated by the model. - Refusal param.Field[string] `json:"refusal"` - // The text content. - Text param.Field[string] `json:"text"` +// Only one field can be non-zero +type ChatCompletionAssistantMessageParamContentUnion struct { + OfText *ChatCompletionContentPartTextParam + OfRefusal *ChatCompletionContentPartRefusalParam + apiunion } -func (r ChatCompletionAssistantMessageParamContent) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u ChatCompletionAssistantMessageParamContentUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r ChatCompletionAssistantMessageParamContent) implementsChatCompletionAssistantMessageParamContentUnion() { +func (u ChatCompletionAssistantMessageParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionAssistantMessageParamContentUnion](u.OfText, u.OfRefusal) } -// Learn about -// [text inputs](https://platform.openai.com/docs/guides/text-generation). -// -// Satisfied by [ChatCompletionContentPartTextParam], -// [ChatCompletionContentPartRefusalParam], -// [ChatCompletionAssistantMessageParamContent]. -type ChatCompletionAssistantMessageParamContentUnion interface { - implementsChatCompletionAssistantMessageParamContentUnion() -} - -// The type of the content part. -type ChatCompletionAssistantMessageParamContentType string - -const ( - ChatCompletionAssistantMessageParamContentTypeText ChatCompletionAssistantMessageParamContentType = "text" - ChatCompletionAssistantMessageParamContentTypeRefusal ChatCompletionAssistantMessageParamContentType = "refusal" -) - -func (r ChatCompletionAssistantMessageParamContentType) IsKnown() bool { - switch r { - case ChatCompletionAssistantMessageParamContentTypeText, ChatCompletionAssistantMessageParamContentTypeRefusal: - return true +func (u ChatCompletionAssistantMessageParamContentUnion) GetText() *string { + if vt := u.OfText; vt != nil && !vt.Text.IsOmitted() { + return &vt.Text.V } - return false + return nil +} + +func (u ChatCompletionAssistantMessageParamContentUnion) GetRefusal() *string { + if vt := u.OfRefusal; vt != nil && !vt.Refusal.IsOmitted() { + return &vt.Refusal.V + } + return nil +} + +func (u ChatCompletionAssistantMessageParamContentUnion) GetType() *string { + if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRefusal; vt != nil { + return (*string)(&vt.Type) + } + return nil } // Deprecated and replaced by `tool_calls`. The name and arguments of a function @@ -418,13 +363,19 @@ type ChatCompletionAssistantMessageParamFunctionCall struct { // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments param.Field[string] `json:"arguments,required"` + Arguments param.String `json:"arguments,omitzero,required"` // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` + apiobject +} + +func (f ChatCompletionAssistantMessageParamFunctionCall) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionAssistantMessageParamFunctionCall) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionAssistantMessageParamFunctionCall + return param.MarshalObject(r, (*shadow)(&r)) } // If the audio output modality is requested, this object contains data about the @@ -432,57 +383,57 @@ func (r ChatCompletionAssistantMessageParamFunctionCall) MarshalJSON() (data []b // [Learn more](https://platform.openai.com/docs/guides/audio). type ChatCompletionAudio struct { // Unique identifier for this audio response. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // Base64 encoded audio bytes generated by the model, in the format specified in // the request. - Data string `json:"data,required"` + Data string `json:"data,omitzero,required"` // The Unix timestamp (in seconds) for when this audio response will no longer be // accessible on the server for use in multi-turn conversations. - ExpiresAt int64 `json:"expires_at,required"` + ExpiresAt int64 `json:"expires_at,omitzero,required"` // Transcript of the audio generated by the model. - Transcript string `json:"transcript,required"` - JSON chatCompletionAudioJSON `json:"-"` + Transcript string `json:"transcript,omitzero,required"` + JSON struct { + ID resp.Field + Data resp.Field + ExpiresAt resp.Field + Transcript resp.Field + raw string + } `json:"-"` } -// chatCompletionAudioJSON contains the JSON metadata for the struct -// [ChatCompletionAudio] -type chatCompletionAudioJSON struct { - ID apijson.Field - Data apijson.Field - ExpiresAt apijson.Field - Transcript apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionAudio) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionAudio) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionAudio) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionAudioJSON) RawJSON() string { - return r.raw -} - // Parameters for audio output. Required when audio output is requested with // `modalities: ["audio"]`. // [Learn more](https://platform.openai.com/docs/guides/audio). type ChatCompletionAudioParam struct { // Specifies the output audio format. Must be one of `wav`, `mp3`, `flac`, `opus`, // or `pcm16`. - Format param.Field[ChatCompletionAudioParamFormat] `json:"format,required"` + // + // Any of "wav", "mp3", "flac", "opus", "pcm16" + Format string `json:"format,omitzero,required"` // The voice the model uses to respond. Supported voices are `ash`, `ballad`, // `coral`, `sage`, and `verse` (also supported but not recommended are `alloy`, // `echo`, and `shimmer`; these voices are less expressive). - Voice param.Field[ChatCompletionAudioParamVoice] `json:"voice,required"` + // + // Any of "alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse" + Voice string `json:"voice,omitzero,required"` + apiobject } +func (f ChatCompletionAudioParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionAudioParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionAudioParam + return param.MarshalObject(r, (*shadow)(&r)) } // Specifies the output audio format. Must be one of `wav`, `mp3`, `flac`, `opus`, // or `pcm16`. -type ChatCompletionAudioParamFormat string +type ChatCompletionAudioParamFormat = string const ( ChatCompletionAudioParamFormatWAV ChatCompletionAudioParamFormat = "wav" @@ -492,18 +443,10 @@ const ( ChatCompletionAudioParamFormatPcm16 ChatCompletionAudioParamFormat = "pcm16" ) -func (r ChatCompletionAudioParamFormat) IsKnown() bool { - switch r { - case ChatCompletionAudioParamFormatWAV, ChatCompletionAudioParamFormatMP3, ChatCompletionAudioParamFormatFLAC, ChatCompletionAudioParamFormatOpus, ChatCompletionAudioParamFormatPcm16: - return true - } - return false -} - // The voice the model uses to respond. Supported voices are `ash`, `ballad`, // `coral`, `sage`, and `verse` (also supported but not recommended are `alloy`, // `echo`, and `shimmer`; these voices are less expressive). -type ChatCompletionAudioParamVoice string +type ChatCompletionAudioParamVoice = string const ( ChatCompletionAudioParamVoiceAlloy ChatCompletionAudioParamVoice = "alloy" @@ -516,140 +459,117 @@ const ( ChatCompletionAudioParamVoiceVerse ChatCompletionAudioParamVoice = "verse" ) -func (r ChatCompletionAudioParamVoice) IsKnown() bool { - switch r { - case ChatCompletionAudioParamVoiceAlloy, ChatCompletionAudioParamVoiceAsh, ChatCompletionAudioParamVoiceBallad, ChatCompletionAudioParamVoiceCoral, ChatCompletionAudioParamVoiceEcho, ChatCompletionAudioParamVoiceSage, ChatCompletionAudioParamVoiceShimmer, ChatCompletionAudioParamVoiceVerse: - return true - } - return false -} - // Represents a streamed chunk of a chat completion response returned by model, // based on the provided input. type ChatCompletionChunk struct { // A unique identifier for the chat completion. Each chunk has the same ID. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // A list of chat completion choices. Can contain more than one elements if `n` is // greater than 1. Can also be empty for the last chunk if you set // `stream_options: {"include_usage": true}`. - Choices []ChatCompletionChunkChoice `json:"choices,required"` + Choices []ChatCompletionChunkChoice `json:"choices,omitzero,required"` // The Unix timestamp (in seconds) of when the chat completion was created. Each // chunk has the same timestamp. - Created int64 `json:"created,required"` + Created int64 `json:"created,omitzero,required"` // The model to generate the completion. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always `chat.completion.chunk`. - Object ChatCompletionChunkObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as + // "chat.completion.chunk". + Object constant.ChatCompletionChunk `json:"object,required"` // The service tier used for processing the request. - ServiceTier ChatCompletionChunkServiceTier `json:"service_tier,nullable"` + // + // Any of "scale", "default" + ServiceTier string `json:"service_tier,omitzero,nullable"` // This fingerprint represents the backend configuration that the model runs with. // Can be used in conjunction with the `seed` request parameter to understand when // backend changes have been made that might impact determinism. - SystemFingerprint string `json:"system_fingerprint"` + SystemFingerprint string `json:"system_fingerprint,omitzero"` // 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 CompletionUsage `json:"usage,nullable"` - JSON chatCompletionChunkJSON `json:"-"` + Usage CompletionUsage `json:"usage,omitzero,nullable"` + JSON struct { + ID resp.Field + Choices resp.Field + Created resp.Field + Model resp.Field + Object resp.Field + ServiceTier resp.Field + SystemFingerprint resp.Field + Usage resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkJSON contains the JSON metadata for the struct -// [ChatCompletionChunk] -type chatCompletionChunkJSON struct { - ID apijson.Field - Choices apijson.Field - Created apijson.Field - Model apijson.Field - Object apijson.Field - ServiceTier apijson.Field - SystemFingerprint apijson.Field - Usage apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunk) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunk) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunk) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkJSON) RawJSON() string { - return r.raw -} - type ChatCompletionChunkChoice struct { // A chat completion delta generated by streamed model responses. - Delta ChatCompletionChunkChoicesDelta `json:"delta,required"` + Delta ChatCompletionChunkChoicesDelta `json:"delta,omitzero,required"` // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum // number of tokens specified in the request was reached, `content_filter` if // content was omitted due to a flag from our content filters, `tool_calls` if the // model called a tool, or `function_call` (deprecated) if the model called a // function. - FinishReason ChatCompletionChunkChoicesFinishReason `json:"finish_reason,required,nullable"` + // + // Any of "stop", "length", "tool_calls", "content_filter", "function_call" + FinishReason string `json:"finish_reason,omitzero,required,nullable"` // The index of the choice in the list of choices. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // Log probability information for the choice. - Logprobs ChatCompletionChunkChoicesLogprobs `json:"logprobs,nullable"` - JSON chatCompletionChunkChoiceJSON `json:"-"` + Logprobs ChatCompletionChunkChoicesLogprobs `json:"logprobs,omitzero,nullable"` + JSON struct { + Delta resp.Field + FinishReason resp.Field + Index resp.Field + Logprobs resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoiceJSON contains the JSON metadata for the struct -// [ChatCompletionChunkChoice] -type chatCompletionChunkChoiceJSON struct { - Delta apijson.Field - FinishReason apijson.Field - Index apijson.Field - Logprobs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoice) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoice) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoice) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoiceJSON) RawJSON() string { - return r.raw -} - // A chat completion delta generated by streamed model responses. type ChatCompletionChunkChoicesDelta struct { // The contents of the chunk message. - Content string `json:"content,nullable"` + Content string `json:"content,omitzero,nullable"` // Deprecated and replaced by `tool_calls`. The name and arguments of a function // that should be called, as generated by the model. // // Deprecated: deprecated - FunctionCall ChatCompletionChunkChoicesDeltaFunctionCall `json:"function_call"` + FunctionCall ChatCompletionChunkChoicesDeltaFunctionCall `json:"function_call,omitzero"` // The refusal message generated by the model. - Refusal string `json:"refusal,nullable"` + Refusal string `json:"refusal,omitzero,nullable"` // The role of the author of this message. - Role ChatCompletionChunkChoicesDeltaRole `json:"role"` - ToolCalls []ChatCompletionChunkChoicesDeltaToolCall `json:"tool_calls"` - JSON chatCompletionChunkChoicesDeltaJSON `json:"-"` + // + // Any of "developer", "system", "user", "assistant", "tool" + Role string `json:"role,omitzero"` + ToolCalls []ChatCompletionChunkChoicesDeltaToolCall `json:"tool_calls,omitzero"` + JSON struct { + Content resp.Field + FunctionCall resp.Field + Refusal resp.Field + Role resp.Field + ToolCalls resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoicesDeltaJSON contains the JSON metadata for the struct -// [ChatCompletionChunkChoicesDelta] -type chatCompletionChunkChoicesDeltaJSON struct { - Content apijson.Field - FunctionCall apijson.Field - Refusal apijson.Field - Role apijson.Field - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoicesDelta) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoicesDelta) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoicesDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoicesDeltaJSON) RawJSON() string { - return r.raw -} - // Deprecated and replaced by `tool_calls`. The name and arguments of a function // that should be called, as generated by the model. // @@ -659,31 +579,23 @@ type ChatCompletionChunkChoicesDeltaFunctionCall struct { // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments string `json:"arguments"` + Arguments string `json:"arguments,omitzero"` // The name of the function to call. - Name string `json:"name"` - JSON chatCompletionChunkChoicesDeltaFunctionCallJSON `json:"-"` + Name string `json:"name,omitzero"` + JSON struct { + Arguments resp.Field + Name resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoicesDeltaFunctionCallJSON contains the JSON metadata for -// the struct [ChatCompletionChunkChoicesDeltaFunctionCall] -type chatCompletionChunkChoicesDeltaFunctionCallJSON struct { - Arguments apijson.Field - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoicesDeltaFunctionCall) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoicesDeltaFunctionCall) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoicesDeltaFunctionCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoicesDeltaFunctionCallJSON) RawJSON() string { - return r.raw -} - // The role of the author of this message. -type ChatCompletionChunkChoicesDeltaRole string +type ChatCompletionChunkChoicesDeltaRole = string const ( ChatCompletionChunkChoicesDeltaRoleDeveloper ChatCompletionChunkChoicesDeltaRole = "developer" @@ -693,93 +605,63 @@ const ( ChatCompletionChunkChoicesDeltaRoleTool ChatCompletionChunkChoicesDeltaRole = "tool" ) -func (r ChatCompletionChunkChoicesDeltaRole) IsKnown() bool { - switch r { - case ChatCompletionChunkChoicesDeltaRoleDeveloper, ChatCompletionChunkChoicesDeltaRoleSystem, ChatCompletionChunkChoicesDeltaRoleUser, ChatCompletionChunkChoicesDeltaRoleAssistant, ChatCompletionChunkChoicesDeltaRoleTool: - return true - } - return false -} - type ChatCompletionChunkChoicesDeltaToolCall struct { - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // The ID of the tool call. - ID string `json:"id"` - Function ChatCompletionChunkChoicesDeltaToolCallsFunction `json:"function"` + ID string `json:"id,omitzero"` + Function ChatCompletionChunkChoicesDeltaToolCallsFunction `json:"function,omitzero"` // The type of the tool. Currently, only `function` is supported. - Type ChatCompletionChunkChoicesDeltaToolCallsType `json:"type"` - JSON chatCompletionChunkChoicesDeltaToolCallJSON `json:"-"` + // + // Any of "function" + Type string `json:"type"` + JSON struct { + Index resp.Field + ID resp.Field + Function resp.Field + Type resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoicesDeltaToolCallJSON contains the JSON metadata for the -// struct [ChatCompletionChunkChoicesDeltaToolCall] -type chatCompletionChunkChoicesDeltaToolCallJSON struct { - Index apijson.Field - ID apijson.Field - Function apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoicesDeltaToolCall) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoicesDeltaToolCall) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoicesDeltaToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoicesDeltaToolCallJSON) RawJSON() string { - return r.raw -} - type ChatCompletionChunkChoicesDeltaToolCallsFunction struct { // The arguments to call the function with, as generated by the model in JSON // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments string `json:"arguments"` + Arguments string `json:"arguments,omitzero"` // The name of the function to call. - Name string `json:"name"` - JSON chatCompletionChunkChoicesDeltaToolCallsFunctionJSON `json:"-"` + Name string `json:"name,omitzero"` + JSON struct { + Arguments resp.Field + Name resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoicesDeltaToolCallsFunctionJSON contains the JSON metadata -// for the struct [ChatCompletionChunkChoicesDeltaToolCallsFunction] -type chatCompletionChunkChoicesDeltaToolCallsFunctionJSON struct { - Arguments apijson.Field - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoicesDeltaToolCallsFunction) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoicesDeltaToolCallsFunction) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoicesDeltaToolCallsFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoicesDeltaToolCallsFunctionJSON) RawJSON() string { - return r.raw -} - // The type of the tool. Currently, only `function` is supported. -type ChatCompletionChunkChoicesDeltaToolCallsType string +type ChatCompletionChunkChoicesDeltaToolCallsType = string const ( ChatCompletionChunkChoicesDeltaToolCallsTypeFunction ChatCompletionChunkChoicesDeltaToolCallsType = "function" ) -func (r ChatCompletionChunkChoicesDeltaToolCallsType) IsKnown() bool { - switch r { - case ChatCompletionChunkChoicesDeltaToolCallsTypeFunction: - return true - } - return false -} - // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum // number of tokens specified in the request was reached, `content_filter` if // content was omitted due to a flag from our content filters, `tool_calls` if the // model called a tool, or `function_call` (deprecated) if the model called a // function. -type ChatCompletionChunkChoicesFinishReason string +type ChatCompletionChunkChoicesFinishReason = string const ( ChatCompletionChunkChoicesFinishReasonStop ChatCompletionChunkChoicesFinishReason = "stop" @@ -789,143 +671,140 @@ const ( ChatCompletionChunkChoicesFinishReasonFunctionCall ChatCompletionChunkChoicesFinishReason = "function_call" ) -func (r ChatCompletionChunkChoicesFinishReason) IsKnown() bool { - switch r { - case ChatCompletionChunkChoicesFinishReasonStop, ChatCompletionChunkChoicesFinishReasonLength, ChatCompletionChunkChoicesFinishReasonToolCalls, ChatCompletionChunkChoicesFinishReasonContentFilter, ChatCompletionChunkChoicesFinishReasonFunctionCall: - return true - } - return false -} - // Log probability information for the choice. type ChatCompletionChunkChoicesLogprobs struct { // A list of message content tokens with log probability information. - Content []ChatCompletionTokenLogprob `json:"content,required,nullable"` + Content []ChatCompletionTokenLogprob `json:"content,omitzero,required,nullable"` // A list of message refusal tokens with log probability information. - Refusal []ChatCompletionTokenLogprob `json:"refusal,required,nullable"` - JSON chatCompletionChunkChoicesLogprobsJSON `json:"-"` + Refusal []ChatCompletionTokenLogprob `json:"refusal,omitzero,required,nullable"` + JSON struct { + Content resp.Field + Refusal resp.Field + raw string + } `json:"-"` } -// chatCompletionChunkChoicesLogprobsJSON contains the JSON metadata for the struct -// [ChatCompletionChunkChoicesLogprobs] -type chatCompletionChunkChoicesLogprobsJSON struct { - Content apijson.Field - Refusal apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionChunkChoicesLogprobs) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionChunkChoicesLogprobs) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionChunkChoicesLogprobs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionChunkChoicesLogprobsJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `chat.completion.chunk`. -type ChatCompletionChunkObject string - -const ( - ChatCompletionChunkObjectChatCompletionChunk ChatCompletionChunkObject = "chat.completion.chunk" -) - -func (r ChatCompletionChunkObject) IsKnown() bool { - switch r { - case ChatCompletionChunkObjectChatCompletionChunk: - return true - } - return false -} - // The service tier used for processing the request. -type ChatCompletionChunkServiceTier string +type ChatCompletionChunkServiceTier = string const ( ChatCompletionChunkServiceTierScale ChatCompletionChunkServiceTier = "scale" ChatCompletionChunkServiceTierDefault ChatCompletionChunkServiceTier = "default" ) -func (r ChatCompletionChunkServiceTier) IsKnown() bool { - switch r { - case ChatCompletionChunkServiceTierScale, ChatCompletionChunkServiceTierDefault: - return true +func NewChatCompletionContentPartOfText(text string) ChatCompletionContentPartUnionParam { + var variant ChatCompletionContentPartTextParam + variant.Text = newString(text) + return ChatCompletionContentPartUnionParam{OfText: &variant} +} + +func NewChatCompletionContentPartOfImageURL(imageURL ChatCompletionContentPartImageImageURLParam) ChatCompletionContentPartUnionParam { + var image_url ChatCompletionContentPartImageParam + image_url.ImageURL = imageURL + return ChatCompletionContentPartUnionParam{OfImageURL: &image_url} +} + +func NewChatCompletionContentPartOfInputAudio(inputAudio ChatCompletionContentPartInputAudioInputAudioParam) ChatCompletionContentPartUnionParam { + var input_audio ChatCompletionContentPartInputAudioParam + input_audio.InputAudio = inputAudio + return ChatCompletionContentPartUnionParam{OfInputAudio: &input_audio} +} + +// Only one field can be non-zero +type ChatCompletionContentPartUnionParam struct { + OfText *ChatCompletionContentPartTextParam + OfImageURL *ChatCompletionContentPartImageParam + OfInputAudio *ChatCompletionContentPartInputAudioParam + apiunion +} + +func (u ChatCompletionContentPartUnionParam) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() +} + +func (u ChatCompletionContentPartUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionContentPartUnionParam](u.OfText, u.OfImageURL, u.OfInputAudio) +} + +func (u ChatCompletionContentPartUnionParam) GetText() *string { + if vt := u.OfText; vt != nil && !vt.Text.IsOmitted() { + return &vt.Text.V } - return false + return nil } -// Learn about -// [text inputs](https://platform.openai.com/docs/guides/text-generation). -type ChatCompletionContentPartParam struct { - // The type of the content part. - Type param.Field[ChatCompletionContentPartType] `json:"type,required"` - ImageURL param.Field[interface{}] `json:"image_url"` - InputAudio param.Field[interface{}] `json:"input_audio"` - // The text content. - Text param.Field[string] `json:"text"` -} - -func (r ChatCompletionContentPartParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionContentPartParam) implementsChatCompletionContentPartUnionParam() {} - -// Learn about -// [text inputs](https://platform.openai.com/docs/guides/text-generation). -// -// Satisfied by [ChatCompletionContentPartTextParam], -// [ChatCompletionContentPartImageParam], -// [ChatCompletionContentPartInputAudioParam], [ChatCompletionContentPartParam]. -type ChatCompletionContentPartUnionParam interface { - implementsChatCompletionContentPartUnionParam() -} - -// The type of the content part. -type ChatCompletionContentPartType string - -const ( - ChatCompletionContentPartTypeText ChatCompletionContentPartType = "text" - ChatCompletionContentPartTypeImageURL ChatCompletionContentPartType = "image_url" - ChatCompletionContentPartTypeInputAudio ChatCompletionContentPartType = "input_audio" -) - -func (r ChatCompletionContentPartType) IsKnown() bool { - switch r { - case ChatCompletionContentPartTypeText, ChatCompletionContentPartTypeImageURL, ChatCompletionContentPartTypeInputAudio: - return true +func (u ChatCompletionContentPartUnionParam) GetImageURL() *ChatCompletionContentPartImageImageURLParam { + if vt := u.OfImageURL; vt != nil { + return &vt.ImageURL } - return false + return nil +} + +func (u ChatCompletionContentPartUnionParam) GetInputAudio() *ChatCompletionContentPartInputAudioInputAudioParam { + if vt := u.OfInputAudio; vt != nil { + return &vt.InputAudio + } + return nil +} + +func (u ChatCompletionContentPartUnionParam) GetType() *string { + if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfImageURL; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfInputAudio; vt != nil { + return (*string)(&vt.Type) + } + return nil } // Learn about [image inputs](https://platform.openai.com/docs/guides/vision). type ChatCompletionContentPartImageParam struct { - ImageURL param.Field[ChatCompletionContentPartImageImageURLParam] `json:"image_url,required"` + ImageURL ChatCompletionContentPartImageImageURLParam `json:"image_url,omitzero,required"` // The type of the content part. - Type param.Field[ChatCompletionContentPartImageType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "image_url". + Type constant.ImageURL `json:"type,required"` + apiobject +} + +func (f ChatCompletionContentPartImageParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionContentPartImageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionContentPartImageParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ChatCompletionContentPartImageParam) implementsChatCompletionContentPartUnionParam() {} - type ChatCompletionContentPartImageImageURLParam struct { // Either a URL of the image or the base64 encoded image data. - URL param.Field[string] `json:"url,required" format:"uri"` + URL param.String `json:"url,omitzero,required" format:"uri"` // Specifies the detail level of the image. Learn more in the // [Vision guide](https://platform.openai.com/docs/guides/vision#low-or-high-fidelity-image-understanding). - Detail param.Field[ChatCompletionContentPartImageImageURLDetail] `json:"detail"` + // + // Any of "auto", "low", "high" + Detail string `json:"detail,omitzero"` + apiobject +} + +func (f ChatCompletionContentPartImageImageURLParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionContentPartImageImageURLParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionContentPartImageImageURLParam + return param.MarshalObject(r, (*shadow)(&r)) } // Specifies the detail level of the image. Learn more in the // [Vision guide](https://platform.openai.com/docs/guides/vision#low-or-high-fidelity-image-understanding). -type ChatCompletionContentPartImageImageURLDetail string +type ChatCompletionContentPartImageImageURLDetail = string const ( ChatCompletionContentPartImageImageURLDetailAuto ChatCompletionContentPartImageImageURLDetail = "auto" @@ -933,323 +812,221 @@ const ( ChatCompletionContentPartImageImageURLDetailHigh ChatCompletionContentPartImageImageURLDetail = "high" ) -func (r ChatCompletionContentPartImageImageURLDetail) IsKnown() bool { - switch r { - case ChatCompletionContentPartImageImageURLDetailAuto, ChatCompletionContentPartImageImageURLDetailLow, ChatCompletionContentPartImageImageURLDetailHigh: - return true - } - return false -} - -// The type of the content part. -type ChatCompletionContentPartImageType string - -const ( - ChatCompletionContentPartImageTypeImageURL ChatCompletionContentPartImageType = "image_url" -) - -func (r ChatCompletionContentPartImageType) IsKnown() bool { - switch r { - case ChatCompletionContentPartImageTypeImageURL: - return true - } - return false -} - // Learn about [audio inputs](https://platform.openai.com/docs/guides/audio). type ChatCompletionContentPartInputAudioParam struct { - InputAudio param.Field[ChatCompletionContentPartInputAudioInputAudioParam] `json:"input_audio,required"` + InputAudio ChatCompletionContentPartInputAudioInputAudioParam `json:"input_audio,omitzero,required"` // The type of the content part. Always `input_audio`. - Type param.Field[ChatCompletionContentPartInputAudioType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "input_audio". + Type constant.InputAudio `json:"type,required"` + apiobject +} + +func (f ChatCompletionContentPartInputAudioParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionContentPartInputAudioParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionContentPartInputAudioParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ChatCompletionContentPartInputAudioParam) implementsChatCompletionContentPartUnionParam() {} - type ChatCompletionContentPartInputAudioInputAudioParam struct { // Base64 encoded audio data. - Data param.Field[string] `json:"data,required"` + Data param.String `json:"data,omitzero,required"` // The format of the encoded audio data. Currently supports "wav" and "mp3". - Format param.Field[ChatCompletionContentPartInputAudioInputAudioFormat] `json:"format,required"` + // + // Any of "wav", "mp3" + Format string `json:"format,omitzero,required"` + apiobject +} + +func (f ChatCompletionContentPartInputAudioInputAudioParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionContentPartInputAudioInputAudioParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionContentPartInputAudioInputAudioParam + return param.MarshalObject(r, (*shadow)(&r)) } // The format of the encoded audio data. Currently supports "wav" and "mp3". -type ChatCompletionContentPartInputAudioInputAudioFormat string +type ChatCompletionContentPartInputAudioInputAudioFormat = string const ( ChatCompletionContentPartInputAudioInputAudioFormatWAV ChatCompletionContentPartInputAudioInputAudioFormat = "wav" ChatCompletionContentPartInputAudioInputAudioFormatMP3 ChatCompletionContentPartInputAudioInputAudioFormat = "mp3" ) -func (r ChatCompletionContentPartInputAudioInputAudioFormat) IsKnown() bool { - switch r { - case ChatCompletionContentPartInputAudioInputAudioFormatWAV, ChatCompletionContentPartInputAudioInputAudioFormatMP3: - return true - } - return false -} - -// The type of the content part. Always `input_audio`. -type ChatCompletionContentPartInputAudioType string - -const ( - ChatCompletionContentPartInputAudioTypeInputAudio ChatCompletionContentPartInputAudioType = "input_audio" -) - -func (r ChatCompletionContentPartInputAudioType) IsKnown() bool { - switch r { - case ChatCompletionContentPartInputAudioTypeInputAudio: - return true - } - return false -} - type ChatCompletionContentPartRefusalParam struct { // The refusal message generated by the model. - Refusal param.Field[string] `json:"refusal,required"` + Refusal param.String `json:"refusal,omitzero,required"` // The type of the content part. - Type param.Field[ChatCompletionContentPartRefusalType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "refusal". + Type constant.Refusal `json:"type,required"` + apiobject +} + +func (f ChatCompletionContentPartRefusalParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionContentPartRefusalParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionContentPartRefusalParam) implementsChatCompletionAssistantMessageParamContentUnion() { -} - -// The type of the content part. -type ChatCompletionContentPartRefusalType string - -const ( - ChatCompletionContentPartRefusalTypeRefusal ChatCompletionContentPartRefusalType = "refusal" -) - -func (r ChatCompletionContentPartRefusalType) IsKnown() bool { - switch r { - case ChatCompletionContentPartRefusalTypeRefusal: - return true - } - return false + type shadow ChatCompletionContentPartRefusalParam + return param.MarshalObject(r, (*shadow)(&r)) } // Learn about // [text inputs](https://platform.openai.com/docs/guides/text-generation). type ChatCompletionContentPartTextParam struct { // The text content. - Text param.Field[string] `json:"text,required"` + Text param.String `json:"text,omitzero,required"` // The type of the content part. - Type param.Field[ChatCompletionContentPartTextType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "text". + Type constant.Text `json:"type,required"` + apiobject } +func (f ChatCompletionContentPartTextParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionContentPartTextParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionContentPartTextParam) implementsChatCompletionAssistantMessageParamContentUnion() { -} - -func (r ChatCompletionContentPartTextParam) implementsChatCompletionContentPartUnionParam() {} - -// The type of the content part. -type ChatCompletionContentPartTextType string - -const ( - ChatCompletionContentPartTextTypeText ChatCompletionContentPartTextType = "text" -) - -func (r ChatCompletionContentPartTextType) IsKnown() bool { - switch r { - case ChatCompletionContentPartTextTypeText: - return true - } - return false + type shadow ChatCompletionContentPartTextParam + return param.MarshalObject(r, (*shadow)(&r)) } type ChatCompletionDeleted struct { // The ID of the chat completion that was deleted. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // Whether the chat completion was deleted. - Deleted bool `json:"deleted,required"` + Deleted bool `json:"deleted,omitzero,required"` // The type of object being deleted. - Object ChatCompletionDeletedObject `json:"object,required"` - JSON chatCompletionDeletedJSON `json:"-"` + // + // This field can be elided, and will be automatically set as + // "chat.completion.deleted". + Object constant.ChatCompletionDeleted `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// chatCompletionDeletedJSON contains the JSON metadata for the struct -// [ChatCompletionDeleted] -type chatCompletionDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionDeleted) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionDeleted) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionDeletedJSON) RawJSON() string { - return r.raw -} - -// The type of object being deleted. -type ChatCompletionDeletedObject string - -const ( - ChatCompletionDeletedObjectChatCompletionDeleted ChatCompletionDeletedObject = "chat.completion.deleted" -) - -func (r ChatCompletionDeletedObject) IsKnown() bool { - switch r { - case ChatCompletionDeletedObjectChatCompletionDeleted: - return true - } - return false -} - // Developer-provided instructions that the model should follow, regardless of // messages sent by the user. With o1 models and newer, `developer` messages // replace the previous `system` messages. type ChatCompletionDeveloperMessageParam struct { // The contents of the developer message. - Content param.Field[[]ChatCompletionContentPartTextParam] `json:"content,required"` + Content []ChatCompletionContentPartTextParam `json:"content,omitzero,required"` // The role of the messages author, in this case `developer`. - Role param.Field[ChatCompletionDeveloperMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "developer". + Role constant.Developer `json:"role,required"` // An optional name for the participant. Provides the model information to // differentiate between participants of the same role. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` + apiobject +} + +func (f ChatCompletionDeveloperMessageParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionDeveloperMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionDeveloperMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `developer`. -type ChatCompletionDeveloperMessageParamRole string - -const ( - ChatCompletionDeveloperMessageParamRoleDeveloper ChatCompletionDeveloperMessageParamRole = "developer" -) - -func (r ChatCompletionDeveloperMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionDeveloperMessageParamRoleDeveloper: - return true - } - return false + type shadow ChatCompletionDeveloperMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } // Specifying a particular function via `{"name": "my_function"}` forces the model // to call that function. type ChatCompletionFunctionCallOptionParam struct { // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` + apiobject +} + +func (f ChatCompletionFunctionCallOptionParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionFunctionCallOptionParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionFunctionCallOptionParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ChatCompletionFunctionCallOptionParam) implementsChatCompletionNewParamsFunctionCallUnion() {} - // Deprecated: deprecated type ChatCompletionFunctionMessageParam struct { // The contents of the function message. - Content param.Field[string] `json:"content,required"` + Content param.String `json:"content,omitzero,required"` // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` // The role of the messages author, in this case `function`. - Role param.Field[ChatCompletionFunctionMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "function". + Role constant.Function `json:"role,required"` + apiobject } +func (f ChatCompletionFunctionMessageParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionFunctionMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionFunctionMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `function`. -type ChatCompletionFunctionMessageParamRole string - -const ( - ChatCompletionFunctionMessageParamRoleFunction ChatCompletionFunctionMessageParamRole = "function" -) - -func (r ChatCompletionFunctionMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionFunctionMessageParamRoleFunction: - return true - } - return false + type shadow ChatCompletionFunctionMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } // A chat completion message generated by the model. type ChatCompletionMessage struct { // The contents of the message. - Content string `json:"content,required,nullable"` + Content string `json:"content,omitzero,required,nullable"` // The refusal message generated by the model. - Refusal string `json:"refusal,required,nullable"` + Refusal string `json:"refusal,omitzero,required,nullable"` // The role of the author of this message. - Role ChatCompletionMessageRole `json:"role,required"` + // + // This field can be elided, and will be automatically set as "assistant". + Role constant.Assistant `json:"role,required"` // If the audio output modality is requested, this object contains data about the // audio response from the model. // [Learn more](https://platform.openai.com/docs/guides/audio). - Audio ChatCompletionAudio `json:"audio,nullable"` + Audio ChatCompletionAudio `json:"audio,omitzero,nullable"` // Deprecated and replaced by `tool_calls`. The name and arguments of a function // that should be called, as generated by the model. // // Deprecated: deprecated - FunctionCall ChatCompletionMessageFunctionCall `json:"function_call"` + FunctionCall ChatCompletionMessageFunctionCall `json:"function_call,omitzero"` // The tool calls generated by the model, such as function calls. - ToolCalls []ChatCompletionMessageToolCall `json:"tool_calls"` - JSON chatCompletionMessageJSON `json:"-"` + ToolCalls []ChatCompletionMessageToolCall `json:"tool_calls,omitzero"` + JSON struct { + Content resp.Field + Refusal resp.Field + Role resp.Field + Audio resp.Field + FunctionCall resp.Field + ToolCalls resp.Field + raw string + } `json:"-"` } -// chatCompletionMessageJSON contains the JSON metadata for the struct -// [ChatCompletionMessage] -type chatCompletionMessageJSON struct { - Content apijson.Field - Refusal apijson.Field - Role apijson.Field - Audio apijson.Field - FunctionCall apijson.Field - ToolCalls apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionMessage) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionMessage) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionMessage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionMessageJSON) RawJSON() string { - return r.raw -} - -// The role of the author of this message. -type ChatCompletionMessageRole string - -const ( - ChatCompletionMessageRoleAssistant ChatCompletionMessageRole = "assistant" -) - -func (r ChatCompletionMessageRole) IsKnown() bool { - switch r { - case ChatCompletionMessageRoleAssistant: - return true - } - return false +func (r ChatCompletionMessage) ToParam() ChatCompletionAssistantMessageParam { + var p ChatCompletionAssistantMessageParam + p.Audio.ID = toParamString(r.Audio.ID, r.Audio.JSON.ID) + p.FunctionCall.Arguments = toParamString(r.FunctionCall.Arguments, r.FunctionCall.JSON.Arguments) + p.FunctionCall.Name = toParamString(r.FunctionCall.Name, r.FunctionCall.JSON.Name) + p.Refusal = toParamString(r.Refusal, r.JSON.Refusal) + _ = p.ToolCalls + _ = r.ToolCalls + return p } // Deprecated and replaced by `tool_calls`. The name and arguments of a function @@ -1261,112 +1038,192 @@ type ChatCompletionMessageFunctionCall struct { // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments string `json:"arguments,required"` + Arguments string `json:"arguments,omitzero,required"` // The name of the function to call. - Name string `json:"name,required"` - JSON chatCompletionMessageFunctionCallJSON `json:"-"` + Name string `json:"name,omitzero,required"` + JSON struct { + Arguments resp.Field + Name resp.Field + raw string + } `json:"-"` } -// chatCompletionMessageFunctionCallJSON contains the JSON metadata for the struct -// [ChatCompletionMessageFunctionCall] -type chatCompletionMessageFunctionCallJSON struct { - Arguments apijson.Field - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionMessageFunctionCall) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionMessageFunctionCall) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionMessageFunctionCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionMessageFunctionCallJSON) RawJSON() string { - return r.raw +func NewChatCompletionMessageParamOfDeveloper(content []ChatCompletionContentPartTextParam) ChatCompletionMessageParamUnion { + var developer ChatCompletionDeveloperMessageParam + developer.Content = content + return ChatCompletionMessageParamUnion{OfDeveloper: &developer} } -// Developer-provided instructions that the model should follow, regardless of -// messages sent by the user. With o1 models and newer, `developer` messages -// replace the previous `system` messages. -type ChatCompletionMessageParam struct { - // The role of the messages author, in this case `developer`. - Role param.Field[ChatCompletionMessageParamRole] `json:"role,required"` - Audio param.Field[interface{}] `json:"audio"` - Content param.Field[interface{}] `json:"content"` - FunctionCall param.Field[interface{}] `json:"function_call"` - // An optional name for the participant. Provides the model information to - // differentiate between participants of the same role. - Name param.Field[string] `json:"name"` - // The refusal message by the assistant. - Refusal param.Field[string] `json:"refusal"` - // Tool call that this message is responding to. - ToolCallID param.Field[string] `json:"tool_call_id"` - ToolCalls param.Field[interface{}] `json:"tool_calls"` +func NewChatCompletionMessageParamOfSystem(content []ChatCompletionContentPartTextParam) ChatCompletionMessageParamUnion { + var system ChatCompletionSystemMessageParam + system.Content = content + return ChatCompletionMessageParamUnion{OfSystem: &system} } -func (r ChatCompletionMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func NewChatCompletionMessageParamOfUser(content []ChatCompletionContentPartUnionParam) ChatCompletionMessageParamUnion { + var user ChatCompletionUserMessageParam + user.Content = content + return ChatCompletionMessageParamUnion{OfUser: &user} } -func (r ChatCompletionMessageParam) implementsChatCompletionMessageParamUnion() {} - -// Developer-provided instructions that the model should follow, regardless of -// messages sent by the user. With o1 models and newer, `developer` messages -// replace the previous `system` messages. -// -// Satisfied by [ChatCompletionDeveloperMessageParam], -// [ChatCompletionSystemMessageParam], [ChatCompletionUserMessageParam], -// [ChatCompletionAssistantMessageParam], [ChatCompletionToolMessageParam], -// [ChatCompletionFunctionMessageParam], [ChatCompletionMessageParam]. -type ChatCompletionMessageParamUnion interface { - implementsChatCompletionMessageParamUnion() +func NewChatCompletionMessageParamOfTool(content []ChatCompletionContentPartTextParam, toolCallID string) ChatCompletionMessageParamUnion { + var tool ChatCompletionToolMessageParam + tool.Content = content + tool.ToolCallID = newString(toolCallID) + return ChatCompletionMessageParamUnion{OfTool: &tool} } -// The role of the messages author, in this case `developer`. -type ChatCompletionMessageParamRole string +func NewChatCompletionMessageParamOfFunction(content string, name string) ChatCompletionMessageParamUnion { + var function ChatCompletionFunctionMessageParam + function.Content = newString(content) + function.Name = newString(name) + return ChatCompletionMessageParamUnion{OfFunction: &function} +} -const ( - ChatCompletionMessageParamRoleDeveloper ChatCompletionMessageParamRole = "developer" - ChatCompletionMessageParamRoleSystem ChatCompletionMessageParamRole = "system" - ChatCompletionMessageParamRoleUser ChatCompletionMessageParamRole = "user" - ChatCompletionMessageParamRoleAssistant ChatCompletionMessageParamRole = "assistant" - ChatCompletionMessageParamRoleTool ChatCompletionMessageParamRole = "tool" - ChatCompletionMessageParamRoleFunction ChatCompletionMessageParamRole = "function" -) +// Only one field can be non-zero +type ChatCompletionMessageParamUnion struct { + OfDeveloper *ChatCompletionDeveloperMessageParam + OfSystem *ChatCompletionSystemMessageParam + OfUser *ChatCompletionUserMessageParam + OfAssistant *ChatCompletionAssistantMessageParam + OfTool *ChatCompletionToolMessageParam + OfFunction *ChatCompletionFunctionMessageParam + apiunion +} -func (r ChatCompletionMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionMessageParamRoleDeveloper, ChatCompletionMessageParamRoleSystem, ChatCompletionMessageParamRoleUser, ChatCompletionMessageParamRoleAssistant, ChatCompletionMessageParamRoleTool, ChatCompletionMessageParamRoleFunction: - return true +func (u ChatCompletionMessageParamUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u ChatCompletionMessageParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionMessageParamUnion](u.OfDeveloper, u.OfSystem, u.OfUser, u.OfAssistant, u.OfTool, u.OfFunction) +} + +func (u ChatCompletionMessageParamUnion) GetName() *string { + if vt := u.OfDeveloper; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V + } else if vt := u.OfSystem; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V + } else if vt := u.OfUser; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V + } else if vt := u.OfAssistant; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V + } else if vt := u.OfFunction; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V } - return false + return nil +} + +func (u ChatCompletionMessageParamUnion) GetAudio() *ChatCompletionAssistantMessageParamAudio { + if vt := u.OfAssistant; vt != nil { + return &vt.Audio + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetFunctionCall() *ChatCompletionAssistantMessageParamFunctionCall { + if vt := u.OfAssistant; vt != nil { + return &vt.FunctionCall + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetRefusal() *string { + if vt := u.OfAssistant; vt != nil && !vt.Refusal.IsOmitted() { + return &vt.Refusal.V + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetToolCalls() []ChatCompletionMessageToolCallParam { + if vt := u.OfAssistant; vt != nil { + return vt.ToolCalls + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetToolCallID() *string { + if vt := u.OfTool; vt != nil && !vt.ToolCallID.IsOmitted() { + return &vt.ToolCallID.V + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetRole() *string { + if vt := u.OfDeveloper; vt != nil { + return (*string)(&vt.Role) + } else if vt := u.OfSystem; vt != nil { + return (*string)(&vt.Role) + } else if vt := u.OfUser; vt != nil { + return (*string)(&vt.Role) + } else if vt := u.OfAssistant; vt != nil { + return (*string)(&vt.Role) + } else if vt := u.OfTool; vt != nil { + return (*string)(&vt.Role) + } else if vt := u.OfFunction; vt != nil { + return (*string)(&vt.Role) + } + return nil +} + +func (u ChatCompletionMessageParamUnion) GetContent() (res chatCompletionMessageParamUnionContent) { + if vt := u.OfDeveloper; vt != nil { + res.OfChatCompletionDeveloperMessageContent = &vt.Content + } else if vt := u.OfSystem; vt != nil { + res.OfChatCompletionDeveloperMessageContent = &vt.Content + } else if vt := u.OfTool; vt != nil { + res.OfChatCompletionDeveloperMessageContent = &vt.Content + } else if vt := u.OfUser; vt != nil { + res.OfChatCompletionUserMessageContent = &vt.Content + } else if vt := u.OfAssistant; vt != nil { + res.OfChatCompletionAssistantMessageContent = &vt.Content + } else if vt := u.OfFunction; vt != nil { + res.OfString = &vt.Content + } + return +} + +// Only one field can be non-zero +type chatCompletionMessageParamUnionContent struct { + OfChatCompletionDeveloperMessageContent *[]ChatCompletionContentPartTextParam + OfChatCompletionUserMessageContent *[]ChatCompletionContentPartUnionParam + OfChatCompletionAssistantMessageContent *[]ChatCompletionAssistantMessageParamContentUnion + OfString *param.String } type ChatCompletionMessageToolCall struct { // The ID of the tool call. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The function that the model called. - Function ChatCompletionMessageToolCallFunction `json:"function,required"` + Function ChatCompletionMessageToolCallFunction `json:"function,omitzero,required"` // The type of the tool. Currently, only `function` is supported. - Type ChatCompletionMessageToolCallType `json:"type,required"` - JSON chatCompletionMessageToolCallJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + JSON struct { + ID resp.Field + Function resp.Field + Type resp.Field + raw string + } `json:"-"` } -// chatCompletionMessageToolCallJSON contains the JSON metadata for the struct -// [ChatCompletionMessageToolCall] -type chatCompletionMessageToolCallJSON struct { - ID apijson.Field - Function apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionMessageToolCall) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionMessageToolCall) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionMessageToolCall) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionMessageToolCallJSON) RawJSON() string { - return r.raw +// ToParam converts this ChatCompletionMessageToolCall to a +// ChatCompletionMessageToolCallParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ChatCompletionMessageToolCallParam.IsOverridden() +func (r ChatCompletionMessageToolCall) ToParam() ChatCompletionMessageToolCallParam { + return param.Override[ChatCompletionMessageToolCallParam](r.RawJSON()) } // The function that the model called. @@ -1375,55 +1232,38 @@ type ChatCompletionMessageToolCallFunction struct { // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments string `json:"arguments,required"` + Arguments string `json:"arguments,omitzero,required"` // The name of the function to call. - Name string `json:"name,required"` - JSON chatCompletionMessageToolCallFunctionJSON `json:"-"` + Name string `json:"name,omitzero,required"` + JSON struct { + Arguments resp.Field + Name resp.Field + raw string + } `json:"-"` } -// chatCompletionMessageToolCallFunctionJSON contains the JSON metadata for the -// struct [ChatCompletionMessageToolCallFunction] -type chatCompletionMessageToolCallFunctionJSON struct { - Arguments apijson.Field - Name apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionMessageToolCallFunction) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionMessageToolCallFunction) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionMessageToolCallFunction) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionMessageToolCallFunctionJSON) RawJSON() string { - return r.raw -} - -// The type of the tool. Currently, only `function` is supported. -type ChatCompletionMessageToolCallType string - -const ( - ChatCompletionMessageToolCallTypeFunction ChatCompletionMessageToolCallType = "function" -) - -func (r ChatCompletionMessageToolCallType) IsKnown() bool { - switch r { - case ChatCompletionMessageToolCallTypeFunction: - return true - } - return false -} - type ChatCompletionMessageToolCallParam struct { // The ID of the tool call. - ID param.Field[string] `json:"id,required"` + ID param.String `json:"id,omitzero,required"` // The function that the model called. - Function param.Field[ChatCompletionMessageToolCallFunctionParam] `json:"function,required"` + Function ChatCompletionMessageToolCallFunctionParam `json:"function,omitzero,required"` // The type of the tool. Currently, only `function` is supported. - Type param.Field[ChatCompletionMessageToolCallType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + apiobject } +func (f ChatCompletionMessageToolCallParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionMessageToolCallParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionMessageToolCallParam + return param.MarshalObject(r, (*shadow)(&r)) } // The function that the model called. @@ -1432,13 +1272,19 @@ type ChatCompletionMessageToolCallFunctionParam struct { // format. Note that the model does not always generate valid JSON, and may // hallucinate parameters not defined by your function schema. Validate the // arguments in your code before calling your function. - Arguments param.Field[string] `json:"arguments,required"` + Arguments param.String `json:"arguments,omitzero,required"` // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` + apiobject +} + +func (f ChatCompletionMessageToolCallFunctionParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionMessageToolCallFunctionParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionMessageToolCallFunctionParam + return param.MarshalObject(r, (*shadow)(&r)) } type ChatCompletionModality string @@ -1448,50 +1294,37 @@ const ( ChatCompletionModalityAudio ChatCompletionModality = "audio" ) -func (r ChatCompletionModality) IsKnown() bool { - switch r { - case ChatCompletionModalityText, ChatCompletionModalityAudio: - return true - } - return false -} - // Specifies a tool the model should use. Use to force the model to call a specific // function. type ChatCompletionNamedToolChoiceParam struct { - Function param.Field[ChatCompletionNamedToolChoiceFunctionParam] `json:"function,required"` + Function ChatCompletionNamedToolChoiceFunctionParam `json:"function,omitzero,required"` // The type of the tool. Currently, only `function` is supported. - Type param.Field[ChatCompletionNamedToolChoiceType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + apiobject } +func (f ChatCompletionNamedToolChoiceParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionNamedToolChoiceParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionNamedToolChoiceParam + return param.MarshalObject(r, (*shadow)(&r)) } -func (r ChatCompletionNamedToolChoiceParam) implementsChatCompletionToolChoiceOptionUnionParam() {} - type ChatCompletionNamedToolChoiceFunctionParam struct { // The name of the function to call. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` + apiobject +} + +func (f ChatCompletionNamedToolChoiceFunctionParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionNamedToolChoiceFunctionParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -// The type of the tool. Currently, only `function` is supported. -type ChatCompletionNamedToolChoiceType string - -const ( - ChatCompletionNamedToolChoiceTypeFunction ChatCompletionNamedToolChoiceType = "function" -) - -func (r ChatCompletionNamedToolChoiceType) IsKnown() bool { - switch r { - case ChatCompletionNamedToolChoiceTypeFunction: - return true - } - return false + type shadow ChatCompletionNamedToolChoiceFunctionParam + return param.MarshalObject(r, (*shadow)(&r)) } // Static predicted output content, such as the content of a text file that is @@ -1500,30 +1333,22 @@ type ChatCompletionPredictionContentParam struct { // The content that should be matched when generating a model response. If // generated tokens would match this content, the entire model response can be // returned much more quickly. - Content param.Field[[]ChatCompletionContentPartTextParam] `json:"content,required"` + Content []ChatCompletionContentPartTextParam `json:"content,omitzero,required"` // The type of the predicted content you want to provide. This type is currently // always `content`. - Type param.Field[ChatCompletionPredictionContentType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "content". + Type constant.Content `json:"type,required"` + apiobject +} + +func (f ChatCompletionPredictionContentParam) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionPredictionContentParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -// The type of the predicted content you want to provide. This type is currently -// always `content`. -type ChatCompletionPredictionContentType string - -const ( - ChatCompletionPredictionContentTypeContent ChatCompletionPredictionContentType = "content" -) - -func (r ChatCompletionPredictionContentType) IsKnown() bool { - switch r { - case ChatCompletionPredictionContentTypeContent: - return true - } - return false + type shadow ChatCompletionPredictionContentParam + return param.MarshalObject(r, (*shadow)(&r)) } // **o1 and o3-mini models only** @@ -1540,49 +1365,37 @@ const ( ChatCompletionReasoningEffortHigh ChatCompletionReasoningEffort = "high" ) -func (r ChatCompletionReasoningEffort) IsKnown() bool { - switch r { - case ChatCompletionReasoningEffortLow, ChatCompletionReasoningEffortMedium, ChatCompletionReasoningEffortHigh: - return true - } - return false -} - // A chat completion message generated by the model. type ChatCompletionStoreMessage struct { // The identifier of the chat message. - ID string `json:"id,required"` - JSON chatCompletionStoreMessageJSON `json:"-"` + ID string `json:"id,omitzero,required"` + JSON struct { + ID resp.Field + raw string + } `json:"-"` ChatCompletionMessage } -// chatCompletionStoreMessageJSON contains the JSON metadata for the struct -// [ChatCompletionStoreMessage] -type chatCompletionStoreMessageJSON struct { - ID apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionStoreMessage) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionStoreMessage) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionStoreMessage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionStoreMessageJSON) RawJSON() string { - return r.raw -} - // Options for streaming response. Only set this when you set `stream: true`. type ChatCompletionStreamOptionsParam struct { // If set, an additional chunk will be streamed before the `data: [DONE]` message. // The `usage` field on this chunk shows the token usage statistics for the entire // request, and the `choices` field will always be an empty array. All other chunks // will also include a `usage` field, but with a null value. - IncludeUsage param.Field[bool] `json:"include_usage"` + IncludeUsage param.Bool `json:"include_usage,omitzero"` + apiobject } +func (f ChatCompletionStreamOptionsParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionStreamOptionsParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionStreamOptionsParam + return param.MarshalObject(r, (*shadow)(&r)) } // Developer-provided instructions that the model should follow, regardless of @@ -1590,151 +1403,135 @@ func (r ChatCompletionStreamOptionsParam) MarshalJSON() (data []byte, err error) // for this purpose instead. type ChatCompletionSystemMessageParam struct { // The contents of the system message. - Content param.Field[[]ChatCompletionContentPartTextParam] `json:"content,required"` + Content []ChatCompletionContentPartTextParam `json:"content,omitzero,required"` // The role of the messages author, in this case `system`. - Role param.Field[ChatCompletionSystemMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "system". + Role constant.System `json:"role,required"` // An optional name for the participant. Provides the model information to // differentiate between participants of the same role. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` + apiobject } +func (f ChatCompletionSystemMessageParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionSystemMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionSystemMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `system`. -type ChatCompletionSystemMessageParamRole string - -const ( - ChatCompletionSystemMessageParamRoleSystem ChatCompletionSystemMessageParamRole = "system" -) - -func (r ChatCompletionSystemMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionSystemMessageParamRoleSystem: - return true - } - return false + type shadow ChatCompletionSystemMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } type ChatCompletionTokenLogprob struct { // The token. - Token string `json:"token,required"` + Token string `json:"token,omitzero,required"` // A list of integers representing the UTF-8 bytes representation of the token. // Useful in instances where characters are represented by multiple tokens and // their byte representations must be combined to generate the correct text // representation. Can be `null` if there is no bytes representation for the token. - Bytes []int64 `json:"bytes,required,nullable"` + Bytes []int64 `json:"bytes,omitzero,required,nullable"` // The log probability of this token, if it is within the top 20 most likely // tokens. Otherwise, the value `-9999.0` is used to signify that the token is very // unlikely. - Logprob float64 `json:"logprob,required"` + Logprob float64 `json:"logprob,omitzero,required"` // List of the most likely tokens and their log probability, at this token // position. In rare cases, there may be fewer than the number of requested // `top_logprobs` returned. - TopLogprobs []ChatCompletionTokenLogprobTopLogprob `json:"top_logprobs,required"` - JSON chatCompletionTokenLogprobJSON `json:"-"` + TopLogprobs []ChatCompletionTokenLogprobTopLogprob `json:"top_logprobs,omitzero,required"` + JSON struct { + Token resp.Field + Bytes resp.Field + Logprob resp.Field + TopLogprobs resp.Field + raw string + } `json:"-"` } -// chatCompletionTokenLogprobJSON contains the JSON metadata for the struct -// [ChatCompletionTokenLogprob] -type chatCompletionTokenLogprobJSON struct { - Token apijson.Field - Bytes apijson.Field - Logprob apijson.Field - TopLogprobs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionTokenLogprob) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionTokenLogprob) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionTokenLogprob) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionTokenLogprobJSON) RawJSON() string { - return r.raw -} - type ChatCompletionTokenLogprobTopLogprob struct { // The token. - Token string `json:"token,required"` + Token string `json:"token,omitzero,required"` // A list of integers representing the UTF-8 bytes representation of the token. // Useful in instances where characters are represented by multiple tokens and // their byte representations must be combined to generate the correct text // representation. Can be `null` if there is no bytes representation for the token. - Bytes []int64 `json:"bytes,required,nullable"` + Bytes []int64 `json:"bytes,omitzero,required,nullable"` // The log probability of this token, if it is within the top 20 most likely // tokens. Otherwise, the value `-9999.0` is used to signify that the token is very // unlikely. - Logprob float64 `json:"logprob,required"` - JSON chatCompletionTokenLogprobTopLogprobJSON `json:"-"` + Logprob float64 `json:"logprob,omitzero,required"` + JSON struct { + Token resp.Field + Bytes resp.Field + Logprob resp.Field + raw string + } `json:"-"` } -// chatCompletionTokenLogprobTopLogprobJSON contains the JSON metadata for the -// struct [ChatCompletionTokenLogprobTopLogprob] -type chatCompletionTokenLogprobTopLogprobJSON struct { - Token apijson.Field - Bytes apijson.Field - Logprob apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ChatCompletionTokenLogprobTopLogprob) UnmarshalJSON(data []byte) (err error) { +func (r ChatCompletionTokenLogprobTopLogprob) RawJSON() string { return r.JSON.raw } +func (r *ChatCompletionTokenLogprobTopLogprob) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r chatCompletionTokenLogprobTopLogprobJSON) RawJSON() string { - return r.raw +type ChatCompletionToolParam struct { + Function shared.FunctionDefinitionParam `json:"function,omitzero,required"` + // The type of the tool. Currently, only `function` is supported. + // + // This field can be elided, and will be automatically set as "function". + Type constant.Function `json:"type,required"` + apiobject } -type ChatCompletionToolParam struct { - Function param.Field[shared.FunctionDefinitionParam] `json:"function,required"` - // The type of the tool. Currently, only `function` is supported. - Type param.Field[ChatCompletionToolType] `json:"type,required"` -} +func (f ChatCompletionToolParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } func (r ChatCompletionToolParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionToolParam + return param.MarshalObject(r, (*shadow)(&r)) } -// The type of the tool. Currently, only `function` is supported. -type ChatCompletionToolType string +func NewChatCompletionToolChoiceOptionOfChatCompletionNamedToolChoice(function ChatCompletionNamedToolChoiceFunctionParam) ChatCompletionToolChoiceOptionUnionParam { + var variant ChatCompletionNamedToolChoiceParam + variant.Function = function + return ChatCompletionToolChoiceOptionUnionParam{OfChatCompletionNamedToolChoice: &variant} +} -const ( - ChatCompletionToolTypeFunction ChatCompletionToolType = "function" -) +// Only one field can be non-zero +type ChatCompletionToolChoiceOptionUnionParam struct { + // Check if union is this variant with !param.IsOmitted(union.OfAuto) + OfAuto string + OfChatCompletionNamedToolChoice *ChatCompletionNamedToolChoiceParam + apiunion +} -func (r ChatCompletionToolType) IsKnown() bool { - switch r { - case ChatCompletionToolTypeFunction: - return true +func (u ChatCompletionToolChoiceOptionUnionParam) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() +} + +func (u ChatCompletionToolChoiceOptionUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionToolChoiceOptionUnionParam](u.OfAuto, u.OfChatCompletionNamedToolChoice) +} + +func (u ChatCompletionToolChoiceOptionUnionParam) GetFunction() *ChatCompletionNamedToolChoiceFunctionParam { + if vt := u.OfChatCompletionNamedToolChoice; vt != nil { + return &vt.Function } - return false + return nil } -// Controls which (if any) tool is called by the model. `none` means the model will -// not call any tool and instead generates a message. `auto` means the model can -// pick between generating a message or calling one or more tools. `required` means -// the model must call one or more tools. Specifying a particular tool via -// `{"type": "function", "function": {"name": "my_function"}}` forces the model to -// call that tool. -// -// `none` is the default when no tools are present. `auto` is the default if tools -// are present. -// -// Satisfied by [ChatCompletionToolChoiceOptionAuto], -// [ChatCompletionNamedToolChoiceParam]. -type ChatCompletionToolChoiceOptionUnionParam interface { - implementsChatCompletionToolChoiceOptionUnionParam() +func (u ChatCompletionToolChoiceOptionUnionParam) GetType() *constant.Function { + if vt := u.OfChatCompletionNamedToolChoice; vt != nil { + return &vt.Type + } + return nil } // `none` means the model will not call any tool and instead generates a message. // `auto` means the model can pick between generating a message or calling one or // more tools. `required` means the model must call one or more tools. -type ChatCompletionToolChoiceOptionAuto string +type ChatCompletionToolChoiceOptionAuto = string const ( ChatCompletionToolChoiceOptionAutoNone ChatCompletionToolChoiceOptionAuto = "none" @@ -1742,77 +1539,45 @@ const ( ChatCompletionToolChoiceOptionAutoRequired ChatCompletionToolChoiceOptionAuto = "required" ) -func (r ChatCompletionToolChoiceOptionAuto) IsKnown() bool { - switch r { - case ChatCompletionToolChoiceOptionAutoNone, ChatCompletionToolChoiceOptionAutoAuto, ChatCompletionToolChoiceOptionAutoRequired: - return true - } - return false -} - -func (r ChatCompletionToolChoiceOptionAuto) implementsChatCompletionToolChoiceOptionUnionParam() {} - type ChatCompletionToolMessageParam struct { // The contents of the tool message. - Content param.Field[[]ChatCompletionContentPartTextParam] `json:"content,required"` + Content []ChatCompletionContentPartTextParam `json:"content,omitzero,required"` // The role of the messages author, in this case `tool`. - Role param.Field[ChatCompletionToolMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "tool". + Role constant.Tool `json:"role,required"` // Tool call that this message is responding to. - ToolCallID param.Field[string] `json:"tool_call_id,required"` + ToolCallID param.String `json:"tool_call_id,omitzero,required"` + apiobject } +func (f ChatCompletionToolMessageParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionToolMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionToolMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `tool`. -type ChatCompletionToolMessageParamRole string - -const ( - ChatCompletionToolMessageParamRoleTool ChatCompletionToolMessageParamRole = "tool" -) - -func (r ChatCompletionToolMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionToolMessageParamRoleTool: - return true - } - return false + type shadow ChatCompletionToolMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } // Messages sent by an end user, containing prompts or additional context // information. type ChatCompletionUserMessageParam struct { // The contents of the user message. - Content param.Field[[]ChatCompletionContentPartUnionParam] `json:"content,required"` + Content []ChatCompletionContentPartUnionParam `json:"content,omitzero,required"` // The role of the messages author, in this case `user`. - Role param.Field[ChatCompletionUserMessageParamRole] `json:"role,required"` + // + // This field can be elided, and will be automatically set as "user". + Role constant.User `json:"role,required"` // An optional name for the participant. Provides the model information to // differentiate between participants of the same role. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` + apiobject } +func (f ChatCompletionUserMessageParam) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionUserMessageParam) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -func (r ChatCompletionUserMessageParam) implementsChatCompletionMessageParamUnion() {} - -// The role of the messages author, in this case `user`. -type ChatCompletionUserMessageParamRole string - -const ( - ChatCompletionUserMessageParamRoleUser ChatCompletionUserMessageParamRole = "user" -) - -func (r ChatCompletionUserMessageParamRole) IsKnown() bool { - switch r { - case ChatCompletionUserMessageParamRoleUser: - return true - } - return false + type shadow ChatCompletionUserMessageParam + return param.MarshalObject(r, (*shadow)(&r)) } type ChatCompletionNewParams struct { @@ -1822,19 +1587,19 @@ type ChatCompletionNewParams struct { // [text](https://platform.openai.com/docs/guides/text-generation), // [images](https://platform.openai.com/docs/guides/vision), and // [audio](https://platform.openai.com/docs/guides/audio). - Messages param.Field[[]ChatCompletionMessageParamUnion] `json:"messages,required"` + Messages []ChatCompletionMessageParamUnion `json:"messages,omitzero,required"` // ID of the model to use. See the // [model endpoint compatibility](https://platform.openai.com/docs/models#model-endpoint-compatibility) // table for details on which models work with the Chat API. - Model param.Field[ChatModel] `json:"model,required"` + Model ChatModel `json:"model,omitzero,required"` // Parameters for audio output. Required when audio output is requested with // `modalities: ["audio"]`. // [Learn more](https://platform.openai.com/docs/guides/audio). - Audio param.Field[ChatCompletionAudioParam] `json:"audio"` + Audio ChatCompletionAudioParam `json:"audio,omitzero"` // Number between -2.0 and 2.0. Positive values penalize new tokens based on their // existing frequency in the text so far, decreasing the model's likelihood to // repeat the same line verbatim. - FrequencyPenalty param.Field[float64] `json:"frequency_penalty"` + FrequencyPenalty param.Float `json:"frequency_penalty,omitzero"` // Deprecated in favor of `tool_choice`. // // Controls which (if any) function is called by the model. @@ -1849,11 +1614,11 @@ type ChatCompletionNewParams struct { // // `none` is the default when no functions are present. `auto` is the default if // functions are present. - FunctionCall param.Field[ChatCompletionNewParamsFunctionCallUnion] `json:"function_call"` + FunctionCall ChatCompletionNewParamsFunctionCallUnion `json:"function_call,omitzero"` // Deprecated in favor of `tools`. // // A list of functions the model may generate JSON inputs for. - Functions param.Field[[]ChatCompletionNewParamsFunction] `json:"functions"` + Functions []ChatCompletionNewParamsFunction `json:"functions,omitzero"` // Modify the likelihood of specified tokens appearing in the completion. // // Accepts a JSON object that maps tokens (specified by their token ID in the @@ -1862,15 +1627,15 @@ type ChatCompletionNewParams struct { // effect will vary per model, but values between -1 and 1 should decrease or // increase likelihood of selection; values like -100 or 100 should result in a ban // or exclusive selection of the relevant token. - LogitBias param.Field[map[string]int64] `json:"logit_bias"` + LogitBias map[string]int64 `json:"logit_bias,omitzero"` // Whether to return log probabilities of the output tokens or not. If true, // returns the log probabilities of each output token returned in the `content` of // `message`. - Logprobs param.Field[bool] `json:"logprobs"` + Logprobs param.Bool `json:"logprobs,omitzero"` // An upper bound for the number of tokens that can be generated for a completion, // including visible output tokens and // [reasoning tokens](https://platform.openai.com/docs/guides/reasoning). - MaxCompletionTokens param.Field[int64] `json:"max_completion_tokens"` + MaxCompletionTokens param.Int `json:"max_completion_tokens,omitzero"` // The maximum number of [tokens](/tokenizer) that can be generated in the chat // completion. This value can be used to control // [costs](https://openai.com/api/pricing/) for text generated via API. @@ -1878,14 +1643,14 @@ type ChatCompletionNewParams struct { // This value is now deprecated in favor of `max_completion_tokens`, and is not // compatible with // [o1 series models](https://platform.openai.com/docs/guides/reasoning). - MaxTokens param.Field[int64] `json:"max_tokens"` + MaxTokens param.Int `json:"max_tokens,omitzero"` // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and // querying for objects via API or the dashboard. // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata"` + Metadata shared.MetadataParam `json:"metadata,omitzero"` // Output types that you would like the model to generate for this request. Most // models are capable of generating text, which is the default: // @@ -1896,29 +1661,31 @@ type ChatCompletionNewParams struct { // this model generate both text and audio responses, you can use: // // `["text", "audio"]` - Modalities param.Field[[]ChatCompletionModality] `json:"modalities"` + Modalities []ChatCompletionModality `json:"modalities,omitzero"` // How many chat completion choices to generate for each input message. Note that // you will be charged based on the number of generated tokens across all of the // choices. Keep `n` as `1` to minimize costs. - N param.Field[int64] `json:"n"` + N param.Int `json:"n,omitzero"` // Whether to enable // [parallel function calling](https://platform.openai.com/docs/guides/function-calling#configuring-parallel-function-calling) // during tool use. - ParallelToolCalls param.Field[bool] `json:"parallel_tool_calls"` + ParallelToolCalls param.Bool `json:"parallel_tool_calls,omitzero"` // Static predicted output content, such as the content of a text file that is // being regenerated. - Prediction param.Field[ChatCompletionPredictionContentParam] `json:"prediction"` + Prediction ChatCompletionPredictionContentParam `json:"prediction,omitzero"` // Number between -2.0 and 2.0. Positive values penalize new tokens based on // whether they appear in the text so far, increasing the model's likelihood to // talk about new topics. - PresencePenalty param.Field[float64] `json:"presence_penalty"` + PresencePenalty param.Float `json:"presence_penalty,omitzero"` // **o1 and o3-mini models only** // // Constrains effort on reasoning for // [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently // supported values are `low`, `medium`, and `high`. Reducing reasoning effort can // result in faster responses and fewer tokens used on reasoning in a response. - ReasoningEffort param.Field[ChatCompletionReasoningEffort] `json:"reasoning_effort"` + // + // Any of "low", "medium", "high" + ReasoningEffort ChatCompletionReasoningEffort `json:"reasoning_effort,omitzero"` // An object specifying the format that the model must output. // // Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured @@ -1936,13 +1703,13 @@ type ChatCompletionNewParams struct { // the message content may be partially cut off if `finish_reason="length"`, which // indicates the generation exceeded `max_tokens` or the conversation exceeded the // max context length. - ResponseFormat param.Field[ChatCompletionNewParamsResponseFormatUnion] `json:"response_format"` + ResponseFormat ChatCompletionNewParamsResponseFormatUnion `json:"response_format,omitzero"` // This feature is in Beta. If specified, our system will make a best effort to // sample deterministically, such that repeated requests with the same `seed` and // parameters should return the same result. Determinism is not guaranteed, and you // should refer to the `system_fingerprint` response parameter to monitor changes // in the backend. - Seed param.Field[int64] `json:"seed"` + Seed param.Int `json:"seed,omitzero"` // Specifies the latency tier to use for processing the request. This parameter is // relevant for customers subscribed to the scale tier service: // @@ -1954,20 +1721,22 @@ type ChatCompletionNewParams struct { // - If set to 'default', the request will be processed using the default service // tier with a lower uptime SLA and no latency guarantee. // - When not set, the default behavior is 'auto'. - ServiceTier param.Field[ChatCompletionNewParamsServiceTier] `json:"service_tier"` + // + // Any of "auto", "default" + ServiceTier ChatCompletionNewParamsServiceTier `json:"service_tier,omitzero"` // Up to 4 sequences where the API will stop generating further tokens. - Stop param.Field[ChatCompletionNewParamsStopUnion] `json:"stop"` + Stop ChatCompletionNewParamsStopUnion `json:"stop,omitzero"` // Whether or not to store the output of this chat completion request for use in // our [model distillation](https://platform.openai.com/docs/guides/distillation) // or [evals](https://platform.openai.com/docs/guides/evals) products. - Store param.Field[bool] `json:"store"` + Store param.Bool `json:"store,omitzero"` // Options for streaming response. Only set this when you set `stream: true`. - StreamOptions param.Field[ChatCompletionStreamOptionsParam] `json:"stream_options"` + StreamOptions ChatCompletionStreamOptionsParam `json:"stream_options,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. We generally recommend altering this or `top_p` but // not both. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // Controls which (if any) tool is called by the model. `none` means the model will // not call any tool and instead generates a message. `auto` means the model can // pick between generating a message or calling one or more tools. `required` means @@ -1977,83 +1746,76 @@ type ChatCompletionNewParams struct { // // `none` is the default when no tools are present. `auto` is the default if tools // are present. - ToolChoice param.Field[ChatCompletionToolChoiceOptionUnionParam] `json:"tool_choice"` + ToolChoice ChatCompletionToolChoiceOptionUnionParam `json:"tool_choice,omitzero"` // A list of tools the model may call. Currently, only functions are supported as a // tool. Use this to provide a list of functions the model may generate JSON inputs // for. A max of 128 functions are supported. - Tools param.Field[[]ChatCompletionToolParam] `json:"tools"` + Tools []ChatCompletionToolParam `json:"tools,omitzero"` // An integer between 0 and 20 specifying the number of most likely tokens to // return at each token position, each with an associated log probability. // `logprobs` must be set to `true` if this parameter is used. - TopLogprobs param.Field[int64] `json:"top_logprobs"` + TopLogprobs param.Int `json:"top_logprobs,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or `temperature` but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f ChatCompletionNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionNewParams + return param.MarshalObject(r, (*shadow)(&r)) } -// Deprecated in favor of `tool_choice`. -// -// Controls which (if any) function is called by the model. -// -// `none` means the model will not call a function and instead generates a message. -// -// `auto` means the model can pick between generating a message or calling a -// function. -// -// Specifying a particular function via `{"name": "my_function"}` forces the model -// to call that function. -// -// `none` is the default when no functions are present. `auto` is the default if -// functions are present. -// -// Satisfied by [ChatCompletionNewParamsFunctionCallAuto], -// [ChatCompletionFunctionCallOptionParam]. -// -// Deprecated: deprecated -type ChatCompletionNewParamsFunctionCallUnion interface { - implementsChatCompletionNewParamsFunctionCallUnion() +// Only one field can be non-zero +type ChatCompletionNewParamsFunctionCallUnion struct { + // Check if union is this variant with !param.IsOmitted(union.OfAuto) + OfAuto string + OfFunctionCallOption *ChatCompletionFunctionCallOptionParam + apiunion +} + +func (u ChatCompletionNewParamsFunctionCallUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() +} + +func (u ChatCompletionNewParamsFunctionCallUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionNewParamsFunctionCallUnion](u.OfAuto, u.OfFunctionCallOption) +} + +func (u ChatCompletionNewParamsFunctionCallUnion) GetName() *string { + if vt := u.OfFunctionCallOption; vt != nil && !vt.Name.IsOmitted() { + return &vt.Name.V + } + return nil } // `none` means the model will not call a function and instead generates a message. // `auto` means the model can pick between generating a message or calling a // function. -type ChatCompletionNewParamsFunctionCallAuto string +type ChatCompletionNewParamsFunctionCallAuto = string const ( ChatCompletionNewParamsFunctionCallAutoNone ChatCompletionNewParamsFunctionCallAuto = "none" ChatCompletionNewParamsFunctionCallAutoAuto ChatCompletionNewParamsFunctionCallAuto = "auto" ) -func (r ChatCompletionNewParamsFunctionCallAuto) IsKnown() bool { - switch r { - case ChatCompletionNewParamsFunctionCallAutoNone, ChatCompletionNewParamsFunctionCallAutoAuto: - return true - } - return false -} - -func (r ChatCompletionNewParamsFunctionCallAuto) implementsChatCompletionNewParamsFunctionCallUnion() { -} - // Deprecated: deprecated type ChatCompletionNewParamsFunction struct { // The name of the function to be called. Must be a-z, A-Z, 0-9, or contain // underscores and dashes, with a maximum length of 64. - Name param.Field[string] `json:"name,required"` + Name param.String `json:"name,omitzero,required"` // A description of what the function does, used by the model to choose when and // how to call the function. - Description param.Field[string] `json:"description"` + Description param.String `json:"description,omitzero"` // The parameters the functions accepts, described as a JSON Schema object. See the // [guide](https://platform.openai.com/docs/guides/function-calling) for examples, // and the @@ -2061,83 +1823,49 @@ type ChatCompletionNewParamsFunction struct { // documentation about the format. // // Omitting `parameters` defines a function with an empty parameter list. - Parameters param.Field[shared.FunctionParameters] `json:"parameters"` + Parameters shared.FunctionParameters `json:"parameters,omitzero"` + apiobject } +func (f ChatCompletionNewParamsFunction) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionNewParamsFunction) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionNewParamsFunction + return param.MarshalObject(r, (*shadow)(&r)) } -// An object specifying the format that the model must output. -// -// Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured -// Outputs which ensures the model will match your supplied JSON schema. Learn more -// in the -// [Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs). -// -// Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the -// message the model generates is valid JSON. -// -// **Important:** when using JSON mode, you **must** also instruct the model to -// produce JSON yourself via a system or user message. Without this, the model may -// generate an unending stream of whitespace until the generation reaches the token -// limit, resulting in a long-running and seemingly "stuck" request. Also note that -// the message content may be partially cut off if `finish_reason="length"`, which -// indicates the generation exceeded `max_tokens` or the conversation exceeded the -// max context length. -type ChatCompletionNewParamsResponseFormat struct { - // The type of response format being defined: `text` - Type param.Field[ChatCompletionNewParamsResponseFormatType] `json:"type,required"` - JSONSchema param.Field[interface{}] `json:"json_schema"` +// Only one field can be non-zero +type ChatCompletionNewParamsResponseFormatUnion struct { + OfResponseFormatText *shared.ResponseFormatTextParam + OfResponseFormatJSONObject *shared.ResponseFormatJSONObjectParam + OfResponseFormatJSONSchema *shared.ResponseFormatJSONSchemaParam + apiunion } -func (r ChatCompletionNewParamsResponseFormat) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) +func (u ChatCompletionNewParamsResponseFormatUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r ChatCompletionNewParamsResponseFormat) ImplementsChatCompletionNewParamsResponseFormatUnion() { +func (u ChatCompletionNewParamsResponseFormatUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionNewParamsResponseFormatUnion](u.OfResponseFormatText, u.OfResponseFormatJSONObject, u.OfResponseFormatJSONSchema) } -// An object specifying the format that the model must output. -// -// Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured -// Outputs which ensures the model will match your supplied JSON schema. Learn more -// in the -// [Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs). -// -// Setting to `{ "type": "json_object" }` enables JSON mode, which ensures the -// message the model generates is valid JSON. -// -// **Important:** when using JSON mode, you **must** also instruct the model to -// produce JSON yourself via a system or user message. Without this, the model may -// generate an unending stream of whitespace until the generation reaches the token -// limit, resulting in a long-running and seemingly "stuck" request. Also note that -// the message content may be partially cut off if `finish_reason="length"`, which -// indicates the generation exceeded `max_tokens` or the conversation exceeded the -// max context length. -// -// Satisfied by [shared.ResponseFormatTextParam], -// [shared.ResponseFormatJSONObjectParam], [shared.ResponseFormatJSONSchemaParam], -// [ChatCompletionNewParamsResponseFormat]. -type ChatCompletionNewParamsResponseFormatUnion interface { - ImplementsChatCompletionNewParamsResponseFormatUnion() -} - -// The type of response format being defined: `text` -type ChatCompletionNewParamsResponseFormatType string - -const ( - ChatCompletionNewParamsResponseFormatTypeText ChatCompletionNewParamsResponseFormatType = "text" - ChatCompletionNewParamsResponseFormatTypeJSONObject ChatCompletionNewParamsResponseFormatType = "json_object" - ChatCompletionNewParamsResponseFormatTypeJSONSchema ChatCompletionNewParamsResponseFormatType = "json_schema" -) - -func (r ChatCompletionNewParamsResponseFormatType) IsKnown() bool { - switch r { - case ChatCompletionNewParamsResponseFormatTypeText, ChatCompletionNewParamsResponseFormatTypeJSONObject, ChatCompletionNewParamsResponseFormatTypeJSONSchema: - return true +func (u ChatCompletionNewParamsResponseFormatUnion) GetJSONSchema() *shared.ResponseFormatJSONSchemaJSONSchemaParam { + if vt := u.OfResponseFormatJSONSchema; vt != nil { + return &vt.JSONSchema } - return false + return nil +} + +func (u ChatCompletionNewParamsResponseFormatUnion) GetType() *string { + if vt := u.OfResponseFormatText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfResponseFormatJSONObject; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfResponseFormatJSONSchema; vt != nil { + return (*string)(&vt.Type) + } + return nil } // Specifies the latency tier to use for processing the request. This parameter is @@ -2158,25 +1886,19 @@ const ( ChatCompletionNewParamsServiceTierDefault ChatCompletionNewParamsServiceTier = "default" ) -func (r ChatCompletionNewParamsServiceTier) IsKnown() bool { - switch r { - case ChatCompletionNewParamsServiceTierAuto, ChatCompletionNewParamsServiceTierDefault: - return true - } - return false +// Only one field can be non-zero +type ChatCompletionNewParamsStopUnion struct { + OfString param.String + OfChatCompletionNewsStopArray []string + apiunion } -// Up to 4 sequences where the API will stop generating further tokens. -// -// Satisfied by [shared.UnionString], [ChatCompletionNewParamsStopArray]. -type ChatCompletionNewParamsStopUnion interface { - ImplementsChatCompletionNewParamsStopUnion() +func (u ChatCompletionNewParamsStopUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u ChatCompletionNewParamsStopUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[ChatCompletionNewParamsStopUnion](u.OfString, u.OfChatCompletionNewsStopArray) } -type ChatCompletionNewParamsStopArray []string - -func (r ChatCompletionNewParamsStopArray) ImplementsChatCompletionNewParamsStopUnion() {} - type ChatCompletionUpdateParams struct { // Set of 16 key-value pairs that can be attached to an object. This can be useful // for storing additional information about the object in a structured format, and @@ -2184,29 +1906,38 @@ type ChatCompletionUpdateParams struct { // // Keys are strings with a maximum length of 64 characters. Values are strings with // a maximum length of 512 characters. - Metadata param.Field[shared.MetadataParam] `json:"metadata,required"` + Metadata shared.MetadataParam `json:"metadata,omitzero,required"` + apiobject } +func (f ChatCompletionUpdateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ChatCompletionUpdateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ChatCompletionUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) } type ChatCompletionListParams struct { // Identifier for the last chat completion from the previous pagination request. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // Number of chat completions to retrieve. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // A list of metadata keys to filter the chat completions by. Example: // // `metadata[key1]=value1&metadata[key2]=value2` - Metadata param.Field[shared.MetadataParam] `query:"metadata"` + Metadata shared.MetadataParam `query:"metadata,omitzero"` // The model used to generate the chat completions. - Model param.Field[string] `query:"model"` + Model param.String `query:"model,omitzero"` // Sort order for chat completions by timestamp. Use `asc` for ascending order or // `desc` for descending order. Defaults to `asc`. - Order param.Field[ChatCompletionListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order ChatCompletionListParamsOrder `query:"order,omitzero"` + apiobject } +func (f ChatCompletionListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [ChatCompletionListParams]'s query parameters as // `url.Values`. func (r ChatCompletionListParams) URLQuery() (v url.Values) { @@ -2224,11 +1955,3 @@ const ( ChatCompletionListParamsOrderAsc ChatCompletionListParamsOrder = "asc" ChatCompletionListParamsOrderDesc ChatCompletionListParamsOrder = "desc" ) - -func (r ChatCompletionListParamsOrder) IsKnown() bool { - switch r { - case ChatCompletionListParamsOrderAsc, ChatCompletionListParamsOrderDesc: - return true - } - return false -} diff --git a/chatcompletion_test.go b/chatcompletion_test.go index 1fb57aa..b41d570 100644 --- a/chatcompletion_test.go +++ b/chatcompletion_test.go @@ -27,69 +27,74 @@ func TestChatCompletionNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionDeveloperMessageParam{ - Content: openai.F([]openai.ChatCompletionContentPartTextParam{{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - Role: openai.F(openai.ChatCompletionDeveloperMessageParamRoleDeveloper), - Name: openai.F("name"), - }}), - Model: openai.F(openai.ChatModelO3Mini), - Audio: openai.F(openai.ChatCompletionAudioParam{ - Format: openai.F(openai.ChatCompletionAudioParamFormatWAV), - Voice: openai.F(openai.ChatCompletionAudioParamVoiceAlloy), - }), - FrequencyPenalty: openai.F(-2.000000), - FunctionCall: openai.F[openai.ChatCompletionNewParamsFunctionCallUnion](openai.ChatCompletionNewParamsFunctionCallAuto(openai.ChatCompletionNewParamsFunctionCallAutoNone)), - Functions: openai.F([]openai.ChatCompletionNewParamsFunction{{ - Name: openai.F("name"), - Description: openai.F("description"), - Parameters: openai.F(shared.FunctionParameters{ + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfDeveloper: &openai.ChatCompletionDeveloperMessageParam{ + Content: []openai.ChatCompletionContentPartTextParam{{Text: openai.String("text")}}, + Name: openai.String("name"), + }, + }}, + Model: openai.ChatModelO3Mini, + Audio: openai.ChatCompletionAudioParam{ + Format: "wav", + Voice: "alloy", + }, + FrequencyPenalty: openai.Float(-2), + FunctionCall: openai.ChatCompletionNewParamsFunctionCallUnion{ + OfAuto: "none", + }, + Functions: []openai.ChatCompletionNewParamsFunction{{ + Name: openai.String("name"), + Description: openai.String("description"), + Parameters: shared.FunctionParameters{ "foo": "bar", - }), - }}), - LogitBias: openai.F(map[string]int64{ - "foo": int64(0), - }), - Logprobs: openai.F(true), - MaxCompletionTokens: openai.F(int64(0)), - MaxTokens: openai.F(int64(0)), - Metadata: openai.F(shared.MetadataParam{ + }, + }}, + LogitBias: map[string]int64{ + "foo": 0, + }, + Logprobs: openai.Bool(true), + MaxCompletionTokens: openai.Int(0), + MaxTokens: openai.Int(0), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Modalities: openai.F([]openai.ChatCompletionModality{openai.ChatCompletionModalityText}), - N: openai.F(int64(1)), - ParallelToolCalls: openai.F(true), - Prediction: openai.F(openai.ChatCompletionPredictionContentParam{ - Content: openai.F([]openai.ChatCompletionContentPartTextParam{{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - Type: openai.F(openai.ChatCompletionPredictionContentTypeContent), - }), - PresencePenalty: openai.F(-2.000000), - ReasoningEffort: openai.F(openai.ChatCompletionReasoningEffortLow), - ResponseFormat: openai.F[openai.ChatCompletionNewParamsResponseFormatUnion](shared.ResponseFormatTextParam{ - Type: openai.F(shared.ResponseFormatTextTypeText), - }), - Seed: openai.F(int64(0)), - ServiceTier: openai.F(openai.ChatCompletionNewParamsServiceTierAuto), - Stop: openai.F[openai.ChatCompletionNewParamsStopUnion](shared.UnionString("string")), - Store: openai.F(true), - StreamOptions: openai.F(openai.ChatCompletionStreamOptionsParam{ - IncludeUsage: openai.F(true), - }), - Temperature: openai.F(1.000000), - ToolChoice: openai.F[openai.ChatCompletionToolChoiceOptionUnionParam](openai.ChatCompletionToolChoiceOptionAuto(openai.ChatCompletionToolChoiceOptionAutoNone)), - Tools: openai.F([]openai.ChatCompletionToolParam{{ - Function: openai.F(shared.FunctionDefinitionParam{ - Name: openai.F("name"), - Description: openai.F("description"), - Parameters: openai.F(shared.FunctionParameters{ + }, + Modalities: []openai.ChatCompletionModality{openai.ChatCompletionModalityText}, + N: openai.Int(1), + ParallelToolCalls: openai.Bool(true), + Prediction: openai.ChatCompletionPredictionContentParam{ + Content: []openai.ChatCompletionContentPartTextParam{{Text: openai.String("text")}}, + }, + PresencePenalty: openai.Float(-2), + ReasoningEffort: openai.ChatCompletionReasoningEffortLow, + ResponseFormat: openai.ChatCompletionNewParamsResponseFormatUnion{ + OfResponseFormatText: &shared.ResponseFormatTextParam{}, + }, + Seed: openai.Int(0), + ServiceTier: openai.ChatCompletionNewParamsServiceTierAuto, + Stop: openai.ChatCompletionNewParamsStopUnion{ + OfString: openai.String("string"), + }, + Store: openai.Bool(true), + StreamOptions: openai.ChatCompletionStreamOptionsParam{ + IncludeUsage: openai.Bool(true), + }, + Temperature: openai.Float(1), + ToolChoice: openai.ChatCompletionToolChoiceOptionUnionParam{ + OfAuto: "none", + }, + Tools: []openai.ChatCompletionToolParam{{ + Function: shared.FunctionDefinitionParam{ + Name: openai.String("name"), + Description: openai.String("description"), + Parameters: shared.FunctionParameters{ "foo": "bar", - }), - Strict: openai.F(true), - }), - Type: openai.F(openai.ChatCompletionToolTypeFunction), - }}), - TopLogprobs: openai.F(int64(0)), - TopP: openai.F(1.000000), - User: openai.F("user-1234"), + }, + Strict: openai.Bool(true), + }, + }}, + TopLogprobs: openai.Int(0), + TopP: openai.Float(1), + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error @@ -138,9 +143,9 @@ func TestChatCompletionUpdate(t *testing.T) { context.TODO(), "completion_id", openai.ChatCompletionUpdateParams{ - Metadata: openai.F(shared.MetadataParam{ + Metadata: shared.MetadataParam{ "foo": "string", - }), + }, }, ) if err != nil { @@ -165,13 +170,13 @@ func TestChatCompletionListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Chat.Completions.List(context.TODO(), openai.ChatCompletionListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), - Metadata: openai.F(shared.MetadataParam{ + After: openai.String("after"), + Limit: openai.Int(0), + Metadata: shared.MetadataParam{ "foo": "string", - }), - Model: openai.F("model"), - Order: openai.F(openai.ChatCompletionListParamsOrderAsc), + }, + Model: openai.String("model"), + Order: openai.ChatCompletionListParamsOrderAsc, }) if err != nil { var apierr *openai.Error diff --git a/chatcompletionmessage.go b/chatcompletionmessage.go index 7228ac3..a771917 100644 --- a/chatcompletionmessage.go +++ b/chatcompletionmessage.go @@ -10,10 +10,10 @@ import ( "net/url" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" ) // ChatCompletionMessageService contains methods and other services that help with @@ -29,8 +29,8 @@ type ChatCompletionMessageService struct { // NewChatCompletionMessageService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewChatCompletionMessageService(opts ...option.RequestOption) (r *ChatCompletionMessageService) { - r = &ChatCompletionMessageService{} +func NewChatCompletionMessageService(opts ...option.RequestOption) (r ChatCompletionMessageService) { + r = ChatCompletionMessageService{} r.Options = opts return } @@ -66,14 +66,19 @@ func (r *ChatCompletionMessageService) ListAutoPaging(ctx context.Context, compl type ChatCompletionMessageListParams struct { // Identifier for the last message from the previous pagination request. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // Number of messages to retrieve. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order for messages by timestamp. Use `asc` for ascending order or `desc` // for descending order. Defaults to `asc`. - Order param.Field[ChatCompletionMessageListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order ChatCompletionMessageListParamsOrder `query:"order,omitzero"` + apiobject } +func (f ChatCompletionMessageListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [ChatCompletionMessageListParams]'s query parameters as // `url.Values`. func (r ChatCompletionMessageListParams) URLQuery() (v url.Values) { @@ -91,11 +96,3 @@ const ( ChatCompletionMessageListParamsOrderAsc ChatCompletionMessageListParamsOrder = "asc" ChatCompletionMessageListParamsOrderDesc ChatCompletionMessageListParamsOrder = "desc" ) - -func (r ChatCompletionMessageListParamsOrder) IsKnown() bool { - switch r { - case ChatCompletionMessageListParamsOrderAsc, ChatCompletionMessageListParamsOrderDesc: - return true - } - return false -} diff --git a/chatcompletionmessage_test.go b/chatcompletionmessage_test.go index 23e2129..650f483 100644 --- a/chatcompletionmessage_test.go +++ b/chatcompletionmessage_test.go @@ -29,9 +29,9 @@ func TestChatCompletionMessageListWithOptionalParams(t *testing.T) { context.TODO(), "completion_id", openai.ChatCompletionMessageListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.ChatCompletionMessageListParamsOrderAsc), + After: openai.String("after"), + Limit: openai.Int(0), + Order: openai.ChatCompletionMessageListParamsOrderAsc, }, ) if err != nil { diff --git a/client.go b/client.go index e62273d..5cea235 100644 --- a/client.go +++ b/client.go @@ -16,25 +16,25 @@ import ( // directly, and instead use the [NewClient] method instead. type Client struct { Options []option.RequestOption - Completions *CompletionService - Chat *ChatService - Embeddings *EmbeddingService - Files *FileService - Images *ImageService - Audio *AudioService - Moderations *ModerationService - Models *ModelService - FineTuning *FineTuningService - Beta *BetaService - Batches *BatchService - Uploads *UploadService + Completions CompletionService + Chat ChatService + Embeddings EmbeddingService + Files FileService + Images ImageService + Audio AudioService + Moderations ModerationService + Models ModelService + FineTuning FineTuningService + Beta BetaService + Batches BatchService + Uploads UploadService } // NewClient generates a new client with the default option read from the // environment (OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID). The option // passed in as arguments are applied after these default arguments, and all option // will be passed down to the services and requests that this client makes. -func NewClient(opts ...option.RequestOption) (r *Client) { +func NewClient(opts ...option.RequestOption) (r Client) { defaults := []option.RequestOption{option.WithEnvironmentProduction()} if o, ok := os.LookupEnv("OPENAI_API_KEY"); ok { defaults = append(defaults, option.WithAPIKey(o)) @@ -47,7 +47,7 @@ func NewClient(opts ...option.RequestOption) (r *Client) { } opts = append(defaults, opts...) - r = &Client{Options: opts} + r = Client{Options: opts} r.Completions = NewCompletionService(opts...) r.Chat = NewChatService(opts...) diff --git a/client_test.go b/client_test.go index 773f3ab..fecdb85 100644 --- a/client_test.go +++ b/client_test.go @@ -39,11 +39,14 @@ func TestUserAgentHeader(t *testing.T) { }), ) client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if userAgent != fmt.Sprintf("OpenAI/Go %s", internal.PackageVersion) { t.Errorf("Expected User-Agent to be correct, but got: %#v", userAgent) @@ -68,11 +71,14 @@ func TestRetryAfter(t *testing.T) { }), ) _, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -108,11 +114,14 @@ func TestDeleteRetryCountHeader(t *testing.T) { option.WithHeaderDel("X-Stainless-Retry-Count"), ) _, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -143,11 +152,14 @@ func TestOverwriteRetryCountHeader(t *testing.T) { option.WithHeader("X-Stainless-Retry-Count", "42"), ) _, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -177,11 +189,14 @@ func TestRetryAfterMs(t *testing.T) { }), ) _, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -205,11 +220,14 @@ func TestContextCancel(t *testing.T) { cancelCtx, cancel := context.WithCancel(context.Background()) cancel() _, err := client.Chat.Completions.New(cancelCtx, openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -230,11 +248,14 @@ func TestContextCancelDelay(t *testing.T) { cancelCtx, cancel := context.WithTimeout(context.Background(), 2*time.Millisecond) defer cancel() _, err := client.Chat.Completions.New(cancelCtx, openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("expected there to be a cancel error") @@ -261,11 +282,14 @@ func TestContextDeadline(t *testing.T) { }), ) _, err := client.Chat.Completions.New(deadlineCtx, openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionUserMessageParam{ - Role: openai.F(openai.ChatCompletionUserMessageParamRoleUser), - Content: openai.F([]openai.ChatCompletionContentPartUnionParam{openai.ChatCompletionContentPartTextParam{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfUser: &openai.ChatCompletionUserMessageParam{ + Content: []openai.ChatCompletionContentPartUnionParam{{ + OfText: &openai.ChatCompletionContentPartTextParam{Text: openai.String("text")}, + }}, + }, + }}, + Model: openai.ChatModelO3Mini, }) if err == nil { t.Error("expected there to be a deadline error") @@ -311,11 +335,12 @@ func TestContextDeadlineStreaming(t *testing.T) { }), ) stream := client.Chat.Completions.NewStreaming(deadlineCtx, openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionDeveloperMessageParam{ - Content: openai.F([]openai.ChatCompletionContentPartTextParam{{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - Role: openai.F(openai.ChatCompletionDeveloperMessageParamRoleDeveloper), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfDeveloper: &openai.ChatCompletionDeveloperMessageParam{ + Content: []openai.ChatCompletionContentPartTextParam{{Text: openai.String("text")}}, + }, + }}, + Model: openai.ChatModelO3Mini, }) for stream.Next() { _ = stream.Current() @@ -363,11 +388,12 @@ func TestContextDeadlineStreamingWithRequestTimeout(t *testing.T) { stream := client.Chat.Completions.NewStreaming( context.Background(), openai.ChatCompletionNewParams{ - Messages: openai.F([]openai.ChatCompletionMessageParamUnion{openai.ChatCompletionDeveloperMessageParam{ - Content: openai.F([]openai.ChatCompletionContentPartTextParam{{Text: openai.F("text"), Type: openai.F(openai.ChatCompletionContentPartTextTypeText)}}), - Role: openai.F(openai.ChatCompletionDeveloperMessageParamRoleDeveloper), - }}), - Model: openai.F(openai.ChatModelO3Mini), + Messages: []openai.ChatCompletionMessageParamUnion{{ + OfDeveloper: &openai.ChatCompletionDeveloperMessageParam{ + Content: []openai.ChatCompletionContentPartTextParam{{Text: openai.String("text")}}, + }, + }}, + Model: openai.ChatModelO3Mini, }, option.WithRequestTimeout((100 * time.Millisecond)), ) diff --git a/completion.go b/completion.go index d28edd4..c6937e8 100644 --- a/completion.go +++ b/completion.go @@ -7,10 +7,12 @@ import ( "net/http" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" "github.com/openai/openai-go/packages/ssestream" + "github.com/openai/openai-go/shared/constant" ) // CompletionService contains methods and other services that help with interacting @@ -26,8 +28,8 @@ type CompletionService struct { // NewCompletionService generates a new service that applies the given options to // each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewCompletionService(opts ...option.RequestOption) (r *CompletionService) { - r = &CompletionService{} +func NewCompletionService(opts ...option.RequestOption) (r CompletionService) { + r = CompletionService{} r.Options = opts return } @@ -57,97 +59,71 @@ func (r *CompletionService) NewStreaming(ctx context.Context, body CompletionNew // non-streamed response objects share the same shape (unlike the chat endpoint). type Completion struct { // A unique identifier for the completion. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The list of completion choices the model generated for the input prompt. - Choices []CompletionChoice `json:"choices,required"` + Choices []CompletionChoice `json:"choices,omitzero,required"` // The Unix timestamp (in seconds) of when the completion was created. - Created int64 `json:"created,required"` + Created int64 `json:"created,omitzero,required"` // The model used for completion. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always "text_completion" - Object CompletionObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "text_completion". + Object constant.TextCompletion `json:"object,required"` // This fingerprint represents the backend configuration that the model runs with. // // Can be used in conjunction with the `seed` request parameter to understand when // backend changes have been made that might impact determinism. - SystemFingerprint string `json:"system_fingerprint"` + SystemFingerprint string `json:"system_fingerprint,omitzero"` // Usage statistics for the completion request. - Usage CompletionUsage `json:"usage"` - JSON completionJSON `json:"-"` + Usage CompletionUsage `json:"usage,omitzero"` + JSON struct { + ID resp.Field + Choices resp.Field + Created resp.Field + Model resp.Field + Object resp.Field + SystemFingerprint resp.Field + Usage resp.Field + raw string + } `json:"-"` } -// completionJSON contains the JSON metadata for the struct [Completion] -type completionJSON struct { - ID apijson.Field - Choices apijson.Field - Created apijson.Field - Model apijson.Field - Object apijson.Field - SystemFingerprint apijson.Field - Usage apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Completion) UnmarshalJSON(data []byte) (err error) { +func (r Completion) RawJSON() string { return r.JSON.raw } +func (r *Completion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always "text_completion" -type CompletionObject string - -const ( - CompletionObjectTextCompletion CompletionObject = "text_completion" -) - -func (r CompletionObject) IsKnown() bool { - switch r { - case CompletionObjectTextCompletion: - return true - } - return false -} - type CompletionChoice struct { // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum // number of tokens specified in the request was reached, or `content_filter` if // content was omitted due to a flag from our content filters. - FinishReason CompletionChoiceFinishReason `json:"finish_reason,required"` - Index int64 `json:"index,required"` - Logprobs CompletionChoiceLogprobs `json:"logprobs,required,nullable"` - Text string `json:"text,required"` - JSON completionChoiceJSON `json:"-"` + // + // Any of "stop", "length", "content_filter" + FinishReason string `json:"finish_reason,omitzero,required"` + Index int64 `json:"index,omitzero,required"` + Logprobs CompletionChoiceLogprobs `json:"logprobs,omitzero,required,nullable"` + Text string `json:"text,omitzero,required"` + JSON struct { + FinishReason resp.Field + Index resp.Field + Logprobs resp.Field + Text resp.Field + raw string + } `json:"-"` } -// completionChoiceJSON contains the JSON metadata for the struct -// [CompletionChoice] -type completionChoiceJSON struct { - FinishReason apijson.Field - Index apijson.Field - Logprobs apijson.Field - Text apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CompletionChoice) UnmarshalJSON(data []byte) (err error) { +func (r CompletionChoice) RawJSON() string { return r.JSON.raw } +func (r *CompletionChoice) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionChoiceJSON) RawJSON() string { - return r.raw -} - // The reason the model stopped generating tokens. This will be `stop` if the model // hit a natural stop point or a provided stop sequence, `length` if the maximum // number of tokens specified in the request was reached, or `content_filter` if // content was omitted due to a flag from our content filters. -type CompletionChoiceFinishReason string +type CompletionChoiceFinishReason = string const ( CompletionChoiceFinishReasonStop CompletionChoiceFinishReason = "stop" @@ -155,151 +131,112 @@ const ( CompletionChoiceFinishReasonContentFilter CompletionChoiceFinishReason = "content_filter" ) -func (r CompletionChoiceFinishReason) IsKnown() bool { - switch r { - case CompletionChoiceFinishReasonStop, CompletionChoiceFinishReasonLength, CompletionChoiceFinishReasonContentFilter: - return true - } - return false -} - type CompletionChoiceLogprobs struct { - TextOffset []int64 `json:"text_offset"` - TokenLogprobs []float64 `json:"token_logprobs"` - Tokens []string `json:"tokens"` - TopLogprobs []map[string]float64 `json:"top_logprobs"` - JSON completionChoiceLogprobsJSON `json:"-"` + TextOffset []int64 `json:"text_offset,omitzero"` + TokenLogprobs []float64 `json:"token_logprobs,omitzero"` + Tokens []string `json:"tokens,omitzero"` + TopLogprobs []map[string]float64 `json:"top_logprobs,omitzero"` + JSON struct { + TextOffset resp.Field + TokenLogprobs resp.Field + Tokens resp.Field + TopLogprobs resp.Field + raw string + } `json:"-"` } -// completionChoiceLogprobsJSON contains the JSON metadata for the struct -// [CompletionChoiceLogprobs] -type completionChoiceLogprobsJSON struct { - TextOffset apijson.Field - TokenLogprobs apijson.Field - Tokens apijson.Field - TopLogprobs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CompletionChoiceLogprobs) UnmarshalJSON(data []byte) (err error) { +func (r CompletionChoiceLogprobs) RawJSON() string { return r.JSON.raw } +func (r *CompletionChoiceLogprobs) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionChoiceLogprobsJSON) RawJSON() string { - return r.raw -} - // Usage statistics for the completion request. type CompletionUsage struct { // Number of tokens in the generated completion. - CompletionTokens int64 `json:"completion_tokens,required"` + CompletionTokens int64 `json:"completion_tokens,omitzero,required"` // Number of tokens in the prompt. - PromptTokens int64 `json:"prompt_tokens,required"` + PromptTokens int64 `json:"prompt_tokens,omitzero,required"` // Total number of tokens used in the request (prompt + completion). - TotalTokens int64 `json:"total_tokens,required"` + TotalTokens int64 `json:"total_tokens,omitzero,required"` // Breakdown of tokens used in a completion. - CompletionTokensDetails CompletionUsageCompletionTokensDetails `json:"completion_tokens_details"` + CompletionTokensDetails CompletionUsageCompletionTokensDetails `json:"completion_tokens_details,omitzero"` // Breakdown of tokens used in the prompt. - PromptTokensDetails CompletionUsagePromptTokensDetails `json:"prompt_tokens_details"` - JSON completionUsageJSON `json:"-"` + PromptTokensDetails CompletionUsagePromptTokensDetails `json:"prompt_tokens_details,omitzero"` + JSON struct { + CompletionTokens resp.Field + PromptTokens resp.Field + TotalTokens resp.Field + CompletionTokensDetails resp.Field + PromptTokensDetails resp.Field + raw string + } `json:"-"` } -// completionUsageJSON contains the JSON metadata for the struct [CompletionUsage] -type completionUsageJSON struct { - CompletionTokens apijson.Field - PromptTokens apijson.Field - TotalTokens apijson.Field - CompletionTokensDetails apijson.Field - PromptTokensDetails apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CompletionUsage) UnmarshalJSON(data []byte) (err error) { +func (r CompletionUsage) RawJSON() string { return r.JSON.raw } +func (r *CompletionUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionUsageJSON) RawJSON() string { - return r.raw -} - // Breakdown of tokens used in a completion. type CompletionUsageCompletionTokensDetails struct { // When using Predicted Outputs, the number of tokens in the prediction that // appeared in the completion. - AcceptedPredictionTokens int64 `json:"accepted_prediction_tokens"` + AcceptedPredictionTokens int64 `json:"accepted_prediction_tokens,omitzero"` // Audio input tokens generated by the model. - AudioTokens int64 `json:"audio_tokens"` + AudioTokens int64 `json:"audio_tokens,omitzero"` // Tokens generated by the model for reasoning. - ReasoningTokens int64 `json:"reasoning_tokens"` + ReasoningTokens int64 `json:"reasoning_tokens,omitzero"` // When using Predicted Outputs, the number of tokens in the prediction that did // not appear in the completion. However, like reasoning tokens, these tokens are // still counted in the total completion tokens for purposes of billing, output, // and context window limits. - RejectedPredictionTokens int64 `json:"rejected_prediction_tokens"` - JSON completionUsageCompletionTokensDetailsJSON `json:"-"` + RejectedPredictionTokens int64 `json:"rejected_prediction_tokens,omitzero"` + JSON struct { + AcceptedPredictionTokens resp.Field + AudioTokens resp.Field + ReasoningTokens resp.Field + RejectedPredictionTokens resp.Field + raw string + } `json:"-"` } -// completionUsageCompletionTokensDetailsJSON contains the JSON metadata for the -// struct [CompletionUsageCompletionTokensDetails] -type completionUsageCompletionTokensDetailsJSON struct { - AcceptedPredictionTokens apijson.Field - AudioTokens apijson.Field - ReasoningTokens apijson.Field - RejectedPredictionTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CompletionUsageCompletionTokensDetails) UnmarshalJSON(data []byte) (err error) { +func (r CompletionUsageCompletionTokensDetails) RawJSON() string { return r.JSON.raw } +func (r *CompletionUsageCompletionTokensDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionUsageCompletionTokensDetailsJSON) RawJSON() string { - return r.raw -} - // Breakdown of tokens used in the prompt. type CompletionUsagePromptTokensDetails struct { // Audio input tokens present in the prompt. - AudioTokens int64 `json:"audio_tokens"` + AudioTokens int64 `json:"audio_tokens,omitzero"` // Cached tokens present in the prompt. - CachedTokens int64 `json:"cached_tokens"` - JSON completionUsagePromptTokensDetailsJSON `json:"-"` + CachedTokens int64 `json:"cached_tokens,omitzero"` + JSON struct { + AudioTokens resp.Field + CachedTokens resp.Field + raw string + } `json:"-"` } -// completionUsagePromptTokensDetailsJSON contains the JSON metadata for the struct -// [CompletionUsagePromptTokensDetails] -type completionUsagePromptTokensDetailsJSON struct { - AudioTokens apijson.Field - CachedTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CompletionUsagePromptTokensDetails) UnmarshalJSON(data []byte) (err error) { +func (r CompletionUsagePromptTokensDetails) RawJSON() string { return r.JSON.raw } +func (r *CompletionUsagePromptTokensDetails) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r completionUsagePromptTokensDetailsJSON) RawJSON() string { - return r.raw -} - type CompletionNewParams struct { // ID of the model to use. You can use the // [List models](https://platform.openai.com/docs/api-reference/models/list) API to // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. - Model param.Field[CompletionNewParamsModel] `json:"model,required"` + Model string `json:"model,omitzero,required"` // The prompt(s) to generate completions for, encoded as a string, array of // strings, array of tokens, or array of token arrays. // // Note that <|endoftext|> is the document separator that the model sees during // training, so if a prompt is not specified the model will generate as if from the // beginning of a new document. - Prompt param.Field[CompletionNewParamsPromptUnion] `json:"prompt,required"` + Prompt CompletionNewParamsPromptUnion `json:"prompt,omitzero,required"` // Generates `best_of` completions server-side and returns the "best" (the one with // the highest log probability per token). Results cannot be streamed. // @@ -309,15 +246,15 @@ type CompletionNewParams struct { // **Note:** Because this parameter generates many completions, it can quickly // consume your token quota. Use carefully and ensure that you have reasonable // settings for `max_tokens` and `stop`. - BestOf param.Field[int64] `json:"best_of"` + BestOf param.Int `json:"best_of,omitzero"` // Echo back the prompt in addition to the completion - Echo param.Field[bool] `json:"echo"` + Echo param.Bool `json:"echo,omitzero"` // Number between -2.0 and 2.0. Positive values penalize new tokens based on their // existing frequency in the text so far, decreasing the model's likelihood to // repeat the same line verbatim. // // [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/text-generation) - FrequencyPenalty param.Field[float64] `json:"frequency_penalty"` + FrequencyPenalty param.Float `json:"frequency_penalty,omitzero"` // Modify the likelihood of specified tokens appearing in the completion. // // Accepts a JSON object that maps tokens (specified by their token ID in the GPT @@ -330,14 +267,14 @@ type CompletionNewParams struct { // // As an example, you can pass `{"50256": -100}` to prevent the <|endoftext|> token // from being generated. - LogitBias param.Field[map[string]int64] `json:"logit_bias"` + LogitBias map[string]int64 `json:"logit_bias,omitzero"` // Include the log probabilities on the `logprobs` most likely output tokens, as // well the chosen tokens. For example, if `logprobs` is 5, the API will return a // list of the 5 most likely tokens. The API will always return the `logprob` of // the sampled token, so there may be up to `logprobs+1` elements in the response. // // The maximum value for `logprobs` is 5. - Logprobs param.Field[int64] `json:"logprobs"` + Logprobs param.Int `json:"logprobs,omitzero"` // The maximum number of [tokens](/tokenizer) that can be generated in the // completion. // @@ -345,55 +282,59 @@ type CompletionNewParams struct { // context length. // [Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken) // for counting tokens. - MaxTokens param.Field[int64] `json:"max_tokens"` + MaxTokens param.Int `json:"max_tokens,omitzero"` // How many completions to generate for each prompt. // // **Note:** Because this parameter generates many completions, it can quickly // consume your token quota. Use carefully and ensure that you have reasonable // settings for `max_tokens` and `stop`. - N param.Field[int64] `json:"n"` + N param.Int `json:"n,omitzero"` // Number between -2.0 and 2.0. Positive values penalize new tokens based on // whether they appear in the text so far, increasing the model's likelihood to // talk about new topics. // // [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/text-generation) - PresencePenalty param.Field[float64] `json:"presence_penalty"` + PresencePenalty param.Float `json:"presence_penalty,omitzero"` // If specified, our system will make a best effort to sample deterministically, // such that repeated requests with the same `seed` and parameters should return // the same result. // // Determinism is not guaranteed, and you should refer to the `system_fingerprint` // response parameter to monitor changes in the backend. - Seed param.Field[int64] `json:"seed"` + Seed param.Int `json:"seed,omitzero"` // Up to 4 sequences where the API will stop generating further tokens. The // returned text will not contain the stop sequence. - Stop param.Field[CompletionNewParamsStopUnion] `json:"stop"` + Stop CompletionNewParamsStopUnion `json:"stop,omitzero"` // Options for streaming response. Only set this when you set `stream: true`. - StreamOptions param.Field[ChatCompletionStreamOptionsParam] `json:"stream_options"` + StreamOptions ChatCompletionStreamOptionsParam `json:"stream_options,omitzero"` // The suffix that comes after a completion of inserted text. // // This parameter is only supported for `gpt-3.5-turbo-instruct`. - Suffix param.Field[string] `json:"suffix"` + Suffix param.String `json:"suffix,omitzero"` // What sampling temperature to use, between 0 and 2. Higher values like 0.8 will // make the output more random, while lower values like 0.2 will make it more // focused and deterministic. // // We generally recommend altering this or `top_p` but not both. - Temperature param.Field[float64] `json:"temperature"` + Temperature param.Float `json:"temperature,omitzero"` // An alternative to sampling with temperature, called nucleus sampling, where the // model considers the results of the tokens with top_p probability mass. So 0.1 // means only the tokens comprising the top 10% probability mass are considered. // // We generally recommend altering this or `temperature` but not both. - TopP param.Field[float64] `json:"top_p"` + TopP param.Float `json:"top_p,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f CompletionNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r CompletionNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow CompletionNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // ID of the model to use. You can use the @@ -401,7 +342,7 @@ func (r CompletionNewParams) MarshalJSON() (data []byte, err error) { // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. -type CompletionNewParamsModel string +type CompletionNewParamsModel = string const ( CompletionNewParamsModelGPT3_5TurboInstruct CompletionNewParamsModel = "gpt-3.5-turbo-instruct" @@ -409,48 +350,30 @@ const ( CompletionNewParamsModelBabbage002 CompletionNewParamsModel = "babbage-002" ) -func (r CompletionNewParamsModel) IsKnown() bool { - switch r { - case CompletionNewParamsModelGPT3_5TurboInstruct, CompletionNewParamsModelDavinci002, CompletionNewParamsModelBabbage002: - return true - } - return false +// Only one field can be non-zero +type CompletionNewParamsPromptUnion struct { + OfString param.String + OfArrayOfStrings []string + OfArrayOfTokens []int64 + OfArrayOfTokenArrays [][]int64 + apiunion } -// The prompt(s) to generate completions for, encoded as a string, array of -// strings, array of tokens, or array of token arrays. -// -// Note that <|endoftext|> is the document separator that the model sees during -// training, so if a prompt is not specified the model will generate as if from the -// beginning of a new document. -// -// Satisfied by [shared.UnionString], [CompletionNewParamsPromptArrayOfStrings], -// [CompletionNewParamsPromptArrayOfTokens], -// [CompletionNewParamsPromptArrayOfTokenArrays]. -type CompletionNewParamsPromptUnion interface { - ImplementsCompletionNewParamsPromptUnion() +func (u CompletionNewParamsPromptUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } + +func (u CompletionNewParamsPromptUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[CompletionNewParamsPromptUnion](u.OfString, u.OfArrayOfStrings, u.OfArrayOfTokens, u.OfArrayOfTokenArrays) } -type CompletionNewParamsPromptArrayOfStrings []string - -func (r CompletionNewParamsPromptArrayOfStrings) ImplementsCompletionNewParamsPromptUnion() {} - -type CompletionNewParamsPromptArrayOfTokens []int64 - -func (r CompletionNewParamsPromptArrayOfTokens) ImplementsCompletionNewParamsPromptUnion() {} - -type CompletionNewParamsPromptArrayOfTokenArrays [][]int64 - -func (r CompletionNewParamsPromptArrayOfTokenArrays) ImplementsCompletionNewParamsPromptUnion() {} - -// Up to 4 sequences where the API will stop generating further tokens. The -// returned text will not contain the stop sequence. -// -// Satisfied by [shared.UnionString], [CompletionNewParamsStopArray]. -type CompletionNewParamsStopUnion interface { - ImplementsCompletionNewParamsStopUnion() +// Only one field can be non-zero +type CompletionNewParamsStopUnion struct { + OfString param.String + OfCompletionNewsStopArray []string + apiunion } -type CompletionNewParamsStopArray []string +func (u CompletionNewParamsStopUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } -func (r CompletionNewParamsStopArray) ImplementsCompletionNewParamsStopUnion() {} +func (u CompletionNewParamsStopUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[CompletionNewParamsStopUnion](u.OfString, u.OfCompletionNewsStopArray) +} diff --git a/completion_test.go b/completion_test.go index b8f9124..58fc4f8 100644 --- a/completion_test.go +++ b/completion_test.go @@ -11,7 +11,6 @@ import ( "github.com/openai/openai-go" "github.com/openai/openai-go/internal/testutil" "github.com/openai/openai-go/option" - "github.com/openai/openai-go/shared" ) func TestCompletionNewWithOptionalParams(t *testing.T) { @@ -27,27 +26,31 @@ func TestCompletionNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Completions.New(context.TODO(), openai.CompletionNewParams{ - Model: openai.F(openai.CompletionNewParamsModelGPT3_5TurboInstruct), - Prompt: openai.F[openai.CompletionNewParamsPromptUnion](shared.UnionString("This is a test.")), - BestOf: openai.F(int64(0)), - Echo: openai.F(true), - FrequencyPenalty: openai.F(-2.000000), - LogitBias: openai.F(map[string]int64{ - "foo": int64(0), - }), - Logprobs: openai.F(int64(0)), - MaxTokens: openai.F(int64(16)), - N: openai.F(int64(1)), - PresencePenalty: openai.F(-2.000000), - Seed: openai.F(int64(0)), - Stop: openai.F[openai.CompletionNewParamsStopUnion](shared.UnionString("\n")), - StreamOptions: openai.F(openai.ChatCompletionStreamOptionsParam{ - IncludeUsage: openai.F(true), - }), - Suffix: openai.F("test."), - Temperature: openai.F(1.000000), - TopP: openai.F(1.000000), - User: openai.F("user-1234"), + Model: "gpt-3.5-turbo-instruct", + Prompt: openai.CompletionNewParamsPromptUnion{ + OfString: openai.String("This is a test."), + }, + BestOf: openai.Int(0), + Echo: openai.Bool(true), + FrequencyPenalty: openai.Float(-2), + LogitBias: map[string]int64{ + "foo": 0, + }, + Logprobs: openai.Int(0), + MaxTokens: openai.Int(16), + N: openai.Int(1), + PresencePenalty: openai.Float(-2), + Seed: openai.Int(0), + Stop: openai.CompletionNewParamsStopUnion{ + OfString: openai.String("\n"), + }, + StreamOptions: openai.ChatCompletionStreamOptionsParam{ + IncludeUsage: openai.Bool(true), + }, + Suffix: openai.String("test."), + Temperature: openai.Float(1), + TopP: openai.Float(1), + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error diff --git a/embedding.go b/embedding.go index 489fdea..474a6dd 100644 --- a/embedding.go +++ b/embedding.go @@ -7,9 +7,11 @@ import ( "net/http" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // EmbeddingService contains methods and other services that help with interacting @@ -25,8 +27,8 @@ type EmbeddingService struct { // NewEmbeddingService generates a new service that applies the given options to // each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewEmbeddingService(opts ...option.RequestOption) (r *EmbeddingService) { - r = &EmbeddingService{} +func NewEmbeddingService(opts ...option.RequestOption) (r EmbeddingService) { + r = EmbeddingService{} r.Options = opts return } @@ -41,121 +43,72 @@ func (r *EmbeddingService) New(ctx context.Context, body EmbeddingNewParams, opt type CreateEmbeddingResponse struct { // The list of embeddings generated by the model. - Data []Embedding `json:"data,required"` + Data []Embedding `json:"data,omitzero,required"` // The name of the model used to generate the embedding. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always "list". - Object CreateEmbeddingResponseObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "list". + Object constant.List `json:"object,required"` // The usage information for the request. - Usage CreateEmbeddingResponseUsage `json:"usage,required"` - JSON createEmbeddingResponseJSON `json:"-"` + Usage CreateEmbeddingResponseUsage `json:"usage,omitzero,required"` + JSON struct { + Data resp.Field + Model resp.Field + Object resp.Field + Usage resp.Field + raw string + } `json:"-"` } -// createEmbeddingResponseJSON contains the JSON metadata for the struct -// [CreateEmbeddingResponse] -type createEmbeddingResponseJSON struct { - Data apijson.Field - Model apijson.Field - Object apijson.Field - Usage apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CreateEmbeddingResponse) UnmarshalJSON(data []byte) (err error) { +func (r CreateEmbeddingResponse) RawJSON() string { return r.JSON.raw } +func (r *CreateEmbeddingResponse) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r createEmbeddingResponseJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always "list". -type CreateEmbeddingResponseObject string - -const ( - CreateEmbeddingResponseObjectList CreateEmbeddingResponseObject = "list" -) - -func (r CreateEmbeddingResponseObject) IsKnown() bool { - switch r { - case CreateEmbeddingResponseObjectList: - return true - } - return false -} - // The usage information for the request. type CreateEmbeddingResponseUsage struct { // The number of tokens used by the prompt. - PromptTokens int64 `json:"prompt_tokens,required"` + PromptTokens int64 `json:"prompt_tokens,omitzero,required"` // The total number of tokens used by the request. - TotalTokens int64 `json:"total_tokens,required"` - JSON createEmbeddingResponseUsageJSON `json:"-"` + TotalTokens int64 `json:"total_tokens,omitzero,required"` + JSON struct { + PromptTokens resp.Field + TotalTokens resp.Field + raw string + } `json:"-"` } -// createEmbeddingResponseUsageJSON contains the JSON metadata for the struct -// [CreateEmbeddingResponseUsage] -type createEmbeddingResponseUsageJSON struct { - PromptTokens apijson.Field - TotalTokens apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *CreateEmbeddingResponseUsage) UnmarshalJSON(data []byte) (err error) { +func (r CreateEmbeddingResponseUsage) RawJSON() string { return r.JSON.raw } +func (r *CreateEmbeddingResponseUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r createEmbeddingResponseUsageJSON) RawJSON() string { - return r.raw -} - // Represents an embedding vector returned by embedding endpoint. type Embedding struct { // The embedding vector, which is a list of floats. The length of vector depends on // the model as listed in the // [embedding guide](https://platform.openai.com/docs/guides/embeddings). - Embedding []float64 `json:"embedding,required"` + Embedding []float64 `json:"embedding,omitzero,required"` // The index of the embedding in the list of embeddings. - Index int64 `json:"index,required"` + Index int64 `json:"index,omitzero,required"` // The object type, which is always "embedding". - Object EmbeddingObject `json:"object,required"` - JSON embeddingJSON `json:"-"` + // + // This field can be elided, and will be automatically set as "embedding". + Object constant.Embedding `json:"object,required"` + JSON struct { + Embedding resp.Field + Index resp.Field + Object resp.Field + raw string + } `json:"-"` } -// embeddingJSON contains the JSON metadata for the struct [Embedding] -type embeddingJSON struct { - Embedding apijson.Field - Index apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Embedding) UnmarshalJSON(data []byte) (err error) { +func (r Embedding) RawJSON() string { return r.JSON.raw } +func (r *Embedding) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r embeddingJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always "embedding". -type EmbeddingObject string - -const ( - EmbeddingObjectEmbedding EmbeddingObject = "embedding" -) - -func (r EmbeddingObject) IsKnown() bool { - switch r { - case EmbeddingObjectEmbedding: - return true - } - return false -} - type EmbeddingModel = string const ( @@ -173,56 +126,49 @@ type EmbeddingNewParams struct { // [Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken) // for counting tokens. Some models may also impose a limit on total number of // tokens summed across inputs. - Input param.Field[EmbeddingNewParamsInputUnion] `json:"input,required"` + Input EmbeddingNewParamsInputUnion `json:"input,omitzero,required"` // ID of the model to use. You can use the // [List models](https://platform.openai.com/docs/api-reference/models/list) API to // see all of your available models, or see our // [Model overview](https://platform.openai.com/docs/models) for descriptions of // them. - Model param.Field[EmbeddingModel] `json:"model,required"` + Model EmbeddingModel `json:"model,omitzero,required"` // The number of dimensions the resulting output embeddings should have. Only // supported in `text-embedding-3` and later models. - Dimensions param.Field[int64] `json:"dimensions"` + Dimensions param.Int `json:"dimensions,omitzero"` // The format to return the embeddings in. Can be either `float` or // [`base64`](https://pypi.org/project/pybase64/). - EncodingFormat param.Field[EmbeddingNewParamsEncodingFormat] `json:"encoding_format"` + // + // Any of "float", "base64" + EncodingFormat EmbeddingNewParamsEncodingFormat `json:"encoding_format,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f EmbeddingNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r EmbeddingNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow EmbeddingNewParams + return param.MarshalObject(r, (*shadow)(&r)) } -// Input text to embed, encoded as a string or array of tokens. To embed multiple -// inputs in a single request, pass an array of strings or array of token arrays. -// The input must not exceed the max input tokens for the model (8192 tokens for -// `text-embedding-ada-002`), cannot be an empty string, and any array must be 2048 -// dimensions or less. -// [Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken) -// for counting tokens. Some models may also impose a limit on total number of -// tokens summed across inputs. -// -// Satisfied by [shared.UnionString], [EmbeddingNewParamsInputArrayOfStrings], -// [EmbeddingNewParamsInputArrayOfTokens], -// [EmbeddingNewParamsInputArrayOfTokenArrays]. -type EmbeddingNewParamsInputUnion interface { - ImplementsEmbeddingNewParamsInputUnion() +// Only one field can be non-zero +type EmbeddingNewParamsInputUnion struct { + OfString param.String + OfArrayOfStrings []string + OfArrayOfTokens []int64 + OfArrayOfTokenArrays [][]int64 + apiunion } -type EmbeddingNewParamsInputArrayOfStrings []string +func (u EmbeddingNewParamsInputUnion) IsMissing() bool { return param.IsOmitted(u) || u.IsNull() } -func (r EmbeddingNewParamsInputArrayOfStrings) ImplementsEmbeddingNewParamsInputUnion() {} - -type EmbeddingNewParamsInputArrayOfTokens []int64 - -func (r EmbeddingNewParamsInputArrayOfTokens) ImplementsEmbeddingNewParamsInputUnion() {} - -type EmbeddingNewParamsInputArrayOfTokenArrays [][]int64 - -func (r EmbeddingNewParamsInputArrayOfTokenArrays) ImplementsEmbeddingNewParamsInputUnion() {} +func (u EmbeddingNewParamsInputUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[EmbeddingNewParamsInputUnion](u.OfString, u.OfArrayOfStrings, u.OfArrayOfTokens, u.OfArrayOfTokenArrays) +} // The format to return the embeddings in. Can be either `float` or // [`base64`](https://pypi.org/project/pybase64/). @@ -232,11 +178,3 @@ const ( EmbeddingNewParamsEncodingFormatFloat EmbeddingNewParamsEncodingFormat = "float" EmbeddingNewParamsEncodingFormatBase64 EmbeddingNewParamsEncodingFormat = "base64" ) - -func (r EmbeddingNewParamsEncodingFormat) IsKnown() bool { - switch r { - case EmbeddingNewParamsEncodingFormatFloat, EmbeddingNewParamsEncodingFormatBase64: - return true - } - return false -} diff --git a/embedding_test.go b/embedding_test.go index 0eee8ec..0ca6b78 100644 --- a/embedding_test.go +++ b/embedding_test.go @@ -11,7 +11,6 @@ import ( "github.com/openai/openai-go" "github.com/openai/openai-go/internal/testutil" "github.com/openai/openai-go/option" - "github.com/openai/openai-go/shared" ) func TestEmbeddingNewWithOptionalParams(t *testing.T) { @@ -27,11 +26,13 @@ func TestEmbeddingNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Embeddings.New(context.TODO(), openai.EmbeddingNewParams{ - Input: openai.F[openai.EmbeddingNewParamsInputUnion](shared.UnionString("The quick brown fox jumped over the lazy dog")), - Model: openai.F(openai.EmbeddingModelTextEmbeddingAda002), - Dimensions: openai.F(int64(1)), - EncodingFormat: openai.F(openai.EmbeddingNewParamsEncodingFormatFloat), - User: openai.F("user-1234"), + Input: openai.EmbeddingNewParamsInputUnion{ + OfString: openai.String("The quick brown fox jumped over the lazy dog"), + }, + Model: openai.EmbeddingModelTextEmbeddingAda002, + Dimensions: openai.Int(1), + EncodingFormat: openai.EmbeddingNewParamsEncodingFormatFloat, + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error diff --git a/field.go b/field.go index 27fd57f..d1586f2 100644 --- a/field.go +++ b/field.go @@ -1,43 +1,51 @@ package openai import ( - "github.com/openai/openai-go/internal/param" + "github.com/openai/openai-go/packages/param" "io" + "time" ) -// F is a param field helper used to initialize a [param.Field] generic struct. -// This helps specify null, zero values, and overrides, as well as normal values. -// You can read more about this in our [README]. -// -// [README]: https://pkg.go.dev/github.com/openai/openai-go#readme-request-fields -func F[T any](value T) param.Field[T] { return param.Field[T]{Value: value, Present: true} } +func String(s string) param.String { + fld := param.NeverOmitted[param.String]() + fld.V = s + return fld +} -// Null is a param field helper which explicitly sends null to the API. -func Null[T any]() param.Field[T] { return param.Field[T]{Null: true, Present: true} } +func Int(i int64) param.Int { + fld := param.NeverOmitted[param.Int]() + fld.V = i + return fld +} -// Raw is a param field helper for specifying values for fields when the -// type you are looking to send is different from the type that is specified in -// the SDK. For example, if the type of the field is an integer, but you want -// to send a float, you could do that by setting the corresponding field with -// Raw[int](0.5). -func Raw[T any](value any) param.Field[T] { return param.Field[T]{Raw: value, Present: true} } +func Bool(b bool) param.Bool { + fld := param.NeverOmitted[param.Bool]() + fld.V = b + return fld +} -// Int is a param field helper which helps specify integers. This is -// particularly helpful when specifying integer constants for fields. -func Int(value int64) param.Field[int64] { return F(value) } +func Float(f float64) param.Float { + fld := param.NeverOmitted[param.Float]() + fld.V = f + return fld +} -// String is a param field helper which helps specify strings. -func String(value string) param.Field[string] { return F(value) } +func Datetime(t time.Time) param.Datetime { + fld := param.NeverOmitted[param.Datetime]() + fld.V = t + return fld +} -// Float is a param field helper which helps specify floats. -func Float(value float64) param.Field[float64] { return F(value) } +func Date(t time.Time) param.Date { + fld := param.NeverOmitted[param.Date]() + fld.V = t + return fld +} -// Bool is a param field helper which helps specify bools. -func Bool(value bool) param.Field[bool] { return F(value) } +func Ptr[T any](v T) *T { return &v } -// FileParam is a param field helper which helps files with a mime content-type. -func FileParam(reader io.Reader, filename string, contentType string) param.Field[io.Reader] { - return F[io.Reader](&file{reader, filename, contentType}) +func File(rdr io.Reader, filename string, contentType string) file { + return file{rdr, filename, contentType} } type file struct { @@ -46,5 +54,15 @@ type file struct { contentType string } -func (f *file) ContentType() string { return f.contentType } -func (f *file) Filename() string { return f.name } +func (f file) Filename() string { + if f.name != "" { + return f.name + } else if named, ok := f.Reader.(interface{ Name() string }); ok { + return named.Name() + } + return "" +} + +func (f file) ContentType() string { + return f.contentType +} diff --git a/file.go b/file.go index b03ade4..4a5c7c7 100644 --- a/file.go +++ b/file.go @@ -15,10 +15,12 @@ import ( "github.com/openai/openai-go/internal/apiform" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // FileService contains methods and other services that help with interacting with @@ -34,8 +36,8 @@ type FileService struct { // NewFileService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewFileService(opts ...option.RequestOption) (r *FileService) { - r = &FileService{} +func NewFileService(opts ...option.RequestOption) (r FileService) { + r = FileService{} r.Options = opts return } @@ -129,113 +131,78 @@ func (r *FileService) Content(ctx context.Context, fileID string, opts ...option } type FileDeleted struct { - ID string `json:"id,required"` - Deleted bool `json:"deleted,required"` - Object FileDeletedObject `json:"object,required"` - JSON fileDeletedJSON `json:"-"` + ID string `json:"id,omitzero,required"` + Deleted bool `json:"deleted,omitzero,required"` + // This field can be elided, and will be automatically set as "file". + Object constant.File `json:"object,required"` + JSON struct { + ID resp.Field + Deleted resp.Field + Object resp.Field + raw string + } `json:"-"` } -// fileDeletedJSON contains the JSON metadata for the struct [FileDeleted] -type fileDeletedJSON struct { - ID apijson.Field - Deleted apijson.Field - Object apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileDeleted) UnmarshalJSON(data []byte) (err error) { +func (r FileDeleted) RawJSON() string { return r.JSON.raw } +func (r *FileDeleted) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileDeletedJSON) RawJSON() string { - return r.raw -} - -type FileDeletedObject string - -const ( - FileDeletedObjectFile FileDeletedObject = "file" -) - -func (r FileDeletedObject) IsKnown() bool { - switch r { - case FileDeletedObjectFile: - return true - } - return false -} - // The `File` object represents a document that has been uploaded to OpenAI. type FileObject struct { // The file identifier, which can be referenced in the API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The size of the file, in bytes. - Bytes int64 `json:"bytes,required"` + Bytes int64 `json:"bytes,omitzero,required"` // The Unix timestamp (in seconds) for when the file was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The name of the file. - Filename string `json:"filename,required"` + Filename string `json:"filename,omitzero,required"` // The object type, which is always `file`. - Object FileObjectObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "file". + Object constant.File `json:"object,required"` // The intended purpose of the file. Supported values are `assistants`, // `assistants_output`, `batch`, `batch_output`, `fine-tune`, `fine-tune-results` // and `vision`. - Purpose FileObjectPurpose `json:"purpose,required"` + // + // Any of "assistants", "assistants_output", "batch", "batch_output", "fine-tune", + // "fine-tune-results", "vision" + Purpose string `json:"purpose,omitzero,required"` // Deprecated. The current status of the file, which can be either `uploaded`, // `processed`, or `error`. // + // Any of "uploaded", "processed", "error" + // // Deprecated: deprecated - Status FileObjectStatus `json:"status,required"` + Status string `json:"status,omitzero,required"` // Deprecated. For details on why a fine-tuning training file failed validation, // see the `error` field on `fine_tuning.job`. // // Deprecated: deprecated - StatusDetails string `json:"status_details"` - JSON fileObjectJSON `json:"-"` + StatusDetails string `json:"status_details,omitzero"` + JSON struct { + ID resp.Field + Bytes resp.Field + CreatedAt resp.Field + Filename resp.Field + Object resp.Field + Purpose resp.Field + Status resp.Field + StatusDetails resp.Field + raw string + } `json:"-"` } -// fileObjectJSON contains the JSON metadata for the struct [FileObject] -type fileObjectJSON struct { - ID apijson.Field - Bytes apijson.Field - CreatedAt apijson.Field - Filename apijson.Field - Object apijson.Field - Purpose apijson.Field - Status apijson.Field - StatusDetails apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FileObject) UnmarshalJSON(data []byte) (err error) { +func (r FileObject) RawJSON() string { return r.JSON.raw } +func (r *FileObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fileObjectJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always `file`. -type FileObjectObject string - -const ( - FileObjectObjectFile FileObjectObject = "file" -) - -func (r FileObjectObject) IsKnown() bool { - switch r { - case FileObjectObjectFile: - return true - } - return false -} - // The intended purpose of the file. Supported values are `assistants`, // `assistants_output`, `batch`, `batch_output`, `fine-tune`, `fine-tune-results` // and `vision`. -type FileObjectPurpose string +type FileObjectPurpose = string const ( FileObjectPurposeAssistants FileObjectPurpose = "assistants" @@ -247,17 +214,9 @@ const ( FileObjectPurposeVision FileObjectPurpose = "vision" ) -func (r FileObjectPurpose) IsKnown() bool { - switch r { - case FileObjectPurposeAssistants, FileObjectPurposeAssistantsOutput, FileObjectPurposeBatch, FileObjectPurposeBatchOutput, FileObjectPurposeFineTune, FileObjectPurposeFineTuneResults, FileObjectPurposeVision: - return true - } - return false -} - // Deprecated. The current status of the file, which can be either `uploaded`, // `processed`, or `error`. -type FileObjectStatus string +type FileObjectStatus = string const ( FileObjectStatusUploaded FileObjectStatus = "uploaded" @@ -265,14 +224,6 @@ const ( FileObjectStatusError FileObjectStatus = "error" ) -func (r FileObjectStatus) IsKnown() bool { - switch r { - case FileObjectStatusUploaded, FileObjectStatusProcessed, FileObjectStatusError: - return true - } - return false -} - // The intended purpose of the uploaded file. // // Use "assistants" for @@ -290,17 +241,9 @@ const ( FilePurposeVision FilePurpose = "vision" ) -func (r FilePurpose) IsKnown() bool { - switch r { - case FilePurposeAssistants, FilePurposeBatch, FilePurposeFineTune, FilePurposeVision: - return true - } - return false -} - type FileNewParams struct { // The File object (not file name) to be uploaded. - File param.Field[io.Reader] `json:"file,required" format:"binary"` + File io.Reader `json:"file,omitzero,required" format:"binary"` // The intended purpose of the uploaded file. // // Use "assistants" for @@ -309,9 +252,14 @@ type FileNewParams struct { // "vision" for Assistants image file inputs, "batch" for // [Batch API](https://platform.openai.com/docs/guides/batch), and "fine-tune" for // [Fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning). - Purpose param.Field[FilePurpose] `json:"purpose,required"` + // + // Any of "assistants", "batch", "fine-tune", "vision" + Purpose FilePurpose `json:"purpose,omitzero,required"` + apiobject } +func (f FileNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FileNewParams) MarshalMultipart() (data []byte, contentType string, err error) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) @@ -332,17 +280,22 @@ type FileListParams struct { // in the list. For instance, if you make a list request and receive 100 objects, // ending with obj_foo, your subsequent call can include after=obj_foo in order to // fetch the next page of the list. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // A limit on the number of objects to be returned. Limit can range between 1 and // 10,000, and the default is 10,000. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` // Sort order by the `created_at` timestamp of the objects. `asc` for ascending // order and `desc` for descending order. - Order param.Field[FileListParamsOrder] `query:"order"` + // + // Any of "asc", "desc" + Order FileListParamsOrder `query:"order,omitzero"` // Only return files with the given purpose. - Purpose param.Field[string] `query:"purpose"` + Purpose param.String `query:"purpose,omitzero"` + apiobject } +func (f FileListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [FileListParams]'s query parameters as `url.Values`. func (r FileListParams) URLQuery() (v url.Values) { return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ @@ -359,11 +312,3 @@ const ( FileListParamsOrderAsc FileListParamsOrder = "asc" FileListParamsOrderDesc FileListParamsOrder = "desc" ) - -func (r FileListParamsOrder) IsKnown() bool { - switch r { - case FileListParamsOrderAsc, FileListParamsOrderDesc: - return true - } - return false -} diff --git a/file_test.go b/file_test.go index aec6f07..74c60cc 100644 --- a/file_test.go +++ b/file_test.go @@ -30,8 +30,8 @@ func TestFileNew(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Files.New(context.TODO(), openai.FileNewParams{ - File: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Purpose: openai.F(openai.FilePurposeAssistants), + File: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Purpose: openai.FilePurposeAssistants, }) if err != nil { var apierr *openai.Error @@ -77,10 +77,10 @@ func TestFileListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Files.List(context.TODO(), openai.FileListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), - Order: openai.F(openai.FileListParamsOrderAsc), - Purpose: openai.F("purpose"), + After: openai.String("after"), + Limit: openai.Int(0), + Order: openai.FileListParamsOrderAsc, + Purpose: openai.String("purpose"), }) if err != nil { var apierr *openai.Error diff --git a/finetuning.go b/finetuning.go index 88fa9c5..873e33c 100644 --- a/finetuning.go +++ b/finetuning.go @@ -14,14 +14,14 @@ import ( // the [NewFineTuningService] method instead. type FineTuningService struct { Options []option.RequestOption - Jobs *FineTuningJobService + Jobs FineTuningJobService } // NewFineTuningService generates a new service that applies the given options to // each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewFineTuningService(opts ...option.RequestOption) (r *FineTuningService) { - r = &FineTuningService{} +func NewFineTuningService(opts ...option.RequestOption) (r FineTuningService) { + r = FineTuningService{} r.Options = opts r.Jobs = NewFineTuningJobService(opts...) return diff --git a/finetuningjob.go b/finetuningjob.go index c2f2557..41f65f8 100644 --- a/finetuningjob.go +++ b/finetuningjob.go @@ -4,20 +4,20 @@ package openai import ( "context" + "encoding/json" "errors" "fmt" "net/http" "net/url" - "reflect" "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" - "github.com/openai/openai-go/shared" - "github.com/tidwall/gjson" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // FineTuningJobService contains methods and other services that help with @@ -28,14 +28,14 @@ import ( // the [NewFineTuningJobService] method instead. type FineTuningJobService struct { Options []option.RequestOption - Checkpoints *FineTuningJobCheckpointService + Checkpoints FineTuningJobCheckpointService } // NewFineTuningJobService generates a new service that applies the given options // to each request. These options are applied after the parent client's options (if // there is one), and before any request-specific options. -func NewFineTuningJobService(opts ...option.RequestOption) (r *FineTuningJobService) { - r = &FineTuningJobService{} +func NewFineTuningJobService(opts ...option.RequestOption) (r FineTuningJobService) { + r = FineTuningJobService{} r.Options = opts r.Checkpoints = NewFineTuningJobCheckpointService(opts...) return @@ -135,293 +135,215 @@ func (r *FineTuningJobService) ListEventsAutoPaging(ctx context.Context, fineTun // through the API. type FineTuningJob struct { // The object identifier, which can be referenced in the API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the fine-tuning job was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // For fine-tuning jobs that have `failed`, this will contain more information on // the cause of the failure. - Error FineTuningJobError `json:"error,required,nullable"` + Error FineTuningJobError `json:"error,omitzero,required,nullable"` // The name of the fine-tuned model that is being created. The value will be null // if the fine-tuning job is still running. - FineTunedModel string `json:"fine_tuned_model,required,nullable"` + FineTunedModel string `json:"fine_tuned_model,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the fine-tuning job was finished. The // value will be null if the fine-tuning job is still running. - FinishedAt int64 `json:"finished_at,required,nullable"` + FinishedAt int64 `json:"finished_at,omitzero,required,nullable"` // The hyperparameters used for the fine-tuning job. This value will only be // returned when running `supervised` jobs. - Hyperparameters FineTuningJobHyperparameters `json:"hyperparameters,required"` + Hyperparameters FineTuningJobHyperparameters `json:"hyperparameters,omitzero,required"` // The base model that is being fine-tuned. - Model string `json:"model,required"` + Model string `json:"model,omitzero,required"` // The object type, which is always "fine_tuning.job". - Object FineTuningJobObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as "fine_tuning.job". + Object constant.FineTuningJob `json:"object,required"` // The organization that owns the fine-tuning job. - OrganizationID string `json:"organization_id,required"` + OrganizationID string `json:"organization_id,omitzero,required"` // The compiled results file ID(s) for the fine-tuning job. You can retrieve the // results with the // [Files API](https://platform.openai.com/docs/api-reference/files/retrieve-contents). - ResultFiles []string `json:"result_files,required"` + ResultFiles []string `json:"result_files,omitzero,required"` // The seed used for the fine-tuning job. - Seed int64 `json:"seed,required"` + Seed int64 `json:"seed,omitzero,required"` // The current status of the fine-tuning job, which can be either // `validating_files`, `queued`, `running`, `succeeded`, `failed`, or `cancelled`. - Status FineTuningJobStatus `json:"status,required"` + // + // Any of "validating_files", "queued", "running", "succeeded", "failed", + // "cancelled" + Status string `json:"status,omitzero,required"` // The total number of billable tokens processed by this fine-tuning job. The value // will be null if the fine-tuning job is still running. - TrainedTokens int64 `json:"trained_tokens,required,nullable"` + TrainedTokens int64 `json:"trained_tokens,omitzero,required,nullable"` // The file ID used for training. You can retrieve the training data with the // [Files API](https://platform.openai.com/docs/api-reference/files/retrieve-contents). - TrainingFile string `json:"training_file,required"` + TrainingFile string `json:"training_file,omitzero,required"` // The file ID used for validation. You can retrieve the validation results with // the // [Files API](https://platform.openai.com/docs/api-reference/files/retrieve-contents). - ValidationFile string `json:"validation_file,required,nullable"` + ValidationFile string `json:"validation_file,omitzero,required,nullable"` // The Unix timestamp (in seconds) for when the fine-tuning job is estimated to // finish. The value will be null if the fine-tuning job is not running. - EstimatedFinish int64 `json:"estimated_finish,nullable"` + EstimatedFinish int64 `json:"estimated_finish,omitzero,nullable"` // A list of integrations to enable for this fine-tuning job. - Integrations []FineTuningJobWandbIntegrationObject `json:"integrations,nullable"` + Integrations []FineTuningJobWandbIntegrationObject `json:"integrations,omitzero,nullable"` // The method used for fine-tuning. - Method FineTuningJobMethod `json:"method"` - JSON fineTuningJobJSON `json:"-"` + Method FineTuningJobMethod `json:"method,omitzero"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + Error resp.Field + FineTunedModel resp.Field + FinishedAt resp.Field + Hyperparameters resp.Field + Model resp.Field + Object resp.Field + OrganizationID resp.Field + ResultFiles resp.Field + Seed resp.Field + Status resp.Field + TrainedTokens resp.Field + TrainingFile resp.Field + ValidationFile resp.Field + EstimatedFinish resp.Field + Integrations resp.Field + Method resp.Field + raw string + } `json:"-"` } -// fineTuningJobJSON contains the JSON metadata for the struct [FineTuningJob] -type fineTuningJobJSON struct { - ID apijson.Field - CreatedAt apijson.Field - Error apijson.Field - FineTunedModel apijson.Field - FinishedAt apijson.Field - Hyperparameters apijson.Field - Model apijson.Field - Object apijson.Field - OrganizationID apijson.Field - ResultFiles apijson.Field - Seed apijson.Field - Status apijson.Field - TrainedTokens apijson.Field - TrainingFile apijson.Field - ValidationFile apijson.Field - EstimatedFinish apijson.Field - Integrations apijson.Field - Method apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJob) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJob) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJob) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobJSON) RawJSON() string { - return r.raw -} - // For fine-tuning jobs that have `failed`, this will contain more information on // the cause of the failure. type FineTuningJobError struct { // A machine-readable error code. - Code string `json:"code,required"` + Code string `json:"code,omitzero,required"` // A human-readable error message. - Message string `json:"message,required"` + Message string `json:"message,omitzero,required"` // The parameter that was invalid, usually `training_file` or `validation_file`. // This field will be null if the failure was not parameter-specific. - Param string `json:"param,required,nullable"` - JSON fineTuningJobErrorJSON `json:"-"` + Param string `json:"param,omitzero,required,nullable"` + JSON struct { + Code resp.Field + Message resp.Field + Param resp.Field + raw string + } `json:"-"` } -// fineTuningJobErrorJSON contains the JSON metadata for the struct -// [FineTuningJobError] -type fineTuningJobErrorJSON struct { - Code apijson.Field - Message apijson.Field - Param apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobError) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobError) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobErrorJSON) RawJSON() string { - return r.raw -} - // The hyperparameters used for the fine-tuning job. This value will only be // returned when running `supervised` jobs. type FineTuningJobHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize FineTuningJobHyperparametersBatchSizeUnion `json:"batch_size"` + BatchSize FineTuningJobHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier FineTuningJobHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs FineTuningJobHyperparametersNEpochsUnion `json:"n_epochs"` - JSON fineTuningJobHyperparametersJSON `json:"-"` + NEpochs FineTuningJobHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + JSON struct { + BatchSize resp.Field + LearningRateMultiplier resp.Field + NEpochs resp.Field + raw string + } `json:"-"` } -// fineTuningJobHyperparametersJSON contains the JSON metadata for the struct -// [FineTuningJobHyperparameters] -type fineTuningJobHyperparametersJSON struct { - BatchSize apijson.Field - LearningRateMultiplier apijson.Field - NEpochs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobHyperparameters) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobHyperparameters) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobHyperparameters) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobHyperparametersJSON) RawJSON() string { - return r.raw +type FineTuningJobHyperparametersBatchSizeUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Union satisfied by [FineTuningJobHyperparametersBatchSizeAuto] or -// [shared.UnionInt]. -type FineTuningJobHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobHyperparametersBatchSizeUnion() +func (u FineTuningJobHyperparametersBatchSizeUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobHyperparametersBatchSizeUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobHyperparametersBatchSizeAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +func (u FineTuningJobHyperparametersBatchSizeUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobHyperparametersBatchSizeAuto string +func (u FineTuningJobHyperparametersBatchSizeUnion) RawJSON() string { return u.JSON.raw } -const ( - FineTuningJobHyperparametersBatchSizeAutoAuto FineTuningJobHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (r *FineTuningJobHyperparametersBatchSizeUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (r FineTuningJobHyperparametersBatchSizeAuto) ImplementsFineTuningJobHyperparametersBatchSizeUnion() { +type FineTuningJobHyperparametersLearningRateMultiplierUnion struct { + OfAuto constant.Auto `json:",inline"` + OfFloat64 float64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfFloat64 resp.Field + raw string + } `json:"-"` } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Union satisfied by [FineTuningJobHyperparametersLearningRateMultiplierAuto] or -// [shared.UnionFloat]. -type FineTuningJobHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobHyperparametersLearningRateMultiplierUnion() +func (u FineTuningJobHyperparametersLearningRateMultiplierUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobHyperparametersLearningRateMultiplierUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobHyperparametersLearningRateMultiplierAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionFloat(0)), - }, - ) +func (u FineTuningJobHyperparametersLearningRateMultiplierUnion) AsFloat() (v float64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobHyperparametersLearningRateMultiplierAuto string +func (u FineTuningJobHyperparametersLearningRateMultiplierUnion) RawJSON() string { return u.JSON.raw } -const ( - FineTuningJobHyperparametersLearningRateMultiplierAutoAuto FineTuningJobHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (r *FineTuningJobHyperparametersLearningRateMultiplierUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (r FineTuningJobHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobHyperparametersLearningRateMultiplierUnion() { +type FineTuningJobHyperparametersNEpochsUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Union satisfied by [FineTuningJobHyperparametersNEpochsAuto] or -// [shared.UnionInt]. -type FineTuningJobHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobHyperparametersNEpochsUnion() +func (u FineTuningJobHyperparametersNEpochsUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobHyperparametersNEpochsUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobHyperparametersNEpochsAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +func (u FineTuningJobHyperparametersNEpochsUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobHyperparametersNEpochsAuto string +func (u FineTuningJobHyperparametersNEpochsUnion) RawJSON() string { return u.JSON.raw } -const ( - FineTuningJobHyperparametersNEpochsAutoAuto FineTuningJobHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobHyperparametersNEpochsAutoAuto: - return true - } - return false -} - -func (r FineTuningJobHyperparametersNEpochsAuto) ImplementsFineTuningJobHyperparametersNEpochsUnion() { -} - -// The object type, which is always "fine_tuning.job". -type FineTuningJobObject string - -const ( - FineTuningJobObjectFineTuningJob FineTuningJobObject = "fine_tuning.job" -) - -func (r FineTuningJobObject) IsKnown() bool { - switch r { - case FineTuningJobObjectFineTuningJob: - return true - } - return false +func (r *FineTuningJobHyperparametersNEpochsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The current status of the fine-tuning job, which can be either // `validating_files`, `queued`, `running`, `succeeded`, `failed`, or `cancelled`. -type FineTuningJobStatus string +type FineTuningJobStatus = string const ( FineTuningJobStatusValidatingFiles FineTuningJobStatus = "validating_files" @@ -432,505 +354,349 @@ const ( FineTuningJobStatusCancelled FineTuningJobStatus = "cancelled" ) -func (r FineTuningJobStatus) IsKnown() bool { - switch r { - case FineTuningJobStatusValidatingFiles, FineTuningJobStatusQueued, FineTuningJobStatusRunning, FineTuningJobStatusSucceeded, FineTuningJobStatusFailed, FineTuningJobStatusCancelled: - return true - } - return false -} - // The method used for fine-tuning. type FineTuningJobMethod struct { // Configuration for the DPO fine-tuning method. - Dpo FineTuningJobMethodDpo `json:"dpo"` + Dpo FineTuningJobMethodDpo `json:"dpo,omitzero"` // Configuration for the supervised fine-tuning method. - Supervised FineTuningJobMethodSupervised `json:"supervised"` + Supervised FineTuningJobMethodSupervised `json:"supervised,omitzero"` // The type of method. Is either `supervised` or `dpo`. - Type FineTuningJobMethodType `json:"type"` - JSON fineTuningJobMethodJSON `json:"-"` + // + // Any of "supervised", "dpo" + Type string `json:"type,omitzero"` + JSON struct { + Dpo resp.Field + Supervised resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fineTuningJobMethodJSON contains the JSON metadata for the struct -// [FineTuningJobMethod] -type fineTuningJobMethodJSON struct { - Dpo apijson.Field - Supervised apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobMethod) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobMethod) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobMethod) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobMethodJSON) RawJSON() string { - return r.raw -} - // Configuration for the DPO fine-tuning method. type FineTuningJobMethodDpo struct { // The hyperparameters used for the fine-tuning job. - Hyperparameters FineTuningJobMethodDpoHyperparameters `json:"hyperparameters"` - JSON fineTuningJobMethodDpoJSON `json:"-"` + Hyperparameters FineTuningJobMethodDpoHyperparameters `json:"hyperparameters,omitzero"` + JSON struct { + Hyperparameters resp.Field + raw string + } `json:"-"` } -// fineTuningJobMethodDpoJSON contains the JSON metadata for the struct -// [FineTuningJobMethodDpo] -type fineTuningJobMethodDpoJSON struct { - Hyperparameters apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobMethodDpo) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobMethodDpo) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobMethodDpo) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobMethodDpoJSON) RawJSON() string { - return r.raw -} - // The hyperparameters used for the fine-tuning job. type FineTuningJobMethodDpoHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize FineTuningJobMethodDpoHyperparametersBatchSizeUnion `json:"batch_size"` + BatchSize FineTuningJobMethodDpoHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // The beta value for the DPO method. A higher beta value will increase the weight // of the penalty between the policy and reference model. - Beta FineTuningJobMethodDpoHyperparametersBetaUnion `json:"beta"` + Beta FineTuningJobMethodDpoHyperparametersBetaUnion `json:"beta,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs FineTuningJobMethodDpoHyperparametersNEpochsUnion `json:"n_epochs"` - JSON fineTuningJobMethodDpoHyperparametersJSON `json:"-"` + NEpochs FineTuningJobMethodDpoHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + JSON struct { + BatchSize resp.Field + Beta resp.Field + LearningRateMultiplier resp.Field + NEpochs resp.Field + raw string + } `json:"-"` } -// fineTuningJobMethodDpoHyperparametersJSON contains the JSON metadata for the -// struct [FineTuningJobMethodDpoHyperparameters] -type fineTuningJobMethodDpoHyperparametersJSON struct { - BatchSize apijson.Field - Beta apijson.Field - LearningRateMultiplier apijson.Field - NEpochs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobMethodDpoHyperparameters) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobMethodDpoHyperparameters) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobMethodDpoHyperparameters) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobMethodDpoHyperparametersJSON) RawJSON() string { - return r.raw +type FineTuningJobMethodDpoHyperparametersBatchSizeUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Union satisfied by [FineTuningJobMethodDpoHyperparametersBatchSizeAuto] or -// [shared.UnionInt]. -type FineTuningJobMethodDpoHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobMethodDpoHyperparametersBatchSizeUnion() +func (u FineTuningJobMethodDpoHyperparametersBatchSizeUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodDpoHyperparametersBatchSizeUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodDpoHyperparametersBatchSizeAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +func (u FineTuningJobMethodDpoHyperparametersBatchSizeUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodDpoHyperparametersBatchSizeAuto string +func (u FineTuningJobMethodDpoHyperparametersBatchSizeUnion) RawJSON() string { return u.JSON.raw } -const ( - FineTuningJobMethodDpoHyperparametersBatchSizeAutoAuto FineTuningJobMethodDpoHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobMethodDpoHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodDpoHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (r *FineTuningJobMethodDpoHyperparametersBatchSizeUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (r FineTuningJobMethodDpoHyperparametersBatchSizeAuto) ImplementsFineTuningJobMethodDpoHyperparametersBatchSizeUnion() { +type FineTuningJobMethodDpoHyperparametersBetaUnion struct { + OfAuto constant.Auto `json:",inline"` + OfFloat64 float64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfFloat64 resp.Field + raw string + } `json:"-"` } -// The beta value for the DPO method. A higher beta value will increase the weight -// of the penalty between the policy and reference model. -// -// Union satisfied by [FineTuningJobMethodDpoHyperparametersBetaAuto] or -// [shared.UnionFloat]. -type FineTuningJobMethodDpoHyperparametersBetaUnion interface { - ImplementsFineTuningJobMethodDpoHyperparametersBetaUnion() +func (u FineTuningJobMethodDpoHyperparametersBetaUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodDpoHyperparametersBetaUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodDpoHyperparametersBetaAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionFloat(0)), - }, - ) +func (u FineTuningJobMethodDpoHyperparametersBetaUnion) AsFloat() (v float64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodDpoHyperparametersBetaAuto string +func (u FineTuningJobMethodDpoHyperparametersBetaUnion) RawJSON() string { return u.JSON.raw } -const ( - FineTuningJobMethodDpoHyperparametersBetaAutoAuto FineTuningJobMethodDpoHyperparametersBetaAuto = "auto" -) - -func (r FineTuningJobMethodDpoHyperparametersBetaAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodDpoHyperparametersBetaAutoAuto: - return true - } - return false +func (r *FineTuningJobMethodDpoHyperparametersBetaUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (r FineTuningJobMethodDpoHyperparametersBetaAuto) ImplementsFineTuningJobMethodDpoHyperparametersBetaUnion() { +type FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion struct { + OfAuto constant.Auto `json:",inline"` + OfFloat64 float64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfFloat64 resp.Field + raw string + } `json:"-"` } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Union satisfied by -// [FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto] or -// [shared.UnionFloat]. -type FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion() +func (u FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionFloat(0)), - }, - ) +func (u FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion) AsFloat() (v float64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto string - -const ( - FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAutoAuto FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (u FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion) RawJSON() string { + return u.JSON.raw } -func (r FineTuningJobMethodDpoHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion() { +func (r *FineTuningJobMethodDpoHyperparametersLearningRateMultiplierUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Union satisfied by [FineTuningJobMethodDpoHyperparametersNEpochsAuto] or -// [shared.UnionInt]. -type FineTuningJobMethodDpoHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobMethodDpoHyperparametersNEpochsUnion() +type FineTuningJobMethodDpoHyperparametersNEpochsUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodDpoHyperparametersNEpochsUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodDpoHyperparametersNEpochsAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +func (u FineTuningJobMethodDpoHyperparametersNEpochsUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodDpoHyperparametersNEpochsAuto string - -const ( - FineTuningJobMethodDpoHyperparametersNEpochsAutoAuto FineTuningJobMethodDpoHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobMethodDpoHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodDpoHyperparametersNEpochsAutoAuto: - return true - } - return false +func (u FineTuningJobMethodDpoHyperparametersNEpochsUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r FineTuningJobMethodDpoHyperparametersNEpochsAuto) ImplementsFineTuningJobMethodDpoHyperparametersNEpochsUnion() { +func (u FineTuningJobMethodDpoHyperparametersNEpochsUnion) RawJSON() string { return u.JSON.raw } + +func (r *FineTuningJobMethodDpoHyperparametersNEpochsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // Configuration for the supervised fine-tuning method. type FineTuningJobMethodSupervised struct { // The hyperparameters used for the fine-tuning job. - Hyperparameters FineTuningJobMethodSupervisedHyperparameters `json:"hyperparameters"` - JSON fineTuningJobMethodSupervisedJSON `json:"-"` + Hyperparameters FineTuningJobMethodSupervisedHyperparameters `json:"hyperparameters,omitzero"` + JSON struct { + Hyperparameters resp.Field + raw string + } `json:"-"` } -// fineTuningJobMethodSupervisedJSON contains the JSON metadata for the struct -// [FineTuningJobMethodSupervised] -type fineTuningJobMethodSupervisedJSON struct { - Hyperparameters apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobMethodSupervised) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobMethodSupervised) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobMethodSupervised) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobMethodSupervisedJSON) RawJSON() string { - return r.raw -} - // The hyperparameters used for the fine-tuning job. type FineTuningJobMethodSupervisedHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion `json:"batch_size"` + BatchSize FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs FineTuningJobMethodSupervisedHyperparametersNEpochsUnion `json:"n_epochs"` - JSON fineTuningJobMethodSupervisedHyperparametersJSON `json:"-"` + NEpochs FineTuningJobMethodSupervisedHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + JSON struct { + BatchSize resp.Field + LearningRateMultiplier resp.Field + NEpochs resp.Field + raw string + } `json:"-"` } -// fineTuningJobMethodSupervisedHyperparametersJSON contains the JSON metadata for -// the struct [FineTuningJobMethodSupervisedHyperparameters] -type fineTuningJobMethodSupervisedHyperparametersJSON struct { - BatchSize apijson.Field - LearningRateMultiplier apijson.Field - NEpochs apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobMethodSupervisedHyperparameters) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobMethodSupervisedHyperparameters) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobMethodSupervisedHyperparameters) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobMethodSupervisedHyperparametersJSON) RawJSON() string { - return r.raw +type FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Union satisfied by [FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto] -// or [shared.UnionInt]. -type FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobMethodSupervisedHyperparametersBatchSizeUnion() +func (u FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +func (u FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto string - -const ( - FineTuningJobMethodSupervisedHyperparametersBatchSizeAutoAuto FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodSupervisedHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (u FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion) RawJSON() string { + return u.JSON.raw } -func (r FineTuningJobMethodSupervisedHyperparametersBatchSizeAuto) ImplementsFineTuningJobMethodSupervisedHyperparametersBatchSizeUnion() { +func (r *FineTuningJobMethodSupervisedHyperparametersBatchSizeUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Union satisfied by -// [FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto] or -// [shared.UnionFloat]. -type FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion() +type FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion struct { + OfAuto constant.Auto `json:",inline"` + OfFloat64 float64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfFloat64 resp.Field + raw string + } `json:"-"` } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionFloat(0)), - }, - ) +func (u FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -type FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto string - -const ( - FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAutoAuto FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (u FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion) AsFloat() (v float64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion() { +func (u FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion) RawJSON() string { + return u.JSON.raw } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Union satisfied by [FineTuningJobMethodSupervisedHyperparametersNEpochsAuto] or -// [shared.UnionInt]. -type FineTuningJobMethodSupervisedHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobMethodSupervisedHyperparametersNEpochsUnion() +func (r *FineTuningJobMethodSupervisedHyperparametersLearningRateMultiplierUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func init() { - apijson.RegisterUnion( - reflect.TypeOf((*FineTuningJobMethodSupervisedHyperparametersNEpochsUnion)(nil)).Elem(), - "", - apijson.UnionVariant{ - TypeFilter: gjson.String, - Type: reflect.TypeOf(FineTuningJobMethodSupervisedHyperparametersNEpochsAuto("")), - }, - apijson.UnionVariant{ - TypeFilter: gjson.Number, - Type: reflect.TypeOf(shared.UnionInt(0)), - }, - ) +type FineTuningJobMethodSupervisedHyperparametersNEpochsUnion struct { + OfAuto constant.Auto `json:",inline"` + OfInt64 int64 `json:",inline"` + JSON struct { + OfAuto resp.Field + OfInt64 resp.Field + raw string + } `json:"-"` } -type FineTuningJobMethodSupervisedHyperparametersNEpochsAuto string - -const ( - FineTuningJobMethodSupervisedHyperparametersNEpochsAutoAuto FineTuningJobMethodSupervisedHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobMethodSupervisedHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobMethodSupervisedHyperparametersNEpochsAutoAuto: - return true - } - return false +func (u FineTuningJobMethodSupervisedHyperparametersNEpochsUnion) AsAuto() (v constant.Auto) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r FineTuningJobMethodSupervisedHyperparametersNEpochsAuto) ImplementsFineTuningJobMethodSupervisedHyperparametersNEpochsUnion() { +func (u FineTuningJobMethodSupervisedHyperparametersNEpochsUnion) AsInt() (v int64) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u FineTuningJobMethodSupervisedHyperparametersNEpochsUnion) RawJSON() string { return u.JSON.raw } + +func (r *FineTuningJobMethodSupervisedHyperparametersNEpochsUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The type of method. Is either `supervised` or `dpo`. -type FineTuningJobMethodType string +type FineTuningJobMethodType = string const ( FineTuningJobMethodTypeSupervised FineTuningJobMethodType = "supervised" FineTuningJobMethodTypeDpo FineTuningJobMethodType = "dpo" ) -func (r FineTuningJobMethodType) IsKnown() bool { - switch r { - case FineTuningJobMethodTypeSupervised, FineTuningJobMethodTypeDpo: - return true - } - return false -} - // Fine-tuning job event object type FineTuningJobEvent struct { // The object identifier. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the fine-tuning job was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The log level of the event. - Level FineTuningJobEventLevel `json:"level,required"` + // + // Any of "info", "warn", "error" + Level string `json:"level,omitzero,required"` // The message of the event. - Message string `json:"message,required"` + Message string `json:"message,omitzero,required"` // The object type, which is always "fine_tuning.job.event". - Object FineTuningJobEventObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as + // "fine_tuning.job.event". + Object constant.FineTuningJobEvent `json:"object,required"` // The data associated with the event. - Data interface{} `json:"data"` + Data interface{} `json:"data,omitzero"` // The type of event. - Type FineTuningJobEventType `json:"type"` - JSON fineTuningJobEventJSON `json:"-"` + // + // Any of "message", "metrics" + Type string `json:"type,omitzero"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + Level resp.Field + Message resp.Field + Object resp.Field + Data resp.Field + Type resp.Field + raw string + } `json:"-"` } -// fineTuningJobEventJSON contains the JSON metadata for the struct -// [FineTuningJobEvent] -type fineTuningJobEventJSON struct { - ID apijson.Field - CreatedAt apijson.Field - Level apijson.Field - Message apijson.Field - Object apijson.Field - Data apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobEvent) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobEvent) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobEventJSON) RawJSON() string { - return r.raw -} - // The log level of the event. -type FineTuningJobEventLevel string +type FineTuningJobEventLevel = string const ( FineTuningJobEventLevelInfo FineTuningJobEventLevel = "info" @@ -938,132 +704,72 @@ const ( FineTuningJobEventLevelError FineTuningJobEventLevel = "error" ) -func (r FineTuningJobEventLevel) IsKnown() bool { - switch r { - case FineTuningJobEventLevelInfo, FineTuningJobEventLevelWarn, FineTuningJobEventLevelError: - return true - } - return false -} - -// The object type, which is always "fine_tuning.job.event". -type FineTuningJobEventObject string - -const ( - FineTuningJobEventObjectFineTuningJobEvent FineTuningJobEventObject = "fine_tuning.job.event" -) - -func (r FineTuningJobEventObject) IsKnown() bool { - switch r { - case FineTuningJobEventObjectFineTuningJobEvent: - return true - } - return false -} - // The type of event. -type FineTuningJobEventType string +type FineTuningJobEventType = string const ( FineTuningJobEventTypeMessage FineTuningJobEventType = "message" FineTuningJobEventTypeMetrics FineTuningJobEventType = "metrics" ) -func (r FineTuningJobEventType) IsKnown() bool { - switch r { - case FineTuningJobEventTypeMessage, FineTuningJobEventTypeMetrics: - return true - } - return false -} - type FineTuningJobWandbIntegrationObject struct { // The type of the integration being enabled for the fine-tuning job - Type FineTuningJobWandbIntegrationObjectType `json:"type,required"` + // + // This field can be elided, and will be automatically set as "wandb". + Type constant.Wandb `json:"type,required"` // The settings for your integration with Weights and Biases. This payload // specifies the project that metrics will be sent to. Optionally, you can set an // explicit display name for your run, add tags to your run, and set a default // entity (team, username, etc) to be associated with your run. - Wandb FineTuningJobWandbIntegration `json:"wandb,required"` - JSON fineTuningJobWandbIntegrationObjectJSON `json:"-"` + Wandb FineTuningJobWandbIntegration `json:"wandb,omitzero,required"` + JSON struct { + Type resp.Field + Wandb resp.Field + raw string + } `json:"-"` } -// fineTuningJobWandbIntegrationObjectJSON contains the JSON metadata for the -// struct [FineTuningJobWandbIntegrationObject] -type fineTuningJobWandbIntegrationObjectJSON struct { - Type apijson.Field - Wandb apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobWandbIntegrationObject) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobWandbIntegrationObject) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobWandbIntegrationObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobWandbIntegrationObjectJSON) RawJSON() string { - return r.raw -} - -// The type of the integration being enabled for the fine-tuning job -type FineTuningJobWandbIntegrationObjectType string - -const ( - FineTuningJobWandbIntegrationObjectTypeWandb FineTuningJobWandbIntegrationObjectType = "wandb" -) - -func (r FineTuningJobWandbIntegrationObjectType) IsKnown() bool { - switch r { - case FineTuningJobWandbIntegrationObjectTypeWandb: - return true - } - return false -} - // The settings for your integration with Weights and Biases. This payload // specifies the project that metrics will be sent to. Optionally, you can set an // explicit display name for your run, add tags to your run, and set a default // entity (team, username, etc) to be associated with your run. type FineTuningJobWandbIntegration struct { // The name of the project that the new run will be created under. - Project string `json:"project,required"` + Project string `json:"project,omitzero,required"` // The entity to use for the run. This allows you to set the team or username of // the WandB user that you would like associated with the run. If not set, the // default entity for the registered WandB API key is used. - Entity string `json:"entity,nullable"` + Entity string `json:"entity,omitzero,nullable"` // A display name to set for the run. If not set, we will use the Job ID as the // name. - Name string `json:"name,nullable"` + Name string `json:"name,omitzero,nullable"` // A list of tags to be attached to the newly created run. These tags are passed // through directly to WandB. Some default tags are generated by OpenAI: // "openai/finetune", "openai/{base-model}", "openai/{ftjob-abcdef}". - Tags []string `json:"tags"` - JSON fineTuningJobWandbIntegrationJSON `json:"-"` + Tags []string `json:"tags,omitzero"` + JSON struct { + Project resp.Field + Entity resp.Field + Name resp.Field + Tags resp.Field + raw string + } `json:"-"` } -// fineTuningJobWandbIntegrationJSON contains the JSON metadata for the struct -// [FineTuningJobWandbIntegration] -type fineTuningJobWandbIntegrationJSON struct { - Project apijson.Field - Entity apijson.Field - Name apijson.Field - Tags apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobWandbIntegration) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobWandbIntegration) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobWandbIntegration) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobWandbIntegrationJSON) RawJSON() string { - return r.raw -} - type FineTuningJobNewParams struct { // The name of the model to fine-tune. You can select one of the // [supported models](https://platform.openai.com/docs/guides/fine-tuning#which-models-can-be-fine-tuned). - Model param.Field[FineTuningJobNewParamsModel] `json:"model,required"` + Model string `json:"model,omitzero,required"` // The ID of an uploaded file that contains training data. // // See [upload file](https://platform.openai.com/docs/api-reference/files/create) @@ -1081,24 +787,24 @@ type FineTuningJobNewParams struct { // // See the [fine-tuning guide](https://platform.openai.com/docs/guides/fine-tuning) // for more details. - TrainingFile param.Field[string] `json:"training_file,required"` + TrainingFile param.String `json:"training_file,omitzero,required"` // The hyperparameters used for the fine-tuning job. This value is now deprecated // in favor of `method`, and should be passed in under the `method` parameter. - Hyperparameters param.Field[FineTuningJobNewParamsHyperparameters] `json:"hyperparameters"` + Hyperparameters FineTuningJobNewParamsHyperparameters `json:"hyperparameters,omitzero"` // A list of integrations to enable for your fine-tuning job. - Integrations param.Field[[]FineTuningJobNewParamsIntegration] `json:"integrations"` + Integrations []FineTuningJobNewParamsIntegration `json:"integrations,omitzero"` // The method used for fine-tuning. - Method param.Field[FineTuningJobNewParamsMethod] `json:"method"` + Method FineTuningJobNewParamsMethod `json:"method,omitzero"` // The seed controls the reproducibility of the job. Passing in the same seed and // job parameters should produce the same results, but may differ in rare cases. If // a seed is not specified, one will be generated for you. - Seed param.Field[int64] `json:"seed"` + Seed param.Int `json:"seed,omitzero"` // A string of up to 64 characters that will be added to your fine-tuned model // name. // // For example, a `suffix` of "custom-model-name" would produce a model name like // `ft:gpt-4o-mini:openai:custom-model-name:7p4lURel`. - Suffix param.Field[string] `json:"suffix"` + Suffix param.String `json:"suffix,omitzero"` // The ID of an uploaded file that contains validation data. // // If you provide this file, the data is used to generate validation metrics @@ -1111,16 +817,20 @@ type FineTuningJobNewParams struct { // // See the [fine-tuning guide](https://platform.openai.com/docs/guides/fine-tuning) // for more details. - ValidationFile param.Field[string] `json:"validation_file"` + ValidationFile param.String `json:"validation_file,omitzero"` + apiobject } +func (f FineTuningJobNewParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FineTuningJobNewParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParams + return param.MarshalObject(r, (*shadow)(&r)) } // The name of the model to fine-tune. You can select one of the // [supported models](https://platform.openai.com/docs/guides/fine-tuning#which-models-can-be-fine-tuned). -type FineTuningJobNewParamsModel string +type FineTuningJobNewParamsModel = string const ( FineTuningJobNewParamsModelBabbage002 FineTuningJobNewParamsModel = "babbage-002" @@ -1129,14 +839,6 @@ const ( FineTuningJobNewParamsModelGPT4oMini FineTuningJobNewParamsModel = "gpt-4o-mini" ) -func (r FineTuningJobNewParamsModel) IsKnown() bool { - switch r { - case FineTuningJobNewParamsModelBabbage002, FineTuningJobNewParamsModelDavinci002, FineTuningJobNewParamsModelGPT3_5Turbo, FineTuningJobNewParamsModelGPT4oMini: - return true - } - return false -} - // The hyperparameters used for the fine-tuning job. This value is now deprecated // in favor of `method`, and should be passed in under the `method` parameter. // @@ -1144,126 +846,95 @@ func (r FineTuningJobNewParamsModel) IsKnown() bool { type FineTuningJobNewParamsHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize param.Field[FineTuningJobNewParamsHyperparametersBatchSizeUnion] `json:"batch_size"` + BatchSize FineTuningJobNewParamsHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier param.Field[FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion] `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs param.Field[FineTuningJobNewParamsHyperparametersNEpochsUnion] `json:"n_epochs"` + NEpochs FineTuningJobNewParamsHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + apiobject +} + +func (f FineTuningJobNewParamsHyperparameters) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FineTuningJobNewParamsHyperparameters) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsHyperparameters + return param.MarshalObject(r, (*shadow)(&r)) } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Satisfied by [FineTuningJobNewParamsHyperparametersBatchSizeAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobNewParamsHyperparametersBatchSizeUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsHyperparametersBatchSizeUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsHyperparametersBatchSizeAuto string - -const ( - FineTuningJobNewParamsHyperparametersBatchSizeAutoAuto FineTuningJobNewParamsHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobNewParamsHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsHyperparametersBatchSizeUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsHyperparametersBatchSizeAuto) ImplementsFineTuningJobNewParamsHyperparametersBatchSizeUnion() { +func (u FineTuningJobNewParamsHyperparametersBatchSizeUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsHyperparametersBatchSizeUnion](u.OfAuto, u.OfInt) } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Satisfied by [FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto], -// [shared.UnionFloat]. -type FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfFloat param.Float + apiunion } -type FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto string - -const ( - FineTuningJobNewParamsHyperparametersLearningRateMultiplierAutoAuto FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion() { +func (u FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion](u.OfAuto, u.OfFloat) } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Satisfied by [FineTuningJobNewParamsHyperparametersNEpochsAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobNewParamsHyperparametersNEpochsUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsHyperparametersNEpochsUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsHyperparametersNEpochsAuto string - -const ( - FineTuningJobNewParamsHyperparametersNEpochsAutoAuto FineTuningJobNewParamsHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobNewParamsHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsHyperparametersNEpochsAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsHyperparametersNEpochsUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsHyperparametersNEpochsAuto) ImplementsFineTuningJobNewParamsHyperparametersNEpochsUnion() { +func (u FineTuningJobNewParamsHyperparametersNEpochsUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsHyperparametersNEpochsUnion](u.OfAuto, u.OfInt) } type FineTuningJobNewParamsIntegration struct { // The type of integration to enable. Currently, only "wandb" (Weights and Biases) // is supported. - Type param.Field[FineTuningJobNewParamsIntegrationsType] `json:"type,required"` + // + // This field can be elided, and will be automatically set as "wandb". + Type constant.Wandb `json:"type,required"` // The settings for your integration with Weights and Biases. This payload // specifies the project that metrics will be sent to. Optionally, you can set an // explicit display name for your run, add tags to your run, and set a default // entity (team, username, etc) to be associated with your run. - Wandb param.Field[FineTuningJobNewParamsIntegrationsWandb] `json:"wandb,required"` + Wandb FineTuningJobNewParamsIntegrationsWandb `json:"wandb,omitzero,required"` + apiobject } +func (f FineTuningJobNewParamsIntegration) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FineTuningJobNewParamsIntegration) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) -} - -// The type of integration to enable. Currently, only "wandb" (Weights and Biases) -// is supported. -type FineTuningJobNewParamsIntegrationsType string - -const ( - FineTuningJobNewParamsIntegrationsTypeWandb FineTuningJobNewParamsIntegrationsType = "wandb" -) - -func (r FineTuningJobNewParamsIntegrationsType) IsKnown() bool { - switch r { - case FineTuningJobNewParamsIntegrationsTypeWandb: - return true - } - return false + type shadow FineTuningJobNewParamsIntegration + return param.MarshalObject(r, (*shadow)(&r)) } // The settings for your integration with Weights and Biases. This payload @@ -1272,303 +943,266 @@ func (r FineTuningJobNewParamsIntegrationsType) IsKnown() bool { // entity (team, username, etc) to be associated with your run. type FineTuningJobNewParamsIntegrationsWandb struct { // The name of the project that the new run will be created under. - Project param.Field[string] `json:"project,required"` + Project param.String `json:"project,omitzero,required"` // The entity to use for the run. This allows you to set the team or username of // the WandB user that you would like associated with the run. If not set, the // default entity for the registered WandB API key is used. - Entity param.Field[string] `json:"entity"` + Entity param.String `json:"entity,omitzero"` // A display name to set for the run. If not set, we will use the Job ID as the // name. - Name param.Field[string] `json:"name"` + Name param.String `json:"name,omitzero"` // A list of tags to be attached to the newly created run. These tags are passed // through directly to WandB. Some default tags are generated by OpenAI: // "openai/finetune", "openai/{base-model}", "openai/{ftjob-abcdef}". - Tags param.Field[[]string] `json:"tags"` + Tags []string `json:"tags,omitzero"` + apiobject +} + +func (f FineTuningJobNewParamsIntegrationsWandb) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FineTuningJobNewParamsIntegrationsWandb) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsIntegrationsWandb + return param.MarshalObject(r, (*shadow)(&r)) } // The method used for fine-tuning. type FineTuningJobNewParamsMethod struct { // Configuration for the DPO fine-tuning method. - Dpo param.Field[FineTuningJobNewParamsMethodDpo] `json:"dpo"` + Dpo FineTuningJobNewParamsMethodDpo `json:"dpo,omitzero"` // Configuration for the supervised fine-tuning method. - Supervised param.Field[FineTuningJobNewParamsMethodSupervised] `json:"supervised"` + Supervised FineTuningJobNewParamsMethodSupervised `json:"supervised,omitzero"` // The type of method. Is either `supervised` or `dpo`. - Type param.Field[FineTuningJobNewParamsMethodType] `json:"type"` + // + // Any of "supervised", "dpo" + Type string `json:"type,omitzero"` + apiobject } +func (f FineTuningJobNewParamsMethod) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FineTuningJobNewParamsMethod) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsMethod + return param.MarshalObject(r, (*shadow)(&r)) } // Configuration for the DPO fine-tuning method. type FineTuningJobNewParamsMethodDpo struct { // The hyperparameters used for the fine-tuning job. - Hyperparameters param.Field[FineTuningJobNewParamsMethodDpoHyperparameters] `json:"hyperparameters"` + Hyperparameters FineTuningJobNewParamsMethodDpoHyperparameters `json:"hyperparameters,omitzero"` + apiobject } +func (f FineTuningJobNewParamsMethodDpo) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r FineTuningJobNewParamsMethodDpo) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsMethodDpo + return param.MarshalObject(r, (*shadow)(&r)) } // The hyperparameters used for the fine-tuning job. type FineTuningJobNewParamsMethodDpoHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize param.Field[FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion] `json:"batch_size"` + BatchSize FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // The beta value for the DPO method. A higher beta value will increase the weight // of the penalty between the policy and reference model. - Beta param.Field[FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion] `json:"beta"` + Beta FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion `json:"beta,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier param.Field[FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion] `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs param.Field[FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion] `json:"n_epochs"` + NEpochs FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + apiobject +} + +func (f FineTuningJobNewParamsMethodDpoHyperparameters) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FineTuningJobNewParamsMethodDpoHyperparameters) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsMethodDpoHyperparameters + return param.MarshalObject(r, (*shadow)(&r)) } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Satisfied by [FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto string - -const ( - FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAutoAuto FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto) ImplementsFineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion() { +func (u FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion](u.OfAuto, u.OfInt) } -// The beta value for the DPO method. A higher beta value will increase the weight -// of the penalty between the policy and reference model. -// -// Satisfied by [FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto], -// [shared.UnionFloat]. -type FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion interface { - ImplementsFineTuningJobNewParamsMethodDpoHyperparametersBetaUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfFloat param.Float + apiunion } -type FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto string - -const ( - FineTuningJobNewParamsMethodDpoHyperparametersBetaAutoAuto FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodDpoHyperparametersBetaAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto) ImplementsFineTuningJobNewParamsMethodDpoHyperparametersBetaUnion() { +func (u FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion](u.OfAuto, u.OfFloat) } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Satisfied by -// [FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto], -// [shared.UnionFloat]. -type FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfFloat param.Float + apiunion } -type FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto string - -const ( - FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAutoAuto FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion() { +func (u FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion](u.OfAuto, u.OfFloat) } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Satisfied by [FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto string - -const ( - FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAutoAuto FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto) ImplementsFineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion() { +func (u FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion](u.OfAuto, u.OfInt) } // Configuration for the supervised fine-tuning method. type FineTuningJobNewParamsMethodSupervised struct { // The hyperparameters used for the fine-tuning job. - Hyperparameters param.Field[FineTuningJobNewParamsMethodSupervisedHyperparameters] `json:"hyperparameters"` + Hyperparameters FineTuningJobNewParamsMethodSupervisedHyperparameters `json:"hyperparameters,omitzero"` + apiobject +} + +func (f FineTuningJobNewParamsMethodSupervised) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FineTuningJobNewParamsMethodSupervised) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsMethodSupervised + return param.MarshalObject(r, (*shadow)(&r)) } // The hyperparameters used for the fine-tuning job. type FineTuningJobNewParamsMethodSupervisedHyperparameters struct { // Number of examples in each batch. A larger batch size means that model // parameters are updated less frequently, but with lower variance. - BatchSize param.Field[FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion] `json:"batch_size"` + BatchSize FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion `json:"batch_size,omitzero"` // Scaling factor for the learning rate. A smaller learning rate may be useful to // avoid overfitting. - LearningRateMultiplier param.Field[FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion] `json:"learning_rate_multiplier"` + LearningRateMultiplier FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion `json:"learning_rate_multiplier,omitzero"` // The number of epochs to train the model for. An epoch refers to one full cycle // through the training dataset. - NEpochs param.Field[FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion] `json:"n_epochs"` + NEpochs FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion `json:"n_epochs,omitzero"` + apiobject +} + +func (f FineTuningJobNewParamsMethodSupervisedHyperparameters) IsMissing() bool { + return param.IsOmitted(f) || f.IsNull() } func (r FineTuningJobNewParamsMethodSupervisedHyperparameters) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow FineTuningJobNewParamsMethodSupervisedHyperparameters + return param.MarshalObject(r, (*shadow)(&r)) } -// Number of examples in each batch. A larger batch size means that model -// parameters are updated less frequently, but with lower variance. -// -// Satisfied by -// [FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion interface { - ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto string - -const ( - FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAutoAuto FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto) ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion() { +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion](u.OfAuto, u.OfInt) } -// Scaling factor for the learning rate. A smaller learning rate may be useful to -// avoid overfitting. -// -// Satisfied by -// [FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto], -// [shared.UnionFloat]. -type FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion interface { - ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfFloat param.Float + apiunion } -type FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto string - -const ( - FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAutoAuto FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto) ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion() { +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion](u.OfAuto, u.OfFloat) } -// The number of epochs to train the model for. An epoch refers to one full cycle -// through the training dataset. -// -// Satisfied by [FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto], -// [shared.UnionInt]. -type FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion interface { - ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion() +// Only one field can be non-zero +type FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion struct { + // Construct this variant with constant.ValueOf[constant.Auto]() Check if union is + // this variant with !param.IsOmitted(union.OfAuto) + OfAuto constant.Auto + OfInt param.Int + apiunion } -type FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto string - -const ( - FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAutoAuto FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto = "auto" -) - -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAutoAuto: - return true - } - return false +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion) IsMissing() bool { + return param.IsOmitted(u) || u.IsNull() } -func (r FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto) ImplementsFineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion() { +func (u FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion[FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion](u.OfAuto, u.OfInt) } // The type of method. Is either `supervised` or `dpo`. -type FineTuningJobNewParamsMethodType string +type FineTuningJobNewParamsMethodType = string const ( FineTuningJobNewParamsMethodTypeSupervised FineTuningJobNewParamsMethodType = "supervised" FineTuningJobNewParamsMethodTypeDpo FineTuningJobNewParamsMethodType = "dpo" ) -func (r FineTuningJobNewParamsMethodType) IsKnown() bool { - switch r { - case FineTuningJobNewParamsMethodTypeSupervised, FineTuningJobNewParamsMethodTypeDpo: - return true - } - return false -} - type FineTuningJobListParams struct { // Identifier for the last job from the previous pagination request. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // Number of fine-tuning jobs to retrieve. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` + apiobject } +func (f FineTuningJobListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [FineTuningJobListParams]'s query parameters as // `url.Values`. func (r FineTuningJobListParams) URLQuery() (v url.Values) { @@ -1580,11 +1214,14 @@ func (r FineTuningJobListParams) URLQuery() (v url.Values) { type FineTuningJobListEventsParams struct { // Identifier for the last event from the previous pagination request. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // Number of events to retrieve. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` + apiobject } +func (f FineTuningJobListEventsParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [FineTuningJobListEventsParams]'s query parameters as // `url.Values`. func (r FineTuningJobListEventsParams) URLQuery() (v url.Values) { diff --git a/finetuningjob_test.go b/finetuningjob_test.go index bd42c13..9ced5e3 100644 --- a/finetuningjob_test.go +++ b/finetuningjob_test.go @@ -11,6 +11,7 @@ import ( "github.com/openai/openai-go" "github.com/openai/openai-go/internal/testutil" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/shared/constant" ) func TestFineTuningJobNewWithOptionalParams(t *testing.T) { @@ -26,43 +27,62 @@ func TestFineTuningJobNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.FineTuning.Jobs.New(context.TODO(), openai.FineTuningJobNewParams{ - Model: openai.F(openai.FineTuningJobNewParamsModelBabbage002), - TrainingFile: openai.F("file-abc123"), - Hyperparameters: openai.F(openai.FineTuningJobNewParamsHyperparameters{ - BatchSize: openai.F[openai.FineTuningJobNewParamsHyperparametersBatchSizeUnion](openai.FineTuningJobNewParamsHyperparametersBatchSizeAuto(openai.FineTuningJobNewParamsHyperparametersBatchSizeAutoAuto)), - LearningRateMultiplier: openai.F[openai.FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion](openai.FineTuningJobNewParamsHyperparametersLearningRateMultiplierAuto(openai.FineTuningJobNewParamsHyperparametersLearningRateMultiplierAutoAuto)), - NEpochs: openai.F[openai.FineTuningJobNewParamsHyperparametersNEpochsUnion](openai.FineTuningJobNewParamsHyperparametersNEpochsAuto(openai.FineTuningJobNewParamsHyperparametersNEpochsAutoAuto)), - }), - Integrations: openai.F([]openai.FineTuningJobNewParamsIntegration{{ - Type: openai.F(openai.FineTuningJobNewParamsIntegrationsTypeWandb), - Wandb: openai.F(openai.FineTuningJobNewParamsIntegrationsWandb{ - Project: openai.F("my-wandb-project"), - Entity: openai.F("entity"), - Name: openai.F("name"), - Tags: openai.F([]string{"custom-tag"}), - }), - }}), - Method: openai.F(openai.FineTuningJobNewParamsMethod{ - Dpo: openai.F(openai.FineTuningJobNewParamsMethodDpo{ - Hyperparameters: openai.F(openai.FineTuningJobNewParamsMethodDpoHyperparameters{ - BatchSize: openai.F[openai.FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion](openai.FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAuto(openai.FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeAutoAuto)), - Beta: openai.F[openai.FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion](openai.FineTuningJobNewParamsMethodDpoHyperparametersBetaAuto(openai.FineTuningJobNewParamsMethodDpoHyperparametersBetaAutoAuto)), - LearningRateMultiplier: openai.F[openai.FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion](openai.FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAuto(openai.FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierAutoAuto)), - NEpochs: openai.F[openai.FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion](openai.FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAuto(openai.FineTuningJobNewParamsMethodDpoHyperparametersNEpochsAutoAuto)), - }), - }), - Supervised: openai.F(openai.FineTuningJobNewParamsMethodSupervised{ - Hyperparameters: openai.F(openai.FineTuningJobNewParamsMethodSupervisedHyperparameters{ - BatchSize: openai.F[openai.FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion](openai.FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAuto(openai.FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeAutoAuto)), - LearningRateMultiplier: openai.F[openai.FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion](openai.FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAuto(openai.FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierAutoAuto)), - NEpochs: openai.F[openai.FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion](openai.FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAuto(openai.FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsAutoAuto)), - }), - }), - Type: openai.F(openai.FineTuningJobNewParamsMethodTypeSupervised), - }), - Seed: openai.F(int64(42)), - Suffix: openai.F("x"), - ValidationFile: openai.F("file-abc123"), + Model: "babbage-002", + TrainingFile: openai.String("file-abc123"), + Hyperparameters: openai.FineTuningJobNewParamsHyperparameters{ + BatchSize: openai.FineTuningJobNewParamsHyperparametersBatchSizeUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + LearningRateMultiplier: openai.FineTuningJobNewParamsHyperparametersLearningRateMultiplierUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + NEpochs: openai.FineTuningJobNewParamsHyperparametersNEpochsUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + }, + Integrations: []openai.FineTuningJobNewParamsIntegration{{ + Wandb: openai.FineTuningJobNewParamsIntegrationsWandb{ + Project: openai.String("my-wandb-project"), + Entity: openai.String("entity"), + Name: openai.String("name"), + Tags: []string{"custom-tag"}, + }, + }}, + Method: openai.FineTuningJobNewParamsMethod{ + Dpo: openai.FineTuningJobNewParamsMethodDpo{ + Hyperparameters: openai.FineTuningJobNewParamsMethodDpoHyperparameters{ + BatchSize: openai.FineTuningJobNewParamsMethodDpoHyperparametersBatchSizeUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + Beta: openai.FineTuningJobNewParamsMethodDpoHyperparametersBetaUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + LearningRateMultiplier: openai.FineTuningJobNewParamsMethodDpoHyperparametersLearningRateMultiplierUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + NEpochs: openai.FineTuningJobNewParamsMethodDpoHyperparametersNEpochsUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + }, + }, + Supervised: openai.FineTuningJobNewParamsMethodSupervised{ + Hyperparameters: openai.FineTuningJobNewParamsMethodSupervisedHyperparameters{ + BatchSize: openai.FineTuningJobNewParamsMethodSupervisedHyperparametersBatchSizeUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + LearningRateMultiplier: openai.FineTuningJobNewParamsMethodSupervisedHyperparametersLearningRateMultiplierUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + NEpochs: openai.FineTuningJobNewParamsMethodSupervisedHyperparametersNEpochsUnion{ + OfAuto: constant.ValueOf[constant.Auto](), + }, + }, + }, + Type: "supervised", + }, + Seed: openai.Int(42), + Suffix: openai.String("x"), + ValidationFile: openai.String("file-abc123"), }) if err != nil { var apierr *openai.Error @@ -108,8 +128,8 @@ func TestFineTuningJobListWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.FineTuning.Jobs.List(context.TODO(), openai.FineTuningJobListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), + After: openai.String("after"), + Limit: openai.Int(0), }) if err != nil { var apierr *openai.Error @@ -158,8 +178,8 @@ func TestFineTuningJobListEventsWithOptionalParams(t *testing.T) { context.TODO(), "ft-AF1WoRqd3aJAHsqc9NY7iL8F", openai.FineTuningJobListEventsParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), + After: openai.String("after"), + Limit: openai.Int(0), }, ) if err != nil { diff --git a/finetuningjobcheckpoint.go b/finetuningjobcheckpoint.go index 7c53e5d..44047f1 100644 --- a/finetuningjobcheckpoint.go +++ b/finetuningjobcheckpoint.go @@ -11,10 +11,12 @@ import ( "github.com/openai/openai-go/internal/apijson" "github.com/openai/openai-go/internal/apiquery" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" "github.com/openai/openai-go/packages/pagination" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" + "github.com/openai/openai-go/shared/constant" ) // FineTuningJobCheckpointService contains methods and other services that help @@ -30,8 +32,8 @@ type FineTuningJobCheckpointService struct { // NewFineTuningJobCheckpointService generates a new service that applies the given // options to each request. These options are applied after the parent client's // options (if there is one), and before any request-specific options. -func NewFineTuningJobCheckpointService(opts ...option.RequestOption) (r *FineTuningJobCheckpointService) { - r = &FineTuningJobCheckpointService{} +func NewFineTuningJobCheckpointService(opts ...option.RequestOption) (r FineTuningJobCheckpointService) { + r = FineTuningJobCheckpointService{} r.Options = opts return } @@ -67,100 +69,75 @@ func (r *FineTuningJobCheckpointService) ListAutoPaging(ctx context.Context, fin // fine-tuning job that is ready to use. type FineTuningJobCheckpoint struct { // The checkpoint identifier, which can be referenced in the API endpoints. - ID string `json:"id,required"` + ID string `json:"id,omitzero,required"` // The Unix timestamp (in seconds) for when the checkpoint was created. - CreatedAt int64 `json:"created_at,required"` + CreatedAt int64 `json:"created_at,omitzero,required"` // The name of the fine-tuned checkpoint model that is created. - FineTunedModelCheckpoint string `json:"fine_tuned_model_checkpoint,required"` + FineTunedModelCheckpoint string `json:"fine_tuned_model_checkpoint,omitzero,required"` // The name of the fine-tuning job that this checkpoint was created from. - FineTuningJobID string `json:"fine_tuning_job_id,required"` + FineTuningJobID string `json:"fine_tuning_job_id,omitzero,required"` // Metrics at the step number during the fine-tuning job. - Metrics FineTuningJobCheckpointMetrics `json:"metrics,required"` + Metrics FineTuningJobCheckpointMetrics `json:"metrics,omitzero,required"` // The object type, which is always "fine_tuning.job.checkpoint". - Object FineTuningJobCheckpointObject `json:"object,required"` + // + // This field can be elided, and will be automatically set as + // "fine_tuning.job.checkpoint". + Object constant.FineTuningJobCheckpoint `json:"object,required"` // The step number that the checkpoint was created at. - StepNumber int64 `json:"step_number,required"` - JSON fineTuningJobCheckpointJSON `json:"-"` + StepNumber int64 `json:"step_number,omitzero,required"` + JSON struct { + ID resp.Field + CreatedAt resp.Field + FineTunedModelCheckpoint resp.Field + FineTuningJobID resp.Field + Metrics resp.Field + Object resp.Field + StepNumber resp.Field + raw string + } `json:"-"` } -// fineTuningJobCheckpointJSON contains the JSON metadata for the struct -// [FineTuningJobCheckpoint] -type fineTuningJobCheckpointJSON struct { - ID apijson.Field - CreatedAt apijson.Field - FineTunedModelCheckpoint apijson.Field - FineTuningJobID apijson.Field - Metrics apijson.Field - Object apijson.Field - StepNumber apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobCheckpoint) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobCheckpoint) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobCheckpoint) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobCheckpointJSON) RawJSON() string { - return r.raw -} - // Metrics at the step number during the fine-tuning job. type FineTuningJobCheckpointMetrics struct { - FullValidLoss float64 `json:"full_valid_loss"` - FullValidMeanTokenAccuracy float64 `json:"full_valid_mean_token_accuracy"` - Step float64 `json:"step"` - TrainLoss float64 `json:"train_loss"` - TrainMeanTokenAccuracy float64 `json:"train_mean_token_accuracy"` - ValidLoss float64 `json:"valid_loss"` - ValidMeanTokenAccuracy float64 `json:"valid_mean_token_accuracy"` - JSON fineTuningJobCheckpointMetricsJSON `json:"-"` + FullValidLoss float64 `json:"full_valid_loss,omitzero"` + FullValidMeanTokenAccuracy float64 `json:"full_valid_mean_token_accuracy,omitzero"` + Step float64 `json:"step,omitzero"` + TrainLoss float64 `json:"train_loss,omitzero"` + TrainMeanTokenAccuracy float64 `json:"train_mean_token_accuracy,omitzero"` + ValidLoss float64 `json:"valid_loss,omitzero"` + ValidMeanTokenAccuracy float64 `json:"valid_mean_token_accuracy,omitzero"` + JSON struct { + FullValidLoss resp.Field + FullValidMeanTokenAccuracy resp.Field + Step resp.Field + TrainLoss resp.Field + TrainMeanTokenAccuracy resp.Field + ValidLoss resp.Field + ValidMeanTokenAccuracy resp.Field + raw string + } `json:"-"` } -// fineTuningJobCheckpointMetricsJSON contains the JSON metadata for the struct -// [FineTuningJobCheckpointMetrics] -type fineTuningJobCheckpointMetricsJSON struct { - FullValidLoss apijson.Field - FullValidMeanTokenAccuracy apijson.Field - Step apijson.Field - TrainLoss apijson.Field - TrainMeanTokenAccuracy apijson.Field - ValidLoss apijson.Field - ValidMeanTokenAccuracy apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *FineTuningJobCheckpointMetrics) UnmarshalJSON(data []byte) (err error) { +func (r FineTuningJobCheckpointMetrics) RawJSON() string { return r.JSON.raw } +func (r *FineTuningJobCheckpointMetrics) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r fineTuningJobCheckpointMetricsJSON) RawJSON() string { - return r.raw -} - -// The object type, which is always "fine_tuning.job.checkpoint". -type FineTuningJobCheckpointObject string - -const ( - FineTuningJobCheckpointObjectFineTuningJobCheckpoint FineTuningJobCheckpointObject = "fine_tuning.job.checkpoint" -) - -func (r FineTuningJobCheckpointObject) IsKnown() bool { - switch r { - case FineTuningJobCheckpointObjectFineTuningJobCheckpoint: - return true - } - return false -} - type FineTuningJobCheckpointListParams struct { // Identifier for the last checkpoint ID from the previous pagination request. - After param.Field[string] `query:"after"` + After param.String `query:"after,omitzero"` // Number of checkpoints to retrieve. - Limit param.Field[int64] `query:"limit"` + Limit param.Int `query:"limit,omitzero"` + apiobject } +func (f FineTuningJobCheckpointListParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + // URLQuery serializes [FineTuningJobCheckpointListParams]'s query parameters as // `url.Values`. func (r FineTuningJobCheckpointListParams) URLQuery() (v url.Values) { diff --git a/finetuningjobcheckpoint_test.go b/finetuningjobcheckpoint_test.go index 6f6cafc..1de9ecb 100644 --- a/finetuningjobcheckpoint_test.go +++ b/finetuningjobcheckpoint_test.go @@ -29,8 +29,8 @@ func TestFineTuningJobCheckpointListWithOptionalParams(t *testing.T) { context.TODO(), "ft-AF1WoRqd3aJAHsqc9NY7iL8F", openai.FineTuningJobCheckpointListParams{ - After: openai.F("after"), - Limit: openai.F(int64(0)), + After: openai.String("after"), + Limit: openai.Int(0), }, ) if err != nil { diff --git a/image.go b/image.go index f52ef80..6a75f79 100644 --- a/image.go +++ b/image.go @@ -11,9 +11,10 @@ import ( "github.com/openai/openai-go/internal/apiform" "github.com/openai/openai-go/internal/apijson" - "github.com/openai/openai-go/internal/param" "github.com/openai/openai-go/internal/requestconfig" "github.com/openai/openai-go/option" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" ) // ImageService contains methods and other services that help with interacting with @@ -29,8 +30,8 @@ type ImageService struct { // NewImageService generates a new service that applies the given options to each // request. These options are applied after the parent client's options (if there // is one), and before any request-specific options. -func NewImageService(opts ...option.RequestOption) (r *ImageService) { - r = &ImageService{} +func NewImageService(opts ...option.RequestOption) (r ImageService) { + r = ImageService{} r.Options = opts return } @@ -63,32 +64,25 @@ func (r *ImageService) Generate(ctx context.Context, body ImageGenerateParams, o type Image struct { // The base64-encoded JSON of the generated image, if `response_format` is // `b64_json`. - B64JSON string `json:"b64_json"` + B64JSON string `json:"b64_json,omitzero"` // The prompt that was used to generate the image, if there was any revision to the // prompt. - RevisedPrompt string `json:"revised_prompt"` + RevisedPrompt string `json:"revised_prompt,omitzero"` // The URL of the generated image, if `response_format` is `url` (default). - URL string `json:"url"` - JSON imageJSON `json:"-"` + URL string `json:"url,omitzero"` + JSON struct { + B64JSON resp.Field + RevisedPrompt resp.Field + URL resp.Field + raw string + } `json:"-"` } -// imageJSON contains the JSON metadata for the struct [Image] -type imageJSON struct { - B64JSON apijson.Field - RevisedPrompt apijson.Field - URL apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Image) UnmarshalJSON(data []byte) (err error) { +func (r Image) RawJSON() string { return r.JSON.raw } +func (r *Image) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imageJSON) RawJSON() string { - return r.raw -} - type ImageModel = string const ( @@ -97,50 +91,50 @@ const ( ) type ImagesResponse struct { - Created int64 `json:"created,required"` - Data []Image `json:"data,required"` - JSON imagesResponseJSON `json:"-"` + Created int64 `json:"created,omitzero,required"` + Data []Image `json:"data,omitzero,required"` + JSON struct { + Created resp.Field + Data resp.Field + raw string + } `json:"-"` } -// imagesResponseJSON contains the JSON metadata for the struct [ImagesResponse] -type imagesResponseJSON struct { - Created apijson.Field - Data apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *ImagesResponse) UnmarshalJSON(data []byte) (err error) { +func (r ImagesResponse) RawJSON() string { return r.JSON.raw } +func (r *ImagesResponse) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r imagesResponseJSON) RawJSON() string { - return r.raw -} - type ImageNewVariationParams struct { // The image to use as the basis for the variation(s). Must be a valid PNG file, // less than 4MB, and square. - Image param.Field[io.Reader] `json:"image,required" format:"binary"` + Image io.Reader `json:"image,omitzero,required" format:"binary"` // The model to use for image generation. Only `dall-e-2` is supported at this // time. - Model param.Field[ImageModel] `json:"model"` + Model ImageModel `json:"model,omitzero"` // The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only // `n=1` is supported. - N param.Field[int64] `json:"n"` + N param.Int `json:"n,omitzero"` // The format in which the generated images are returned. Must be one of `url` or // `b64_json`. URLs are only valid for 60 minutes after the image has been // generated. - ResponseFormat param.Field[ImageNewVariationParamsResponseFormat] `json:"response_format"` + // + // Any of "url", "b64_json" + ResponseFormat ImageNewVariationParamsResponseFormat `json:"response_format,omitzero"` // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024`. - Size param.Field[ImageNewVariationParamsSize] `json:"size"` + // + // Any of "256x256", "512x512", "1024x1024" + Size ImageNewVariationParamsSize `json:"size,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f ImageNewVariationParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageNewVariationParams) MarshalMultipart() (data []byte, contentType string, err error) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) @@ -166,14 +160,6 @@ const ( ImageNewVariationParamsResponseFormatB64JSON ImageNewVariationParamsResponseFormat = "b64_json" ) -func (r ImageNewVariationParamsResponseFormat) IsKnown() bool { - switch r { - case ImageNewVariationParamsResponseFormatURL, ImageNewVariationParamsResponseFormatB64JSON: - return true - } - return false -} - // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024`. type ImageNewVariationParamsSize string @@ -184,43 +170,42 @@ const ( ImageNewVariationParamsSize1024x1024 ImageNewVariationParamsSize = "1024x1024" ) -func (r ImageNewVariationParamsSize) IsKnown() bool { - switch r { - case ImageNewVariationParamsSize256x256, ImageNewVariationParamsSize512x512, ImageNewVariationParamsSize1024x1024: - return true - } - return false -} - type ImageEditParams struct { // The image to edit. Must be a valid PNG file, less than 4MB, and square. If mask // is not provided, image must have transparency, which will be used as the mask. - Image param.Field[io.Reader] `json:"image,required" format:"binary"` + Image io.Reader `json:"image,omitzero,required" format:"binary"` // A text description of the desired image(s). The maximum length is 1000 // characters. - Prompt param.Field[string] `json:"prompt,required"` + Prompt param.String `json:"prompt,omitzero,required"` // An additional image whose fully transparent areas (e.g. where alpha is zero) // indicate where `image` should be edited. Must be a valid PNG file, less than // 4MB, and have the same dimensions as `image`. - Mask param.Field[io.Reader] `json:"mask" format:"binary"` + Mask io.Reader `json:"mask,omitzero" format:"binary"` // The model to use for image generation. Only `dall-e-2` is supported at this // time. - Model param.Field[ImageModel] `json:"model"` + Model ImageModel `json:"model,omitzero"` // The number of images to generate. Must be between 1 and 10. - N param.Field[int64] `json:"n"` + N param.Int `json:"n,omitzero"` // The format in which the generated images are returned. Must be one of `url` or // `b64_json`. URLs are only valid for 60 minutes after the image has been // generated. - ResponseFormat param.Field[ImageEditParamsResponseFormat] `json:"response_format"` + // + // Any of "url", "b64_json" + ResponseFormat ImageEditParamsResponseFormat `json:"response_format,omitzero"` // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024`. - Size param.Field[ImageEditParamsSize] `json:"size"` + // + // Any of "256x256", "512x512", "1024x1024" + Size ImageEditParamsSize `json:"size,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f ImageEditParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageEditParams) MarshalMultipart() (data []byte, contentType string, err error) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) @@ -246,14 +231,6 @@ const ( ImageEditParamsResponseFormatB64JSON ImageEditParamsResponseFormat = "b64_json" ) -func (r ImageEditParamsResponseFormat) IsKnown() bool { - switch r { - case ImageEditParamsResponseFormatURL, ImageEditParamsResponseFormatB64JSON: - return true - } - return false -} - // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024`. type ImageEditParamsSize string @@ -264,48 +241,52 @@ const ( ImageEditParamsSize1024x1024 ImageEditParamsSize = "1024x1024" ) -func (r ImageEditParamsSize) IsKnown() bool { - switch r { - case ImageEditParamsSize256x256, ImageEditParamsSize512x512, ImageEditParamsSize1024x1024: - return true - } - return false -} - type ImageGenerateParams struct { // A text description of the desired image(s). The maximum length is 1000 // characters for `dall-e-2` and 4000 characters for `dall-e-3`. - Prompt param.Field[string] `json:"prompt,required"` + Prompt param.String `json:"prompt,omitzero,required"` // The model to use for image generation. - Model param.Field[ImageModel] `json:"model"` + Model ImageModel `json:"model,omitzero"` // The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only // `n=1` is supported. - N param.Field[int64] `json:"n"` + N param.Int `json:"n,omitzero"` // The quality of the image that will be generated. `hd` creates images with finer // details and greater consistency across the image. This param is only supported // for `dall-e-3`. - Quality param.Field[ImageGenerateParamsQuality] `json:"quality"` + // + // Any of "standard", "hd" + Quality ImageGenerateParamsQuality `json:"quality,omitzero"` // The format in which the generated images are returned. Must be one of `url` or // `b64_json`. URLs are only valid for 60 minutes after the image has been // generated. - ResponseFormat param.Field[ImageGenerateParamsResponseFormat] `json:"response_format"` + // + // Any of "url", "b64_json" + ResponseFormat ImageGenerateParamsResponseFormat `json:"response_format,omitzero"` // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024` for `dall-e-2`. Must be one of `1024x1024`, `1792x1024`, or // `1024x1792` for `dall-e-3` models. - Size param.Field[ImageGenerateParamsSize] `json:"size"` + // + // Any of "256x256", "512x512", "1024x1024", "1792x1024", "1024x1792" + Size ImageGenerateParamsSize `json:"size,omitzero"` // The style of the generated images. Must be one of `vivid` or `natural`. Vivid // causes the model to lean towards generating hyper-real and dramatic images. // Natural causes the model to produce more natural, less hyper-real looking // images. This param is only supported for `dall-e-3`. - Style param.Field[ImageGenerateParamsStyle] `json:"style"` + // + // Any of "vivid", "natural" + Style ImageGenerateParamsStyle `json:"style,omitzero"` // A unique identifier representing your end-user, which can help OpenAI to monitor // and detect abuse. // [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids). - User param.Field[string] `json:"user"` + User param.String `json:"user,omitzero"` + apiobject } +func (f ImageGenerateParams) IsMissing() bool { return param.IsOmitted(f) || f.IsNull() } + func (r ImageGenerateParams) MarshalJSON() (data []byte, err error) { - return apijson.MarshalRoot(r) + type shadow ImageGenerateParams + return param.MarshalObject(r, (*shadow)(&r)) } // The quality of the image that will be generated. `hd` creates images with finer @@ -318,14 +299,6 @@ const ( ImageGenerateParamsQualityHD ImageGenerateParamsQuality = "hd" ) -func (r ImageGenerateParamsQuality) IsKnown() bool { - switch r { - case ImageGenerateParamsQualityStandard, ImageGenerateParamsQualityHD: - return true - } - return false -} - // The format in which the generated images are returned. Must be one of `url` or // `b64_json`. URLs are only valid for 60 minutes after the image has been // generated. @@ -336,14 +309,6 @@ const ( ImageGenerateParamsResponseFormatB64JSON ImageGenerateParamsResponseFormat = "b64_json" ) -func (r ImageGenerateParamsResponseFormat) IsKnown() bool { - switch r { - case ImageGenerateParamsResponseFormatURL, ImageGenerateParamsResponseFormatB64JSON: - return true - } - return false -} - // The size of the generated images. Must be one of `256x256`, `512x512`, or // `1024x1024` for `dall-e-2`. Must be one of `1024x1024`, `1792x1024`, or // `1024x1792` for `dall-e-3` models. @@ -357,14 +322,6 @@ const ( ImageGenerateParamsSize1024x1792 ImageGenerateParamsSize = "1024x1792" ) -func (r ImageGenerateParamsSize) IsKnown() bool { - switch r { - case ImageGenerateParamsSize256x256, ImageGenerateParamsSize512x512, ImageGenerateParamsSize1024x1024, ImageGenerateParamsSize1792x1024, ImageGenerateParamsSize1024x1792: - return true - } - return false -} - // The style of the generated images. Must be one of `vivid` or `natural`. Vivid // causes the model to lean towards generating hyper-real and dramatic images. // Natural causes the model to produce more natural, less hyper-real looking @@ -375,11 +332,3 @@ const ( ImageGenerateParamsStyleVivid ImageGenerateParamsStyle = "vivid" ImageGenerateParamsStyleNatural ImageGenerateParamsStyle = "natural" ) - -func (r ImageGenerateParamsStyle) IsKnown() bool { - switch r { - case ImageGenerateParamsStyleVivid, ImageGenerateParamsStyleNatural: - return true - } - return false -} diff --git a/image_test.go b/image_test.go index f4334ee..20ca67f 100644 --- a/image_test.go +++ b/image_test.go @@ -28,12 +28,12 @@ func TestImageNewVariationWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Images.NewVariation(context.TODO(), openai.ImageNewVariationParams{ - Image: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Model: openai.F(openai.ImageModelDallE2), - N: openai.F(int64(1)), - ResponseFormat: openai.F(openai.ImageNewVariationParamsResponseFormatURL), - Size: openai.F(openai.ImageNewVariationParamsSize256x256), - User: openai.F("user-1234"), + Image: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Model: openai.ImageModelDallE2, + N: openai.Int(1), + ResponseFormat: openai.ImageNewVariationParamsResponseFormatURL, + Size: openai.ImageNewVariationParamsSize256x256, + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error @@ -57,14 +57,14 @@ func TestImageEditWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Images.Edit(context.TODO(), openai.ImageEditParams{ - Image: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Prompt: openai.F("A cute baby sea otter wearing a beret"), - Mask: openai.F(io.Reader(bytes.NewBuffer([]byte("some file contents")))), - Model: openai.F(openai.ImageModelDallE2), - N: openai.F(int64(1)), - ResponseFormat: openai.F(openai.ImageEditParamsResponseFormatURL), - Size: openai.F(openai.ImageEditParamsSize256x256), - User: openai.F("user-1234"), + Image: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Prompt: openai.String("A cute baby sea otter wearing a beret"), + Mask: io.Reader(bytes.NewBuffer([]byte("some file contents"))), + Model: openai.ImageModelDallE2, + N: openai.Int(1), + ResponseFormat: openai.ImageEditParamsResponseFormatURL, + Size: openai.ImageEditParamsSize256x256, + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error @@ -88,14 +88,14 @@ func TestImageGenerateWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Images.Generate(context.TODO(), openai.ImageGenerateParams{ - Prompt: openai.F("A cute baby sea otter"), - Model: openai.F(openai.ImageModelDallE2), - N: openai.F(int64(1)), - Quality: openai.F(openai.ImageGenerateParamsQualityStandard), - ResponseFormat: openai.F(openai.ImageGenerateParamsResponseFormatURL), - Size: openai.F(openai.ImageGenerateParamsSize256x256), - Style: openai.F(openai.ImageGenerateParamsStyleVivid), - User: openai.F("user-1234"), + Prompt: openai.String("A cute baby sea otter"), + Model: openai.ImageModelDallE2, + N: openai.Int(1), + Quality: openai.ImageGenerateParamsQualityStandard, + ResponseFormat: openai.ImageGenerateParamsResponseFormatURL, + Size: openai.ImageGenerateParamsSize256x256, + Style: openai.ImageGenerateParamsStyleVivid, + User: openai.String("user-1234"), }) if err != nil { var apierr *openai.Error diff --git a/internal/apierror/apierror.go b/internal/apierror/apierror.go index 81fa67c..cb17eae 100644 --- a/internal/apierror/apierror.go +++ b/internal/apierror/apierror.go @@ -8,43 +8,44 @@ import ( "net/http/httputil" "github.com/openai/openai-go/internal/apijson" + "github.com/openai/openai-go/packages/param" + "github.com/openai/openai-go/packages/resp" ) +// aliased to make param.APIUnion private when embedding +type apiunion = param.APIUnion + +// aliased to make param.APIObject private when embedding +type apiobject = param.APIObject + // Error represents an error that originates from the API, i.e. when a request is // made and the API returns a response with a HTTP status code. Other errors are // not wrapped by this SDK. type Error struct { - Code string `json:"code,required,nullable"` - Message string `json:"message,required"` - Param string `json:"param,required,nullable"` - Type string `json:"type,required"` - JSON errorJSON `json:"-"` + Code string `json:"code,omitzero,required,nullable"` + Message string `json:"message,omitzero,required"` + Param string `json:"param,omitzero,required,nullable"` + Type string `json:"type,omitzero,required"` + JSON struct { + Code resp.Field + Message resp.Field + Param resp.Field + Type resp.Field + raw string + } `json:"-"` StatusCode int Request *http.Request Response *http.Response } -// errorJSON contains the JSON metadata for the struct [Error] -type errorJSON struct { - Code apijson.Field - Message apijson.Field - Param apijson.Field - Type apijson.Field - raw string - ExtraFields map[string]apijson.Field -} - -func (r *Error) UnmarshalJSON(data []byte) (err error) { +func (r Error) RawJSON() string { return r.JSON.raw } +func (r *Error) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r errorJSON) RawJSON() string { - return r.raw -} - func (r *Error) Error() string { // Attempt to re-populate the response body - return fmt.Sprintf("%s \"%s\": %d %s %s", r.Request.Method, r.Request.URL, r.Response.StatusCode, http.StatusText(r.Response.StatusCode), r.JSON.RawJSON()) + return fmt.Sprintf("%s %q: %d %s %s", r.Request.Method, r.Request.URL, r.Response.StatusCode, http.StatusText(r.Response.StatusCode), r.JSON.raw) } func (r *Error) DumpRequest(body bool) []byte { diff --git a/internal/apifield/metadata.go b/internal/apifield/metadata.go new file mode 100644 index 0000000..4719290 --- /dev/null +++ b/internal/apifield/metadata.go @@ -0,0 +1,27 @@ +package apifield + +import "encoding/json" + +type ExplicitNull struct{} +type NeverOmitted struct{} +type CustomValue struct{ Override any } +type ResponseData json.RawMessage +type ExtraFields map[string]any + +func (ExplicitNull) IsNull() bool { return true } +func (NeverOmitted) IsNull() bool { return false } +func (v CustomValue) IsNull() bool { return v.Override == nil } +func (r ResponseData) IsNull() bool { return string(r) == `null` } +func (ExtraFields) IsNull() bool { return false } + +func (ExplicitNull) RawResponse() json.RawMessage { return nil } +func (NeverOmitted) RawResponse() json.RawMessage { return nil } +func (r ResponseData) RawResponse() json.RawMessage { return json.RawMessage(r) } +func (CustomValue) RawResponse() json.RawMessage { return nil } +func (ExtraFields) RawResponse() json.RawMessage { return nil } + +func (ExplicitNull) IsOverridden() (any, bool) { return nil, false } +func (NeverOmitted) IsOverridden() (any, bool) { return nil, false } +func (v CustomValue) IsOverridden() (any, bool) { return v.Override, true } +func (ResponseData) IsOverridden() (any, bool) { return nil, false } +func (ExtraFields) IsOverridden() (any, bool) { return nil, false } diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go index 148fcb5..ddd96d4 100644 --- a/internal/apiform/encoder.go +++ b/internal/apiform/encoder.go @@ -13,7 +13,8 @@ import ( "sync" "time" - "github.com/openai/openai-go/internal/param" + internalparam "github.com/openai/openai-go/internal/param" + "github.com/openai/openai-go/packages/param" ) var encoders sync.Map // map[encoderEntry]encoderFunc @@ -180,10 +181,14 @@ func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { } func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { - if t.Implements(reflect.TypeOf((*param.FieldLike)(nil)).Elem()) { + if t.Implements(reflect.TypeOf((*internalparam.FieldLike)(nil)).Elem()) { return e.newFieldTypeEncoder(t) } + if idx, ok := param.RichPrimitiveTypes[t]; ok { + return e.newRichFieldTypeEncoder(t, idx) + } + encoderFields := []encoderField{} extraEncoder := (*encoderField)(nil) diff --git a/internal/apiform/richparam.go b/internal/apiform/richparam.go new file mode 100644 index 0000000..227d999 --- /dev/null +++ b/internal/apiform/richparam.go @@ -0,0 +1,27 @@ +package apiform + +import ( + "github.com/openai/openai-go/packages/param" + "mime/multipart" + "reflect" +) + +// TODO(v2): verify this is correct, w.r.t. to null, overrides and omit +func (e *encoder) newRichFieldTypeEncoder(t reflect.Type, underlyingValueIdx []int) encoderFunc { + underlying := t.FieldByIndex(underlyingValueIdx) + primitiveEncoder := e.newPrimitiveTypeEncoder(underlying.Type) + return func(key string, value reflect.Value, writer *multipart.Writer) error { + if fielder, ok := value.Interface().(param.Fielder); ok { + if fielder.IsNull() { + return writer.WriteField(key, "null") + } else if ovr, ok := fielder.IsOverridden(); ok { + ovr := reflect.ValueOf(ovr) + encode := e.newTypeEncoder(ovr.Type()) + return encode(key, ovr, writer) + } else if !param.IsOmitted(fielder) { + return primitiveEncoder(key, value.FieldByName("V"), writer) + } + } + return nil + } +} diff --git a/internal/apijson/decoder.go b/internal/apijson/decoder.go index 68b7ed6..6885c96 100644 --- a/internal/apijson/decoder.go +++ b/internal/apijson/decoder.go @@ -433,9 +433,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc { status: valid, } } - if metadata := getSubField(value, inlineDecoder.idx, inlineDecoder.goname); metadata.IsValid() { - metadata.Set(reflect.ValueOf(meta)) - } + setSubField(value, inlineDecoder.idx, inlineDecoder.goname, meta) return err } @@ -489,9 +487,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc { } if explicit { - if metadata := getSubField(value, df.idx, df.goname); metadata.IsValid() { - metadata.Set(reflect.ValueOf(meta)) - } + setSubField(value, df.idx, df.goname, meta) } if !explicit { untypedExtraFields[fieldName] = meta diff --git a/internal/apijson/encoder.go b/internal/apijson/encoder.go index 71b3f4e..79bc698 100644 --- a/internal/apijson/encoder.go +++ b/internal/apijson/encoder.go @@ -381,7 +381,7 @@ func (e *encoder) encodeMapEntries(json []byte, v reflect.Value) ([]byte, error) return json, nil } -func (e *encoder) newMapEncoder(t reflect.Type) encoderFunc { +func (e *encoder) newMapEncoder(_ reflect.Type) encoderFunc { return func(value reflect.Value) ([]byte, error) { json := []byte("{}") var err error diff --git a/internal/apijson/field.go b/internal/apijson/field.go index 3ef207c..854d6dd 100644 --- a/internal/apijson/field.go +++ b/internal/apijson/field.go @@ -1,7 +1,5 @@ package apijson -import "reflect" - type status uint8 const ( @@ -23,19 +21,3 @@ func (j Field) IsNull() bool { return j.status <= null } func (j Field) IsMissing() bool { return j.status == missing } func (j Field) IsInvalid() bool { return j.status == invalid } func (j Field) Raw() string { return j.raw } - -func getSubField(root reflect.Value, index []int, name string) reflect.Value { - strct := root.FieldByIndex(index[:len(index)-1]) - if !strct.IsValid() { - panic("couldn't find encapsulating struct for field " + name) - } - meta := strct.FieldByName("JSON") - if !meta.IsValid() { - return reflect.Value{} - } - field := meta.FieldByName(name) - if !field.IsValid() { - return reflect.Value{} - } - return field -} diff --git a/internal/apijson/json_test.go b/internal/apijson/json_test.go index e656344..8a6aed2 100644 --- a/internal/apijson/json_test.go +++ b/internal/apijson/json_test.go @@ -86,8 +86,8 @@ type JSONFieldStruct struct { B int64 `json:"b"` C string `json:"c"` D string `json:"d"` - ExtraFields map[string]int64 `json:"-,extras"` - JSON JSONFieldStructJSON `json:"-,metadata"` + ExtraFields map[string]int64 `json:",extras"` + JSON JSONFieldStructJSON `json:",metadata"` } type JSONFieldStructJSON struct { @@ -112,13 +112,13 @@ type Union interface { } type Inline struct { - InlineField Primitives `json:"-,inline"` - JSON InlineJSON `json:"-,metadata"` + InlineField Primitives `json:",inline"` + JSON InlineJSON `json:",metadata"` } type InlineArray struct { - InlineField []string `json:"-,inline"` - JSON InlineJSON `json:"-,metadata"` + InlineField []string `json:",inline"` + JSON InlineJSON `json:",metadata"` } type InlineJSON struct { diff --git a/internal/apijson/port.go b/internal/apijson/port.go index 502ab77..b40013c 100644 --- a/internal/apijson/port.go +++ b/internal/apijson/port.go @@ -53,7 +53,7 @@ func Port(from any, to any) error { for i := 0; i < t.NumField(); i++ { field := t.Field(i) ptag, ok := parseJSONStructTag(field) - if !ok || ptag.name == "-" { + if !ok || ptag.name == "-" || ptag.name == "" { continue } values[ptag.name] = v.Field(i) diff --git a/internal/apijson/subfield.go b/internal/apijson/subfield.go new file mode 100644 index 0000000..0518845 --- /dev/null +++ b/internal/apijson/subfield.go @@ -0,0 +1,45 @@ +package apijson + +import ( + "github.com/openai/openai-go/packages/resp" + "reflect" +) + +func getSubField(root reflect.Value, index []int, name string) reflect.Value { + strct := root.FieldByIndex(index[:len(index)-1]) + if !strct.IsValid() { + panic("couldn't find encapsulating struct for field " + name) + } + meta := strct.FieldByName("JSON") + if !meta.IsValid() { + return reflect.Value{} + } + field := meta.FieldByName(name) + if !field.IsValid() { + return reflect.Value{} + } + return field +} + +var respFieldType = reflect.TypeOf(resp.Field{}) +var fieldType = reflect.TypeOf(Field{}) + +func setSubField(root reflect.Value, index []int, name string, meta Field) { + if metadata := getSubField(root, index, name); metadata.IsValid() { + if metadata.Type() == respFieldType { + var rf resp.Field + if meta.IsNull() { + rf = resp.NewNullField() + } else if meta.IsMissing() { + _ = rf + } else if meta.IsInvalid() { + rf = resp.NewInvalidField(meta.raw) + } else { + rf = resp.NewValidField(meta.raw) + } + metadata.Set(reflect.ValueOf(rf)) + } else if metadata.Type() == fieldType { + metadata.Set(reflect.ValueOf(meta)) + } + } +} diff --git a/internal/apiquery/encoder.go b/internal/apiquery/encoder.go index ed8c4a2..ab58dec 100644 --- a/internal/apiquery/encoder.go +++ b/internal/apiquery/encoder.go @@ -9,7 +9,8 @@ import ( "sync" "time" - "github.com/openai/openai-go/internal/param" + internalparam "github.com/openai/openai-go/internal/param" + "github.com/openai/openai-go/packages/param" ) var encoders sync.Map // map[reflect.Type]encoderFunc @@ -85,6 +86,7 @@ func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc { if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { return e.newTimeTypeEncoder(t) } + if !e.root && t.Implements(reflect.TypeOf((*json.Marshaler)(nil)).Elem()) { return marshalerEncoder } @@ -115,10 +117,14 @@ func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc { } func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { - if t.Implements(reflect.TypeOf((*param.FieldLike)(nil)).Elem()) { + if t.Implements(reflect.TypeOf((*internalparam.FieldLike)(nil)).Elem()) { return e.newFieldTypeEncoder(t) } + if idx, ok := param.RichPrimitiveTypes[t]; ok { + return e.newRichFieldTypeEncoder(t, idx) + } + encoderFields := []encoderField{} // This helper allows us to recursively collect field encoders into a flat diff --git a/internal/apiquery/query_test.go b/internal/apiquery/query_test.go index 1e740d6..06e0951 100644 --- a/internal/apiquery/query_test.go +++ b/internal/apiquery/query_test.go @@ -1,6 +1,7 @@ package apiquery import ( + "github.com/openai/openai-go/packages/param" "net/url" "testing" "time" @@ -101,6 +102,10 @@ type DeeplyNested3 struct { D *string `query:"d"` } +type RichPrimitives struct { + A param.String `query:"a"` +} + var tests = map[string]struct { enc string val interface{} @@ -320,6 +325,14 @@ var tests = map[string]struct { }, QuerySettings{NestedFormat: NestedQueryFormatDots}, }, + + "rich_primitives": { + `a=hello`, + RichPrimitives{ + A: param.String{V: "hello"}, + }, + QuerySettings{}, + }, } func TestEncode(t *testing.T) { diff --git a/internal/apiquery/richparam.go b/internal/apiquery/richparam.go new file mode 100644 index 0000000..9e6b6e4 --- /dev/null +++ b/internal/apiquery/richparam.go @@ -0,0 +1,29 @@ +package apiquery + +import ( + "fmt" + "github.com/openai/openai-go/packages/param" + "reflect" +) + +// TODO(v2): verify this is correct w.r.t. to null, override and omit handling +func (e *encoder) newRichFieldTypeEncoder(t reflect.Type, underlyingValueIdx []int) encoderFunc { + underlying := t.FieldByIndex(underlyingValueIdx) + primitiveEncoder := e.newPrimitiveTypeEncoder(underlying.Type) + return func(key string, value reflect.Value) []Pair { + if fielder, ok := value.Interface().(param.Fielder); ok { + if fielder.IsNull() { + return []Pair{{key, "null"}} + } else if ovr, ok := fielder.IsOverridden(); ok { + ovr := reflect.ValueOf(ovr) + encode := e.newTypeEncoder(ovr.Type()) + return encode(key, ovr) + } else if !param.IsOmitted(fielder) { + res := primitiveEncoder(key, value.FieldByName("V")) + fmt.Printf("%#v\n", res) + return res + } + } + return nil + } +} diff --git a/internal/encoding/json/decode.go b/internal/encoding/json/decode.go new file mode 100644 index 0000000..9321433 --- /dev/null +++ b/internal/encoding/json/decode.go @@ -0,0 +1,1324 @@ +// Vendored from Go 1.24.0-pre-release +// To find alterations, check package shims, and comments beginning in SHIM(). +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Represents JSON data structure using native Go types: booleans, floats, +// strings, arrays, and maps. + +package json + +import ( + "encoding" + "encoding/base64" + "fmt" + "github.com/openai/openai-go/internal/encoding/json/shims" + "reflect" + "strconv" + "strings" + "unicode" + "unicode/utf16" + "unicode/utf8" + _ "unsafe" // for linkname +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. If v is nil or not a pointer, +// Unmarshal returns an [InvalidUnmarshalError]. +// +// Unmarshal uses the inverse of the encodings that +// [Marshal] uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a value implementing [Unmarshaler], +// Unmarshal calls that value's [Unmarshaler.UnmarshalJSON] method, including +// when the input is a JSON null. +// Otherwise, if the value implements [encoding.TextUnmarshaler] +// and the input is a JSON quoted string, Unmarshal calls +// [encoding.TextUnmarshaler.UnmarshalText] with the unquoted form of the string. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by [Marshal] (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. By +// default, object keys which don't have a corresponding struct field are +// ignored (see [Decoder.DisallowUnknownFields] for an alternative). +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// - bool, for JSON booleans +// - float64, for JSON numbers +// - string, for JSON strings +// - []any, for JSON arrays +// - map[string]any, for JSON objects +// - nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a map, Unmarshal first establishes a map to +// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal +// reuses the existing map, keeping existing entries. Unmarshal then stores +// key-value pairs from the JSON object into the map. The map's key type must +// either be any string type, an integer, or implement [encoding.TextUnmarshaler]. +// +// If the JSON-encoded data contain a syntax error, Unmarshal returns a [SyntaxError]. +// +// If a JSON value is not appropriate for a given target type, +// or if a JSON number overflows the target type, Unmarshal +// skips that field and completes the unmarshaling as best it can. +// If no more serious errors are encountered, Unmarshal returns +// an [UnmarshalTypeError] describing the earliest such error. In any +// case, it's not guaranteed that all the remaining fields following +// the problematic one will be unmarshaled into the target object. +// +// The JSON null value unmarshals into an interface, map, pointer, or slice +// by setting that Go value to nil. Because null is often used in JSON to mean +// “not present,” unmarshaling a JSON null into any other Go type has no effect +// on the value and produces no error. +// +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +func Unmarshal(data []byte, v any) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + var d decodeState + err := checkValid(data, &d.scan) + if err != nil { + return err + } + + d.init(data) + return d.unmarshal(v) +} + +// Unmarshaler is the interface implemented by types +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +// +// By convention, to approximate the behavior of [Unmarshal] itself, +// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes + Struct string // name of the struct type containing the field + Field string // the full path from root node to the field, include embedded struct +} + +func (e *UnmarshalTypeError) Error() string { + if e.Struct != "" || e.Field != "" { + return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String() + } + return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() +} + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// +// Deprecated: No longer used; kept for compatibility. +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() +} + +// An InvalidUnmarshalError describes an invalid argument passed to [Unmarshal]. +// (The argument to [Unmarshal] must be a non-nil pointer.) +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Pointer { + return "json: Unmarshal(non-pointer " + e.Type.String() + ")" + } + return "json: Unmarshal(nil " + e.Type.String() + ")" +} + +func (d *decodeState) unmarshal(v any) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Pointer || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + + d.scan.reset() + d.scanWhile(scanSkipSpace) + // We decode rv not rv.Elem because the Unmarshaler interface + // test must be applied at the top level of the value. + err := d.value(rv) + if err != nil { + return d.addErrorContext(err) + } + return d.savedError +} + +// A Number represents a JSON number literal. +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +// An errorContext provides context for type errors during decoding. +type errorContext struct { + Struct reflect.Type + FieldStack []string +} + +// decodeState represents the state while decoding a JSON value. +type decodeState struct { + data []byte + off int // next read offset in data + opcode int // last read result + scan scanner + errorContext *errorContext + savedError error + useNumber bool + disallowUnknownFields bool +} + +// readIndex returns the position of the last byte read. +func (d *decodeState) readIndex() int { + return d.off - 1 +} + +// phasePanicMsg is used as a panic message when we end up with something that +// shouldn't happen. It can indicate a bug in the JSON decoder, or that +// something is editing the data slice while the decoder executes. +const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?" + +func (d *decodeState) init(data []byte) *decodeState { + d.data = data + d.off = 0 + d.savedError = nil + if d.errorContext != nil { + d.errorContext.Struct = nil + // Reuse the allocated space for the FieldStack slice. + d.errorContext.FieldStack = d.errorContext.FieldStack[:0] + } + return d +} + +// saveError saves the first err it is called with, +// for reporting at the end of the unmarshal. +func (d *decodeState) saveError(err error) { + if d.savedError == nil { + d.savedError = d.addErrorContext(err) + } +} + +// addErrorContext returns a new error enhanced with information from d.errorContext +func (d *decodeState) addErrorContext(err error) error { + if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) { + switch err := err.(type) { + case *UnmarshalTypeError: + err.Struct = d.errorContext.Struct.Name() + fieldStack := d.errorContext.FieldStack + if err.Field != "" { + fieldStack = append(fieldStack, err.Field) + } + err.Field = strings.Join(fieldStack, ".") + } + } + return err +} + +// skip scans to the end of what was started. +func (d *decodeState) skip() { + s, data, i := &d.scan, d.data, d.off + depth := len(s.parseState) + for { + op := s.step(s, data[i]) + i++ + if len(s.parseState) < depth { + d.off = i + d.opcode = op + return + } + } +} + +// scanNext processes the byte at d.data[d.off]. +func (d *decodeState) scanNext() { + if d.off < len(d.data) { + d.opcode = d.scan.step(&d.scan, d.data[d.off]) + d.off++ + } else { + d.opcode = d.scan.eof() + d.off = len(d.data) + 1 // mark processed EOF with len+1 + } +} + +// scanWhile processes bytes in d.data[d.off:] until it +// receives a scan code not equal to op. +func (d *decodeState) scanWhile(op int) { + s, data, i := &d.scan, d.data, d.off + for i < len(data) { + newOp := s.step(s, data[i]) + i++ + if newOp != op { + d.opcode = newOp + d.off = i + return + } + } + + d.off = len(data) + 1 // mark processed EOF with len+1 + d.opcode = d.scan.eof() +} + +// rescanLiteral is similar to scanWhile(scanContinue), but it specialises the +// common case where we're decoding a literal. The decoder scans the input +// twice, once for syntax errors and to check the length of the value, and the +// second to perform the decoding. +// +// Only in the second step do we use decodeState to tokenize literals, so we +// know there aren't any syntax errors. We can take advantage of that knowledge, +// and scan a literal's bytes much more quickly. +func (d *decodeState) rescanLiteral() { + data, i := d.data, d.off +Switch: + switch data[i-1] { + case '"': // string + for ; i < len(data); i++ { + switch data[i] { + case '\\': + i++ // escaped char + case '"': + i++ // tokenize the closing quote too + break Switch + } + } + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number + for ; i < len(data); i++ { + switch data[i] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '.', 'e', 'E', '+', '-': + default: + break Switch + } + } + case 't': // true + i += len("rue") + case 'f': // false + i += len("alse") + case 'n': // null + i += len("ull") + } + if i < len(data) { + d.opcode = stateEndValue(&d.scan, data[i]) + } else { + d.opcode = scanEnd + } + d.off = i + 1 +} + +// value consumes a JSON value from d.data[d.off-1:], decoding into v, and +// reads the following byte ahead. If v is invalid, the value is discarded. +// The first byte of the value has been read already. +func (d *decodeState) value(v reflect.Value) error { + switch d.opcode { + default: + panic(phasePanicMsg) + + case scanBeginArray: + if v.IsValid() { + if err := d.array(v); err != nil { + return err + } + } else { + d.skip() + } + d.scanNext() + + case scanBeginObject: + if v.IsValid() { + if err := d.object(v); err != nil { + return err + } + } else { + d.skip() + } + d.scanNext() + + case scanBeginLiteral: + // All bytes inside literal return scanContinue op code. + start := d.readIndex() + d.rescanLiteral() + + if v.IsValid() { + if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil { + return err + } + } + } + return nil +} + +type unquotedValue struct{} + +// valueQuoted is like value but decodes a +// quoted string literal or literal null into an interface value. +// If it finds anything other than a quoted string literal or null, +// valueQuoted returns unquotedValue{}. +func (d *decodeState) valueQuoted() any { + switch d.opcode { + default: + panic(phasePanicMsg) + + case scanBeginArray, scanBeginObject: + d.skip() + d.scanNext() + + case scanBeginLiteral: + v := d.literalInterface() + switch v.(type) { + case nil, string: + return v + } + } + return unquotedValue{} +} + +// indirect walks down v allocating pointers as needed, +// until it gets to a non-pointer. +// If it encounters an Unmarshaler, indirect stops and returns that. +// If decodingNull is true, indirect stops at the first settable pointer so it +// can be set to nil. +func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // Issue #24153 indicates that it is generally not a guaranteed property + // that you may round-trip a reflect.Value by calling Value.Addr().Elem() + // and expect the value to still be settable for values derived from + // unexported embedded struct fields. + // + // The logic below effectively does this when it first addresses the value + // (to satisfy possible pointer methods) and continues to dereference + // subsequent pointers as necessary. + // + // After the first round-trip, we set v back to the original value to + // preserve the original RW flags contained in reflect.Value. + v0 := v + haveAddr := false + + // If v is a named type and is addressable, + // start with its address, so that if the type has pointer methods, + // we find them. + if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() { + haveAddr = true + v = v.Addr() + } + for { + // Load value from interface, but only if the result will be + // usefully addressable. + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) { + haveAddr = false + v = e + continue + } + } + + if v.Kind() != reflect.Pointer { + break + } + + if decodingNull && v.CanSet() { + break + } + + // Prevent infinite loop if v is an interface pointing to its own address: + // var v any + // v = &v + if v.Elem().Kind() == reflect.Interface && v.Elem().Elem().Equal(v) { + v = v.Elem() + break + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + if v.Type().NumMethod() > 0 && v.CanInterface() { + if u, ok := v.Interface().(Unmarshaler); ok { + return u, nil, reflect.Value{} + } + if !decodingNull { + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, reflect.Value{} + } + } + } + + if haveAddr { + v = v0 // restore original value after round-trip Value.Addr().Elem() + haveAddr = false + } else { + v = v.Elem() + } + } + return nil, nil, v +} + +// array consumes an array from d.data[d.off-1:], decoding into v. +// The first byte of the array ('[') has been read already. +func (d *decodeState) array(v reflect.Value) error { + // Check for unmarshaler. + u, ut, pv := indirect(v, false) + if u != nil { + start := d.readIndex() + d.skip() + return u.UnmarshalJSON(d.data[start:d.off]) + } + if ut != nil { + d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + } + v = pv + + // Check type of target. + switch v.Kind() { + case reflect.Interface: + if v.NumMethod() == 0 { + // Decoding into nil interface? Switch to non-reflect code. + ai := d.arrayInterface() + v.Set(reflect.ValueOf(ai)) + return nil + } + // Otherwise it's invalid. + fallthrough + default: + d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + case reflect.Array, reflect.Slice: + break + } + + i := 0 + for { + // Look ahead for ] - can only happen on first iteration. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndArray { + break + } + + // Expand slice length, growing the slice if necessary. + if v.Kind() == reflect.Slice { + if i >= v.Cap() { + v.Grow(1) + } + if i >= v.Len() { + v.SetLen(i + 1) + } + } + + if i < v.Len() { + // Decode into element. + if err := d.value(v.Index(i)); err != nil { + return err + } + } else { + // Ran out of fixed array: skip. + if err := d.value(reflect.Value{}); err != nil { + return err + } + } + i++ + + // Next token must be , or ]. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndArray { + break + } + if d.opcode != scanArrayValue { + panic(phasePanicMsg) + } + } + + if i < v.Len() { + if v.Kind() == reflect.Array { + for ; i < v.Len(); i++ { + v.Index(i).SetZero() // zero remainder of array + } + } else { + v.SetLen(i) // truncate the slice + } + } + if i == 0 && v.Kind() == reflect.Slice { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } + return nil +} + +var nullLiteral = []byte("null") + +// SHIM(reflect): reflect.TypeFor[T]() reflect.T +var textUnmarshalerType = shims.TypeFor[encoding.TextUnmarshaler]() + +// object consumes an object from d.data[d.off-1:], decoding into v. +// The first byte ('{') of the object has been read already. +func (d *decodeState) object(v reflect.Value) error { + // Check for unmarshaler. + u, ut, pv := indirect(v, false) + if u != nil { + start := d.readIndex() + d.skip() + return u.UnmarshalJSON(d.data[start:d.off]) + } + if ut != nil { + d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + } + v = pv + t := v.Type() + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + oi := d.objectInterface() + v.Set(reflect.ValueOf(oi)) + return nil + } + + var fields structFields + + // Check type of target: + // struct or + // map[T1]T2 where T1 is string, an integer type, + // or an encoding.TextUnmarshaler + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind, have an integer kind, + // or be an encoding.TextUnmarshaler. + switch t.Key().Kind() { + case reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + default: + if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) + d.skip() + return nil + } + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + fields = cachedTypeFields(t) + // ok + default: + d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) + d.skip() + return nil + } + + var mapElem reflect.Value + var origErrorContext errorContext + if d.errorContext != nil { + origErrorContext = *d.errorContext + } + + for { + // Read opening " of string key or closing }. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if d.opcode != scanBeginLiteral { + panic(phasePanicMsg) + } + + // Read key. + start := d.readIndex() + d.rescanLiteral() + item := d.data[start:d.readIndex()] + key, ok := unquoteBytes(item) + if !ok { + panic(phasePanicMsg) + } + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := t.Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.SetZero() + } + subv = mapElem + } else { + f := fields.byExactName[string(key)] + if f == nil { + f = fields.byFoldedName[string(foldName(key))] + } + if f != nil { + subv = v + destring = f.quoted + if d.errorContext == nil { + d.errorContext = new(errorContext) + } + for i, ind := range f.index { + if subv.Kind() == reflect.Pointer { + if subv.IsNil() { + // If a struct embeds a pointer to an unexported type, + // it is not possible to set a newly allocated value + // since the field is unexported. + // + // See https://golang.org/issue/21357 + if !subv.CanSet() { + d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem())) + // Invalidate subv to ensure d.value(subv) skips over + // the JSON value without assigning it to subv. + subv = reflect.Value{} + destring = false + break + } + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + if i < len(f.index)-1 { + d.errorContext.FieldStack = append( + d.errorContext.FieldStack, + subv.Type().Field(ind).Name, + ) + } + subv = subv.Field(ind) + } + d.errorContext.Struct = t + d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) + } else if d.disallowUnknownFields { + d.saveError(fmt.Errorf("json: unknown field %q", key)) + } + } + + // Read : before value. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode != scanObjectKey { + panic(phasePanicMsg) + } + d.scanWhile(scanSkipSpace) + + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + if err := d.literalStore(nullLiteral, subv, false); err != nil { + return err + } + case string: + if err := d.literalStore([]byte(qv), subv, true); err != nil { + return err + } + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + if err := d.value(subv); err != nil { + return err + } + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := t.Key() + var kv reflect.Value + if reflect.PointerTo(kt).Implements(textUnmarshalerType) { + kv = reflect.New(kt) + if err := d.literalStore(item, kv, true); err != nil { + return err + } + kv = kv.Elem() + } else { + switch kt.Kind() { + case reflect.String: + kv = reflect.New(kt).Elem() + kv.SetString(string(key)) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + s := string(key) + n, err := strconv.ParseInt(s, 10, 64) + // SHIM(reflect): reflect.Type.OverflowInt(int64) bool + okt := shims.OverflowableType{Type: kt} + if err != nil || okt.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) + break + } + kv = reflect.New(kt).Elem() + kv.SetInt(n) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + s := string(key) + n, err := strconv.ParseUint(s, 10, 64) + // SHIM(reflect): reflect.Type.OverflowUint(uint64) bool + okt := shims.OverflowableType{Type: kt} + if err != nil || okt.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) + break + } + kv = reflect.New(kt).Elem() + kv.SetUint(n) + default: + panic("json: Unexpected key type") // should never occur + } + } + if kv.IsValid() { + v.SetMapIndex(kv, subv) + } + } + + // Next token must be , or }. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.errorContext != nil { + // Reset errorContext to its original state. + // Keep the same underlying array for FieldStack, to reuse the + // space and avoid unnecessary allocs. + d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)] + d.errorContext.Struct = origErrorContext.Struct + } + if d.opcode == scanEndObject { + break + } + if d.opcode != scanObjectValue { + panic(phasePanicMsg) + } + } + return nil +} + +// convertNumber converts the number literal s to a float64 or a Number +// depending on the setting of d.useNumber. +func (d *decodeState) convertNumber(s string) (any, error) { + if d.useNumber { + return Number(s), nil + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + // SHIM(reflect): reflect.TypeFor[T]() reflect.Type + return nil, &UnmarshalTypeError{Value: "number " + s, Type: shims.TypeFor[float64](), Offset: int64(d.off)} + } + return f, nil +} + +// SHIM(reflect): TypeFor[T]() reflect.Type +var numberType = shims.TypeFor[Number]() + +// literalStore decodes a literal stored in item into v. +// +// fromQuoted indicates whether this literal came from unwrapping a +// string from the ",string" struct tag option. this is used only to +// produce more helpful error messages. +func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error { + // Check for unmarshaler. + if len(item) == 0 { + // Empty string given. + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return nil + } + isNull := item[0] == 'n' // null + u, ut, pv := indirect(v, isNull) + if u != nil { + return u.UnmarshalJSON(item) + } + if ut != nil { + if item[0] != '"' { + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return nil + } + val := "number" + switch item[0] { + case 'n': + val = "null" + case 't', 'f': + val = "bool" + } + d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())}) + return nil + } + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + return ut.UnmarshalText(s) + } + + v = pv + + switch c := item[0]; c { + case 'n': // null + // The main parser checks that only true and false can reach here, + // but if this was a quoted string input, it could be anything. + if fromQuoted && string(item) != "null" { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + break + } + switch v.Kind() { + case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice: + v.SetZero() + // otherwise, ignore null for primitives/string + } + case 't', 'f': // true, false + value := item[0] == 't' + // The main parser checks that only true and false can reach here, + // but if this was a quoted string input, it could be anything. + if fromQuoted && string(item) != "true" && string(item) != "false" { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + break + } + switch v.Kind() { + default: + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) + } + case reflect.Bool: + v.SetBool(value) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(value)) + } else { + d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) + } + } + + case '"': // string + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + switch v.Kind() { + default: + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + case reflect.Slice: + if v.Type().Elem().Kind() != reflect.Uint8 { + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) + n, err := base64.StdEncoding.Decode(b, s) + if err != nil { + d.saveError(err) + break + } + v.SetBytes(b[:n]) + case reflect.String: + t := string(s) + if v.Type() == numberType && !isValidNumber(t) { + return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item) + } + v.SetString(t) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(string(s))) + } else { + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + } + } + + default: // number + if c != '-' && (c < '0' || c > '9') { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + switch v.Kind() { + default: + if v.Kind() == reflect.String && v.Type() == numberType { + // s must be a valid number, because it's + // already been tokenized. + v.SetString(string(item)) + break + } + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) + case reflect.Interface: + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + break + } + if v.NumMethod() != 0 { + d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.Set(reflect.ValueOf(n)) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(string(item), 10, 64) + if err != nil || v.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetInt(n) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(string(item), 10, 64) + if err != nil || v.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetUint(n) + + case reflect.Float32, reflect.Float64: + n, err := strconv.ParseFloat(string(item), v.Type().Bits()) + if err != nil || v.OverflowFloat(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetFloat(n) + } + } + return nil +} + +// The xxxInterface routines build up a value to be stored +// in an empty interface. They are not strictly necessary, +// but they avoid the weight of reflection in this common case. + +// valueInterface is like value but returns any. +func (d *decodeState) valueInterface() (val any) { + switch d.opcode { + default: + panic(phasePanicMsg) + case scanBeginArray: + val = d.arrayInterface() + d.scanNext() + case scanBeginObject: + val = d.objectInterface() + d.scanNext() + case scanBeginLiteral: + val = d.literalInterface() + } + return +} + +// arrayInterface is like array but returns []any. +func (d *decodeState) arrayInterface() []any { + var v = make([]any, 0) + for { + // Look ahead for ] - can only happen on first iteration. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndArray { + break + } + + v = append(v, d.valueInterface()) + + // Next token must be , or ]. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndArray { + break + } + if d.opcode != scanArrayValue { + panic(phasePanicMsg) + } + } + return v +} + +// objectInterface is like object but returns map[string]any. +func (d *decodeState) objectInterface() map[string]any { + m := make(map[string]any) + for { + // Read opening " of string key or closing }. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if d.opcode != scanBeginLiteral { + panic(phasePanicMsg) + } + + // Read string key. + start := d.readIndex() + d.rescanLiteral() + item := d.data[start:d.readIndex()] + key, ok := unquote(item) + if !ok { + panic(phasePanicMsg) + } + + // Read : before value. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode != scanObjectKey { + panic(phasePanicMsg) + } + d.scanWhile(scanSkipSpace) + + // Read value. + m[key] = d.valueInterface() + + // Next token must be , or }. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndObject { + break + } + if d.opcode != scanObjectValue { + panic(phasePanicMsg) + } + } + return m +} + +// literalInterface consumes and returns a literal from d.data[d.off-1:] and +// it reads the following byte ahead. The first byte of the literal has been +// read already (that's how the caller knows it's a literal). +func (d *decodeState) literalInterface() any { + // All bytes inside literal return scanContinue op code. + start := d.readIndex() + d.rescanLiteral() + + item := d.data[start:d.readIndex()] + + switch c := item[0]; c { + case 'n': // null + return nil + + case 't', 'f': // true, false + return c == 't' + + case '"': // string + s, ok := unquote(item) + if !ok { + panic(phasePanicMsg) + } + return s + + default: // number + if c != '-' && (c < '0' || c > '9') { + panic(phasePanicMsg) + } + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + } + return n + } +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + var r rune + for _, c := range s[2:6] { + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = c - 'a' + 10 + case 'A' <= c && c <= 'F': + c = c - 'A' + 10 + default: + return -1 + } + r = r*16 + rune(c) + } + return r +} + +// unquote converts a quoted JSON string literal s into an actual string t. +// The rules are different than for Go, so cannot use strconv.Unquote. +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) + t = string(s) + return +} + +// unquoteBytes should be an internal detail, +// but widely used packages access it using linkname. +// Notable members of the hall of shame include: +// - github.com/bytedance/sonic +// +// Do not remove or change the type signature. +// See go.dev/issue/67401. +// +//go:linkname unquoteBytes +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } + s = s[1 : len(s)-1] + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} diff --git a/internal/encoding/json/encode.go b/internal/encoding/json/encode.go new file mode 100644 index 0000000..d42df9a --- /dev/null +++ b/internal/encoding/json/encode.go @@ -0,0 +1,1349 @@ +// Vendored from Go 1.24.0-pre-release +// To find alterations, check package shims, and comments beginning in SHIM(). +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package json implements encoding and decoding of JSON as defined in +// RFC 7159. The mapping between JSON and Go values is described +// in the documentation for the Marshal and Unmarshal functions. +// +// See "JSON and Go" for an introduction to this package: +// https://golang.org/doc/articles/json_and_go.html +package json + +import ( + "bytes" + "cmp" + "encoding" + "encoding/base64" + "fmt" + "github.com/openai/openai-go/internal/encoding/json/shims" + "math" + "reflect" + "slices" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" + _ "unsafe" // for linkname +) + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements [Marshaler] +// and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] +// to produce JSON. If no [Marshaler.MarshalJSON] method is present but the +// value implements [encoding.TextMarshaler] instead, Marshal calls +// [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// [Unmarshaler.UnmarshalJSON]. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and [Number] values encode as JSON numbers. +// NaN and +/-Inf values will return an [UnsupportedValueError]. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// So that the JSON will be safe to embed inside HTML