Skip to main content

Variable Store system

The Variable Store is the mechanism for passing data between activities within a workflow and persisting state. Think of it as a key-value store scoped to each workflow execution, where every activity can read from and write to shared data. Understanding the variable store is crucial for building effective workflows. It’s how context flows through your workflow, how agents share information, and how decisions are made based on accumulated data.

How the variable store works

The variable store provides a shared data layer for workflow execution.
1

Workflow starts

A new variable store is created for the workflow execution. It starts empty except for the trigger input data.
2

Trigger data stored

The trigger’s input data is stored under the trigger key:
{
  "trigger": {
    "input": {...}
  }
}
3

Activities execute and write

As each activity completes, its output is automatically stored in the variable store under the activity’s name:
{
  "trigger": {...},
  "document_agent": {
    "output": {...}
  }
}
4

Subsequent activities read

Later activities read from the variable store using variable references:
{{document_agent.output.extracted_text}}
5

Data accumulates

As the workflow progresses, more data accumulates in the variable store, creating rich context for later activities.
6

Workflow completes

When the workflow finishes, the final variable store state is preserved in execution history. You can inspect it for debugging and auditing.
Each workflow execution has its own isolated variable store. Multiple concurrent executions of the same workflow don’t share data — each has its own independent context.

Setting variables

Variables are written to the store automatically by activity outputs, but you can also set them explicitly.

Automatic activity outputs

By default, each activity’s output is stored under the activity’s name: Activity name: document_extractor Activity output:
{
  "extracted_text": "...",
  "metadata": {
    "pages": 12,
    "language": "en"
  },
  "confidence": 0.95
}
Variable store:
{
  "document_extractor": {
    "output": {
      "extracted_text": "...",
      "metadata": {...},
      "confidence": 0.95
    }
  }
}

Custom variable names via output mapping

Customize how activity outputs are stored: Output mapping:
{
  "extracted_text": "{{agent.output.text}}",
  "document_language": "{{agent.output.metadata.language}}",
  "extraction_confidence": "{{agent.output.confidence}}"
}
Variable store:
{
  "extracted_text": "...",
  "document_language": "en",
  "extraction_confidence": 0.95
}
This creates cleaner, more accessible variable names for downstream activities.

Manual variable setting within prompts

Agent prompts can explicitly set variables: Agent instruction:
Analyze the document and set the following variables:
- document_type: The type of document (invoice, contract, etc.)
- risk_level: low, medium, or high
- requires_review: true if human review is needed
The agent’s structured output sets these variables directly in the variable store.

Getting variables

Access data from the variable store using the {{variable_path}} syntax.

Basic variable references

Syntax: {{key.nested.field}} Examples:
// Trigger input
{{trigger.input.customer_id}}
{{trigger.input.document_url}}

// Activity output
{{agent_name.output.field_name}}
{{tool_name.output.result}}

// Nested fields
{{compliance_agent.output.analysis.risk_score}}
{{document_agent.output.metadata.pages}}

Accessing arrays

Array element by index:
{{agent.output.findings[0]}}
{{agent.output.findings[1].severity}}
Array length:
{{agent.output.findings.length}}

Accessing objects

Object field:
{{agent.output.customer.name}}
{{agent.output.customer.contact.email}}
All object properties:
{{agent.output.customer}}
// Returns the entire customer object

Default values

Provide default values if a variable doesn’t exist:
{{agent.output.score || 0}}
{{agent.output.message || "No message provided"}}

Type checking

Check if a variable exists before using it:
exists({{agent.output.optional_field}})
isDefined({{agent.output.data}})
isEmpty({{agent.output.results}})

Variable scope

Variables exist at different scopes within a workflow.

Workflow-level scope

Available throughout the entire workflow execution. Variables at workflow scope:
  • Trigger input: {{trigger.input.*}}
  • All activity outputs: {{activity_name.output.*}}
  • Custom variables set via output mapping
Example:
Activity 1: Extract document
  → Sets: {{extracted_text}}

Activity 2: Analyze compliance (10 steps later)
  → Reads: {{extracted_text}}
  ✓ Available across entire workflow

Branch scope (Condition and Parallel nodes)

Variables within branches have special considerations. Condition branches: Variables set within a branch are available downstream:
Condition: risk_score > 0.8
  ├─ True branch:
  │   → Agent: "Detailed analysis"
  │     Output: {{detailed_analysis.output}}

  └─ False branch:
  │   → Agent: "Standard analysis"
  │     Output: {{standard_analysis.output}}

Next activity after Condition:
  → Can access whichever branch executed
  → Check exists({{detailed_analysis.output}})
Parallel branches: Each branch’s outputs are merged into the variable store after all branches complete:
Parallel node: "risk_assessment"
  ├─ Branch 1: {{risk_assessment.branch_1.output}}
  ├─ Branch 2: {{risk_assessment.branch_2.output}}
  └─ Branch 3: {{risk_assessment.branch_3.output}}

