Custom Emitters
Custom Emitters
Section titled “Custom Emitters”The sidecar’s EmitterRegistry allows you to add custom translation targets. This lets AgentCTX translate CTX statements into any format — YAML, Terraform, Kubernetes manifests, or your own DSL.
How Emitters Work
Section titled “How Emitters Work”An emitter is a pure function that converts a CTXStatement AST into a string:
interface Emitter { emit(ast: CTXStatement): string; emitBatch?(asts: CTXStatement[]): string; // Optional batch support}Creating a Custom Emitter
Section titled “Creating a Custom Emitter”Step 1: Define the Emitter
Section titled “Step 1: Define the Emitter”import type { CTXStatement } from '@agentctx/core';
const yamlEmitter = { emit(ast: CTXStatement): string { const lines = [ `operation: ${ast.operator}`, `plane: ${ast.plane}`, `target: "${ast.target}"`, ];
if (ast.filters.length > 0) { lines.push('filters:'); for (const f of ast.filters) { lines.push(` - type: ${f.type}`); lines.push(` value: "${f.value}"`); } }
if (ast.payload) { lines.push(`payload: "${ast.payload.raw}"`); }
return lines.join('\n'); }};Step 2: Register It
Section titled “Step 2: Register It”import { Sidecar, EmitterRegistry } from '@agentctx/core';
const registry = new EmitterRegistry();registry.register('yaml', yamlEmitter);
const sidecar = new Sidecar(registry);Step 3: Use It
Section titled “Step 3: Use It”const result = sidecar.translate(ast, 'yaml');console.log(result.output);// operation: ?// plane: k// target: "auth patterns"// filters:// - type: tag// value: "code"// - type: limit// value: "3"Built-In Emitters
Section titled “Built-In Emitters”| Target | Output |
|---|---|
human | English prose |
surrealql | SurrealQL queries |
sql | Standard SQL |
rest | HTTP requests |
graphql | GraphQL queries |
mcp-jsonrpc | MCP JSON-RPC messages |
Batch Support
Section titled “Batch Support”For emitters that can optimize multi-statement output, implement emitBatch:
const csvEmitter = { emit(ast: CTXStatement): string { return `${ast.operator},${ast.plane},${ast.target}`; }, emitBatch(asts: CTXStatement[]): string { return 'op,plane,target\n' + asts.map(a => `${a.operator},${a.plane},${a.target}`).join('\n'); }};See Also
Section titled “See Also”- Sidecar — how the sidecar works
- Formal Specification — the AST structure