140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
package openai
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/nomadcode/nomadcode-core/internal/model"
|
|
)
|
|
|
|
func TestGenerateCallsResponsesAPI(t *testing.T) {
|
|
var gotPath string
|
|
var gotAuth string
|
|
var gotBody map[string]any
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotPath = r.URL.Path
|
|
gotAuth = r.Header.Get("Authorization")
|
|
if err := json.NewDecoder(r.Body).Decode(&gotBody); err != nil {
|
|
t.Fatalf("decode request: %v", err)
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{
|
|
"id": "resp_test",
|
|
"model": "qwen3.6:35b-a3b-bf16",
|
|
"output_text": "hello from model",
|
|
"usage": {
|
|
"input_tokens": 3,
|
|
"output_tokens": 4,
|
|
"total_tokens": 7
|
|
}
|
|
}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(Config{
|
|
BaseURL: server.URL,
|
|
APIKey: "test-key",
|
|
Model: "qwen3.6:35b-a3b-bf16",
|
|
ContextSize: 262144,
|
|
}, nil)
|
|
|
|
result, err := client.Generate(context.Background(), model.GenerateInput{
|
|
Input: "say hello",
|
|
Instructions: "be brief",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Generate returned error: %v", err)
|
|
}
|
|
|
|
if gotPath != "/v1/responses" {
|
|
t.Fatalf("expected /v1/responses, got %q", gotPath)
|
|
}
|
|
if gotAuth != "Bearer test-key" {
|
|
t.Fatalf("expected auth header, got %q", gotAuth)
|
|
}
|
|
if gotBody["model"] != "qwen3.6:35b-a3b-bf16" {
|
|
t.Fatalf("unexpected model: %#v", gotBody["model"])
|
|
}
|
|
if gotBody["input"] != "say hello" {
|
|
t.Fatalf("unexpected input: %#v", gotBody["input"])
|
|
}
|
|
if gotBody["instructions"] != "be brief" {
|
|
t.Fatalf("unexpected instructions: %#v", gotBody["instructions"])
|
|
}
|
|
if _, ok := gotBody["context_size"]; ok {
|
|
t.Fatal("Responses API request must not include unsupported context_size")
|
|
}
|
|
options, ok := gotBody["options"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("expected options object, got %#v", gotBody["options"])
|
|
}
|
|
if options["num_ctx"] != float64(262144) {
|
|
t.Fatalf("unexpected options.num_ctx: %#v", options["num_ctx"])
|
|
}
|
|
if result.Text != "hello from model" {
|
|
t.Fatalf("unexpected result text: %q", result.Text)
|
|
}
|
|
if result.Usage.TotalTokens != 7 {
|
|
t.Fatalf("unexpected usage: %#v", result.Usage)
|
|
}
|
|
}
|
|
|
|
func TestGenerateExtractsOutputContent(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{
|
|
"id": "resp_test",
|
|
"output": [
|
|
{
|
|
"type": "message",
|
|
"content": [
|
|
{"type": "output_text", "text": "hello "},
|
|
{"type": "output_text", "text": "again"}
|
|
]
|
|
}
|
|
],
|
|
"usage": {
|
|
"prompt_tokens": 2,
|
|
"completion_tokens": 5
|
|
}
|
|
}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(Config{BaseURL: server.URL, Model: "model-a"}, nil)
|
|
result, err := client.Generate(context.Background(), model.GenerateInput{Input: "say hello"})
|
|
if err != nil {
|
|
t.Fatalf("Generate returned error: %v", err)
|
|
}
|
|
if result.Text != "hello again" {
|
|
t.Fatalf("unexpected result text: %q", result.Text)
|
|
}
|
|
if result.Usage.InputTokens != 2 || result.Usage.OutputTokens != 5 || result.Usage.TotalTokens != 7 {
|
|
t.Fatalf("unexpected usage: %#v", result.Usage)
|
|
}
|
|
}
|
|
|
|
func TestResponsesURL(t *testing.T) {
|
|
tests := map[string]string{
|
|
"http://localhost:11434": "http://localhost:11434/v1/responses",
|
|
"http://localhost:11434/": "http://localhost:11434/v1/responses",
|
|
"http://localhost:11434/v1": "http://localhost:11434/v1/responses",
|
|
"http://localhost:11434/v1/": "http://localhost:11434/v1/responses",
|
|
"http://localhost:11434/v1/responses": "http://localhost:11434/v1/responses",
|
|
}
|
|
|
|
for input, want := range tests {
|
|
got, err := responsesURL(input)
|
|
if err != nil {
|
|
t.Fatalf("responsesURL(%q) returned error: %v", input, err)
|
|
}
|
|
if got != want {
|
|
t.Fatalf("responsesURL(%q) = %q, want %q", input, got, want)
|
|
}
|
|
}
|
|
}
|