RCL Compiler Output Specification
Section titled “RCL Compiler Output Specification”Overview
Section titled “Overview”The RCL compiler transforms RCL files into two output formats: JSON and JavaScript/TypeScript modules. This document defines the expected structure and schema for these outputs based on the actual implementation.
Schema Reference
Section titled “Schema Reference”All output must validate against: https://rcl.rcsagents.io/schemas/rcl-output.schema.json
Output Formats
Section titled “Output Formats”1. JSON Output (-f json)
Section titled “1. JSON Output (-f json)”The JSON output contains three main sections:
{ "$schema": "https://rcl.rcsagents.io/schemas/rcl-output.schema.json", "agent": { "name": "BMWAgent", "displayName": "BMW Virtual Assistant", "start": "MainFlow", "config": { "description": "Your personal BMW assistant", "logoUri": { "type": "url", "value": "https://example.com/logo.png" }, "color": "#0066CC", "phoneNumber": { "type": "phone", "value": "+1-555-BMW-HELP" }, "phoneLabel": "Call BMW Support" }, "defaults": { "fallbackMessage": "I didn't understand that. Please choose from the available options.", "messageTrafficType": "PROMOTION" } }, "flows": { "MainFlow": { "$schema": "https://rcl.rcsagents.io/schemas/csm/machine-definition.schema.json", "id": "MainFlow", "initial": "Welcome", "states": { "Welcome": { "transitions": [ { "pattern": "Order Coffee", "target": "OrderCoffee", "context": { "action": "order" } }, { "pattern": ":default", "target": "Welcome" } ], "meta": { "messageId": "Welcome" } } } } }, "messages": { "Welcome": { "type": "richCard", "title": "Welcome to Coffee Shop", "description": "How can we help you today?", "media": { "type": "url", "value": "https://example.com/welcome.jpg" }, "suggestions": [ { "type": "reply", "text": "Order Coffee", "postbackData": "order_coffee" }, { "type": "reply", "text": "View Menu", "postbackData": "view_menu" } ], "messageTrafficType": "PROMOTION" } }}2. JavaScript Output (-f js)
Section titled “2. JavaScript Output (-f js)”The JavaScript output is an ES module with named exports:
// Generated from filename.rclexport const agent = { "name": "CoffeeShop", "displayName": "Quick Coffee", // ... agent configuration};
export const messages = { "Welcome": { "type": "richCard", "title": "Welcome", // ... message definition } // ... other messages};
export const flows = { "MainFlow": { "id": "MainFlow", "initial": "Welcome", "states": { // ... state definitions } } // ... other flows};
// Utility functionsexport function getMessage(messageId) { return messages[messageId];}
export function getFlow(flowId) { return flows[flowId];}
export function createMachine(flowId, options = {}) { // Create state machine instance}
// Default exportexport default { messages, flows, agent, getMessage, getFlow, createMachine };Schema Compliance
Section titled “Schema Compliance”Agent Configuration
Section titled “Agent Configuration”Must conform to the agentOutput definition in rcl-output.schema.json
Structure:
{ "agent": { "name": "string (required from RCL agent declaration)", "displayName": "string (required, max 100 chars)", "brandName": "string (optional)", "config": { "description": "string", "logoUri": { "type": "url", "value": "https://..." }, "heroUri": { "type": "url", "value": "https://..." }, "color": "#RRGGBB (hex color)", "phoneNumber": { "type": "phone", "value": "+..." }, "phoneLabel": "string", "email": { "type": "email", "value": "user@domain.com" }, "emailLabel": "string", "website": { "type": "url", "value": "https://..." }, "websiteLabel": "string", "address": "string", "openingHours": "string", "agentUseCase": "TRANSACTIONAL|PROMOTIONAL|OTP|MULTI_USE", "hostingRegion": "NORTH_AMERICA|EUROPE|ASIA_PACIFIC" }, "defaults": { "messageTrafficType": "PROMOTION|TRANSACTION|AUTHENTICATION|SERVICEREQUEST|ACKNOWLEDGEMENT", "fallbackMessage": "string", "postbackData": "string (JS expression template)" } }}Messages
Section titled “Messages”Must conform to the messageOutput definition in rcl-output.schema.json
Types and Structure:
Text Message
Section titled “Text Message”{ "type": "text", "text": "Message content (max 2048 chars)", "suggestions": [ /* max 11 suggestions */ ], "messageTrafficType": "PROMOTION", "ttl": "3600s"}Rich Card Message
Section titled “Rich Card Message”{ "type": "richCard", "title": "Card Title (max 200 chars)", "description": "Card description (max 2000 chars)", "size": "small|medium|large|compact", "media": { "type": "url", "value": "https://example.com/image.jpg" }, "suggestions": [ /* max 11 suggestions */ ], "messageTrafficType": "PROMOTION"}Carousel Message
Section titled “Carousel Message”{ "type": "carousel", "title": "Carousel Title", "size": "medium", "cards": [ { "title": "Card 1", "description": "First card", "suggestions": [ /* max 4 suggestions per card */ ] }, { "title": "Card 2", "description": "Second card", "suggestions": [ /* max 4 suggestions per card */ ] } ]}Suggestions
Section titled “Suggestions”{ "suggestions": [ { "type": "reply", "text": "Button Text (max 25 chars)", "postbackData": "callback_value (max 2048 chars)" }, { "type": "action", "text": "Call Us", "postbackData": "action_call", "phoneNumber": "+1234567890" }, { "type": "action", "text": "Visit Website", "postbackData": "action_url", "url": "https://example.com" } ]}Must conform to CSM Machine Definition Schema
Structure:
{ "flows": { "FlowId": { "id": "FlowId", "initial": "InitialStateName", "states": { "StateName": { "transitions": [ { "pattern": "user_input_pattern", "target": "NextStateName", "priority": 10, "context": { "key": "value" } }, { "pattern": ":default", "target": "FallbackState" } ], "meta": { "messageId": "MessageToShow", "transient": false } } }, "meta": { "name": "Flow Display Name", "description": "What this flow does" } } }}Key Concepts:
- States: Represent conversation steps
- Transitions: Define how to move between states based on user input
- Patterns: Match against user input (postbackData from suggestions)
- Context: Variables passed between states
- Priority: Higher numbers checked first (auto-assigned by compiler)
:default: Fallback transition when no patterns match
Type Tag Processing
Section titled “Type Tag Processing”RCL type tags are converted to typed objects:
<url https://example.com> → {"type": "url", "value": "https://example.com"}<phone +1234567890> → {"type": "phone", "value": "+1234567890"}<email user@domain.com> → {"type": "email", "value": "user@domain.com"}<money 19.99> → {"type": "money", "value": "19.99", "currency": "USD"}<datetime 2024-07-26> → {"type": "datetime", "value": "2024-07-26T00:00:00Z"}<duration P1D> → {"type": "duration", "value": "P1D"}PostbackData Generation
Section titled “PostbackData Generation”When suggestions don't specify postbackData, it's auto-generated:
Rules:
- Convert to lowercase
- Replace non-alphanumeric with underscores
- Collapse multiple underscores to single
- Trim leading/trailing underscores
Examples:
"Order Coffee"→"order_coffee""Small ($3.50)"→"small_3_50""Yes, please!"→"yes_please""BMW M3 Series"→"bmw_m3_series"
Message Traffic Types
Section titled “Message Traffic Types”Valid values (from schema):
MESSAGE_TRAFFIC_TYPE_UNSPECIFIEDAUTHENTICATIONTRANSACTIONPROMOTION(default)SERVICEREQUESTACKNOWLEDGEMENT
Agent Use Cases
Section titled “Agent Use Cases”Valid values (from schema):
AGENT_USE_CASE_UNSPECIFIEDTRANSACTIONALPROMOTIONALOTPMULTI_USE
Hosting Regions
Section titled “Hosting Regions”Valid values (from schema):
HOSTING_REGION_UNSPECIFIEDNORTH_AMERICAEUROPEASIA_PACIFIC
Validation
Section titled “Validation”The compiler validates output against these schemas:
rcl-output.schema.json- Complete output structurecsm/machine-definition.schema.json- Individual flows- Internal validation - Cross-references, state transitions, message references
Validation Tools:
# Using ajv-clinpx ajv validate -s https://rcl.rcsagents.io/schemas/rcl-output.schema.json -d output.json
# Using jsonschema (Python)jsonschema -i output.json https://rcl.rcsagents.io/schemas/rcl-output.schema.jsonImplementation Notes
Section titled “Implementation Notes”- Flat Structure: Output uses simplified, flat message structure (not nested RCS API format)
- CSM Format: Flows use Conversation State Machine format, not XState
- Auto-Generation: Many fields auto-generated from RCL (postbackData, priorities, etc.)
- Validation: All output validated against schemas before generation
- Type Safety: TypeScript definitions available matching schemas
Migration from Legacy Format
Section titled “Migration from Legacy Format”If updating from older documentation expecting nested RCS format:
Old (Incorrect):
{ "agent": { "rcsBusinessMessagingAgent": { /* nested config */ } }, "messages": { "Welcome": { "contentMessage": { "text": "...", "suggestions": [...] } } }}New (Correct):
{ "agent": { "config": { /* flat config */ }, "defaults": { /* flat defaults */ } }, "messages": { "Welcome": { "type": "text", "text": "...", "suggestions": [...] } }}Related Documentation
Section titled “Related Documentation”- JSON Schemas - Complete schema documentation
- Getting Started - Basic RCL usage
- Examples - Complete example files