# panto-subagents Delegation and workflows for [Pantograph](https://github.com/travisp/pantograph). The `subagents` extension lets a primary agent start specialized child agents, run several at once, and continue their conversations later. ## Install ```toml [extensions] rocks = ["panto-subagents"] ``` For a local checkout, use `paths = ["/path/to/panto-subagents"]` instead. ### Dependencies Panto installs the rock's dependencies with it: - **lyaml** parses profile frontmatter. It binds the system libyaml, which LuaRocks does not vendor — install it first (`brew install libyaml`, or `apt install libyaml-dev`), otherwise the rock fails to build and panto quietly starts without the `subagents.*` tools. - **toml2lua** reads TOML workflows. Pure Lua, nothing to install. - **luv** backs profile and workflow discovery. Panto already ships it. Structured workflow output is validated against its JSON Schema by a built-in validator covering the schema subset those results use. Installing the `jsonschema` rock switches validation over to it; that rock needs a system PCRE, so it is not a declared dependency. ## Agent profiles Agents are Markdown files with YAML frontmatter: ```markdown --- name: reviewer description: Reviews changes for correctness and missing tests model: anthropic:sonnet reasoning: high --- You are a focused code reviewer. Report only concrete findings. ``` Profiles are loaded recursively from: - `${XDG_CONFIG_HOME:-$HOME/.config}/panto/agents/` - `.panto/agents/` in the current project Project profiles override user profiles with the same name. `name` defaults to the filename. `model` and `reasoning` are optional; each value follows the same precedence: tool call, then profile, then the primary agent. Models use full `provider:model` names. ## Delegation The primary uses `subagents.run` to start a child from a profile: ```lua subagents.run { agent = "reviewer", prompt = "Review the authentication changes.", } ``` Every started child returns an ID. Passing it back resumes the same conversation, including after restarting Panto and resuming the primary: ```lua subagents.run { id = "0198...", prompt = "Now focus on the missing tests.", } ``` Children receive the primary's system and project context plus their own profile prompt, but not the primary's conversation. They share its workspace and tools except for `subagents.*`. Multiple calls in one tool batch run concurrently. Their tagged assistant and tool activity is visible in the TUI while they work. Child conversations are stored as normal JSONL sessions beneath their owning primary session, so they remain resumable without appearing in the user's `/resume` picker. A child ID cannot be resumed from another primary conversation. `subagents.models` provides bounded search and validation for configured providers, models, and model-specific reasoning levels without placing the entire model catalog in every tool prompt. ## Workflows TOML workflows define fixed dependency graphs. They are loaded from `${XDG_CONFIG_HOME:-$HOME/.config}/panto/workflows/` and `.panto/workflows/`, then exposed as `/workflow:` commands. Ready steps run concurrently; each dependent step receives its predecessors' labeled outputs. The Lua workflow API handles dynamic branching and fan-out. It can await one job or a group, and supports one-turn workers whose validated tool input is their structured result. `subagents.lua` may also define workflow-local agent profiles inline, so a primary can create specialized workers without writing profile files or restarting Panto; those profiles disappear when the tool call ends. Panto extensions can use this API directly, while `subagents.lua` runs model-authored one-off workflows in a restricted Lua environment. ## Development [mise](https://mise.jdx.dev) provides Lua 5.4 and LuaRocks: ```sh mise run deps # install the rocks into ./.rocks (gitignored) mise run check # run the specs against that tree ``` `mise run deps` passes Homebrew's libyaml prefix to lyaml when brew is available. Without mise, install the same rocks with any LuaRocks targeting Lua 5.4 and run `lua spec/run.lua` from the repo root. `panto lua spec/run.lua` runs the suite inside panto's own interpreter and rocks tree, skipping whatever cases that tree has no rock for. The specs are plain Lua asserts — no framework. `spec/run.lua` loads every `spec/test_*.lua`, each of which returns an ordered array of `{ name, function }` cases. A case asserts and returns nothing to pass, or returns `"skip", reason` when an optional rock is missing; skips do not fail the run. `spec/fake_ext.lua` is a scriptable stand-in for the `panto.ext` host seam: it queues the result each spawned child settles with, records every spawn spec, tool, and command the extension produced, and settles awaits synchronously. See [DESIGN.md](DESIGN.md) for the runtime and persistence design.