Edit Flow
Create and edit pi-flows flows and agents from the main session. Use when the user wants to create a new flow, add or change an agent, or edit an existing flow/agent. Covers agent frontmatter, flow YAML, step types, model references, the flowagents and flowwrite tools, write locations, and how to fix validation errors.
Score breakdown
Estimated from the available content and source signals.
Model compatibility
Inferred fit is not the same as a recorded hands-on test.
Overview
Edit Flow
You are creating and editing pi-flows flows and agents directly in this session. Two tools do the writing (both validate before writing and return diagnostics on failure):
flow_agents—op: "list"returns the agent catalog;op: "write"validates and writes an agent.mdto.pi/flows/agents/<name>.md(filename derived from the agent's frontmattername).flow_write—namespace(defaultcustom),name,content. Validates and writes a flow to.pi/flows/flows/<namespace>/<name>.yaml, which auto-registers as the/<namespace>:<name>command.
These tools derive their write locations from the discovery convention — there is no raw path. Writing to a name that already exists overwrites it (that is how you edit).
The edit-flow tools are off by default. They are active only when
flows.editFlow: trueis set in.pi/settings.json(project, when trusted) or~/.pi/agent/settings.json(global). Ifflow_agents/flow_writeare not available, tell the user to enable that setting and restart the session.
Workflow
- Clarify what the user wants the flow to do. Ask if it is unclear.
- Call
flow_agentswithop: "list"to see existing agents and theirinputs,outputs, andsource_type. Reusebuilt-in/localagents where they fit. - For each role not already covered, author a purpose-built agent with
flow_agentsop: "write". Do not repurpose infrastructure agents (flow-decision,project-context-reader) for unrelated tasks. - Author the flow with
flow_write. Wire every declared input. Fix any validation diagnostics and retry. - Tell the user the resulting command name (
/<namespace>:<name>).
Editing an existing flow/agent = read the current file, change it, then write it back with the same tool and the same name/namespace.
Agent files (.md)
YAML frontmatter + Markdown body (the system prompt).
---
name: code-reviewer
description: Reviews source code for quality and correctness
model: @coding
thinking: medium
tools: read, grep, find
inputs:
- research_context
outputs:
- name: findings
description: Categorized issues found
- name: verdict
description: "pass" or "fail"
access:
read:
- "src/**"
write:
- "src/**"
bash:
deny:
- "rm -rf *"
card:
label: "Reviewer"
metric: "default"
architect:
use_when: "User wants code reviewed for quality"
produces: "A findings report and a pass/fail verdict"
depends_on: "An implementer must have produced code"
domain: "review"
---
# System Prompt
You are a code reviewer. Task: ${{task}}
Context: ${{input.research_context}}
| Field | Required | Notes |
|---|---|---|
name | Yes | Unique. Filename = <name>.md. Referenced as agent: <name> in steps. |
description | Yes | One line. Shown in catalog. |
model | Yes | See Model references. |
tools | Yes | Comma-separated. Guard blocks anything not listed. Standard: read, write, edit, grep, find, ls, bash, ask_user, skill_read. |
thinking | No | off/minimal/low/medium/high/xhigh. Overrides any :level suffix in model. |
skills | No | Comma-separated skill names injected into the prompt. |
inputs | No | Names → ${{input.NAME}} in the prompt. Flow step must wire each one. |
outputs | No | Names (or {name, description} objects). Become finish parameters and ${{result.STEP.NAME}} downstream. |
interactive | No | true allows mid-task UI prompts. Default false. |
output | No | Output file hint (display only). |
access | No | read/write glob allowlists; bash.deny command patterns. * = segment, ** = any depth. |
card | No | label, metric (default/files/tests/custom), role. |
architect | No | use_when/produces/depends_on/domain metadata surfaced in flow_agents op: list. |
Model references
The model: field accepts three forms. Prefer @role. Use the other two when a specific model is required regardless of role config, or when the user explicitly asks for a non-role model.
| Form | Example | When |
|---|---|---|
@role (preferred) | model: @coding | Default. Resolves via the active role→model map (/roles). Built-in roles: @planning, @coding, @fast, @architect. |
provider/model[:thinking] | model: anthropic/claude-haiku-4-5:high | A specific provider+model is required; optional :thinking suffix sets the thinking level. |
bare model-id | model: claude-haiku-4-5 | A specific model id with no provider qualifier; thinking comes from the thinking: field or none. |
A thinking: field always overrides any :thinking suffix in model.
Flow files (.yaml)
name: my-flow # REQUIRED
description: What it does # REQUIRED
max_concurrent: 3 # optional (default 4)
task_required: true # optional — prompt for task if invoked with no args
task_prompt: "Task:" # optional
steps:
- id: research
agent: code-reviewer
task: Review ${{task}}
name is the frontmatter name; the command name comes from the on-disk location (namespace/name you pass to flow_write). Every step needs a unique id. Step type is usually inferred from which fields are present; set type: explicitly when ambiguous.
Step types
- agent — dispatch an agent.
- id: impl agent: implementer task: Implement ${{task}} blockedBy: [research] inputs: ctx: ${{result.research.summary}} on_complete: verify # optional cross-segment jump on_error: handler # optional - fork — user (or
agent:in autonomous mode) picks a branch.
Branch keys must match- id: choose type: fork question: Which strategy? options: [Fast, Full] branches: { Fast: fast-impl, Full: full-impl } agent: flow-decision # autonomous-mode decider allowCustom: false multiSelect: falseoptionsexactly. - conditional — presence/absence of a result field.
- id: has-gaps type: conditional check: research.artifacts # stepId.field present: gap-filler absent: finalize - agent-decision — agent calls
finish({ branch })to choose.- id: complexity type: agent-decision agent: analyzer task: Simple or complex? branches: { simple: quick, complex: thorough } - agent-loop-decision — loop back or exit.
- id: should-fix type: agent-loop-decision agent: flow-decision task: Iteration ${{loop.should-fix.iteration}}/${{loop.should-fix.max}}. ${{result.verify.summary}} loop_target: fixer # jump back exit_target: done # continue forward max_iterations: 3 - flow-ref — delegate to another flow file.
- id: sub type: flow-ref path: "project/changes/*/exec.yaml" # glob ok on_complete: verify
Template variables
Expanded in task, inputs values, and question. Not validated — a typo silently becomes empty string.
${{task}}— the user task.${{input.NAME}}— input wired into this step.${{result.STEP_ID.status|summary|artifacts|files|fullOutput|OUTPUTNAME}}—STEP_IDis the stepid, not the agent name.${{loop.STEP_ID.iteration|max}}— loop counters.
Wire data between steps via inputs: (agent declares names in frontmatter, step supplies values). Prefix an input value with file:// to inject file content verbatim; that file's producer step must be in blockedBy.
Write locations (discovery)
| Content | Tool | Lands at |
|---|---|---|
| Agent | flow_agents op: write | .pi/flows/agents/<name>.md |
| Flow | flow_write | .pi/flows/flows/<namespace>/<name>.yaml → /<namespace>:<name> |
Project-local definitions (.pi/flows/) override package and built-in ones.
Fixing validation errors
Both tools validate before writing. On failure they return { written: false, diagnostics: [...] } and write nothing. Read each diagnostic's message and suggestion, fix the content, and call the tool again. Common cases:
- Missing required field (
name,description,model,toolsfor agents;name,descriptionfor flows) → add it. - "Agent not in catalog" → the flow references an agent that does not exist. Create it with
flow_agentsop: write, then retryflow_write. - Unwired declared input → add the missing key to the step's
inputs:block. - Unknown tool in
tools:→ use a valid tool name (see the standard list above) or an extension-registered tool name. - Invalid YAML → fix indentation/quoting; re-validate.
Best for
- Clarify what the user wants the flow to do. Ask if it is unclear.
- Call flowagents with op: "list" to see existing agents and their inputs, outputs, and sourcetype. Reuse built-in/local agents where they fit.
- For each role not already covered, author a purpose-built agent with flowagents op: "write". Do not repurpose infrastructure agents (flow-decision, project-context-reader) for unrelated tasks.
- Author the flow with flowwrite. Wire every declared input. Fix any validation diagnostics and retry.
- Tell the user the resulting command name (/<namespace>:<name>).
Tips and best practices
- Review the source instructions and adapt inputs before running the workflow.
What This Skill Can Do
AI-generated examples showing real capabilities
Was this skill useful?
Be the first to share a result.