Skip to content

Commit 011dee4

Browse files
committed
Better show sessions used
1 parent 6877b73 commit 011dee4

4 files changed

Lines changed: 34 additions & 40 deletions

File tree

cli/src/components/freebuff-model-selector.tsx

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,26 @@ export const FreebuffModelSelector: React.FC = () => {
9898
? session.rateLimitsByModel
9999
: undefined
100100

101-
const getQuotaHint = useCallback(
102-
(modelId: string): string => {
103-
const rateLimit = rateLimitsByModel?.[modelId]
104-
if (rateLimit) {
105-
return `${formatSessionUnits(rateLimit.recentCount)}/${rateLimit.limit} used`
106-
}
107-
return isFreebuffPremiumModelId(modelId)
108-
? `0/${FREEBUFF_PREMIUM_SESSION_LIMIT} used`
109-
: 'Unlimited'
110-
},
101+
// All premium models share one quota pool: the server replicates the same
102+
// snapshot under each premium model id, so any entry has the right count.
103+
// Grab the first one (or 0 when the user has no usage and the map is
104+
// absent) so the footer can render the single shared counter.
105+
const sharedPremiumUsed = useMemo(
106+
() =>
107+
rateLimitsByModel
108+
? (Object.values(rateLimitsByModel)[0]?.recentCount ?? 0)
109+
: 0,
111110
[rateLimitsByModel],
112111
)
113112

113+
// Per-row hint is a tier badge, not a quota counter: premium models share
114+
// the 5-session pool (shown once in the footer); MiniMax is unlimited.
115+
const getTierLabel = useCallback(
116+
(modelId: string): string =>
117+
isFreebuffPremiumModelId(modelId) ? 'Premium' : 'Unlimited',
118+
[],
119+
)
120+
114121
const BUTTON_CHROME = 4 // 2 border + 2 padding
115122

116123
// Decide whether secondary details (warning / deployment hours) get their
@@ -130,7 +137,7 @@ export const FreebuffModelSelector: React.FC = () => {
130137
}
131138

132139
const hintLen = (model: FreebuffModelOption): number =>
133-
Math.max(getQuotaHint(model.id).length, 'Closed'.length)
140+
Math.max(getTierLabel(model.id).length, 'Closed'.length)
134141

135142
const oneLineLen = (model: FreebuffModelOption): number => {
136143
const inlineDetails = detailsTextLen(model)
@@ -140,7 +147,7 @@ export const FreebuffModelSelector: React.FC = () => {
140147
3 /* " · " */ +
141148
model.tagline.length +
142149
(inlineDetails > 0 ? 3 + inlineDetails : 0) +
143-
1 /* space before hint */ +
150+
3 /* " · " before hint */ +
144151
hintLen(model)
145152
)
146153
}
@@ -150,7 +157,7 @@ export const FreebuffModelSelector: React.FC = () => {
150157
model.displayName.length +
151158
3 +
152159
model.tagline.length +
153-
1 +
160+
3 +
154161
hintLen(model)
155162

156163
const detailsLineLen = (model: FreebuffModelOption): number => {
@@ -176,7 +183,7 @@ export const FreebuffModelSelector: React.FC = () => {
176183
contentMaxWidth,
177184
),
178185
}
179-
}, [contentMaxWidth, deploymentAvailabilityLabel, getQuotaHint])
186+
}, [contentMaxWidth, deploymentAvailabilityLabel, getTierLabel])
180187

