File size: 2,744 Bytes
5a55e77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package filter

import (
	"encoding/json"
	"regexp"
	"strings"

	"zai-proxy/internal/model"
)

var glmToolCallBlockPattern = regexp.MustCompile(`<glm_block[^>]*type="tool_call"[^>]*>([\s\S]*?)</glm_block>`)

// IsFunctionToolCall 判断 tool_call 阶段的内容是否是用户定义的函数调用(非 mcp/search)
func IsFunctionToolCall(editContent string, phase string) bool {
	if phase != "tool_call" {
		return false
	}
	// 排除 mcp / search 类型的 tool call
	if strings.Contains(editContent, `"mcp"`) || strings.Contains(editContent, `mcp-server`) {
		return false
	}
	if strings.Contains(editContent, `"search_result"`) || strings.Contains(editContent, `"search_image"`) {
		return false
	}
	// 包含函数调用特征
	return strings.Contains(editContent, `"function"`) || strings.Contains(editContent, `"arguments"`)
}

// ParseFunctionToolCalls 从上游 edit_content 解析函数调用
func ParseFunctionToolCalls(editContent string) []model.ToolCall {
	// 尝试从 glm_block 中提取
	matches := glmToolCallBlockPattern.FindAllStringSubmatch(editContent, -1)
	if len(matches) > 0 {
		var allCalls []model.ToolCall
		for _, match := range matches {
			if calls := parseToolCallJSON(match[1]); len(calls) > 0 {
				allCalls = append(allCalls, calls...)
			}
		}
		if len(allCalls) > 0 {
			return allCalls
		}
	}

	// 尝试直接解析为 JSON
	return parseToolCallJSON(editContent)
}

// parseToolCallJSON 解析 tool call JSON 数据
func parseToolCallJSON(content string) []model.ToolCall {
	content = strings.TrimSpace(content)
	if content == "" {
		return nil
	}

	// 尝试解析为单个 tool call 对象
	var single struct {
		ID       string `json:"id"`
		Type     string `json:"type"`
		Function struct {
			Name      string `json:"name"`
			Arguments string `json:"arguments"`
		} `json:"function"`
		Name      string `json:"name"`
		Arguments string `json:"arguments"`
	}
	if err := json.Unmarshal([]byte(content), &single); err == nil {
		if single.Function.Name != "" {
			return []model.ToolCall{{
				ID:   single.ID,
				Type: "function",
				Function: model.FunctionCall{
					Name:      single.Function.Name,
					Arguments: single.Function.Arguments,
				},
			}}
		}
		if single.Name != "" {
			return []model.ToolCall{{
				ID:   single.ID,
				Type: "function",
				Function: model.FunctionCall{
					Name:      single.Name,
					Arguments: single.Arguments,
				},
			}}
		}
	}

	// 尝试解析为数组
	var arr []json.RawMessage
	if err := json.Unmarshal([]byte(content), &arr); err == nil {
		var calls []model.ToolCall
		for _, raw := range arr {
			if parsed := parseToolCallJSON(string(raw)); len(parsed) > 0 {
				calls = append(calls, parsed...)
			}
		}
		return calls
	}

	return nil
}