Files
cleveractors-core/features/yaml_template_engine.feature
2026-05-27 21:41:03 +00:00

158 lines
5.3 KiB
Gherkin

Feature: YAML Template Engine with Jinja2 Support
As a developer using CleverAgents
I want to use Jinja2 templates directly in YAML files
So that I can create dynamic configurations without multiline strings
Background:
Given the YAML template engine is initialized
Scenario: Process YAML with inline Jinja2 loops
Given I have a YAML string with inline Jinja2 templates:
"""
config:
name: {{ project_name }}
version: {{ version }}
agents:
{% for i in range(num_agents) %}
agent_{{ i }}:
type: llm
config:
model: {% if i == 0 %}gpt-4{% else %}gpt-3.5-turbo{% endif %}
temperature: {{ 0.5 + i * 0.1 }}
system_prompt: Agent {{ i }} is ready
{% endfor %}
"""
And I have a YAML template context:
| key | value |
| project_name| TestProject |
| version | 1.0 |
| num_agents | 3 |
When I process the YAML with the template engine
Then the result should contain a "config" section with name "TestProject"
And the result should contain 3 agents named "agent_0", "agent_1", "agent_2"
And agent "agent_0" should have model "gpt-4"
And agent "agent_1" should have model "gpt-3.5-turbo"
Scenario: Process YAML with conditional blocks
Given I have a YAML string with conditional Jinja2 templates:
"""
agents:
base_agent:
type: llm
config:
model: gpt-3.5-turbo
{% if enable_supervisor %}
supervisor:
type: llm
config:
model: gpt-4
temperature: 0.3
system_prompt: I supervise {{ num_agents }} agents
{% endif %}
"""
And I have a YAML template context:
| key | value |
| enable_supervisor | true |
| num_agents | 5 |
When I process the YAML with the template engine
Then the result should contain an agent named "supervisor"
And agent "supervisor" should have system_prompt "I supervise 5 agents"
Scenario: Process nested structures with Jinja2
Given I have a YAML string with nested Jinja2 templates:
"""
teams:
{% for team in teams %}
{{ team.name }}:
lead: {{ team.lead }}
members:
{% for member in team.members %}
- name: {{ member.name }}
role: {{ member.role }}
skills:
{% for skill in member.skills %}
- {{ skill }}
{% endfor %}
{% endfor %}
{% endfor %}
"""
And I have a complex template context with teams data
When I process the YAML with the template engine
Then the result should contain teams "backend" and "frontend"
And team "backend" should have lead "Alice"
And team "backend" should have 2 members
Scenario: Deferred template rendering
Given I have a YAML string with Jinja2 templates:
"""
template:
type: composite
components:
{% for i in range(team_size) %}
worker_{{ i }}:
type: agent
config:
id: {{ i }}
name: Worker {{ i + 1 }}
{% endfor %}
"""
When I load the YAML without context for deferred rendering
Then the template should be stored for later rendering
When I render the stored template with context:
| key | value |
| team_size | 3 |
Then the rendered result should contain 3 workers
Scenario: Complex Jinja2 expressions and filters
Given I have a YAML string with complex Jinja2 expressions:
"""
analysis:
data_points: {{ data | length }}
average: {{ (data | sum(attribute='value')) / (data | length) }}
above_threshold: {{ data | selectattr('value', '>', threshold) | list | length }}
summary:
{% for item in data | sort(attribute='value', reverse=True) %}
- name: {{ item.name }}
value: {{ item.value }}
status: {% if item.value > threshold %}high{% elif item.value > threshold * 0.5 %}medium{% else %}low{% endif %}
{% endfor %}
"""
And I have a template context with data array
When I process the YAML with the template engine
Then the analysis data_points should be 4
And the analysis average should be 60.25
And the analysis above_threshold should be 2
And the first summary item should have status "high"
Scenario: Handle empty template blocks gracefully
Given I have a YAML string with empty loops:
"""
items:
{% for item in items %}
- {{ item }}
{% endfor %}
static: value
"""
And I have a YAML template context:
| key | value |
| items | [] |
When I process the YAML with the template engine
Then the result should contain "items.static" with value "value"
Scenario: Support Unicode and special characters
Given I have a YAML string with Unicode content:
"""
messages:
{% for msg in messages %}
- text: {{ msg.text }}
emoji: {{ msg.emoji }}
{% endfor %}
"""
And I have a template context with Unicode messages
When I process the YAML with the template engine
Then the result should contain 3 messages
And the second message text should be "Ça va?"