Basic Output Structure

The last code step’s output determines what gets returned in API responses and displayed in the UI. Here’s the complete structure with all possible properties:

CODE_OUTPUT
return {
  // The main output value that will be available in API responses
  result: any,

  display: string | array, // Displayed in all contexts
  workflow_display: string | array,
  rule_display: string | array,
  record_display: string,

  // Arrays of metric blocks for displaying key data points and statistics
  rule_blocks: array,
  record_blocks: array,
};

Result Property

The result property is special and serves multiple purposes:

  1. API Response: Used as the response when running the workflow via API
  2. Record Access: Accessible through record.rules.RULE_KEY.result in the record API response when running a record via the API

Result Rules

  1. If the last code step includes a result property, it becomes the API response
  2. If no result property exists, the entire output becomes the API response
  3. Earlier steps’ results are overridden by the last code step
CODE_OUTPUT
// Example of result handling
return {
  result: {
    success: true,
    data: MODEL_ANALYSIS.output.message,
    metadata: {
      processed_at: new Date().toISOString(),
      confidence_score: MODEL_ANALYSIS.output.message.confidence,
    },
  },
};

If you are only building workflows and running them via API, the result property discussed above is all you need to understand for handling workflow outputs. The following sections about display types and blocks are specifically for showing outputs in record and rule contexts within Cortex.

If you’re not familiar with records and rules in Cortex, we recommend understanding those concepts first before proceeding to the next sections.

Understanding Rule and Record Output Properties

Properties related to rules and records are displayed in different contexts on the record page:

Record and rule properties serve different purposes in displaying results:

  • Record properties (like record_display and record_blocks) appear at the top level of the record page, showing the overall results and key metrics for the entire record
  • Rule properties (like rule_display and rule_blocks) appear within their specific rule section on the record page, showing results specific to that individual rule

You can elevate important results to be more prominent by using record properties, which will display them at the top of the record page for better visibility.

Display Types

Display properties allow you to show information in different formats and contexts. You can use markdown for rich text formatting or structured arrays/objects for more complex layouts.

Markdown

All display properties support markdown formatting:

CODE_OUTPUT
return {
  display: `
# Analysis Results 📊

## Key Findings
- Revenue: ${util.formatCurrency(MODEL_STEP.output.message.revenue)}
- Growth: ${MODEL_STEP.output.message.growth_percentage}%

## Details
${MODEL_STEP.output.message.analysis}
  `,
};

Structured Display

You can use arrays and objects for structured displays. Cortex will render them as beautiful, readable UI content. Each array can optionally include a configuration object as its first element:

CODE_OUTPUT
return {
  record_display: [
    // Content follows
    '# Financial Report',
    'Generated on: ' + new Date().toISOString(),

    // More sections can follow, each with optional config
    [{ $variant: 'info' }, '## Revenue Breakdown'],
  ],
};

Tables in Structured Display

Tables can be created using objects in structured displays. Each object represents a row, with keys as columns:

CODE_OUTPUT
return {
  rule_display: [
    '# Performance Metrics',
    '',
    'Monthly Overview:',

    // Single row table
    {
      Metric: 'Value',
      Revenue: util.formatCurrency(MODEL_STEP.output.message.revenue),
      Growth: MODEL_STEP.output.message.growth + '%',
      Status: MODEL_STEP.output.message.status,
    },

    // Multi-row table
    [
      // Row 1
      {
        Month: 'January',
        Revenue: util.formatCurrency(1000000),
        Growth: '15%',
        Status: 'On Track',
      },
      // Row 2
      {
        Month: 'February',
        Revenue: util.formatCurrency(1200000),
        Growth: '20%',
        Status: 'Exceeding',
      },
    ],
  ],
};

Display Configuration

In structured displays, any nested array can include a configuration object as its first element. However, this configuration object cannot be used at the root level of the display:

CODE_OUTPUT
return {
  record_display: [
    // Section with success variant
    [{ $variant: 'success' }, '# Successful Analysis', 'All tests passed'],

    // Section with warning variant
    [
      { $variant: 'warning' },
      '# Attention Required',
      'Some metrics need review',
    ],

    // Section without config (optional)
    ['# Regular Section', 'No special styling'],
  ],
};

Mermaid Diagrams

Cortex supports Mermaid diagrams in display properties to output diagrams in the result UI. You can create various types of diagrams using Mermaid syntax, including:

  • XY Charts
  • Mindmaps
  • Pie Charts
  • C4 Diagrams

Basic Mermaid Usage

CODE_OUTPUT
return {
  display: `
# Analysis Visualization 📊

\`\`\`mermaid
graph TD
    A[Input Document] -->|Process| B(Text Extraction)
    B --> C{Analysis}
    C -->|High Risk| D[Alert]
    C -->|Medium Risk| E[Review]
    C -->|Low Risk| F[Approve]
\`\`\`
  `,
};

Dynamic Diagrams with Data

You can create diagrams dynamically using workflow data:

CODE_OUTPUT
const analysisResults = MODEL_STEP.output.message;

// Create pie chart segments from analysis results
const pieSegments = analysisResults.categories
  .map((cat) => `    "${cat.name}" : ${cat.percentage}`)
  .join('\n');

return {
  record_display: `
## Analysis Distribution

\`\`\`mermaid
pie title Document Category Distribution
${pieSegments}
\`\`\`

## Process Flow

\`\`\`mermaid
graph LR
    A[Start] -->|${analysisResults.steps[0]}| B(Processing)
    B -->|${analysisResults.steps[1]}| C{Analysis}
    C -->|${analysisResults.outcomes.success}| D[Success]
    C -->|${analysisResults.outcomes.failure}| E[Failure]
\`\`\`
  `,
};

Metric Blocks

Blocks display key metrics with optional formatting and styling. All properties except label and value are optional.

Record Blocks

CODE_OUTPUT
return {
  record_blocks: [
    {
      label: 'Revenue', // Required
      value: 1234567, // Required
      description: 'YTD Revenue', // Optional
      value_color: 'success', // Optional
      format: 'currency', // Optional
      order: 1, // Optional
    },
  ],
};

Rule Blocks

CODE_OUTPUT
return {
  rule_blocks: [
    {
      label: 'Risk Score',
      value: 85.7,
      description: 'Credit risk assessment score based on historical data',
      value_color: 'warning',
      format: 'number',
      order: 1,
    },
  ],
};

Block Properties

  1. Required Properties:

    • label: Identifies the metric
    • value: The actual value to display
  2. Optional Properties:

    • description: Tooltip text explaining the metric
    • value_color: Color styling for the value
    • format: How to format the value
    • order: Display order (numeric)

Available Formats

  • date: Formats timestamps as dates
  • datetime: Formats timestamps with date and time
  • number: Formats numerical values
  • currency: Formats monetary values
  • percent: Formats percentage values

Available Colors

The following colors can be used to style values and variants in blocks and display UIs. Choose colors that effectively communicate the meaning and importance of the data being displayed.

Standard Colors

Available for variants and value colors:

  • status - Special dynamic color based on status
  • info - Informational blue
  • success - Positive green
  • danger - Critical red
  • warning - Cautionary yellow
  • orange - Orange highlight
  • yellow - Yellow highlight
  • green - Green highlight
  • red - Red highlight
  • blue - Blue highlight

Special Status Color

The status color is dynamic and changes based on the workflow or rule status:

CODE_OUTPUT
return {
  rule_blocks: [
    {
      label: 'Workflow Status',
      value: 'Processing Complete',
      value_color: 'status', // Will reflect current workflow status
      order: 1,
    },
  ],
};