import React, { useState, useEffect } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Checkbox } from '@/components/ui/checkbox' import { Input } from '@/components/ui/input' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' import { MultiSelect } from '@/components/ui/multi-select' import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import { Button } from '@/components/ui/button' import { ChevronDown, ChevronRight } from 'lucide-react' import { mockData } from './lib/data' export interface Model { name: string inputPrice: number outputPrice: number } export interface Provider { provider: string uri: string models: Model[] } const App: React.FC = () => { const [data, setData] = useState([]) const [comparisonModels, setComparisonModels] = useState([]) const [inputTokens, setInputTokens] = useState(1) const [outputTokens, setOutputTokens] = useState(1) const [selectedProviders, setSelectedProviders] = useState([]) const [selectedModels, setSelectedModels] = useState([]) const [expandedProviders, setExpandedProviders] = useState([]) useEffect(() => { setData(mockData) setComparisonModels(['OpenAI:GPT-4o', 'Anthropic:Claude 3.5 (Sonnet)', 'Google:Gemini 1.5 Pro']) }, []) const calculatePrice = (price: number, tokens: number): number => { return price * tokens } const calculateComparison = (modelPrice: number, comparisonPrice: number): string => { return (((modelPrice - comparisonPrice) / comparisonPrice) * 100).toFixed(2) } const filteredData = data .filter((provider) => selectedProviders.length === 0 || selectedProviders.includes(provider.provider)) .map((provider) => ({ ...provider, models: provider.models.filter((model) => selectedModels.length === 0 || selectedModels.includes(model.name)), })) .filter((provider) => provider.models.length > 0) console.log(filteredData) const toggleProviderExpansion = (provider: string) => { setExpandedProviders((prev) => (prev.includes(provider) ? prev.filter((p) => p !== provider) : [...prev, provider])) } return ( LLM Pricing Comparison Tool

Select Comparison Models

{data.map((provider) => ( toggleProviderExpansion(provider.provider)} > {provider.models.map((model) => (
{ if (checked) { setComparisonModels((prev) => [...prev, `${provider.provider}:${model.name}`]) } else { setComparisonModels((prev) => prev.filter((m) => m !== `${provider.provider}:${model.name}`) ) } }} />
))}
))}
setInputTokens(Number(e.target.value))} className="mt-1" />
setOutputTokens(Number(e.target.value))} className="mt-1" />

Note: If you use Amazon Bedrock or Azure prices for Anthropic, Cohere or OpenAI should be the same.

Provider Model Input Price (per 1M tokens) Output Price (per 1M tokens) Total Price {comparisonModels.map((model) => ( Compared to {model} ))} ({ label: provider.provider, value: provider.provider })) || []} onValueChange={setSelectedProviders} defaultValue={selectedProviders} /> provider.models) .map((model) => ({ label: model.name, value: model.name })) .reduce((acc: { label: string; value: string }[], curr: { label: string; value: string }) => { if (!acc.find((m) => m.value === curr.value)) { acc.push(curr) } return acc }, []) || [] } defaultValue={selectedModels} onValueChange={setSelectedModels} /> {comparisonModels.flatMap((model) => [ Input, Output, ])} {filteredData.flatMap((provider) => provider.models.map((model) => ( {' '} {provider.provider} {model.name} ${model.inputPrice.toFixed(2)} ${model.outputPrice.toFixed(2)} $ {( calculatePrice(model.inputPrice, inputTokens) + calculatePrice(model.outputPrice, outputTokens) ).toFixed(2)} {comparisonModels.flatMap((comparisonModel) => { const [comparisonProvider, comparisonModelName] = comparisonModel.split(':') const comparisonModelData = data .find((p) => p.provider === comparisonProvider) ?.models.find((m) => m.name === comparisonModelName)! return [ 0 ? 'bg-red-100' : '' }`} > {`${provider.provider}:${model.name}` === comparisonModel ? '0.00%' : `${calculateComparison(model.inputPrice, comparisonModelData.inputPrice)}%`} , 0 ? 'bg-red-100' : '' }`} > {`${provider.provider}:${model.name}` === comparisonModel ? '0.00%' : `${calculateComparison(model.outputPrice, comparisonModelData.outputPrice)}%`} , ] })} )) )}
) } export default App