provider_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
  7	"charm.land/fantasy"
  8	"github.com/openai/openai-go/v2"
  9)
 10
 11// ReasoningEffort represents the reasoning effort level for OpenAI models.
 12type ReasoningEffort string
 13
 14const (
 15	// ReasoningEffortMinimal represents minimal reasoning effort.
 16	ReasoningEffortMinimal ReasoningEffort = "minimal"
 17	// ReasoningEffortLow represents low reasoning effort.
 18	ReasoningEffortLow ReasoningEffort = "low"
 19	// ReasoningEffortMedium represents medium reasoning effort.
 20	ReasoningEffortMedium ReasoningEffort = "medium"
 21	// ReasoningEffortHigh represents high reasoning effort.
 22	ReasoningEffortHigh ReasoningEffort = "high"
 23)
 24
 25// Global type identifiers for OpenAI-specific provider data.
 26const (
 27	TypeProviderOptions     = Name + ".options"
 28	TypeProviderFileOptions = Name + ".file_options"
 29	TypeProviderMetadata    = Name + ".metadata"
 30)
 31
 32// ProviderMetadata represents additional metadata from OpenAI provider.
 33type ProviderMetadata struct {
 34	Logprobs                 []openai.ChatCompletionTokenLogprob `json:"logprobs"`
 35	AcceptedPredictionTokens int64                               `json:"accepted_prediction_tokens"`
 36	RejectedPredictionTokens int64                               `json:"rejected_prediction_tokens"`
 37}
 38
 39// Options implements the ProviderOptions interface.
 40func (*ProviderMetadata) Options() {}
 41
 42// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
 43func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
 44	type plain ProviderMetadata
 45	raw, err := json.Marshal(plain(m))
 46	if err != nil {
 47		return nil, err
 48	}
 49	return json.Marshal(struct {
 50		Type string          `json:"type"`
 51		Data json.RawMessage `json:"data"`
 52	}{
 53		Type: TypeProviderMetadata,
 54		Data: raw,
 55	})
 56}
 57
 58// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
 59func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
 60	type plain ProviderMetadata
 61	var pm plain
 62	err := json.Unmarshal(data, &pm)
 63	if err != nil {
 64		return err
 65	}
 66	*m = ProviderMetadata(pm)
 67	return nil
 68}
 69
 70// ProviderOptions represents additional options for OpenAI provider.
 71type ProviderOptions struct {
 72	LogitBias           map[string]int64 `json:"logit_bias"`
 73	LogProbs            *bool            `json:"log_probs"`
 74	TopLogProbs         *int64           `json:"top_log_probs"`
 75	ParallelToolCalls   *bool            `json:"parallel_tool_calls"`
 76	User                *string          `json:"user"`
 77	ReasoningEffort     *ReasoningEffort `json:"reasoning_effort"`
 78	MaxCompletionTokens *int64           `json:"max_completion_tokens"`
 79	TextVerbosity       *string          `json:"text_verbosity"`
 80	Prediction          map[string]any   `json:"prediction"`
 81	Store               *bool            `json:"store"`
 82	Metadata            map[string]any   `json:"metadata"`
 83	PromptCacheKey      *string          `json:"prompt_cache_key"`
 84	SafetyIdentifier    *string          `json:"safety_identifier"`
 85	ServiceTier         *string          `json:"service_tier"`
 86	StructuredOutputs   *bool            `json:"structured_outputs"`
 87}
 88
 89// Options implements the ProviderOptions interface.
 90func (*ProviderOptions) Options() {}
 91
 92// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
 93func (o ProviderOptions) MarshalJSON() ([]byte, error) {
 94	type plain ProviderOptions
 95	raw, err := json.Marshal(plain(o))
 96	if err != nil {
 97		return nil, err
 98	}
 99	return json.Marshal(struct {
100		Type string          `json:"type"`
101		Data json.RawMessage `json:"data"`
102	}{
103		Type: TypeProviderOptions,
104		Data: raw,
105	})
106}
107
108// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
109func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
110	type plain ProviderOptions
111	var oo plain
112	err := json.Unmarshal(data, &oo)
113	if err != nil {
114		return err
115	}
116	*o = ProviderOptions(oo)
117	return nil
118}
119
120// ProviderFileOptions represents file options for OpenAI provider.
121type ProviderFileOptions struct {
122	ImageDetail string `json:"image_detail"`
123}
124
125// Options implements the ProviderOptions interface.
126func (*ProviderFileOptions) Options() {}
127
128// MarshalJSON implements custom JSON marshaling with type info for ProviderFileOptions.
129func (o ProviderFileOptions) MarshalJSON() ([]byte, error) {
130	type plain ProviderFileOptions
131	raw, err := json.Marshal(plain(o))
132	if err != nil {
133		return nil, err
134	}
135	return json.Marshal(struct {
136		Type string          `json:"type"`
137		Data json.RawMessage `json:"data"`
138	}{
139		Type: TypeProviderFileOptions,
140		Data: raw,
141	})
142}
143
144// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderFileOptions.
145func (o *ProviderFileOptions) UnmarshalJSON(data []byte) error {
146	type plain ProviderFileOptions
147	var of plain
148	err := json.Unmarshal(data, &of)
149	if err != nil {
150		return err
151	}
152	*o = ProviderFileOptions(of)
153	return nil
154}
155
156// ReasoningEffortOption creates a pointer to a ReasoningEffort value.
157func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
158	return &e
159}
160
161// NewProviderOptions creates new provider options for OpenAI.
162func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
163	return fantasy.ProviderOptions{
164		Name: opts,
165	}
166}
167
168// NewProviderFileOptions creates new file options for OpenAI.
169func NewProviderFileOptions(opts *ProviderFileOptions) fantasy.ProviderOptions {
170	return fantasy.ProviderOptions{
171		Name: opts,
172	}
173}
174
175// ParseOptions parses provider options from a map.
176func ParseOptions(data map[string]any) (*ProviderOptions, error) {
177	var options ProviderOptions
178	if err := fantasy.ParseOptions(data, &options); err != nil {
179		return nil, err
180	}
181	return &options, nil
182}
183
184// Register OpenAI provider-specific types with the global registry.
185func init() {
186	fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
187		var v ProviderOptions
188		if err := json.Unmarshal(data, &v); err != nil {
189			return nil, err
190		}
191		return &v, nil
192	})
193	fantasy.RegisterProviderType(TypeProviderFileOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
194		var v ProviderFileOptions
195		if err := json.Unmarshal(data, &v); err != nil {
196			return nil, err
197		}
198		return &v, nil
199	})
200	fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
201		var v ProviderMetadata
202		if err := json.Unmarshal(data, &v); err != nil {
203			return nil, err
204		}
205		return &v, nil
206	})
207}