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

# Dynamic Variables

> Define agent-level variables that are automatically populated with scenario-specific values during workflow evaluator generation

export const CopyPageButton = () => {
  if (typeof window !== 'undefined') {
    setTimeout(function () {
      if (document.getElementById('ck-tools')) return;
      var anchor = document.getElementById('content-area') || document.querySelector('.mdx-content');
      if (!anchor) return;
      if (!document.getElementById('ck-style')) {
        var s = document.createElement('style');
        s.id = 'ck-style';
        s.textContent = '#ck-tools{position:absolute;top:6px;right:0;z-index:100;font-family:inherit;}' + '.ck-row{display:inline-flex;align-items:stretch;border:1px solid rgba(0,0,0,0.15);border-radius:8px;overflow:hidden;background:#fff;}' + ':root.dark .ck-row{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12);}' + '.ck-btn{padding:5px 12px;border:none;background:none;cursor:pointer;font-size:13px;font-weight:500;font-family:inherit;color:#374151;}' + ':root.dark .ck-btn{color:#d1d5db;}' + '.ck-btn:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-btn:hover{background:rgba(255,255,255,0.06);}' + '.ck-chevron{padding:5px 8px;border:none;background:none;cursor:pointer;font-size:14px;font-family:inherit;color:#374151;}' + ':root.dark .ck-chevron{color:#d1d5db;}' + '.ck-chevron:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-chevron:hover{background:rgba(255,255,255,0.06);}' + '.ck-divider{width:1px;background:rgba(0,0,0,0.12);flex-shrink:0;}' + ':root.dark .ck-divider{background:rgba(255,255,255,0.12);}' + '.ck-dd{position:absolute;top:calc(100% + 4px);right:0;min-width:180px;background:#fff;border:1px solid rgba(0,0,0,0.12);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.1);padding:4px;display:none;z-index:200;}' + ':root.dark .ck-dd{background:#1f2937;border-color:rgba(255,255,255,0.1);box-shadow:0 4px 16px rgba(0,0,0,0.35);}' + '.ck-item{display:block;width:100%;padding:7px 12px;border:none;background:none;border-radius:6px;cursor:pointer;font-size:13px;font-family:inherit;text-align:left;color:#374151;}' + ':root.dark .ck-item{color:#d1d5db;}' + '.ck-item:hover{background:rgba(0,0,0,0.05);}' + ':root.dark .ck-item:hover{background:rgba(255,255,255,0.07);}';
        document.head.appendChild(s);
      }
      var wrap = document.createElement('div');
      wrap.id = 'ck-tools';
      var row = document.createElement('div');
      row.className = 'ck-row';
      var mainBtn = document.createElement('button');
      mainBtn.className = 'ck-btn';
      mainBtn.textContent = 'Copy page';
      var divider = document.createElement('span');
      divider.className = 'ck-divider';
      var chevron = document.createElement('button');
      chevron.className = 'ck-chevron';
      chevron.textContent = '▾';
      var dd = document.createElement('div');
      dd.className = 'ck-dd';
      function closeDD() {
        dd.style.display = 'none';
      }
      function openDD() {
        dd.style.display = 'block';
      }
      chevron.onclick = function (e) {
        e.stopPropagation();
        if (dd.style.display === 'block') {
          closeDD();
        } else {
          openDD();
        }
      };
      document.addEventListener('click', function (e) {
        if (!e.target.closest('#ck-tools')) {
          closeDD();
        }
      });
      document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') {
          closeDD();
        }
      });
      function makeItem(label, fn) {
        var b = document.createElement('button');
        b.className = 'ck-item';
        b.textContent = label;
        b.onclick = function () {
          fn();
          closeDD();
        };
        return b;
      }
      function getMarkdown() {
        var walk = function (node) {
          if (!node) return '';
          if (node.nodeType === 3) return node.textContent || '';
          if (node.nodeType !== 1) return '';
          var tag = node.tagName.toLowerCase();
          var skip = ['script', 'style', 'svg', 'noscript', 'button', 'iframe'];
          if (skip.indexOf(tag) !== -1) return '';
          if (node.id === 'ck-tools') return '';
          var ch = Array.from(node.childNodes).map(walk).join('');
          if (tag === 'h1') return '\n# ' + ch.trim() + '\n\n';
          if (tag === 'h2') return '\n## ' + ch.trim() + '\n\n';
          if (tag === 'h3') return '\n### ' + ch.trim() + '\n\n';
          if (tag === 'p') return '\n' + ch.trim() + '\n\n';
          if (tag === 'pre') return '\n```\n' + node.textContent.trim() + '\n```\n\n';
          if (tag === 'li') return '- ' + ch.trim() + '\n';
          if (tag === 'code') return '`' + ch.trim() + '`';
          return ch;
        };
        var content = document.querySelector('.mdx-content') || document.getElementById('content-area') || document.body;
        return walk(content).replace(/\n\n\n+/g, '\n\n').trim();
      }
      function copyMd() {
        var md = getMarkdown();
        navigator.clipboard.writeText(md).then(function () {
          mainBtn.textContent = 'Copied!';
          setTimeout(function () {
            mainBtn.textContent = 'Copy page';
          }, 2000);
        });
      }
      function viewMd() {
        var md = getMarkdown();
        var safe = md.split('&').join('&amp;').split('<').join('&lt;').split('>').join('&gt;');
        var html = '<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{font-family:monospace;max-width:860px;margin:40px auto;padding:0 24px;line-height:1.7;white-space:pre-wrap;word-wrap:break-word}</style></head><body>' + safe + '</body></html>';
        window.open(URL.createObjectURL(new Blob([html], {
          type: 'text/html'
        })), '_blank');
      }
      function openClaude() {
        var prompt = 'Can you read this Cekura docs page ' + window.location.href + ' so I can ask you questions?';
        window.open('https://claude.ai/new?q=' + encodeURIComponent(prompt), '_blank');
      }
      mainBtn.onclick = copyMd;
      dd.appendChild(makeItem('Copy page', copyMd));
      dd.appendChild(makeItem('View as Markdown', viewMd));
      dd.appendChild(makeItem('Open in Claude', openClaude));
      row.appendChild(mainBtn);
      row.appendChild(divider);
      row.appendChild(chevron);
      wrap.appendChild(row);
      wrap.appendChild(dd);
      anchor.style.position = 'relative';
      anchor.insertBefore(wrap, anchor.firstChild);
    }, 50);
  }
  return null;
};

