From f32f260c865b1d1be7d6eba841718e9b2cfa1236 Mon Sep 17 00:00:00 2001 From: daniel nakov Date: Fri, 4 Oct 2024 21:51:28 -0400 Subject: [PATCH] Display conversation cost based on usage data --- src/pages/ConsolePage.scss | 3 +++ src/pages/ConsolePage.tsx | 51 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/pages/ConsolePage.scss b/src/pages/ConsolePage.scss index ae162f7d..0dbd4fd7 100644 --- a/src/pages/ConsolePage.scss +++ b/src/pages/ConsolePage.scss @@ -51,6 +51,9 @@ padding-top: 16px; padding-bottom: 4px; position: relative; + .cost { + float: right; + } } .content-block-body { color: #6e6e7f; diff --git a/src/pages/ConsolePage.tsx b/src/pages/ConsolePage.tsx index 366756ce..aae5414a 100644 --- a/src/pages/ConsolePage.tsx +++ b/src/pages/ConsolePage.tsx @@ -54,6 +54,15 @@ interface RealtimeEvent { event: { [key: string]: any }; } +interface UsageTotal { + input_audio_tokens: number; + output_audio_tokens: number; + input_text_tokens: number; + output_text_tokens: number; + cost: number; +} + + export function ConsolePage() { /** * Ask user for API Key @@ -124,7 +133,14 @@ export function ConsolePage() { lng: -122.418137, }); const [marker, setMarker] = useState(null); - + const [usage, setUsage] = useState({ + input_audio_tokens: 0, + output_audio_tokens: 0, + input_text_tokens: 0, + output_text_tokens: 0, + cost: 0, + }); + /** * Utility for formatting the timing of logs */ @@ -207,6 +223,13 @@ export function ConsolePage() { lng: -122.418137, }); setMarker(null); + setUsage({ + input_audio_tokens: 0, + output_audio_tokens: 0, + input_text_tokens: 0, + output_text_tokens: 0, + cost: 0, + }); const client = clientRef.current; client.disconnect(); @@ -467,6 +490,28 @@ export function ConsolePage() { return realtimeEvents.concat(realtimeEvent); } }); + if(realtimeEvent.event.type === 'response.done') { + setUsage((usage) => { + const u = realtimeEvent.event.response.usage; + const input_audio_tokens = u.input_token_details.audio_tokens; + const output_audio_tokens = u.output_token_details.audio_tokens; + const input_text_tokens = u.input_token_details.text_tokens; + const output_text_tokens = u.output_token_details.text_tokens; + + const currentCost = input_audio_tokens * 100 / 1000000 + + output_audio_tokens * 200 / 1000000 + + input_text_tokens * 5 / 1000000 + + output_text_tokens * 20 / 1000000; + + return { + output_audio_tokens: usage.output_audio_tokens + output_audio_tokens, + input_audio_tokens: usage.input_audio_tokens + input_audio_tokens, + output_text_tokens: usage.output_text_tokens + output_text_tokens, + input_text_tokens: usage.input_text_tokens + input_text_tokens, + cost: usage.cost + currentCost + } + }) + } }); client.on('error', (event: any) => console.error(event)); client.on('conversation.interrupted', async () => { @@ -533,7 +578,9 @@ export function ConsolePage() { -
events
+
events + ${usage.cost.toFixed(2)} +
{!realtimeEvents.length && `awaiting connection...`} {realtimeEvents.map((realtimeEvent, i) => {