mirror of
https://github.com/ollama/ollama.git
synced 2025-08-24 16:41:13 +02:00
fix(openai): handle reasoning_effort (#11868)
This commit is contained in:
@@ -769,8 +769,8 @@ func (t *ThinkValue) IsString() bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsBool returns the value as a bool (true if enabled in any way)
|
// Bool returns the value as a bool (true if enabled in any way)
|
||||||
func (t *ThinkValue) AsBool() bool {
|
func (t *ThinkValue) Bool() bool {
|
||||||
if t == nil || t.Value == nil {
|
if t == nil || t.Value == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -786,8 +786,8 @@ func (t *ThinkValue) AsBool() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsString returns the value as a string
|
// String returns the value as a string
|
||||||
func (t *ThinkValue) AsString() string {
|
func (t *ThinkValue) String() string {
|
||||||
if t == nil || t.Value == nil {
|
if t == nil || t.Value == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@@ -103,6 +103,7 @@ type ChatCompletionRequest struct {
|
|||||||
ResponseFormat *ResponseFormat `json:"response_format"`
|
ResponseFormat *ResponseFormat `json:"response_format"`
|
||||||
Tools []api.Tool `json:"tools"`
|
Tools []api.Tool `json:"tools"`
|
||||||
Reasoning *Reasoning `json:"reasoning,omitempty"`
|
Reasoning *Reasoning `json:"reasoning,omitempty"`
|
||||||
|
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatCompletion struct {
|
type ChatCompletion struct {
|
||||||
@@ -541,10 +542,6 @@ func fromChatRequest(r ChatCompletionRequest) (*api.ChatRequest, error) {
|
|||||||
options["top_p"] = 1.0
|
options["top_p"] = 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Reasoning != nil {
|
|
||||||
options["reasoning"] = *r.Reasoning.Effort
|
|
||||||
}
|
|
||||||
|
|
||||||
var format json.RawMessage
|
var format json.RawMessage
|
||||||
if r.ResponseFormat != nil {
|
if r.ResponseFormat != nil {
|
||||||
switch strings.ToLower(strings.TrimSpace(r.ResponseFormat.Type)) {
|
switch strings.ToLower(strings.TrimSpace(r.ResponseFormat.Type)) {
|
||||||
@@ -560,9 +557,15 @@ func fromChatRequest(r ChatCompletionRequest) (*api.ChatRequest, error) {
|
|||||||
|
|
||||||
var think *api.ThinkValue
|
var think *api.ThinkValue
|
||||||
if r.Reasoning != nil {
|
if r.Reasoning != nil {
|
||||||
|
options["reasoning"] = *r.Reasoning.Effort
|
||||||
think = &api.ThinkValue{
|
think = &api.ThinkValue{
|
||||||
Value: *r.Reasoning.Effort,
|
Value: *r.Reasoning.Effort,
|
||||||
}
|
}
|
||||||
|
} else if r.ReasoningEffort != nil {
|
||||||
|
options["reasoning"] = *r.ReasoningEffort
|
||||||
|
think = &api.ThinkValue{
|
||||||
|
Value: *r.ReasoningEffort,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &api.ChatRequest{
|
return &api.ChatRequest{
|
||||||
|
@@ -44,8 +44,8 @@ func chatPrompt(ctx context.Context, m *Model, tokenize tokenizeFunc, opts *api.
|
|||||||
thinkVal := false
|
thinkVal := false
|
||||||
thinkLevel := ""
|
thinkLevel := ""
|
||||||
if think != nil {
|
if think != nil {
|
||||||
thinkVal = think.AsBool()
|
thinkVal = think.Bool()
|
||||||
thinkLevel = think.AsString()
|
thinkLevel = think.String()
|
||||||
}
|
}
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
if err := m.Template.Execute(&b, template.Values{Messages: append(system, msgs[i:]...), Tools: tools, Think: thinkVal, ThinkLevel: thinkLevel, IsThinkSet: think != nil}); err != nil {
|
if err := m.Template.Execute(&b, template.Values{Messages: append(system, msgs[i:]...), Tools: tools, Think: thinkVal, ThinkLevel: thinkLevel, IsThinkSet: think != nil}); err != nil {
|
||||||
@@ -105,8 +105,8 @@ func chatPrompt(ctx context.Context, m *Model, tokenize tokenizeFunc, opts *api.
|
|||||||
thinkVal := false
|
thinkVal := false
|
||||||
thinkLevel := ""
|
thinkLevel := ""
|
||||||
if think != nil {
|
if think != nil {
|
||||||
thinkVal = think.AsBool()
|
thinkVal = think.Bool()
|
||||||
thinkLevel = think.AsString()
|
thinkLevel = think.String()
|
||||||
}
|
}
|
||||||
if err := m.Template.Execute(&b, template.Values{Messages: append(system, msgs[currMsgIdx:]...), Tools: tools, Think: thinkVal, ThinkLevel: thinkLevel, IsThinkSet: think != nil}); err != nil {
|
if err := m.Template.Execute(&b, template.Values{Messages: append(system, msgs[currMsgIdx:]...), Tools: tools, Think: thinkVal, ThinkLevel: thinkLevel, IsThinkSet: think != nil}); err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
|
@@ -205,7 +205,7 @@ func (s *Server) GenerateHandler(c *gin.Context) {
|
|||||||
|
|
||||||
// Validate Think value: string values currently only allowed for gptoss models
|
// Validate Think value: string values currently only allowed for gptoss models
|
||||||
if req.Think != nil && req.Think.IsString() && !useHarmony {
|
if req.Think != nil && req.Think.IsString() && !useHarmony {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("think value %q is not supported for this model", req.Think.AsString())})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("think value %q is not supported for this model", req.Think.String())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ func (s *Server) GenerateHandler(c *gin.Context) {
|
|||||||
if req.Suffix != "" {
|
if req.Suffix != "" {
|
||||||
caps = append(caps, model.CapabilityInsert)
|
caps = append(caps, model.CapabilityInsert)
|
||||||
}
|
}
|
||||||
if req.Think != nil && req.Think.AsBool() {
|
if req.Think != nil && req.Think.Bool() {
|
||||||
caps = append(caps, model.CapabilityThinking)
|
caps = append(caps, model.CapabilityThinking)
|
||||||
// TODO(drifkin): consider adding a warning if it's false and the model
|
// TODO(drifkin): consider adding a warning if it's false and the model
|
||||||
// doesn't support thinking. It's not strictly required, but it can be a
|
// doesn't support thinking. It's not strictly required, but it can be a
|
||||||
@@ -288,10 +288,10 @@ func (s *Server) GenerateHandler(c *gin.Context) {
|
|||||||
values.Messages = append(msgs, api.Message{Role: "user", Content: req.Prompt})
|
values.Messages = append(msgs, api.Message{Role: "user", Content: req.Prompt})
|
||||||
}
|
}
|
||||||
|
|
||||||
values.Think = req.Think != nil && req.Think.AsBool()
|
values.Think = req.Think != nil && req.Think.Bool()
|
||||||
values.ThinkLevel = ""
|
values.ThinkLevel = ""
|
||||||
if req.Think != nil {
|
if req.Think != nil {
|
||||||
values.ThinkLevel = req.Think.AsString()
|
values.ThinkLevel = req.Think.String()
|
||||||
}
|
}
|
||||||
values.IsThinkSet = req.Think != nil
|
values.IsThinkSet = req.Think != nil
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ func (s *Server) GenerateHandler(c *gin.Context) {
|
|||||||
var thinkingState *thinking.Parser
|
var thinkingState *thinking.Parser
|
||||||
if !useHarmony {
|
if !useHarmony {
|
||||||
openingTag, closingTag := thinking.InferTags(m.Template.Template)
|
openingTag, closingTag := thinking.InferTags(m.Template.Template)
|
||||||
if req.Think != nil && req.Think.AsBool() && openingTag != "" && closingTag != "" {
|
if req.Think != nil && req.Think.Bool() && openingTag != "" && closingTag != "" {
|
||||||
thinkingState = &thinking.Parser{
|
thinkingState = &thinking.Parser{
|
||||||
OpeningTag: openingTag,
|
OpeningTag: openingTag,
|
||||||
ClosingTag: closingTag,
|
ClosingTag: closingTag,
|
||||||
@@ -1547,7 +1547,7 @@ func (s *Server) ChatHandler(c *gin.Context) {
|
|||||||
if len(req.Tools) > 0 {
|
if len(req.Tools) > 0 {
|
||||||
caps = append(caps, model.CapabilityTools)
|
caps = append(caps, model.CapabilityTools)
|
||||||
}
|
}
|
||||||
if req.Think != nil && req.Think.AsBool() {
|
if req.Think != nil && req.Think.Bool() {
|
||||||
caps = append(caps, model.CapabilityThinking)
|
caps = append(caps, model.CapabilityThinking)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,7 +1601,7 @@ func (s *Server) ChatHandler(c *gin.Context) {
|
|||||||
|
|
||||||
// Validate Think value: string values currently only allowed for gptoss models
|
// Validate Think value: string values currently only allowed for gptoss models
|
||||||
if req.Think != nil && req.Think.IsString() && !useHarmony {
|
if req.Think != nil && req.Think.IsString() && !useHarmony {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("think value %q is not supported for this model", req.Think.AsString())})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("think value %q is not supported for this model", req.Think.String())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,7 +1620,7 @@ func (s *Server) ChatHandler(c *gin.Context) {
|
|||||||
|
|
||||||
var thinkingState *thinking.Parser
|
var thinkingState *thinking.Parser
|
||||||
openingTag, closingTag := thinking.InferTags(m.Template.Template)
|
openingTag, closingTag := thinking.InferTags(m.Template.Template)
|
||||||
if req.Think != nil && req.Think.AsBool() && openingTag != "" && closingTag != "" {
|
if req.Think != nil && req.Think.Bool() && openingTag != "" && closingTag != "" {
|
||||||
thinkingState = &thinking.Parser{
|
thinkingState = &thinking.Parser{
|
||||||
OpeningTag: openingTag,
|
OpeningTag: openingTag,
|
||||||
ClosingTag: closingTag,
|
ClosingTag: closingTag,
|
||||||
|
Reference in New Issue
Block a user