Go 1.27.1, and the code it can say more simply

Modules declare go 1.27.1 and the build images follow. go fix applied the
modernizers, and the stream request helper is now a generic method on
Client; omitzero is not applied, since it changes what the JSON says.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-09-16 19:23:22 -07:00
co-authored by Hanzo Dev
parent 8f73ecd09a
commit 2e39f0248d
16 changed files with 44 additions and 56 deletions
+1 -1
View File
@@ -96,7 +96,7 @@ func (c *Client) CreateChatCompletionStream(
return nil, err
}
resp, err := sendRequestStream[ChatCompletionStreamResponse](c, req)
resp, err := c.sendRequestStream[ChatCompletionStreamResponse](req)
if err != nil {
return
}
+4 -4
View File
@@ -157,21 +157,21 @@ func (c *Client) sendRequestRaw(req *http.Request) (response RawResponse, err er
return
}
func sendRequestStream[T streamable](client *Client, req *http.Request) (*streamReader[T], error) {
func (c *Client) sendRequestStream[T streamable](req *http.Request) (*streamReader[T], error) {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "text/event-stream")
req.Header.Set("Cache-Control", "no-cache")
req.Header.Set("Connection", "keep-alive")
resp, err := client.config.HTTPClient.Do(req) //nolint:bodyclose // body is closed in stream.Close()
resp, err := c.config.HTTPClient.Do(req) //nolint:bodyclose // body is closed in stream.Close()
if err != nil {
return new(streamReader[T]), err
}
if isFailureStatusCode(resp) {
return new(streamReader[T]), client.handleErrorResp(resp)
return new(streamReader[T]), c.handleErrorResp(resp)
}
return &streamReader[T]{
emptyMessagesLimit: client.config.EmptyMessagesLimit,
emptyMessagesLimit: c.config.EmptyMessagesLimit,
reader: bufio.NewReader(resp.Body),
response: resp,
errAccumulator: utils.NewErrorAccumulator(),
+5 -5
View File
@@ -59,8 +59,8 @@ func TestDecodeResponse(t *testing.T) {
testCases := []struct {
name string
value interface{}
expected interface{}
value any
expected any
body io.Reader
hasError bool
}{
@@ -78,9 +78,9 @@ func TestDecodeResponse(t *testing.T) {
},
{
name: "map input",
value: &map[string]interface{}{},
value: &map[string]any{},
body: bytes.NewReader([]byte(`{"test": "test"}`)),
expected: map[string]interface{}{
expected: map[string]any{
"test": "test",
},
},
@@ -100,7 +100,7 @@ func TestDecodeResponse(t *testing.T) {
},
}
assertEqual := func(t *testing.T, expected, actual interface{}) {
assertEqual := func(t *testing.T, expected, actual any) {
t.Helper()
if expected == actual {
return
+3 -3
View File
@@ -68,7 +68,7 @@ func TestMultiplePromptsCompletionsWrong(t *testing.T) {
req := openai.CompletionRequest{
MaxTokens: 5,
Model: "ada",
Prompt: []interface{}{"Lorem ipsum", 9},
Prompt: []any{"Lorem ipsum", 9},
}
_, err := client.CreateCompletion(context.Background(), req)
if !errors.Is(err, openai.ErrCompletionRequestPromptTypeNotSupported) {
@@ -85,7 +85,7 @@ func TestMultiplePromptsCompletions(t *testing.T) {
req := openai.CompletionRequest{
MaxTokens: 5,
Model: "ada",
Prompt: []interface{}{"Lorem ipsum", "Lorem ipsum"},
Prompt: []any{"Lorem ipsum", "Lorem ipsum"},
}
_, err := client.CreateCompletion(context.Background(), req)
checks.NoError(t, err, "CreateCompletion error")
@@ -124,7 +124,7 @@ func handleCompletionEndpoint(w http.ResponseWriter, r *http.Request) {
switch v := completionReq.Prompt.(type) {
case string:
prompts = append(prompts, v)
case []interface{}:
case []any:
for _, item := range v {
if str, ok := item.(string); ok {
prompts = append(prompts, str)
+1 -1
View File
@@ -88,7 +88,7 @@ func (b base64String) Decode() ([]float32, error) {
const sizeOfFloat32 = 4
floats := make([]float32, len(decodedData)/sizeOfFloat32)
for i := 0; i < len(floats); i++ {
for i := range floats {
floats[i] = math.Float32frombits(binary.LittleEndian.Uint32(decodedData[i*4 : (i+1)*4]))
}
+2 -2
View File
@@ -224,13 +224,13 @@ func assertAPIErrorMessage(t *testing.T, apiErr openai.APIError, expected string
}
}
func assertAPIErrorInnerError(t *testing.T, apiErr openai.APIError, expected interface{}) {
func assertAPIErrorInnerError(t *testing.T, apiErr openai.APIError, expected any) {
if !reflect.DeepEqual(apiErr.InnerError, expected) {
t.Errorf("Unexpected APIError InnerError: %v; expected: %v; ", apiErr, expected)
}
}
func assertAPIErrorCode(t *testing.T, apiErr openai.APIError, expected interface{}) {
func assertAPIErrorCode(t *testing.T, apiErr openai.APIError, expected any) {
switch v := apiErr.Code.(type) {
case int:
if v != expected {
+1 -1
View File
@@ -1,3 +1,3 @@
module github.com/hanzoai/go-openai
go 1.26.5
go 1.27.1
+4 -5
View File
@@ -95,7 +95,7 @@ func reflectSchema(t reflect.Type) (*Definition, error) {
return nil, err
}
d = *object
case reflect.Ptr:
case reflect.Pointer:
definition, err := reflectSchema(t.Elem())
if err != nil {
return nil, err
@@ -117,8 +117,7 @@ func reflectSchemaObject(t reflect.Type) (*Definition, error) {
}
properties := make(map[string]Definition)
var requiredFields []string
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
for field := range t.Fields() {
if !field.IsExported() {
continue
}
@@ -126,8 +125,8 @@ func reflectSchemaObject(t reflect.Type) (*Definition, error) {
var required = true
if jsonTag == "" {
jsonTag = field.Name
} else if strings.HasSuffix(jsonTag, ",omitempty") {
jsonTag = strings.TrimSuffix(jsonTag, ",omitempty")
} else if before, ok := strings.CutSuffix(jsonTag, ",omitempty"); ok {
jsonTag = before
required = false
}
+2 -2
View File
@@ -173,7 +173,7 @@ func TestDefinition_MarshalJSON(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
wantBytes := []byte(tt.want)
var want map[string]interface{}
var want map[string]any
err := json.Unmarshal(wantBytes, &want)
if err != nil {
t.Errorf("Failed to Unmarshal JSON: error = %v", err)
@@ -201,7 +201,7 @@ func structToMap(t *testing.T, v any) map[string]any {
return nil
}
var got map[string]interface{}
var got map[string]any
err = json.Unmarshal(gotBytes, &got)
if err != nil {
t.Errorf("Failed to Unmarshal JSON: error = %v", err)
+2 -10
View File
@@ -3,6 +3,7 @@ package jsonschema
import (
"encoding/json"
"errors"
"slices"
)
func VerifySchemaAndUnmarshal(schema Definition, content []byte, v any) error {
@@ -63,7 +64,7 @@ func validateObject(schema Definition, data any) bool {
value, exists := dataMap[key]
if exists && !Validate(valueSchema, value) {
return false
} else if !exists && contains(schema.Required, key) {
} else if !exists && slices.Contains(schema.Required, key) {
return false
}
}
@@ -82,12 +83,3 @@ func validateArray(schema Definition, data any) bool {
}
return true
}
func contains[S ~[]E, E comparable](s S, v E) bool {
for i := range s {
if v == s[i] {
return true
}
}
return false
}
+1 -1
View File
@@ -31,7 +31,7 @@ type Permission struct {
AllowView bool `json:"allow_view"`
AllowFineTuning bool `json:"allow_fine_tuning"`
Organization string `json:"organization"`
Group interface{} `json:"group"`
Group any `json:"group"`
IsBlocking bool `json:"is_blocking"`
}
-2
View File
@@ -205,9 +205,7 @@ func TestRun(t *testing.T) {
checks.NoError(t, err, "CancelRun error")
_, err = client.CreateThreadAndRun(ctx, openai.CreateThreadAndRunRequest{
RunRequest: openai.RunRequest{
AssistantID: assistantID,
},
Thread: openai.ThreadRequest{
Messages: []openai.ThreadMessage{
{
+1 -1
View File
@@ -42,7 +42,7 @@ func TestSpeechIntegration(t *testing.T) {
}
// Parse the JSON body of the request
var params map[string]interface{}
var params map[string]any
err = json.NewDecoder(r.Body).Decode(&params)
if err != nil {
http.Error(w, "failed to parse request body", http.StatusBadRequest)
+1 -1
View File
@@ -44,7 +44,7 @@ func (c *Client) CreateCompletionStream(
return nil, err
}
resp, err := sendRequestStream[CompletionResponse](c, req)
resp, err := c.sendRequestStream[CompletionResponse](req)
if err != nil {
return
}
+2 -3
View File
@@ -193,7 +193,7 @@ func TestCreateCompletionStreamTooManyEmptyStreamMessagesError(t *testing.T) {
dataBytes = append(dataBytes, []byte("data: "+data+"\n\n")...)
// Totally 301 empty messages (300 is the limit)
for i := 0; i < 299; i++ {
for range 299 {
dataBytes = append(dataBytes, '\n')
}
@@ -296,8 +296,7 @@ func TestCreateCompletionStreamBrokenJSONError(t *testing.T) {
_, _ = stream.Recv()
_, streamErr := stream.Recv()
var syntaxError *json.SyntaxError
if !errors.As(streamErr, &syntaxError) {
if _, ok := errors.AsType[*json.SyntaxError](streamErr); !ok {
t.Errorf("TestCreateCompletionStreamBrokenJSONError did not return json.SyntaxError")
}
}
+2 -2
View File
@@ -84,7 +84,7 @@ func TestThread(t *testing.T) {
checks.NoError(t, err, "RetrieveThread error")
_, err = client.ModifyThread(ctx, threadID, openai.ModifyThreadRequest{
Metadata: map[string]interface{}{
Metadata: map[string]any{
"key": "value",
},
})
@@ -167,7 +167,7 @@ func TestAzureThread(t *testing.T) {
checks.NoError(t, err, "RetrieveThread error")
_, err = client.ModifyThread(ctx, threadID, openai.ModifyThreadRequest{
Metadata: map[string]interface{}{
Metadata: map[string]any{
"key": "value",
},
})