|
2 | 2 |
|
3 | 3 | <a href="https://pkg.go.dev/github.com/openai/openai-go"><img src="https://pkg.go.dev/badge/github.com/openai/openai-go.svg" alt="Go Reference"></a>
|
4 | 4 |
|
5 |
| -This SDK includes breaking changes from the previous version to improve the ergonomics of constructing parameters and accessing responses. |
| 5 | +This SDK includes breaking changes to improve the ergonomics of constructing parameters and accessing responses. |
| 6 | + |
| 7 | +To reduce verbosity, the `openai.F(...)` and `param.Field[T]` have been removed. |
| 8 | +All calls to `openai.F(...)` can be deleted. |
| 9 | + |
| 10 | +The SDK now uses the <code>\`json:"...,omitzero"\`</code> struct tag to omit fields. Nested structs, arrays and maps |
| 11 | +can be declared like normal. |
| 12 | + |
| 13 | +The old SDK used interfaces for unions in requests, which required |
| 14 | +a type assertion to access variants and fields. The new design uses |
| 15 | +structs with a field for each variant, wherein only one field can be set. |
| 16 | +These struct unions also expose 'Get' methods to access and mutate subfields |
| 17 | +which may be shared by multiple variants. |
6 | 18 |
|
7 | 19 | # Request parameters
|
8 | 20 |
|
9 | 21 | ## Required primitives parameters serialize their zero values (`string`, `int64`, etc.)
|
10 | 22 |
|
11 |
| -> [!CAUTION] > **This change can cause new behavior in existing code, without compiler warnings.** |
| 23 | +> [!CAUTION] |
| 24 | +> |
| 25 | +> **This change can cause new behavior in existing code, without compiler warnings.** |
| 26 | +
|
| 27 | +While migrating, ensure that all required fields are explicitly set. A required primitive |
| 28 | +field `Age` will use the <code>\`json:"age,required"\`</code> struct tag without `omitzero`. |
| 29 | + |
| 30 | +If a required primitive field is not set, the zero value will be serialized. |
| 31 | +This was not the case in with `param.Field[T]`. |
12 | 32 |
|
13 | 33 | ```diff
|
14 | 34 | type FooParams struct {
|
15 | 35 | - Age param.Field[int64] `json:"age,required"`
|
16 | 36 | - Name param.Field[string] `json:"name"`
|
17 |
| -+ Age int64 `json:"age,required"` |
| 37 | ++ Age int64 `json:"age,required"` // <== Notice no omitzero |
18 | 38 | + Name param.Opt[string] `json:"name,omitzero"`
|
19 | 39 | }
|
20 | 40 | ```
|
@@ -48,43 +68,24 @@ _ = FooParams{
|
48 | 68 | </tr>
|
49 | 69 | </table>
|
50 | 70 |
|
51 |
| -The required field `"age"` is now present as `0`. Required primitive fields without the <code>\`json:"...,omitzero"\`</code> struct tag |
| 71 | +The required field `"age"` is now present as `0`. Fields without the <code>\`json:"...,omitzero"\`</code> struct tag |
52 | 72 | are always serialized, including their zero values.
|
53 | 73 |
|
54 | 74 | ## Transition from `param.Field[T]` to `omitzero`
|
55 | 75 |
|
56 |
| -The new SDK uses <a href="https://pkg.go.dev/encoding/json#Marshal"><code>\`json:"...,omitzero"\`</code> semantics</a> from Go 1.24+ for JSON encoding[^1]. |
57 |
| - |
58 |
| -`omitzero` is used for structs, slices, maps, string enums, and optional primitive types wrapped in `param.Opt[T]` (e.g. `param.Opt[string]`). |
59 |
| - |
60 |
| -**Fields of a request struct:** |
61 |
| - |
62 |
| -```diff |
63 |
| -type FooParams struct { |
64 |
| -- RequiredString param.Field[string] `json:"required_string,required"` |
65 |
| -+ RequiredString string `json:"required_string,required"` |
66 |
| - |
67 |
| -- OptionalString param.Field[string] `json:"optional_string"` |
68 |
| -+ OptionalString param.Opt[string] `json:"optional_string,omitzero"` |
69 |
| - |
70 |
| -- Array param.Field[[]BarParam] `json"array"` |
71 |
| -+ Array []BarParam `json"array,omitzero"` |
| 76 | +The `openai.F(...)` function and `param.Field[T]` type are no longer present in the new SDK. |
72 | 77 |
|
73 |
| -- Map param.Field[map[string]BarParam] `json"map"` |
74 |
| -+ Map map[string]BarParam `json"map,omitzero"` |
| 78 | +To represent omitted fields, the SDK uses <a href="https://pkg.go.dev/encoding/json#Marshal"><code>\`json:"...,omitzero"\`</code> semantics</a> from Go 1.24+ for JSON encoding[^1]. `omitzero` always omits fields |
| 79 | +with zero values. |
75 | 80 |
|
76 |
| -- RequiredObject param.Field[BarParam] `json:"required_object,required"` |
77 |
| -+ RequiredObject BarParam `json:"required_object,omitzero,required"` |
| 81 | +In all cases other than optional primitives, `openai.F()` can simply be removed. |
| 82 | +For optional primitive types, such as `param.Opt[string]`, you can use `openai.String(string)` to construct the value. |
| 83 | +Similar functions exist for other primitive types like `openai.Int(int)`, `openai.Bool(bool)`, etc. |
78 | 84 |
|
79 |
| -- OptionalObject param.Field[BarParam] `json:"optional_object"` |
80 |
| -+ OptionalObject BarParam `json:"optional_object,omitzero"` |
| 85 | +`omitzero` is used for fields whose type is either a struct, slice, map, string enum, |
| 86 | +or wrapped optional primitive (e.g. `param.Opt[T]`). Required primitive fields don't use `omitzero`. |
81 | 87 |
|
82 |
| -- StringEnum param.Field[BazEnum] `json:"string_enum"` |
83 |
| -+ StringEnum BazEnum `json:"string_enum,omitzero"` |
84 |
| -} |
85 |
| -``` |
86 |
| - |
87 |
| -**Previous vs New SDK: Constructing a request** |
| 88 | +**Example User Code: Constructing a request** |
88 | 89 |
|
89 | 90 | ```diff
|
90 | 91 | foo = FooParams{
|
@@ -112,12 +113,36 @@ foo = FooParams{
|
112 | 113 | }
|
113 | 114 | ```
|
114 | 115 |
|
115 |
| -`param.Opt[string]` can be constructed with `openai.String(string)`. Similar functions exist for other primitive |
116 |
| -types like `openai.Int(int)`, `openai.Bool(bool)`, etc. |
| 116 | +**Internal SDK Code: Fields of a request struct:** |
| 117 | + |
| 118 | +```diff |
| 119 | +type FooParams struct { |
| 120 | +- RequiredString param.Field[string] `json:"required_string,required"` |
| 121 | ++ RequiredString string `json:"required_string,required"` |
| 122 | + |
| 123 | +- OptionalString param.Field[string] `json:"optional_string"` |
| 124 | ++ OptionalString param.Opt[string] `json:"optional_string,omitzero"` |
| 125 | + |
| 126 | +- Array param.Field[[]BarParam] `json"array"` |
| 127 | ++ Array []BarParam `json"array,omitzero"` |
| 128 | + |
| 129 | +- Map param.Field[map[string]BarParam] `json"map"` |
| 130 | ++ Map map[string]BarParam `json"map,omitzero"` |
| 131 | + |
| 132 | +- RequiredObject param.Field[BarParam] `json:"required_object,required"` |
| 133 | ++ RequiredObject BarParam `json:"required_object,omitzero,required"` |
| 134 | + |
| 135 | +- OptionalObject param.Field[BarParam] `json:"optional_object"` |
| 136 | ++ OptionalObject BarParam `json:"optional_object,omitzero"` |
| 137 | + |
| 138 | +- StringEnum param.Field[BazEnum] `json:"string_enum"` |
| 139 | ++ StringEnum BazEnum `json:"string_enum,omitzero"` |
| 140 | +} |
| 141 | +``` |
117 | 142 |
|
118 | 143 | ## Request Unions: Removing interfaces and moving to structs
|
119 | 144 |
|
120 |
| -For a type `AnimalUnionParam` which could be either a `string | CatParam | DogParam`. |
| 145 | +For a type `AnimalUnionParam` which could be either a `CatParam | DogParam`. |
121 | 146 |
|
122 | 147 | <table>
|
123 | 148 | <tr><th>Previous</th> <th>New</th></tr>
|
@@ -237,14 +262,23 @@ The `.IsNull()` method has been changed to `.IsPresent()` to better reflect its
|
237 | 262 | ```diff
|
238 | 263 | - if !resp.Foo.JSON.Bar.IsNull() {
|
239 | 264 | + if resp.Foo.JSON.Bar.IsPresent() {
|
240 |
| - println("bar is present:", resp.Foo.Bar) |
241 |
| - } |
| 265 | + println("bar is present:", resp.Foo.Bar) |
| 266 | +} |
242 | 267 | ```
|
243 | 268 |
|
244 | 269 | | Previous | New | Returns true for values |
|
245 | 270 | | -------------- | ------------------- | ----------------------- |
|
246 | 271 | | `.IsNull()` | `!.IsPresent()` | `null` or Omitted |
|
247 | 272 | | `.IsMissing()` | `.Raw() == ""` | Omitted |
|
248 |
| -| `.Invalid()` | `.IsExplicitNull()` | `null` | |
| 273 | +| | `.IsExplicitNull()` | `null` | |
| 274 | + |
| 275 | +## Checking Raw JSON of a response |
| 276 | + |
| 277 | +The `.RawJSON()` method has moved to the parent of the `.JSON` property. |
| 278 | + |
| 279 | +```diff |
| 280 | +- resp.Foo.JSON.RawJSON() |
| 281 | ++ resp.Foo.RawJSON() |
| 282 | +``` |
249 | 283 |
|
250 | 284 | [^1]: The SDK doesn't require Go 1.24, despite supporting the `omitzero` feature
|
0 commit comments