reverse changes

This commit is contained in:
Grace Guo
2025-11-03 15:51:48 -08:00
parent 2a5214930e
commit c51ab4aa80
4 changed files with 118 additions and 99 deletions

View File

@@ -381,3 +381,30 @@ func TestAPIShowModel(t *testing.T) {
t.Errorf("%s missing modified_at: %#v", modelName, resp) t.Errorf("%s missing modified_at: %#v", modelName, resp)
} }
} }
func TestAPIEmbeddings(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
client, _, cleanup := InitServerConnection(ctx, t)
defer cleanup()
req := api.EmbeddingRequest{
Model: libraryEmbedModels[0],
Prompt: "why is the sky blue?",
Options: map[string]interface{}{
"temperature": 0,
"seed": 123,
},
}
if err := PullIfMissing(ctx, client, req.Model); err != nil {
t.Fatalf("pull failed %s", err)
}
resp, err := client.Embeddings(ctx, &req)
if err != nil {
t.Fatalf("embeddings call failed %s", err)
}
if len(resp.Embedding) == 0 {
t.Errorf("zero length embedding response")
}
}

View File

@@ -12,18 +12,22 @@ import (
"github.com/ollama/ollama/api" "github.com/ollama/ollama/api"
) )
// TestQwen3VLStreaming tests Qwen3-VL with streaming enabled // getTestConfig returns model and streaming mode based on environment variables or defaults
func TestQwen3VLStreaming(t *testing.T) { func getTestConfig() (model string, stream bool) {
runQwen3VLTests(t, true) model = os.Getenv("QWEN3VL_MODEL")
if model == "" {
model = "qwen3-vl:235b-cloud" // default
}
streamStr := os.Getenv("QWEN3VL_STREAM")
stream = streamStr != "false" // default to true
return model, stream
} }
// TestQwen3VLNonStreaming tests Qwen3-VL with streaming disabled func TestQwen3VL(t *testing.T) {
func TestQwen3VLNonStreaming(t *testing.T) { model, stream := getTestConfig()
runQwen3VLTests(t, false)
}
func runQwen3VLTests(t *testing.T, stream bool) {
models := []string{"qwen3-vl:235b-cloud", "qwen3-vl:235b-instruct-cloud"}
tests := []struct { tests := []struct {
name string name string
messages []api.Message messages []api.Message
@@ -46,10 +50,10 @@ func runQwen3VLTests(t *testing.T, stream bool) {
}, },
{ {
Role: "user", Role: "user",
Content: "What is the answer to this question?", Content: "What is in this image?",
}, },
}, },
images: []string{"testdata/question.png"}, images: []string{"testdata/menu.png"},
}, },
{ {
name: "Multiple Images Scenario", name: "Multiple Images Scenario",
@@ -63,7 +67,7 @@ func runQwen3VLTests(t *testing.T, stream bool) {
Content: "Use both images to answer the question.", Content: "Use both images to answer the question.",
}, },
}, },
images: []string{"testdata/question.png", "testdata/menu.png"}, images: []string{"testdata/satmath1.png", "testdata/satmath2.png"},
}, },
{ {
name: "Tools Scenario", name: "Tools Scenario",
@@ -158,102 +162,90 @@ func runQwen3VLTests(t *testing.T, stream bool) {
}, },
} }
for _, model := range models {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
// Load and attach images if specified // Load and attach images to last user message
messages := tt.messages
if len(tt.images) > 0 { if len(tt.images) > 0 {
var imgs []api.ImageData var imgs []api.ImageData
for _, path := range tt.images { for _, path := range tt.images {
imgs = append(imgs, loadImageData(t, path)) imgs = append(imgs, loadImageData(t, path))
} }
if len(tt.messages) > 0 { // Find last user message and attach images
lastMessage := &tt.messages[len(tt.messages)-1] for i := len(messages) - 1; i >= 0; i-- {
if lastMessage.Role == "user" { if messages[i].Role == "user" {
lastMessage.Images = imgs messages[i].Images = imgs
break
} }
} }
} }
// Build chat request
req := api.ChatRequest{
Model: model,
Messages: tt.messages,
Tools: tt.tools,
Stream: &stream,
Options: map[string]any{
"seed": 42,
"temperature": 0.0,
},
}
isRemote := os.Getenv("OLLAMA_TEST_EXISTING") != ""
// Use integration helpers
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel() defer cancel()
client, _, cleanup := InitServerConnection(ctx, t) client, _, cleanup := InitServerConnection(ctx, t)
defer cleanup() defer cleanup()
// Skip pulling/preloading when using an existing (cloud) server // Pull/preload model if not using remote server
if !isRemote { if os.Getenv("OLLAMA_TEST_EXISTING") == "" {
if err := PullIfMissing(ctx, client, req.Model); err != nil { if err := PullIfMissing(ctx, client, model); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Preload model once to reduce startup latency // Preload to reduce startup latency
_ = client.Generate(ctx, &api.GenerateRequest{Model: req.Model}, func(r api.GenerateResponse) error { return nil }) _ = client.Generate(ctx, &api.GenerateRequest{Model: model}, func(api.GenerateResponse) error { return nil })
}
// Build and execute chat request
req := &api.ChatRequest{
Model: model,
Messages: messages,
Tools: tt.tools,
Stream: &stream,
Options: map[string]any{"seed": 42, "temperature": 0.0},
} }
var contentBuf, thinkingBuf strings.Builder var contentBuf, thinkingBuf strings.Builder
var gotCalls []api.ToolCall var toolCalls []api.ToolCall
err := client.Chat(ctx, &req, func(r api.ChatResponse) error { err := client.Chat(ctx, req, func(r api.ChatResponse) error {
contentBuf.WriteString(r.Message.Content) contentBuf.WriteString(r.Message.Content)
thinkingBuf.WriteString(r.Message.Thinking) thinkingBuf.WriteString(r.Message.Thinking)
if len(r.Message.ToolCalls) > 0 { toolCalls = append(toolCalls, r.Message.ToolCalls...)
gotCalls = append(gotCalls, r.Message.ToolCalls...)
}
return nil return nil
}) })
if err != nil { if err != nil {
t.Fatalf("chat error: %v", err) t.Fatalf("chat error: %v", err)
} }
// Log responses (truncated) // Log truncated responses
content := contentBuf.String() logTruncated := func(label, text string) {
thinking := thinkingBuf.String() if text != "" {
const maxLog = 800 if len(text) > 800 {
if len(thinking) > 0 { text = text[:800] + "... [truncated]"
if len(thinking) > maxLog {
thinking = thinking[:maxLog] + "... [truncated]"
} }
t.Logf("Thinking: %s", thinking) t.Logf("%s: %s", label, text)
} }
if len(content) > 0 {
if len(content) > maxLog {
content = content[:maxLog] + "... [truncated]"
} }
t.Logf("Content: %s", content) logTruncated("Thinking", thinkingBuf.String())
} logTruncated("Content", contentBuf.String())
if len(gotCalls) > 0 {
t.Logf("Tool calls: %d", len(gotCalls)) if len(toolCalls) > 0 {
for i, call := range gotCalls { t.Logf("Tool calls: %d", len(toolCalls))
for i, call := range toolCalls {
t.Logf(" [%d] %s(%+v)", i, call.Function.Name, call.Function.Arguments) t.Logf(" [%d] %s(%+v)", i, call.Function.Name, call.Function.Arguments)
} }
} }
// If this is a tools scenario, validate tool_calls // Validate tool calls if tools were provided
if len(tt.tools) > 0 { if len(tt.tools) > 0 {
if len(gotCalls) == 0 { if len(toolCalls) == 0 {
t.Fatalf("expected at least one tool call, got none") t.Fatal("expected at least one tool call, got none")
} }
if gotCalls[0].Function.Name == "" { if toolCalls[0].Function.Name == "" {
t.Fatalf("tool call missing function name: %#v", gotCalls[0]) t.Fatalf("tool call missing function name: %#v", toolCalls[0])
} }
} }
}) })
} }
}
} }
// loadImageData loads image data from a file path // loadImageData loads image data from a file path

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB