Type Guards

Updated

The SDK exports 47 runtime type guards for narrowing discriminated union types. After a guard returns true, TypeScript automatically infers the specific type, giving you full autocomplete and type safety.

All guards are exported from the package root.

import.ts
import {
  // Primitive guards
  isSwapPrimitive,
  isLendingDepositPrimitive,
  // Block guards
  isTableBlock,
  isChartBlock,
  // Chart subtype guards
  isPieChartBlock,
  // Message guards
  isAgentMessage,
  isBlock,
} from '@chaoslabs/ai-sdk';

Primitive Type Guards (33)

Each primitive type guard narrows a Primitive union to its specific member type. They all follow the same signature pattern:

typescript
function is<Name>Primitive(p: Primitive): p is <Name>Primitive

Base (3)

GuardNarrows ToMatches
isSwapPrimitive(p)SwapPrimitivep.type === 'swap'
isBridgePrimitive(p)BridgePrimitivep.type === 'bridge'
isTransferTypedPrimitive(p)TransferPrimitivep.type === 'transfer'
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop

Lending (5)

GuardNarrows ToMatches
isLendingDepositPrimitive(p)LendingDepositPrimitivep.type === 'lending_deposit'
isLendingWithdrawPrimitive(p)LendingWithdrawPrimitivep.type === 'lending_withdraw'
isLendingBorrowPrimitive(p)LendingBorrowPrimitivep.type === 'lending_borrow'
isLendingRepayPrimitive(p)LendingRepayPrimitivep.type === 'lending_repay'
isLendingClaimRewardsPrimitive(p)LendingClaimRewardsPrimitivep.type === 'lending_claim_rewards'

Staking (8)

GuardNarrows ToMatches
isStakingStakePrimitive(p)StakingStakePrimitivep.type === 'staking_stake'
isStakingUnstakePrimitive(p)StakingUnstakePrimitivep.type === 'staking_unstake'
isStakingClaimPrimitive(p)StakingClaimPrimitivep.type === 'staking_claim'
isStakingCooldownPrimitive(p)StakingCooldownPrimitivep.type === 'staking_cooldown'
isStakingDelegatePrimitive(p)StakingDelegatePrimitivep.type === 'staking_delegate'
isStakingUndelegatePrimitive(p)StakingUndelegatePrimitivep.type === 'staking_undelegate'
isStakingWrapPrimitive(p)StakingWrapPrimitivep.type === 'staking_wrap'
isStakingUnwrapPrimitive(p)StakingUnwrapPrimitivep.type === 'staking_unwrap'

Pendle (6)

GuardNarrows ToMatches
isPendleAddLiquidityPrimitive(p)PendleAddLiquidityPrimitivep.type === 'pendle_add_liquidity'
isPendleRemoveLiquidityPrimitive(p)PendleRemoveLiquidityPrimitivep.type === 'pendle_remove_liquidity'
isPendleMintPtYtPrimitive(p)PendleMintPtYtPrimitivep.type === 'pendle_mint_pt_yt'
isPendleRedeemPrimitive(p)PendleRedeemPrimitivep.type === 'pendle_redeem'
isPendleSwapToPtPrimitive(p)PendleSwapToPtPrimitivep.type === 'pendle_swap_to_pt'
isPendleSwapToYtPrimitive(p)PendleSwapToYtPrimitivep.type === 'pendle_swap_to_yt'

Perpetuals (7)

GuardNarrows ToMatches
isPerpOpenPrimitive(p)PerpOpenPrimitivep.type === 'perp_open'
isPerpClosePrimitive(p)PerpClosePrimitivep.type === 'perp_close'
isPerpIncreasePrimitive(p)PerpIncreasePrimitivep.type === 'perp_increase'
isPerpDecreasePrimitive(p)PerpDecreasePrimitivep.type === 'perp_decrease'
isPerpDepositPrimitive(p)PerpDepositPrimitivep.type === 'perp_deposit'
isPerpWithdrawPrimitive(p)PerpWithdrawPrimitivep.type === 'perp_withdraw'
isPerpSetLeveragePrimitive(p)PerpSetLeveragePrimitivep.type === 'perp_set_leverage'

Vault (4)

GuardNarrows ToMatches
isVaultDepositPrimitive(p)VaultDepositPrimitivep.type === 'vault_deposit'
isVaultWithdrawPrimitive(p)VaultWithdrawPrimitivep.type === 'vault_withdraw'
isVaultBorrowPrimitive(p)VaultBorrowPrimitivep.type === 'vault_borrow'
isVaultRepayPrimitive(p)VaultRepayPrimitivep.type === 'vault_repay'

Primitive Guard Example

primitive-guard-example.ts
import {
  extractPrimitives,
  isSwapPrimitive,
  isLendingDepositPrimitive,
  isPerpOpenPrimitive,
  type Primitive,
} from '@chaoslabs/ai-sdk';
 
const primitives: Primitive[] = extractPrimitives(response);
 
for (const p of primitives) {
  if (isSwapPrimitive(p)) {
    // p is narrowed to SwapPrimitive
    console.log('Swap:', p.params.token_in, '->', p.params.token_out);
  } else if (isLendingDepositPrimitive(p)) {
    // p is narrowed to LendingDepositPrimitive
    console.log('Deposit:', p.params.amount, p.params.asset);
  } else if (isPerpOpenPrimitive(p)) {
    // p is narrowed to PerpOpenPrimitive
    console.log('Open perp:', p.params.side, p.params.size);
  }
}

Block Type Guards (9)

Block guards narrow the Block discriminated union to specific block types.

GuardNarrows ToMatches
isTableBlock(block)TableBlockblock.type === 'table'
isMarkdownBlock(block)MarkdownBlockblock.type === 'markdown'
isTransactionActionBlock(block)ActionBlockblock.type === 'action'
isInteractiveBlock(block)InteractiveBlockblock.type === 'interactive'
isCodeBlock(block)CodeBlockblock.type === 'code'
isFormBlock(block)FormBlockblock.type === 'form'
isChartBlock(block)ChartBlockblock.type === 'pie_chart' | 'bar_chart' | 'timeseries_chart'
isInfoBlock(block)AlertBlockblock.type === 'alert'
isErrorBlock(block)AlertBlock & { severity: 'error' }block.type === 'alert' && block.severity === 'error'
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop

Block Guard Signatures

block-guards.ts
export function isTableBlock(block: Block): block is TableBlock;
export function isMarkdownBlock(block: Block): block is MarkdownBlock;
export function isTransactionActionBlock(block: Block): block is ActionBlock;
export function isInteractiveBlock(block: Block): block is InteractiveBlock;
export function isCodeBlock(block: Block): block is CodeBlock;
export function isFormBlock(block: Block): block is FormBlock;
export function isChartBlock(block: Block): block is ChartBlock;
export function isInfoBlock(block: Block): block is AlertBlock;
export function isErrorBlock(block: Block): block is AlertBlock & { severity: 'error' };

Chart Subtype Guards (3)

Narrow from Block directly to a specific chart type.

GuardNarrows ToMatches
isPieChartBlock(block)PieChartBlockblock.type === 'pie_chart'
isBarChartBlock(block)BarChartBlockblock.type === 'bar_chart'
isTimeseriesChartBlock(block)TimeseriesChartBlockblock.type === 'timeseries_chart'
chart-guards.ts
export function isPieChartBlock(block: Block): block is PieChartBlock;
export function isTimeseriesChartBlock(block: Block): block is TimeseriesChartBlock;
export function isBarChartBlock(block: Block): block is BarChartBlock;

Message Type Guards (2)

Message guards check unknown values (not pre-typed unions), making them safe for validating data from external sources like parsed JSON.

GuardNarrows ToChecks
isAgentMessage(thing)ChaosSDKMessagekind === 'message' and has type string
isBlock(thing)Blockkind === 'block' and has type string
message-guards.ts
export function isAgentMessage(thing: unknown): thing is ChaosSDKMessage;
export function isBlock(thing: unknown): thing is Block;

Message Guard Example

message-guard-example.ts
import { isAgentMessage, isBlock } from '@chaoslabs/ai-sdk';
 
// Validate parsed NDJSON lines during streaming
const parsed: unknown = JSON.parse(line);
 
if (isAgentMessage(parsed)) {
  // parsed is ChaosSDKMessage
  console.log('Message type:', parsed.type);
}
 
if (isBlock(parsed)) {
  // parsed is Block
  console.log('Block type:', parsed.type);
}

Combining Guards

Type guards compose naturally with the block extraction helpers and primitive validators.

combining-guards.ts
import {
  extractBlocks,
  isTableBlock,
  isTransactionActionBlock,
  isSwapPrimitive,
  isPieChartBlock,
} from '@chaoslabs/ai-sdk';
 
const blocks = extractBlocks(response);
 
for (const block of blocks) {
  if (isTableBlock(block)) {
    console.log('Table headers:', block.tableHeaders);
  } else if (isPieChartBlock(block)) {
    console.log('Pie chart series:', block.series.length);
  } else if (isTransactionActionBlock(block)) {
    for (const p of block.primitives ?? []) {
      if (isSwapPrimitive(p)) {
        console.log(`Swap ${p.params.token_in} -> ${p.params.token_out}`);
      }
    }
  }
}
Was this helpful?