diff --git a/model/renderers/glmocr.go b/model/renderers/glmocr.go
index e7910f6a5..2888750ac 100644
--- a/model/renderers/glmocr.go
+++ b/model/renderers/glmocr.go
@@ -46,12 +46,11 @@ func (r *GlmOcrRenderer) Render(messages []api.Message, tools []api.Tool, thinkV
sb.WriteString("{function-name}{arg-key-1}{arg-value-1}{arg-key-2}{arg-value-2}...")
}
- enableThinking := false
- thinkingExplicitlySet := false
- if thinkValue != nil {
- enableThinking = thinkValue.Bool()
- thinkingExplicitlySet = true
- }
+ // thinkValue is accepted for renderer interface parity. Do not inject
+ // /nothink or an empty generation when thinking is off —
+ // ResolveThinking fills Default:false on omission, and those markers
+ // derail glm-ocr table recognition (#18810).
+ _ = thinkValue
imageOffset := 0
for i, message := range messages {
@@ -61,9 +60,6 @@ func (r *GlmOcrRenderer) Render(messages []api.Message, tools []api.Tool, thinkV
content, nextOffset := r.renderContent(message, imageOffset)
imageOffset = nextOffset
sb.WriteString(content)
- if thinkingExplicitlySet && !enableThinking && !strings.HasSuffix(message.Content, "/nothink") {
- sb.WriteString("/nothink")
- }
case "assistant":
sb.WriteString("<|assistant|>\n")
if message.Thinking != "" {
@@ -99,9 +95,6 @@ func (r *GlmOcrRenderer) Render(messages []api.Message, tools []api.Tool, thinkV
}
sb.WriteString("<|assistant|>\n")
- if thinkingExplicitlySet && !enableThinking {
- sb.WriteString("\n")
- }
return sb.String(), nil
}
diff --git a/model/renderers/glmocr_test.go b/model/renderers/glmocr_test.go
index 1f8b9c038..ab87eb2b7 100644
--- a/model/renderers/glmocr_test.go
+++ b/model/renderers/glmocr_test.go
@@ -1,6 +1,7 @@
package renderers
import (
+ "strings"
"testing"
"github.com/google/go-cmp/cmp"
@@ -97,3 +98,45 @@ func TestGlmOcrRenderer_Images(t *testing.T) {
})
}
}
+
+// ResolveThinking fills Default:false when the client omits think. That must not
+// inject /nothink or an empty generation — those markers derail
+// glm-ocr table recognition (see #18810).
+func TestGlmOcrRenderer_NoNothinkWhenThinkingOff(t *testing.T) {
+ messages := []api.Message{
+ {
+ Role: "user",
+ Content: "Table Recognition:",
+ Images: []api.ImageData{api.ImageData("img1")},
+ },
+ }
+ want := "[gMASK]<|user|>\n[img-0] Table Recognition:<|assistant|>\n"
+
+ tests := []struct {
+ name string
+ think *api.ThinkValue
+ }{
+ {name: "think_omitted", think: nil},
+ {name: "think_false", think: &api.ThinkValue{Value: false}},
+ {name: "think_true", think: &api.ThinkValue{Value: true}},
+ }
+
+ renderer := &GlmOcrRenderer{useImgTags: true}
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := renderer.Render(messages, nil, tt.think)
+ if err != nil {
+ t.Fatalf("Render() error = %v", err)
+ }
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Fatalf("Render() mismatch (-want +got):\n%s", diff)
+ }
+ if strings.Contains(got, "/nothink") {
+ t.Fatalf("prompt unexpectedly contains /nothink: %q", got)
+ }
+ if strings.HasSuffix(got, "\n") {
+ t.Fatalf("prompt unexpectedly ends with empty think block: %q", got)
+ }
+ })
+ }
+}