summaryrefslogtreecommitdiff
path: root/internal/role/role_test.go
blob: 6d2294e083badc85ae7e2723cf64ed65b7c812ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package role

import (
	"encoding/json"
	"reflect"
	"testing"
)

func TestRoleConfig_JSONRoundTrip(t *testing.T) {
	rc := RoleConfig{
		Role:             "coder",
		SystemPrompt:     "You are a careful coding agent.",
		Tools:            []string{"Bash", "Read", "Edit"},
		SandboxKind:      "docker",
		DefaultBudgetUSD: 1.5,
		EscalationLadder: []Tier{
			{
				Candidates: []Rung{
					{Provider: "local", Model: "llama3.1:8b"},
				},
				SelectionMode: "single",
				MaxRetries:    2,
			},
			{
				Candidates: []Rung{
					{Provider: "groq", Model: "llama-3.3-70b-versatile"},
					{Provider: "openrouter", Model: "meta-llama/llama-3.3-70b-instruct:free"},
				},
				SelectionMode: "round_robin",
				MaxRetries:    1,
			},
			{
				Candidates: []Rung{
					{Provider: "anthropic", Model: "claude-sonnet-5"},
				},
				MaxRetries: 0,
			},
		},
	}

	b, err := json.Marshal(rc)
	if err != nil {
		t.Fatalf("Marshal: %v", err)
	}

	var got RoleConfig
	if err := json.Unmarshal(b, &got); err != nil {
		t.Fatalf("Unmarshal: %v", err)
	}

	if !reflect.DeepEqual(rc, got) {
		t.Errorf("round trip mismatch:\n  want: %+v\n  got:  %+v", rc, got)
	}
}

func TestTier_EffectiveSelectionMode(t *testing.T) {
	cases := []struct {
		name string
		tier Tier
		want string
	}{
		{"empty defaults to round_robin", Tier{}, "round_robin"},
		{"explicit single", Tier{SelectionMode: "single"}, "single"},
		{"explicit round_robin", Tier{SelectionMode: "round_robin"}, "round_robin"},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			if got := c.tier.EffectiveSelectionMode(); got != c.want {
				t.Errorf("got %q, want %q", got, c.want)
			}
		})
	}
}