Skip to main content

Overview

Renderers transform context fragments into different output formats suitable for various LLM prompt styles. All renderers implement the same base interface and support common options like fragment grouping.

Available Renderers

XmlRenderer

Hierarchical XML with proper nesting and escaping

MarkdownRenderer

Human-readable markdown with bullet points

TomlRenderer

TOML-like configuration format

ToonRenderer

Token-efficient format with CSV-style tables

XmlRenderer

Renders fragments as XML with proper nesting and escaping.

Basic Usage

import { XmlRenderer, term, hint, guardrail } from '@deepagents/context';

const fragments = [
  term('MRR', 'monthly recurring revenue'),
  hint('Always exclude test accounts'),
  guardrail({ rule: 'Never expose PII', reason: 'Privacy compliance' }),
];

const renderer = new XmlRenderer({ groupFragments: true });
console.log(renderer.render(fragments));

Output

<terms>
  <term>
    <name>MRR</name>
    <definition>monthly recurring revenue</definition>
  </term>
</terms>
<hints>
  <hint>Always exclude test accounts</hint>
</hints>
<guardrails>
  <guardrail>
    <rule>Never expose PII</rule>
    <reason>Privacy compliance</reason>
  </guardrail>
</guardrails>

Handling Complex Data

import { workflow } from '@deepagents/context';

const frag = workflow({
  task: 'Analysis',
  steps: ['Load data', 'Clean data', 'Analyze'],
});

const renderer = new XmlRenderer();
console.log(renderer.render([frag]));
Output:
<workflow>
  <task>Analysis</task>
  <steps>
    <step>Load data</step>
    <step>Clean data</step>
    <step>Analyze</step>
  </steps>
</workflow>

XML Escaping

The renderer automatically escapes special XML characters:
const frag = term('Example', 'Use <tags> & "quotes" in text');
const renderer = new XmlRenderer();
console.log(renderer.render([frag]));
Output:
<term>
  <name>Example</name>
  <definition>Use &lt;tags&gt; &amp; &quot;quotes&quot; in text</definition>
</term>

MarkdownRenderer

Renders fragments as human-readable Markdown with bullet points.

Basic Usage

import { MarkdownRenderer, styleGuide } from '@deepagents/context';

const fragments = [
  styleGuide({
    prefer: 'CTEs for readability',
    never: 'Subqueries when CTEs work',
    always: 'Use meaningful aliases',
  }),
];

const renderer = new MarkdownRenderer();
console.log(renderer.render(fragments));

Output

## Style Guide

- **prefer**: CTEs for readability
- **never**: Subqueries when CTEs work
- **always**: Use meaningful aliases

Nested Structures

import { workflow } from '@deepagents/context';

const frag = workflow({
  task: 'Customer Analysis',
  steps: [
    'Segment customers by value',
    'Calculate metrics per segment',
    'Identify trends',
  ],
});

const renderer = new MarkdownRenderer();
console.log(renderer.render([frag]));
Output:
## Workflow

- **task**: Customer Analysis
- **steps**:
  - Segment customers by value
  - Calculate metrics per segment
  - Identify trends

TomlRenderer

Renders fragments as TOML-like configuration format.

Basic Usage

import { TomlRenderer, styleGuide } from '@deepagents/context';

const fragments = [
  styleGuide({
    prefer: 'CTEs',
    never: 'subqueries',
  }),
];

const renderer = new TomlRenderer();
console.log(renderer.render(fragments));

Output

[styleGuide]
prefer = "CTEs"
never = "subqueries"

Arrays and Objects

import { workflow } from '@deepagents/context';

const frag = workflow({
  task: 'Data Pipeline',
  steps: ['extract', 'transform', 'load'],
  triggers: ['schedule', 'webhook'],
});

const renderer = new TomlRenderer();
console.log(renderer.render([frag]));
Output:
[workflow]
task = "Data Pipeline"
steps = ["extract", "transform", "load"]
triggers = ["schedule", "webhook"]

ToonRenderer

Token-Oriented Object Notation (TOON) is a compact, token-efficient format designed for LLM prompts.

Key Features

  • YAML-like indentation for hierarchy
  • CSV-style tables for uniform object arrays
  • Minimal delimiters to reduce token usage
  • Automatic table detection for efficient array encoding

Basic Usage

import { ToonRenderer, styleGuide } from '@deepagents/context';

const fragments = [
  styleGuide({
    prefer: 'CTEs',
    never: 'subqueries',
  }),
];

const renderer = new ToonRenderer();
console.log(renderer.render(fragments));

Output

styleGuide:
  prefer: CTEs
  never: subqueries

Tabular Arrays

TOON automatically detects uniform object arrays and renders them as compact tables:
const frag = {
  name: 'products',
  data: [
    { id: 1, name: 'Widget', price: 19.99 },
    { id: 2, name: 'Gadget', price: 29.99 },
    { id: 3, name: 'Doohickey', price: 39.99 },
  ],
};

const renderer = new ToonRenderer();
console.log(renderer.render([frag]));
Output:
products[3]{id,name,price}:
  1,Widget,19.99
  2,Gadget,29.99
  3,Doohickey,39.99
The header products[3]{id,name,price}: indicates:
  • products - array name
  • [3] - array length
  • {id,name,price} - field names (CSV header)

Primitive Arrays

const frag = {
  name: 'tags',
  data: ['typescript', 'nodejs', 'ai'],
};

const renderer = new ToonRenderer();
console.log(renderer.render([frag]));
Output:
tags[3]: typescript,nodejs,ai

Mixed Arrays

When arrays contain non-uniform data, TOON uses list syntax:
import { workflow } from '@deepagents/context';

const frag = workflow({
  task: 'Analysis',
  steps: ['Load data', 'Process', 'Report'],
});

const renderer = new ToonRenderer();
console.log(renderer.render([frag]));
Output:
workflow:
  task: Analysis
  steps[3]:
    - Load data
    - Process
    - Report

Renderer Options

All renderers support the groupFragments option:
interface RendererOptions {
  /**
   * When true, fragments with the same name are grouped under a pluralized parent tag.
   * e.g., multiple <hint> become <hints><hint>...</hint><hint>...</hint></hints>
   */
  groupFragments?: boolean;
}

Example: Fragment Grouping

const renderer = new XmlRenderer({ groupFragments: false });

const fragments = [
  term('API', 'Application Programming Interface'),
  term('SDK', 'Software Development Kit'),
];

console.log(renderer.render(fragments));
// Output:
// <term><name>API</name>...</term>
// <term><name>SDK</name>...</term>

Choosing a Renderer

1

Use XmlRenderer

When working with models that prefer structured XML (e.g., Claude with Anthropic’s prompt style)
2

Use MarkdownRenderer

For human-readable documentation or when the model handles markdown well
3

Use TomlRenderer

For configuration-style data or when you need a format that’s between XML and YAML
4

Use ToonRenderer

When minimizing token usage is critical or when you have large tabular datasets

Custom Rendering

You can create custom renderers by extending the base ContextRenderer class:
import { ContextRenderer, type ContextFragment } from '@deepagents/context';

class JsonRenderer extends ContextRenderer {
  render(fragments: ContextFragment[]): string {
    const sanitized = this.sanitizeFragments(fragments);
    return JSON.stringify(sanitized, null, 2);
  }
  
  protected renderFragment() { return ''; }
  protected renderPrimitive() { return ''; }
  protected renderArray() { return ''; }
  protected renderObject() { return ''; }
}

Next Steps

Domain Knowledge

Add business logic with domain fragments

User Context

Capture user-specific information

Messages

Work with conversation messages

API Reference

Complete renderer API documentation

Build docs developers (and LLMs) love