WIP commit保存以下定制工作以便后续合并 upstream v0.1.124-125: - Windsurf: tier access service, NLU extractor, cold threshold, Google login - Antigravity: client/oauth 调整 - Ops: log stream handler/broadcaster/middleware, OpsLogStreamView - Frontend: WindsurfLoginModal Google, GoogleIcon, AccountsView, sidebar/router/i18n
145 lines
4.0 KiB
Go
145 lines
4.0 KiB
Go
package windsurf
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestExtractToolCallsNLU(t *testing.T) {
|
|
tools := []string{"edit_file", "read_file", "run_command"}
|
|
|
|
tests := []struct {
|
|
name string
|
|
text string
|
|
available []string
|
|
wantCount int
|
|
wantName string
|
|
}{
|
|
{
|
|
name: "marker form: function: edit_file with JSON",
|
|
text: `I'll use function: edit_file with {"path": "/tmp/x", "content": "abc"}`,
|
|
available: tools,
|
|
wantCount: 1,
|
|
wantName: "edit_file",
|
|
},
|
|
{
|
|
name: "marker form: tool_call read_file",
|
|
text: `tool_call: read_file arguments: {"path": "/etc/hosts"}`,
|
|
available: tools,
|
|
wantCount: 1,
|
|
wantName: "read_file",
|
|
},
|
|
{
|
|
name: "marker form: nested JSON object",
|
|
text: `function: run_command with {"cmd": "ls", "opts": {"long": true}}`,
|
|
available: tools,
|
|
wantCount: 1,
|
|
wantName: "run_command",
|
|
},
|
|
{
|
|
name: "bare name fallback when no marker",
|
|
text: `Sure, I'll edit_file {"path": "/tmp/y"} for you.`,
|
|
available: tools,
|
|
wantCount: 1,
|
|
wantName: "edit_file",
|
|
},
|
|
{
|
|
name: "unknown tool name rejected when available list is non-empty",
|
|
text: `function: delete_universe {"target": "all"}`,
|
|
available: tools,
|
|
wantCount: 0,
|
|
},
|
|
{
|
|
name: "no JSON after marker yields no call",
|
|
text: `function: edit_file but I'm not sure what arguments to use`,
|
|
available: tools,
|
|
wantCount: 0,
|
|
},
|
|
{
|
|
name: "empty text returns nil",
|
|
text: "",
|
|
available: tools,
|
|
wantCount: 0,
|
|
},
|
|
{
|
|
name: "duplicate names deduplicated",
|
|
text: `function: edit_file {"path": "/a"} then function: edit_file {"path": "/b"}`,
|
|
available: tools,
|
|
wantCount: 1,
|
|
wantName: "edit_file",
|
|
},
|
|
{
|
|
name: "name not in available list is rejected even when JSON valid",
|
|
text: `Calling foo with {"x": 1}`,
|
|
available: []string{"bar"},
|
|
wantCount: 0,
|
|
},
|
|
{
|
|
name: "marker with no available list still extracts",
|
|
text: `function: my_tool {"x": 1}`,
|
|
available: nil,
|
|
wantCount: 1,
|
|
wantName: "my_tool",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := ExtractToolCallsNLU(tc.text, tc.available)
|
|
if len(got) != tc.wantCount {
|
|
t.Fatalf("expected %d call(s), got %d: %+v", tc.wantCount, len(got), got)
|
|
}
|
|
if tc.wantCount > 0 && got[0].Name != tc.wantName {
|
|
t.Fatalf("expected name %q, got %q", tc.wantName, got[0].Name)
|
|
}
|
|
if tc.wantCount > 0 && got[0].ArgumentsJSON == "" {
|
|
t.Fatalf("expected non-empty ArgumentsJSON, got %q", got[0].ArgumentsJSON)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasNLUSignal(t *testing.T) {
|
|
tests := []struct {
|
|
text string
|
|
want bool
|
|
}{
|
|
{"function: edit_file {}", true},
|
|
{"I'll call edit_file", true},
|
|
{"calling tool edit_file", true},
|
|
{"调用工具 edit_file", true},
|
|
{"Hello, just a chat reply.", false},
|
|
{"", false},
|
|
{"<tool_use><name>foo</name></tool_use>", false},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.text, func(t *testing.T) {
|
|
if got := HasNLUSignal(tc.text); got != tc.want {
|
|
t.Fatalf("HasNLUSignal(%q) = %v, want %v", tc.text, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResolveEmulationFlavor(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
meta *ModelMeta
|
|
want string
|
|
}{
|
|
{"nil meta", nil, EmulationFlavorAuto},
|
|
{"explicit override wins", &ModelMeta{Provider: "anthropic", EmulationFlavor: "nlu"}, "nlu"},
|
|
{"anthropic default tool_use", &ModelMeta{Provider: "anthropic"}, EmulationFlavorToolUse},
|
|
{"zhipu default nlu", &ModelMeta{Provider: "zhipu"}, EmulationFlavorNLU},
|
|
{"moonshot default nlu", &ModelMeta{Provider: "moonshot"}, EmulationFlavorNLU},
|
|
{"openai default auto", &ModelMeta{Provider: "openai"}, EmulationFlavorAuto},
|
|
{"unknown provider auto", &ModelMeta{Provider: "xyz"}, EmulationFlavorAuto},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := ResolveEmulationFlavor(tc.meta); got != tc.want {
|
|
t.Fatalf("ResolveEmulationFlavor = %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|