Custom Workflows¶
Create your own workflow templates to define custom orchestration patterns. Templates are automatically loaded into the workflow picker.
Template Location¶
Place custom templates in:
Each workflow directory contains a template.yaml file and markdown templates for each task.
Template Structure¶
A workflow template consists of:
~/.perles/workflows/joke-contest/
├── template.yaml # DAG definition and metadata
├── v1-joke-contest-epic.md # Epic instructions (coordinator)
├── v1-joke-contest-joke-1.md # Task 1 template
├── v1-joke-contest-joke-2.md # Task 2 template
├── v1-joke-contest-judge.md # Task 3 template
└── v1-human-review.md # Human review gate
Template YAML Reference¶
Top-Level Registration Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
namespace |
string | Yes | Always "workflow" |
key |
string | Yes | Unique identifier (e.g., "joke-contest") |
version |
string | Yes | Version identifier (e.g., "v1") |
name |
string | Yes | Human-readable name for the workflow picker |
description |
string | Yes | Description of what the workflow does |
epic_template |
string | Yes | Filename of the markdown template for epic content |
system_prompt |
string | No | Override system prompt (usually leave empty) |
path |
string | No | Path prefix for artifact inputs/outputs (e.g., ".spec") |
labels |
list | No | Tags for filtering (e.g., ["category:meta", "lang:go"]) |
arguments |
list | No | User-configurable parameters |
nodes |
list | No | DAG of workflow tasks |
Argument Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Unique identifier, accessed as {{.Args.key}} |
label |
string | Yes | Human-readable label for form field |
description |
string | No | Help text / placeholder |
type |
string | Yes | Input type: text, number, textarea, select, multi-select |
required |
bool | No | Whether the field must be filled (default: false) |
default |
string | No | Default value |
options |
list | Conditional | Required for select and multi-select types |
Node Fields (DAG Tasks)¶
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Unique identifier within the workflow |
name |
string | Yes | Display name for the task |
template |
string | Yes | Filename of the markdown template |
assignee |
string | No | Worker role (e.g., "worker-1", "human" for review gates) |
after |
list | No | Node keys this node depends on (runs after these complete) |
inputs |
list | No | Artifacts consumed by this node |
outputs |
list | No | Artifacts produced by this node |
Artifact Fields (Inputs/Outputs)¶
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Stable identifier for template access (e.g., {{.Inputs.plan}}) |
file |
string | Yes | Filename, may contain template syntax |
Complete Example¶
template.yaml¶
registry:
- namespace: "workflow"
key: "joke-contest"
version: "v1"
name: "Joke Contest"
description: "Two workers write jokes in parallel, then a third judges"
epic_template: "v1-joke-contest-epic.md"
labels:
- "category:meta"
arguments:
- key: "theme"
label: "Joke Theme"
description: "Optional theme or topic for the jokes"
type: "text"
required: false
nodes:
# Phase 1: Parallel joke writing
- key: "joke-1"
name: "Joker 1 - Write Joke"
template: "v1-joke-contest-joke-1.md"
assignee: "worker-1"
- key: "joke-2"
name: "Joker 2 - Write Joke"
template: "v1-joke-contest-joke-2.md"
assignee: "worker-2"
# Phase 2: Human review gate
- key: "review"
name: "Human Review"
template: "v1-human-review.md"
assignee: "human"
after:
- "joke-1"
- "joke-2"
# Phase 3: Judge picks winner
- key: "judge"
name: "Judge - Pick Winner"
template: "v1-joke-contest-judge.md"
assignee: "worker-3"
after:
- "review"
Epic Template (v1-joke-contest-epic.md)¶
Epic templates use Go template syntax and have access to workflow arguments:
# Joke Contest: {{.Name}}
You are the **Coordinator** for a joke contest workflow.
## Context
{{- if .Args.theme}}
- **Theme:** {{.Args.theme}}
{{- else}}
- **Theme:** Any topic (no theme specified)
{{- end}}
## Your Workers
| Worker | Role | Phase |
|--------|------|-------|
| worker-1 | Joker 1 | 1 |
| worker-2 | Joker 2 | 1 |
| human | Reviewer | 2 |
| worker-3 | Judge | 3 |
**NOTE:** You (the Coordinator) are NOT a worker. Start immediately.
Template Variables¶
Templates have access to these variables:
| Variable | Description |
|---|---|
{{.Name}} |
Workflow name |
{{.Args.<key>}} |
User-provided argument values |
{{.Date}} |
Current date |
{{.Inputs.<key>}} |
Input artifact references |
{{.Outputs.<key>}} |
Output artifact references |
DAG Execution¶
Nodes define a directed acyclic graph (DAG):
- Nodes with no
afterfield start immediately (can run in parallel) - Nodes with
afterwait for all listed dependencies to complete assignee: "human"creates a human review gate that pauses for manual approval