From ca321f7cb2454b4d98dcce2b5e74cc72de4c8358 Mon Sep 17 00:00:00 2001 From: sharath <29162020+tnfssc@users.noreply.github.com> Date: Sat, 28 Jun 2025 15:09:48 +0000 Subject: [PATCH] refactor(pricing): enhance model filtering and update terminology for clarity --- .../app/(dashboard)/model-pricing/page.tsx | 293 +++++++++--------- 1 file changed, 151 insertions(+), 142 deletions(-) diff --git a/frontend/src/app/(dashboard)/model-pricing/page.tsx b/frontend/src/app/(dashboard)/model-pricing/page.tsx index 8f367e4a..2f7ebbd8 100644 --- a/frontend/src/app/(dashboard)/model-pricing/page.tsx +++ b/frontend/src/app/(dashboard)/model-pricing/page.tsx @@ -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,21 +144,33 @@ export default function PricingPage() { refetch, } = useAvailableModels(); + const { allModels } = useModelSelection(); + const [selectedModelId, setSelectedModelId] = useState( 'anthropic/claude-sonnet-4-20250514', ); const [showAllTasks, setShowAllTasks] = useState(false); - // Filter to only show models that have pricing information available - const models = - modelsResponse?.models?.filter((model: Model) => { - return ( - model.input_cost_per_million_tokens !== null && - model.input_cost_per_million_tokens !== undefined && - model.output_cost_per_million_tokens !== null && - model.output_cost_per_million_tokens !== undefined - ); - }) || []; + // 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 && + model.input_cost_per_million_tokens !== undefined && + model.output_cost_per_million_tokens !== null && + model.output_cost_per_million_tokens !== undefined + ); + }) || []; + + 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,166 +236,168 @@ export default function PricingPage() {
{/* Header Section */}
-

- Credits & Pricing -

+

Token Pricing

- 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.

- {/* What are Credits Section */} + {/* What are Tokens Section */} - What are credits? + Understanding Tokens & Compute

- 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.

- {/* How Credits Work Section */} + {/* How Pricing Works Section */} - How do credits work? + How does pricing work?

- 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).

{/* Usage Examples Section */} - - - - - Usage Examples - - - Here are some examples demonstrating credits consumption across - different task types and complexity levels. - - - -
- {/* Model Selection */} -
- - -
+ {!DISABLE_EXAMPLES && ( + + + + + Usage Examples + + + Here are some examples demonstrating credits consumption across + different task types and complexity levels. + + + +
+ {/* Model Selection */} +
+ + +
- {/* Example Tasks Grid */} -
- {(showAllTasks ? exampleTasks : exampleTasks.slice(0, 3)).map( - (task, index) => { - const calculatedCost = selectedModel - ? calculateCost( - task.inputTokens, - task.outputTokens, - selectedModel, - ) - : null; + {/* Example Tasks Grid */} +
+ {(showAllTasks ? exampleTasks : exampleTasks.slice(0, 3)).map( + (task, index) => { + const calculatedCost = selectedModel + ? calculateCost( + task.inputTokens, + task.outputTokens, + selectedModel, + ) + : null; - return ( -
-
-

- {task.name} -

-
-
-
- Model: - - {selectedModel?.display_name || task.originalModel} - + return ( +
+
+

+ {task.name} +

-
- - Input Tokens: - - {task.inputTokens.toLocaleString()} -
-
- - Output Tokens: - - {task.outputTokens.toLocaleString()} -
- {/*
- Duration: - {task.duration} -
*/} -
- Cost: - {calculatedCost !== null ? ( - - ${calculatedCost.toFixed(2)} - - ) : ( +
+
- Select model above + Model: - )} + + {selectedModel?.display_name || + task.originalModel} + +
+
+ + Input Tokens: + + {task.inputTokens.toLocaleString()} +
+
+ + Output Tokens: + + {task.outputTokens.toLocaleString()} +
+
+ Cost: + {calculatedCost !== null ? ( + + ${calculatedCost.toFixed(2)} + + ) : ( + + Select model above + + )} +
-
- ); - }, + ); + }, + )} +
+ + {/* Show More/Less Button */} + {exampleTasks.length > 3 && ( +
+ +
)}
- - {/* Show More/Less Button */} - {exampleTasks.length > 3 && ( -
- -
- )} -
- - + + + )} {/* Model Pricing Table */} @@ -427,7 +436,7 @@ export default function PricingPage() {
- {model.display_name} + {model.display_name ?? model.id}