UNPKG

@hhoangphuoc/escape-room-cli

Version:

A CLI for playing AI-generated escape room games. Install globally with: npm install -g @hhoangphuoc/escape-room-cli

209 lines (208 loc) 7.03 kB
// // escape-room-cli/source/components/UsageMonitor.tsx export {}; // import React, { useState, useEffect } from 'react'; // import { Box, Text, Spacer } from 'ink'; // import { useAuth } from '../context/AuthContext.js'; // interface UsageMonitoringData { // currentSessionCost: number; // currentSessionTokens: number; // userTotalCost: number; // userTotalTokens: number; // lastRequestCost: number; // lastRequestTokens: number; // averageCostPerRequest: number; // modelUsageBreakdown: Record<string, { // requests: number; // cost: number; // }>; // } // interface UsageAlert { // id: string; // type: 'user_daily_limit' | 'session_limit' | 'request_limit' | 'model_cost_spike'; // threshold: number; // currentValue: number; // timestamp: string; // } // interface UsageMonitorProps { // gameId?: string; // refreshInterval?: number; // milliseconds // showDetailed?: boolean; // } // export const UsageMonitor: React.FC<UsageMonitorProps> = ({ // gameId, // refreshInterval = 30000, // 30 seconds default // showDetailed = false // }) => { // const { apiCall } = useAuth(); // const [usageData, setUsageData] = useState<UsageMonitoringData | null>(null); // const [alerts, setAlerts] = useState<UsageAlert[]>([]); // const [loading, setLoading] = useState(true); // const [error, setError] = useState<string | null>(null); // const fetchUsageData = async () => { // try { // const params = gameId ? `?gameId=${gameId}` : ''; // const response = await apiCall(`/api/usage/monitoring${params}`); // if (response.success) { // setUsageData(response.data); // setError(null); // } else { // setError('Failed to fetch usage data'); // } // } catch (err) { // setError(err instanceof Error ? err.message : 'Unknown error'); // } finally { // setLoading(false); // } // }; // const fetchAlerts = async () => { // try { // const response = await apiCall('/api/usage/alerts'); // if (response.success) { // setAlerts(response.data.alerts); // } // } catch (err) { // // Silently handle alert fetch errors // console.error('Failed to fetch alerts:', err); // } // }; // useEffect(() => { // fetchUsageData(); // fetchAlerts(); // const interval = setInterval(() => { // fetchUsageData(); // fetchAlerts(); // }, refreshInterval); // return () => clearInterval(interval); // }, [gameId, refreshInterval]); // if (loading) { // return ( // <Box> // <Text color="gray">Loading usage data...</Text> // </Box> // ); // } // if (error) { // return ( // <Box> // <Text color="red">Usage Monitor Error: {error}</Text> // </Box> // ); // } // if (!usageData) { // return ( // <Box> // <Text color="gray">No usage data available</Text> // </Box> // ); // } // const formatCost = (cost: number): string => { // return cost < 0.01 ? `$${cost.toFixed(5)}` : `$${cost.toFixed(3)}`; // }; // const formatTokens = (tokens: number): string => { // return tokens.toLocaleString(); // }; // return ( // <Box flexDirection="column" borderStyle="single" borderColor="blue" padding={1}> // <Box> // <Text color="blue" bold>AI Usage Monitor</Text> // <Spacer /> // <Text color="gray">Live</Text> // </Box> // {/* Alerts */} // {alerts.length > 0 && ( // <Box marginTop={1}> // {alerts.map((alert) => ( // <Box key={alert.id}> // <Text color="red">⚠️ {alert.type.replace('_', ' ').toUpperCase()}: ${alert.currentValue.toFixed(3)} / ${alert.threshold.toFixed(3)}</Text> // </Box> // ))} // </Box> // )} // {/* Current Session */} // <Box marginTop={1}> // <Box width="50%"> // <Text color="cyan">Session: {formatCost(usageData.currentSessionCost)}</Text> // </Box> // <Box width="50%"> // <Text color="cyan">Tokens: {formatTokens(usageData.currentSessionTokens)}</Text> // </Box> // </Box> // {/* User Total */} // <Box> // <Box width="50%"> // <Text color="yellow">Total: {formatCost(usageData.userTotalCost)}</Text> // </Box> // <Box width="50%"> // <Text color="yellow">Tokens: {formatTokens(usageData.userTotalTokens)}</Text> // </Box> // </Box> // {/* Last Request */} // <Box> // <Box width="50%"> // <Text color="green">Last: {formatCost(usageData.lastRequestCost)}</Text> // </Box> // <Box width="50%"> // <Text color="green">Tokens: {formatTokens(usageData.lastRequestTokens)}</Text> // </Box> // </Box> // {/* Average */} // <Box> // <Text color="magenta">Avg/Request: {formatCost(usageData.averageCostPerRequest)}</Text> // </Box> // {/* Detailed Model Breakdown */} // {showDetailed && Object.keys(usageData.modelUsageBreakdown).length > 0 && ( // <Box marginTop={1} flexDirection="column"> // <Text color="white" bold>Model Usage:</Text> // {Object.entries(usageData.modelUsageBreakdown).map(([model, data]) => ( // <Box key={model}> // <Text color="gray"> // {model}: {data.requests} req, {formatCost(data.cost)} // </Text> // </Box> // ))} // </Box> // )} // </Box> // ); // }; // /** // * Compact usage monitor for header/status bar // */ // export const CompactUsageMonitor: React.FC<{ gameId?: string }> = ({ gameId }) => { // const { apiCall } = useAuth(); // const [usageData, setUsageData] = useState<UsageMonitoringData | null>(null); // useEffect(() => { // const fetchData = async () => { // try { // const params = gameId ? `?gameId=${gameId}` : ''; // const response = await apiCall(`/api/usage/monitoring${params}`); // if (response.success) { // setUsageData(response.data); // } // } catch (err) { // // Silently handle errors for compact monitor // } // }; // fetchData(); // const interval = setInterval(fetchData, 60000); // Update every minute // return () => clearInterval(interval); // }, [gameId]); // if (!usageData) { // return <Text color="gray">Usage: Loading...</Text>; // } // const formatCost = (cost: number): string => { // return cost < 0.01 ? `$${cost.toFixed(5)}` : `$${cost.toFixed(3)}`; // }; // return ( // <Box> // <Text color="cyan"> // Session: {formatCost(usageData.currentSessionCost)} // </Text> // <Text color="gray"> | </Text> // <Text color="yellow"> // Total: {formatCost(usageData.userTotalCost)} // </Text> // </Box> // ); // }; // export default UsageMonitor;