> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Variable Substitution

> Dynamic variable substitution with {{var}} and {{var.property}} syntax

Variable substitution enables dynamic content replacement using `{{variable}}` placeholders that resolve at runtime, supporting both flat variables and dot-notation for nested data structures.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(name="Daily Agent", instructions="Answer using today's date when asked.")
agent.start("Summarise the top AI news for {{today}}")
```

The user includes placeholders in the prompt; the agent resolves variables before answering.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Variable Resolution"
        A[📝 {{user.name}}] --> B[🔍 Look up]
        B --> C[📊 variables["user"]["name"]]
        C --> D[✅ "Alice"]
    end
    
    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff
    
    class A input
    class B,C process
    class D output
```

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant VariableSubstitution

    User->>Agent: Request
    Agent->>VariableSubstitution: Process
    VariableSubstitution-->>Agent: Result
    Agent-->>User: Response
```

## Quick Start

<Steps>
  <Step title="Dynamic placeholders in prompts">
    Built-in providers such as `{{today}}`, `{{now}}`, and `{{uuid}}` resolve when the agent runs:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent

    agent = Agent(name="Daily Agent", instructions="Answer concisely.")
    agent.start("What is today's date? Reply with {{today}} only.")
    ```
  </Step>

  <Step title="Dot notation for nested data">
    Pass a variables dict when substituting text in workflows or templates:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents.utils.variables import substitute_variables

    text = substitute_variables(
        "Welcome {{user.name}}! Your role is {{user.role}}",
        {"user": {"name": "Alice", "role": "admin", "settings": {"theme": "dark"}}},
    )
    # "Welcome Alice! Your role is admin"
    ```
  </Step>

  <Step title="Graceful fallback for missing keys">
    Missing segments stay as literal placeholders — no error is raised:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents.utils.variables import substitute_variables

    text = substitute_variables(
        "Process {{data.value}} or use {{fallback}} if missing",
        {"data": {"other": "something"}, "fallback": "default"},
    )
    # "Process {{data.value}} or use default if missing"
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant Feature as Variable Substitution

    User->>Agent: Request
    Agent->>Feature: Process request
    Feature-->>Agent: Result
    Agent-->>User: Response
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    A[📝 Input Text] --> B{🔍 Has {{var}}?}
    B -->|No| C[✅ Return as-is]
    B -->|Yes| D{📊 Dotted name?}
    D -->|No| E[🔍 Provider Registry]
    D -->|Yes| F[🗂️ Dict Traversal]
    E --> G{✅ Found?}
    F --> G
    G -->|Yes| H[🔄 Replace]
    G -->|No| I[📝 Keep Original]
    H --> J[✅ Result]
    I --> J
    
    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff
    
    class A input
    class B,D,E,F,G process
    class C,H,I,J output
```

| Resolution Order         | Description                                   |
| ------------------------ | --------------------------------------------- |
| **1. Provider Registry** | Dynamic providers (for non-dotted names only) |
| **2. Dict Traversal**    | Navigate nested dicts using dot notation      |
| **3. Graceful Fallback** | Keep original `{{...}}` if not found          |

***

## Configuration Options

| Pattern        | Type  | Description                                                  |
| -------------- | ----- | ------------------------------------------------------------ |
| `{{name}}`     | `str` | Flat variable name - checks providers then static variables  |
| `{{obj.prop}}` | `str` | Dot notation - traverses nested dicts only                   |
| `{{missing}}`  | `str` | Missing variables remain as literal text (graceful fallback) |

**Traversal Rules:**

* Only **dict** objects are traversed (not lists, objects, or attributes)
* Provider registry is consulted **only for non-dotted names**
* Missing segments result in graceful fallback (no errors)

***

## Common Patterns

### Pattern 1: User configuration

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.utils.variables import substitute_variables

instructions = substitute_variables(
    "Hello {{user.name}}! Theme: {{user.settings.theme}}",
    {
        "user": {
            "name": "Bob",
            "settings": {"theme": "light", "notifications": True},
        }
    },
)
```

### Pattern 2: API Endpoint Templates

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
variables = {
    "api": {
        "base_url": "https://api.example.com",
        "version": "v1",
        "endpoints": {
            "users": "/users",
            "posts": "/posts"
        }
    }
}

template = "{{api.base_url}}/{{api.version}}{{api.endpoints.users}}"
# Resolves to: "https://api.example.com/v1/users"
```

### Pattern 3: Multi-Level Data Access

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
variables = {
    "company": {
        "departments": {
            "engineering": {
                "team_lead": "Charlie",
                "budget": 100000
            }
        }
    }
}

instruction = "Contact {{company.departments.engineering.team_lead}}"
# Resolves to: "Contact Charlie"
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use Descriptive Variable Names">
    Choose clear, descriptive names that make templates self-documenting.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Good
    variables = {
        "user": {"name": "Alice", "role": "admin"},
        "project": {"name": "Dashboard", "deadline": "2024-01-15"}
    }

    # Avoid
    variables = {
        "u": {"n": "Alice", "r": "admin"},
        "p": {"n": "Dashboard", "d": "2024-01-15"}
    }
    ```
  </Accordion>

  <Accordion title="Structure Data Hierarchically">
    Organize related data into logical groupings for cleaner templates.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Organized structure
    variables = {
        "user": {
            "profile": {"name": "Bob", "email": "bob@example.com"},
            "preferences": {"theme": "dark", "language": "en"}
        },
        "system": {
            "version": "1.2.0",
            "environment": "production"
        }
    }
    ```
  </Accordion>

  <Accordion title="Handle Missing Data Gracefully">
    Design templates that degrade gracefully when optional data is missing.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Template with fallback
    template = "Welcome {{user.name}}! {{user.title}} is optional."

    # Works with partial data
    variables = {"user": {"name": "Carol"}}
    # Result: "Welcome Carol! {{user.title}} is optional."
    ```
  </Accordion>

  <Accordion title="Avoid Deep Nesting">
    Keep dot-notation paths reasonably short for maintainability.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Reasonable depth
    {{config.database.host}}

    # Too deep - consider flattening
    {{app.modules.auth.providers.oauth.google.client_id}}
    ```
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="YAML Template Variables" icon="code" href="/docs/features/yaml-template-variables">
    Brace-safe `{topic}` placeholders in YAML
  </Card>

  <Card title="Workflow Variables" icon="diagram-project" href="/docs/features/workflows">
    Variable passing between workflow steps
  </Card>
</CardGroup>
