You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9a5931c
Browse filesBrowse the repository at this point in the historyBrowse files
fix(cloud): three review findings from #92, and the BYOK fallback it broke
1. A failed chat request threw instead of showing its error. handleSend declared
`req` inside the try and read it in the catch, so every non-aborted failure — a
BYOK provider error included — was a ReferenceError, and the webview was left
in its streaming state. `req` now lives outside the try, with a value the catch
can read even when preparing the request is the thing that threw.
2. A refresh that merely failed signed the user out. With (1) fixed, that same
catch ran sessionExpired() on any gateway 401 — including one whose refresh was
offline, a 503, or unparseable, which classifyRefresh deliberately answers with
"keep the tokens". The catch no longer ends anything; exactly one caller does,
the refresh endpoint answering 401. It shows the sign-in card only once the
session HAS ended (!cloudSignedIn), the rule the agent hook already used.
Otherwise the request's own error is shown, the credentials stay, and the next
message tries the refresh again.
3. An expiry found with the chat closed was never shown. The focus check can end
the session with no webview to hear about it: post() drops the card, and the
next `ready` finds no token and returns. sessionExpired() now leaves a marker
in globalState — written before the tokens are deleted, so a crash in between
cannot lose it — and `ready` replays the card from it. Last, so the card lands
under a replayed transcript instead of above it; that also covers a new chat, a
resumed session, and the chat moving to an editor tab, each of which loads a
fresh document. The marker goes when the user answers: signs in, signs out, or
picks "Use my own key instead", which now takes the card away too.
4. Not in the review: this change made BYOK unreachable by default.
prepProviderRequest answered "signed out" for ANY gateway-mode request with no
token. Gateway is the default mode and levelcode.ai the default host, so that
was everyone using LevelCode on their own key with no account: chat and agent
said "Your session has expired", inline edit said "No API key set for LevelCode
Cloud", and completions stopped — where the setting promises "automatically
fall back to BYOK when you're signed out". The branch now hangs off the marker
from (3). Only a session that ENDED stops a request to ask for a sign-in; it
still never prompts for a key that user never needed.
Verified: 43 suites, 722 cases, 0 failing. sessionExpiredHost.test.js is new (25
cases) and RUNS the host code — sliced out of extension.js, against stand-ins for
SecretStorage, globalState, fetch and the adapter, on the defaults package.json
ships. The string guards all passed with (1) in place, which is why reading the
source was not enough. Each defect put back in turn fails its own case: `req` in
the try -> "req is not defined"; sessionExpired() in the catch -> "access token
kept"; no marker -> the closed-chat replay; the token-only branch -> a BYOK user's
message never reaches the provider. sessionExpiredUi.test.js goes from 10 to 16:
the order of `ready`, and the card run against a stand-in DOM. tsc --checkJs
reports "Cannot find name 'req'" at the old line 2095 and no unresolved name in
extension.js after. The card flows were also driven in headless Chrome against
the real chat.html.
0 commit comments