Skip to content

Commit a702293

Browse files
committed
improvement(usage): update usage limit in realtime, standardize token output object across providers (#2553)
* improvement(usage-limit): update usage in real time, fix token output object * updated tokenBreakdown to tokens, standardized input/output/total token object type across providers * update remaining references * ack PR comment * remove singleton query client instance from hooks, leave only in zustand
1 parent 96f2f94 commit a702293

File tree

51 files changed

+368
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+368
-388
lines changed

apps/sim/app/(landing)/components/nav/nav.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface NavProps {
2020
}
2121

2222
export default function Nav({ hideAuthButtons = false, variant = 'landing' }: NavProps = {}) {
23-
const [githubStars, setGithubStars] = useState('18.6k')
23+
const [githubStars, setGithubStars] = useState('24k')
2424
const [isHovered, setIsHovered] = useState(false)
2525
const [isLoginHovered, setIsLoginHovered] = useState(false)
2626
const router = useRouter()
Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
11
'use client'
22

3-
import { type ReactNode, useState } from 'react'
3+
import type { ReactNode } from 'react'
44
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
55

6-
export function QueryProvider({ children }: { children: ReactNode }) {
7-
const [queryClient] = useState(
8-
() =>
9-
new QueryClient({
10-
defaultOptions: {
11-
queries: {
12-
staleTime: 30 * 1000,
13-
gcTime: 5 * 60 * 1000,
14-
refetchOnWindowFocus: false,
15-
retry: 1,
16-
retryOnMount: false,
17-
},
18-
mutations: {
19-
retry: 1,
20-
},
21-
},
22-
})
23-
)
6+
/**
7+
* Singleton QueryClient instance for client-side use.
8+
* Can be imported directly for cache operations outside React components.
9+
*/
10+
function makeQueryClient() {
11+
return new QueryClient({
12+
defaultOptions: {
13+
queries: {
14+
staleTime: 30 * 1000,
15+
gcTime: 5 * 60 * 1000,
16+
refetchOnWindowFocus: false,
17+
retry: 1,
18+
retryOnMount: false,
19+
},
20+
mutations: {
21+
retry: 1,
22+
},
23+
},
24+
})
25+
}
26+
27+
let browserQueryClient: QueryClient | undefined
2428

29+
export function getQueryClient() {
30+
if (typeof window === 'undefined') {
31+
return makeQueryClient()
32+
}
33+
if (!browserQueryClient) {
34+
browserQueryClient = makeQueryClient()
35+
}
36+
return browserQueryClient
37+
}
38+
39+
export function QueryProvider({ children }: { children: ReactNode }) {
40+
const queryClient = getQueryClient()
2541
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
2642
}

apps/sim/app/api/logs/route.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,15 +259,16 @@ export async function GET(request: NextRequest) {
259259
input: 0,
260260
output: 0,
261261
total: 0,
262-
tokens: { prompt: 0, completion: 0, total: 0 },
262+
tokens: { input: 0, output: 0, total: 0 },
263263
})
264264
}
265265
const modelCost = models.get(block.cost.model)
266266
modelCost.input += Number(block.cost.input) || 0
267267
modelCost.output += Number(block.cost.output) || 0
268268
modelCost.total += Number(block.cost.total) || 0
269-
modelCost.tokens.prompt += block.cost.tokens?.prompt || 0
270-
modelCost.tokens.completion += block.cost.tokens?.completion || 0
269+
modelCost.tokens.input += block.cost.tokens?.input || block.cost.tokens?.prompt || 0
270+
modelCost.tokens.output +=
271+
block.cost.tokens?.output || block.cost.tokens?.completion || 0
271272
modelCost.tokens.total += block.cost.tokens?.total || 0
272273
}
273274
}
@@ -279,8 +280,8 @@ export async function GET(request: NextRequest) {
279280
output: totalOutputCost,
280281
tokens: {
281282
total: totalTokens,
282-
prompt: totalPromptTokens,
283-
completion: totalCompletionTokens,
283+
input: totalPromptTokens,
284+
output: totalCompletionTokens,
284285
},
285286
models: Object.fromEntries(models),
286287
}

