Skip to main content

Pipeline Schema Reference

The pipelineSchema in agent.yaml defines the configurable surface of a pipeline agent. It declares which nodes exist, how they connect, what parameters each node exposes, and what global thresholds are available.

Overviewโ€‹

pipelineSchema:
nodes: # Pipeline stages with configurable slots
- id: expert_pool
slots: [...]
- id: arbitration
slots: [...]
edges: # Data flow connections between nodes
- source: expert_pool
target: arbitration
thresholds: # Global pipeline parameters
- id: history_limit

The schema serves two purposes:

  1. Frontend: Drives the Pipeline Configurator โ€” each node becomes a configurable card, each slot becomes a form field, each edge becomes a visual connection.
  2. Agent: Provides default values that are used when no override is specified in the configuration.

Enabling the Configuratorโ€‹

Add x-stella-supports-configurator: true to configSchema to enable the Pipeline Configurator for an agent type:

configSchema:
type: object
x-stella-supports-configurator: true
properties:
# ... other config properties

Without this flag, the agent uses the legacy configuration view.

Nodesโ€‹

Each node represents a pipeline stage.

nodes:
- id: expert_pool # Unique identifier (used in config overrides)
label: "Expert Pool" # Display name
description: "Parallel expert execution with structured verdicts (~200ms)"
icon: "๐Ÿงช" # Emoji icon
position: # Layout position (row/col grid)
row: 0
col: 1
slots: # Configurable parameters
- id: experts
label: "Built-in Experts"
type: expert_list
description: "Configure built-in experts"

Node Fieldsโ€‹

FieldTypeRequiredDescription
idstringYesUnique node identifier. Used as key in config.nodes[id].
labelstringYesHuman-readable name
descriptionstringNoBrief description of what this stage does
iconstringNoEmoji icon for the node
positionobjectYes{ row: number, col: number } โ€” layout position in the pipeline visualization
slotsarrayYesList of configurable parameters (see Slots)

Slotsโ€‹

Slots define the individual parameters that can be configured for each node.

Slot Fieldsโ€‹

FieldTypeRequiredDescription
idstringYesUnique within the node. Used as key in config.nodes[nodeId][slotId].
labelstringYesHuman-readable name
typestringYesOne of: text, number, select, string_list, key_value, expert_list, verdict_directives
descriptionstringNoHelp text explaining what this parameter controls
defaultanyNoDefault value used when no override is specified

Slot Typesโ€‹

textโ€‹

Free-form text input. Used for prompts, personas, and messages.

- id: system_prompt
label: "System Prompt"
type: text
description: "System prompt for the bridge generator"
maxLength: 5000 # Optional character limit
default: |
You produce a short conversational filler phrase...
Extra FieldTypeDescription
maxLengthnumberMaximum character count

numberโ€‹

Numeric input with optional range constraints.

- id: temperature
label: "Temperature"
type: number
min: 0
max: 1
step: 0.1
default: 0.7
Extra FieldTypeDescription
minnumberMinimum allowed value
maxnumberMaximum allowed value
stepnumberIncrement step size

selectโ€‹

Single choice from predefined options.

- id: model
label: "Model"
type: select
options: ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini", "gpt-4.1-nano"]
default: "gpt-4o-mini"
Extra FieldTypeDescription
optionsstring[]Available choices

string_listโ€‹

Ordered list of strings. Used for tags and other simple list-valued parameters.

- id: stop_sequences
label: "Stop Sequences"
type: string_list
description: "Strings that halt generation"
default: ["\n\n"]

key_valueโ€‹

Key-value map. Used for mappings like expert โ†’ tone.

- id: tone_map
label: "Tone Map"
type: key_value
description: "Expert name โ†’ tone when that expert flags something"
default:
medical: "cautious"
legal: "cautious"
probing: "curious"

expert_listโ€‹

Specialized type for managing expert configurations. Supports enable/disable, priority ordering, model selection, and prompt editing per expert.

- id: experts
label: "Built-in Experts"
type: expert_list
description: "Configure built-in experts"

- id: custom_experts
label: "Custom Experts"
type: expert_list
description: "Define new custom experts"
isCustom: true # Allows creating new experts (not just editing existing ones)
Extra FieldTypeDescription
isCustombooleanIf true, allows defining entirely new experts rather than just configuring existing ones

