Merge pull request #12461 from ollama/drifkin/qwen3-coder-tweaks

qwen3-coder: fix tool definition type rendering
This commit is contained in:
Devon Rifkin 2025-09-30 19:47:44 -07:00 committed by GitHub
commit 6b50f2b9cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 3 deletions

View File

@ -99,9 +99,7 @@ func Qwen3CoderRenderer(messages []api.Message, tools []api.Tool, _ *api.ThinkVa
sb.WriteString("\n<name>" + name + "</name>")
if len(prop.Type) > 0 {
// TODO(!!!)(drifkin): we should match the reference implementation for
// more complex types here instead of using this format
sb.WriteString("\n<type>" + prop.ToTypeScriptType() + "</type>")
sb.WriteString("\n<type>" + formatToolDefinitionType(prop.Type) + "</type>")
}
if prop.Description != "" {
@ -215,3 +213,24 @@ func formatToolCallArgument(value any) string {
return fmt.Sprintf("%v", value)
}
func formatToolDefinitionType(tp api.PropertyType) string {
if len(tp) == 0 {
return "[]"
}
if len(tp) == 1 {
return tp[0]
}
// TODO(drifkin): it would be nice to format the JSON here similarly to
// python's default json.dumps behavior (spaces after commas and colons).
// This would let us be byte-for-byte compatible with the reference
// implementation for most common inputs
jsonBytes, err := json.Marshal(tp)
if err != nil {
return "[]"
}
return string(jsonBytes)
}

View File

@ -336,3 +336,35 @@ func TestFormatToolCallArgument(t *testing.T) {
})
}
}
func TestQwen3ToolDefinitionTypes(t *testing.T) {
tests := []struct {
name string
propertyType api.PropertyType
expected string
}{
{
name: "simple",
propertyType: api.PropertyType{"string"},
expected: "string",
},
{
name: "multiple",
propertyType: api.PropertyType{"string", "number"},
expected: "[\"string\",\"number\"]",
},
{
name: "empty",
propertyType: api.PropertyType{},
expected: "[]",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := formatToolDefinitionType(tt.propertyType)
if got != tt.expected {
t.Errorf("formatToolDefinitionType() = %v, want %v", got, tt.expected)
}
})
}
}