aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/core/core-bundle.js20
-rw-r--r--modules/core/module-loader.js2
-rw-r--r--modules/core/ollama-manager.js20
3 files changed, 41 insertions, 1 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) {
diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js
index e1ed716..2cb5003 100644
--- a/modules/core/module-loader.js
+++ b/modules/core/module-loader.js
@@ -4,7 +4,7 @@
// Core module bundle loaded synchronously in main.html.
// This loader only handles version cache-busting, splash, terminal init, and optional ext modules.
- const LATEST_VER = 'v4.6.143';
+ const LATEST_VER = 'v4.6.144';
const CACHE = '?v=' + LATEST_VER;
// Exposed so ext modules can register their own URL with the same cache-busting version
// instead of an unversioned path the browser may already have cached (shell.js did).
diff --git a/modules/core/ollama-manager.js b/modules/core/ollama-manager.js
index 1201280..5684210 100644
--- a/modules/core/ollama-manager.js
+++ b/modules/core/ollama-manager.js
@@ -27,6 +27,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) ---
@@ -123,6 +139,7 @@ class OllamaManager {
enabled: true
}];
}
+ this.providers.forEach(p => { if (p.endpoint) p.endpoint = p.endpoint.replace(/\/+$/, ''); });
}
_saveProviders() {
@@ -633,6 +650,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);
@@ -1041,6 +1059,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 };
@@ -1294,6 +1313,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) {