Skip to main content
T1 starter · every office job: the first example with infer.schema:. The model doesn’t get to answer in prose. It returns the JSON shape you declared, or the engine rejects it.

The job

The meeting ended an hour ago and nobody remembers who owns what. The transcript is sitting in a file. This workflow extracts every action item as {owner, task, due}: typed, validated, importable by whatever tracker you use.

The shape

The file

meeting-actions.nika

How it works

1

A typed input with a default

transcript_path is type: string with a default: path — the caller may omit it. The engine still validates the value before any task runs. There is no required: true on this input.
2

The schema IS the contract

infer.schema: is standard JSON Schema. The model must return a matching object. On violation the engine rejects (and may retry). Downstream tasks index into it directly: ${{ tasks.extract.output.actions }}.
3

Write, then a success-only log

save writes the JSON. trace is not a parallel sibling: it runs after: { save: success } — only if the write succeeded.

Constructs you just used

Make it yours

  • Add due to the required: list if your team always sets deadlines.
  • Chain a nika:notify task that posts each owner their items.
  • Swap the transcript file for a nika:fetch of your meeting tool’s export API. The schema doesn’t change.

Next · Price watch

The next starter has zero model calls: pure tools, bindings and one CEL comparison.