package core import ( "testing" "ezops/pkg/agentcli/llm" ) func TestEnsureToolMessageIntegrityKeepsCompleteMultiToolGroup(t *testing.T) { msgs := []llm.Message{ {Role: "system", Content: "sys"}, {Role: "user", Content: "查看异常副本"}, {Role: "assistant", Content: "并行检查", ToolCalls: []llm.ToolCall{ {ID: "call-1", Type: "function", Function: llm.FunctionCall{Name: "kubernetes_get", Arguments: "{}"}}, {ID: "call-2", Type: "function", Function: llm.FunctionCall{Name: "kubernetes_get", Arguments: "{}"}}, {ID: "call-3", Type: "function", Function: llm.FunctionCall{Name: "kubernetes_get", Arguments: "{}"}}, }}, {Role: "tool", ToolCallID: "call-1", Name: "kubernetes_get", Content: "deployments"}, {Role: "tool", ToolCallID: "call-2", Name: "kubernetes_get", Content: "statefulsets"}, {Role: "tool", ToolCallID: "call-3", Name: "kubernetes_get", Content: "pods"}, } got := ensureToolMessageIntegrity(msgs) if len(got) != len(msgs) { t.Fatalf("完整多工具结果组应全部保留,got=%d want=%d", len(got), len(msgs)) } for i := 3; i < len(got); i++ { if got[i].Role != "tool" || got[i].ToolCallID == "" { t.Fatalf("第 %d 条工具结果异常: %+v", i, got[i]) } } } func TestEnsureToolMessageIntegrityDropsIncompleteToolGroup(t *testing.T) { msgs := []llm.Message{ {Role: "system", Content: "sys"}, {Role: "assistant", Content: "并行检查", ToolCalls: []llm.ToolCall{ {ID: "call-1", Type: "function", Function: llm.FunctionCall{Name: "kubernetes_get", Arguments: "{}"}}, {ID: "call-2", Type: "function", Function: llm.FunctionCall{Name: "kubernetes_get", Arguments: "{}"}}, }}, {Role: "tool", ToolCallID: "call-1", Name: "kubernetes_get", Content: "deployments"}, {Role: "user", Content: "继续"}, } got := ensureToolMessageIntegrity(msgs) if len(got) != 2 { t.Fatalf("不完整工具结果组应整体丢弃,got=%d want=2: %+v", len(got), got) } if got[0].Role != "system" || got[1].Role != "user" { t.Fatalf("剩余消息异常: %+v", got) } } func TestSuppressBroadKubernetesGetAfterDiagnose(t *testing.T) { agent := NewAgent(nil, nil, &Config{Mode: "kubernetes"}, nil, nil) history := map[string]int{`kubernetes_diagnose:{"namespace":"astralx"}`: 1} msg := agent.suppressBroadKubernetesGet("kubernetes_get", map[string]interface{}{"resource": "pods"}, history) if msg == "" { t.Fatal("expected broad pods query to be suppressed after diagnose") } } func TestSuppressBroadKubernetesGetBlocksAllPodAliasesAfterDiagnose(t *testing.T) { agent := NewAgent(nil, nil, &Config{Mode: "kubernetes"}, nil, nil) history := map[string]int{`kubernetes_diagnose:{"namespace":"astralx","focus":"all"}`: 1} for _, resource := range []string{"pods", "pod"} { msg := agent.suppressBroadKubernetesGet("kubernetes_get", map[string]interface{}{"resource": resource}, history) if msg == "" { t.Fatalf("expected broad %s query to be suppressed after diagnose", resource) } } } func TestSuppressBroadKubernetesGetAllowsFilteredQuery(t *testing.T) { agent := NewAgent(nil, nil, &Config{Mode: "kubernetes"}, nil, nil) history := map[string]int{`kubernetes_diagnose:{"namespace":"astralx"}`: 1} msg := agent.suppressBroadKubernetesGet("kubernetes_get", map[string]interface{}{ "resource": "pods", "status_filter": "NotRunning", }, history) if msg != "" { t.Fatalf("expected filtered pods query to pass, got %q", msg) } } func TestSuppressBroadKubernetesGetAllowsStatusFilteredPodsAfterDiagnose(t *testing.T) { agent := NewAgent(nil, nil, &Config{Mode: "kubernetes"}, nil, nil) history := map[string]int{`kubernetes_diagnose:{"namespace":"astralx","focus":"pods"}`: 1} cases := []map[string]interface{}{ {"resource": "pods", "status_filter": "NotRunning"}, {"resource": "pod", "status_filter": "CrashLoopBackOff"}, } for _, args := range cases { msg := agent.suppressBroadKubernetesGet("kubernetes_get", args, history) if msg != "" { t.Fatalf("expected status_filter query to pass for args=%v, got %q", args, msg) } } }