"use client"; import { makeAssistantToolUI } from "@assistant-ui/react"; import { z } from "zod"; import { cn } from "@/lib/utils"; import { BarChart3, TrendingUp, TrendingDown, Globe } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; // Schema for market token const MarketTokenSchema = z.object({ symbol: z.string(), name: z.string(), price: z.number(), priceChange24h: z.number(), marketCap: z.number().optional(), volume24h: z.number().optional(), }); // Schema for market overview tool arguments export const MarketOverviewArgsSchema = z.object({ tokens: z.array(MarketTokenSchema), totalMarketCap: z.number().optional(), totalVolume24h: z.number().optional(), btcDominance: z.number().optional(), fearGreedIndex: z.number().optional(), }); export type MarketOverviewArgs = z.infer; // Schema for market overview result export const MarketOverviewResultSchema = z.object({ success: z.boolean(), message: z.string().optional(), }); export type MarketOverviewResult = z.infer; const formatPrice = (price: number): string => { if (price < 1) return `$${price.toFixed(4)}`; return `$${price.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; }; const formatLargeNumber = (num: number): string => { if (num >= 1e12) return `$${(num / 1e12).toFixed(2)}T`; if (num >= 1e9) return `$${(num / 1e9).toFixed(2)}B`; if (num >= 1e6) return `$${(num / 1e6).toFixed(2)}M`; return `$${num.toFixed(2)}`; }; /** * MarketOverviewToolUI - Displays market overview inline in chat * Used when AI responds to "show market overview" or "how's the market?" */ export const MarketOverviewToolUI = makeAssistantToolUI({ toolName: "get_market_overview", render: ({ args, status }) => { const isLoading = status.type === "running"; const tokens = args.tokens || []; return ( Market Overview {isLoading && Loading...} {/* Global Stats */} {(args.totalMarketCap || args.btcDominance || args.fearGreedIndex) && (
{args.totalMarketCap && (

Total Market Cap

{formatLargeNumber(args.totalMarketCap)}

)} {args.totalVolume24h && (

24h Volume

{formatLargeNumber(args.totalVolume24h)}

)} {args.btcDominance && (

BTC Dominance

{args.btcDominance.toFixed(1)}%

)} {args.fearGreedIndex && (
50 ? "bg-green-500/10" : "bg-red-500/10")}>

Fear & Greed

50 ? "text-green-500" : "text-red-500")}> {args.fearGreedIndex} - {args.fearGreedIndex > 75 ? "Extreme Greed" : args.fearGreedIndex > 50 ? "Greed" : args.fearGreedIndex > 25 ? "Fear" : "Extreme Fear"}

)}
)} {/* Token Prices */}
{tokens.map((token) => (

{token.symbol}

{token.name}

{formatPrice(token.price)}

= 0 ? "text-green-500" : "text-red-500")}> {token.priceChange24h >= 0 ? : } {token.priceChange24h >= 0 ? "+" : ""}{token.priceChange24h.toFixed(2)}%

))}
); }, });