Block Types

Updated

The Chaos AI SDK returns structured content as blocks. Each block has a kind: "block" field and a type discriminant. The Block union type covers all 10 block types.

types.ts
type Block =
  | MarkdownBlock
  | TableBlock
  | PieChartBlock
  | BarChartBlock
  | TimeseriesChartBlock
  | ActionBlock
  | InteractiveBlock
  | AlertBlock
  | CodeBlock
  | FormBlock;
Typetype ValueDescription
TableBlock"table"Tabular data with headers and rows
PieChartBlock"pie_chart"Pie chart with series data
BarChartBlock"bar_chart"Bar chart with series data
TimeseriesChartBlock"timeseries_chart"Time-series chart with series data
ActionBlock"action"Transaction actions with primitives and risk analysis
MarkdownBlock"markdown"Rendered markdown content
InteractiveBlock"interactive"User prompts with selectable options
AlertBlock"alert"Alerts, warnings, and errors
CodeBlock"code"Code snippets with language tag
FormBlock"form"Input forms with typed fields

TableBlock

types.ts
interface TableBlock {
  kind: "block";
  type: "table";
  title?: string;
  tableHeaders: string[];
  tableRows: unknown[][];
  tableHeadersMetadata?: {
    [k: string]: { [k: string]: unknown };
  };
}

Tables contain structured data with column headers and rows of cell values. Use table utility functions like tableToObjects() and getTableColumn() to work with table data.

example.ts
import { extractBlocks, extractTableBlocks, tableToObjects } from '@chaoslabs/ai-sdk';
 
const tables = extractTableBlocks(response);
for (const table of tables) {
  console.log(`Table: ${table.title}`);
  console.log(`  Columns: ${table.tableHeaders.join(', ')}`);
  console.log(`  Rows: ${table.tableRows.length}`);
 
  // Convert to typed objects
  const rows = tableToObjects<{ Asset: string; Balance: string }>(table);
  for (const row of rows) {
    console.log(`  ${row.Asset}: ${row.Balance}`);
  }
}

PieChartBlock

types.ts
interface PieChartBlock {
  kind: "block";
  type: "pie_chart";
  title?: string;
  series: ChartSeries[];
  isCurrency?: boolean;
}
 
interface ChartSeries {
  name: string;
  data: ChartDataPoint[];
}
 
interface ChartDataPoint {
  x: string | number;
  y: number;
}
example.ts
import { extractChartBlocks, getChartData, getChartPercentages } from '@chaoslabs/ai-sdk';
 
const charts = extractChartBlocks(response);
for (const chart of charts) {
  if (chart.type === 'pie_chart') {
    const data = getChartData(chart);
    const pcts = getChartPercentages(chart);
    for (const item of pcts) {
      console.log(`${item.label}: ${item.percentage.toFixed(1)}%`);
    }
  }
}

BarChartBlock

types.ts
interface BarChartBlock {
  kind: "block";
  type: "bar_chart";
  title?: string;
  series: ChartSeries[];
  isCurrency?: boolean;
}

Bar charts share the same ChartSeries / ChartDataPoint structure as pie charts.

TimeseriesChartBlock

types.ts
interface TimeseriesChartBlock {
  kind: "block";
  type: "timeseries_chart";
  title?: string;
  series: ChartSeries[];
}

Time-series charts use the same series structure. The x values in ChartDataPoint are typically timestamps.

