Skip to content

Commit bdb89fe

Browse files
committed
fix: 优化工具调用与思考模式的兼容性处理
- 修复思考内容开始标记识别逻辑,添加缓冲区处理跨块内容 - 工具调用时自动禁用 auto_web_search 避免冲突 - 优化 glm_block 前文本提取,正确处理 details 标签 - 关闭 preview_mode 以提升稳定性 - 添加上游响应和工具处理的调试日志
1 parent f7ec104 commit bdb89fe

3 files changed

Lines changed: 26 additions & 9 deletions

File tree

internal/chat.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func extractAllMediaURLs(messages []Message) (imageURLs, videoURLs []string) {
120120
return imageURLs, videoURLs
121121
}
122122

123-
func makeUpstreamRequest(token string, messages []Message, model string, imageURLs, videoURLs []string) (*http.Response, string, error) {
123+
func makeUpstreamRequest(token string, messages []Message, model string, imageURLs, videoURLs []string, hasTools bool) (*http.Response, string, error) {
124124
payload, err := DecodeJWTPayload(token)
125125
if err != nil || payload == nil {
126126
return nil, "", fmt.Errorf("invalid token")
@@ -244,8 +244,8 @@ func makeUpstreamRequest(token string, messages []Message, model string, imageUR
244244
"features": map[string]interface{}{
245245
"image_generation": true,
246246
"web_search": true,
247-
"auto_web_search": autoWebSearch,
248-
"preview_mode": true,
247+
"auto_web_search": autoWebSearch && !hasTools,
248+
"preview_mode": false,
249249
"flags": []string{},
250250
"enable_thinking": enableThinking,
251251
},
@@ -370,10 +370,15 @@ type ThinkingFilter struct {
370370

371371
func (f *ThinkingFilter) ProcessThinking(deltaContent string) string {
372372
if !f.hasSeenFirstThinking {
373-
f.hasSeenFirstThinking = true
374-
if idx := strings.Index(deltaContent, "> "); idx != -1 {
375-
deltaContent = deltaContent[idx+2:]
373+
// 合并缓存和当前内容,查找 "> " 作为思考内容的开始标记
374+
combined := f.buffer + deltaContent
375+
if idx := strings.Index(combined, "> "); idx != -1 {
376+
f.hasSeenFirstThinking = true
377+
f.buffer = ""
378+
deltaContent = combined[idx+2:]
376379
} else {
380+
// 没找到开始标记,缓存当前内容继续等待
381+
f.buffer = combined
377382
return ""
378383
}
379384
}
@@ -556,7 +561,7 @@ func HandleChatCompletions(w http.ResponseWriter, r *http.Request) {
556561
}
557562
}
558563

559-
resp, modelName, err := makeUpstreamRequest(token, messages, req.Model, reqImageURLs, reqVideoURLs)
564+
resp, modelName, err := makeUpstreamRequest(token, messages, req.Model, reqImageURLs, reqVideoURLs, len(req.Tools) > 0)
560565
if err != nil {
561566
LogError("Upstream request failed (attempt %d): %v", attempt+1, err)
562567
lastError = err.Error()
@@ -1094,6 +1099,8 @@ func handleNonStreamResponse(w http.ResponseWriter, body io.ReadCloser, completi
10941099

10951100
for scanner.Scan() {
10961101
line := scanner.Text()
1102+
LogDebug("[Upstream] %s", line)
1103+
10971104
if !strings.HasPrefix(line, "data: ") {
10981105
continue
10991106
}
@@ -1723,6 +1730,8 @@ func handleNonStreamResponseWithRetry(w http.ResponseWriter, body io.ReadCloser,
17231730

17241731
for scanner.Scan() {
17251732
line := scanner.Text()
1733+
LogDebug("[Upstream] %s", line)
1734+
17261735
if !strings.HasPrefix(line, "data: ") {
17271736
continue
17281737
}

internal/models.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,13 @@ func FormatImageSearchResults(results []ImageSearchResult) string {
594594
func ExtractTextBeforeGlmBlock(editContent string) string {
595595
if idx := strings.Index(editContent, "<glm_block"); idx != -1 {
596596
text := editContent[:idx]
597-
if strings.HasSuffix(text, "\n") {
598-
text = text[:len(text)-1]
597+
// 如果包含 </details>,只取 </details> 之后的内容
598+
if detailsIdx := strings.Index(text, "</details>"); detailsIdx != -1 {
599+
text = text[detailsIdx+len("</details>"):]
599600
}
601+
// 去掉开头和结尾的换行
602+
text = strings.TrimPrefix(text, "\n")
603+
text = strings.TrimSuffix(text, "\n")
600604
return text
601605
}
602606
return ""

internal/tools.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,20 @@ func getToolChoiceInstructions(toolChoice interface{}, toolNames []string) strin
129129

130130
func ProcessMessagesWithTools(messages []Message, tools []Tool, toolChoice interface{}) []Message {
131131
if !Cfg.ToolSupport || len(tools) == 0 {
132+
LogDebug("[Tools] Tool support disabled or no tools provided")
132133
return messages
133134
}
134135
if tc, ok := toolChoice.(string); ok && tc == "none" {
136+
LogDebug("[Tools] Tool choice is 'none', skipping tool processing")
135137
return messages
136138
}
137139

138140
toolPrompt := GenerateToolPrompt(tools, toolChoice)
139141
if toolPrompt == "" {
142+
LogDebug("[Tools] Generated empty tool prompt")
140143
return messages
141144
}
145+
LogDebug("[Tools] Injecting tool prompt for %d tools", len(tools))
142146

143147
processed := make([]Message, len(messages))
144148
copy(processed, messages)

0 commit comments

Comments
 (0)