返回 DeepSeek-Reasonix
result_test.go
根目录 / internal / plugin / result_test.go
1 package plugin
2
3 import (
4 "strings"
5 "testing"
6 )
7
8 func TestParseToolResultStructuredContentVariants(t *testing.T) {
9 text, _, err := parseToolResult([]byte(`{"content":[],"structuredContent":{"ok":true}}`))
10 if err != nil || text != `{"ok":true}` {
11 t.Fatalf("empty text used structuredContent: %q %v", text, err)
12 }
13 text, _, err = parseToolResult([]byte(`{"content":[{"type":"text","text":"{\"ok\":true}"}],"structuredContent":{"ok":true}}`))
14 if err != nil || text != `{"ok":true}` {
15 t.Fatalf("equal JSON must collapse: %q %v", text, err)
16 }
17 text, _, err = parseToolResult([]byte(`{"content":[{"type":"text","text":"hello"}],"structuredContent":{"ok":true}}`))
18 if err != nil || !strings.Contains(text, "hello") || !strings.Contains(text, "structured content") {
19 t.Fatalf("unequal content must keep both: %q %v", text, err)
20 }
21 text, _, err = parseToolResult([]byte(`{"content":[{"type":"text","text":"boom"}],"isError":true}`))
22 if err == nil || text != "boom" {
23 t.Fatalf("error result: %q %v", text, err)
24 }
25 classified, ok := err.(interface{ RetryableToolError() bool })
26 if !ok || classified.RetryableToolError() {
27 t.Fatalf("MCP isError must be a typed non-retryable application error: %T", err)
28 }
29 }
30
31 func TestOutputSchemaMismatchIsTelemetryOnly(t *testing.T) {
32 ResetProtocolMetricsForTest()
33 text, _, err := parseToolResultWithSchema(
34 []byte(`{"content":[],"structuredContent":{"ok":"not-a-boolean"}}`),
35 []byte(`{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}`),
36 )
37 if err != nil || text == "" {
38 t.Fatalf("third-party output mismatch must not fail: text=%q err=%v", text, err)
39 }
40 if got := OutputSchemaMismatchCount(); got != 1 {
41 t.Fatalf("mismatch count = %d, want 1", got)
42 }
43 }
44
44 lines GO