diff options
| author | t <t@tjp.lol> | 2026-08-19 19:02:30 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-08-19 19:03:52 -0600 |
| commit | d1306506aa7f504b0e91c9c6ed7314afbf99978e (patch) | |
| tree | e5a7295dbc566a3679e99e14dae13376b0469e84 /subagents/models.lua | |
| parent | 94e3fd8358bbdb5d6ed81aed475fab7fc73e2097 (diff) | |
Add background Lua workflows, inline child prompts, and layered config
subagents.lua now starts a workflow on its own coroutine and returns a
session-scoped id immediately, so fan-out continues while the primary keeps
working; completion wakes the primary, and later calls read immutable records
from subagents.workflows. Every ctx:agent takes a workflow-unique name so those
records are addressable. A session_start guidance message tells the primary when
to reach for run vs lua.
Children no longer inherit the primary's system context: a child starts from the
fixed child-role instruction plus its profile, and subagents.run/ctx:agent
accept an inline system_prompt instead of a profile. The now-redundant `agent`
form of subagents.models is gone.
Concurrency defaults to five and is configurable through [subagents]
max_concurrent in any layered config.toml; turn boundaries reap only settled
jobs so background workflows survive, while interrupt and session end cancel.
Config roots come from panto.ext.dirs.layers rather than a hand-rolled XDG
lookup, which picks up the base and git-ignored local layers for both agents/
and workflows/.
TOML workflows tighten up: the subagents.workflow tool takes a discovered name
only (inline `steps` duplicated subagents.lua at less power), an optional
top-level `output` array chooses the reported steps and their order instead of
the terminal set, a step with no workflow input gets no empty input heading, and
a workflow naming an undiscovered agent is rejected at discovery rather than
part-way through a run.
Diffstat (limited to 'subagents/models.lua')
| -rw-r--r-- | subagents/models.lua | 56 |
1 files changed, 3 insertions, 53 deletions
diff --git a/subagents/models.lua b/subagents/models.lua index 511aa51..7272298 100644 --- a/subagents/models.lua +++ b/subagents/models.lua @@ -1,17 +1,12 @@ -- The `subagents.models` tool: a bounded window onto the model catalog. -- -- The catalog is far too large to inline into `subagents.run`'s description or --- schema, so it is queried on demand instead. Four forms, chosen in this order: +-- schema, so it is queried on demand instead. Three forms: -- --- { agent = "reviewer" } what that profile will actually run on -- { model = "anthropic:sonnet"} exact lookup: wire name, reasoning levels -- { provider =, query =, limit=} bounded search -- { } inherited model/reasoning + provider counts -- --- The agent form is the join the primary actually wants before overriding a --- profile: it reports the profile's own model, or says the profile inherits --- the primary model and shows what that is. --- -- Results are short readable lines, not JSON. A truncated search says so -- explicitly so the primary refines the query instead of assuming it saw -- everything; `limit` is clamped to 1..50 (default 10) so no query can dump @@ -22,8 +17,6 @@ -- tool cannot confirm is still validated at spawn time — the catalog is -- advice, the runtime is authoritative. -local spawn = require("subagents.spawn") - local DEFAULT_LIMIT = 10 local MAX_LIMIT = 50 @@ -143,52 +136,13 @@ local function clamp_limit(value) return limit end --- The agent form: report the profile's effective model, or say it inherits. -local function describe_agent(name, profiles) - profiles = spawn.profiles(profiles) - local profile = (profiles.by_name or {})[name] - if not profile then - return string.format("Error: unknown agent '%s'; known: %s", name, spawn.agent_names(profiles)) - end - - local out = { "agent: " .. profile.name } - if profile.description ~= "" then - out[#out + 1] = "description: " .. profile.description - end - - if profile.model then - local result, err = ask({ model = profile.model }) - if not result then - return "Error: " .. err - end - out[#out + 1] = format_exact(result, profile.model) - else - out[#out + 1] = "model: inherits the primary model" - local result, err = ask({}) - if not result then - return "Error: " .. err - end - out[#out + 1] = format_overview(result) - end - - if profile.reasoning then - out[#out + 1] = "profile reasoning: " .. profile.reasoning - end - return table.concat(out, "\n") -end - -function M.handle(input, profiles) +function M.handle(input) input = input or {} if type(input) ~= "table" then return "Error: expected a table of arguments." end - local agent, err = optional_string(input.agent, "agent") - if err then - return err - end - local model - model, err = optional_string(input.model, "model") + local model, err = optional_string(input.model, "model") if err then return err end @@ -203,10 +157,6 @@ function M.handle(input, profiles) return err end - if agent then - return describe_agent(agent, profiles) - end - if model then local result, ask_err = ask({ model = model }) if not result then |
