summaryrefslogtreecommitdiff
path: root/spec/test_models.lua
blob: ae01396d20e285db6a061c7381836976e9153df7 (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
-- subagents/models.lua: the four catalog query forms and the profile join.
--
-- The fake host answers by query shape, so each case checks both what the tool
-- asked the host for (`handle.models_queries`) and how it rendered the answer.

local fake = require("spec.fake_ext")
local models = require("subagents.models")

local function has(text, needle)
    assert(type(text) == "string", "expected a string result, got " .. type(text))
    assert(text:find(needle, 1, true), "expected to find " .. needle .. " in:\n" .. tostring(text))
end

local function catalog(query)
    if query.model then
        if query.model == "anthropic:sonnet" then
            return {
                found = true,
                ref = "anthropic:sonnet",
                wire_model = "claude-sonnet-4-6",
                reasoning_default = "medium",
                reasoning_levels = { "low", "medium", "high" },
                context_window = 200000,
                max_tokens = 64000,
            }
        end
        return { found = false }
    end
    if query.provider or query.query then
        return {
            matches = {
                { ref = "anthropic:sonnet", wire_model = "claude-sonnet-4-6", reasoning_default = "medium" },
                { ref = "anthropic:opus", wire_model = "claude-opus-4-6" },
            },
            truncated = true,
        }
    end
    return {
        model = "anthropic:sonnet",
        reasoning = "medium",
        providers = { { name = "anthropic", style = "messages", models = 7 } },
    }
end

local function profile_set()
    local reviewer = {
        name = "reviewer",
        description = "Reviews changes",
        model = "anthropic:sonnet",
        reasoning = "high",
        body = "b",
    }
    local scout = { name = "scout", description = "", body = "b" }
    return {
        list = { reviewer, scout },
        by_name = { reviewer = reviewer, scout = scout },
        warnings = {},
    }
end

local function with_host(fn)
    local handle = fake.install({ models_response = catalog })
    local ok, err = pcall(fn, handle, profile_set())
    handle.restore()
    if not ok then
        error(err, 0)
    end
end

return {
    { "no arguments reports the inherited model and provider counts", function()
        with_host(function(handle, profiles)
            local text = models.handle({}, profiles)
            has(text, "inherited model: anthropic:sonnet")
            has(text, "inherited reasoning: medium")
            has(text, "anthropic (messages, 7 models)")
            assert(next(handle.models_queries[1]) == nil, "the overview query carries no fields")
        end)
    end },

    { "an exact model lookup reports its reasoning levels", function()
        with_host(function(handle, profiles)
            local text = models.handle({ model = "anthropic:sonnet" }, profiles)
            has(text, "model: anthropic:sonnet")
            has(text, "wire model: claude-sonnet-4-6")
            has(text, "default reasoning: medium")
            has(text, "reasoning levels: low, medium, high")
            has(text, "context window: 200000")
            assert(handle.models_queries[1].model == "anthropic:sonnet")
        end)
    end },

    { "an unknown model says so and suggests a search", function()
        with_host(function(handle, profiles)
            local text = models.handle({ model = "acme:turbo" }, profiles)
            has(text, "No configured model matches 'acme:turbo'")
            has(text, "subagents.models")
        end)
    end },

    { "a search reports matches and says when more exist", function()
        with_host(function(handle, profiles)
            local text = models.handle({ query = "son" }, profiles)
            has(text, "2 match(es):")
            has(text, "anthropic:sonnet — wire claude-sonnet-4-6, default reasoning medium")
            has(text, "more exist — refine the query")
            assert(handle.models_queries[1].limit == 10, "the default limit is 10")
        end)
    end },

    { "limit is clamped to 1..50", function()
        with_host(function(handle, profiles)
            models.handle({ query = "son", limit = 500 }, profiles)
            assert(handle.models_queries[1].limit == 50, tostring(handle.models_queries[1].limit))
            models.handle({ provider = "anthropic", limit = 0 }, profiles)
            assert(handle.models_queries[2].limit == 1, tostring(handle.models_queries[2].limit))
            models.handle({ query = "son", limit = 7.6 }, profiles)
            assert(handle.models_queries[3].limit == 7, "a fractional limit is floored")
        end)
    end },

    { "an agent with a model reports that model", function()
        with_host(function(handle, profiles)
            local text = models.handle({ agent = "reviewer" }, profiles)
            has(text, "agent: reviewer")
            has(text, "description: Reviews changes")
            has(text, "wire model: claude-sonnet-4-6")
            has(text, "profile reasoning: high")
            assert(handle.models_queries[1].model == "anthropic:sonnet", "the profile model is looked up")
        end)
    end },

    { "an agent without a model says it inherits", function()
        with_host(function(handle, profiles)
            local text = models.handle({ agent = "scout" }, profiles)
            has(text, "agent: scout")
            has(text, "model: inherits the primary model")
            has(text, "inherited model: anthropic:sonnet")
            assert(next(handle.models_queries[1]) == nil, "the inherited case asks for the overview")
        end)
    end },

    { "an unknown agent names the known profiles", function()
        with_host(function(handle, profiles)
            local text = models.handle({ agent = "ghost" }, profiles)
            has(text, "Error: unknown agent 'ghost'")
            has(text, "reviewer, scout")
        end)
    end },

    { "a non-string field is refused", function()
        with_host(function(handle, profiles)
            has(models.handle({ query = 12 }, profiles), "Error: `query` must be a non-empty string")
            has(models.handle({ model = "" }, profiles), "Error: `model` must be a non-empty string")
            assert(#handle.models_queries == 0, "a refused call never reaches the host")
        end)
    end },
}