mirror of https://github.com/ollama/ollama
renderers: add olmo3.1 and olmo3 fixes (#13447)
This commit is contained in:
parent
8dbc9e7b68
commit
e3731fb160
|
|
@ -10,12 +10,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
olmo3DefaultSystemMessage = "You are a helpful function-calling AI assistant. "
|
olmo3DefaultSystemMessage = "You are a helpful function-calling AI assistant. "
|
||||||
olmo3NoFunctionsMessage = "You do not currently have access to any functions. "
|
olmo31DefaultSystemMessage = "You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai. "
|
||||||
olmo3WithFunctionsMessage = "You are provided with function signatures within <functions></functions> XML tags. You may call one or more functions to assist with the user query. Output any function calls within <function_calls></function_calls> XML tags. Do not make assumptions about what values to plug into functions."
|
olmo3NoFunctionsMessage = "You do not currently have access to any functions. "
|
||||||
|
olmo3WithFunctionsMessage = "You are provided with function signatures within <functions></functions> XML tags. You may call one or more functions to assist with the user query. Output any function calls within <function_calls></function_calls> XML tags. Do not make assumptions about what values to plug into functions."
|
||||||
)
|
)
|
||||||
|
|
||||||
type Olmo3Renderer struct{}
|
type Olmo3Renderer struct {
|
||||||
|
UseExtendedSystemMessage bool
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Olmo3Renderer) Render(messages []api.Message, tools []api.Tool, _ *api.ThinkValue) (string, error) {
|
func (r *Olmo3Renderer) Render(messages []api.Message, tools []api.Tool, _ *api.ThinkValue) (string, error) {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
|
@ -51,7 +54,11 @@ func (r *Olmo3Renderer) Render(messages []api.Message, tools []api.Tool, _ *api.
|
||||||
} else {
|
} else {
|
||||||
// Default system message - single newline after "system"
|
// Default system message - single newline after "system"
|
||||||
sb.WriteString("<|im_start|>system\n")
|
sb.WriteString("<|im_start|>system\n")
|
||||||
sb.WriteString(olmo3DefaultSystemMessage)
|
if r.UseExtendedSystemMessage {
|
||||||
|
sb.WriteString(olmo31DefaultSystemMessage)
|
||||||
|
} else {
|
||||||
|
sb.WriteString(olmo3DefaultSystemMessage)
|
||||||
|
}
|
||||||
|
|
||||||
if len(tools) > 0 {
|
if len(tools) > 0 {
|
||||||
functionsJSON, err := marshalWithSpaces(tools)
|
functionsJSON, err := marshalWithSpaces(tools)
|
||||||
|
|
@ -140,7 +147,7 @@ func (r *Olmo3Renderer) Render(messages []api.Message, tools []api.Tool, _ *api.
|
||||||
}
|
}
|
||||||
|
|
||||||
if needsGenerationPrompt {
|
if needsGenerationPrompt {
|
||||||
sb.WriteString("<|im_start|>assistant\n\n")
|
sb.WriteString("<|im_start|>assistant\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.String(), nil
|
return sb.String(), nil
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
"You are a helpful function-calling AI assistant. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
"You are a helpful function-calling AI assistant. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Hello!<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with system message no tools",
|
name: "with system message no tools",
|
||||||
|
|
@ -36,7 +36,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
"You are a helpful assistant.<|im_end|>\n" +
|
"You are a helpful assistant.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Hello!<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with system message and tools",
|
name: "with system message and tools",
|
||||||
|
|
@ -64,7 +64,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
`You are a helpful assistant.<functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
`You are a helpful assistant.<functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"What is the weather?<|im_end|>\n" +
|
"What is the weather?<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default system with tools - includes function instruction",
|
name: "default system with tools - includes function instruction",
|
||||||
|
|
@ -93,7 +93,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
`<functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
`<functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"What is the weather?<|im_end|>\n" +
|
"What is the weather?<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "assistant with tool calls - function call syntax",
|
name: "assistant with tool calls - function call syntax",
|
||||||
|
|
@ -141,7 +141,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
`Let me check the weather.<function_calls>get_weather(location="San Francisco")</function_calls><|im_end|>` + "\n" +
|
`Let me check the weather.<function_calls>get_weather(location="San Francisco")</function_calls><|im_end|>` + "\n" +
|
||||||
"<|im_start|>environment\n" +
|
"<|im_start|>environment\n" +
|
||||||
`{"temperature": 68}<|im_end|>` + "\n" +
|
`{"temperature": 68}<|im_end|>` + "\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multi-turn conversation",
|
name: "multi-turn conversation",
|
||||||
|
|
@ -159,7 +159,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
"Hi there!<|im_end|>\n" +
|
"Hi there!<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"How are you?<|im_end|>\n" +
|
"How are you?<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "parallel tool calls - newline separated",
|
name: "parallel tool calls - newline separated",
|
||||||
|
|
@ -214,7 +214,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
`{"temperature": 68}<|im_end|>` + "\n" +
|
`{"temperature": 68}<|im_end|>` + "\n" +
|
||||||
"<|im_start|>environment\n" +
|
"<|im_start|>environment\n" +
|
||||||
`{"temperature": 55}<|im_end|>` + "\n" +
|
`{"temperature": 55}<|im_end|>` + "\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "tool call with multiple arguments",
|
name: "tool call with multiple arguments",
|
||||||
|
|
@ -259,7 +259,7 @@ func TestOlmo3Renderer(t *testing.T) {
|
||||||
"Book a flight<|im_end|>\n" +
|
"Book a flight<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
`<function_calls>book_flight(from="SFO", to="NYC")</function_calls><|im_end|>` + "\n" +
|
`<function_calls>book_flight(from="SFO", to="NYC")</function_calls><|im_end|>` + "\n" +
|
||||||
"<|im_start|>assistant\n\n",
|
"<|im_start|>assistant\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "assistant prefill - no generation prompt",
|
name: "assistant prefill - no generation prompt",
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,31 @@
|
||||||
package renderers
|
package renderers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ollama/ollama/api"
|
"github.com/ollama/ollama/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Olmo3ThinkVariant int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
olmo3ThinkDefaultSystemMessage = "You are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai."
|
// Olmo3Think32B is for allenai/Olmo-3-32B-Think
|
||||||
olmo3ThinkNoFunctionsMessage = " You do not currently have access to any functions."
|
Olmo3Think32B Olmo3ThinkVariant = iota
|
||||||
|
// Olmo31Think is for allenai/Olmo-3-7B-Think and allenai/Olmo-3.1-32B-Think (includes model info)
|
||||||
|
Olmo31Think
|
||||||
)
|
)
|
||||||
|
|
||||||
type Olmo3ThinkRenderer struct{}
|
const (
|
||||||
|
olmo3ThinkFunctionsSuffix = " You do not currently have access to any functions. <functions></functions>"
|
||||||
|
olmo3Think32BSystemMessage = "You are a helpful AI assistant."
|
||||||
|
olmo31ThinkSystemMessage = "You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai."
|
||||||
|
)
|
||||||
|
|
||||||
type olmo3ThinkToolCall struct {
|
type Olmo3ThinkRenderer struct {
|
||||||
ID string `json:"id,omitempty"`
|
Variant Olmo3ThinkVariant
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
Function olmo3ThinkToolCallFunc `json:"function"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type olmo3ThinkToolCallFunc struct {
|
func (r *Olmo3ThinkRenderer) Render(messages []api.Message, _ []api.Tool, _ *api.ThinkValue) (string, error) {
|
||||||
Name string `json:"name"`
|
|
||||||
Arguments string `json:"arguments"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Olmo3ThinkRenderer) Render(messages []api.Message, tools []api.Tool, _ *api.ThinkValue) (string, error) {
|
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
|
||||||
var systemMessage *api.Message
|
var systemMessage *api.Message
|
||||||
|
|
@ -37,34 +37,31 @@ func (r *Olmo3ThinkRenderer) Render(messages []api.Message, tools []api.Tool, _
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Skip tool messages - Think models don't support tools
|
||||||
|
if message.Role == "tool" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
filteredMessages = append(filteredMessages, message)
|
filteredMessages = append(filteredMessages, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
systemContent := olmo3ThinkDefaultSystemMessage
|
|
||||||
if systemMessage != nil {
|
|
||||||
systemContent = systemMessage.Content
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.WriteString("<|im_start|>system\n")
|
sb.WriteString("<|im_start|>system\n")
|
||||||
sb.WriteString(systemContent)
|
|
||||||
|
|
||||||
if len(tools) > 0 {
|
if systemMessage != nil {
|
||||||
functionsJSON, err := marshalWithSpaces(tools)
|
sb.WriteString(systemMessage.Content)
|
||||||
if err != nil {
|
sb.WriteString(olmo3ThinkFunctionsSuffix)
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
sb.WriteString(" <functions>")
|
|
||||||
sb.WriteString(string(functionsJSON))
|
|
||||||
sb.WriteString("</functions>")
|
|
||||||
} else {
|
} else {
|
||||||
sb.WriteString(olmo3ThinkNoFunctionsMessage)
|
// Default system message varies by variant
|
||||||
sb.WriteString(" <functions></functions>")
|
switch r.Variant {
|
||||||
|
case Olmo3Think32B:
|
||||||
|
sb.WriteString(olmo3Think32BSystemMessage)
|
||||||
|
default: // Olmo3Think7B, Olmo31Think use same template - diverges from HF but confirmed difference from team
|
||||||
|
sb.WriteString(olmo31ThinkSystemMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.WriteString("<|im_end|>\n")
|
sb.WriteString("<|im_end|>\n")
|
||||||
|
|
||||||
for i, message := range filteredMessages {
|
for _, message := range filteredMessages {
|
||||||
lastMessage := i == len(filteredMessages)-1
|
|
||||||
|
|
||||||
switch message.Role {
|
switch message.Role {
|
||||||
case "user":
|
case "user":
|
||||||
sb.WriteString("<|im_start|>user\n")
|
sb.WriteString("<|im_start|>user\n")
|
||||||
|
|
@ -73,58 +70,15 @@ func (r *Olmo3ThinkRenderer) Render(messages []api.Message, tools []api.Tool, _
|
||||||
|
|
||||||
case "assistant":
|
case "assistant":
|
||||||
sb.WriteString("<|im_start|>assistant\n")
|
sb.WriteString("<|im_start|>assistant\n")
|
||||||
|
|
||||||
if message.Content != "" {
|
if message.Content != "" {
|
||||||
sb.WriteString(message.Content)
|
sb.WriteString(message.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(message.ToolCalls) > 0 {
|
|
||||||
toolCalls := make([]olmo3ThinkToolCall, len(message.ToolCalls))
|
|
||||||
for j, tc := range message.ToolCalls {
|
|
||||||
argsJSON, err := json.Marshal(tc.Function.Arguments)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
toolCalls[j] = olmo3ThinkToolCall{
|
|
||||||
ID: tc.ID,
|
|
||||||
Type: "function",
|
|
||||||
Function: olmo3ThinkToolCallFunc{
|
|
||||||
Name: tc.Function.Name,
|
|
||||||
Arguments: string(argsJSON),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toolCallsJSON, err := marshalWithSpaces(toolCalls)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
sb.WriteString("<function_calls>")
|
|
||||||
sb.WriteString(string(toolCallsJSON))
|
|
||||||
sb.WriteString("</function_calls>")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !lastMessage {
|
|
||||||
sb.WriteString("<|im_end|>\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
case "tool":
|
|
||||||
sb.WriteString("<|im_start|>environment\n")
|
|
||||||
sb.WriteString(message.Content)
|
|
||||||
sb.WriteString("<|im_end|>\n")
|
sb.WriteString("<|im_end|>\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
needsGenerationPrompt := true
|
// Always add generation prompt with <think> tag for thinking models
|
||||||
if len(filteredMessages) > 0 {
|
sb.WriteString("<|im_start|>assistant\n<think>")
|
||||||
lastMsg := filteredMessages[len(filteredMessages)-1]
|
|
||||||
if lastMsg.Role == "assistant" && len(lastMsg.ToolCalls) == 0 && lastMsg.Content != "" {
|
|
||||||
needsGenerationPrompt = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if needsGenerationPrompt {
|
|
||||||
sb.WriteString("<|im_start|>assistant\n<think>")
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.String(), nil
|
return sb.String(), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,24 +11,27 @@ import (
|
||||||
func TestOlmo3ThinkRenderer(t *testing.T) {
|
func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
variant Olmo3ThinkVariant
|
||||||
msgs []api.Message
|
msgs []api.Message
|
||||||
tools []api.Tool
|
tools []api.Tool
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "basic without system - adds default system",
|
name: "7b_basic_without_system",
|
||||||
|
variant: Olmo31Think,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "user", Content: "Hello!"},
|
{Role: "user", Content: "Hello!"},
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
"You are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
"You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Hello!<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with system message no tools",
|
name: "7b_with_custom_system",
|
||||||
|
variant: Olmo31Think,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "system", Content: "You are a helpful assistant."},
|
{Role: "system", Content: "You are a helpful assistant."},
|
||||||
{Role: "user", Content: "Hello!"},
|
{Role: "user", Content: "Hello!"},
|
||||||
|
|
@ -41,9 +44,9 @@ func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with system message and tools",
|
name: "7b_tools_ignored",
|
||||||
|
variant: Olmo31Think,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "system", Content: "You are a helpful assistant."},
|
|
||||||
{Role: "user", Content: "What is the weather?"},
|
{Role: "user", Content: "What is the weather?"},
|
||||||
},
|
},
|
||||||
tools: []api.Tool{
|
tools: []api.Tool{
|
||||||
|
|
@ -52,27 +55,20 @@ func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
Function: api.ToolFunction{
|
Function: api.ToolFunction{
|
||||||
Name: "get_weather",
|
Name: "get_weather",
|
||||||
Description: "Get the current weather",
|
Description: "Get the current weather",
|
||||||
Parameters: api.ToolFunctionParameters{
|
|
||||||
Type: "object",
|
|
||||||
Required: []string{"location"},
|
|
||||||
Properties: map[string]api.ToolProperty{
|
|
||||||
"location": {Type: api.PropertyType{"string"}, Description: "The city"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
`You are a helpful assistant. <functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
"You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"What is the weather?<|im_end|>\n" +
|
"What is the weather?<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "assistant with tool calls",
|
name: "7b_tool_calls_and_tool_messages_ignored",
|
||||||
|
variant: Olmo31Think,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "system", Content: "You are a helpful assistant."},
|
|
||||||
{Role: "user", Content: "What is the weather in SF?"},
|
{Role: "user", Content: "What is the weather in SF?"},
|
||||||
{
|
{
|
||||||
Role: "assistant",
|
Role: "assistant",
|
||||||
|
|
@ -81,53 +77,33 @@ func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
{
|
{
|
||||||
ID: "call_1",
|
ID: "call_1",
|
||||||
Function: api.ToolCallFunction{
|
Function: api.ToolCallFunction{
|
||||||
Name: "get_weather",
|
Name: "get_weather",
|
||||||
Arguments: map[string]any{
|
Arguments: map[string]any{"location": "San Francisco"},
|
||||||
"location": "San Francisco",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{Role: "tool", Content: `{"temperature": 68}`, ToolName: "get_weather"},
|
|
||||||
},
|
|
||||||
tools: []api.Tool{
|
|
||||||
{
|
|
||||||
Type: "function",
|
|
||||||
Function: api.ToolFunction{
|
|
||||||
Name: "get_weather",
|
|
||||||
Description: "Get the current weather",
|
|
||||||
Parameters: api.ToolFunctionParameters{
|
|
||||||
Type: "object",
|
|
||||||
Required: []string{"location"},
|
|
||||||
Properties: map[string]api.ToolProperty{
|
|
||||||
"location": {Type: api.PropertyType{"string"}, Description: "The city"},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{Role: "tool", Content: `{"temperature": 68}`},
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
`You are a helpful assistant. <functions>[{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather", "parameters": {"type": "object", "required": ["location"], "properties": {"location": {"type": "string", "description": "The city"}}}}}]</functions><|im_end|>` + "\n" +
|
"You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"What is the weather in SF?<|im_end|>\n" +
|
"What is the weather in SF?<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
`Let me check the weather.<function_calls>[{"id": "call_1", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\":\"San Francisco\"}"}}]</function_calls><|im_end|>` + "\n" +
|
"Let me check the weather.<|im_end|>\n" +
|
||||||
"<|im_start|>environment\n" +
|
|
||||||
`{"temperature": 68}<|im_end|>` + "\n" +
|
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multi-turn conversation",
|
name: "7b_multi_turn_conversation",
|
||||||
|
variant: Olmo31Think,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "system", Content: "You are a helpful assistant."},
|
|
||||||
{Role: "user", Content: "Hello"},
|
{Role: "user", Content: "Hello"},
|
||||||
{Role: "assistant", Content: "Hi there!"},
|
{Role: "assistant", Content: "Hi there!"},
|
||||||
{Role: "user", Content: "How are you?"},
|
{Role: "user", Content: "How are you?"},
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
"You are a helpful assistant. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
"You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Hello<|im_end|>\n" +
|
"Hello<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
|
|
@ -138,73 +114,56 @@ func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "parallel tool calls",
|
name: "32b_basic_without_system",
|
||||||
|
variant: Olmo3Think32B,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "user", Content: "Get weather in SF and NYC"},
|
{Role: "user", Content: "Hello!"},
|
||||||
{
|
|
||||||
Role: "assistant",
|
|
||||||
ToolCalls: []api.ToolCall{
|
|
||||||
{
|
|
||||||
ID: "call_1",
|
|
||||||
Function: api.ToolCallFunction{
|
|
||||||
Name: "get_weather",
|
|
||||||
Arguments: map[string]any{"location": "San Francisco"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "call_2",
|
|
||||||
Function: api.ToolCallFunction{
|
|
||||||
Name: "get_weather",
|
|
||||||
Arguments: map[string]any{"location": "New York"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{Role: "tool", Content: `{"temperature": 68}`, ToolName: "get_weather"},
|
|
||||||
{Role: "tool", Content: `{"temperature": 55}`, ToolName: "get_weather"},
|
|
||||||
},
|
|
||||||
tools: []api.Tool{
|
|
||||||
{
|
|
||||||
Type: "function",
|
|
||||||
Function: api.ToolFunction{
|
|
||||||
Name: "get_weather",
|
|
||||||
Parameters: api.ToolFunctionParameters{
|
|
||||||
Type: "object",
|
|
||||||
Properties: map[string]api.ToolProperty{
|
|
||||||
"location": {Type: api.PropertyType{"string"}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
`You are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai. <functions>[{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"location": {"type": "string"}}}}}]</functions><|im_end|>` + "\n" +
|
"You are a helpful AI assistant.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Get weather in SF and NYC<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
|
||||||
`<function_calls>[{"id": "call_1", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\":\"San Francisco\"}"}}, {"id": "call_2", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\":\"New York\"}"}}]</function_calls><|im_end|>` + "\n" +
|
|
||||||
"<|im_start|>environment\n" +
|
|
||||||
`{"temperature": 68}<|im_end|>` + "\n" +
|
|
||||||
"<|im_start|>environment\n" +
|
|
||||||
`{"temperature": 55}<|im_end|>` + "\n" +
|
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "assistant message only content no tool calls",
|
name: "32b_with_custom_system_gets_suffix",
|
||||||
|
variant: Olmo3Think32B,
|
||||||
msgs: []api.Message{
|
msgs: []api.Message{
|
||||||
{Role: "user", Content: "Tell me a joke"},
|
{Role: "system", Content: "You are a helpful assistant."},
|
||||||
{Role: "assistant", Content: "Why did the chicken cross the road?"},
|
{Role: "user", Content: "Hello!"},
|
||||||
{Role: "user", Content: "I don't know, why?"},
|
|
||||||
},
|
},
|
||||||
expected: "<|im_start|>system\n" +
|
expected: "<|im_start|>system\n" +
|
||||||
"You are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
"You are a helpful assistant. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"Tell me a joke<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"Why did the chicken cross the road?<|im_end|>\n" +
|
"<think>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "31_basic_without_system",
|
||||||
|
variant: Olmo31Think,
|
||||||
|
msgs: []api.Message{
|
||||||
|
{Role: "user", Content: "Hello!"},
|
||||||
|
},
|
||||||
|
expected: "<|im_start|>system\n" +
|
||||||
|
"You are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n" +
|
||||||
"<|im_start|>user\n" +
|
"<|im_start|>user\n" +
|
||||||
"I don't know, why?<|im_end|>\n" +
|
"Hello!<|im_end|>\n" +
|
||||||
|
"<|im_start|>assistant\n" +
|
||||||
|
"<think>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "31_with_custom_system_gets_suffix",
|
||||||
|
variant: Olmo31Think,
|
||||||
|
msgs: []api.Message{
|
||||||
|
{Role: "system", Content: "You are a helpful assistant."},
|
||||||
|
{Role: "user", Content: "Hello!"},
|
||||||
|
},
|
||||||
|
expected: "<|im_start|>system\n" +
|
||||||
|
"You are a helpful assistant. You do not currently have access to any functions. <functions></functions><|im_end|>\n" +
|
||||||
|
"<|im_start|>user\n" +
|
||||||
|
"Hello!<|im_end|>\n" +
|
||||||
"<|im_start|>assistant\n" +
|
"<|im_start|>assistant\n" +
|
||||||
"<think>",
|
"<think>",
|
||||||
},
|
},
|
||||||
|
|
@ -212,7 +171,7 @@ func TestOlmo3ThinkRenderer(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
rendered, err := (&Olmo3ThinkRenderer{}).Render(tt.msgs, tt.tools, nil)
|
rendered, err := (&Olmo3ThinkRenderer{Variant: tt.variant}).Render(tt.msgs, tt.tools, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,18 @@ func rendererForName(name string) Renderer {
|
||||||
renderer := &CogitoRenderer{isThinking: true}
|
renderer := &CogitoRenderer{isThinking: true}
|
||||||
return renderer
|
return renderer
|
||||||
case "olmo3":
|
case "olmo3":
|
||||||
renderer := &Olmo3Renderer{}
|
renderer := &Olmo3Renderer{UseExtendedSystemMessage: false}
|
||||||
|
return renderer
|
||||||
|
case "olmo3.1":
|
||||||
|
renderer := &Olmo3Renderer{UseExtendedSystemMessage: true}
|
||||||
return renderer
|
return renderer
|
||||||
case "olmo3-think":
|
case "olmo3-think":
|
||||||
renderer := &Olmo3ThinkRenderer{}
|
// Used for Olmo-3-7B-Think and Olmo-3.1-32B-Think (same template)
|
||||||
|
renderer := &Olmo3ThinkRenderer{Variant: Olmo31Think}
|
||||||
|
return renderer
|
||||||
|
case "olmo3-32b-think":
|
||||||
|
// Used for Olmo-3-32B-Think
|
||||||
|
renderer := &Olmo3ThinkRenderer{Variant: Olmo3Think32B}
|
||||||
return renderer
|
return renderer
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue