mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
working i/o cards
This commit is contained in:
parent
78850bb7a6
commit
28424804ad
4 changed files with 107 additions and 34 deletions
|
|
@ -3,6 +3,7 @@
|
|||
* Datadog-style: header with icon/metrics, content below
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { message } from 'antd';
|
||||
import { ParsedMessage } from './prettyMessagesTypes';
|
||||
import { SectionHeader } from './SectionHeader';
|
||||
|
|
@ -17,6 +18,8 @@ interface InputCardProps {
|
|||
}
|
||||
|
||||
export function InputCard({ messages, promptTokens, inputCost }: InputCardProps) {
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
|
||||
if (messages.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -48,30 +51,41 @@ export function InputCard({ messages, promptTokens, inputCost }: InputCardProps)
|
|||
tokens={promptTokens}
|
||||
cost={inputCost}
|
||||
onCopy={handleCopy}
|
||||
isCollapsed={isCollapsed}
|
||||
onToggleCollapse={() => setIsCollapsed(!isCollapsed)}
|
||||
/>
|
||||
|
||||
{/* Content */}
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
{/* System Message - Collapsible with arrow */}
|
||||
{systemMessage && (
|
||||
<CollapsibleMessage
|
||||
label="SYSTEM"
|
||||
content={systemMessage.content}
|
||||
defaultExpanded={!!(systemMessage.content && systemMessage.content.length < 200)}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
maxHeight: isCollapsed ? '0px' : '10000px',
|
||||
overflow: 'hidden',
|
||||
transition: 'max-height 0.3s ease-out, opacity 0.3s ease-out',
|
||||
opacity: isCollapsed ? 0 : 1,
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
{/* System Message - Collapsible with arrow */}
|
||||
{systemMessage && (
|
||||
<CollapsibleMessage
|
||||
label="SYSTEM"
|
||||
content={systemMessage.content}
|
||||
defaultExpanded={!!(systemMessage.content && systemMessage.content.length < 200)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* History - Tree style, collapsed by default */}
|
||||
{historyMessages.length > 0 && <HistoryTree messages={historyMessages} />}
|
||||
{/* History - Tree style, collapsed by default */}
|
||||
{historyMessages.length > 0 && <HistoryTree messages={historyMessages} />}
|
||||
|
||||
{/* Last User Message - Always visible */}
|
||||
{lastMessage && (
|
||||
<SimpleMessageBlock
|
||||
label={lastMessage.role.toUpperCase()}
|
||||
content={lastMessage.content}
|
||||
toolCalls={lastMessage.toolCalls}
|
||||
/>
|
||||
)}
|
||||
{/* Last User Message - Always visible */}
|
||||
{lastMessage && (
|
||||
<SimpleMessageBlock
|
||||
label={lastMessage.role.toUpperCase()}
|
||||
content={lastMessage.content}
|
||||
toolCalls={lastMessage.toolCalls}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* Datadog-style: header with icon/metrics, content below
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Typography, message as antdMessage } from 'antd';
|
||||
import { ParsedMessage } from './prettyMessagesTypes';
|
||||
import { SectionHeader } from './SectionHeader';
|
||||
|
|
@ -17,6 +18,8 @@ interface OutputCardProps {
|
|||
}
|
||||
|
||||
export function OutputCard({ message, completionTokens, outputCost }: OutputCardProps) {
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
|
||||
const handleCopy = () => {
|
||||
if (!message) return;
|
||||
|
||||
|
|
@ -39,11 +42,22 @@ export function OutputCard({ message, completionTokens, outputCost }: OutputCard
|
|||
tokens={completionTokens}
|
||||
cost={outputCost}
|
||||
onCopy={handleCopy}
|
||||
isCollapsed={isCollapsed}
|
||||
onToggleCollapse={() => setIsCollapsed(!isCollapsed)}
|
||||
/>
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
<Text type="secondary" style={{ fontSize: 13, fontStyle: 'italic' }}>
|
||||
No response data available
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
maxHeight: isCollapsed ? '0px' : '10000px',
|
||||
overflow: 'hidden',
|
||||
transition: 'max-height 0.3s ease-out, opacity 0.3s ease-out',
|
||||
opacity: isCollapsed ? 0 : 1,
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
<Text type="secondary" style={{ fontSize: 13, fontStyle: 'italic' }}>
|
||||
No response data available
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -63,15 +77,26 @@ export function OutputCard({ message, completionTokens, outputCost }: OutputCard
|
|||
tokens={completionTokens}
|
||||
cost={outputCost}
|
||||
onCopy={handleCopy}
|
||||
isCollapsed={isCollapsed}
|
||||
onToggleCollapse={() => setIsCollapsed(!isCollapsed)}
|
||||
/>
|
||||
|
||||
{/* Content */}
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
<SimpleMessageBlock
|
||||
label="ASSISTANT"
|
||||
content={message.content}
|
||||
toolCalls={message.toolCalls}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
maxHeight: isCollapsed ? '0px' : '10000px',
|
||||
overflow: 'hidden',
|
||||
transition: 'max-height 0.3s ease-out, opacity 0.3s ease-out',
|
||||
opacity: isCollapsed ? 0 : 1,
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: '12px 16px' }}>
|
||||
<SimpleMessageBlock
|
||||
label="ASSISTANT"
|
||||
content={message.content}
|
||||
toolCalls={message.toolCalls}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
import { Typography, Button, Tooltip } from 'antd';
|
||||
import {
|
||||
MessageOutlined,
|
||||
CopyOutlined
|
||||
CopyOutlined,
|
||||
DownOutlined,
|
||||
UpOutlined
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
|
@ -15,21 +17,45 @@ interface SectionHeaderProps {
|
|||
tokens?: number;
|
||||
cost?: number;
|
||||
onCopy: () => void;
|
||||
isCollapsed?: boolean;
|
||||
onToggleCollapse?: () => void;
|
||||
}
|
||||
|
||||
export function SectionHeader({ type, tokens, cost, onCopy }: SectionHeaderProps) {
|
||||
export function SectionHeader({ type, tokens, cost, onCopy, isCollapsed, onToggleCollapse }: SectionHeaderProps) {
|
||||
return (
|
||||
<div
|
||||
onClick={onToggleCollapse}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '10px 16px',
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
borderBottom: isCollapsed ? 'none' : '1px solid #f0f0f0',
|
||||
background: '#fafafa',
|
||||
cursor: onToggleCollapse ? 'pointer' : 'default',
|
||||
transition: 'background 0.15s ease',
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (onToggleCollapse) {
|
||||
e.currentTarget.style.background = '#f5f5f5';
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = '#fafafa';
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
{/* Collapse Arrow */}
|
||||
{onToggleCollapse && (
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
{isCollapsed ? (
|
||||
<DownOutlined style={{ fontSize: 10, color: '#8c8c8c' }} />
|
||||
) : (
|
||||
<UpOutlined style={{ fontSize: 10, color: '#8c8c8c' }} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Icon + Label */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
{type === 'input' ? (
|
||||
|
|
@ -59,7 +85,15 @@ export function SectionHeader({ type, tokens, cost, onCopy }: SectionHeaderProps
|
|||
|
||||
{/* Copy Button */}
|
||||
<Tooltip title="Copy">
|
||||
<Button type="text" size="small" icon={<CopyOutlined />} onClick={onCopy} />
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<CopyOutlined />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // Prevent triggering collapse
|
||||
onCopy();
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue