diff --git a/src/components/chat/ChatFlowList.jsx b/src/components/chat/ChatFlowList.jsx
index 089931d..ebfc607 100644
--- a/src/components/chat/ChatFlowList.jsx
+++ b/src/components/chat/ChatFlowList.jsx
@@ -27,6 +27,7 @@ import CalculateIcon from '@mui/icons-material/Calculate';
import QrCodeScannerIcon from '@mui/icons-material/QrCodeScanner';
import DirectionsIcon from '@mui/icons-material/Directions';
import EditNoteIcon from '@mui/icons-material/EditNote';
+import PaidRoundedIcon from '@mui/icons-material/PaidRounded';
import Button from '@mui/material/Button';
import { enqueueSnackbar } from 'notistack';
import { deliveryEditorAutomat, setLastDeliveryPath } from '../../automats';
@@ -73,7 +74,7 @@ function parseMessagePayload(raw) {
return { content: raw };
}
-function formatUsageText(usage, prefix = '') {
+function formatUsageText(usage) {
if (!usage) return '';
const input = Number(usage.input ?? usage.prompt_tokens ?? 0);
const output = Number(usage.output ?? usage.completion_tokens ?? 0);
@@ -81,8 +82,28 @@ function formatUsageText(usage, prefix = '') {
const cost = typeof usage.cost === 'number' ? ` · $${usage.cost.toFixed(6)}` : '';
const fmt = (n) => n.toLocaleString('de-DE');
const cachedPart = cached > 0 ? ` / ${fmt(cached)} Cache` : '';
- const pfx = prefix ? `${prefix} ` : '';
- return `${pfx}${fmt(input)} Prompt${cachedPart} · ${fmt(output)} Antwort${cost}`;
+ return `${fmt(input)} Prompt${cachedPart} · ${fmt(output)} Antwort${cost}`;
+}
+
+function formatUsageTooltip(usage) {
+ if (!usage) return '';
+ const input = Number(usage.input ?? usage.prompt_tokens ?? 0);
+ const output = Number(usage.output ?? usage.completion_tokens ?? 0);
+ const cached = Number(usage.cached ?? 0);
+ const cost = typeof usage.cost === 'number' ? `$${usage.cost.toFixed(6)}` : null;
+ const fmt = (n) => n.toLocaleString('de-DE');
+
+ const lines = [
+ `Prompt: ${fmt(input)} Tokens`,
+ ];
+ if (cached > 0) {
+ lines.push(`Cache: ${fmt(cached)} Tokens`);
+ }
+ lines.push(`Antwort: ${fmt(output)} Tokens`);
+ if (cost) {
+ lines.push(`Kosten: ${cost}`);
+ }
+ return lines.join('\n');
}
export function aggregateUsage(turns = []) {
@@ -685,11 +706,11 @@ function WorkIconView({ tool }) {
return iconElement;
}
-function UsageChipView({ usage, prefix = '', isSummary = false, title = '' }) {
- const text = formatUsageText(usage, prefix);
+function UsageChipView({ usage, isSummary = false }) {
+ const text = formatUsageText(usage);
if (!text) return null;
- const chip = (
+ return (
);
+}
- if (title) {
- return (
-
- {chip}
-
- );
- }
+function UsageIconView({ usage }) {
+ if (!usage) return null;
+ const tooltipText = formatUsageTooltip(usage);
+ if (!tooltipText) return null;
- return chip;
+ return (
+
+ {tooltipText}
+
+ }
+ >
+
+
+
+
+ );
}
export function TurnRow({ turn, isLive = false }) {
@@ -732,8 +786,9 @@ export function TurnRow({ turn, isLive = false }) {
);
const hasTools = Boolean(turn.tools && turn.tools.length > 0);
const hasContent = Boolean(turn.content);
- const showHandshake = !hasReasonings && !hasTools && !hasContent;
- const showStatusLine = showHandshake || hasReasonings || hasTools;
+ const hasUsage = Boolean(turn.usage);
+ const showHandshake = !hasReasonings && !hasTools && !hasContent && !hasUsage;
+ const showStatusLine = showHandshake || hasReasonings || hasTools || hasUsage;
return (
(
))}
+
+ {hasUsage ? (
+
+ ) : null}
) : null}
@@ -794,13 +853,6 @@ export function TurnRow({ turn, isLive = false }) {
) : null}
-
- {/* Pricing / usage is always on a new line */}
- {turn.usage ? (
-
-
-
- ) : null}
);
}
@@ -1263,18 +1315,11 @@ export default class ChatFlowList extends PureComponent {
{(() => {
const activeSummary = aggregateUsage(activeTurns);
if (!activeSummary) return null;
- const count = activeTurns.length;
- const prefix = count > 1 ? `Summe (${count} Turns):` : 'Summe:';
- const tooltipTitle = count > 1
- ? `Zusammenfassung von ${count} LLM-Turns`
- : 'Zusammenfassung des LLM-Turns';
return (
);