Presidentlin commited on
Commit
f39f6c2
·
1 Parent(s): f54e377
src/App.tsx CHANGED
@@ -7,8 +7,10 @@ import { mockData } from "@/lib/data";
7
 
8
  import { ComparisonSelector } from "@/components/ComparisonSelector";
9
  import { PricingTable } from "@/components/PricingTable";
10
- import { benchmarkData } from "./lib/benchmarks/ index";
11
  import { BenchmarkTable } from "./components/BenchmarkTable";
 
 
12
 
13
 
14
  export interface FlattenedModel extends Model {
@@ -41,33 +43,49 @@ const App: React.FC = () => {
41
  const [expandedProviders, setExpandedProviders] = useState<string[]>([]);
42
  const [tokenCalculation, setTokenCalculation] = useState<string>("million");
43
  const [linkProviderModel, setLinkProviderModel] = useState<boolean>(false);
44
- const [benchmarkSortKey, setBenchmarkSortKey] = useState<string | null>(null);
 
 
 
 
45
 
46
  const [sortConfig, setSortConfig] = useState<{
47
  key: keyof FlattenedModel;
48
  direction: string;
49
  } | null>(null);
50
 
 
 
 
 
 
 
51
  useEffect(() => {
52
  setData(mockData);
53
  }, []);
54
 
55
- const normalize = (str: string) => str.toLowerCase().replace(/[^a-z0-9]/g, "");
56
-
57
- const flattenData = (data: Provider[]): FlattenedModel[] =>
58
- data.flatMap((provider) =>
59
- provider.models.map((model) => {
60
- const matchedBenchmark = benchmarkData.find(
61
- (b) => normalize(b.model) === normalize(model.name)
62
- );
63
- return {
64
- provider: provider.provider,
65
- uri: provider.uri,
66
- ...model,
67
- benchmark: matchedBenchmark?.benchmark ?? {},
68
- };
69
- })
70
- );
 
 
 
 
 
 
71
 
72
  const filteredData = useMemo(() => {
73
  if (!selectedProviders.length && !selectedModels.length && !linkProviderModel) return data;
@@ -85,26 +103,82 @@ const App: React.FC = () => {
85
  .filter((p) => p.models.length > 0);
86
  }, [data, selectedProviders, selectedModels, linkProviderModel]);
87
 
88
- const benchmarkedModels = useMemo(() => {
89
- const flattened = flattenData(data); // all models, with benchmark lookup
90
- return flattened.filter(
91
- (model) => model.benchmark && Object.keys(model.benchmark).length > 0
92
- );
93
- }, [data]);
94
 
95
- const sortedBenchmarkedModels = useMemo(() => {
96
- if (!benchmarkSortKey) return benchmarkedModels;
97
 
98
- return [...benchmarkedModels].sort((a, b) => {
99
- const aVal = a.benchmark?.[benchmarkSortKey] ?? -Infinity;
100
- const bVal = b.benchmark?.[benchmarkSortKey] ?? -Infinity;
101
- return bVal - aVal;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  });
103
- }, [benchmarkedModels, benchmarkSortKey]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
 
106
  const sortedFlattenedData = useMemo(() => {
107
- const flattened = flattenData(filteredData);
108
  if (!sortConfig) return flattened;
109
 
110
  return [...flattened].sort((a, b) => {
@@ -131,21 +205,7 @@ const App: React.FC = () => {
131
  );
132
  };
133
 
134
- const getModelsForSelectedProviders = () => {
135
- const allModels = data.flatMap((provider) =>
136
- provider.models.map((model) => ({
137
- label: model.name,
138
- value: model.name,
139
- provider: provider.provider,
140
- }))
141
- );
142
-
143
- const filtered = linkProviderModel
144
- ? allModels.filter((m) => selectedProviders.includes(m.provider))
145
- : allModels;
146
 
147
- return Array.from(new Map(filtered.map((m) => [m.value, m])).values());
148
- };
149
 
150
  return (
151
  <Card className="w-full max-w-6xl mx-auto">
@@ -210,11 +270,61 @@ const App: React.FC = () => {
210
 
211
  {/* Pricing Table */}
212
  <h2 className="text-lg font-semibold mb-2">Pricing Table</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
 
215
  {/* Benchmark Table */}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  <h2 className="text-lg font-semibold mt-12 mb-2">Benchmark Table</h2>
217
- <BenchmarkTable data={sortedBenchmarkedModels} />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  </CardContent>
219
  </Card>
220
  );
 
7
 
8
  import { ComparisonSelector } from "@/components/ComparisonSelector";
9
  import { PricingTable } from "@/components/PricingTable";
10
+
11
  import { BenchmarkTable } from "./components/BenchmarkTable";
12
+ import { benchmarkData } from "./lib/benchmarks/ index";
13
+ import { BenchmarkComparisonSelector } from "./components/BenchmarkComparisonSelector";
14
 
15
 
16
  export interface FlattenedModel extends Model {
 
43
  const [expandedProviders, setExpandedProviders] = useState<string[]>([]);
44
  const [tokenCalculation, setTokenCalculation] = useState<string>("million");
45
  const [linkProviderModel, setLinkProviderModel] = useState<boolean>(false);
46
+ const [benchmarkComparisonMetrics, setBenchmarkComparisonMetrics] = useState<string[]>([]);
47
+ const [selectedBenchmarkProviders, setSelectedBenchmarkProviders] = useState<string[]>([]);
48
+ const [selectedBenchmarkModels, setSelectedBenchmarkModels] = useState<string[]>([]);
49
+ const [linkBenchmarkProviderModel, setLinkBenchmarkProviderModel] = useState<boolean>(false);
50
+
51
 
52
  const [sortConfig, setSortConfig] = useState<{
53
  key: keyof FlattenedModel;
54
  direction: string;
55
  } | null>(null);
56
 
57
+ const [benchmarkSortConfig, setBenchmarkSortConfig] = useState<{
58
+ key: string;
59
+ direction: "ascending" | "descending";
60
+ } | null>(null);
61
+
62
+
63
  useEffect(() => {
64
  setData(mockData);
65
  }, []);
66
 
67
+
68
+ const flattenDataFromPricing = (data: Provider[]): FlattenedModel[] =>
69
+ data.flatMap((provider) =>
70
+ provider.models.map((model) => ({
71
+ provider: provider.provider,
72
+ uri: provider.uri,
73
+ ...model,
74
+ benchmark: {},
75
+ }))
76
+ );
77
+
78
+ const flattenDataFromBenchmarks = (): FlattenedModel[] =>
79
+ benchmarkData.map((b) => ({
80
+ provider: b.provider ?? "Unknown",
81
+ uri: b.source, // placeholder or use an optional `b.link` if available
82
+ name: b.model,
83
+ inputPrice: b.inputPrice,
84
+ outputPrice: b.outputPrice,
85
+ benchmark: b.benchmark ?? {},
86
+ }));
87
+
88
+
89
 
90
  const filteredData = useMemo(() => {
91
  if (!selectedProviders.length && !selectedModels.length && !linkProviderModel) return data;
 
103
  .filter((p) => p.models.length > 0);
104
  }, [data, selectedProviders, selectedModels, linkProviderModel]);
105
 
106
+ const benchmarkedModels = useMemo(() => {
107
+ return flattenDataFromBenchmarks();
108
+ }, []);
 
 
 
109
 
 
 
110
 
111
+
112
+ const filteredBenchmarkedModels = useMemo(() => {
113
+ return benchmarkedModels.filter((model) => {
114
+ const providerMatch =
115
+ selectedBenchmarkProviders.length === 0 || selectedBenchmarkProviders.includes(model.provider);
116
+ const modelMatch =
117
+ selectedBenchmarkModels.length === 0 || selectedBenchmarkModels.includes(model.name);
118
+
119
+ if (linkBenchmarkProviderModel) {
120
+ return providerMatch && modelMatch;
121
+ }
122
+
123
+ // When not linking, allow filtering by either
124
+ if (selectedBenchmarkProviders.length > 0 && selectedBenchmarkModels.length > 0) {
125
+ return providerMatch || modelMatch;
126
+ }
127
+
128
+ return providerMatch && modelMatch; // this handles the case where one or both are empty
129
  });
130
+ }, [
131
+ benchmarkedModels,
132
+ selectedBenchmarkProviders,
133
+ selectedBenchmarkModels,
134
+ linkBenchmarkProviderModel,
135
+ ]);
136
+
137
+
138
+ const sortedBenchmarkedModels = useMemo(() => {
139
+ if (!benchmarkSortConfig) return filteredBenchmarkedModels;
140
+
141
+ return [...benchmarkedModels].sort((a, b) => {
142
+ const key = benchmarkSortConfig.key;
143
+ const aVal = key === "provider" || key === "name"
144
+ ? (a as any)[key]?.toLowerCase?.() ?? ""
145
+ : a.benchmark?.[key] ?? -Infinity;
146
+ const bVal = key === "provider" || key === "name"
147
+ ? (b as any)[key]?.toLowerCase?.() ?? ""
148
+ : b.benchmark?.[key] ?? -Infinity;
149
+
150
+ if (typeof aVal === "string" && typeof bVal === "string") {
151
+ return benchmarkSortConfig.direction === "ascending"
152
+ ? aVal.localeCompare(bVal)
153
+ : bVal.localeCompare(aVal);
154
+ }
155
+
156
+ return benchmarkSortConfig.direction === "ascending"
157
+ ? aVal - bVal
158
+ : bVal - aVal;
159
+ });
160
+ }, [filteredBenchmarkedModels, benchmarkSortConfig]);
161
+
162
+
163
+ const benchmarkProviders = useMemo(() => {
164
+ const modelsInBenchmark = new Set(
165
+ benchmarkedModels.map((m) => `${m.provider}:${m.name}`)
166
+ );
167
+
168
+ return data
169
+ .map((provider) => ({
170
+ ...provider,
171
+ models: provider.models.filter((model) =>
172
+ modelsInBenchmark.has(`${provider.provider}:${model.name}`)
173
+ ),
174
+ }))
175
+ .filter((p) => p.models.length > 0);
176
+ }, [data, benchmarkedModels]);
177
+
178
 
179
 
180
  const sortedFlattenedData = useMemo(() => {
181
+ const flattened = flattenDataFromPricing(filteredData);
182
  if (!sortConfig) return flattened;
183
 
184
  return [...flattened].sort((a, b) => {
 
205
  );
206
  };
207
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
 
 
209
 
210
  return (
211
  <Card className="w-full max-w-6xl mx-auto">
 
270
 
271
  {/* Pricing Table */}
272
  <h2 className="text-lg font-semibold mb-2">Pricing Table</h2>
273
+ <PricingTable
274
+ data={sortedFlattenedData}
275
+ providers={data}
276
+ selectedProviders={selectedProviders}
277
+ selectedModels={selectedModels}
278
+ onProviderChange={setSelectedProviders}
279
+ onModelChange={setSelectedModels}
280
+ comparisonModels={comparisonModels}
281
+ inputTokens={inputTokens}
282
+ outputTokens={outputTokens}
283
+ tokenCalculation={tokenCalculation}
284
+ requestSort={requestSort}
285
+ sortConfig={sortConfig}
286
+ linkProviderModel={linkProviderModel}
287
+ />
288
 
289
 
290
  {/* Benchmark Table */}
291
+ <h3 className="text-lg font-semibold mt-12 mb-2">Select Benchmark Metrics to Compare</h3>
292
+ <BenchmarkComparisonSelector
293
+ allMetrics={Array.from(new Set(benchmarkedModels.flatMap((m) => Object.keys(m.benchmark ?? {})))).sort()}
294
+ selected={benchmarkComparisonMetrics}
295
+ onChange={(metric, checked) =>
296
+ setBenchmarkComparisonMetrics((prev) =>
297
+ checked ? [...prev, metric] : prev.filter((m) => m !== metric)
298
+ )
299
+ }
300
+ />
301
+
302
+
303
+
304
+
305
+
306
  <h2 className="text-lg font-semibold mt-12 mb-2">Benchmark Table</h2>
307
+ <BenchmarkTable
308
+ data={sortedBenchmarkedModels}
309
+ comparisonMetrics={benchmarkComparisonMetrics}
310
+ requestSort={(key) => {
311
+ setBenchmarkSortConfig((prev) =>
312
+ prev?.key === key
313
+ ? { key, direction: prev.direction === "ascending" ? "descending" : "ascending" }
314
+ : { key, direction: "descending" }
315
+ );
316
+ }}
317
+ sortConfig={benchmarkSortConfig}
318
+ allProviders={benchmarkProviders}
319
+ selectedProviders={selectedBenchmarkProviders}
320
+ selectedModels={selectedBenchmarkModels}
321
+ onProviderChange={setSelectedBenchmarkProviders}
322
+ onModelChange={setSelectedBenchmarkModels}
323
+ linkProviderModel={linkBenchmarkProviderModel}
324
+ onLinkToggle={setLinkBenchmarkProviderModel}
325
+ />
326
+
327
+
328
  </CardContent>
329
  </Card>
330
  );
src/components/BenchmarkComparisonSelector.tsx ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // components/BenchmarkComparisonSelector.tsx
2
+ import React from "react";
3
+ import { Checkbox } from "@/components/ui/checkbox";
4
+
5
+ interface Props {
6
+ allMetrics: string[];
7
+ selected: string[];
8
+ onChange: (metric: string, checked: boolean) => void;
9
+ }
10
+
11
+ export const BenchmarkComparisonSelector: React.FC<Props> = ({
12
+ allMetrics,
13
+ selected,
14
+ onChange,
15
+ }) => {
16
+ return (
17
+ <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2 mb-4">
18
+ {allMetrics.map((metric) => (
19
+ <div key={metric} className="flex items-center space-x-2">
20
+ <Checkbox
21
+ id={metric}
22
+ checked={selected.includes(metric)}
23
+ onCheckedChange={(checked) => onChange(metric, !!checked)}
24
+ />
25
+ <label htmlFor={metric} className="text-sm">
26
+ {metric.replace(/_/g, " ").toUpperCase()}
27
+ </label>
28
+ </div>
29
+ ))}
30
+ </div>
31
+ );
32
+ };
src/components/BenchmarkTable.tsx CHANGED
@@ -1,93 +1,183 @@
1
  import * as React from "react";
2
  import {
3
- Table,
4
- TableHeader,
5
- TableBody,
6
- TableRow,
7
- TableHead,
8
- TableCell,
9
  } from "@/components/ui/table";
10
  import { MultiSelect } from "@/components/ui/multi-select";
11
- import { FlattenedModel } from "@/App";
 
12
 
13
  interface BenchmarkTableProps {
14
- data: FlattenedModel[];
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
 
17
- export const BenchmarkTable: React.FC<BenchmarkTableProps> = ({ data }) => {
18
- // Extract all unique benchmark keys
19
- const benchmarkMetrics = React.useMemo(() => {
20
- const allKeys = data.flatMap((model) =>
21
- model.benchmark ? Object.keys(model.benchmark) : []
22
- );
23
- return Array.from(new Set(allKeys)).sort();
24
- }, [data]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- // State: visible metrics
27
- const [visibleMetrics, setVisibleMetrics] = React.useState<string[]>([]);
 
 
 
 
 
 
28
 
29
- // Set default to all if empty on first render
30
- React.useEffect(() => {
31
- if (benchmarkMetrics.length && visibleMetrics.length === 0) {
32
- setVisibleMetrics(benchmarkMetrics);
33
- }
34
- }, [benchmarkMetrics]);
35
 
36
- // Style cells by score
37
- const getCellStyle = (value?: number) => {
38
- if (value === undefined) return "";
39
- if (value >= 85) return "bg-green-100";
40
- if (value >= 60) return "bg-yellow-100";
41
- return "bg-red-100";
42
- };
43
 
44
- return (
45
- <>
46
- <div className="mb-4 max-w-md">
47
- <MultiSelect
48
- options={benchmarkMetrics.map((metric) => ({
49
- label: metric.replace(/_/g, " ").toUpperCase(),
50
- value: metric,
51
- }))}
52
- defaultValue={benchmarkMetrics}
53
- onValueChange={setVisibleMetrics}
54
- placeholder="Select benchmarks to show"
55
- />
56
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
- <Table>
59
- <TableHeader>
60
- <TableRow>
61
- <TableHead>Provider</TableHead>
62
- <TableHead>Model</TableHead>
63
- {visibleMetrics.map((metric) => (
64
- <TableHead key={metric}>
65
- {metric.replace(/_/g, " ").toUpperCase()}
66
- </TableHead>
67
- ))}
68
- </TableRow>
69
- </TableHeader>
70
- <TableBody>
71
- {data.map((model) => (
72
- <TableRow key={`${model.provider}-${model.name}`}>
73
- <TableCell>
74
- <a href={model.uri} className="underline">
75
- {model.provider}
76
- </a>
77
- </TableCell>
78
- <TableCell>{model.name}</TableCell>
79
- {visibleMetrics.map((metric) => {
80
- const score = model.benchmark?.[metric];
81
- return (
82
- <TableCell key={metric} className={getCellStyle(score)}>
83
- {score !== undefined ? `${score.toFixed(1)}%` : "—"}
84
- </TableCell>
85
- );
86
- })}
87
- </TableRow>
88
- ))}
89
- </TableBody>
90
- </Table>
91
- </>
92
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  };
 
1
  import * as React from "react";
2
  import {
3
+ Table,
4
+ TableHeader,
5
+ TableBody,
6
+ TableRow,
7
+ TableHead,
8
+ TableCell,
9
  } from "@/components/ui/table";
10
  import { MultiSelect } from "@/components/ui/multi-select";
11
+ import { Switch } from "@/components/ui/switch";
12
+ import { Provider, FlattenedModel } from "@/App";
13
 
14
  interface BenchmarkTableProps {
15
+ data: FlattenedModel[];
16
+ comparisonMetrics?: string[];
17
+ requestSort: (key: string) => void;
18
+ sortConfig: {
19
+ key: string;
20
+ direction: "ascending" | "descending";
21
+ } | null;
22
+ allProviders: Provider[];
23
+ selectedProviders: string[];
24
+ selectedModels: string[];
25
+ onProviderChange: (values: string[]) => void;
26
+ onModelChange: (values: string[]) => void;
27
+ linkProviderModel: boolean;
28
+ onLinkToggle: (checked: boolean) => void;
29
  }
30
 
31
+ export const BenchmarkTable: React.FC<BenchmarkTableProps> = ({
32
+ data,
33
+ comparisonMetrics,
34
+ requestSort,
35
+ sortConfig,
36
+ allProviders,
37
+ selectedProviders,
38
+ selectedModels,
39
+ onProviderChange,
40
+ onModelChange,
41
+ linkProviderModel,
42
+ onLinkToggle,
43
+ }) => {
44
+ const benchmarkMetrics = React.useMemo(() => {
45
+ if (!comparisonMetrics || comparisonMetrics.length === 0) return [];
46
+ return comparisonMetrics;
47
+ }, [comparisonMetrics]);
48
+
49
+ const getCellStyle = (value?: number) => {
50
+ if (value === undefined) return "";
51
+ if (value >= 85) return "bg-green-100";
52
+ if (value >= 60) return "bg-yellow-100";
53
+ return "bg-red-100";
54
+ };
55
+
56
+ const renderSortIndicator = (key: string) => {
57
+ if (sortConfig?.key !== key) return null;
58
+ return sortConfig.direction === "ascending" ? " ▲" : " ▼";
59
+ };
60
 
61
+ const modelOptions = React.useMemo(() => {
62
+ const flat = allProviders.flatMap((provider) =>
63
+ provider.models.map((model) => ({
64
+ label: model.name,
65
+ value: model.name,
66
+ provider: provider.provider,
67
+ }))
68
+ );
69
 
70
+ const filtered = linkProviderModel
71
+ ? flat.filter((m) => selectedProviders.includes(m.provider))
72
+ : flat;
 
 
 
73
 
74
+ return Array.from(new Map(filtered.map((m) => [m.value, m])).values());
75
+ }, [allProviders, selectedProviders, linkProviderModel]);
 
 
 
 
 
76
 
77
+ return (
78
+ <>
79
+ <div className="flex items-center space-x-4 mb-4">
80
+ <div className="flex-1">
81
+ <label className="text-sm font-medium block mb-1">Providers</label>
82
+ <MultiSelect
83
+ options={allProviders.map((p) => ({ label: p.provider, value: p.provider }))}
84
+ defaultValue={selectedProviders}
85
+ onValueChange={onProviderChange}
86
+ />
87
+ </div>
88
+ <div className="flex-1">
89
+ <label className="text-sm font-medium block mb-1">Models</label>
90
+ <MultiSelect
91
+ options={modelOptions.map(({ label, value }) => ({ label, value }))}
92
+ defaultValue={selectedModels}
93
+ onValueChange={onModelChange}
94
+ />
95
+ </div>
96
+ <div className="flex items-center pt-6 space-x-2">
97
+ <Switch
98
+ id="linkBenchmarkProviderModel"
99
+ checked={linkProviderModel}
100
+ onCheckedChange={onLinkToggle}
101
+ />
102
+ <label htmlFor="linkBenchmarkProviderModel" className="text-sm">
103
+ Link Provider and Model
104
+ </label>
105
+ </div>
106
+ </div>
107
 
108
+ <Table>
109
+ <TableHeader>
110
+ <TableRow>
111
+ <TableHead>
112
+ <button
113
+ onClick={() => requestSort("provider")}
114
+ className="font-medium underline underline-offset-2"
115
+ >
116
+ Provider{renderSortIndicator("provider")}
117
+ </button>
118
+ </TableHead>
119
+ <TableHead>
120
+ <button
121
+ onClick={() => requestSort("name")}
122
+ className="font-medium underline underline-offset-2"
123
+ >
124
+ Model{renderSortIndicator("name")}
125
+ </button>
126
+ </TableHead>
127
+ <TableHead>
128
+ <button
129
+ onClick={() => requestSort("inputPrice")}
130
+ className="font-medium underline underline-offset-2"
131
+ >
132
+ Input Price (USD){renderSortIndicator("inputPrice")}
133
+ </button>
134
+ </TableHead>
135
+ <TableHead>
136
+ <button
137
+ onClick={() => requestSort("outputPrice")}
138
+ className="font-medium underline underline-offset-2"
139
+ >
140
+ Output Price (USD){renderSortIndicator("outputPrice")}
141
+ </button>
142
+ </TableHead>
143
+
144
+ {benchmarkMetrics.map((metric) => (
145
+ <TableHead key={metric}>
146
+ <button
147
+ onClick={() => requestSort(metric)}
148
+ className="font-medium underline underline-offset-2"
149
+ >
150
+ {metric.replace(/_/g, " ").toUpperCase()}
151
+ {renderSortIndicator(metric)}
152
+ </button>
153
+ </TableHead>
154
+ ))}
155
+ </TableRow>
156
+ </TableHeader>
157
+ <TableBody>
158
+ {data.map((model) => (
159
+ <TableRow key={`${model.provider}-${model.name}`}>
160
+ <TableCell>
161
+ <a href={model.uri} className="underline">
162
+ {model.provider}
163
+ </a>
164
+ </TableCell>
165
+ <TableCell>{model.name}</TableCell>
166
+ <TableCell>${model.inputPrice.toFixed(2)}</TableCell>
167
+ <TableCell>${model.outputPrice.toFixed(2)}</TableCell>
168
+
169
+ {benchmarkMetrics.map((metric) => {
170
+ const score = model.benchmark?.[metric];
171
+ return (
172
+ <TableCell key={metric} className={getCellStyle(score)}>
173
+ {score !== undefined ? `${score.toFixed(1)}%` : "-"}
174
+ </TableCell>
175
+ );
176
+ })}
177
+ </TableRow>
178
+ ))}
179
+ </TableBody>
180
+ </Table>
181
+ </>
182
+ );
183
  };
src/lib/benchmarks/google.ts CHANGED
@@ -2,36 +2,42 @@ import { Benchmark } from "./types";
2
 
3
 
4
  export const googleBenchmarks: Benchmark[] = [
5
- {
6
- model: "Gemini Diffusion",
7
- benchmark: {
8
- livecodebench_v6: 30.9,
9
- bigcodebench: 45.4,
10
- lbpp_v2: 56.8,
11
- swe_bench_verified: 22.9,
12
- humaneval: 89.6,
13
- mbpp: 76.0,
14
- gpqa_diamond: 40.4,
15
- aime_2025: 23.3,
16
- bigbench_extra_hard: 15.0,
17
- global_mmlu_lite: 69.1,
 
 
 
 
 
18
  },
19
- source: "Google Gemini site",
20
- },
21
- {
22
- model: "Gemini 2.0 Flash-Lite",
23
- benchmark: {
24
- livecodebench_v6: 28.5,
25
- bigcodebench: 45.8,
26
- lbpp_v2: 56.0,
27
- swe_bench_verified: 28.5,
28
- humaneval: 90.2,
29
- mbpp: 75.8,
30
- gpqa_diamond: 56.5,
31
- aime_2025: 20.0,
32
- bigbench_extra_hard: 21.0,
33
- global_mmlu_lite: 79.0,
 
 
 
34
  },
35
- source: "Google Gemini site",
36
- },
37
  ];
 
2
 
3
 
4
  export const googleBenchmarks: Benchmark[] = [
5
+ {
6
+ model: "Gemini Diffusion",
7
+ provider: "Google",
8
+ inputPrice: 0,
9
+ outputPrice: 0,
10
+ benchmark: {
11
+ livecodebench_v6: 30.9,
12
+ bigcodebench: 45.4,
13
+ lbpp_v2: 56.8,
14
+ swe_bench_verified: 22.9,
15
+ humaneval: 89.6,
16
+ mbpp: 76.0,
17
+ gpqa_diamond: 40.4,
18
+ aime_2025: 23.3,
19
+ bigbench_extra_hard: 15.0,
20
+ global_mmlu_lite: 69.1,
21
+ },
22
+ source: "https://deepmind.google/models/gemini-diffusion/",
23
  },
24
+ {
25
+ model: "Gemini 2.0 Flash-Lite",
26
+ provider: "Google",
27
+ inputPrice: 0.10,
28
+ outputPrice: 0.40,
29
+ benchmark: {
30
+ livecodebench_v6: 28.5,
31
+ bigcodebench: 45.8,
32
+ lbpp_v2: 56.0,
33
+ swe_bench_verified: 28.5,
34
+ humaneval: 90.2,
35
+ mbpp: 75.8,
36
+ gpqa_diamond: 56.5,
37
+ aime_2025: 20.0,
38
+ bigbench_extra_hard: 21.0,
39
+ global_mmlu_lite: 79.0,
40
+ },
41
+ source: "https://deepmind.google/models/gemini-diffusion/",
42
  },
 
 
43
  ];
src/lib/benchmarks/types.ts CHANGED
@@ -20,7 +20,10 @@ export type BenchmarkMetric =
20
 
21
  export interface Benchmark {
22
  model: string;
 
23
  benchmark: Partial<Record<BenchmarkMetric, number>>;
24
- source?: string;
 
 
25
  version?: string;
26
  }
 
20
 
21
  export interface Benchmark {
22
  model: string;
23
+ provider: string;
24
  benchmark: Partial<Record<BenchmarkMetric, number>>;
25
+ inputPrice: number;
26
+ outputPrice: number;
27
+ source: string;
28
  version?: string;
29
  }
src/lib/benchmarks/xai.ts CHANGED
@@ -2,32 +2,38 @@ import { Benchmark } from "./types";
2
 
3
 
4
  export const xaiBenchmarks: Benchmark[] = [
5
- {
6
- model: "Grok 3 Beta",
7
- benchmark: {
8
- aime_24: 52.2,
9
- gpqa: 75.4,
10
- lcb: 57.0,
11
- mmlu_pro: 79.9,
12
- loft: 83.3,
13
- simpleqa: 43.6,
14
- mmmu: 73.2,
15
- egoschema: 74.5,
 
 
 
 
 
16
  },
17
- source: "x.ai blog",
18
- },
19
  {
20
- model: "Grok 3 mini Beta",
21
- benchmark: {
22
- aime_24: 39.7,
23
- gpqa: 66.2,
24
- lcb: 41.5,
25
- mmlu_pro: 78.9,
26
- loft: 83.1,
27
- simpleqa: 21.7,
28
- mmmu: 69.4,
29
- egoschema: 74.3,
 
 
 
 
 
30
  },
31
- source: "x.ai blog",
32
- },
33
  ];
 
2
 
3
 
4
  export const xaiBenchmarks: Benchmark[] = [
5
+ {
6
+ model: "Grok 3 Beta",
7
+ provider: "Xai",
8
+ inputPrice: 3.00,
9
+ outputPrice: 15.00,
10
+ benchmark: {
11
+ aime_24: 52.2,
12
+ gpqa: 75.4,
13
+ lcb: 57.0,
14
+ mmlu_pro: 79.9,
15
+ loft: 83.3,
16
+ simpleqa: 43.6,
17
+ mmmu: 73.2,
18
+ egoschema: 74.5,
19
+ },
20
+ source: "https://x.ai/news/grok-3",
21
  },
 
 
22
  {
23
+ model: "Grok 3 mini Beta",
24
+ provider: "Xai",
25
+ inputPrice: 0.30,
26
+ outputPrice: 0.50,
27
+ benchmark: {
28
+ aime_24: 39.7,
29
+ gpqa: 66.2,
30
+ lcb: 41.5,
31
+ mmlu_pro: 78.9,
32
+ loft: 83.1,
33
+ simpleqa: 21.7,
34
+ mmmu: 69.4,
35
+ egoschema: 74.3,
36
+ },
37
+ source: "https://x.ai/news/grok-3",
38
  },
 
 
39
  ];