返回 DeepSeek-Reasonix
tool_execution_wire_test.go
根目录 / internal / provider / anthropic / tool_execution_wire_test.go
1 package anthropic
2
3 import (
4 "context"
5 "encoding/json"
6 "strings"
7 "testing"
8
9 "reasonix/internal/provider"
10 )
11
12 func TestBuildRequestExcludesToolExecution(t *testing.T) {
13 code := 1
14 msgs := provider.ModelMessages([]provider.Message{
15 {Role: provider.RoleUser, Content: "run tests"},
16 {Role: provider.RoleAssistant, ToolCalls: []provider.ToolCall{
17 {ID: "call_1", Name: "bash", Arguments: `{"command":"go test ./..."}`},
18 }},
19 {
20 Role: provider.RoleTool, ToolCallID: "call_1", Name: "bash", Content: "FAIL",
21 ToolExecution: &provider.ToolExecution{
22 Kind: "shell", Shell: "bash", State: "failed", ExitCode: &code,
23 FailurePhase: "execution", OutputTail: "中文stderr-marker-must-not-leak",
24 },
25 },
26 })
27 req := (&client{model: "claude-test"}).buildRequest(context.Background(), provider.Request{Messages: msgs})
28 body, err := json.Marshal(req)
29 if err != nil {
30 t.Fatal(err)
31 }
32 s := string(body)
33 for _, banned := range []string{"tool_execution", "outputTail", "中文stderr-marker-must-not-leak", "failurePhase", "mutationRisk"} {
34 if strings.Contains(s, banned) {
35 t.Fatalf("anthropic wire leaked %q: %s", banned, s)
36 }
37 }
38 if !strings.Contains(s, "tool_result") || !strings.Contains(s, "call_1") {
39 t.Fatalf("anthropic tool_result missing: %s", s)
40 }
41 }
42
43 func TestBuildRequestStableWhenLocalExecutionAdded(t *testing.T) {
44 base := []provider.Message{
45 {Role: provider.RoleUser, Content: "run"},
46 {Role: provider.RoleAssistant, ToolCalls: []provider.ToolCall{{ID: "c1", Name: "bash", Arguments: `{"command":"true"}`}}},
47 {Role: provider.RoleTool, ToolCallID: "c1", Name: "bash", Content: "ok"},
48 }
49 code := 0
50 withMeta := append([]provider.Message(nil), base...)
51 withMeta[2].ToolExecution = &provider.ToolExecution{Kind: "shell", OutputTail: "noise", ExitCode: &code}
52 a, err := json.Marshal((&client{model: "claude-test"}).buildRequest(context.Background(), provider.Request{Messages: provider.ModelMessages(base)}))
53 if err != nil {
54 t.Fatal(err)
55 }
56 b, err := json.Marshal((&client{model: "claude-test"}).buildRequest(context.Background(), provider.Request{Messages: provider.ModelMessages(withMeta)}))
57 if err != nil {
58 t.Fatal(err)
59 }
60 if string(a) != string(b) {
61 t.Fatalf("anthropic request diverged\nbase=%s\nmeta=%s", a, b)
62 }
63 }
64
64 lines GO