Redeo Docs
DocsLukiScript / Config Top-Level Structure

Specification

Config Top-Level Structure

Every stilt config has a handful of top-level keys that define identity, provider constraints, and the execution graph.

Config Top-Level Structure

Every stilt config has a handful of top-level keys that define identity, provider constraints, and the execution graph.

Config Structure

A stilt config is a YAML or JSON object with the following top-level keys. The platform auto-manages id, version, and author from the account:

yaml
name: My Stilt                    # required — display name, shown in the library
description: What this stilt does  # optional — shown below the name in the library

allowedTargets:                    # required — which providers/models this stilt can use
  strategy: universal              # "universal" or "constrained"

exit: step1                        # required — which step produces the final answer

knobs: {}                          # required (can be empty) — runtime controls

steps: []                          # required — ordered list of execution steps

name is the only field that must always be present. Everything else has sensible defaults or is filled in by the platform.

steps is the execution graph — an ordered array of steps that run from top to bottom. Each step makes one or more LLM calls. Steps can read outputs from previous steps, branch into parallel nodes, loop over the entire sequence, and more. The rest of this documentation covers what goes inside steps and knobs.

allowedTargets

allowedTargets controls which providers and models a stilt can use. Two strategies are available:

Universal — the stilt works with any provider and any model. No restrictions.

yaml
allowedTargets:
  strategy: universal

Constrained — lock the stilt to specific providers and models via explicit providers and models arrays.

yaml
allowedTargets:
  strategy: constrained
  providers:
    - openrouter
  models:
    - gpt-oss-20b
    - qwen3-coder-480b

With constrained, "*" can be used as a wildcard to mean "any provider" or "any model". A wildcard cannot be mixed with explicit entries — either ["*"] or ["gpt-oss-20b", "qwen3-coder-480b"], never both.

exit and init

Two concepts control the beginning and end of the stilt's visible output:

exit is required. It marks the step that produces the stilt's answer. Every time the steps finish one full pass, the exit step's output becomes a checkpoint — in Studio's timeline it shows up as a diamond (rhombus) at the end of that pass. If the stilt has loops, each iteration produces one checkpoint. When the final loop completes, that last checkpoint's output is what the API returns.

The exit step can be a normal step without nodes (single LLM call) or a sequential step with nodes (serial chain — the last node's output is the answer). A normal step with nodes cannot be the exit step, because all nodes run simultaneously and there is no deterministic "last" node.

If the step referenced by exit doesn't exist, validation fails before the stilt runs.

init is optional. It's not a top-level key — it's a timeline marker on a step: timeline: "init". At most one step can carry this marker, and that step cannot have nodes (must be single-output) and cannot be the same step as the exit.

The init node is always created in the timeline — it's the first node visible. If no step is tagged as init, the node appears but stays empty. If a step is tagged, that step's output populates the init node's content, providing an initial visible result before the main search begins.

Full Example

A two-step stilt — the first step analyzes the input, the second rewrites based on that analysis:

yaml
name: Analyze and Rewrite
description: Two-stage analysis and rewrite stilt

allowedTargets:
  strategy: universal

exit: rewrite

knobs: {}

steps:
  - id: analyze
    name: Analyze
    type: normal
    fields:
      - name: Context
        type: text
        from: input.context
    systemPrompt: "Analyze the input and identify key themes."

  - id: rewrite
    name: Rewrite
    type: normal
    fields:
      - name: Analysis
        type: ingest
        from:
          stepId: analyze
          loopRef: current
    systemPrompt: "Rewrite based on the analysis. Be clear and concise."

When this stilt runs, analyze receives the user's input via the Context text field, produces its analysis, then rewrite ingests that analysis and produces the final output. Since exit: rewrite, the rewrite step's output is what the API returns.

Common Validation Failures

Referencing a step id in exit that doesn't match any step in steps. Using strategy: constrained but leaving providers or models empty, or mixing "*" with explicit entries. Having two steps with timeline: "init" — only one is allowed. Tagging a step as both init and the exit step — they must be different. Giving the exit step nodes on a normal step — only sequential steps can be exit steps with nodes.