From d1306506aa7f504b0e91c9c6ed7314afbf99978e Mon Sep 17 00:00:00 2001 From: t Date: Wed, 19 Aug 2026 19:02:30 -0600 Subject: 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. --- spec/test_progress_replay.lua | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'spec/test_progress_replay.lua') diff --git a/spec/test_progress_replay.lua b/spec/test_progress_replay.lua index cf2925e..ffe7e5c 100644 --- a/spec/test_progress_replay.lua +++ b/spec/test_progress_replay.lua @@ -3,6 +3,8 @@ local progress = require("subagents.progress") local run = require("subagents.run") local luatool = require("subagents.luatool") local toml_workflows = require("subagents.toml_workflows") +local workflow = require("subagents.workflow") +local uv = require("luv") local function plain(lines) return table.concat(lines, "\n"):gsub("\27%[[%d;]*m", "") @@ -269,24 +271,29 @@ return { "settled status is retained for durable presentation") handle.queue_for("alpha", { output = "fixed done" }) - toml_workflows.handle({ - prompt = "fixed", + toml_workflows.run(assert(toml_workflows.validate({ + name = "fixed", steps = { { id = "step", agent = "alpha", prompt = "run fixed" } }, - }, profiles) + }, "fixed")), "fixed", profiles) assert(handle.runs[2].metadata.subagents.tool_call_id == "outer-run", "fixed workflow child keeps the same outer owner") assert(handle.runs[2].metadata.subagents.sequence == 2, "fixed workflow child follows spawn order") handle.queue_for("inline", { output = "inline done" }) - local source = [[return subagents.workflow(function(ctx, input) - return ctx:agent({ agent = "inline", prompt = input }):await() + local source = [[return subagents.workflow(function(ctx) + local result = ctx:agent({ name = "inline-work", agent = "inline", prompt = "dynamic" }):await() + return result.output end)]] - luatool.handle({ - prompt = "dynamic", + local workflow_id = luatool.handle({ source = source, agents = { { name = "inline", system_prompt = "INLINE" } }, - }, profiles) + }, profiles, { tool_call_id = "outer-run" }) + for _ = 1, 100 do + uv.run("nowait") + if workflow.workflows[workflow_id].status ~= "running" then break end + end + assert(workflow.workflows[workflow_id].status == "completed") local child = handle.spawns[3] local manifest = child.system_messages[2].metadata.subagents assert(manifest.inline == true, "inline workflow manifest is explicitly marked") -- cgit v1.3