Skip to content

Generators ​

Generators make additional LLM or image-generation calls beyond the normal chat reply. The results go into variables, which you can then use in content rules, expressions, or other classifiers.

Use generators for things like: generating a scene background image when the location changes, producing a short story recap, or creating procedural flavor text.

Generators are extra API calls. Each one adds latency and token cost. Use conditions to prevent unnecessary calls.

Basic shape ​

Text generator ​

json
{
  "name": "StoryRecap",
  "type": "Text",
  "phase": "On Response",
  "condition": "turnCount % 5 == 0",
  "prompt": "Summarize the last few events in one sentence.",
  "includeHistory": true,
  "maxTokens": "80",
  "updates": [
    { "variable": "recap", "setTo": "{{content}}" }
  ]
}

% is the remainder operator — turnCount % 5 == 0 means "every 5 turns" (when the turn number divides evenly by 5).

Image generator ​

json
{
  "name": "SceneImage",
  "type": "Image",
  "phase": "On Response",
  "condition": "sceneChanged",
  "prompt": "\"A fantasy scene: \" + currentScene",
  "aspectRatio": "16:9",
  "updates": [
    { "variable": "background", "setTo": "{{content}}" }
  ]
}

Fields shared by all generator types ​

name ​

A unique identifier for this generator. Used in dependency references.

type ​

One of: "Text", "Image", "Image-to-Image". Default: "Text".

phase ​

When the generator fires:

  • "On Input" — after the user sends a message, before the bot replies
  • "On Response" — after the bot replies

Note: the schema previously listed an "Initialization" phase option but this was removed from the schema. Use "On Input" with a condition like isNull(someVariable) to initialize variables on first use instead. See Gotchas.

condition ​

An expression. The generator only runs if this evaluates to truthy (true or a number greater than zero). Always set a condition — generators are expensive.

json
{ "condition": "sceneChanged" }
{ "condition": "turnCount % 5 == 0" }
{ "condition": "isNull(recap)" }

lazy ​

Default: false. Note: in the current release, this setting does not do anything yet — you can ignore it. The stage always waits for all generators to complete before returning a response, regardless of this flag. (source)

dependencies ​

A comma-separated list of classifier or generator names that must complete before this generator fires.

prompt ​

The prompt to send. This is an expression (or a string template). Use template tags to include current state.

json
{ "prompt": "\"Describe the scene: \" + currentScene" }
{ "prompt": "\"What is {{char}} likely to do next, given mood = \" + mood + \"?\"" }

updates ​

Variable updates applied when the generator finishes. Use {{content}} to reference the generator's output.

json
"updates": [
  { "variable": "recap", "setTo": "{{content}}" },
  { "variable": "lastGeneratedAt", "setTo": "turnCount" }
]

Text generator fields ​

includeHistory ​

When true, recent chat history is included in the prompt for context. Increases token usage.

historyContextSize ​

Default: 0 (use preset). Only relevant when includeHistory is true. A number limiting how much history is sent.

minTokens ​

Default: "50". The minimum number of tokens to request in the response.

maxTokens ​

Default: "250". The maximum number of tokens to request. Keep this low for concise outputs like labels or short phrases.

stoppingStrings ​

A comma-delimited list of strings. If the LLM produces any of them, the response ends there.

json
{ "stoppingStrings": "\\n,." }

retryCondition ​

Default: "" (never retry, treated as false). If this formula evaluates to true after the generator runs, the generator retries. {{content}} is available here and refers to the generator's output — this is a special case where the generator's output becomes available as {{content}}, overriding the normal rule that template tags only appear inside strings. The stage will retry at most three times.

json
{ "retryCondition": "isNull({{content}}) or {{content}} == \"\"" }
{ "retryCondition": "not contains({{content}}, \"http\")" }

Image generator fields ​

negativePrompt ​

Content to exclude from the generated image.

json
{ "negativePrompt": "blurry, low quality, text" }

aspectRatio ​

Valid values: "21:9", "16:9", "3:2", "5:4", "1:1", "4:5", "2:3", "9:16", "9:21".

json
{ "aspectRatio": "16:9" }

removeBackground ​

When true, attempts to remove the background from the generated image.

Image-to-Image generator fields ​

Advanced — skip if you're just getting started

Image-to-Image generation is a specialized feature. The notes below and the known bug are only relevant if you are building bots that transform existing images.

Image-to-Image generators take an existing image and transform it.

sourceImageUrl ​

An expression that evaluates to a URL of the source image.

json
{ "sourceImageUrl": "background" }

imageToImageType ​

The transform model to use. Values (case-sensitive, lowercase): "edit", "canny", "face". Default: "edit".

  • "edit" (Qwen) — general-purpose image editing
  • "canny" (Flux) — edge-guided generation
  • "face" (Flux) — face-swap style transfer

Known bug: the current release reads this from a misspelled key iamgeToImageType in the source code. If you set imageToImageType to "canny" or "face", the stage reads undefined and defaults to "edit". See Gotchas.

Worked examples ​

A recap generator that fires every five turns ​

json
{
  "name": "Recap",
  "type": "Text",
  "phase": "On Response",
  "condition": "turnCount % 5 == 0",
  "prompt": "\"In one sentence, summarize the most recent events in this conversation.\"",
  "includeHistory": true,
  "maxTokens": "80",
  "stoppingStrings": "\\n",
  "updates": [
    { "variable": "recap", "setTo": "{{content}}" }
  ]
}

A scene background image gated on a flag ​

json
{
  "name": "BackgroundImage",
  "type": "Image",
  "phase": "On Response",
  "condition": "sceneChanged",
  "prompt": "\"Fantasy scene, detailed illustration: \" + currentScene + \". No text, no UI elements.\"",
  "negativePrompt": "text, letters, watermark, ui",
  "aspectRatio": "16:9",
  "updates": [
    { "variable": "background", "setTo": "{{content}}" }
  ]
}

The background variable has a special meaning — Statosphere uses it to set the chat background. See Background Variable.