Skip to content

5queezer/pi-subflow

Repository files navigation

pi-subflow

Delegate bounded work from Pi to isolated subagents with single-task, chain, parallel, and DAG workflows, including conditional edges, nested workflows, and bounded loops.

pi-subflow is a Pi extension and TypeScript orchestration core for coordinating focused subagents without putting planning, policy checks, execution, validation, and rendering into one oversized prompt.

Use it when work benefits from independent research/review streams, staged handoffs, or a final verifier. Do not use it for small direct tasks the current assistant can do faster by itself.

Features

  • Single, chain, parallel, DAG, conditional-edge, bounded-loop, and nested-workflow subagent execution
  • DAG preflight validation with precise diagnostics
  • PocketFlow node-backed internal DAG execution for validation, max-turns guards, stage execution, verifier repair, and result aggregation
  • dagYaml shorthand for concise LLM-authored task graphs
  • Inline nested workflows with parent/child namespacing and synthetic summaries
  • Verifier fan-in with dependency-output injection
  • Markdown-section and minimal JSON required-field validation
  • Retry, timeout, max-turn, and budget helpers
  • Project/user agent discovery with policy gates
  • Runtime tool allowlist checks
  • Workflow slash commands from .pi/subflow/workflows/*.{yaml,yml} and ~/.pi/agent/subflow/workflows/*.{yaml,yml}
  • Dry-run workflow optimization with subflow_optimize, scorer-backed eval sets, objective scoring, manual candidate comparison, train/holdout splits, budget controls, and safe JSON reports in .pi/subflow/optimizer-reports/
  • JSONL run history at .pi/subflow/runs.jsonl

Quick start

git clone git@github.com:5queezer/pi-subflow.git pi-subflow
cd pi-subflow
npm install
npm run build
pi -e ./dist/extension.js

Then ask Pi to use the subflow tool, for example:

Use subflow to run API, test, and docs reviewers in parallel, then run a verifier that synthesizes the findings.

For local development, you can symlink the built extension and reload Pi after rebuilding. The build also links dist/node_modules back to the project dependencies so Pi can resolve runtime packages such as yaml when the extension directory points at dist.

ln -sfn "$PWD/dist" ~/.pi/agent/extensions/subflow
npm run build
# then run /reload inside Pi

Workflow modes

flowchart TD
  U[User request] --> D{Work shape?}
  D -->|One bounded task| S[Single]
  D -->|Linear handoff| C[Chain]
  D -->|Independent tasks| P[Parallel]
  D -->|Named dependencies| G[DAG]
  P --> V[Verifier fan-in]
  G --> V
Loading
Mode Use when Input shape
Single exactly one focused subagent task is useful agent + task
Chain each step needs the previous step's output chain: [{ agent, task }] with optional {previous}
Parallel 2+ tasks are independent tasks: [...] with no dependsOn
DAG tasks have named dependencies, conditional edges, verifier fan-in, or bounded loops tasks: [...] with dependsOn, when, loop, or dagYaml
Nested workflows a task contains inline child tasks or statically includes a relative workflow file workflow: { tasks: [...] }, workflow: { dagYaml }, or workflow: { uses }

Example DAG shorthand:

api-review:
  agent: reviewer
  task: Review src/index.ts and public exports

test-review:
  agent: reviewer
  task: Review tests for coverage gaps

final-verdict:
  agent: reviewer
  role: verifier
  needs: [api-review, test-review]
  task: Synthesize the findings into a prioritized verdict

Verifier tasks receive dependency outputs automatically. A verifier with no explicit dependsOn depends on all non-verifier tasks. dagYaml is parsed as YAML, so arrays can be written inline (needs: [api-review, test-review]) or as block sequences. Conditional edges use when expressions against dependency outputs. Nested workflows namespace child task names under the parent, flow the parent dependsOn into workflow roots, and expose a synthetic parent summary for downstream dependents. Bounded loops repeat a namespaced body up to loop.maxIterations, can stop early with loop.until, and expose a synthetic loop summary for downstream dependents. DAG execution is node-backed internally even though the public API stays runDag; chain and parallel remain custom orchestration.

Workflow templates

Example workflows live in examples/workflows/, split into concrete recipes (task-specific jobs) and abstract patterns (reusable shapes). Both advertise the DAG YAML schema with:

# yaml-language-server: $schema=https://raw.githubusercontent.com/5queezer/pi-subflow/refs/heads/master/schemas/subflow-dag.schema.json

Recipes (concrete jobs):

Patterns (reusable DAG shapes — see Workflow patterns for model fit and rationale):

Copy a .yaml or .yml template into .pi/subflow/workflows/ to register it as a slash command at Pi session startup:

.pi/subflow/workflows/code-review.yaml -> /code-review
.pi/subflow/workflows/code-review.yml  -> /code-review

User-level workflow files are also supported under ~/.pi/agent/subflow/workflows/. If a project and user workflow have the same command name, the project workflow wins. During prompt-resource discovery, the extension writes generated prompt stubs under .pi/subflow/prompts/ or ~/.pi/agent/subflow/prompts/ when no manual prompt file with the same name exists, so Pi can discover the workflow prompt surface. Run /reload or start a new session after adding, removing, or renaming workflow files.

Development

npm install
npm run build && npm test

Before submitting changes, run:

npm run build && npm test

Optimizer

subflow_propose_candidates generates validated static DAG candidate YAMLs without executing or mutating workflows. safe and exploratory currently share the verifier fan-in transform; model-thinking proposes deterministic verifier-only model/thinking variants for later optimizer evaluation. subflow_optimize is dry-run-only and writes JSON reports without mutating workflow files:

subflow_optimize({
  workflowPath | dagYaml,
  evalSet: { path | inline },
  candidateDagYamls?,
  maxCandidateRuns?,
  maxCost?,
  maxRunCost?,
  maxCandidateCost?,
  maxTotalCost?,
  maxConcurrency?,
  timeoutSeconds?,
})
  • Use subflow_propose_candidates to generate candidate YAMLs, then pass selected valid outputs to subflow_optimize as candidateDagYamls.
  • Use strategy: "model-thinking" to generate verifier-only model/thinking variants from the built-in Mini/Strong search space; Bayesian search, all-task mutation, and custom search spaces are future work.
  • Canonical eval sets should be stored at .pi/subflow/evals/*.yaml and loaded via evalSet.path.
  • For quick experiments, use evalSet.inline (not recommended for reusable cases).
  • maxCandidateRuns limits candidate runs per case.
  • maxRunCost caps cost per run, maxCandidateCost caps total cost per candidate, and maxTotalCost caps total optimizer spend.
  • maxCost is a compatibility alias for current per-candidate budget behavior; when no dedicated caps are provided, it is also passed as the run-level cost cap.
  • maxConcurrency and timeoutSeconds control executor behavior.
  • Invalid candidates are reported individually and do not abort the entire optimizer run.
  • Reports are written under .pi/subflow/optimizer-reports/.
  • Optimizer assets: examples/evals/docs-consistency.yaml, examples/workflows/recipes/docs-consistency.yaml

Documentation

  • GitHub Wiki — detailed usage, TypeScript API, configuration, policy, architecture, current DAG expressiveness (conditional edges, nested workflows, bounded loops), remaining graph roadmap items, workflow optimization, self-optimizing static DAGs, and troubleshooting. Source pages live in doc/wiki/ and are published with npm run wiki:sync or npm run wiki:sync:push.
  • doc/wiki/Workflow-optimization.md — dry-run optimizer, canonical eval sets, scorer-backed recommendations, train/holdout splits, and safety model
  • schemas/subflow-dag.schema.json — YAML schema for workflow templates
  • schemas/subflow-eval.schema.json — YAML schema for optimizer eval sets
  • doc/adr/ — architecture decision records
  • CONTRIBUTING.md — contribution workflow

Keep the README, wiki, ADRs, and the subflow tool's LLM-facing guidance synchronized when behavior, schema, validation, public API, install/test commands, or design rationale change.

License

ISC

About

Pi extension and TypeScript orchestration core for bounded subagent workflows, including chains, parallel fanout, and validated DAG fan-in.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors