Dynamic Embeds | Solace Agent Mesh

Skip to main content

# Dynamic Embeds

## Dynamic Embeds​

Dynamic embeds provide a mechanism for agents to insert context-dependent information into their text responses or tool parameters using a specialized `«...»` syntax. This feature allows for the dynamic retrieval and formatting of data without requiring explicit tool calls for simple data retrieval or calculations.

### Overview​

Dynamic embeds allow an agent to defer the inclusion of data until it is needed, resolving the value just before the final response is sent to the user.

- Standard Approach: "The current time is [call `get_time` tool]."
- With Dynamic Embeds: "The current time is `«datetime:%H:%M»`."

The system resolves the embed directive, a dynamic placeholder for data that gets computed at runtime, replacing it with the evaluated result (for example, "The current time is 10:45.").

### Syntax​

There are two primary syntaxes for embed directives.

#### Simple Syntax​

This syntax is used for most general-purpose embeds.

    «type:expression | format_spec»

- `type`: A keyword indicating the type of information to embed (for example, `state`, `math`, `datetime`).
- `expression`: The specific data to retrieve or the expression to evaluate.
- `format_spec`: (Optional) A specifier for formatting the output value (for example, a number precision `.2f` or a `strftime` string `%Y-%m-%d`).

#### Chain Syntax​

This syntax is used exclusively for the `artifact_content` embed type to apply a sequence of transformations.

    «artifact_content:spec >>> modifier1 >>> modifier2 >>> format:output_format»

- `artifact_spec`: The artifact identifier (`filename[:version]`).
- `>>>`: The chain delimiter, separating transformation steps.
- `modifier`: A transformation to apply to the data (for example, `jsonpath`, `grep`, `slice_lines`).
- `format`: A required final step that specifies the output format (for example, `text`, `json`, `datauri`).

### Available Embed Types​

#### General Purpose Embeds​

These are typically resolved by the agent host during execution.

Type | Description | Example
--- | --- | ---
`state` | Accesses a session state variable. | `«state:user_name»`
`math` | Evaluates a mathematical expression. | `«math:100 * 0.05 | .2f»` (Result: `5.00`)
`datetime` | Inserts the current date and/or time. | `«datetime:%Y-%m-%d»` (Result: `2023-10-27`)
`uuid` | Inserts a random Version 4 UUID. | `«uuid:»`
`status_update` | Signals a temporary status update to the UI. | `«status_update:Searching knowledge base...»`

#### Artifact-Related Embeds​

##### `artifact_meta`​

Retrieves a JSON string containing the full metadata of a specified artifact.

- Syntax: `«artifact_meta:filename[:version]»`
- Example: `«artifact_meta:report.csv»`

##### `artifact_return`​

This is the primary way to return an artifact to the user. It attaches the specified artifact to the message as a file attachment. The embed itself is removed from the text during gateway processing.

- Syntax: `«artifact_return:filename[:version]»`
- Resolution: Late-stage (processed by gateway before sending to user)
- Examples:
  - `«artifact_return:report.pdf»` - Returns the latest version of report.pdf
  - `«artifact_return:data.csv:3»` - Returns version 3 of data.csv
- Note: `artifact_return` is not necessary if the artifact was just created in the same response, since newly created artifacts are automatically attached to messages.

##### `artifact_content`​

Embeds the content of an artifact, with support for a chain of transformations. This is the most advanced embed type.

Note: If this embed resolves to binary content (like an image), it will be automatically converted into an attached file, similar to `artifact_return`.

Tip: If you're building a custom Python tool that needs to process artifact content, consider using the `Artifact` type hint instead of embeds. This allows the framework to automatically load artifact content before your tool executes. For more information, see Working with Artifacts in Tools.

Modifiers (Data Transformations) Modifiers are applied sequentially to transform the data.

Modifier | Description
--- | ---
`jsonpath:<expr>` | Applies a JSONPath query to JSON data.
`select_cols:<c1,c2>` | Selects specific columns from CSV data.
`filter_rows_eq:<col>:<val>` | Filters CSV rows where a column's value equals the specified value.
`slice_rows:<start>:<end>` | Selects a slice of rows from CSV data.
`slice_lines:<start>:<end>` | Selects a slice of lines from text data.
`grep:<pattern>` | Filters lines matching a regular expression in text data.
`head:<N>` / `tail:<N>` | Returns the first or last N lines of text data.
`select_fields:<f1,f2>` | Selects specific fields from a list of dictionaries.
`apply_to_template:<file>` | Renders data using a Mustache template artifact. See the Templates Guide.

Formatters (Final Output) This is the required final step in an `artifact_content` chain, defining the output format.

Formatter | Description
--- | ---
`text` | Plain text, decoded as UTF-8.
`json` / `json_pretty` | A compact or indented JSON string.
`csv` | A CSV formatted string.
`datauri` | A Base64-encoded data URI, typically for images (`data:image/png;base64,...`).

`artifact_content` Examples:

- To embed an image for display in a UI: `«artifact_content:logo.png >>> format:datauri»`
- To extract and format specific data from a JSON file: `«artifact_content:results.json >>> jsonpath:$.data[*].name >>> format:json»`
- To get the last 10 lines of a log file: `«artifact_content:debug.log >>> tail:10 >>> format:text»`
- To filter a CSV file and render it using an HTML template: `«artifact_content:users.csv >>> filter_rows_eq:Status:Active >>> apply_to_template:active_users.html >>> format:text»`

### Technical Details​

#### Resolution Stages​

Embeds are resolved in two distinct stages, depending on where the required data is available:

1. Early Stage (Agent Host): Resolved by the agent runtime itself. This stage handles simple, context-local embeds like `state`, `math`, and `datetime`.
2. Late Stage (Gateway): Resolved by the Gateway component before the final message is sent to the client. This is necessary for `artifact_content` embeds, which may involve large files or transformations that are too resource-intensive for the agent host.

#### Configuration​

- Enabling/Disabling: Embed resolution is enabled by default. It can be disabled in the `app_config` of the agent host or gateway by setting `enable_embed_resolution: false`.
- Resource Limits: The gateway enforces configurable limits to prevent abuse, including `gateway_artifact_content_limit_bytes` (default: 32KB) and `gateway_recursive_embed_depth` (default: 3).

### Error Handling​

If an embed directive fails during parsing or evaluation, it is replaced with a descriptive error message in the final output.

- Parsing Error: `[Error: Invalid modifier format: 'badmodifier']`
- Evaluation Error: `[Error: State variable 'user_id' not found]`
- Limit Exceeded: `[Error: Artifact 'large_file.zip' exceeds size limit]`

## Templates​

### Using Templates for Formatted Output​

The `apply_to_template` modifier, used within an `«artifact_content:...»` embed directive, enables an agent to render structured data using a Mustache template. This mechanism allows for the separation of data and presentation, enabling the agent to control the output format (for example, HTML, Markdown) without generating the formatting markup itself.

### The Templating Workflow​

The process involves three distinct steps:

1. Template Creation: Author a Mustache template file that defines the desired output structure.
2. Artifact Storage: Persist the template file as an artifact in the agent's artifact storage using the `create_artifact` tool.
3. Template Rendering: Utilize an `«artifact_content:...»` embed chain to process a data artifact and then apply the stored template to the result.

#### Step 1: Create a Mustache Template​

Mustache is a logic-less template syntax. Templates are created as text files (for example, `user_table.html.mustache`) containing placeholders for data injection.

Key Mustache Syntax:

- `{{variable}}`: A variable placeholder. It is replaced with the corresponding value from the data context.
- `{{#section}}...{{/section}}`: A section tag. The enclosed block is rendered for each item in a list or if the section variable is a non-empty object or truthy value.
- `{{^section}}...{{/section}}`: An inverted section tag. The enclosed block is rendered only if the section variable is false, null, or an empty list.
- `{{! comment }}`: A comment tag. The content is ignored during rendering.

Example: `user_table.html.mustache` This template generates an HTML table from a list of user objects.

    <h2>User List</h2>
    {{#items}}
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        {{#.}}
        <tr>
          <td>{{name}}</td>
          <td>{{status}}</td>
        </tr>
        {{/.}}
      </tbody>
    </table>
    {{/items}}
    {{^items}}
    <p>No users found.</p>
    {{/items}}

#### Step 2: Store the Template as an Artifact​

The template must be stored as an artifact to be accessible by the Gateway during the late-stage embed resolution process. This is accomplished using the `create_artifact` tool.

Example Agent Interaction:

> User: "Please create an HTML template to display a list of users." Agent: "Acknowledged. I will create the template artifact `user_table.html.mustache`." (The agent then invokes the `create_artifact` tool with the specified filename and the HTML content from Step 1.)

#### Step 3: Render the Template with an Embed​

With the data and template artifacts stored, the agent can construct an `artifact_content` embed chain to perform the rendering.

- Syntax: `... >>> apply_to_template:template_filename[:version] >>> ...`
- Data Context: The data provided to the template engine is the output of the preceding modifier in the chain.
  - If the data is a list, it is automatically wrapped in a dictionary of the form `{'items': your_list}`. The template should use `{{#items}}` to iterate over this list.
  - If the data is a dictionary, it is used directly as the rendering context.
- Output Format: It is mandatory to terminate the chain with a `format:` step (for example, `format:text`) to specify the MIME type of the final rendered output.

Complete Example: The following embed chain processes a JSON file and renders its content using the HTML template created in Step 1.

    «artifact_content:user_data.json >>> jsonpath:$.users[*] >>> select_fields:name,status >>> apply_to_template:user_table.html.mustache >>> format:text»

Execution Flow:

1. `artifact_content:user_data.json`: Loads the raw data from the `user_data.json` artifact.
2. `jsonpath:$.users[*]`: Applies a JSONPath expression to extract the list of user objects.
3. `select_fields:name,status`: Filters each object in the list to retain only the `name` and `status` fields.
4. `apply_to_template:user_table.html.mustache`: Renders the resulting list of users using the specified Mustache template.

### Error Handling​

- Template Not Found: If the specified template artifact does not exist, the embed resolves to `[Error: Template artifact '...' not found]`.
- Rendering Error: If the data structure is incompatible with the template's expectations, the embed resolves to `[Error: Error rendering template '...']`.