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