-- 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 }, }