1package agent
2
3import (
4 "reflect"
5 "testing"
6
7 "github.com/patriceckhart/zot/packages/agent/extproto"
8 "github.com/patriceckhart/zot/packages/core"
9)
10
11type rememberingDetailedConfirmer struct {
12 calls []core.ToolCallConfirmation
13}
14
15func (c *rememberingDetailedConfirmer) Confirm(string, string) core.ConfirmDecision {
16 panic("Confirm called instead of ConfirmToolCall")
17}
18
19func (c *rememberingDetailedConfirmer) ConfirmToolCall(call core.ToolCallConfirmation) core.ConfirmDecision {
20 c.calls = append(c.calls, call)
21 return core.ConfirmDecision{Allow: true, RememberTool: true}
22}
23
24func TestConfirmationEventIncludesExtensionOrigin(t *testing.T) {
25 var event extproto.EventFromHost
26 confirmer := &confirmationEventConfirmer{
27 inner: &rememberingDetailedConfirmer{},
28 emit: func(ev extproto.EventFromHost) { event = ev },
29 origin: func(id string) string {
30 if id != "host-call" {
31 t.Fatalf("tool ID: %q", id)
32 }
33 return "caller"
34 },
35 }
36 confirmer.ConfirmToolCall(core.ToolCallConfirmation{ID: "host-call", Name: "read"})
37 if event.OriginExtension != "caller" || event.Event != "tool_confirmation_requested" {
38 t.Fatalf("confirmation event: %+v", event)
39 }
40}
41
42func TestConfirmationEventConfirmerEmitsOnlyWhenPrompting(t *testing.T) {
43 inner := &rememberingDetailedConfirmer{}
44 var events []extproto.EventFromHost
45 notifier := &confirmationEventConfirmer{
46 inner: inner,
47 emit: func(event extproto.EventFromHost) {
48 events = append(events, event)
49 },
50 }
51 gate := core.NewConfirmGate(notifier)
52 call := core.ToolCallConfirmation{
53 ID: "call-1",
54 Name: "edit",
55 Summary: "main.go",
56 Content: "-old\n+new\n",
57 }
58
59 if allowed, _, _ := gate.CheckToolCall(call); !allowed {
60 t.Fatal("first call should be allowed")
61 }
62 if allowed, _, _ := gate.CheckToolCall(core.ToolCallConfirmation{Name: "edit", Summary: "other.go"}); !allowed {
63 t.Fatal("remembered tool should be allowed")
64 }
65
66 if len(events) != 1 {
67 t.Fatalf("events = %d, want 1", len(events))
68 }
69 want := extproto.EventFromHost{
70 Event: "tool_confirmation_requested",
71 ToolID: "call-1",
72 ToolName: "edit",
73 ToolPreview: "main.go",
74 }
75 if !reflect.DeepEqual(events[0], want) {
76 t.Fatalf("event = %+v, want %+v", events[0], want)
77 }
78 if len(inner.calls) != 1 || inner.calls[0] != call {
79 t.Fatalf("inner calls = %+v, want [%+v]", inner.calls, call)
80 }
81}