parsers.go 1.47 KB
Newer Older
Devon Rifkin's avatar
Devon Rifkin committed
1
2
3
4
package parsers

import (
	"github.com/ollama/ollama/api"
5
	"github.com/ollama/ollama/harmony"
Devon Rifkin's avatar
Devon Rifkin committed
6
7
)

Devon Rifkin's avatar
Devon Rifkin committed
8
type Parser interface {
9
10
11
12
13
14
	// Init initializes the parser with tools and optional last message for chat prefill
	// Returns processed tools if the parser needs to modify them (e.g., harmony renames them)
	Init(tools []api.Tool, lastMessage *api.Message) []api.Tool
	// Add processes streamed content and returns parsed content, thinking, and tool calls
	// The done flag indicates if this is the last chunk (used for draining accumulators)
	Add(s string, done bool) (content string, thinking string, calls []api.ToolCall, err error)
Devon Rifkin's avatar
Devon Rifkin committed
15
16
17
18
	HasToolSupport() bool
	HasThinkingSupport() bool
}

Devon Rifkin's avatar
Devon Rifkin committed
19
func ParserForName(name string) Parser {
Devon Rifkin's avatar
Devon Rifkin committed
20
21
22
23
	switch name {
	case "qwen3-coder":
		parser := &Qwen3CoderParser{}
		return parser
24
25
26
	case "qwen3-vl-instruct":
		parser := &Qwen3VLParser{hasThinkingSupport: false}
		return parser
Devon Rifkin's avatar
Devon Rifkin committed
27
28
	case "passthrough":
		return &PassthroughParser{}
29
30
	case "harmony":
		return harmony.NewHarmonyMessageHandler()
Devon Rifkin's avatar
Devon Rifkin committed
31
32
33
34
35
36
37
	default:
		return nil
	}
}

type PassthroughParser struct{}

38
39
40
41
42
func (p *PassthroughParser) Init(tools []api.Tool, lastMessage *api.Message) []api.Tool {
	return tools // passthrough doesn't modify tools
}

func (p *PassthroughParser) Add(s string, done bool) (content string, thinking string, calls []api.ToolCall, err error) {
Devon Rifkin's avatar
Devon Rifkin committed
43
44
45
46
47
48
49
50
51
52
	return s, "", nil, nil
}

func (p *PassthroughParser) HasToolSupport() bool {
	return false
}

func (p *PassthroughParser) HasThinkingSupport() bool {
	return false
}