aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-10-23 20:25:19 +0200
committerAgando <roduccomm@gmail.com>2026-10-23 20:25:19 +0200
commit8e942d0eacf9e6e46fec1e51d6c18ea40afe3310 (patch)
treeca03eac5debd107edc9809344f9a1ef11a1b2121
parent492cbe7c24bc84b4f541235e62adce19fc690e35 (diff)
fix(newos4): agent read gets its own chat cursor (v4.6.76)
Two readers shared one cursor. The 30 s UI poller printed each reply and advanced webx11_chat_state.cursor, so the agent's chat_hermes read then asked for 'since=<that>' and got an empty list — the answer appeared on the terminal and never reached the model. That is the reported symptom exactly. chat_hermes read now uses webx11_chat_agent_cursor, starts from 0 on first use so the whole thread is visible, and never touches the display cursor. Empty reads say why ('still awaiting Hermes' vs 'no new messages since your last read'). Proven: UI poll consumed the reply (printed to terminal), then chat_hermes read still returned both the agent's question and Hermes's answer.
-rw-r--r--main.html6
-rw-r--r--modules/core/core-bundle.js20
-rw-r--r--modules/core/module-aiassist.js20
-rw-r--r--modules/core/module-loader.js2
4 files changed, 34 insertions, 14 deletions
diff --git a/main.html b/main.html
index 49df90d..23ab761 100644
--- a/main.html
+++ b/main.html
@@ -1349,13 +1349,13 @@
</script>
<!-- v4.5.63: A2A scratchpad fixes + agent-register arg fix -->
-<script src="modules/core/core-bundle.js?v=v4.6.75"></script>
+<script src="modules/core/core-bundle.js?v=v4.6.76"></script>
<!-- Async dependency-ordered module loader now only initializes terminal and loads optional ext modules -->
-<script src="modules/core/module-loader.js?v=v4.6.75"></script>
+<script src="modules/core/module-loader.js?v=v4.6.76"></script>
<!-- Critical ext bundle loads AFTER webx11 exists so registerModule calls work -->
-<script src="modules/ext/critical-ext-bundle.js?v=v4.6.75"></script>
+<script src="modules/ext/critical-ext-bundle.js?v=v4.6.76"></script>
<script>
// ═══ ONE TRUE VERSION SOURCE ═══
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js
index a689774..697b5ec 100644
--- a/modules/core/core-bundle.js
+++ b/modules/core/core-bundle.js
@@ -11094,19 +11094,29 @@ buildSystemPrompt() {
});
}
const st = ds._chatThread();
+ // v4.6.76: a SEPARATE cursor from the terminal display. The UI poller
+ // runs every 30 s and advances the shared cursor, so a read that used it
+ // returned nothing — the answer was printed for the human and the model
+ // never saw it. Two readers, two cursors. First read is from 0.
+ let ac = 0;
+ try { ac = parseInt(localStorage.getItem('webx11_chat_agent_cursor') || '0', 10) || 0; } catch (e) { ac = 0; }
const resp = await fetch(
- '/spaces/newos4/api/chat/poll.php' + (st.cursor ? '?since=' + st.cursor : ''),
+ '/spaces/newos4/api/chat/poll.php' + (ac ? '?since=' + ac : ''),
{ headers: { 'X-Chat-Token': st.token } });
const j = await resp.json().catch(() => null);
if (!resp.ok || !j || !j.success) {
return JSON.stringify({ error: (j && j.error) || ('HTTP ' + resp.status) });
}
- if (j.cursor) ds._chatSaveState({ token: st.token, cursor: j.cursor, thread: j.thread || '' });
+ if (j.cursor) { try { localStorage.setItem('webx11_chat_agent_cursor', String(j.cursor)); } catch (e) {} }
+ const msgs = (j.messages || []).slice(-10).map(m => ({
+ author: m.author, ts: m.ts, text: m.text
+ }));
return JSON.stringify({
awaiting: j.awaiting,
- messages: (j.messages || []).slice(-10).map(m => ({
- author: m.author, ts: m.ts, text: m.text
- }))
+ messages: msgs,
+ note: msgs.length ? undefined
+ : (j.awaiting ? 'no reply yet — still awaiting Hermes'
+ : 'no new messages since your last read')
});
} catch (e) {
return JSON.stringify({ error: e.message });
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js
index ce650b9..cefff5d 100644
--- a/modules/core/module-aiassist.js
+++ b/modules/core/module-aiassist.js
@@ -2707,19 +2707,29 @@ buildSystemPrompt() {
});
}
const st = ds._chatThread();
+ // v4.6.76: a SEPARATE cursor from the terminal display. The UI poller
+ // runs every 30 s and advances the shared cursor, so a read that used it
+ // returned nothing — the answer was printed for the human and the model
+ // never saw it. Two readers, two cursors. First read is from 0.
+ let ac = 0;
+ try { ac = parseInt(localStorage.getItem('webx11_chat_agent_cursor') || '0', 10) || 0; } catch (e) { ac = 0; }
const resp = await fetch(
- '/spaces/newos4/api/chat/poll.php' + (st.cursor ? '?since=' + st.cursor : ''),
+ '/spaces/newos4/api/chat/poll.php' + (ac ? '?since=' + ac : ''),
{ headers: { 'X-Chat-Token': st.token } });
const j = await resp.json().catch(() => null);
if (!resp.ok || !j || !j.success) {
return JSON.stringify({ error: (j && j.error) || ('HTTP ' + resp.status) });
}
- if (j.cursor) ds._chatSaveState({ token: st.token, cursor: j.cursor, thread: j.thread || '' });
+ if (j.cursor) { try { localStorage.setItem('webx11_chat_agent_cursor', String(j.cursor)); } catch (e) {} }
+ const msgs = (j.messages || []).slice(-10).map(m => ({
+ author: m.author, ts: m.ts, text: m.text
+ }));
return JSON.stringify({
awaiting: j.awaiting,
- messages: (j.messages || []).slice(-10).map(m => ({
- author: m.author, ts: m.ts, text: m.text
- }))
+ messages: msgs,
+ note: msgs.length ? undefined
+ : (j.awaiting ? 'no reply yet — still awaiting Hermes'
+ : 'no new messages since your last read')
});
} catch (e) {
return JSON.stringify({ error: e.message });
diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js
index 678cdda..e52a846 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.75';
+ const LATEST_VER = 'v4.6.76';
const CACHE = '?v=' + LATEST_VER;
const stored = localStorage.getItem('webx11_cache_ver');
if (stored !== LATEST_VER) {