<CopyPageButton />

## Overview

Dynamic variables are `{{variableName}}` placeholders in your agent's system prompt that get replaced with realistic, caller-specific values at call time. When Cekura generates workflow evaluators, it produces appropriate values for each dynamic variable so the evaluator knows exactly what information to provide during the conversation.

Dynamic variables are useful when your agent:

* Addresses callers by name or account details pulled from a CRM (`{{firstName}}`, `{{accountId}}`)
* References call-specific data like policy numbers, order IDs, or member numbers
* Uses contextual information that changes per caller (`{{planType}}`, `{{memberSince}}`)

## How Dynamic Variables Work

<Note>
  Dynamic Variables is for **auto-generating** realistic values for your `{{var}}` placeholders. If you instead need to **supply specific, known values** for those same system-prompt placeholders when triggering a test run — for example, values from a production form, CRM, or fixed test dataset — use the `main_agent_variables` section of a [Test Profile](/documentation/key-concepts/evaluators/test-profile#profile-sections-main-agent-vs-testing-agent) instead. Both mechanisms inject values via `assistantOverrides.variableValues` on Vapi (or the equivalent on other providers), but Dynamic Variables generates the values while Test Profile `main_agent_variables` lets you specify them.
</Note>

### 1. Auto-Detection

When you create an agent or save changes to its description, Cekura automatically scans for `{{variableName}}` patterns and generates a description for each variable based on how it is used in the prompt. These detected variables appear in the **Dynamic Variables** section of your agent settings.

### 2. Scenario Generation

When a workflow evaluator is generated, Cekura runs a single coordinated generation pass that produces:

* A **test profile** with persona facts (name, address, etc.)
* **Dynamic variable values** — one value per variable, consistent with the test profile
* **Mock tool entries** — tool input/output pairs that use the same identity (only if mock tools are configured for the agent)

This ensures all three data sources are internally consistent. For example, if `firstName=Sarah` and `accountId=ACC-4521` are generated, the mock tool entries will also reference Sarah's account so the agent's tool calls return matching data.

### 3. Value Injection at Call Time

The generated variable values are passed to the evaluator before the call starts. The evaluator uses them to answer questions the agent asks during the conversation (e.g., providing the correct account number when prompted).

## Managing Dynamic Variables

Dynamic variables are managed in **Agent Settings**, in the **Dynamic Variables** accordion on the right-hand panel.

<Note>
  Variables are auto-populated when the agent is created or whenever the description is saved. You do not need to add them manually unless you want to define variables that are not derived from `{{...}}` placeholders.
</Note>

### View Variables

Open the **Dynamic Variables** section in agent settings. Each variable shows its name and, when expanded, its description — which tells the generation system what kind of value to produce.

### Edit a Variable

Click the **pencil icon** on any variable to update its name or description. Improving the description helps Cekura generate more accurate and realistic values.

### Add Variables

Click **"Add Variables"** to add one or more variables manually:

* **Form mode**: Fill in a name and description for each variable. Use the **"Add another variable"** button to add multiple at once.
* **JSON mode**: Paste a JSON array of `{"name": "...", "description": "..."}` objects for bulk import.

Variable names must use only letters, digits, and underscores, and must start with a letter or underscore (e.g., `firstName`, `account_id`).

### Delete a Variable

Click the **trash icon** on any variable to remove it. Deleting a variable means it will no longer be generated during scenario creation. Evaluators that have already been generated are not affected.

## Example

**Agent description snippet:**

```
Hello {{firstName}}, I see your account number is {{accountId}}.
How can I help you today?
```

**Auto-detected variables:**

| Name        | Auto-generated Description                             |
| ----------- | ------------------------------------------------------ |
| `firstName` | The caller's first name as it appears on their account |
| `accountId` | The unique account identifier for the caller           |

**At evaluator generation, Cekura produces consistent values across all three outputs:**

```
Test profile (sectioned):
  {
    "main_agent_variables":     { "firstName": "Sarah", "accountId": "ACC-4521" },
    "testing_agent_variables":  { "customer_name": "Sarah Johnson",
                                  "story": "Calling about her latest statement." }
  }
Mock tool entry:
  { "input":  { "account_id": "ACC-4521" },
    "output": { "name": "Sarah Johnson", "balance": 1240.00 } }
```

The values in `main_agent_variables` are what the agent under test actually receives as dynamic variables at call time (via `assistantOverrides.variableValues` on VAPI, `retell_llm_dynamic_variables` on Retell, etc.). The values in `testing_agent_variables` are persona context for Cekura's simulated caller — they never reach the agent under test. See [Test Profile → Profile Sections](/documentation/key-concepts/evaluators/test-profile#profile-sections-main-agent-vs-testing-agent) for details.

## Relationship to Test Profiles and Mock Tools

Dynamic variables, test profiles, and mock tools are generated together as a coordinated set:

| Concept               | Purpose                                                                                                                                                                                      |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Test Profile**      | Sectioned identity blob — `main_agent_variables` (sent to your agent) plus `testing_agent_variables` (persona for the simulator).                                                            |
| **Dynamic Variables** | Per-call values injected into the agent's system prompt via `{{...}}` placeholders. Live in `test_profile.information.main_agent_variables` and are the single source of truth at call time. |
| **Mock Tools**        | Predefined tool responses that return data consistent with the persona.                                                                                                                      |

All three are kept in sync so that the agent's system prompt, tool responses, and evaluator behavior all reflect the same fictional caller identity.

<Tip>
  Write detailed descriptions for your dynamic variables. The generation system uses these descriptions to produce realistic, contextually correct values. For example, instead of "Account ID", write "The 8-digit numeric account ID in the format ACCT-XXXXXXXX used to look up the caller's record."
</Tip>
