File size: 3,239 Bytes
8646505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package tools

import (
	"strings"
	"testing"

	"zai-proxy/internal/model"
)

func TestBuildToolSystemPrompt_Basic(t *testing.T) {
	tools := []model.Tool{
		{
			Type: "function",
			Function: model.ToolFunction{
				Name:        "get_weather",
				Description: "Get current weather",
				Parameters: map[string]interface{}{
					"type": "object",
					"properties": map[string]interface{}{
						"city": map[string]interface{}{
							"type":        "string",
							"description": "City name",
						},
					},
					"required": []string{"city"},
				},
			},
		},
	}

	result := BuildToolSystemPrompt(tools, nil)

	if !strings.Contains(result, "get_weather") {
		t.Error("should contain tool name")
	}
	if !strings.Contains(result, "Get current weather") {
		t.Error("should contain description")
	}
	if !strings.Contains(result, "<tool_call>") {
		t.Error("should contain format instruction")
	}
	if !strings.Contains(result, "city") {
		t.Error("should contain parameter info")
	}
}

func TestBuildToolSystemPrompt_Empty(t *testing.T) {
	result := BuildToolSystemPrompt(nil, nil)
	if result != "" {
		t.Error("should return empty for nil tools")
	}
}

func TestBuildToolSystemPrompt_ToolChoiceNone(t *testing.T) {
	tools := []model.Tool{{
		Type:     "function",
		Function: model.ToolFunction{Name: "test"},
	}}

	result := BuildToolSystemPrompt(tools, "none")
	if !strings.Contains(result, "禁止调用任何工具") {
		t.Error("should instruct not to call tools")
	}
}

func TestBuildToolSystemPrompt_ToolChoiceRequired(t *testing.T) {
	tools := []model.Tool{{
		Type:     "function",
		Function: model.ToolFunction{Name: "test"},
	}}

	result := BuildToolSystemPrompt(tools, "required")
	if !strings.Contains(result, "必须包含至少一个") {
		t.Error("should instruct to call at least one tool")
	}
}

func TestBuildToolSystemPrompt_ToolChoiceSpecific(t *testing.T) {
	tools := []model.Tool{{
		Type:     "function",
		Function: model.ToolFunction{Name: "get_weather"},
	}}

	choice := map[string]interface{}{
		"type": "function",
		"function": map[string]interface{}{
			"name": "get_weather",
		},
	}

	result := BuildToolSystemPrompt(tools, choice)
	if !strings.Contains(result, `必须调用工具 "get_weather"`) {
		t.Error("should instruct to call specific tool")
	}
}

func TestConvertToolCallToText(t *testing.T) {
	toolCalls := []model.ToolCall{
		{
			ID:   "call_123",
			Type: "function",
			Function: model.FunctionCall{
				Name:      "get_weather",
				Arguments: `{"city":"Beijing"}`,
			},
		},
	}

	result := ConvertToolCallToText(toolCalls)
	if !strings.Contains(result, "<tool_call>") {
		t.Error("should contain <tool_call> tag")
	}
	if !strings.Contains(result, "get_weather") {
		t.Error("should contain function name")
	}
	if !strings.Contains(result, "Beijing") {
		t.Error("should contain arguments")
	}
}

func TestConvertToolResultToText(t *testing.T) {
	result := ConvertToolResultToText("call_123", `{"temp": 25}`)
	if !strings.Contains(result, "call_123") {
		t.Error("should contain call ID")
	}
	if !strings.Contains(result, `{"temp": 25}`) {
		t.Error("should contain result content")
	}
	if !strings.Contains(result, "<tool_result") {
		t.Error("should contain <tool_result> tag")
	}
}