|
5ac549c…
|
lmata
|
1 |
package llm |
|
5ac549c…
|
lmata
|
2 |
|
|
5ac549c…
|
lmata
|
3 |
import ( |
|
5ac549c…
|
lmata
|
4 |
"context" |
|
5ac549c…
|
lmata
|
5 |
"encoding/json" |
|
5ac549c…
|
lmata
|
6 |
"net/http" |
|
5ac549c…
|
lmata
|
7 |
"net/http/httptest" |
|
5ac549c…
|
lmata
|
8 |
"testing" |
|
5ac549c…
|
lmata
|
9 |
) |
|
5ac549c…
|
lmata
|
10 |
|
|
5ac549c…
|
lmata
|
11 |
func TestOpenAISummarizeRetriesWithMaxCompletionTokens(t *testing.T) { |
|
5ac549c…
|
lmata
|
12 |
t.Helper() |
|
5ac549c…
|
lmata
|
13 |
|
|
5ac549c…
|
lmata
|
14 |
requests := 0 |
|
5ac549c…
|
lmata
|
15 |
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
5ac549c…
|
lmata
|
16 |
requests++ |
|
5ac549c…
|
lmata
|
17 |
|
|
5ac549c…
|
lmata
|
18 |
var body map[string]any |
|
5ac549c…
|
lmata
|
19 |
if err := json.NewDecoder(r.Body).Decode(&body); err != nil { |
|
5ac549c…
|
lmata
|
20 |
t.Fatalf("decode request: %v", err) |
|
5ac549c…
|
lmata
|
21 |
} |
|
5ac549c…
|
lmata
|
22 |
|
|
5ac549c…
|
lmata
|
23 |
switch requests { |
|
5ac549c…
|
lmata
|
24 |
case 1: |
|
5ac549c…
|
lmata
|
25 |
if _, ok := body["max_tokens"]; !ok { |
|
5ac549c…
|
lmata
|
26 |
t.Fatalf("first request missing max_tokens: %#v", body) |
|
5ac549c…
|
lmata
|
27 |
} |
|
5ac549c…
|
lmata
|
28 |
w.WriteHeader(http.StatusBadRequest) |
|
5ac549c…
|
lmata
|
29 |
_, _ = w.Write([]byte(`{"error":{"message":"Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.","param":"max_tokens"}}`)) |
|
5ac549c…
|
lmata
|
30 |
case 2: |
|
5ac549c…
|
lmata
|
31 |
if _, ok := body["max_completion_tokens"]; !ok { |
|
5ac549c…
|
lmata
|
32 |
t.Fatalf("second request missing max_completion_tokens: %#v", body) |
|
5ac549c…
|
lmata
|
33 |
} |
|
5ac549c…
|
lmata
|
34 |
if _, ok := body["max_tokens"]; ok { |
|
5ac549c…
|
lmata
|
35 |
t.Fatalf("second request still included max_tokens: %#v", body) |
|
5ac549c…
|
lmata
|
36 |
} |
|
5ac549c…
|
lmata
|
37 |
_, _ = w.Write([]byte(`{"choices":[{"message":{"content":"relay smoke test succeeded"}}]}`)) |
|
5ac549c…
|
lmata
|
38 |
default: |
|
5ac549c…
|
lmata
|
39 |
t.Fatalf("unexpected extra request %d", requests) |
|
5ac549c…
|
lmata
|
40 |
} |
|
5ac549c…
|
lmata
|
41 |
})) |
|
5ac549c…
|
lmata
|
42 |
defer srv.Close() |
|
5ac549c…
|
lmata
|
43 |
|
|
5ac549c…
|
lmata
|
44 |
p := newOpenAIProvider("test-key", srv.URL, "gpt-5.4-mini", srv.Client()) |
|
5ac549c…
|
lmata
|
45 |
got, err := p.Summarize(context.Background(), "test prompt") |
|
5ac549c…
|
lmata
|
46 |
if err != nil { |
|
5ac549c…
|
lmata
|
47 |
t.Fatalf("Summarize returned error: %v", err) |
|
5ac549c…
|
lmata
|
48 |
} |
|
5ac549c…
|
lmata
|
49 |
if got != "relay smoke test succeeded" { |
|
5ac549c…
|
lmata
|
50 |
t.Fatalf("Summarize = %q, want %q", got, "relay smoke test succeeded") |
|
5ac549c…
|
lmata
|
51 |
} |
|
5ac549c…
|
lmata
|
52 |
if requests != 2 { |
|
5ac549c…
|
lmata
|
53 |
t.Fatalf("request count = %d, want 2", requests) |
|
5ac549c…
|
lmata
|
54 |
} |
|
5ac549c…
|
lmata
|
55 |
} |
|
5ac549c…
|
lmata
|
56 |
|
|
5ac549c…
|
lmata
|
57 |
func TestShouldRetryWithMaxCompletionTokens(t *testing.T) { |
|
5ac549c…
|
lmata
|
58 |
t.Helper() |
|
5ac549c…
|
lmata
|
59 |
|
|
5ac549c…
|
lmata
|
60 |
body := []byte(`{"error":{"message":"Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.","param":"max_tokens"}}`) |
|
5ac549c…
|
lmata
|
61 |
if !shouldRetryWithMaxCompletionTokens(http.StatusBadRequest, body) { |
|
5ac549c…
|
lmata
|
62 |
t.Fatalf("expected retry to be enabled") |
|
5ac549c…
|
lmata
|
63 |
} |
|
5ac549c…
|
lmata
|
64 |
if shouldRetryWithMaxCompletionTokens(http.StatusUnauthorized, body) { |
|
5ac549c…
|
lmata
|
65 |
t.Fatalf("unexpected retry on unauthorized response") |
|
5ac549c…
|
lmata
|
66 |
} |
|
5ac549c…
|
lmata
|
67 |
} |