diff options
| author | t <t@tjp.lol> | 2026-08-31 10:17:11 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-09-02 08:26:58 -0600 |
| commit | 997d80bc69a6363e8c65a987dace0e30d761522d (patch) | |
| tree | 9b5a991a920cbee0d6e8c4e841ec7d28912d2f3a | |
| parent | 7a31ae2163f4ce1c6807da1737203d1063839c14 (diff) | |
Expose background workflow activity events
Bracket each background workflow with lifecycle events and emit its primary
wake before completion so integrations do not report a premature idle state.
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | spec/test_luatool.lua | 4 | ||||
| -rw-r--r-- | subagents/workflow.lua | 11 |
3 files changed, 15 insertions, 6 deletions
@@ -142,8 +142,10 @@ starts model-authored workflows in a restricted environment and returns a session-scoped workflow ID immediately. Work continues on Pantograph's event loop; completion wakes the primary, and later calls can inspect field-read-only records through `subagents.workflows[id]`, including named child status and -outputs. Every `ctx:agent` needs a workflow-unique `name`, and the callback must -return the workflow's string result. +outputs. While one is live the extension emits balanced `background_work_start` +and `background_work_end` events, allowing lifecycle integrations to remain +busy across the primary turn boundary. Every `ctx:agent` needs a workflow-unique +`name`, and the callback must return the workflow's string result. The same read-only workflow records are exposed to other extensions as `panto.ext.workflows`. Extensions can iterate this table or look up an ID; each diff --git a/spec/test_luatool.lua b/spec/test_luatool.lua index e7f2294..ee0a79e 100644 --- a/spec/test_luatool.lua +++ b/spec/test_luatool.lua @@ -112,7 +112,9 @@ return { assert(record.agents.review.status == "completed") assert(#handle.submissions == 1, "completion wakes the primary once") has(handle.submissions[1], id) - assert(handle.emitted[1] == "agent_submission", "the host pipeline is explicitly woken") + assert(table.concat(handle.emitted, ",") == + "background_work_start,agent_submission,background_work_end", + "background work brackets the primary wake") end) end }, diff --git a/subagents/workflow.lua b/subagents/workflow.lua index 671890e..ff534cb 100644 --- a/subagents/workflow.lua +++ b/subagents/workflow.lua @@ -748,6 +748,11 @@ local function make_workflow_record(id) return record end +local function emit(name) + local ext = host() + if type(ext.emit) == "function" then pcall(ext.emit, name) end +end + local function notify(record) if record.suppress_notification or record.status == "cancelled" then return end local primary = host().agent @@ -755,9 +760,7 @@ local function notify(record) local submitted = pcall(primary.submit, primary, string.format( "[subagents] Workflow %s %s. Inspect subagents.workflows[%q] with subagents.lua.", record.id, record.status, record.id)) - if submitted and type(host().emit) == "function" then - pcall(host().emit, "agent_submission") - end + if submitted then emit("agent_submission") end end local function finish_workflow(record, status, result, err) @@ -769,6 +772,7 @@ local function finish_workflow(record, status, result, err) active_workflows[record.id] = nil progress.workflow_finished(record.tool_call_id) notify(record) + emit("background_work_end") end -- Start a model-authored workflow on its own coroutine and return before the @@ -826,6 +830,7 @@ function M.start(wf, opts) end end) progress.workflow_started(record.tool_call_id) + emit("background_work_start") return id end |
