responses_options.go

  1// Package openai provides an implementation of the fantasy AI SDK for OpenAI's language models.
  2package openai
  3
  4import (
  5	"encoding/json"
  6	"slices"
  7
  8	"charm.land/fantasy"
  9)
 10
 11// Global type identifiers for OpenAI Responses API-specific data.
 12const (
 13	TypeResponsesProviderOptions   = Name + ".responses.options"
 14	TypeResponsesReasoningMetadata = Name + ".responses.reasoning_metadata"
 15)
 16
 17// Register OpenAI Responses API-specific types with the global registry.
 18func init() {
 19	fantasy.RegisterProviderType(TypeResponsesProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
 20		var v ResponsesProviderOptions
 21		if err := json.Unmarshal(data, &v); err != nil {
 22			return nil, err
 23		}
 24		return &v, nil
 25	})
 26	fantasy.RegisterProviderType(TypeResponsesReasoningMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
 27		var v ResponsesReasoningMetadata
 28		if err := json.Unmarshal(data, &v); err != nil {
 29			return nil, err
 30		}
 31		return &v, nil
 32	})
 33}
 34
 35// ResponsesReasoningMetadata represents reasoning metadata for OpenAI Responses API.
 36type ResponsesReasoningMetadata struct {
 37	ItemID           string   `json:"item_id"`
 38	EncryptedContent *string  `json:"encrypted_content"`
 39	Summary          []string `json:"summary"`
 40}
 41
 42// Options implements the ProviderOptions interface.
 43func (*ResponsesReasoningMetadata) Options() {}
 44
 45// MarshalJSON implements custom JSON marshaling with type info for ResponsesReasoningMetadata.
 46func (m ResponsesReasoningMetadata) MarshalJSON() ([]byte, error) {
 47	type plain ResponsesReasoningMetadata
 48	return fantasy.MarshalProviderType(TypeResponsesReasoningMetadata, plain(m))
 49}
 50
 51// UnmarshalJSON implements custom JSON unmarshaling with type info for ResponsesReasoningMetadata.
 52func (m *ResponsesReasoningMetadata) UnmarshalJSON(data []byte) error {
 53	type plain ResponsesReasoningMetadata
 54	var p plain
 55	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
 56		return err
 57	}
 58	*m = ResponsesReasoningMetadata(p)
 59	return nil
 60}
 61
 62// IncludeType represents the type of content to include for OpenAI Responses API.
 63type IncludeType string
 64
 65const (
 66	// IncludeReasoningEncryptedContent includes encrypted reasoning content.
 67	IncludeReasoningEncryptedContent IncludeType = "reasoning.encrypted_content"
 68	// IncludeFileSearchCallResults includes file search call results.
 69	IncludeFileSearchCallResults IncludeType = "file_search_call.results"
 70	// IncludeMessageOutputTextLogprobs includes message output text log probabilities.
 71	IncludeMessageOutputTextLogprobs IncludeType = "message.output_text.logprobs"
 72)
 73
 74// ServiceTier represents the service tier for OpenAI Responses API.
 75type ServiceTier string
 76
 77const (
 78	// ServiceTierAuto represents the auto service tier.
 79	ServiceTierAuto ServiceTier = "auto"
 80	// ServiceTierFlex represents the flex service tier.
 81	ServiceTierFlex ServiceTier = "flex"
 82	// ServiceTierPriority represents the priority service tier.
 83	ServiceTierPriority ServiceTier = "priority"
 84)
 85
 86// TextVerbosity represents the text verbosity level for OpenAI Responses API.
 87type TextVerbosity string
 88
 89const (
 90	// TextVerbosityLow represents low text verbosity.
 91	TextVerbosityLow TextVerbosity = "low"
 92	// TextVerbosityMedium represents medium text verbosity.
 93	TextVerbosityMedium TextVerbosity = "medium"
 94	// TextVerbosityHigh represents high text verbosity.
 95	TextVerbosityHigh TextVerbosity = "high"
 96)
 97
 98// ResponsesProviderOptions represents additional options for OpenAI Responses API.
 99type ResponsesProviderOptions struct {
100	Include           []IncludeType    `json:"include"`
101	Instructions      *string          `json:"instructions"`
102	Logprobs          any              `json:"logprobs"`
103	MaxToolCalls      *int64           `json:"max_tool_calls"`
104	Metadata          map[string]any   `json:"metadata"`
105	ParallelToolCalls *bool            `json:"parallel_tool_calls"`
106	PromptCacheKey    *string          `json:"prompt_cache_key"`
107	ReasoningEffort   *ReasoningEffort `json:"reasoning_effort"`
108	ReasoningSummary  *string          `json:"reasoning_summary"`
109	SafetyIdentifier  *string          `json:"safety_identifier"`
110	ServiceTier       *ServiceTier     `json:"service_tier"`
111	StrictJSONSchema  *bool            `json:"strict_json_schema"`
112	TextVerbosity     *TextVerbosity   `json:"text_verbosity"`
113	User              *string          `json:"user"`
114}
115
116// Options implements the ProviderOptions interface.
117func (*ResponsesProviderOptions) Options() {}
118
119// MarshalJSON implements custom JSON marshaling with type info for ResponsesProviderOptions.
120func (o ResponsesProviderOptions) MarshalJSON() ([]byte, error) {
121	type plain ResponsesProviderOptions
122	return fantasy.MarshalProviderType(TypeResponsesProviderOptions, plain(o))
123}
124
125// UnmarshalJSON implements custom JSON unmarshaling with type info for ResponsesProviderOptions.
126func (o *ResponsesProviderOptions) UnmarshalJSON(data []byte) error {
127	type plain ResponsesProviderOptions
128	var p plain
129	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
130		return err
131	}
132	*o = ResponsesProviderOptions(p)
133	return nil
134}
135
136// responsesReasoningModelIds lists the model IDs that support reasoning for OpenAI Responses API.
137var responsesReasoningModelIDs = []string{
138	"o1",
139	"o1-2024-12-17",
140	"o3-mini",
141	"o3-mini-2025-01-31",
142	"o3",
143	"o3-2025-04-16",
144	"o4-mini",
145	"o4-mini-2025-04-16",
146	"codex-mini-latest",
147	"gpt-5",
148	"gpt-5-2025-08-07",
149	"gpt-5-mini",
150	"gpt-5-mini-2025-08-07",
151	"gpt-5-nano",
152	"gpt-5-nano-2025-08-07",
153	"gpt-5-codex",
154	"gpt-5.1",
155	"gpt-5.1-codex",
156	"gpt-5.1-codex-mini",
157}
158
159// responsesModelIds lists all model IDs for OpenAI Responses API.
160var responsesModelIDs = append([]string{
161	"gpt-4.1",
162	"gpt-4.1-2025-04-14",
163	"gpt-4.1-mini",
164	"gpt-4.1-mini-2025-04-14",
165	"gpt-4.1-nano",
166	"gpt-4.1-nano-2025-04-14",
167	"gpt-4o",
168	"gpt-4o-2024-05-13",
169	"gpt-4o-2024-08-06",
170	"gpt-4o-2024-11-20",
171	"gpt-4o-mini",
172	"gpt-4o-mini-2024-07-18",
173	"gpt-4-turbo",
174	"gpt-4-turbo-2024-04-09",
175	"gpt-4-turbo-preview",
176	"gpt-4-0125-preview",
177	"gpt-4-1106-preview",
178	"gpt-4",
179	"gpt-4-0613",
180	"gpt-4.5-preview",
181	"gpt-4.5-preview-2025-02-27",
182	"gpt-3.5-turbo-0125",
183	"gpt-3.5-turbo",
184	"gpt-3.5-turbo-1106",
185	"chatgpt-4o-latest",
186	"gpt-5-chat-latest",
187}, responsesReasoningModelIDs...)
188
189// NewResponsesProviderOptions creates new provider options for OpenAI Responses API.
190func NewResponsesProviderOptions(opts *ResponsesProviderOptions) fantasy.ProviderOptions {
191	return fantasy.ProviderOptions{
192		Name: opts,
193	}
194}
195
196// ParseResponsesOptions parses provider options from a map for OpenAI Responses API.
197func ParseResponsesOptions(data map[string]any) (*ResponsesProviderOptions, error) {
198	var options ResponsesProviderOptions
199	if err := fantasy.ParseOptions(data, &options); err != nil {
200		return nil, err
201	}
202	return &options, nil
203}
204
205// IsResponsesModel checks if a model ID is a Responses API model for OpenAI.
206func IsResponsesModel(modelID string) bool {
207	return slices.Contains(responsesModelIDs, modelID)
208}
209
210// IsResponsesReasoningModel checks if a model ID is a Responses API reasoning model for OpenAI.
211func IsResponsesReasoningModel(modelID string) bool {
212	return slices.Contains(responsesReasoningModelIDs, modelID)
213}