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

56 lines (55 loc) 5.3 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState } from 'react'; import { Box, Text } from 'ink'; import { formatTokens, formatCost, // getWarningColor, calculateContextWarning } from '../utils/formatters.js'; // Using shared getWarningColor function from formatters const ConversationHistoryComponent = ({ conversation, maxEntries = 10, showTokenUsage = true, showCost = true, showReasoningProcess = false, }) => { const [searchTerm] = useState(''); const [filterType] = useState('all'); if (!conversation || !conversation.entries || conversation.entries.length === 0) { return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCDD Conversation History" }), _jsx(Text, { color: "gray", children: "No conversation history available for this session." })] })); } // Apply search and filter let filteredEntries = conversation.entries; // Apply type filter if (filterType !== 'all') { filteredEntries = filteredEntries.filter(entry => entry.type === filterType); } // Apply search term if (searchTerm.trim()) { const searchLower = searchTerm.toLowerCase(); filteredEntries = filteredEntries.filter(entry => entry.content.toLowerCase().includes(searchLower) || (entry.reasoningProcess && entry.reasoningProcess.toLowerCase().includes(searchLower)) || (entry.metadata.model && entry.metadata.model.toLowerCase().includes(searchLower))); } // Get the most recent entries if there's a limit const displayEntries = maxEntries > 0 && filteredEntries.length > maxEntries ? filteredEntries.slice(-maxEntries) : filteredEntries; const getEntryTypeIcon = (type) => { switch (type) { case 'user_input': return '👤'; case 'agent_response': return '🤖'; case 'system_message': return '⚙️'; default: return '❓'; } }; const getEntryTypeColor = (type) => { switch (type) { case 'user_input': return 'cyan'; case 'agent_response': return 'green'; case 'system_message': return 'gray'; default: return 'gray'; } }; return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\uD83D\uDCDD Conversation History (", conversation.entries.length, " entries)"] }), filteredEntries.length !== conversation.entries.length && (_jsxs(Text, { color: "yellow", children: [" | Filtered: ", filteredEntries.length] }))] }), _jsxs(Text, { color: "gray", children: ["Game: ", conversation.gameMode, " | Session: ", conversation.sessionId.slice(-8)] })] }), _jsx(Box, { flexDirection: "column", children: displayEntries.map((entry, index) => { // const reasoningTokens = entry.tokenUsage?.reasoningTokens ?? 0; // const hasReasoningTokens = reasoningTokens > 0; const costAmount = entry.metadata.cost ?? 0; const hasCost = costAmount > 0; return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsxs(Text, { color: getEntryTypeColor(entry.type), children: [getEntryTypeIcon(entry.type), " ", entry.type.replace('_', ' ').toUpperCase()] }), entry.metadata.model && (_jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: "yellow", children: ["[", entry.metadata.model, "]"] }) }))] }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", children: entry.formattedTimestamp || new Date(entry.timestamp).toLocaleTimeString() }), showTokenUsage && entry.tokenUsage && entry.tokenUsage.totalTokens > 0 && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "yellow", children: [formatTokens(entry.tokenUsage.totalTokens), " tokens"] }) })), showCost && hasCost && (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { color: "magenta", children: formatCost(costAmount) }) }))] })] }), _jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { wrap: "wrap", color: "gray", children: entry.content }) }), showReasoningProcess && entry.reasoningProcess && (_jsx(Box, { paddingLeft: 4, marginTop: 1, children: _jsxs(Text, { color: "gray", italic: true, wrap: "wrap", children: ["\uD83D\uDCAD Reasoning: ", entry.reasoningProcess] }) })), showTokenUsage && entry.tokenUsage && (entry.tokenUsage.inputTokens > 0 || entry.tokenUsage.outputTokens > 0) && (_jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["\uD83D\uDCC8 Input: ", formatTokens(entry.tokenUsage.inputTokens), " | Output: ", formatTokens(entry.tokenUsage.outputTokens)] }) })), index < displayEntries.length - 1 && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: '─'.repeat(100) }) }))] }, entry.id)); }) }), _jsx(Box, { justifyContent: "center", marginTop: 1, flexDirection: "column", alignItems: "center", children: _jsx(Text, { color: "gray", children: "Press ESC to close" }) })] })); }; export default ConversationHistoryComponent;