From 62cea2eee425c499a55731d3b33e4610de873030 Mon Sep 17 00:00:00 2001 From: Its My Work Date: Mon, 14 Sep 2026 04:34:38 +0000 Subject: [PATCH] fix(engine): don't send the first message before the real default loads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _globalDefaultEngine starts hardcoded 'api' and only becomes the actual configured default once checkVersion()'s /api/version fetch resolves and calls resolveEngineForView(). A message sent before that fetch landed — in practice, the very first message on a freshly loaded page — went out with curEngine still on that placeholder 'api'. The server bakes whatever `engine` arrives into the session's run_engine permanently (server.js ~11914), so this silently and irreversibly routed that chat's billing through the API key instead of the user's actually configured Subscription default, for the life of the chat. Capture checkVersion()'s promise as _versionCheckDone and await it at the top of send() — a no-op once already resolved, so this costs nothing beyond the first message of a session. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_011E2bJQ2sL9LgEWosjvydTR --- public/index.html | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 7964e5e..57b52e0 100644 --- a/public/index.html +++ b/public/index.html @@ -11838,6 +11838,17 @@

Delegate to Agent

function sendChat(text) { inEl.value = text; send(); } async function send() { + // _globalDefaultEngine starts hardcoded 'api' and only becomes the real + // configured default once checkVersion()'s /api/version fetch resolves + // (see resolveEngineForView()). A message sent before that fetch lands — + // e.g. the very first message of a fresh page load — used to go out with + // curEngine still on that placeholder 'api', and the server bakes whatever + // `engine` arrives into the session's run_engine permanently (server.js + // ~11914). That silently routed billing through the API key instead of the + // user's actually-configured Subscription default, and stuck that way for + // the life of the chat. Awaiting an already-settled promise is a no-op, so + // this costs nothing once the page has been open for more than an instant. + if (typeof _versionCheckDone !== 'undefined') { try { await _versionCheckDone; } catch {} } if (!ws || ws.readyState !== 1) { toast(t('toast.no_connection'), true); return; } const txt = inEl.value.trim(); @@ -17571,7 +17582,7 @@

Delegate to Agent

_projectsReady = loadProjectsList(); loadRemoteHosts(); connect(); -checkVersion(); +let _versionCheckDone = checkVersion(); // ─── Image chip hover preview ─── { const _prev = $i('imgChipPreview');