Improve TUI timestamp consistency and formatting
This commit is contained in:
@@ -78,10 +78,19 @@ export function App({
|
||||
onTransfer,
|
||||
onExit,
|
||||
}: AppProps): React.ReactElement {
|
||||
const ensureTimestamp = useCallback((message: Message): Message => ({
|
||||
...message,
|
||||
timestamp: message.timestamp ?? Date.now(),
|
||||
}), []);
|
||||
|
||||
const ensureTimestamps = useCallback((history: Message[]): Message[] => (
|
||||
history.map(ensureTimestamp)
|
||||
), [ensureTimestamp]);
|
||||
|
||||
const ctrlCExitWindowMs = 1_500;
|
||||
const { exit } = useApp();
|
||||
const [input, setInput] = useState('');
|
||||
const [messages, setMessages] = useState<Message[]>(session.getHistory());
|
||||
const [messages, setMessages] = useState<Message[]>(ensureTimestamps(session.getHistory()));
|
||||
const [isStreaming, setIsStreaming] = useState(false);
|
||||
const [streamingContent, setStreamingContent] = useState('');
|
||||
const [scrollOffset, setScrollOffset] = useState(0);
|
||||
@@ -682,7 +691,7 @@ export function App({
|
||||
const messageWithTimestamp = session.addMessage(userMessage);
|
||||
setMessages(prev => [...prev, messageWithTimestamp]);
|
||||
} else {
|
||||
setMessages(prev => [...prev, { ...userMessage, timestamp: Date.now() }]);
|
||||
setMessages(prev => [...prev, ensureTimestamp(userMessage)]);
|
||||
}
|
||||
setScrollOffset(0);
|
||||
|
||||
@@ -696,7 +705,7 @@ export function App({
|
||||
await agent.process(command.content);
|
||||
const usage = agent.getUsage();
|
||||
setTokenUsage({ inputTokens: usage.inputTokens, outputTokens: usage.outputTokens });
|
||||
setMessages(session.getHistory());
|
||||
setMessages(ensureTimestamps(session.getHistory()));
|
||||
} else if (modelClient.chatStream) {
|
||||
let fullContent = '';
|
||||
|
||||
@@ -757,6 +766,8 @@ export function App({
|
||||
exit,
|
||||
onExit,
|
||||
isStreaming,
|
||||
ensureTimestamp,
|
||||
ensureTimestamps,
|
||||
messages.length,
|
||||
tokenUsage.inputTokens,
|
||||
tokenUsage.outputTokens,
|
||||
|
||||
@@ -13,16 +13,12 @@ export interface MessageListProps {
|
||||
}
|
||||
|
||||
// Helper to format timestamp in human-readable way
|
||||
function formatTimestamp(timestamp: number): string {
|
||||
function formatTimestampParts(timestamp: number): { date: string; time: string } {
|
||||
const date = new Date(timestamp);
|
||||
const now = new Date();
|
||||
const isSameDay = date.toDateString() === now.toDateString();
|
||||
|
||||
if (isSameDay) {
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
|
||||
return date.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
||||
return {
|
||||
date: date.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }),
|
||||
time: date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
||||
};
|
||||
}
|
||||
|
||||
// Individual message component
|
||||
@@ -35,7 +31,7 @@ const MessageItem = memo(function MessageItem({
|
||||
}): React.ReactElement {
|
||||
const isUser = message.role === 'user';
|
||||
const accentColor = isUser ? 'blue' : '#ff8c00';
|
||||
const timestampText = message.timestamp ? formatTimestamp(message.timestamp) : 'unknown time';
|
||||
const timestamp = formatTimestampParts(message.timestamp ?? Date.now());
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -55,7 +51,7 @@ const MessageItem = memo(function MessageItem({
|
||||
<Text color={accentColor} bold>
|
||||
{isUser ? 'You' : 'Flynn'}
|
||||
</Text>
|
||||
<Text color="gray">| {timestampText}</Text>
|
||||
<Text color="gray">| {timestamp.date} | {timestamp.time}</Text>
|
||||
</Box>
|
||||
|
||||
{/* Content */}
|
||||
|
||||
@@ -48,12 +48,16 @@ export function formatPrompt(state: 'default' | 'thinking'): string {
|
||||
return `${colors.orange}${colors.bold}flynn>${colors.reset} `;
|
||||
}
|
||||
|
||||
function formatMessageTime(timestamp: number): string {
|
||||
return new Date(timestamp).toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
});
|
||||
function formatMessageTimestampParts(timestamp: number): { date: string; time: string } {
|
||||
const date = new Date(timestamp);
|
||||
return {
|
||||
date: date.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }),
|
||||
time: date.toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export interface MinimalTuiConfig {
|
||||
@@ -1237,9 +1241,16 @@ export class MinimalTui {
|
||||
}
|
||||
|
||||
private async handleMessage(content: string): Promise<void> {
|
||||
const userTimestamp = formatMessageTimestampParts(Date.now());
|
||||
process.stdout.write(
|
||||
`\n${colors.blue}${colors.bold}You${colors.reset} ${colors.gray}[${userTimestamp.date} | ${userTimestamp.time}]${colors.reset}\n`,
|
||||
);
|
||||
process.stdout.write(`${content}\n`);
|
||||
|
||||
const assistantTimestamp = formatMessageTimestampParts(Date.now());
|
||||
// Print Flynn label before response
|
||||
process.stdout.write(
|
||||
`\n${colors.orange}${colors.bold}Flynn${colors.reset} ${colors.gray}[${formatMessageTime(Date.now())}]${colors.reset}\n`,
|
||||
`\n${colors.orange}${colors.bold}Flynn${colors.reset} ${colors.gray}[${assistantTimestamp.date} | ${assistantTimestamp.time}]${colors.reset}\n`,
|
||||
);
|
||||
this.startBusyIndicator();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user