aboutsummaryrefslogtreecommitdiff
path: root/modules/core/core-bundle.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/core-bundle.js')
-rw-r--r--modules/core/core-bundle.js20
1 files changed, 20 insertions, 0 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js
index 2a7ec3e..6a37d61 100644
--- a/modules/core/core-bundle.js
+++ b/modules/core/core-bundle.js
@@ -1307,6 +1307,22 @@ class OllamaManager {
return err;
}
+ _sessionRepairNotice() {
+ // A 401 here means the cookie/Bearer we sent is not in any session store: the store
+ // moved on (another device signed in, poll race, expired) and this tab kept the old
+ // value. Clear the local copy so the next attempt is anonymous-demo instead of a
+ // permanent 401, and say what to do. (2026-11-02)
+ try {
+ localStorage.removeItem('webx11_session_id');
+ localStorage.removeItem('webx11_session');
+ localStorage.removeItem('webx11_encrypted_session');
+ document.cookie = 'webx11_session=; path=/; max-age=0';
+ } catch (e) {}
+ this.terminal.print('πŸ”’ Your login session is no longer valid on the server. ' +
+ 'Open https://webx11.duckdns.org/dashboard.html , sign in with Telegram ' +
+ '(or β€œSign in with a code”), then reload this page.', 'warning');
+ }
+
constructor(terminal) {
this.terminal = terminal;
// --- Backward-compat properties (reflected from active provider) ---
@@ -1403,6 +1419,7 @@ class OllamaManager {
enabled: true
}];
}
+ this.providers.forEach(p => { if (p.endpoint) p.endpoint = p.endpoint.replace(/\/+$/, ''); });
}
_saveProviders() {
@@ -1913,6 +1930,7 @@ class OllamaManager {
} catch (error) {
// Remember why this provider failed so chat() can name the real cause
// instead of falling back to the generic "No provider responded".
+ if (error.status === 401) { this._sessionRepairNotice(); }
this._lastChatError = error.message || String(error);
if (fullText && fullText.length > 0) {
this.terminal.printStreamingResponse(`\n\n[Stream error: ${error.message}]`, true);
@@ -2321,6 +2339,7 @@ class OllamaManager {
if (error.message === 'Failed to fetch' && provider.type === 'ollama') {
return await this.chatWithToolsFallback(messages, tools, useModel);
}
+ if (error.status === 401) { this._sessionRepairNotice(); }
this.terminal.print(`${provider.name} /api/chat error: ${error.message}`, 'error');
this._lastChatError = error.message || String(error);
return { message: null, tool_calls: null, error: error.message };
@@ -2574,6 +2593,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
// ─── Backward-compat methods ─────────────────────────────────────────────
setEndpoint(url) {
+ if (typeof url === 'string') url = url.replace(/\/+$/, '');
this.endpoint = url;
// Also update the current provider's endpoint if it exists
if (this.currentProvider) {