v0.0.5: context compaction, minimal config, retry/search/code symbols/diff/status/test commands
This commit is contained in:
@@ -30,6 +30,10 @@ func TestOpenAICompatibleClientStreamsContentAndToolCalls(t *testing.T) {
|
||||
if raw["thinking"] != "high" {
|
||||
t.Fatalf("thinking = %#v", raw["thinking"])
|
||||
}
|
||||
streamOptions, ok := raw["stream_options"].(map[string]any)
|
||||
if !ok || streamOptions["include_usage"] != true {
|
||||
t.Fatalf("stream_options = %#v", raw["stream_options"])
|
||||
}
|
||||
if !req.Stream {
|
||||
t.Fatal("request did not enable stream")
|
||||
}
|
||||
@@ -66,6 +70,75 @@ func TestOpenAICompatibleClientStreamsContentAndToolCalls(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestChatStreamCapturesUsage(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body := mustReadBody(t, r)
|
||||
var raw map[string]any
|
||||
if err := json.NewDecoder(strings.NewReader(body)).Decode(&raw); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
streamOptions, ok := raw["stream_options"].(map[string]any)
|
||||
if !ok || streamOptions["include_usage"] != true {
|
||||
t.Fatalf("stream_options = %#v", raw["stream_options"])
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
_, _ = w.Write([]byte(`data: {"choices":[{"delta":{"content":"ok"},"finish_reason":""}]}` + "\n\n"))
|
||||
_, _ = w.Write([]byte(`data: {"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":3,"total_tokens":15}}` + "\n\n"))
|
||||
_, _ = w.Write([]byte("data: [DONE]\n\n"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewOpenAICompatibleClient(server.URL, "sk-test", server.Client())
|
||||
var usage *Usage
|
||||
err := client.ChatStream(context.Background(), ChatRequest{Model: "test"}, func(event StreamEvent) error {
|
||||
if event.Usage != nil {
|
||||
usage = event.Usage
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if usage == nil {
|
||||
t.Fatal("usage was not emitted")
|
||||
}
|
||||
if usage.PromptTokens != 12 || usage.CompletionTokens != 3 || usage.TotalTokens != 15 {
|
||||
t.Fatalf("usage = %#v", usage)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenAICompatibleClientRetriesTransientHTTPError(t *testing.T) {
|
||||
attempts := 0
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
attempts++
|
||||
if attempts == 1 {
|
||||
http.Error(w, "temporary", http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
_, _ = w.Write([]byte(`data: {"choices":[{"delta":{"content":"ok"},"finish_reason":""}]}` + "\n\n"))
|
||||
_, _ = w.Write([]byte("data: [DONE]\n\n"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewOpenAICompatibleClient(server.URL, "sk-test", server.Client())
|
||||
var content strings.Builder
|
||||
err := client.ChatStream(context.Background(), ChatRequest{Model: "test"}, func(event StreamEvent) error {
|
||||
content.WriteString(event.Content)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if attempts != 2 {
|
||||
t.Fatalf("attempts = %d, want 2", attempts)
|
||||
}
|
||||
if content.String() != "ok" {
|
||||
t.Fatalf("content = %q", content.String())
|
||||
}
|
||||
}
|
||||
|
||||
func mustReadBody(t *testing.T, r *http.Request) string {
|
||||
t.Helper()
|
||||
data, err := io.ReadAll(r.Body)
|
||||
|
||||
Reference in New Issue
Block a user