"use client"; import { makeAssistantToolUI } from "@assistant-ui/react"; import { z } from "zod"; import { cn } from "@/lib/utils"; import { Shield, TrendingUp, TrendingDown, Users, AlertTriangle, Star, Bell, ExternalLink } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { ChainIcon } from "@/components/crypto/ChainIcon"; import { SafetyBadge } from "@/components/crypto/SafetyBadge"; // Schema for token analysis tool arguments export const TokenAnalysisArgsSchema = z.object({ symbol: z.string(), name: z.string().optional(), chain: z.string(), contractAddress: z.string().optional(), price: z.number(), priceChange24h: z.number(), marketCap: z.number().optional(), volume24h: z.number().optional(), liquidity: z.number().optional(), safetyScore: z.number().optional(), holderCount: z.number().optional(), top10HolderPercent: z.number().optional(), }); export type TokenAnalysisArgs = z.infer; // Schema for token analysis result export const TokenAnalysisResultSchema = z.object({ success: z.boolean(), message: z.string().optional(), isInWatchlist: z.boolean().optional(), }); export type TokenAnalysisResult = z.infer; const formatPrice = (price: number): string => { if (price < 0.00001) return `$${price.toExponential(2)}`; if (price < 1) return `$${price.toFixed(6)}`; return `$${price.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; }; const formatLargeNumber = (num: number): string => { if (num >= 1e9) return `$${(num / 1e9).toFixed(2)}B`; if (num >= 1e6) return `$${(num / 1e6).toFixed(2)}M`; if (num >= 1e3) return `$${(num / 1e3).toFixed(2)}K`; return `$${num.toFixed(2)}`; }; /** * TokenAnalysisToolUI - Displays comprehensive token analysis in chat * Used when AI responds to token research queries like "analyze BULLA" or "is BULLA safe?" */ export const TokenAnalysisToolUI = makeAssistantToolUI({ toolName: "analyze_token", render: ({ args, result, status }) => { const isLoading = status.type === "running"; const isInWatchlist = result?.isInWatchlist ?? false; const handleOpenDexScreener = () => { if (args.contractAddress) { window.open(`https://dexscreener.com/${args.chain}/${args.contractAddress}`, "_blank"); } }; return ( 📊 Token Analysis {isLoading && Analyzing...} {/* Token Header */}
{args.symbol} {args.name && {args.name}}
{formatPrice(args.price)} = 0 ? "text-green-500" : "text-red-500" )}> {args.priceChange24h >= 0 ? : } {args.priceChange24h >= 0 ? "+" : ""}{args.priceChange24h.toFixed(2)}%
{args.safetyScore !== undefined && ( )}
{/* Metrics Grid */}
{args.marketCap && (

Market Cap

{formatLargeNumber(args.marketCap)}

)} {args.volume24h && (

24h Volume

{formatLargeNumber(args.volume24h)}

)} {args.liquidity && (

Liquidity

{formatLargeNumber(args.liquidity)}

)} {args.holderCount && (

Holders

{args.holderCount.toLocaleString()}

)}
{/* Holder Concentration Warning */} {args.top10HolderPercent && args.top10HolderPercent > 50 && (
Top 10 holders own {args.top10HolderPercent}% of supply - high concentration risk
)} {/* Action Buttons */}
); }, });