Skip to main content

Overview

Jinba Flow supports powerful templating capabilities that allow you to:
  • Reference results from previous steps
  • Access configured secrets securely
  • Use Jinja2 templates for complex logic
  • Create dynamic, reusable workflows

Variable Placeholders

Basic Syntax

Variables are enclosed in double curly braces: {{ variable }}

Available Variables

VariableDescriptionExample
steps.<step_id>.resultResult from a previous step{{steps.fetch_data.result}}
steps.<step_id>.result.<property>Specific property from result{{steps.api_call.result.content}}
secrets.<secret_name>Configured workspace secret{{secrets.API_KEY}}
itemCurrent item in forEach loop{{item}}
item.<property>Property of current item{{item.id}}

Accessing Step Results

# Access entire result
- name: data
  value: "{{steps.previous_step.result}}"

# Access specific property
- name: content
  value: "{{steps.llm_response.result.content}}"

# Access nested property
- name: user_email
  value: "{{steps.get_user.result.user.email}}"

# Access array element
- name: first_item
  value: "{{steps.get_list.result[0]}}"

Using Secrets

Secrets are configured at the workspace level and accessed securely:
config:
  - name: api_key
    value: "{{secrets.OPENAI_API_KEY}}"
  - name: token
    value: "{{secrets.GITHUB_TOKEN}}"
Security Notes:
  • Secrets are encrypted at rest
  • Never hardcode sensitive values in workflows
  • Use secrets for API keys, tokens, and credentials

Jinja2 Templates

Jinba Flow supports full Jinja2 templating for advanced logic. Templates are processed before step execution.

Control Structures

For Loops

value: |
  items = []
  {%- for user in steps.get_users.result %}
  items.append({
    "id": "{{user.id}}",
    "name": "{{user.name}}"
  })
  {%- endfor %}

Conditional Statements

value: |
  {%- if steps.check.result.status == 'success' %}
  print("Processing successful")
  {%- else %}
  print("Handling error")
  {%- endif %}

Loop with Index

value: |
  {%- for item in items %}
  {{loop.index}}: {{item}}
  {%- endfor %}

Built-in Functions

Jinja2 provides useful built-in functions:
# zip - Combine multiple lists
{%- for a, b in zip(list1, list2) %}
{{a}}: {{b}}
{%- endfor %}

# range - Generate number sequence
{%- for i in range(5) %}
Item {{i}}
{%- endfor %}

# length/count
Total: {{items|length}}

Filters

Apply transformations to values:
# String manipulation
{{ variable | upper }}
{{ variable | lower }}
{{ variable | trim }}
{{ variable | replace('old', 'new') }}

# Default values
{{ variable | default('fallback_value') }}

# JSON handling
{{ data | tojson }}

# List operations
{{ items | first }}
{{ items | last }}
{{ items | join(', ') }}

Whitespace Control

Use {%- and -%} to control whitespace:
value: |
  {%- for item in items -%}
  {{item}}
  {%- endfor -%}
  • {%- removes whitespace before the tag
  • -%} removes whitespace after the tag

Common Patterns

Processing Lists

- id: process_items
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        results = []
        {%- for item in steps.input_list.result %}
        results.append({
          "id": "{{item.id}}",
          "processed": True
        })
        {%- endfor %}
        result = results

Conditional Data Selection

- id: select_data
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        {%- if steps.config.result.mode == 'full' %}
        data = {{steps.full_data.result}}
        {%- else %}
        data = {{steps.summary_data.result}}
        {%- endif %}
        result = data

Combining Multiple Sources

- id: merge_data
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        combined = []
        {%- for user, order in zip(steps.users.result, steps.orders.result) %}
        combined.append({
          "user": "{{user.name}}",
          "order": "{{order.id}}"
        })
        {%- endfor %}
        result = combined

Filtering Lists

value: |
  active_items = []
  {%- for item in items if item.status == 'active' %}
  active_items.append("{{item.name}}")
  {%- endfor %}

Building Dynamic Prompts

- id: generate_prompt
  tool: LLM
  input:
    - name: prompt
      value: |
        Analyze the following items:
        {%- for item in steps.items.result %}
        - {{item.name}}: {{item.description}}
        {%- endfor %}
        
        Provide insights based on the above data.

Best Practices

Variable References

  • Use descriptive step IDs for clarity
  • Access only the properties you need
  • Handle potential null/undefined values with defaults

Templates

  • Keep templates readable with proper indentation
  • Use whitespace control for clean output
  • Break complex logic into multiple steps

Secrets

  • Never log or expose secret values
  • Use workspace-level secrets for team sharing
  • Rotate secrets regularly

Performance

  • Avoid deeply nested templates
  • Limit loop iterations
  • Pre-process data when possible

Troubleshooting

Common Issues

Variable not found
  • Check step ID spelling
  • Ensure the referenced step runs before current step
  • Verify the property path is correct
Template syntax error
  • Check for balanced braces {{ }}
  • Verify Jinja2 tag syntax {% %}
  • Look for missing quotes in strings
Unexpected output
  • Use debug steps to inspect intermediate values
  • Check whitespace handling
  • Verify data types (string vs object)