@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
JavaScript
// // 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;