Each expert's verdict labels, their LLM-facing explanations, and the deterministic action wired to each verdict are configured inline in the Expert Module โ€” see verdict_directives and Verdict Responses.

verdict_directivesโ€‹

Editor for an expert's verdict โ†’ response mapping. Each verdict an expert can emit is a row with: the label and a plain-language explanation (both handed to the classifying LLM), and the deterministic action + template applied in the arbitration layer.

- id: verdict_directives
label: "Verdict Responses"
type: verdict_directives

The action is one of:

ActionEffect
informDefault. The verdict influences tone/guidance; the response LLM still writes the reply.
prependSpeak the template first, then the generated reply.
overrideSpeak only the template; the response LLM is bypassed (post-processing still runs).
short_circuitSpeak only the template and end the turn โ€” nothing downstream runs.

Verdict directives are stored per expert (under nodes.expert_pool.experts[name].verdict_directives), so no top-level slot is required for built-in experts โ€” the Expert Module renders this editor for every expert. The output interface ({verdict, confidence, recommendation}) is fixed; only the verdict labels/explanations/actions are configurable.

Edgesโ€‹

Edges define data flow connections between nodes.

edges:
- source: expert_pool
target: arbitration
label: "ExpertVerdict[]"

- source: bridge_generator
target: response_generator
label: "bridge phrase"
style: dashed # Visual style: dashed = non-blocking/async

Edge Fieldsโ€‹

FieldTypeRequiredDescription
sourcestringYesSource node id
targetstringYesTarget node id
labelstringNoDescription of the data passed along this edge
stylestringNo"dashed" for non-blocking connections, solid by default

Thresholdsโ€‹

Global pipeline parameters that affect cross-stage behavior.

thresholds:
- id: history_limit
label: "History Limit"
description: "Maximum conversation history messages to include"
type: number
min: 5
max: 50
step: 5
default: 20

Threshold Fieldsโ€‹

FieldTypeRequiredDescription
idstringYesUnique identifier. Used as key in config.thresholds[id].
labelstringYesHuman-readable name
descriptionstringNoHelp text
typestringYesCurrently only "number" is supported
minnumberNoMinimum allowed value
maxnumberNoMaximum allowed value
stepnumberNoIncrement step
defaultnumberNoDefault value

Configuration Formatโ€‹

When a user saves a configuration, only the overridden values are stored:

{
"nodes": {
"arbitration": {
"gate_failure_message": "Sorry, I didn't catch that โ€” could you repeat it?"
},
"response_generator": {
"persona": "You are a medical intake assistant...",
"temperature": 0.5,
"max_tokens": 200
}
},
"thresholds": {
"history_limit": 30
}
}

Nodes and slots not present in the configuration use their schema defaults. This is the sparse override pattern โ€” configurations are minimal diffs against the schema.

How the Agent Receives Configurationโ€‹

  1. The configuration is wrapped in a pipeline_config key and serialized as the AGENT_CONFIG environment variable:
{
"pipeline_config": {
"nodes": { ... },
"thresholds": { ... }
},
"plan": { ... }
}
  1. The agent reads it in on_session_start():
async def on_session_start(self, session_id: str, config: Dict[str, Any]):
pipeline_config = config.get("pipeline_config")
if not pipeline_config:
raise ValueError("pipeline_config is required")
self._apply_pipeline_config(pipeline_config)
  1. _apply_pipeline_config() merges overrides with built-in defaults for each stage.

Backend Validationโ€‹

The backend validates configurations before saving:

  • Node IDs: Only node IDs present in pipelineSchema.nodes are accepted. Unknown node IDs result in a 400 Bad Request.
  • Threshold ranges: Threshold values are validated against min/max from the schema. Out-of-range values are rejected.
  • Sanitization: All configuration values pass through sanitizeAgentConfig() to prevent injection attacks.

Complete Exampleโ€‹

See agents/stella-v2-agent/agent.yaml for the full stella-v2 pipeline schema with 5 nodes (expert_pool, arbitration, response_generator, bridge_generator, barge_in), 3 edges, and 1 threshold.

See Alsoโ€‹