Next activity:
  → Access all branch outputs:
  → {{risk_assessment.branch_1.technical_score}}
  → {{risk_assessment.branch_2.financial_score}}
  → {{risk_assessment.branch_3.compliance_score}}

Loop scope (ForEach nodes)

Special variables available only within ForEach loops. Loop-specific variables:
// Current item being processed
{{foreach.current_item}}

// Zero-based index
{{foreach.index}}

// Total items in collection
{{foreach.total_items}}

// Results from previous iterations
{{foreach.previous_results}}
Example:
ForEach: documents
Loop variable: "document"

Loop body:
  → Agent input: {
      document_url: "{{foreach.document}}",
      document_number: "{{foreach.index + 1}}",
      total_documents: "{{foreach.total_items}}"
    }

Sub Use Case scope

Child workflows have their own isolated variable stores. Parent workflow variable store:
{
  "trigger": {...},
  "parent_agent": {...}
}
Child workflow variable store (independent):
{
  "trigger": {...},  // Input from parent
  "child_agent": {...}
}
Parent and child don’t share variable stores. Data flows explicitly through input/output mapping.

Variable store structure

Understanding the structure helps you access data efficiently.

Complete variable store example

{
  "trigger": {
    "input": {
      "customer_id": "CUST-12345",
      "document_url": "https://bucket.s3.com/doc.pdf",
      "urgency": "high"
    },
    "metadata": {
      "triggered_at": "2024-01-15T10:30:00Z",
      "triggered_by": "api"
    }
  },

  "document_extractor": {
    "output": {
      "extracted_text": "...",
      "document_type": "invoice",
      "metadata": {
        "pages": 3,
        "language": "en",
        "confidence": 0.95
      }
    }
  },

  "compliance_check": {
    "output": {
      "is_compliant": true,
      "risk_score": 0.3,
      "findings": [
        "All required fields present",
        "No anomalies detected"
      ]
    }
  },

  "risk_assessment": {
    "technical_analysis": {
      "output": {
        "score": 85,
        "concerns": []
      }
    },
    "financial_analysis": {
      "output": {
        "score": 90,
        "amount": 50000,
        "currency": "AED"
      }
    }
  },

  "final_decision": {
    "output": {
      "approved": true,
      "confidence": 0.92,
      "next_steps": [...]
    }
  }
}

Accessing nested data

// Top-level
{{trigger.input.customer_id}}  // "CUST-12345"

// Nested object
{{document_extractor.output.metadata.pages}}  // 3

// Array
{{compliance_check.output.findings[0]}}  // "All required fields present"

// Parallel branch output
{{risk_assessment.financial_analysis.output.amount}}  // 50000

// Deep nesting
{{final_decision.output.next_steps[0].action}}

Use cases

Understanding when and how to use the variable store effectively.

Passing context between distant nodes

Scenario: A node late in the workflow needs data from an early node.
Node 1: Extract customer data
  → Output: {{customer_data}}

