1package core
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/zut/packages/provider"
8)
9
10type compactLifecycleClient struct {
11 hadLifecycle bool
12}
13
14func (c *compactLifecycleClient) Name() string { return "compact-lifecycle" }
15
16func (c *compactLifecycleClient) Stream(_ context.Context, req provider.Request) (<-chan provider.Event, error) {
17 c.hadLifecycle = req.Lifecycle != nil
18 if req.Lifecycle != nil {
19 req.Lifecycle.RequestAttempt(1, 1)
20 }
21 out := make(chan provider.Event, 2)
22 out <- provider.EventTextDelta{Delta: "summary"}
23 out <- provider.EventDone{Stop: provider.StopEnd, Message: provider.Message{
24 Role: provider.RoleAssistant,
25 Content: []provider.Content{provider.TextBlock{Text: "summary"}},
26 }}
27 close(out)
28 return out, nil
29}
30
31func TestCompactWithEventsEmitsRequestLifecycle(t *testing.T) {
32 client := &compactLifecycleClient{}
33 agent := NewAgent(client, "compact-model", "system", Registry{})
34 agent.SetMessages([]provider.Message{{
35 Role: provider.RoleUser,
36 Content: []provider.Content{provider.TextBlock{Text: "source"}},
37 }})
38
39 var events []AgentEvent
40 summary, err := agent.CompactWithEvents(context.Background(), 0, func(event AgentEvent) {
41 events = append(events, event)
42 })
43 if err != nil {
44 t.Fatalf("CompactWithEvents: %v", err)
45 }
46 if summary != "summary" {
47 t.Fatalf("summary = %q, want summary", summary)
48 }
49 if !client.hadLifecycle {
50 t.Fatal("compaction request did not receive a lifecycle observer")
51 }
52
53 if len(events) != 4 {
54 t.Fatalf("events = %#v, want agent request, provider request, assistant start, text delta", events)
55 }
56 agentRequest, ok := events[0].(EvRequestStarted)
57 if !ok || agentRequest.Scope != RetryScopeAgent || agentRequest.Attempt != 1 || agentRequest.MaxAttempts != 1 {
58 t.Fatalf("first event = %#v, want initial agent request", events[0])
59 }
60 providerRequest, ok := events[1].(EvRequestStarted)
61 if !ok || providerRequest.Scope != RetryScopeProvider || providerRequest.Attempt != 1 || providerRequest.MaxAttempts != 1 {
62 t.Fatalf("second event = %#v, want initial provider request", events[1])
63 }
64 if _, ok := events[2].(EvAssistantStart); !ok {
65 t.Fatalf("third event = %#v, want assistant start", events[2])
66 }
67 if delta, ok := events[3].(EvTextDelta); !ok || delta.Delta != "summary" {
68 t.Fatalf("fourth event = %#v, want summary text delta", events[3])
69 }
70}