Template Syntax
Handlebars template variables and helpers available in agent prompt templates and workflow Blackboard templates.
Template Syntax
AEGIS uses Handlebars for template rendering in three places:
- Agent prompt templates —
spec.task.prompt_templatein an agent manifest - Workflow Blackboard templates —
input_templatefields in workflow state definitions - Workflow output templates —
metadata.output_templatevalues in a workflow manifest
All three use {{variable}} syntax, but the available variable namespaces differ.
Agent Prompt Templates
The spec.task.prompt_template field in an agent manifest is rendered once per iteration before the prompt is sent to the LLM.
Available Variables
| Variable | Type | Description |
|---|---|---|
{{instruction}} | string | The agent's spec.task.instruction field |
{{input}} | string | The execution input provided by the caller |
{{iteration_number}} | integer | Current iteration count (1-indexed) |
{{previous_error}} | string | Error message from the previous iteration, if any |
{{context}} | string | Concatenated context attachment strings |
Variables that are null or not populated render as an empty string by default (strict mode is disabled). Referencing an undefined variable does not cause an error.
Example
spec:
task:
instruction: "Summarise the provided email thread as bullet points."
prompt_template: |
{{#if instruction}}Task: {{instruction}}
{{/if}}{{#if iteration_number}}[Iteration {{iteration_number}}]
{{/if}}{{#if previous_error}}Previous attempt failed: {{previous_error}}
Please try a different approach.
{{/if}}{{#if input}}Input:
{{input}}{{/if}}Notes
-
HTML escaping is disabled. Backticks, quotes,
<,>in{{input}}and{{instruction}}are passed verbatim to the LLM. You do not need to escape them. -
If
prompt_templateis omitted, the orchestrator uses a built-in default:{{#if instruction}}Task: {{instruction}} {{/if}}{{#if input}}Input: {{input}}{{/if}}
Workflow Blackboard Templates (input_template)
Workflow state input_template fields let you compose an agent's input from outputs of earlier states and values stored on the Blackboard.
Available Variables
State Output Variables
Reference the output of any completed state by its name:
{{STATE_NAME.output}}If the state produced structured JSON output, access nested fields with dot notation:
{{STATE_NAME.output.field_name}}
{{STATE_NAME.output.nested.key}}Example:
states:
- name: WRITE_DRAFT
kind: Agent
agent_id: draft-agent-uuid
- name: REVIEW_DRAFT
kind: Agent
agent_id: review-agent-uuid
input_template: |
Review the following draft and suggest three improvements:
{{WRITE_DRAFT.output}}Workflow Context / Blackboard Variables
Access values stored in the Blackboard — the shared mutable context for the workflow execution — using:
{{workflow.context.KEY}}The Blackboard is populated from the workflow's initial input object and updated by System states that write context variables.
Example:
input_template: |
Task: {{workflow.context.task_description}}
Target language: {{workflow.context.language}}
Prior analysis: {{ANALYSE.output}}Input Variables
The workflow's initial execution input is available as:
{{input.FIELD_NAME}}Example:
# Workflow started with: { "repo_url": "https://github.com/...", "pr_number": 42 }
input_template: |
Review pull request #{{input.pr_number}} in repo {{input.repo_url}}.
Diff:
{{FETCH_DIFF.output}}Agent State intent: and input: Fields
Agent states expose two distinct template fields that map to separate variables inside the agent's prompt template:
| Field | Resolves to in prompt | Purpose |
|---|---|---|
intent: | {{intent}} | Natural-language steering — the "why" |
input: | {{input}} | Structured data — the "what" |
Fallback behaviour: When intent: is absent on a state, {{intent}} inside the agent's prompt template falls back to the workflow-level caller intent. When intent: is present on the state, it overrides the workflow-level intent for that state only.
Example:
SUMMARIZE:
kind: Agent
agent: summarizer-agent
intent: "Summarize the analysis output as three bullet points."
input: |
Analysis: {{ANALYZE.output}}
Context: {{workflow.context.project_name}}Here {{intent}} in the agent's prompt receives the per-state override, and {{input}} receives the rendered input: block. A downstream state that omits intent: will have {{intent}} resolve to whatever the caller originally passed when starting the workflow.
Conditionals
Use {{#if}} to render sections only when a variable is non-empty:
{{#if previous_error}}
A previous attempt failed with: {{previous_error}}
Please take a different approach.
{{/if}}
{{#if workflow.context.additional_instructions}}
Additional instructions: {{workflow.context.additional_instructions}}
{{/if}}Iteration Over Arrays
Use {{#each}} to iterate over array values in structured state output:
The following issues were identified:
{{#each ANALYSE.output.issues}}
- {{this.severity}}: {{this.description}} (line {{this.line}})
{{/each}}Missing Variables
- Undefined variables render as an empty string. Use
{{#if}}guards to avoid blank lines in prompts. - Nested access on null — if
WRITE_DRAFT.outputis null and you write{{WRITE_DRAFT.output.title}}, the entire expression renders as empty rather than erroring.
Escaping
To render a literal {{ in template output, use \{{:
The variable syntax looks like \{{variable_name}}.Workflow Output Templates (output_template)
The metadata.output_template field in a workflow manifest declares how the workflow's structured output is extracted from the Blackboard at completion. Unlike input_template (which renders a single string for an agent's input), output_template is an object where each leaf value is rendered independently as a separate Handlebars expression.
How It Works
Each key in output_template maps to a property in output_schema. Each value is a Handlebars expression evaluated against the final Blackboard. The rendered string is then type-coerced to match the schema's declared type for that property.
metadata:
output_schema:
type: object
properties:
summary:
type: string
count:
type: integer
passed:
type: boolean
output_template:
summary: "{{ANALYZE.output}}"
count: "{{TRANSFORM.output.record_count}}"
passed: "{{VALIDATE.status}}"In this example, summary is used as-is (string), count is parsed as an integer, and passed is compared to "true" to produce a boolean.
Available Variables
Output templates have access to the same Blackboard variables as any workflow state template:
{{STATE.output}}— output of any completed state{{STATE.output.stdout}}— stdout of System/ContainerRun states{{STATE.score}}— validation score of Agent states{{STATE.status}}— status of any completed state{{blackboard.KEY}}— any Blackboard key{{input.KEY}}— workflow start input fields
Key Difference from State Templates
State input_template values produce a single string that becomes the agent's input. Output template values are rendered independently per key and then type-coerced — each leaf is a separate render pass, not part of a single concatenated template.