05-examples.md
This document collects representative QPlan examples with a step-first mindset. Each one runs directly with runQplan, using modules from basicModules or src/modules/basic.
1. Hello QPlan โ simplest step
step id="hello" desc="First output" {
echo msg="hello" -> out
print text=out
}
- All actions must be inside steps.
echostores its result inout, andprintreads it directly from ctx.
2. Read a file + compute averages
step id="load" desc="Read file" {
file read path="./nums.txt" -> raw
json parse data=raw -> parsed
return list=parsed
}
step id="avg" desc="Average" {
math op="avg" arr=load.list -> avg
math op="sum" arr=load.list -> total
return average=avg total=total
}
step id="report" desc="Print" {
print label="total" value=avg.total
print label="avg" value=avg.average
}
- Reads a JSON array from disk, parses it, and calculates average and sum.
- References the
loadstep output viaload.listusing dot paths.
3. Async flow with Future + Join
step id="async" desc="Create futures" {
future task="A" delay=300 value="doneA" -> f1
future task="B" delay=500 value="doneB" -> f2
return list=[f1,f2]
}
step id="join" desc="Join futures" {
join futures="f1,f2" -> values
return values=values
}
- The
futuremodule stores{ __future: Promise }objects in ctx, enablingjointo runPromise.allby name.
4. Parallel block with error suppression
step id="parallelWork" desc="Parallel run" {
parallel concurrency=2 ignoreErrors=true {
echo msg="A" -> a
sleep ms=100 -> s1
sleep ms=50 -> s2
jump to="skip" # step control still works inside parallel when the target exists
}
}
step id="skip" desc="Next step" {
print text="parallel finished"
}
- You can place
concurrencyandignoreErrorsbefore or after the block. - Jumps always target step IDs.
5. Each loop with stop/skip
step id="loop" desc="Loop example" {
var 0 -> total
json parse data="[1,2,3,4]" -> nums
each (n, idx) in nums {
if n == 3 {
stop
}
if idx == 0 {
skip
}
math add a=total b=n -> total
}
return count=nums.length total=total
}
- Inside
each,stopexits the loop andskipjumps to the next iteration. - Dot-path access such as
nums.lengthis resolved by the ExecutionContext.
6. Counter updates with While + Set
step id="counter" desc="While loop" {
var 0 -> count
while count < 5 {
set count = count + 1
}
return final=count
}
setonly mutates existing ctx variables, keeping loop arithmetic simple.
7. Step onError policies + jump
step id="prepare" desc="Initialize" {
var 0 -> retryCount
}
step id="mayFail" desc="Failure example" onError="retry=2" {
math op="div" a=1 b=retryCount -> fail # first run divides by zero โ error โ retry
return value=fail
}
step id="cleanup" desc="Handle error" onError="continue" {
jump to="summary"
}
step id="summary" desc="Wrap up" {
print final=mayFail.value
}
onError="retry=2"retries the entire step twice before surfacing the final error.cleanupfinishes safely with onError=โcontinueโ and jumps tosummary.
8. AI-driven usage with module metadata
import { buildAIPlanPrompt, registry, setUserLanguage } from "qplan";
import { httpModule } from "qplan/dist/modules/basic/http.js";
registry.register(httpModule);
setUserLanguage("en"); // supply any language string (e.g., "fr")
const prompt = buildAIPlanPrompt("Fetch open API data and summarize it");
const script = await callLLM(prompt);
await runQplan(script);
- Registering modules automatically teaches the AI how to call them via the prompt builder.
9. Validate before running
import { runQplan, validateQplanScript } from "qplan";
const candidate = `
plan {
@title "Mini example"
step id="one" { print "ok" }
}
`;
const validation = validateQplanScript(candidate);
if (!validation.ok) {
console.error("QPlan validation failed:", validation.error, validation.issues);
} else {
await runQplan(candidate);
}
- The
validateQplanScripthelper lets you keep validation inline with your execution flow (e.g., in agents or CI) without shelling out to the CLI.
Use these examples as a baseline, then add your own ActionModules or customize step structures to capture diverse automation scenarios in QPlan.