Template Authoring
Templates are pre-built pipelines packaged as JSON. When deployed, Pulse checks prerequisites, runs a wizard to collect configuration, substitutes placeholders, and wires every node into a running agent graph.
Back to Developer HubWhere templates live
Built-in
Shipped with the release. Curated and reviewed before merge. Available to every install.
User templates
Per-install, hot-reloaded on demand. Drop a JSON file into the user-templates folder of your data directory; it never propagates to other installs.
Template anatomy
A template is a single JSON document. Top-level metadata, a prerequisites list, the wizard's config fields, the node graph, and an optional topics manifest.
1{
2 "id": "job-matcher-auto-apply",
3 "name": "Job Matcher, Auto Apply",
4 "description": "Polls job sources, scores against the candidate CV, drafts tailored applications, routes through optional human review, and dispatches.",
5 "category": "Human Resources",
6 "industry": "HR",
7 "workflow": "routing",
8 "icon": "Briefcase",
9 "tags": ["job", "candidate", "auto-apply"],
10
11 "prerequisites": [
12 { "title": "LLM Provider", "description": "A configured language-model provider." },
13 { "title": "Job Sources", "description": "At least one job-board connector installed." }
14 ],
15
16 "configFields": [
17 {
18 "key": "candidateName",
19 "label": "Your full name",
20 "type": "TEXT",
21 "required": true,
22 "group": "Identity"
23 },
24 {
25 "key": "minScore",
26 "label": "Minimum match score (0-100)",
27 "type": "NUMBER",
28 "required": false,
29 "defaultValue": 70,
30 "group": "Matching"
31 }
32 ],
33
34 "nodes": [
35 {
36 "id": "fetcher",
37 "type": "agent",
38 "label": "Job Fetcher",
39 "engine": "external-tools",
40 "inputTopic": "schedule.jobs-poll",
41 "outputTopic": "raw-jobs",
42 "externalTools": ["jobs.list_new"]
43 },
44 {
45 "id": "scorer",
46 "type": "agent",
47 "label": "Match Scorer",
48 "engine": "llm",
49 "inputTopic": "raw-jobs",
50 "outputTopic": "scored-jobs",
51 "systemPrompt": "Evaluate jobs for {{candidateName}}. Score 0-100 based on skills match."
52 }
53 ],
54
55 "topics": [
56 { "name": "raw-jobs", "description": "Jobs as received from sources, pre-scoring." }
57 ]
58}Config fields, 8 types
configFields drives the deploy wizard. Each entry sets the input control and how the value is substituted into nodes.
| Type | Renders as | Substitution |
|---|---|---|
| TEXT | Single-line input | {{key}} → verbatim |
| Email input | {{key}} → verbatim | |
| PASSWORD | Masked input | {{key}} → never logged |
| NUMBER | Numeric input | {{key}} → as number |
| TOGGLE | Switch | {{key}} → "true" / "false" |
| SELECT | Dropdown | {{key}} → option value |
| TAGS | Chip input | {{key}} → CSV string |
| UPLOAD | File dropzone | {{key}} → file path |
SELECT example
1{
2 "key": "llmProvider",
3 "label": "LLM provider",
4 "type": "SELECT",
5 "options": [
6 { "value": "local", "label": "Local model" },
7 { "value": "managed-a", "label": "Managed provider A" },
8 { "value": "managed-b", "label": "Managed provider B" }
9 ],
10 "defaultValue": "local"
11}Conditional visibility
1{
2 "key": "webhookUrl",
3 "label": "Webhook URL",
4 "type": "TEXT",
5 "visibleWhen": { "field": "dispatcher", "equals": "webhook" }
6}Placeholder substitution
- Dotted paths work: {{candidate.name}}.
- List values become CSV.
- Booleans become "true" / "false" strings.
- Missing keys fail-fast in the wizard.
- Substitution is recursive, resolved left-to-right.
Before
"systemPrompt": "Hi {{candidateName}}. Match jobs scoring at least {{minScore}}. Required skills: {{keywords}}."After wizard fill
"systemPrompt": "Hi Alice. Match jobs scoring at least 75. Required skills: kubernetes,terraform."Prerequisites
Two flavours: declarative checks Pulse evaluates automatically (plugin installed, setting non-blank), and human-readable prose for ambiguous setups (pick-one-of-many, version-sensitive).
Most templates mix both, declarative for the basics, prose for the nuances.
Node engines
rule-based
Deterministic routing on field comparisons. No model calls.
1{
2 "engine": "rule-based",
3 "rules": [
4 { "condition": "score >= {{minScore}}", "action": "emit", "target": "qualified" },
5 { "condition": "always", "action": "emit", "target": "rejected" }
6 ]
7}llm
Reasoning agent backed by a language model. Optional consensus mode adds redundancy on critical steps.
1{
2 "engine": "llm",
3 "systemPrompt": "...",
4 "temperature": 0.3,
5 "maxTokens": 1000,
6 "consensus": { "enabled": true, "quorumSize": 3 }
7}external-tools
Scripted tool-calling. Executes tools in prompt order without inter-step reasoning. For branching, use llm.
1{
2 "engine": "external-tools",
3 "externalTools": ["jobs.list_new", "jobs.list_recent"],
4 "systemPrompt": "Use the tools to fetch new postings every cycle.",
5 "maxToolCalls": 5
6}Best practices
IDs are permanent
Changing an id breaks every deployed instance. Use lowercase-kebab-case and pick carefully.
Strong descriptions
The root description drives adoption. Name workflows explicitly; describe the output.
Group fields by narrative
Identity → Preferences → Credentials → Advanced. Narrative beats alphabetical.
Defensive defaults
Every optional field needs a sane default. Deploy-without-fill must yield a working pipeline.
Validate in the wizard
Fail-fast in the wizard on missing credentials or invalid ranges, not at the third event in production.
Name topics semantically
raw-jobs beats topic-1. Operators read these names in the Flow page.
Opt into consensus
Don't default every llm node to consensus mode, only where a single-model mistake is expensive.
Pass-through fields
Use passThroughFields to preserve event state through agents that only modify a subset.
Test cases
Embed test cases inside the template; the dry-run endpoint replays them against the deployed graph during development.
1"testCases": [
2 {
3 "name": "matches well-fitting job",
4 "input": { "title": "Senior Rust Developer", "salary": 180000 },
5 "expectedOutput": { "score": { "min": 80 } }
6 }
7]Shadow templates
Mark a template as shadow-only. It only appears under Pipelines → Shadows. Operators run it against real traffic, compare to production, then promote when confident.
1{
2 "id": "job-matcher-v2-experimental",
3 "shadow": true,
4 "nodes": [...]
5}Publishing
Built-in (PR)
Add the JSON to the pipeline-templates resources, run the lint-audit test suite, submit a PR with a short justification.
User template
Drop the JSON into the user-templates folder of your data directory and reload from Templates → Refresh. Appears with a Custom badge; never shared automatically.
Troubleshooting
| Symptom | Fix |
|---|---|
| Template not found | Verify the file is under the right folder with a .json extension. |
| Unknown placeholder {{foo}} | Add foo to configFields or check the spelling. |
| Missing required prerequisite | The referenced plugin isn't installed, fix in Settings. |
| Agent never receives events | Confirm inputTopic matches the upstream agent's outputTopic. |
| Validation failed: schema mismatch | Events don't match the topic schema, adjust schema or producer. |
Browse the template gallery
See the published catalogue of pipelines you can deploy in one click.