summaryrefslogtreecommitdiff
path: root/spec/test_jobs.lua
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-08-19 19:02:30 -0600
committert <t@tjp.lol>2026-08-19 19:03:52 -0600
commitd1306506aa7f504b0e91c9c6ed7314afbf99978e (patch)
treee5a7295dbc566a3679e99e14dae13376b0469e84 /spec/test_jobs.lua
parent94e3fd8358bbdb5d6ed81aed475fab7fc73e2097 (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 'spec/test_jobs.lua')
-rw-r--r--spec/test_jobs.lua36
1 files changed, 18 insertions, 18 deletions
diff --git a/spec/test_jobs.lua b/spec/test_jobs.lua
index de36ab5..25faf6e 100644
--- a/spec/test_jobs.lua
+++ b/spec/test_jobs.lua
@@ -129,20 +129,20 @@ return {
end)
end },
- { "the gate runs four at a time and queues the rest", function()
+ { "the gate runs five at a time and queues the rest", function()
with_jobs(function()
local start, built = starter()
local handles = {}
- for _, name in ipairs({ "a", "b", "c", "d", "e", "f" }) do
+ for _, name in ipairs({ "a", "b", "c", "d", "e", "f", "g" }) do
handles[#handles + 1] = assert(start(name))
end
- assert(#built == 4, "the gate holds at four running, saw " .. #built)
- assert(handles[5]:result() == nil, "a queued child has not settled")
+ assert(#built == 5, "the gate holds at five running, saw " .. #built)
+ assert(handles[6]:result() == nil, "a queued child has not settled")
local results = jobs.await(handles, "all")
- assert(#built == 6, "the queue drains as slots free up, saw " .. #built)
- assert(#results == 6, "every child reports")
- assert(results[5].text == "e" and results[6].text == "f", "queued children keep their place")
+ assert(#built == 7, "the queue drains as slots free up, saw " .. #built)
+ assert(#results == 7, "every child reports")
+ assert(results[6].text == "f" and results[7].text == "g", "queued children keep their place")
end)
end },
@@ -150,20 +150,20 @@ return {
with_jobs(function()
local start, built = starter()
local handles = {}
- for _, name in ipairs({ "a", "b", "c", "d", "e" }) do
+ for _, name in ipairs({ "a", "b", "c", "d", "e", "f" }) do
handles[#handles + 1] = assert(start(name))
end
- handles[5]:cancel()
+ handles[6]:cancel()
- local result = handles[5]:result()
+ local result = handles[6]:result()
assert(type(result) == "table", "a cancelled queued child settles immediately")
assert(result.status == "cancelled", tostring(result.status))
assert(result.error == "cancelled before the child started", tostring(result.error))
- assert(#built == 4, "the queued child was never built")
- assert(not contains(built, "e"), "the queued child was never built")
+ assert(#built == 5, "the queued child was never built")
+ assert(not contains(built, "f"), "the queued child was never built")
- jobs.await({ handles[1], handles[2], handles[3], handles[4] }, "all")
- assert(#built == 4, "a cancelled child does not start when a slot frees up")
+ jobs.await({ handles[1], handles[2], handles[3], handles[4], handles[5] }, "all")
+ assert(#built == 5, "a cancelled child does not start when a slot frees up")
end)
end },
@@ -202,16 +202,16 @@ return {
with_jobs(function()
local start, built, made = starter()
local handles = {}
- for _, name in ipairs({ "a", "b", "c", "d", "e" }) do
+ for _, name in ipairs({ "a", "b", "c", "d", "e", "f" }) do
handles[#handles + 1] = assert(start(name, { settle = 5 }))
end
jobs.cancel_all()
- for _, name in ipairs({ "a", "b", "c", "d" }) do
+ for _, name in ipairs({ "a", "b", "c", "d", "e" }) do
assert(made[name]._cancel_requested, "running child " .. name .. " was not cancelled")
end
- assert(#built == 4, "cancel_all must not start the queued child")
- assert(handles[5]:result().status == "cancelled", "the queued child settles cancelled")
+ assert(#built == 5, "cancel_all must not start the queued child")
+ assert(handles[6]:result().status == "cancelled", "the queued child settles cancelled")
local results = jobs.await(handles, "all")
for index, result in ipairs(results) do