refactor(pricing): enhance model filtering and update terminology for clarity

This commit is contained in:
sharath 2025-06-28 15:09:48 +00:00
parent 8a0a8f37b1
commit ca321f7cb2
No known key found for this signature in database
1 changed files with 151 additions and 142 deletions

View File

@ -1,13 +1,6 @@
'use client';
import {
AlertCircle,
Clock,
DollarSign,
Zap,
Server,
Globe,
} from 'lucide-react';
import { AlertCircle, Zap, Server, Globe } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
Card,
@ -16,7 +9,6 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import {
Select,
SelectContent,
@ -27,7 +19,8 @@ import {
import { useAvailableModels } from '@/hooks/react-query/subscriptions/use-billing';
import type { Model } from '@/lib/api';
import { Loader2 } from 'lucide-react';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { useModelSelection } from '@/components/thread/chat-input/_use-model-selection';
// Example task data with token usage
const exampleTasks = [
@ -141,6 +134,8 @@ const exampleTasks = [
},
];
const DISABLE_EXAMPLES = true;
export default function PricingPage() {
const {
data: modelsResponse,
@ -149,13 +144,16 @@ export default function PricingPage() {
refetch,
} = useAvailableModels();
const { allModels } = useModelSelection();
const [selectedModelId, setSelectedModelId] = useState<string>(
'anthropic/claude-sonnet-4-20250514',
);
const [showAllTasks, setShowAllTasks] = useState<boolean>(false);
// Filter to only show models that have pricing information available
const models =
// Filter to only show models that have pricing information available and sort by display name order
const models = useMemo(() => {
const filteredModels =
modelsResponse?.models?.filter((model: Model) => {
return (
model.input_cost_per_million_tokens !== null &&
@ -165,6 +163,15 @@ export default function PricingPage() {
);
}) || [];
return filteredModels
.map((v) => ({
...v,
display_name: allModels.find((m) => m.id === v.short_name)?.label,
priority: allModels.find((m) => m.id === v.short_name)?.priority,
}))
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
}, [modelsResponse?.models, allModels]);
// Find the selected model
const selectedModel = models.find((model) => model.id === selectedModelId);
@ -229,52 +236,54 @@ export default function PricingPage() {
<div className="space-y-8 p-8 max-w-4xl mx-auto">
{/* Header Section */}
<div className="space-y-4">
<h1 className="text-3xl font-bold text-foreground">
Credits & Pricing
</h1>
<h1 className="text-3xl font-bold text-foreground">Token Pricing</h1>
<p className="text-lg text-muted-foreground max-w-3xl">
Understand how credits work, explore pricing for AI models, and find
Understand how tokens work, explore pricing for AI models, and find
the right plan for your needs.
</p>
</div>
{/* What are Credits Section */}
{/* What are Tokens Section */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Zap className="w-5 h-5 text-blue-500" />
What are credits?
Understanding Tokens & Compute
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-muted-foreground">
Credits are our standard unit of measurement for platform usage -
the more complex or lengthy the task, the more credits it requires.
Credits provide a unified way to measure consumption across
different types of AI operations and computational resources.
Tokens are the fundamental units that AI models use to process text
- the more complex or lengthy your task, the more tokens it
requires. Compute usage is measured by both input tokens (your
prompts and context) and output tokens (the AI's responses), with
different models having varying computational requirements and costs
per token.
</p>
</CardContent>
</Card>
{/* How Credits Work Section */}
{/* How Pricing Works Section */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Server className="w-5 h-5 text-green-500" />
How do credits work?
How does pricing work?
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-muted-foreground">
Credits are consumed based on AI model usage. We apply a 50% markup
over the direct model provider costs. The specific credits
consumption is determined by the model used and the number of tokens
processed (both input and output tokens).
Usage costs are calculated based on token consumption from AI model
interactions. We apply a 50% markup over direct model provider costs
to maintain our platform and services. Your total cost depends on
the specific model used and the number of tokens processed for both
input (prompts, context) and output (generated responses).
</p>
</CardContent>
</Card>
{/* Usage Examples Section */}
{!DISABLE_EXAMPLES && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
@ -334,9 +343,12 @@ export default function PricingPage() {
</div>
<div className="space-y-2 text-sm mt-6">
<div className="flex justify-between">
<span className="text-muted-foreground">Model:</span>
<span className="text-muted-foreground">
Model:
</span>
<span>
{selectedModel?.display_name || task.originalModel}
{selectedModel?.display_name ||
task.originalModel}
</span>
</div>
<div className="flex justify-between">
@ -351,10 +363,6 @@ export default function PricingPage() {
</span>
<span>{task.outputTokens.toLocaleString()}</span>
</div>
{/* <div className="flex justify-between">
<span className="text-muted-foreground">Duration:</span>
<span>{task.duration}</span>
</div> */}
<div className="flex justify-between font-semibold">
<span className="text-muted-foreground">Cost:</span>
{calculatedCost !== null ? (
@ -389,6 +397,7 @@ export default function PricingPage() {
</div>
</CardContent>
</Card>
)}
{/* Model Pricing Table */}
<Card>
@ -427,7 +436,7 @@ export default function PricingPage() {
<div className="w-2 h-2 bg-blue-500 rounded-full flex-shrink-0"></div>
<div className="min-w-0">
<div className="font-medium text-foreground truncate">
{model.display_name}
{model.display_name ?? model.id}
</div>
</div>
</div>