Refresh web console controls and Codex quota display#983
Conversation
There was a problem hiding this comment.
Findings
- [Major] Refetch Codex limits when the selected model changes —
getCodexSubscriptionLimitsnow selects a model-specific limit bucket, but the web query is keyed only bysessionIdand is infinitely stale. After switching between a model with its own bucket and a regular Codex model, the header badge can keep showing the old model's quota until a later thinking transition happens. Evidence:web/src/hooks/queries/useCodexSubscriptionLimits.ts:22, related selector contextcli/src/modules/common/codexSubscriptionLimits.ts:76.
Suggested fix:// SessionHeader.tsx const codexLimitsState = useCodexSubscriptionLimits({ api, sessionId: session.id, model: session.model ?? null, enabled: session.active && session.metadata?.flavor === 'codex', thinking: props.status?.thinking ?? session.thinking }) // useCodexSubscriptionLimits.ts queryKey: [ ...queryKeys.sessionCodexSubscriptionLimits(sessionId ?? 'unknown'), args.model ?? null ],
Summary
- Review mode: initial
- One issue found: Codex quota display can become stale after model changes because the client cache key does not include the model. Residual risk: web UI paths are not covered by automated tests in this run.
Testing
- Not run (automation:
bunis not installed in this runner)
HAPI Bot
| const thinking = args.thinking === true | ||
| const enabled = Boolean(args.enabled && api && sessionId) | ||
| const query = useQuery({ | ||
| queryKey: queryKeys.sessionCodexSubscriptionLimits(sessionId ?? 'unknown'), |
There was a problem hiding this comment.
[MAJOR] This query needs to vary with the selected model. The CLI selector now chooses a model-specific bucket when model matches limitId/limitName, but this cache key only contains sessionId and staleTime is infinite. If the user switches between Spark and a regular Codex model, the header badge can keep rendering the previous model's quota until a later thinking transition refetches it.
Suggested fix:
// include model in the hook args from SessionHeader
model: session.model ?? null,
// and key by it here
queryKey: [
...queryKeys.sessionCodexSubscriptionLimits(sessionId ?? 'unknown'),
args.model ?? null
],a0a37fd to
b304743
Compare
There was a problem hiding this comment.
Findings
- [Minor] Avoid fetching hidden Telegram-only header data —
SessionHeaderreturnsnullin Telegram, but the new Codex limits hook runs before that return and is enabled for every active Codex session. Opening a Codex session in the Mini App now triggers/codex-subscription-limitsand an RPC that can spawncodex app-server, even though the badge is never rendered. Evidence:web/src/components/SessionHeader.tsx:211,web/src/components/SessionHeader.tsx:246.
Suggested fix:const telegramHeaderHidden = isTelegramApp() const codexLimitsState = useCodexSubscriptionLimits({ api, sessionId: session.id, model: session.model ?? null, enabled: !telegramHeaderHidden && session.active && session.metadata?.flavor === 'codex', thinking: props.status?.thinking ?? session.thinking }) if (telegramHeaderHidden) { return null }
Summary
- Review mode: follow-up after new commits
- Prior stale-model-cache issue no longer reproduces because the query key now includes
model. One minor issue remains: Telegram opens can still trigger the new quota RPC for a header that is not displayed. Residual risk: this review did not run the full browser UI manually.
Testing
- Not run (automation)
HAPI Bot
| session.id, | ||
| session.metadata?.flavor ?? null | ||
| ) | ||
| const codexLimitsState = useCodexSubscriptionLimits({ |
There was a problem hiding this comment.
[MINOR] This hook still runs before the Telegram early-return below, so active Codex sessions opened in the Mini App will fetch /codex-subscription-limits and route an RPC that can spawn codex app-server, even though SessionHeader returns null and never renders the quota badge in Telegram.
Suggested fix:
const telegramHeaderHidden = isTelegramApp()
const codexLimitsState = useCodexSubscriptionLimits({
api,
sessionId: session.id,
model: session.model ?? null,
enabled: !telegramHeaderHidden && session.active && session.metadata?.flavor === 'codex',
thinking: props.status?.thinking ?? session.thinking
})
if (telegramHeaderHidden) {
return null
}
Summary
Testing
AI assistance