[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop

ActionBlock

Action blocks represent DeFi transaction intents with risk analysis. They contain primitives (typed operation descriptors) and optional raw transactions.

types.ts
interface ActionBlock {
  kind: "block";
  type: "action";
  metadata: { [k: string]: unknown };
  needs_confirmation: boolean;
  notes: string;
  primitives: Primitive[];
  references?: string[];
  risks: Risks;
  sequence?: boolean;
  transactions?: TransactionSequence[];
  value?: { [k: string]: unknown };
}
 
interface Risks {
  level: "low" | "medium" | "high" | "critical";
  blockers: RiskInfoItem[];
  warnings: RiskInfoItem[];
  info: RiskInfoItem[];
}
 
interface RiskInfoItem {
  id?: string;
  severity?: "block" | "warn" | "info";
  title?: string;
  message?: string;
  impact?: RiskImpact;
}
 
interface RiskImpact {
  metric: string;
  current?: number;
  projected?: number;
  threshold?: number;
  at_risk_usd?: number;
  liquidation_price?: string;
}
example.ts
import {
  extractTransactionBlocks,
  extractPrimitives,
  getAllWarnings,
  getHighestRiskLevel,
} from '@chaoslabs/ai-sdk';
 
const actions = extractTransactionBlocks(response);
for (const action of actions) {
  console.log(`Risk level: ${action.risks.level}`);
  console.log(`Needs confirmation: ${action.needs_confirmation}`);
  console.log(`Primitives: ${action.primitives.length}`);
 
  if (action.transactions) {
    for (const seq of action.transactions) {
      console.log(`  Chain: ${seq.transactions[0]?.chainId}`);
      console.log(`  Requires approval: ${seq.requiresApproval}`);
    }
  }
}
 
// Aggregate across all action blocks
const allPrimitives = extractPrimitives(response);
const warnings = getAllWarnings(response);
const highestRisk = getHighestRiskLevel(response);

MarkdownBlock

types.ts
interface MarkdownBlock {
  kind: "block";
  type: "markdown";
  content: string;
}
example.ts
import { extractMarkdownBlocks } from '@chaoslabs/ai-sdk';
 
const markdowns = extractMarkdownBlocks(response);
for (const md of markdowns) {
  console.log(md.content);
}

InteractiveBlock

Interactive blocks prompt the user to select from options or confirm/cancel an action.

types.ts
interface InteractiveBlock {
  kind: "block";
  type: "interactive";
  title: string;
  body?: string;
  context?: string;
  style: "options" | "confirm_cancel";
  options?: InteractiveOption[];
}
 
interface InteractiveOption {
  id: string;
  label: string;
  description?: string;
  metadata?: { [k: string]: unknown };
}
example.ts
import { extractInteractiveBlocks } from '@chaoslabs/ai-sdk';
 
const interactives = extractInteractiveBlocks(response);
for (const block of interactives) {
  console.log(`Prompt: ${block.title}`);
  if (block.options) {
    for (const opt of block.options) {
      console.log(`  [${opt.id}] ${opt.label}`);
    }
  }
}

AlertBlock

Alerts convey informational, warning, or error messages.

types.ts
interface AlertBlock {
  kind: "block";
  type: "alert";
  severity: "info" | "warning" | "error";
  content: string;
  code?: "timeout" | "high_demand" | "validation" | "portfolio_fetch" | "price_fetch" | "generic";
  retryable?: boolean;
}
example.ts
import { extractInfoBlocks } from '@chaoslabs/ai-sdk';
 
const alerts = extractInfoBlocks(response);
for (const alert of alerts) {
  if (alert.severity === 'error') {
    console.error(`Error [${alert.code}]: ${alert.content}`);
    if (alert.retryable) console.log('This error is retryable.');
  } else if (alert.severity === 'warning') {
    console.warn(`Warning: ${alert.content}`);
  } else {
    console.info(`Info: ${alert.content}`);
  }
}

CodeBlock

types.ts
interface CodeBlock {
  kind: "block";
  type: "code";
  content: string;
  language: string;
}
example.ts
import { extractCodeBlocks } from '@chaoslabs/ai-sdk';
 
const codeBlocks = extractCodeBlocks(response);
for (const block of codeBlocks) {
  console.log(`Language: ${block.language}`);
  console.log(block.content);
}

FormBlock

Forms collect user input with typed fields. The fields array contains at least one FormField.

types.ts
interface FormBlock {
  kind: "block";
  type: "form";
  title: string;
  subtitle?: string;
  primitive?: string;
  fields: [FormField, ...FormField[]];
  submit_label: string;
  cancel_label?: string;
  context_note?: string;
  validation_rules?: {}[];
  tool_name?: string;
  tool_params?: {};
}
 
type FormField =
  | TextInputFormField
  | NumberInputFormField
  | CurrencyInputFormField
  | TokenAmountInputFormField
  | TokenSelectFormField
  | ChainSelectFormField
  | ProtocolSelectFormField
  | SelectFormField
  | SliderFormField
  | ToggleFormField
  | AddressInputFormField
  | ReadonlyFormField;
example.ts
import { extractFormBlocks } from '@chaoslabs/ai-sdk';
 
const forms = extractFormBlocks(response);
for (const form of forms) {
  console.log(`Form: ${form.title}`);
  console.log(`Submit: ${form.submit_label}`);
  for (const field of form.fields) {
    console.log(`  [${field.type}] ${field.label}: ${field.value ?? '(empty)'}`);
  }
}

Type Guards

The SDK exports type guard functions for narrowing Block values to specific types:

FunctionNarrows to
isTableBlock(block)TableBlock
isChartBlock(block)ChartBlock
isPieChartBlock(block)PieChartBlock
isBarChartBlock(block)BarChartBlock
isTimeseriesChartBlock(block)TimeseriesChartBlock
isTransactionActionBlock(block)ActionBlock
isMarkdownBlock(block)MarkdownBlock
isInteractiveBlock(block)InteractiveBlock
isInfoBlock(block)AlertBlock
isErrorBlock(block)AlertBlock & { severity: 'error' }
isCodeBlock(block)CodeBlock
isFormBlock(block)FormBlock
example.ts
import {
  extractBlocks,
  isTableBlock,
  isChartBlock,
  isTransactionActionBlock,
} from '@chaoslabs/ai-sdk';
 
for (const block of extractBlocks(response)) {
  if (isTableBlock(block)) {
    console.log('Table:', block.title, block.tableHeaders);
  } else if (isChartBlock(block)) {
    console.log('Chart:', block.title, block.series.length, 'series');
  } else if (isTransactionActionBlock(block)) {
    console.log('Action:', block.primitives.length, 'primitives');
  }
}

See Helper Functions for block extraction, search, table/chart/risk utilities, and block statistics.

Was this helpful?