interactive_extension_policy_test.go RawHistoryFolder
1package agent
2
3import (
4 "context"
5 "encoding/json"
6 "strings"
7 "testing"
8
9 "github.com/bnema/zut/packages/agent/extensions"
10 "github.com/bnema/zut/packages/agent/modes"
11 "github.com/bnema/zut/packages/core"
12)
13
14func TestExtensionAdapterPreservesInteractivePolicy(t *testing.T) {
15 manager := extensions.New(t.TempDir(), t.TempDir(), "test", "provider", "model", nonInteractiveExtHooks{})
16 adapter := &extToolAdapter{mgr: manager}
17 tool := adapter.NewExtensionTool(ExtensionToolInfo{
18 Name: "ask_user", Interactive: true, Schema: json.RawMessage(`{"type":"object"}`),
19 })
20 if !extensions.IsInteractiveTool(tool) {
21 t.Fatal("adapter lost interactive registration")
22 }
23 result, err := tool.Execute(context.Background(), json.RawMessage(`{}`), nil)
24 if err != nil || !result.IsError {
25 t.Fatalf("headless execution result=%+v err=%v", result, err)
26 }
27}
28
29func TestInteractiveExtensionSupportRequiresAttachedHost(t *testing.T) {
30 hooks := &interactiveExtHooks{}
31 if hooks.SupportsInteractiveTools() {
32 t.Fatal("unattached host permits interactive tools")
33 }
34 hooks.attachInteractive(&modes.Interactive{})
35 if !hooks.SupportsInteractiveTools() {
36 t.Fatal("attached TUI rejects interactive tools")
37 }
38}
39
40func TestScheduledSessionRegistryExcludesInteractiveExtensionTools(t *testing.T) {
41 interactive := extensions.NewTool(nil, extensions.ToolInfo{Name: "ask_user", Interactive: true, Schema: json.RawMessage(`{"type":"object"}`)})
42 ordinary := extensions.NewTool(nil, extensions.ToolInfo{Name: "lookup", Schema: json.RawMessage(`{"type":"object"}`)})
43 registry := scheduledSessionRegistry(core.Registry{"ask_user": interactive, "lookup": ordinary})
44 if _, ok := registry["ask_user"]; ok {
45 t.Fatal("scheduled background session retained an interactive tool")
46 }
47 if registry["lookup"] != ordinary {
48 t.Fatal("scheduled background session lost an ordinary extension tool")
49 }
50}
51
52func TestResidentRegistryRejectsInteractiveExtensionTools(t *testing.T) {
53 tool := extensions.NewTool(nil, extensions.ToolInfo{Name: "ask_user", Interactive: true, Schema: json.RawMessage(`{"type":"object"}`)})
54 if _, err := residentChildRegistry(core.Registry{"ask_user": tool}, []string{"ask_user"}); err == nil || !strings.Contains(err.Error(), "interactive") {
55 t.Fatalf("resident registry accepted interactive tool: %v", err)
56 }
57}