Redeo Docs
DocsLADR / How to Add Caller-Tunable Knobs

Adding Features

How to Add Caller-Tunable Knobs

How to Add Caller-Tunable Knobs

Knobs are caller-tunable parameters declared in the ladder config. They let the caller control fan-out, recursion depth, and other strategy parameters at call time without editing the ladder. Two input types: slider (discrete steps) and numerical (continuous range).

Slider knob (discrete choices)

A slider knob presents 3-5 discrete options. The caller picks one; the ladder uses its value.

yaml
knobs:
  branches:
    name: Branches
    type: nodes
    input: slider
    steps:
      - { title: Fast, value: 3, default: true }
      - { title: Balanced, value: 5 }
      - { title: Wide, value: 8 }
  • name: display label shown in Foundry and the API.
  • type: nodes, loops, recursion, or generic. Controls how the value is used.
  • input: slider: declares the slider input type.
  • steps: 3-5 options. Exactly one should have default: true.

Using the knob value in a step:

yaml
- id: generate
  nodes: branches                # references the knob by name
  fields:
    - { name: Question, type: text, from: input.context }
  systemPrompt: "Generate a solution."

When nodes: branches, the runtime resolves the knob value (3, 5, or 8) and dispatches that many parallel nodes.

Passing a knob value at call time:

bash
curl ... -d '{
  "model": "gpt-4o",
  "messages": [...],
  "knobs": { "branches": 8 }
}'

If the caller passes a value that matches a step, it's accepted. Non-matching values are silently ignored (the default is used).

Numerical knob (continuous range)

A numerical knob accepts any value within a declared range. The value is clamped to [min, max].

yaml
knobs:
  threshold:
    name: Threshold
    type: generic
    input: numerical
    default: 0.8
    min: 0.0
    max: 1.0
  • default: the value used when the caller doesn't pass one. If omitted, defaults to min.
  • min and max: required. The value is clamped to this range.

Using the knob value in a system prompt or gate:

Knob values are injected via knobInfo fields:

yaml
- id: verify
  fields:
    - { name: Candidate, type: ingest, from: { stepId: generate, loopRef: current } }
    - { name: Threshold, type: knobInfo, from: threshold }
  systemPrompt: "Score the candidate. The acceptance threshold is in the Threshold field."

The Threshold field resolves to the knob's value (e.g., 0.8). The LLM sees it as Threshold: 0.8 in the prompt.

Passing a numerical knob at call time:

bash
curl ... -d '{
  "model": "gpt-4o",
  "messages": [...],
  "knobs": { "threshold": 0.95 }
}'

The value 0.95 is within [0.0, 1.0], so it's accepted. A value of 1.5 would be clamped to 1.0. A value of -0.5 would be clamped to 0.0.

Knob references in config fields

Beyond knobInfo fields, knob values can be referenced directly in nodes: and recursion.maxDepth using the {{knobs.X}} template syntax.

Nodes:

yaml
nodes: branches                     # shorthand: resolves to the knob value
# or:
nodes: "{{knobs.branches}}"         # explicit template form (same result)

Both forms resolve to the knob's numeric value and dispatch that many parallel nodes.

Recursion depth:

yaml
recursion:
  maxDepth: "{{knobs.depth}}"       # resolves to the knob value

Knob types and their effect:

Knob typeWhere it's usedEffect
nodesnodes: fieldNumber of parallel LLM calls per step
loopsAPI maxLoops parameterMax loop iterations for the pipeline
recursionrecursion.maxDepthMax recursion nesting depth
genericknobInfo fields onlyArbitrary numeric value injected into prompts

The type field is informational for slider/numerical inputs — it doesn't enforce where the knob can be referenced. But it helps Foundry display the knob in the right category.