diff --git a/gui/src/components/console/CostBadge.tsx b/gui/src/components/console/CostBadge.tsx new file mode 100644 index 0000000000..ba01b383c9 --- /dev/null +++ b/gui/src/components/console/CostBadge.tsx @@ -0,0 +1,61 @@ +import React from "react"; +import useLLMLog from "../../hooks/useLLMLog"; +import useTotalUsage from "../../hooks/useTotalUsage"; +import { useAppSelector } from "../../redux/hooks"; + +interface CostBadgeProps { + className?: string; +} + +const CostBadge: React.FC = ({ className = "" }) => { + const llmLog = useLLMLog(); + const totalUsage = useTotalUsage(llmLog); + + if (totalUsage.totalCost === 0) { + return null; + } + + const formatCost = (cost: number): string => { + if (cost < 0.0001) return "<$0.00"; + if (cost < 0.01) return `$${cost.toFixed(4)}`; + if (cost < 1) return `$${cost.toFixed(3)}`; + return `$${cost.toFixed(2)}`; + }; + + const getCostColor = (): string => { + if (totalUsage.totalCost < 0.01) return "var(--vscode-charts-green)"; + if (totalUsage.totalCost < 0.1) return "var(--vscode-charts-yellow)"; + return "var(--vscode-charts-red)"; + }; + + return ( +
+ + + + + + {formatCost(totalUsage.totalCost)} +
+ ); +}; + +export default CostBadge; diff --git a/gui/src/pages/gui/Chat.tsx b/gui/src/pages/gui/Chat.tsx index d37ff2efce..ad6408e779 100644 --- a/gui/src/pages/gui/Chat.tsx +++ b/gui/src/pages/gui/Chat.tsx @@ -16,6 +16,7 @@ import { import { ErrorBoundary } from "react-error-boundary"; import styled from "styled-components"; import { Button, lightGray, vscBackground } from "../../components"; +import CostBadge from "../../components/console/CostBadge"; import { useFindWidget } from "../../components/find/FindWidget"; import TimelineItem from "../../components/gui/TimelineItem"; import { NewSessionButton } from "../../components/mainInput/belowMainInput/NewSessionButton"; @@ -469,6 +470,9 @@ export function Chat() { ))}
+
+ +
({})), + setState: vi.fn(), + acquireTerminalShellIntegration: vi.fn(() => ({ + shellIntegrationSeq: vi.fn(), + })), +}; + +(global as any).vscode = mockVscode; + afterEach(() => { vi.clearAllMocks(); + mockVscode.postMessage.mockClear(); }); afterAll(() => {