Node 2-10: Various processing steps
  (Don't use customer_data)

Node 11: Send personalized email
  → Input: {{customer_data.email}}
  ✓ Data preserved across 10 intermediate steps
The variable store maintains all data throughout execution, so later nodes can access early outputs.

Accumulating results from parallel branches

Scenario: Multiple agents analyze the same document; combine their insights.
Parallel node: Document analysis
  ├─ Branch 1: Technical analysis → {{technical_score}}
  ├─ Branch 2: Financial analysis → {{financial_score}}
  ├─ Branch 3: Legal analysis → {{legal_score}}
  └─ Branch 4: Compliance analysis → {{compliance_score}}

Synthesis agent:
  Input: {
    technical: "{{parallel.branch_1.output}}",
    financial: "{{parallel.branch_2.output}}",
    legal: "{{parallel.branch_3.output}}",
    compliance: "{{parallel.branch_4.output}}"
  }
The variable store collects outputs from all branches for easy synthesis.

Building up a final report

Scenario: Accumulate findings throughout the workflow for a final report.
Workflow: Due diligence analysis

Step 1: Company research
  → Output: {{company_profile}}

Step 2: Financial analysis
  → Output: {{financial_assessment}}

Step 3: Legal review
  → Output: {{legal_findings}}

Step 4: Market analysis
  → Output: {{market_position}}

Step 5: Report generation agent
  Input: {
    company_profile: "{{company_profile}}",
    financial_assessment: "{{financial_assessment}}",
    legal_findings: "{{legal_findings}}",
    market_position: "{{market_position}}"
  }
  Output: Comprehensive due diligence report
Each step contributes data to the variable store; the final report agent synthesizes everything.

Conditional routing based on accumulated data

Scenario: Route based on multiple factors from different activities.
Step 1: Extract document data
  → Output: {{amount}}, {{document_type}}

Step 2: Risk assessment
  → Output: {{risk_score}}

Step 3: Compliance check
  → Output: {{is_compliant}}

Step 4: Condition node
  Condition:
    {{amount}} > 50000 AND
    {{risk_score}} > 0.7 AND
    {{is_compliant}} == true

  ├─ True: Escalate to manager
  └─ False: Auto-approve
The condition evaluates data from multiple previous activities stored in the variable store.

Cross-execution persistence

The variable store is normally scoped to a single workflow execution, but you can persist data across multiple runs.

Workflow-level state

For state that needs to persist across workflow runs, use external storage: Pattern:
Workflow execution 1:
  → Process data
  → Tool: "Store result in database"
    Key: "workflow_state"
    Value: {{accumulated_data}}

Workflow execution 2:
  → Tool: "Retrieve state from database"
    Key: "workflow_state"
  → Continue processing with previous state

Use cases for persistent state

Running totals

Accumulate totals across multiple workflow runs.Example: Track total processed invoices, cumulative amounts

State machines

Maintain state across workflow executions.Example: Customer onboarding progress (stage 1 → stage 2 → stage 3)

Historical context

Access results from previous executions.Example: Compare current analysis to previous runs for trend detection

Caching

Store computed results for reuse in future executions.Example: Cache customer research that doesn’t change frequently

Implementation with HashiCorp Vault

MagOneAI integrates with HashiCorp Vault for secure persistent storage: Store data:
Tool: "Vault Write"
Input: {
  path: "workflow_state/customer_onboarding/{{customer_id}}",
  data: {
    stage: "document_verification",
    completed_steps: ["registration", "email_verification"],
    pending_documents: ["passport", "proof_of_address"]
  }
}
Retrieve data:
Tool: "Vault Read"
Input: {
  path: "workflow_state/customer_onboarding/{{customer_id}}"
}
Output: {{vault_data.data}}
Use in workflow:
Condition: {{vault_data.data.stage}} == "document_verification"
  ├─ True: Continue from where we left off
  └─ False: Start from beginning

Best practices

Choose variable names that indicate source and content.Good:
  • compliance_agent.risk_assessment
  • document_extractor.extracted_text
  • financial_analysis.total_amount
Poor:
  • result1
  • output
  • data
Use consistent output structures across similar activities. This makes workflows easier to understand and maintain.Standard structure:
{
  "success": true,
  "data": {...},
  "metadata": {
    "confidence": 0.95,
    "processing_time_ms": 1500
  }
}
Always verify variables exist before using them in conditions or expressions:
exists({{agent.output.score}}) AND {{agent.output.score}} > 0.8
Instead of deeply nested paths, map to cleaner top-level variables:
{
  "customer_email": "{{agent.output.customer.contact.primary_email}}",
  "risk_score": "{{agent.output.analysis.risk_assessment.final_score}}"
}
Then use: {{customer_email}} instead of {{agent.output.customer.contact.primary_email}}
For reusable workflows (Sub Use Cases), document the expected input variables and guaranteed output variables. This is the workflow’s “contract.”Example:
Inputs:
  - document_url: string (required)
  - document_type: string (optional)

Outputs:
  - verified: boolean
  - confidence: number (0-1)
  - extracted_data: object
Don’t store large documents or images directly in variables. Store URLs or references instead.Good: {{document_url}} Poor: {{base64_encoded_document}} (can be megabytes)
Name parallel branches semantically so their outputs are self-documenting:
Parallel node: "document_analysis"
  ├─ Branch: "technical_review"
  ├─ Branch: "financial_review"
  └─ Branch: "legal_review"

Access: {{document_analysis.technical_review.output.score}}
View the complete variable store for any workflow execution in MagOneAI Studio’s execution history. This is invaluable for debugging — you can see exactly what data was available at each step.

Debugging with the variable store

The variable store is your primary debugging tool for workflows.

Viewing variable store in execution history

For any completed or running workflow execution:
  1. Open execution details in MagOneAI Studio
  2. Navigate to “Variable Store” tab
  3. See the complete variable store state at each activity
What you can see:
  • Initial state (trigger input)
  • State after each activity
  • Final state
  • Variables that were read vs written at each step

Common debugging patterns

Problem: Activity not receiving expected input → Check variable store before the activity. Does the variable exist? Is the path correct? Problem: Condition routing incorrectly → Check variable store at the Condition node. What values is it comparing? Problem: Missing data in final output → Trace backward through the variable store. Which activity should have set this variable? Did it run? Did it produce output? Problem: Parallel branches not working as expected → Check variable store after parallel completion. Did all branches complete? Are outputs structured correctly?

Next steps