Skip to content

Generators

A Generator is a saved recipe: a form and a fixed pipeline of steps that turn your answers into a finished deliverable, every time, without re-planning from scratch.

{
id, ownerId, name, slug, description, icon,
inputsSchema: Json, // JSON Schema for the input form
steps: GeneratorStep[],
outputKinds: OutputKind[], // 'text'|'markdown'|'docx'|'pdf'|'image'|'code'|'react-app'|'fullstack-app'|'html'|'scene3d'|'data'|'zip'
priceCredits: number,
isPublic: boolean,
runs: number,
createdAt,
}
GeneratorStep = {
id, title, role, // e.g. role: 'researcher'
skills: string[], // built-in skill names this step is allowed to use
instruction: string, // templated: {{inputs.x}}, {{steps.id.output}}
tier: 'cheap' | 'standard' | 'strong',
dependsOn: string[],
outputKind: OutputKind,
}
GET /api/studio/generators → Generator[] (public ones + your own)
POST /api/studio/generators → Generator
GET /api/studio/generators/:idOrSlug → Generator
PUT /api/studio/generators/:id → Generator (owner or the world owner only)
DELETE /api/studio/generators/:id

The input form

inputsSchema is plain JSON Schema, built with a small authoring kit (apps/api/src/studio/generators/define.ts): str/text (single-line vs. multiline), num, bool, pick (enum), each carrying a human title, help text, placeholder, and validation (minLength, min/max, etc.). The Studio’s generator form (schemaForm.tsx) renders this schema directly — a new field type in the schema is a new field in the UI with no extra frontend code. A few non-standard hints steer the form without breaking any other JSON Schema consumer: x-multiline (textarea), x-placeholder, x-advanced (folded under “Advanced”), x-showWhen (conditional on another boolean field — e.g. the email campaign’s “test recipient” field only appears once “send a test” is checked).

Templating

Two placeholder forms are interpreted when a step’s instruction/title is rendered (renderTemplate() in packages/agents/src/graph.ts):

  • {{inputs.<field>}} — the value you typed into that form field.
  • {{steps.<id>.output}} — the text output of an earlier step in the same run; using this implicitly makes the current step depend on that one.

Running one

POST /api/studio/projects { generatorId: "gen_blog", inputs: { topic: "...", tone: "Direct and opinionated", wordCount: 900 } }

Because a generator’s steps are already a complete, valid task graph, plan() skips the model call entirely for this path — it renders the templates and hands the result straight to the same repair pass (research-task guarantee, cycle check) that a free-text brief goes through. This is why generator runs are cheaper and more predictable than free-text briefs: the only model calls are the steps themselves, never a planning call.

Validation, structurally enforced

Every generator — seeded or user-created — is checked against real constraints before it can run (validateSeedGenerators() in apps/api/src/studio/generators/index.ts, asserted at API boot for the seed catalogue): unique ids/slugs, every referenced skill exists in BUILTIN_SKILLS, every dependsOn points at an earlier step, every {{steps.x.output}} reference is backed by an actual dependency, every declared outputKind is produced by at least one step, and — enforced structurally, not just by convention — no step may use the strong tier. strong is reserved for the planner and the QA reviewer only; a generator step that tried to request it would fail validation before ever reaching a user.

Saving your own

POST /api/studio/generators takes the same shape (minus id/ownerId/runs/createdAt); a slug is derived from the name if you don’t supply one.

You do not have to write that JSON by hand. GeneratorBuilder.tsx in the Studio is a real visual builder: pick an icon, name and description; design the input form field by field (text, long text, number, yes/no, a choice, a list — with labels, descriptions, defaults and required flags); then build the pipeline as a stack of reorderable steps, each with a role, a model tier, an output kind, the skills it may call, what it depends on, and its instruction template. An earlier version of this page described it as a raw JSON editor; that is no longer true.

Once saved (and made public), your generator appears in the Studio’s generator gallery alongside the eleven seeded ones and can be listed on the Marketplace.

A run can also author one for you — studio.author_generator, driven by the Agent crew & pipeline generator — which is the same thing arrived at from the other direction: describe the work, get back a crew and a pipeline that names it.

The eleven seeded generators

Every fresh install ships with ten generators, upserted idempotently at boot (seedGenerators()) — see the Generators catalogue for one page per generator with its exact fields and pipeline.