109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useChat } from '../contexts/ChatContext';
|
|
import { useConfig } from '../contexts/ConfigContext';
|
|
import { Button } from './ui/button';
|
|
import { AnalyticsDashboard } from './AnalyticsDashboard';
|
|
|
|
export function AnalyticsPanel() {
|
|
const { lastTokenUsage } = useChat();
|
|
const { provider, selectedModel } = useConfig();
|
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
|
|
// Define pricing per million tokens for different models (in USD)
|
|
const modelPricing: {
|
|
[key: string]: {
|
|
inputPerMillion: number;
|
|
outputPerMillion: number;
|
|
currency: string;
|
|
};
|
|
} = {
|
|
// OpenAI models
|
|
'gpt-4o': { inputPerMillion: 5, outputPerMillion: 15, currency: 'USD' },
|
|
'gpt-4-turbo': { inputPerMillion: 10, outputPerMillion: 30, currency: 'USD' },
|
|
'gpt-3.5-turbo': { inputPerMillion: 0.5, outputPerMillion: 1.5, currency: 'USD' },
|
|
|
|
// Anthropic models
|
|
'claude-3-opus-20240229': { inputPerMillion: 15, outputPerMillion: 75, currency: 'USD' },
|
|
'claude-3-sonnet-20240229': { inputPerMillion: 3, outputPerMillion: 15, currency: 'USD' },
|
|
'claude-3-haiku-20240307': { inputPerMillion: 0.25, outputPerMillion: 1.25, currency: 'USD' },
|
|
|
|
// Google models
|
|
'gemini-pro': { inputPerMillion: 0.25, outputPerMillion: 0.25, currency: 'USD' },
|
|
'gemini-1.5-pro': { inputPerMillion: 3.5, outputPerMillion: 10.5, currency: 'USD' },
|
|
|
|
// Default for unknown models
|
|
'default': { inputPerMillion: 1, outputPerMillion: 3, currency: 'USD' }
|
|
};
|
|
|
|
if (!lastTokenUsage) return null;
|
|
|
|
const { prompt, completion, total } = lastTokenUsage;
|
|
|
|
// Get pricing for the selected model, or use default
|
|
const pricing = modelPricing[selectedModel] || modelPricing.default;
|
|
const { inputPerMillion, outputPerMillion, currency } = pricing;
|
|
|
|
// Calculate costs
|
|
const promptCost = (prompt / 1000000) * inputPerMillion;
|
|
const completionCost = (completion / 1000000) * outputPerMillion;
|
|
const totalCost = promptCost + completionCost;
|
|
|
|
return (
|
|
<div className="p-2 border-t space-y-2">
|
|
<div className="flex justify-between items-center">
|
|
<div className="flex items-center gap-2">
|
|
<div className="text-xs font-medium">Token Usage</div>
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
className="h-6 px-2 text-xs"
|
|
onClick={() => setIsExpanded(!isExpanded)}
|
|
>
|
|
{isExpanded ? 'Hide Details' : 'Show Details'}
|
|
</Button>
|
|
|
|
<AnalyticsDashboard />
|
|
</div>
|
|
<div className="text-xs text-muted-foreground">
|
|
Total: {total.toLocaleString()} tokens
|
|
</div>
|
|
</div>
|
|
|
|
{isExpanded && (
|
|
<div className="bg-muted/30 rounded-md p-3 space-y-3 text-sm">
|
|
<div className="grid grid-cols-2 gap-2">
|
|
<div className="space-y-1">
|
|
<h4 className="text-xs font-medium">Last Message</h4>
|
|
<div className="grid grid-cols-2 gap-1 text-xs">
|
|
<div>Input:</div>
|
|
<div className="text-right">{prompt.toLocaleString()} tokens</div>
|
|
<div>Output:</div>
|
|
<div className="text-right">{completion.toLocaleString()} tokens</div>
|
|
<div>Total:</div>
|
|
<div className="text-right">{total.toLocaleString()} tokens</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<h4 className="text-xs font-medium">Estimated Cost</h4>
|
|
<div className="grid grid-cols-2 gap-1 text-xs">
|
|
<div>Input:</div>
|
|
<div className="text-right">{currency} {promptCost.toFixed(6)}</div>
|
|
<div>Output:</div>
|
|
<div className="text-right">{currency} {completionCost.toFixed(6)}</div>
|
|
<div>Total:</div>
|
|
<div className="text-right">{currency} {totalCost.toFixed(6)}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="text-xs text-muted-foreground mt-2">
|
|
<p>Pricing: {currency} {inputPerMillion} / {currency} {outputPerMillion} per million tokens (input/output)</p>
|
|
<p className="mt-1">Note: View detailed analytics by clicking the Analytics button.</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|