github.com/anthropics/anthropic-sdk-go@v1.70.1/betasessionutil_test.go (about)

     1  package anthropic
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"testing"
     7  )
     8  
     9  func sseEvent(t *testing.T, raw string) BetaManagedAgentsStreamSessionEventsUnion {
    10  	t.Helper()
    11  	var ev BetaManagedAgentsStreamSessionEventsUnion
    12  	if err := json.Unmarshal([]byte(raw), &ev); err != nil {
    13  		t.Fatalf("unmarshal: %v", err)
    14  	}
    15  	return ev
    16  }
    17  
    18  func eventStart(t *testing.T, eventID string) BetaManagedAgentsStreamSessionEventsUnion {
    19  	return sseEvent(t, fmt.Sprintf(`{"type":"event_start","event":{"type":"agent.message","id":%q}}`, eventID))
    20  }
    21  
    22  func eventDelta(t *testing.T, eventID, text string, index int) BetaManagedAgentsStreamSessionEventsUnion {
    23  	return sseEvent(t, fmt.Sprintf(`{"type":"event_delta","event_id":%q,"delta":{"type":"content_delta","index":%d,"content":{"type":"text","text":%q}}}`, eventID, index, text))
    24  }
    25  
    26  func feed(acc *BetaManagedAgentsEventAccumulator, evs ...BetaManagedAgentsStreamSessionEventsUnion) {
    27  	for _, ev := range evs {
    28  		acc.Accumulate(ev)
    29  	}
    30  }
    31  
    32  func TestBetaManagedAgentsEventAccumulator_StartOpensEmptyPreview(t *testing.T) {
    33  	var acc BetaManagedAgentsEventAccumulator
    34  	feed(&acc, eventStart(t, "evt_1"))
    35  	msg, ok := acc.AgentMessages["evt_1"]
    36  	if !ok {
    37  		t.Fatal("expected preview")
    38  	}
    39  	if msg.ID != "evt_1" || msg.Type != "agent.message" || len(msg.Content) != 0 {
    40  		t.Fatalf("unexpected seed: %+v", msg)
    41  	}
    42  }
    43  
    44  func TestBetaManagedAgentsEventAccumulator_StartIgnoresNonAgentMessage(t *testing.T) {
    45  	var acc BetaManagedAgentsEventAccumulator
    46  	feed(&acc, sseEvent(t, `{"type":"event_start","event":{"type":"agent.thinking","id":"evt_1"}}`))
    47  	if _, ok := acc.AgentMessages["evt_1"]; ok {
    48  		t.Fatal("expected no preview for agent.thinking start")
    49  	}
    50  }
    51  
    52  func TestBetaManagedAgentsEventAccumulator_DeltaForIgnoredPreviewIsNoOp(t *testing.T) {
    53  	var acc BetaManagedAgentsEventAccumulator
    54  	feed(&acc,
    55  		sseEvent(t, `{"type":"event_start","event":{"type":"agent.thinking","id":"evt_1"}}`),
    56  		eventDelta(t, "evt_1", "x", 0),
    57  	)
    58  	if _, ok := acc.AgentMessages["evt_1"]; ok {
    59  		t.Fatal("expected no preview for ignored type")
    60  	}
    61  }
    62  
    63  func TestBetaManagedAgentsEventAccumulator_DeltaAppendsAndInserts(t *testing.T) {
    64  	var acc BetaManagedAgentsEventAccumulator
    65  	feed(&acc,
    66  		eventStart(t, "evt_1"),
    67  		eventDelta(t, "evt_1", "Hel", 0),
    68  		eventDelta(t, "evt_1", "lo", 0),
    69  		eventDelta(t, "evt_1", "World", 1),
    70  	)
    71  	msg := acc.AgentMessages["evt_1"]
    72  	if len(msg.Content) != 2 || msg.Content[0].Text != "Hello" || msg.Content[1].Text != "World" {
    73  		t.Fatalf("unexpected content: %+v", msg.Content)
    74  	}
    75  	if text := acc.AgentMessageText("evt_1"); text != "HelloWorld" {
    76  		t.Fatalf("unexpected joined text: %q", text)
    77  	}
    78  }
    79  
    80  func TestBetaManagedAgentsEventAccumulator_DeltaDefaultsIndexZero(t *testing.T) {
    81  	var acc BetaManagedAgentsEventAccumulator
    82  	feed(&acc,
    83  		eventStart(t, "evt_1"),
    84  		sseEvent(t, `{"type":"event_delta","event_id":"evt_1","delta":{"type":"content_delta","content":{"type":"text","text":"a"}}}`),
    85  		sseEvent(t, `{"type":"event_delta","event_id":"evt_1","delta":{"type":"content_delta","content":{"type":"text","text":"b"}}}`),
    86  	)
    87  	if text := acc.AgentMessageText("evt_1"); text != "ab" {
    88  		t.Fatalf("unexpected joined text: %q", text)
    89  	}
    90  }
    91  
    92  func TestBetaManagedAgentsEventAccumulator_DeltaSeedsTheUnionVariant(t *testing.T) {
    93  	var acc BetaManagedAgentsEventAccumulator
    94  	feed(&acc,
    95  		eventStart(t, "evt_1"),
    96  		eventDelta(t, "evt_1", "Hel", 0),
    97  	)
    98  	block := acc.AgentMessages["evt_1"].Content[0]
    99  	if _, ok := block.AsAny().(BetaManagedAgentsTextBlock); !ok {
   100  		t.Fatalf("expected preview block to report the text variant, got %T", block.AsAny())
   101  	}
   102  }
   103  
   104  func TestBetaManagedAgentsEventAccumulator_ContentlessDeltaKeepsIndexAlignment(t *testing.T) {
   105  	// Deltas address entries by index, so a fragment carrying no content still
   106  	// has to occupy its slot or every later fragment falls out of range.
   107  	var acc BetaManagedAgentsEventAccumulator
   108  	feed(&acc,
   109  		eventStart(t, "evt_1"),
   110  		sseEvent(t, `{"type":"event_delta","event_id":"evt_1","delta":{"type":"content_delta","index":0}}`),
   111  		eventDelta(t, "evt_1", "World", 1),
   112  	)
   113  	msg := acc.AgentMessages["evt_1"]
   114  	if len(msg.Content) != 2 || msg.Content[1].Text != "World" {
   115  		t.Fatalf("unexpected content: %+v", msg.Content)
   116  	}
   117  }
   118  
   119  func TestBetaManagedAgentsEventAccumulator_DeltaBeforeStartIsNoOp(t *testing.T) {
   120  	var acc BetaManagedAgentsEventAccumulator
   121  	feed(&acc, eventDelta(t, "evt_1", "x", 0))
   122  	if _, ok := acc.AgentMessages["evt_1"]; ok {
   123  		t.Fatal("expected no preview without event_start")
   124  	}
   125  }
   126  
   127  func TestBetaManagedAgentsEventAccumulator_OutOfRangeIndexIsNoOp(t *testing.T) {
   128  	var acc BetaManagedAgentsEventAccumulator
   129  	feed(&acc,
   130  		eventStart(t, "evt_1"),
   131  		eventDelta(t, "evt_1", "x", 2),
   132  		eventDelta(t, "evt_1", "y", -1),
   133  	)
   134  	if len(acc.AgentMessages["evt_1"].Content) != 0 {
   135  		t.Fatalf("expected out-of-range deltas to be dropped, got %+v", acc.AgentMessages["evt_1"].Content)
   136  	}
   137  }
   138  
   139  func TestBetaManagedAgentsEventAccumulator_BufferedEventReplacesPreview(t *testing.T) {
   140  	var acc BetaManagedAgentsEventAccumulator
   141  	feed(&acc,
   142  		eventStart(t, "evt_1"),
   143  		eventDelta(t, "evt_1", "partial", 0),
   144  		sseEvent(t, `{"type":"agent.message","id":"evt_1","processed_at":"2024-01-01T00:00:00Z","content":[{"type":"text","text":"complete"}]}`),
   145  	)
   146  	if text := acc.AgentMessageText("evt_1"); text != "complete" {
   147  		t.Fatalf("expected final event to replace preview, got %q", text)
   148  	}
   149  }
   150  
   151  func TestBetaManagedAgentsEventAccumulator_StragglerDeltaAfterBufferedEventIsDropped(t *testing.T) {
   152  	var acc BetaManagedAgentsEventAccumulator
   153  	feed(&acc,
   154  		eventStart(t, "evt_1"),
   155  		eventDelta(t, "evt_1", "partial", 0),
   156  		sseEvent(t, `{"type":"agent.message","id":"evt_1","processed_at":"2024-01-01T00:00:00Z","content":[{"type":"text","text":"complete"}]}`),
   157  		eventDelta(t, "evt_1", "straggler", 0),
   158  	)
   159  	if text := acc.AgentMessageText("evt_1"); text != "complete" {
   160  		t.Fatalf("expected straggler delta after the canonical event to be dropped, got %q", text)
   161  	}
   162  }
   163  
   164  func TestBetaManagedAgentsEventAccumulator_ModelRequestEndClearsPreviews(t *testing.T) {
   165  	var acc BetaManagedAgentsEventAccumulator
   166  	feed(&acc,
   167  		eventStart(t, "evt_1"),
   168  		eventDelta(t, "evt_1", "x", 0),
   169  		sseEvent(t, `{"type":"span.model_request_end","id":"sevt_2","model_request_start_id":"sevt_1","is_error":true,"processed_at":"2024-01-01T00:00:00Z"}`),
   170  	)
   171  	if len(acc.AgentMessages) != 0 {
   172  		t.Fatal("expected previews to be cleared by span.model_request_end")
   173  	}
   174  }
   175  
   176  func TestBetaManagedAgentsEventAccumulator_ModelRequestEndKeepsCanonicalMessages(t *testing.T) {
   177  	var acc BetaManagedAgentsEventAccumulator
   178  	feed(&acc,
   179  		eventStart(t, "evt_1"),
   180  		eventDelta(t, "evt_1", "partial", 0),
   181  		sseEvent(t, `{"type":"agent.message","id":"evt_1","processed_at":"2024-01-01T00:00:00Z","content":[{"type":"text","text":"complete"}]}`),
   182  		eventStart(t, "evt_2"),
   183  		eventDelta(t, "evt_2", "open", 0),
   184  		sseEvent(t, `{"type":"span.model_request_end","id":"sevt_2","model_request_start_id":"sevt_1","is_error":true,"processed_at":"2024-01-01T00:00:00Z"}`),
   185  	)
   186  	if text := acc.AgentMessageText("evt_1"); text != "complete" {
   187  		t.Fatalf("expected canonical message to survive span.model_request_end, got %q", text)
   188  	}
   189  	if _, ok := acc.AgentMessages["evt_2"]; ok {
   190  		t.Fatal("expected open preview to be discarded by span.model_request_end")
   191  	}
   192  }
   193  
   194  func TestBetaManagedAgentsEventAccumulator_OtherEventsAreNoOps(t *testing.T) {
   195  	var acc BetaManagedAgentsEventAccumulator
   196  	feed(&acc, sseEvent(t, `{"type":"session.status_running","id":"sevt_1","processed_at":"2024-01-01T00:00:00Z"}`))
   197  	if _, ok := acc.AgentMessages["sevt_1"]; ok {
   198  		t.Fatal("expected no preview")
   199  	}
   200  }
   201  
   202  func TestBetaManagedAgentsEventAccumulator_UnrecognizedEventTypeIsNoOp(t *testing.T) {
   203  	var acc BetaManagedAgentsEventAccumulator
   204  	feed(&acc,
   205  		eventStart(t, "evt_1"),
   206  		eventDelta(t, "evt_1", "Hi", 0),
   207  		sseEvent(t, `{"type":"session.some_future_event","id":"evt_1","result":{"type":"object"}}`),
   208  	)
   209  	if text := acc.AgentMessageText("evt_1"); text != "Hi" {
   210  		t.Fatalf("expected preview to be untouched by an unrecognized event type, got %q", text)
   211  	}
   212  }
   213  
   214  func TestBetaManagedAgentsEventAccumulator_MultiplePreviews(t *testing.T) {
   215  	var acc BetaManagedAgentsEventAccumulator
   216  	feed(&acc,
   217  		eventStart(t, "evt_a"),
   218  		eventDelta(t, "evt_a", "alpha", 0),
   219  		eventStart(t, "evt_b"),
   220  		eventDelta(t, "evt_b", "beta", 0),
   221  		sseEvent(t, `{"type":"event_start","event":{"type":"agent.thinking","id":"evt_c"}}`),
   222  	)
   223  	if len(acc.AgentMessages) != 2 {
   224  		t.Fatalf("expected 2 previews, got %d", len(acc.AgentMessages))
   225  	}
   226  	if acc.AgentMessageText("evt_a") != "alpha" || acc.AgentMessageText("evt_b") != "beta" {
   227  		t.Fatalf("unexpected: a=%q b=%q", acc.AgentMessageText("evt_a"), acc.AgentMessageText("evt_b"))
   228  	}
   229  }
   230  
   231  func TestBetaManagedAgentsEventAccumulator_ZeroValue(t *testing.T) {
   232  	var acc BetaManagedAgentsEventAccumulator
   233  	if acc.AgentMessageText("evt_1") != "" {
   234  		t.Fatal("expected empty text from zero value")
   235  	}
   236  	if len(acc.AgentMessages) != 0 {
   237  		t.Fatal("expected empty map from zero value")
   238  	}
   239  }