1package sdk
2
3import (
4 "encoding/json"
5 "strings"
6 "testing"
7 "time"
8
9 "github.com/bnema/zut/packages/core"
10)
11
12func TestToEventPreservesCacheDiagnostics(t *testing.T) {
13 for _, diagnostics := range []core.EvCacheDiagnostics{
14 {Eligible: true, Mode: "automatic", Transport: "http_sse", Continuation: "full"},
15 {Eligible: false, Mode: "below_minimum", Transport: "websocket", Continuation: "incremental"},
16 } {
17 event := toEvent(diagnostics)
18 if event.Type != "cache_diagnostics" || event.CacheDiagnostics == nil {
19 t.Fatalf("event = %#v", event)
20 }
21 got := event.CacheDiagnostics
22 if got.Eligible != diagnostics.Eligible || got.Mode != diagnostics.Mode || got.Transport != diagnostics.Transport || got.Continuation != diagnostics.Continuation {
23 t.Fatalf("cache diagnostics = %#v, want %#v", got, diagnostics)
24 }
25 encoded, err := json.Marshal(event)
26 if err != nil {
27 t.Fatal(err)
28 }
29 if !json.Valid(encoded) {
30 t.Fatalf("encoded diagnostics are invalid JSON: %s", encoded)
31 }
32 if !diagnostics.Eligible && !strings.Contains(string(encoded), `"eligible":false`) {
33 t.Fatalf("encoded ineligible diagnostics = %s, want eligible=false", encoded)
34 }
35 }
36}
37
38func TestToEventPreservesActivityAndToolStreamFacts(t *testing.T) {
39 retry := toEvent(core.EvRetryScheduled{
40 Scope: core.RetryScopeProvider, Attempt: 2, MaxAttempts: 3, Delay: 250 * time.Millisecond,
41 })
42 if retry.Type != "retry_scheduled" || retry.Scope != "provider" || retry.Attempt != 2 || retry.MaxAttempts != 3 || retry.DelayMS == nil || *retry.DelayMS != 250 {
43 t.Fatalf("retry event = %#v", retry)
44 }
45
46 zeroDelay := toEvent(core.EvRetryScheduled{Scope: core.RetryScopeProvider, Attempt: 2, MaxAttempts: 3})
47 encoded, err := json.Marshal(zeroDelay)
48 if err != nil {
49 t.Fatalf("marshal zero-delay retry: %v", err)
50 }
51 var wire map[string]any
52 if err := json.Unmarshal(encoded, &wire); err != nil {
53 t.Fatalf("decode zero-delay retry: %v", err)
54 }
55 if got, ok := wire["delay_ms"]; !ok || got != float64(0) {
56 t.Fatalf("zero-delay retry JSON delay_ms = %#v, want 0", got)
57 }
58
59 toolStart := toEvent(core.EvToolUseStart{ID: "call-1", Name: "read"})
60 if toolStart.Type != "tool_use_start" || toolStart.ID != "call-1" || toolStart.Name != "read" {
61 t.Fatalf("tool start = %#v", toolStart)
62 }
63 toolArgs := toEvent(core.EvToolUseArgs{ID: "call-1", Delta: `{"path":"a"`})
64 if toolArgs.Type != "tool_use_args" || toolArgs.ID != "call-1" || toolArgs.Delta == "" {
65 t.Fatalf("tool args = %#v", toolArgs)
66 }
67 toolEnd := toEvent(core.EvToolExecutionStarted{ID: "call-1", Name: "read"})
68 if toolEnd.Type != "tool_execution_started" || toolEnd.ID != "call-1" || toolEnd.Name != "read" {
69 t.Fatalf("tool execution = %#v", toolEnd)
70 }
71}