- 创建英文版工具模拟实现清单,涵盖13个核心实现面 - 添加中文版工具模拟实现清单,详细说明各项验收标准 - 编写英文版工具模拟方法论文档,阐述核心实现模式 - 补充中文版方法论文档,包括多轮调用与重试策略指导 - 实现HTTP API服务器测试,验证工具历史保持功能 - 新增工具模拟核心模块,包含工具定义提取与注入功能 - 添加拒绝检测、动作块解析等关键工具模拟组件
115 lines
3.7 KiB
Go
115 lines
3.7 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeOpenAIRequestKeepsEmulationForToolHistoryWithoutTools(t *testing.T) {
|
|
s := &Server{cfg: Config{EmulateToolCalls: true}}
|
|
req := openAIChatRequest{
|
|
Model: "test-model",
|
|
Messages: []rawMessage{
|
|
{
|
|
Role: "user",
|
|
Content: "Call ping once, then after the tool result reply FINAL_OK.",
|
|
},
|
|
{
|
|
Role: "assistant",
|
|
Content: nil,
|
|
ToolCalls: []rawToolCall{
|
|
{
|
|
ID: "call_1",
|
|
Type: "function",
|
|
Function: struct {
|
|
Name string `json:"name"`
|
|
Arguments string `json:"arguments"`
|
|
}{
|
|
Name: "ping",
|
|
Arguments: "{\"value\":\"x\"}",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Role: "tool",
|
|
ToolCallID: "call_1",
|
|
Content: "pong",
|
|
},
|
|
},
|
|
}
|
|
|
|
normalized, err := s.normalizeOpenAIRequest(req)
|
|
if err != nil {
|
|
t.Fatalf("normalizeOpenAIRequest() error = %v", err)
|
|
}
|
|
if !normalized.Emulated {
|
|
t.Fatalf("expected emulation to stay enabled when tool history exists")
|
|
}
|
|
if len(normalized.ChatRequest.Messages) != 3 {
|
|
t.Fatalf("message count = %d", len(normalized.ChatRequest.Messages))
|
|
}
|
|
if normalized.ChatRequest.Messages[1].Role != "assistant" {
|
|
t.Fatalf("assistant message role = %q", normalized.ChatRequest.Messages[1].Role)
|
|
}
|
|
if !strings.Contains(normalized.ChatRequest.Messages[1].Text, "json action") || !strings.Contains(normalized.ChatRequest.Messages[1].Text, "\"tool\": \"ping\"") {
|
|
t.Fatalf("assistant tool call was not rewritten into action format: %q", normalized.ChatRequest.Messages[1].Text)
|
|
}
|
|
if normalized.ChatRequest.Messages[2].Role != "user" {
|
|
t.Fatalf("tool result role = %q", normalized.ChatRequest.Messages[2].Role)
|
|
}
|
|
if !strings.Contains(normalized.ChatRequest.Messages[2].Text, "pong") {
|
|
t.Fatalf("tool result was not converted into a follow-up prompt: %q", normalized.ChatRequest.Messages[2].Text)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeAnthropicRequestKeepsEmulationForToolHistoryWithoutTools(t *testing.T) {
|
|
s := &Server{cfg: Config{EmulateToolCalls: true}}
|
|
req := anthropicRequest{
|
|
Model: "test-model",
|
|
Messages: []rawMessage{
|
|
{
|
|
Role: "user",
|
|
Content: []any{
|
|
map[string]any{"type": "text", "text": "Use ping, then after the tool result reply FINAL_OK."},
|
|
},
|
|
},
|
|
{
|
|
Role: "assistant",
|
|
Content: []any{
|
|
map[string]any{"type": "tool_use", "id": "call_1", "name": "ping", "input": map[string]any{"value": "x"}},
|
|
},
|
|
},
|
|
{
|
|
Role: "user",
|
|
Content: []any{
|
|
map[string]any{"type": "tool_result", "tool_use_id": "call_1", "content": []any{map[string]any{"type": "text", "text": "pong"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
normalized, err := s.normalizeAnthropicRequest(req)
|
|
if err != nil {
|
|
t.Fatalf("normalizeAnthropicRequest() error = %v", err)
|
|
}
|
|
if !normalized.Emulated {
|
|
t.Fatalf("expected emulation to stay enabled when anthropic tool history exists")
|
|
}
|
|
if len(normalized.ChatRequest.Messages) != 3 {
|
|
t.Fatalf("message count = %d", len(normalized.ChatRequest.Messages))
|
|
}
|
|
if normalized.ChatRequest.Messages[1].Role != "assistant" {
|
|
t.Fatalf("assistant message role = %q", normalized.ChatRequest.Messages[1].Role)
|
|
}
|
|
if !strings.Contains(normalized.ChatRequest.Messages[1].Text, "json action") || !strings.Contains(normalized.ChatRequest.Messages[1].Text, "\"tool\": \"ping\"") {
|
|
t.Fatalf("assistant tool_use was not rewritten into action format: %q", normalized.ChatRequest.Messages[1].Text)
|
|
}
|
|
if normalized.ChatRequest.Messages[2].Role != "user" {
|
|
t.Fatalf("tool result role = %q", normalized.ChatRequest.Messages[2].Role)
|
|
}
|
|
if !strings.Contains(normalized.ChatRequest.Messages[2].Text, "pong") {
|
|
t.Fatalf("tool result was not converted into a follow-up prompt: %q", normalized.ChatRequest.Messages[2].Text)
|
|
}
|
|
}
|