1package agent
2
3import (
4 "context"
5 "encoding/json"
6 "os"
7 "path/filepath"
8 "runtime"
9 "testing"
10 "time"
11
12 "github.com/patriceckhart/zot/packages/agent/extensions"
13)
14
15func TestExtToolAdapterPreservesInteractiveTimeoutPolicy(t *testing.T) {
16 if runtime.GOOS == "windows" {
17 t.Skip("mock uses /bin/sh; skip on windows")
18 }
19 root := t.TempDir()
20 extDir := filepath.Join(root, "extensions", "adapter-mock")
21 if err := os.MkdirAll(extDir, 0o755); err != nil {
22 t.Fatal(err)
23 }
24 script := `#!/bin/sh
25printf '%s\n' '{"type":"hello","name":"adapter-mock","version":"0.1","capabilities":["tools"]}'
26printf '%s\n' '{"type":"register_tool","name":"ask","description":"interactive","schema":{"type":"object"},"interactive":true}'
27printf '%s\n' '{"type":"register_tool","name":"normal","description":"normal","schema":{"type":"object"}}'
28printf '%s\n' '{"type":"ready"}'
29while IFS= read -r line; do
30 case "$line" in
31 *'"type":"shutdown"'*) printf '%s\n' '{"type":"shutdown_ack"}'; exit 0;;
32 esac
33done
34`
35 if err := os.WriteFile(filepath.Join(extDir, "run.sh"), []byte(script), 0o755); err != nil {
36 t.Fatal(err)
37 }
38 manifest, _ := json.Marshal(map[string]any{"name": "adapter-mock", "exec": "./run.sh"})
39 if err := os.WriteFile(filepath.Join(extDir, "extension.json"), manifest, 0o644); err != nil {
40 t.Fatal(err)
41 }
42
43 mgr := extensions.New(root, "", "0.0.0", "openai", "test", nonInteractiveExtHooks{})
44 if errs := mgr.Discover(context.Background()); len(errs) != 0 {
45 t.Fatalf("discover errs: %v", errs)
46 }
47 defer mgr.Stop(2 * time.Second)
48 mgr.WaitForReady(time.Second)
49
50 adapter := &extToolAdapter{mgr: mgr}
51 infos := adapter.Tools()
52 if len(infos) != 2 {
53 t.Fatalf("got %d tools, want 2: %#v", len(infos), infos)
54 }
55 for _, info := range infos {
56 _ = adapter.NewExtensionTool(info)
57 wantInteractive := info.Name == "ask"
58 if info.Interactive != wantInteractive {
59 t.Fatalf("tool %q interactive metadata = %v, want %v", info.Name, info.Interactive, wantInteractive)
60 }
61 }
62}