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.
  • echo stores its result in out, and print reads 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 load step output via load.list using 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 future module stores { __future: Promise } objects in ctx, enabling join to run Promise.all by 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 concurrency and ignoreErrors before 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, stop exits the loop and skip jumps to the next iteration.
  • Dot-path access such as nums.length is 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
}
  • set only 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.
  • cleanup finishes safely with onError=โ€œcontinueโ€ and jumps to summary.

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 validateQplanScript helper 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.