Files
openai.openai-go/MIGRATION.md
2025-03-21 05:07:09 +00:00

6.0 KiB

OpenAI Go Migration Guide

Go Reference

This SDK includes breaking changes from the previous version to improve the ergonomics of constructing parameters and accessing responses.

Request parameters

Required primitives parameters serialize their zero values (string, int64, etc.)

[!CAUTION] > This change can cause new behavior in existing code, without compiler warnings.

type FooParams struct {
-        Age  param.Field[int64]  `json:"age,required"`
-        Name param.Field[string] `json:"name"`
+        Age  int64               `json:"age,required"`
+        Name param.Opt[string]   `json:"name,omitzero"`
}
Previous New
_ = FooParams{
    Name: openai.String("Jerry")
}
`{"name": "Jerry"}` // (after serialization)
_ = FooParams{
    Name: openai.String("Jerry")
}
`{"name": "Jerry", "age": 0}` // <== Notice the age field

The required field "age" is now present as 0. Required primitive fields without the `json:"...,omitzero"` struct tag are always serialized, including their zero values.

Transition from param.Field[T] to omitzero

The new SDK uses `json:"...,omitzero"` semantics from Go 1.24+ for JSON encoding1 .

omitzero is used for structs, slices, maps, string enums, and optional primitive types wrapped in param.Opt[T] (e.g. param.Opt[string]).

Fields of a request struct:

type FooParams struct {
-    RequiredString param.Field[string]   `json:"required_string,required"`
+    RequiredString string                `json:"required_string,required"`

-    OptionalString param.Field[string]   `json:"optional_string"`
+    OptionalString param.Opt[string]     `json:"optional_string,omitzero"`

-    Array param.Field[[]BarParam]        `json"array"`
+    Array []BarParam                     `json"array,omitzero"`

-    Map param.Field[map[string]BarParam] `json"map"`
+    Map map[string]BarParam              `json"map,omitzero"`

-    RequiredObject param.Field[BarParam] `json:"required_object,required"`
+    RequiredObject BarParam              `json:"required_object,omitzero,required"`

-    OptionalObject param.Field[BarParam] `json:"optional_object"`
+    OptionalObject BarParam              `json:"optional_object,omitzero"`

-    StringEnum     param.Field[BazEnum]  `json:"string_enum"`
+    StringEnum     BazEnum               `json:"string_enum,omitzero"`
}

Previous vs New SDK: Constructing a request

foo = FooParams{
-    RequiredString: openai.String("hello"),
+    RequiredString: "hello",

-    OptionalString: openai.String("hi"),
+    OptionalString: openai.String("hi"),

-    Array: openai.F([]BarParam{
-        BarParam{Prop: ... }
-    }),
+    Array: []BarParam{
+        BarParam{Prop: ... }
+    },

-    RequiredObject: openai.F(BarParam{ ... }),
+    RequiredObject: BarParam{ ... },

-    OptionalObject: openai.F(BarParam{ ... }),
+    OptionalObject: BarParam{ ... },

-    StringEnum: openai.F[BazEnum]("baz-ok"),
+    StringEnum: "baz-ok",
}

param.Opt[string] can be constructed with openai.String(string). Similar functions exist for other primitive types like openai.Int(int), openai.Bool(bool), etc.

Request Unions: Removing interfaces and moving to structs

For a type AnimalUnionParam which could be either a string | CatParam | DogParam.

Previous New
type AnimalParam interface {
	ImplAnimalParam()
}

func (Dog)         ImplAnimalParam() {}
func (Cat)         ImplAnimalParam() {}
type AnimalUnionParam struct {
	OfCat 	 *Cat              `json:",omitzero,inline`
	OfDog    *Dog              `json:",omitzero,inline`
}
var dog AnimalParam = DogParam{
	Name: "spot", ...
}
var cat AnimalParam = CatParam{
	Name: "whiskers", ...
}
dog := AnimalUnionParam{
	OfDog: &DogParam{Name: "spot", ... },
}
cat := AnimalUnionParam{
	OfCat: &CatParam{Name: "whiskers", ... },
}
var name string
switch v := animal.(type) {
case Dog:
	name = v.Name
case Cat:
	name = v.Name
}
// Accessing fields
var name *string = animal.GetName()

Sending explicit null values

The old SDK had a function param.Null[T]() which could set param.Field[T] to null.

The new SDK uses param.NullOpt[T]() for to set a param.Opt[T] to null, and param.NullObj[T]() to set a param struct T to null.

- var nullObj param.Field[BarParam] = param.Null[BarParam]()
+ var nullObj BarParam              = param.NullObj[BarParam]()

- var nullPrimitive param.Field[int64] = param.Null[int64]()
+ var nullPrimitive param.Opt[int64]   = param.NullOpt[int64]()

Sending custom values

The openai.Raw[T](any) function has been removed. All request structs now support a .WithExtraField(map[string]any) method to customize the fields.

foo := FooParams{
     A: param.String("hello"),
-    B: param.Raw[string](12) // sending `12` instead of a string
}
+ foo.WithExtraFields(map[string]any{
+    "B": 12,
+ })

Response Properties

Checking for presence of optional fields

The .IsNull() method has been changed to .IsPresent() to better reflect its behavior.

- if !resp.Foo.JSON.Bar.IsNull() {
+ if resp.Foo.JSON.Bar.IsPresent() {
     println("bar is present:", resp.Foo.Bar)
  }
Previous New Returns true for values
.IsNull() !.IsPresent() null or Omitted
.IsMissing() .Raw() == "" Omitted
.Invalid() .IsExplicitNull() null

  1. The SDK doesn't require Go 1.24, despite supporting the omitzero feature ↩︎