Files
ollama/model/renderers/renderer_test.go
Daniel Hiltgen a18c230189 model: add Laguna v8 chat support and fix Metal inference (#17291)
Add a laguna-v8 renderer/parser matching the Laguna XS 2.1 template, and fix v2 handling of embedded thinking and structured tool arguments.

Prevent FP16 overflow in Metal's quantized routed-MoE prefill path by scaling the linear branch and folding the inverse into the routing scale. Other backends and token-generation paths are unchanged.

Add comprehensive v2/v8 Jinja parity and parser tests.
2026-07-21 16:06:29 -07:00

110 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package renderers
import (
"testing"
"github.com/ollama/ollama/api"
)
type mockRenderer struct{}
func (m *mockRenderer) Render(msgs []api.Message, tools []api.Tool, think *api.ThinkValue) (string, error) {
return "mock-output", nil
}
func (m *mockRenderer) LeadingBOS() string {
return ""
}
func TestRegisterCustomRenderer(t *testing.T) {
// Register a custom renderer
Register("custom-renderer", func() Renderer {
return &mockRenderer{}
})
// Retrieve and use it
result, err := RenderWithRenderer("custom-renderer", nil, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result != "mock-output" {
t.Errorf("expected 'mock-output', got %q", result)
}
}
func TestBuiltInRendererStillWorks(t *testing.T) {
tests := []struct {
name string
}{
{name: "qwen3-coder"},
{name: "qwen3.5"},
}
messages := []api.Message{
{Role: "user", Content: "Hello"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := RenderWithRenderer(tt.name, messages, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result == "" {
t.Fatalf("expected non-empty result from %s renderer", tt.name)
}
})
}
}
func TestLeadingBOSForRenderer(t *testing.T) {
tests := []struct {
name string
want string
}{
{name: "gemma4", want: "<bos>"},
{name: "gemma4-small", want: "<bos>"},
{name: "gemma4-large", want: "<bos>"},
{name: "functiongemma", want: "<bos>"},
{name: "lfm2", want: "<|startoftext|>"},
{name: "lfm2-thinking", want: "<|startoftext|>"},
{name: "laguna", want: "〈|EOS|〉"},
{name: "laguna-v8", want: "〈|EOS|〉"},
{name: "deepseek3.1", want: "<begin▁of▁sentence>"},
{name: "cogito", want: "<begin▁of▁sentence>"},
{name: "qwen3-coder", want: ""},
{name: "unknown", want: ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := LeadingBOSForRenderer(tt.name); got != tt.want {
t.Fatalf("LeadingBOSForRenderer(%q) = %q, want %q", tt.name, got, tt.want)
}
})
}
}
func TestOverrideBuiltInRenderer(t *testing.T) {
// Override the built-in renderer
Register("qwen3-coder", func() Renderer {
return &mockRenderer{}
})
// Should get the override
result, err := RenderWithRenderer("qwen3-coder", nil, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result != "mock-output" {
t.Errorf("expected 'mock-output' from override, got %q", result)
}
}
func TestUnknownRendererReturnsError(t *testing.T) {
_, err := RenderWithRenderer("nonexistent-renderer", nil, nil, nil)
if err == nil {
t.Error("expected error for unknown renderer")
}
}