Portfolio Analysis

Updated

This recipe demonstrates how to use WALLET_MODEL for portfolio analysis. You will extract table blocks, convert them to structured objects, and work with chart data including pie chart percentages.

Full Example

portfolio.ts
import {
  Chaos,
  WALLET_MODEL,
  extractTableBlocks,
  extractChartBlocks,
  tableToObjects,
  getTableColumn,
  findTableByTitle,
  getTableDimensions,
  getChartData,
  getChartPercentages,
  getChartTotal,
  findChartByTitle,
  isPieChartBlock,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
// Step 1: Request portfolio analysis
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Analyze the portfolio for 0xYourWallet on Ethereum',
    },
  ],
  metadata: {
    user_id: 'user-123',
    session_id: 'session-portfolio',
  },
});
 
// Step 2: Extract and parse tables
const tables = extractTableBlocks(response);
console.log(`Found ${tables.length} table(s)`);
 
for (const table of tables) {
  console.log(`\nTable: ${table.title}`);
  const { columns, rows } = getTableDimensions(table);
  console.log(`  Dimensions: ${columns} columns x ${rows} rows`);
  console.log(`  Headers: ${table.tableHeaders.join(', ')}`);
 
  // Convert to typed objects
  interface PortfolioRow {
    Asset: string;
    Balance: string;
    Value: string;
    Allocation: string;
  }
  const data = tableToObjects<PortfolioRow>(table);
  for (const row of data) {
    console.log(`  ${row.Asset}: ${row.Balance} ($${row.Value})`);
  }
}
 
// Step 3: Find a specific table by title
const holdingsTable = findTableByTitle(response, 'holdings');
if (holdingsTable) {
  // Extract a single column
  const assets = getTableColumn(holdingsTable, 'Asset');
  console.log('Assets in portfolio:', assets);
}
 
// Step 4: Extract and parse charts
const charts = extractChartBlocks(response);
console.log(`\nFound ${charts.length} chart(s)`);
 
for (const chart of charts) {
  console.log(`\nChart: ${chart.title} (${chart.type})`);
 
  // Pie charts support getChartData and getChartPercentages
  if (isPieChartBlock(chart)) {
    const data = getChartData(chart);
    const total = getChartTotal(chart);
    const percentages = getChartPercentages(chart);
 
    console.log(`  Total value: $${total}`);
    for (const item of percentages) {
      console.log(`  ${item.label}: ${item.percentage.toFixed(1)}%`);
    }
  }
}
 
// Step 5: Find a chart by title
const allocationChart = findChartByTitle(response, 'allocation');
if (allocationChart && isPieChartBlock(allocationChart)) {
  const top = getChartPercentages(allocationChart)
    .sort((a, b) => b.percentage - a.percentage)
    .slice(0, 3);
  console.log('\nTop 3 allocations:', top);
}

Working with Tables

Convert to Objects

tableToObjects maps each row to an object keyed by header names. Use a TypeScript interface for full type safety.

table-objects.ts
import { extractTableBlocks, tableToObjects } from '@chaoslabs/ai-sdk';
 
interface TokenHolding {
  Token: string;
  Amount: string;
  'USD Value': string;
  Chain: string;
}
 
const tables = extractTableBlocks(response);
if (tables.length > 0) {
  const holdings = tableToObjects<TokenHolding>(tables[0]);
 
  // Now fully typed
  for (const h of holdings) {
    console.log(`${h.Token} on ${h.Chain}: ${h.Amount} ($${h['USD Value']})`);
  }
}

Extract a Column

getTableColumn returns all values for a named column as unknown[].

table-column.ts
import { extractTableBlocks, getTableColumn, findTableRow } from '@chaoslabs/ai-sdk';
 
const table = extractTableBlocks(response)[0];
if (table) {
  const values = getTableColumn(table, 'USD Value') as string[];
  console.log('All USD values:', values);
 
  // Find a specific row by column match
  const ethRow = findTableRow(table, 'Token', 'ETH');
  if (ethRow) {
    console.log('ETH row:', ethRow);
  }
}

Working with Charts

Chart blocks come in three types: pie_chart, bar_chart, and timeseries_chart. The getChartData, getChartTotal, and getChartPercentages utilities work with PieChartBlock. Use the isPieChartBlock, isBarChartBlock, and isTimeseriesChartBlock type guards to narrow.

charts.ts
import {
  extractChartBlocks,
  isPieChartBlock,
  isBarChartBlock,
  isTimeseriesChartBlock,
  getChartData,
  getChartPercentages,
} from '@chaoslabs/ai-sdk';
 
for (const chart of extractChartBlocks(response)) {
  if (isPieChartBlock(chart)) {
    const pcts = getChartPercentages(chart);
    console.log('Pie chart:', pcts);
  } else if (isBarChartBlock(chart)) {
    console.log('Bar chart:', chart.title, chart.series);
  } else if (isTimeseriesChartBlock(chart)) {
    console.log('Timeseries:', chart.title, chart.series);
  }
}
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop
Was this helpful?