Supported Sources
The template system supports these sources:{{agent.*}}- References agent attributes{{test_case.*}}- References test case attributes{{test_case.expected_behaviors}}- References test case criteria (used by Composite Evaluation){{customer_metadata.*}}- References metadata you provide at conversation upload time (see Customer Metadata below)
Basic Usage
The simplest form is accessing a top-level attribute:Customer Metadata (Upload-Time Values)
When you submit a production call for conversation monitoring, you can attach arbitrarymetadata to that specific conversation. Those values are stored with the conversation and can be referenced in any LLM judge metric prompt using {{customer_metadata.<key>}}. The value is substituted per conversation at evaluation time, so the same metric can be judged against a different ground-truth value for each uploaded call.
This is the recommended way to evaluate uploaded conversations against facts that are only known at upload time — order totals, prices, account balances, confirmation numbers, expected outcomes, and similar per-call ground truth.
1. Provide the value when you upload the conversation (POST /v1/conversations:submit):
coval conversations submit --metadata milk_price='$2.50'.
2. Reference the value in your metric prompt:
If a metric prompt references a
{{customer_metadata.<key>}} that a conversation did not supply, that metric fails for that conversation with a clear error. Make sure every conversation you attach the metric to includes the key, or scope the metric to the conversations that carry it.Nested Paths
You can access nested attributes using dot notation:Array Indexing
Access specific elements in arrays using bracket notation:Array Access Without Indexing
Access entire arrays without indexing - they’ll be returned as strings:Dynamic Keys via Multi-Pass Resolution
The system supports dynamic key resolution through multiple passes, allowing you to use one template variable to determine another:- First pass: Resolves
{{test_case.username}}→ “user1” - Second pass: Resolves
{{agent.users.user1.email}}→ “test@example.com”
Complete Example
Here’s a comprehensive example combining multiple features: Agent attributes:Use Cases
In Metric Prompts
Attributes are commonly used in metric prompts to create context-aware evaluations. See Configure metrics for examples of using attributes in evaluation metrics.In Test Scenarios
You can embed agent attributes directly into test case scenarios and expected behaviors. This allows the same test set to work with different agents that have different attribute values. See Test Sets for more information.In Criteria
Use attributes in criteria definitions to create dynamic validation that adapts to the specific agent or test case being evaluated. These criteria are used by the Composite Evaluation metric.Passing State Into Your Agent
Beyond evaluation, you can inject{{test_case.*}} and {{agent.*}} values into your agent’s connection configuration so your backend resolves the right context for each test case — for example, an account or customer ID that determines which records the agent looks up. Coval substitutes each test case’s value before it connects to your agent, so one test set can drive many different backend states.
This works across simulator types:
| Simulator | Where state is injected |
|---|---|
Chat (MODEL_TYPE_CHAT) | Custom headers and input template |
| Inbound voice (SIP) | Custom SIP headers, configured via mutations |
| Outbound voice | The trigger-call payload |
account_id attribute. The same {{test_case.<attribute>}} pattern applies to the voice fields above. (The scenario text of every test case also supports these variables, regardless of simulator type.)