logo
Casey AIWidgets

Widgets

Casey emits lightweight widget hints — the frontend owns rendering and data fetching.

When Casey thinks a visual component would help, it emits a widget SSE event with a hint — just the widget type and a minimal identifier. The frontend is fully responsible for rendering the widget and fetching any data it needs.

Casey does NOT send widget data. It sends a type and an identifier. The frontend renders the component using its own data-fetching hooks.

Widget Hint Format

Every widget event arrives as:

data: {"type": "widget", "widget": {"type": "deal_card", "dealId": 123}}

The widget object always has a type field, plus optional identifiers depending on the widget type.

Widget Types

deal_card

An interactive deal card shown when Casey is discussing a specific deal.

{ "type": "deal_card", "dealId": 123 }
FieldTypeDescription
type"deal_card"Widget type
dealIdnumberThe deal's database ID

Frontend: Fetch deal data using the deal ID and render a deal card component.


founder_card

A single rich founder card shown when Casey is discussing a deal's founders. Displays founder name, title, description, and social media link. Casey emits one founder_card widget per founder — a deal with 3 founders produces 3 separate widget events.

{ "type": "founder_card", "dealId": 123, "founderId": 456 }
FieldTypeDescription
type"founder_card"Widget type
dealIdnumberThe deal's database ID
founderIdnumberThe founder's person ID (person.id)

Frontend: Fetch the specific founder's data using founderId (and optionally dealId for context) and render a single founder card (name, title, bio, social link). Multiple founder_card widgets for the same deal should be rendered side by side.


investment_summary

Shows the user's investment details for a specific investment.

{ "type": "investment_summary", "investmentId": 456 }
FieldTypeDescription
type"investment_summary"Widget type
investmentIdnumberThe investment's database ID

Frontend: Fetch investment data and render an investment summary card.


portfolio_overview

Shows the user's overall portfolio summary.

{ "type": "portfolio_overview" }
FieldTypeDescription
type"portfolio_overview"Widget type

Frontend: Fetch portfolio data and render the portfolio overview component. No identifier needed — it's scoped to the current user.


support

Shows a support/help prompt with a contextual message.

{
  "type": "support",
  "message": "Need help with your payment? Contact our team."
}
FieldTypeDescription
type"support"Widget type
messagestringA short, contextual message to display in the widget

Frontend: Render a support widget/card with the provided message and a link to contact support.


TypeScript Types

type CaseyWidgetHint =
  | { type: "deal_card"; dealId: number }
  | { type: "founder_card"; dealId: number; founderId: number }
  | { type: "investment_summary"; investmentId: number }
  | { type: "portfolio_overview" }
  | { type: "support"; message: string };

Rendering Strategy

Widgets should be rendered inline within the chat message where they appear. A simple approach:

function ChatMessage({ message, widgets }: ChatMessageProps) {
  return (
    <div>
      <Markdown>{message.content}</Markdown>
      {widgets?.map((hint, i) => (
        <WidgetRenderer key={i} hint={hint} />
      ))}
    </div>
  );
}

function WidgetRenderer({ hint }: { hint: CaseyWidgetHint }) {
  switch (hint.type) {
    case 'deal_card':
      return <DealCard dealId={hint.dealId} />;
    case 'founder_card':
      return <FounderCard dealId={hint.dealId} founderId={hint.founderId} />;
    case 'investment_summary':
      return <InvestmentSummary investmentId={hint.investmentId} />;
    case 'portfolio_overview':
      return <PortfolioOverview />;
    case 'support':
      return <SupportCard message={hint.message} />;
    default:
      return null; // Gracefully ignore unknown types
  }
}

Always handle unknown widget types with a fallback. Casey may add new widget types in the future, and the frontend should degrade gracefully.

During Streaming vs. History

  • During streaming: Widget hints arrive as real-time widget SSE events. Render them as they arrive.
  • From conversation history: Widget hints are stored in the widgets array on assistant messages (see Conversations). Render them alongside the message content.
Was this page helpful?

Last updated Mar 26, 2026

Built with Documentation.AI