diff --git a/model/renderers/deepseek3.go b/model/renderers/deepseek3.go
deleted file mode 100644
index 74794bac1..000000000
--- a/model/renderers/deepseek3.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package renderers
-
-import (
- "encoding/json"
- "strings"
-
- "github.com/ollama/ollama/api"
-)
-
-type DeepSeekRenderer struct {
- isThinking bool
-}
-
-func (r *DeepSeekRenderer) Render(messages []api.Message, tools []api.Tool, thinkValue *api.ThinkValue) (string, error) {
- var sb strings.Builder
-
- // thinking is enabled: model must support it AND user must request it (true)
- enableThinking := r.isThinking && (thinkValue != nil && thinkValue.Bool())
-
- var systemPrompt strings.Builder
- var conversationMessages []api.Message
- isFirstSystemPrompt := true
-
- for _, message := range messages {
- if message.Role == "system" {
- if isFirstSystemPrompt {
- systemPrompt.WriteString(message.Content)
- isFirstSystemPrompt = false
- } else {
- systemPrompt.WriteString("\n\n" + message.Content)
- }
- } else {
- conversationMessages = append(conversationMessages, message)
- }
- }
-
- sb.WriteString("<|begin▁of▁sentence|>" + systemPrompt.String())
-
- isLastUser := false
- isToolContext := false
-
- for _, message := range conversationMessages {
- switch message.Role {
- case "user":
- isToolContext = false
- isLastUser = true
- sb.WriteString("<|User|>" + message.Content)
-
- case "assistant":
- if len(message.ToolCalls) > 0 {
- if isLastUser {
- sb.WriteString("<|Assistant|>")
- }
- isLastUser = false
- isToolContext = false
-
- if message.Content != "" {
- sb.WriteString(message.Content)
- }
-
- sb.WriteString("<|tool▁calls▁begin|>")
-
- for _, toolCall := range message.ToolCalls {
- sb.WriteString("<|tool▁call▁begin|>" + toolCall.Function.Name + "<|tool▁sep|>")
-
- argsJSON, _ := json.Marshal(toolCall.Function.Arguments)
- sb.WriteString(string(argsJSON))
- sb.WriteString("<|tool▁call▁end|>")
- }
-
- sb.WriteString("<|tool▁calls▁end|><|end▁of▁sentence|>")
- } else {
- if isLastUser {
- sb.WriteString("<|Assistant|>")
- }
- isLastUser = false
-
- content := message.Content
-
- if isToolContext {
- sb.WriteString(content + "<|end▁of▁sentence|>")
- isToolContext = false
- } else {
- // Remove any existing tags from content (matching Jinja behavior)
- if strings.Contains(content, "") {
- parts := strings.SplitN(content, "", 2)
- if len(parts) > 1 {
- content = parts[1]
- }
- }
- sb.WriteString(content + "<|end▁of▁sentence|>")
- }
- }
-
- case "tool":
- isLastUser = false
- isToolContext = true
- sb.WriteString("<|tool▁output▁begin|>" + message.Content + "<|tool▁output▁end|>")
- }
- }
-
- if isLastUser && !isToolContext {
- sb.WriteString("<|Assistant|>")
- if enableThinking {
- sb.WriteString("")
- } else {
- sb.WriteString("")
- }
- }
-
- return sb.String(), nil
-}
diff --git a/model/renderers/deepseek3_test.go b/model/renderers/deepseek3_test.go
deleted file mode 100644
index 74ae86e9e..000000000
--- a/model/renderers/deepseek3_test.go
+++ /dev/null
@@ -1,330 +0,0 @@
-package renderers
-
-import (
- "testing"
-
- "github.com/google/go-cmp/cmp"
-
- "github.com/ollama/ollama/api"
-)
-
-func TestDeepSeekRenderer(t *testing.T) {
- tests := []struct {
- name string
- messages []api.Message
- tools []api.Tool
- thinkValue *api.ThinkValue
- expected string
- }{
- {
- name: "debug multi-turn conversation",
- messages: []api.Message{
- {Role: "user", Content: "hey!"},
- {Role: "assistant", Content: "Hey there! 👋 How's it going?"},
- {Role: "user", Content: "how are you?"},
- },
- thinkValue: &api.ThinkValue{Value: true},
- expected: `<|begin▁of▁sentence|><|User|>hey!<|Assistant|>Hey there! 👋 How's it going?<|end▁of▁sentence|><|User|>how are you?<|Assistant|>`,
- },
- {
- name: "historical message with thinking field",
- messages: []api.Message{
- {Role: "user", Content: "hello"},
- {
- Role: "assistant",
- Thinking: "The user is greeting me, I should respond politely.",
- Content: "Hello! How can I help you today?",
- },
- {Role: "user", Content: "thanks"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>hello<|Assistant|>Hello! How can I help you today?<|end▁of▁sentence|><|User|>thanks<|Assistant|>`,
- },
- {
- name: "conversation with thinking enabled",
- messages: []api.Message{
- {Role: "user", Content: "hey!"},
- {
- Role: "assistant",
- Content: `Hey there! 😊 How's your day going? What can I help you with today - whether it's answering
-questions, brainstorming ideas, or just having a chat?!`,
- },
- {Role: "user", Content: "chat"},
- },
- thinkValue: &api.ThinkValue{Value: true},
- expected: `<|begin▁of▁sentence|><|User|>hey!<|Assistant|>Hey there! 😊 How's your day going? What can I help you with today - whether it's answering
-questions, brainstorming ideas, or just having a chat?!<|end▁of▁sentence|><|User|>chat<|Assistant|>`,
- },
- {
- name: "basic user message",
- messages: []api.Message{
- {Role: "user", Content: "Hello, how are you?"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Hello, how are you?<|Assistant|>`,
- },
- {
- name: "basic with system message",
- messages: []api.Message{
- {Role: "system", Content: "You are a helpful assistant."},
- {Role: "user", Content: "Hello, how are you?"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|>You are a helpful assistant.<|User|>Hello, how are you?<|Assistant|>`,
- },
- {
- name: "multiple system messages",
- messages: []api.Message{
- {Role: "system", Content: "First instruction"},
- {Role: "system", Content: "Second instruction"},
- {Role: "user", Content: "Hello"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|>First instruction
-
-Second instruction<|User|>Hello<|Assistant|>`,
- },
- {
- name: "thinking enabled",
- messages: []api.Message{
- {Role: "user", Content: "Hello, how are you?"},
- },
- thinkValue: &api.ThinkValue{Value: true},
- expected: `<|begin▁of▁sentence|><|User|>Hello, how are you?<|Assistant|>`,
- },
- {
- name: "thinking enabled with system",
- messages: []api.Message{
- {Role: "system", Content: "You are a helpful assistant."},
- {Role: "user", Content: "Hello, how are you?"},
- },
- thinkValue: &api.ThinkValue{Value: true},
- expected: `<|begin▁of▁sentence|>You are a helpful assistant.<|User|>Hello, how are you?<|Assistant|>`,
- },
- {
- name: "conversation with assistant response",
- messages: []api.Message{
- {Role: "user", Content: "What is the capital of France?"},
- {Role: "assistant", Content: "The capital of France is Paris."},
- {Role: "user", Content: "Fantastic!"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>What is the capital of France?<|Assistant|>The capital of France is Paris.<|end▁of▁sentence|><|User|>Fantastic!<|Assistant|>`,
- },
- {
- name: "assistant with tool calls",
- messages: []api.Message{
- {Role: "user", Content: "What's the weather?"},
- {
- Role: "assistant",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "Paris",
- },
- },
- },
- },
- },
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>What's the weather?<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"Paris"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|>`,
- },
- {
- name: "assistant with content and tool calls",
- messages: []api.Message{
- {Role: "user", Content: "What's the weather in Paris?"},
- {
- Role: "assistant",
- Content: "I'll check the weather for you.",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "Paris",
- },
- },
- },
- },
- },
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>What's the weather in Paris?<|Assistant|>I'll check the weather for you.<|tool▁calls▁begin|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"Paris"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|>`,
- },
- {
- name: "tool response",
- messages: []api.Message{
- {Role: "user", Content: "What's the weather?"},
- {
- Role: "assistant",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "Paris",
- },
- },
- },
- },
- },
- {Role: "tool", Content: "Temperature: 22°C, Sunny"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>What's the weather?<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"Paris"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|><|tool▁output▁begin|>Temperature: 22°C, Sunny<|tool▁output▁end|>`,
- },
- {
- name: "multiple tool calls",
- messages: []api.Message{
- {Role: "user", Content: "Get weather for Paris and London"},
- {
- Role: "assistant",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "Paris",
- },
- },
- },
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "London",
- },
- },
- },
- },
- },
- {Role: "tool", Content: "Paris: 22°C, Sunny"},
- {Role: "tool", Content: "London: 18°C, Cloudy"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Get weather for Paris and London<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"Paris"}<|tool▁call▁end|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"London"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|><|tool▁output▁begin|>Paris: 22°C, Sunny<|tool▁output▁end|><|tool▁output▁begin|>London: 18°C, Cloudy<|tool▁output▁end|>`,
- },
- {
- name: "content with tag removal",
- messages: []api.Message{
- {Role: "user", Content: "Think about this"},
- {Role: "assistant", Content: "I'm thinking about this.The answer is 42."},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Think about this<|Assistant|>The answer is 42.<|end▁of▁sentence|>`,
- },
- {
- name: "empty system message",
- messages: []api.Message{
- {Role: "system", Content: ""},
- {Role: "user", Content: "Hello"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Hello<|Assistant|>`,
- },
- {
- name: "empty assistant content",
- messages: []api.Message{
- {Role: "user", Content: "Hello"},
- {Role: "assistant", Content: ""},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Hello<|Assistant|><|end▁of▁sentence|>`,
- },
- {
- name: "special characters",
- messages: []api.Message{
- {Role: "user", Content: "What about <|special|> tokens and \"quotes\"?"},
- {Role: "assistant", Content: "They're handled normally."},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>What about <|special|> tokens and "quotes"?<|Assistant|>They're handled normally.<|end▁of▁sentence|>`,
- },
- {
- name: "tool calls with null content",
- messages: []api.Message{
- {Role: "user", Content: "Get weather"},
- {
- Role: "assistant",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "get_weather",
- Arguments: api.ToolCallFunctionArguments{
- "location": "Paris",
- },
- },
- },
- },
- },
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Get weather<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>get_weather<|tool▁sep|>{"location":"Paris"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|>`,
- },
- {
- name: "assistant after tool context",
- messages: []api.Message{
- {Role: "user", Content: "Process data"},
- {
- Role: "assistant",
- ToolCalls: []api.ToolCall{
- {
- Function: api.ToolCallFunction{
- Name: "process",
- Arguments: api.ToolCallFunctionArguments{
- "data": "test",
- },
- },
- },
- },
- },
- {Role: "tool", Content: "Success"},
- {Role: "assistant", Content: "Done"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Process data<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>process<|tool▁sep|>{"data":"test"}<|tool▁call▁end|><|tool▁calls▁end|><|end▁of▁sentence|><|tool▁output▁begin|>Success<|tool▁output▁end|>Done<|end▁of▁sentence|>`,
- },
- {
- name: "no messages",
- messages: []api.Message{},
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|>`,
- },
- {
- name: "only system messages",
- messages: []api.Message{
- {Role: "system", Content: "System instruction"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|>System instruction`,
- },
- {
- name: "multiple think tags in content",
- messages: []api.Message{
- {Role: "user", Content: "Complex question"},
- {Role: "assistant", Content: "First thoughtSecond thoughtFinal answer"},
- },
- thinkValue: &api.ThinkValue{Value: false},
- expected: `<|begin▁of▁sentence|><|User|>Complex question<|Assistant|>Second thoughtFinal answer<|end▁of▁sentence|>`,
- },
- }
-
- renderer := &DeepSeekRenderer{isThinking: true}
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- rendered, err := renderer.Render(tt.messages, tt.tools, tt.thinkValue)
- if err != nil {
- t.Fatalf("Render() error = %v", err)
- }
- if tt.name == "debug multi-turn conversation" {
- t.Logf("Actual rendered output: %q", rendered)
- }
- if diff := cmp.Diff(tt.expected, rendered); diff != "" {
- t.Errorf("Render() mismatch (-want +got):\n%s", diff)
- }
- })
- }
-}
diff --git a/model/renderers/renderer.go b/model/renderers/renderer.go
index e6fede7a5..e3d797a62 100644
--- a/model/renderers/renderer.go
+++ b/model/renderers/renderer.go
@@ -59,9 +59,6 @@ func rendererForName(name string) Renderer {
case "cogito":
renderer := &CogitoRenderer{isThinking: true}
return renderer
- case "deepseek":
- renderer := &DeepSeekRenderer{isThinking: true}
- return renderer
case "olmo3":
renderer := &Olmo3Renderer{UseExtendedSystemMessage: false}
return renderer