apps/sim/app/api/providers/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ export async function POST(request: NextRequest) {
165165
: '',
166166
model: executionData.output?.model,
167167
tokens: executionData.output?.tokens || {
168-
prompt: 0,
169-
completion: 0,
168+
input: 0,
169+
output: 0,
170170
total: 0,
171171
},
172172
// Sanitize any potential Unicode characters in tool calls

apps/sim/app/api/tools/search/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ export async function POST(request: NextRequest) {
8787
output: 0,
8888
total: SEARCH_TOOL_COST,
8989
tokens: {
90-
prompt: 0,
91-
completion: 0,
90+
input: 0,
91+
output: 0,
9292
total: 0,
9393
},
9494
model: 'search-exa',

apps/sim/app/api/workspaces/[id]/notifications/[notificationId]/test/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function buildTestPayload(subscription: typeof workspaceNotificationSubscription
5353
totalDurationMs: 5000,
5454
cost: {
5555
total: 0.00123,
56-
tokens: { prompt: 100, completion: 50, total: 150 },
56+
tokens: { input: 100, output: 50, total: 150 },
5757
},
5858
},
5959
links: {

apps/sim/app/chat/[identifier]/chat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export default function ChatClient({ identifier }: { identifier: string }) {
117117
const [error, setError] = useState<string | null>(null)
118118
const messagesEndRef = useRef<HTMLDivElement>(null)
119119
const messagesContainerRef = useRef<HTMLDivElement>(null)
120-
const [starCount, setStarCount] = useState('19.4k')
120+
const [starCount, setStarCount] = useState('24k')
121121
const [conversationId, setConversationId] = useState('')
122122

123123
const [showScrollButton, setShowScrollButton] = useState(false)

apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/frozen-canvas/frozen-canvas.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ function formatExecutionData(executionData: any) {
131131
: null,
132132
tokens: tokens
133133
? {
134-
prompt: tokens.prompt || 0,
135-
completion: tokens.completion || 0,
134+
input: tokens.input || tokens.prompt || 0,
135+
output: tokens.output || tokens.completion || 0,
136136
total: tokens.total || 0,
137137
}
138138
: null,
@@ -347,12 +347,12 @@ function PinnedLogs({
347347
</h4>
348348
<div className='space-y-[4px] rounded-[4px] border border-[var(--border)] bg-[var(--surface-3)] p-[12px] text-[13px]'>
349349
<div className='flex justify-between text-[var(--text-primary)]'>
350-
<span>Prompt:</span>
351-
<span>{formatted.tokens.prompt}</span>
350+
<span>Input:</span>
351+
<span>{formatted.tokens.input}</span>
352352
</div>
353353
<div className='flex justify-between text-[var(--text-primary)]'>
354-
<span>Completion:</span>
355-
<span>{formatted.tokens.completion}</span>
354+
<span>Output:</span>
355+
<span>{formatted.tokens.output}</span>
356356
</div>
357357
<div className='flex justify-between border-[var(--border)] border-t pt-[4px] font-medium text-[var(--text-primary)]'>
358358
<span>Total:</span>
@@ -498,8 +498,8 @@ export function FrozenCanvas({
498498
total: null,
499499
},
500500
tokens: span.tokens || {
501-
prompt: null,
502-
completion: null,
501+
input: null,
502+
output: null,
503503
total: null,
504504
},
505505
modelUsed: span.model || null,

apps/sim/app/workspace/[workspaceId]/logs/components/log-details/log-details.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ export const LogDetails = memo(function LogDetails({
344344
Tokens:
345345
</span>
346346
<span className='font-medium text-[12px] text-[var(--text-secondary)]'>
347-
{log.cost?.tokens?.prompt || 0} in / {log.cost?.tokens?.completion || 0}{' '}
348-
out
347+
{log.cost?.tokens?.input || log.cost?.tokens?.prompt || 0} in /{' '}
348+
{log.cost?.tokens?.output || log.cost?.tokens?.completion || 0} out
349349
</span>
350350
</div>
351351
</div>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export function CredentialSelector({
116116
setStoreValue('')
117117
}, [invalidSelection, selectedId, effectiveProviderId, setStoreValue])
118118

119-
useCredentialRefreshTriggers(refetchCredentials, effectiveProviderId, provider)
119+
useCredentialRefreshTriggers(refetchCredentials)
120120

121121
const handleOpenChange = useCallback(
122122
(isOpen: boolean) => {
@@ -268,11 +268,7 @@ export function CredentialSelector({
268268
)
269269
}
270270

271-
function useCredentialRefreshTriggers(
272-
refetchCredentials: () => Promise<unknown>,
273-
effectiveProviderId?: string,
274-
provider?: OAuthProvider
275-
) {
271+
function useCredentialRefreshTriggers(refetchCredentials: () => Promise<unknown>) {
276272
useEffect(() => {
277273
const refresh = () => {
278274
void refetchCredentials()
@@ -290,26 +286,12 @@ function useCredentialRefreshTriggers(
290286
}
291287
}
292288

293-
const handleCredentialDisconnected = (event: Event) => {
294-
const customEvent = event as CustomEvent<{ providerId?: string }>
295-
const providerId = customEvent.detail?.providerId
296-
297-
if (
298-
providerId &&
299-
(providerId === effectiveProviderId || (provider && providerId.startsWith(provider)))
300-
) {
301-
refresh()
302-
}
303-
}
304-
305289
document.addEventListener('visibilitychange', handleVisibilityChange)
306290
window.addEventListener('pageshow', handlePageShow)
307-
window.addEventListener('credential-disconnected', handleCredentialDisconnected)
308291

309292
return () => {
310293
document.removeEventListener('visibilitychange', handleVisibilityChange)
311294
window.removeEventListener('pageshow', handlePageShow)
312-
window.removeEventListener('credential-disconnected', handleCredentialDisconnected)
313295
}
314-
}, [refetchCredentials, effectiveProviderId, provider])
296+
}, [refetchCredentials])
315297
}

0 commit comments

Comments
 (0)