181188
const isJoinable = useCallback(
182189
(modelId: string) => {
@@ -255,8 +262,8 @@ export const FreebuffModelSelector: React.FC = () => {
255262
// anything except re-picking the queue we're already in.
256263
const interactable =
257264
!pending && canJoin && model.id !== committedModelId
258-
const quotaHint = getQuotaHint(model.id)
259-
const hint = isAvailable ? quotaHint : 'Closed'
265+
const tierLabel = getTierLabel(model.id)
266+
const hint = isAvailable ? tierLabel : 'Closed'
260267

261268
// Focused row: green border + arrow indicator + bold name. The name
262269
// itself stays the normal foreground color so it doesn't shout — the
@@ -317,7 +324,7 @@ export const FreebuffModelSelector: React.FC = () => {
317324
{showInlineWarning && (
318325
<span fg={warningColor}> · {model.warning}</span>
319326
)}
320-
<span fg={hintColor}> {hint}</span>
327+
<span fg={hintColor}> · {hint}</span>
321328
</text>
322329
{showWrappedDetails && (
323330
<text>
@@ -336,6 +343,14 @@ export const FreebuffModelSelector: React.FC = () => {
336343
</Button>
337344
)
338345
})}
346+
{/* Single shared-quota footer. Replaces the per-row "X/5 used" hints
347+
which made it look like each premium model had its own pool.
348+
wrapMode: 'word' so the line reflows on narrow terminals instead of
349+
clipping. */}
350+
<text style={{ fg: theme.muted, marginTop: 1, wrapMode: 'word' }}>
351+
{formatSessionUnits(sharedPremiumUsed)} /{' '}
352+
{FREEBUFF_PREMIUM_SESSION_LIMIT} premium sessions used today
353+
</text>
339354
</box>
340355
)
341356
}

cli/src/components/status-bar.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ const formatSessionRemaining = (ms: number): string => {
6666
return minutes === 0 ? `${hours}h left` : `${hours}h ${minutes}m left`
6767
}
6868

69-
const formatSessionUnits = (units: number): string =>
70-
Number.isInteger(units) ? String(units) : units.toFixed(1)
71-
7269
interface StatusBarProps {
7370
timerStartTime: number | null
7471
isAtBottom: boolean
@@ -179,16 +176,10 @@ export const StatusBar = ({
179176
freebuffSession?.status === 'active'
180177
? getFreebuffModel(freebuffSession.model).displayName
181178
: null
182-
const quotaText =
183-
freebuffSession?.status === 'active' && freebuffSession.rateLimit
184-
? `Premium ${formatSessionUnits(freebuffSession.rateLimit.recentCount)}/${freebuffSession.rateLimit.limit} used · `
185-
: freebuffSession?.status === 'active'
186-
? 'Unlimited · '
187-
: ''
188179
return (
189180
<span fg={isUrgent ? theme.warning : theme.secondary}>
190181
{modelName ? `${modelName} · ` : ''}
191-
{quotaText}{formatSessionRemaining(sessionProgress.remainingMs)}
182+
{formatSessionRemaining(sessionProgress.remainingMs)}
192183
</span>
193184
)
194185
}

cli/src/components/waiting-room-screen.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,18 +263,6 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
263263
<span>Elapsed </span>
264264
{formatElapsed(elapsedMs)}
265265
</text>
266-
{/* Premium session quota. Minimax is unlimited, so it has no
267-
rateLimit payload and skips this line. */}
268-
{session.rateLimit && (
269-
<text style={{ fg: theme.muted, alignSelf: 'flex-start' }}>
270-
<span>Premium sessions </span>
271-
<span fg={theme.foreground}>
272-
{formatSessionUnits(session.rateLimit.recentCount)} /{' '}
273-
{session.rateLimit.limit}
274-
</span>
275-
<span> used in the last 20 hours</span>
276-
</text>
277-
)}
278266
</box>
279267
</>
280268
)}

common/src/constants/freebuff-models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const FREEBUFF_MODELS = [
8080
{
8181
id: FREEBUFF_MINIMAX_MODEL_ID,
8282
displayName: 'MiniMax M2.7',
83-
tagline: 'Fastest, unlimited',
83+
tagline: 'Fastest',
8484
availability: 'always',
8585
},
8686
] as const satisfies readonly FreebuffModelOption[]

0 commit comments

Comments
 (0)