Skip to main content
Custom variables are accessible in:
  • Agent prompts via custom Jinja2 templates
  • Custom tools via shared_state.custom_variables

Quick Start

from droidrun.agent.droid import DroidAgent
from droidrun.config_manager.config_manager import DroidrunConfig

# Define custom prompts that render variables
custom_prompts = {
    "manager_system": """
{{ instruction }}

{% if variables %}
Available variables:
{% for key, value in variables.items() %}
- {{ key }}: {{ value }}
{% endfor %}
{% endif %}
    """
}

# Create agent with variables
config = DroidrunConfig()

agent = DroidAgent(
    goal="Send email to recipient with subject",
    config=config,
    variables={"recipient": "john@example.com", "subject": "Update"},
    prompts=custom_prompts  # Required to see variables
)

result = await agent.run()
Important: Default prompts don’t render variables. You must provide custom prompts via the prompts parameter.

How Variables Work

When you pass variables to DroidAgent:
  1. Stored in DroidAgentState.custom_variables
  2. Passed to prompt templates as variables dict
  3. Rendered in Jinja2 templates via {% if variables %} blocks
  4. Available to all child agents throughout the workflow
Access Summary:
  • ✅ Agent prompts (via custom Jinja2 templates)
  • ✅ Agents can read and pass to tools as arguments
  • ✅ Custom tools (via shared_state.custom_variables)

Basic Usage

from droidrun.agent.droid import DroidAgent
from droidrun.config_manager.config_manager import DroidrunConfig

# Define variables
variables = {
    "recipient": "alice@example.com",
    "message": "Hello from Droidrun!"
}

# Custom prompt to render variables
custom_prompts = {
    "codeact_system": """
You are an agent that controls Android devices.

{% if variables %}
Available variables:
{% for key, value in variables.items() %}
- {{ key }}: {{ value }}
{% endfor %}
{% endif %}

Use these variables when executing tasks.
    """
}

# Create agent
config = DroidrunConfig()

agent = DroidAgent(
    goal="Send message to recipient",
    config=config,
    variables=variables,
    prompts=custom_prompts
)

result = await agent.run()

Available Prompt Keys

Customize these prompts to render variables:
  • manager_system - Manager agent system prompt
  • executor_system - Executor agent system prompt
  • codeact_system - CodeAct agent system prompt
  • codeact_user - CodeAct agent user prompt
  • scripter_system - Scripter agent system prompt

Accessing Variables in Custom Tools

Custom tools can directly access variables via the shared_state keyword argument:
from droidrun.agent.droid import DroidAgent
from droidrun.config_manager.config_manager import DroidrunConfig

def send_notification(title: str, *, tools=None, shared_state=None, **kwargs):
    """Send a notification using channel from custom variables.

    Args:
        title: Notification title
        tools: Tools instance (optional, injected automatically)
        shared_state: DroidAgentState (optional, injected automatically)
    """
    if not shared_state:
        return "Error: shared_state required"

    # Access custom variables
    channel = shared_state.custom_variables.get("notification_channel", "default")
    return f"Sent '{title}' to {channel}"

custom_tools = {
    "send_notification": {
        "arguments": ["title"],
        "description": "Send a notification with title. Usage: {\"action\": \"send_notification\", \"title\": \"Alert\"}",
        "function": send_notification
    }
}

config = DroidrunConfig()

agent = DroidAgent(
    goal="Send notification with title 'Alert'",
    config=config,
    custom_tools=custom_tools,
    variables={"notification_channel": "alerts"}
)

Use Cases

Parameterized Workflows

# Define reusable workflow with different variables
for user in ["alice@example.com", "bob@example.com"]:
    agent = DroidAgent(
        goal="Send welcome email",
        config=config,
        variables={"recipient": user},
        prompts=custom_prompts
    )
    await agent.run()

Configuration Data

variables = {
    "api_endpoint": "https://api.example.com/v2",
    "timeout": 30
}

agent = DroidAgent(
    goal="Call API endpoint",
    config=config,
    variables=variables,
    prompts=custom_prompts
)

Key Points

  1. Custom prompts required - Default prompts don’t render variables in agent context
  2. Direct access in tools - Custom tools access shared_state.custom_variables via keyword argument
  3. Available to all agents - Manager, Executor, CodeAct, Scripter all receive variables
  4. Jinja2 templates - Use {% if variables %} blocks in custom prompts
  5. Auto-injection - tools and shared_state are injected automatically by Droidrun
I