From 21fa42c18dbafef43977ab73c403eef6d694b14a Mon Sep 17 00:00:00 2001 From: Liu Shuang Date: Sat, 30 Nov 2024 17:39:47 +0800 Subject: [PATCH 1/4] feat: add gpt-4o-2024-11-20 model (#905) --- completion.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/completion.go b/completion.go index 9e3073694..f11566081 100644 --- a/completion.go +++ b/completion.go @@ -37,6 +37,7 @@ const ( GPT4o = "gpt-4o" GPT4o20240513 = "gpt-4o-2024-05-13" GPT4o20240806 = "gpt-4o-2024-08-06" + GPT4o20241120 = "gpt-4o-2024-11-20" GPT4oLatest = "chatgpt-4o-latest" GPT4oMini = "gpt-4o-mini" GPT4oMini20240718 = "gpt-4o-mini-2024-07-18" @@ -119,6 +120,7 @@ var disabledModelsForEndpoints = map[string]map[string]bool{ GPT4o: true, GPT4o20240513: true, GPT4o20240806: true, + GPT4o20241120: true, GPT4oLatest: true, GPT4oMini: true, GPT4oMini20240718: true, From c203ca001fecd40210cfcf9923ab69235c92e321 Mon Sep 17 00:00:00 2001 From: Qiying Wang <781345688@qq.com> Date: Sat, 30 Nov 2024 18:29:05 +0800 Subject: [PATCH 2/4] feat: add RecvRaw (#896) --- stream_reader.go | 39 ++++++++++++++++++++++----------------- stream_reader_test.go | 13 +++++++++++++ 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/stream_reader.go b/stream_reader.go index 4210a1948..ecfa26807 100644 --- a/stream_reader.go +++ b/stream_reader.go @@ -32,17 +32,28 @@ type streamReader[T streamable] struct { } func (stream *streamReader[T]) Recv() (response T, err error) { - if stream.isFinished { - err = io.EOF + rawLine, err := stream.RecvRaw() + if err != nil { return } - response, err = stream.processLines() - return + err = stream.unmarshaler.Unmarshal(rawLine, &response) + if err != nil { + return + } + return response, nil +} + +func (stream *streamReader[T]) RecvRaw() ([]byte, error) { + if stream.isFinished { + return nil, io.EOF + } + + return stream.processLines() } //nolint:gocognit -func (stream *streamReader[T]) processLines() (T, error) { +func (stream *streamReader[T]) processLines() ([]byte, error) { var ( emptyMessagesCount uint hasErrorPrefix bool @@ -53,9 +64,9 @@ func (stream *streamReader[T]) processLines() (T, error) { if readErr != nil || hasErrorPrefix { respErr := stream.unmarshalError() if respErr != nil { - return *new(T), fmt.Errorf("error, %w", respErr.Error) + return nil, fmt.Errorf("error, %w", respErr.Error) } - return *new(T), readErr + return nil, readErr } noSpaceLine := bytes.TrimSpace(rawLine) @@ -68,11 +79,11 @@ func (stream *streamReader[T]) processLines() (T, error) { } writeErr := stream.errAccumulator.Write(noSpaceLine) if writeErr != nil { - return *new(T), writeErr + return nil, writeErr } emptyMessagesCount++ if emptyMessagesCount > stream.emptyMessagesLimit { - return *new(T), ErrTooManyEmptyStreamMessages + return nil, ErrTooManyEmptyStreamMessages } continue @@ -81,16 +92,10 @@ func (stream *streamReader[T]) processLines() (T, error) { noPrefixLine := bytes.TrimPrefix(noSpaceLine, headerData) if string(noPrefixLine) == "[DONE]" { stream.isFinished = true - return *new(T), io.EOF - } - - var response T - unmarshalErr := stream.unmarshaler.Unmarshal(noPrefixLine, &response) - if unmarshalErr != nil { - return *new(T), unmarshalErr + return nil, io.EOF } - return response, nil + return noPrefixLine, nil } } diff --git a/stream_reader_test.go b/stream_reader_test.go index cd6e46eff..449a14b43 100644 --- a/stream_reader_test.go +++ b/stream_reader_test.go @@ -63,3 +63,16 @@ func TestStreamReaderReturnsErrTestErrorAccumulatorWriteFailed(t *testing.T) { _, err := stream.Recv() checks.ErrorIs(t, err, test.ErrTestErrorAccumulatorWriteFailed, "Did not return error when write failed", err.Error()) } + +func TestStreamReaderRecvRaw(t *testing.T) { + stream := &streamReader[ChatCompletionStreamResponse]{ + reader: bufio.NewReader(bytes.NewReader([]byte("data: {\"key\": \"value\"}\n"))), + } + rawLine, err := stream.RecvRaw() + if err != nil { + t.Fatalf("Did not return raw line: %v", err) + } + if !bytes.Equal(rawLine, []byte("{\"key\": \"value\"}")) { + t.Fatalf("Did not return raw line: %v", string(rawLine)) + } +} From af5355f5b1a7701f891109e8a17b7b245ac5363b Mon Sep 17 00:00:00 2001 From: Tim Misiak Date: Sun, 8 Dec 2024 05:12:05 -0800 Subject: [PATCH 3/4] Fix ID field to be optional (#911) The ID field is not always present for streaming responses. Without omitempty, the entire ToolCall struct will be missing. --- chat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chat.go b/chat.go index 2b13f8dd7..fcaf79cf7 100644 --- a/chat.go +++ b/chat.go @@ -179,7 +179,7 @@ func (m *ChatCompletionMessage) UnmarshalJSON(bs []byte) error { type ToolCall struct { // Index is not nil only in chat completion chunk object Index *int `json:"index,omitempty"` - ID string `json:"id"` + ID string `json:"id,omitempty"` Type ToolType `json:"type"` Function FunctionCall `json:"function"` } From 56a9acf86fc3ce0e9030feafa346d64bade94027 Mon Sep 17 00:00:00 2001 From: Alex Baranov <677093+sashabaranov@users.noreply.github.com> Date: Sun, 8 Dec 2024 13:16:48 +0000 Subject: [PATCH 4/4] Ignore test.mp3 (#913) --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 99b40bf17..b0ac1605c 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,7 @@ # Auth token for tests .openai-token -.idea \ No newline at end of file +.idea + +# Generated by tests +test.mp3 \ No newline at end of file