diff --git a/apps/macos/Sources/Clawdis/Resources/WebChat/bootstrap.js b/apps/macos/Sources/Clawdis/Resources/WebChat/bootstrap.js index c04b2d4ea..bcccdd2c0 100644 --- a/apps/macos/Sources/Clawdis/Resources/WebChat/bootstrap.js +++ b/apps/macos/Sources/Clawdis/Resources/WebChat/bootstrap.js @@ -35,6 +35,13 @@ async function fetchBootstrap() { }; } +function latestTimestamp(messages) { + if (!Array.isArray(messages) || messages.length === 0) return 0; + const withTs = messages.filter((m) => typeof m?.timestamp === "number"); + if (withTs.length === 0) return messages.length; // best-effort monotonic fallback + return withTs[withTs.length - 1].timestamp; +} + class NativeTransport { constructor(sessionKey) { this.sessionKey = sessionKey; @@ -190,6 +197,43 @@ const startChat = async () => { mount.textContent = ""; mount.appendChild(panel); logStatus("boot: ready"); + + // Periodically sync messages + thinking from the session store so webchat stays + // in lock-step with other transports (e.g., WhatsApp or CLI). + let lastSyncedTs = latestTimestamp(initialMessages); + const syncIntervalMs = 3000; + async function syncFromSession() { + if (agent.state.isStreaming) return; // avoid stomping in-flight turns + try { + const infoUrl = new URL(`./info?session=${encodeURIComponent(sessionKey)}`, window.location.href); + const resp = await fetch(infoUrl, { credentials: "omit" }); + if (!resp.ok) return; + const info = await resp.json(); + const messages = Array.isArray(info.initialMessages) ? info.initialMessages : []; + const ts = latestTimestamp(messages); + const thinking = typeof info.thinkingLevel === "string" ? info.thinkingLevel : "off"; + + if (ts && ts !== lastSyncedTs) { + agent.replaceMessages(messages); + lastSyncedTs = ts; + } + + if (thinking && thinking !== agent.state.thinkingLevel) { + agent.setThinkingLevel(thinking); + if (panel?.agentInterface) { + panel.agentInterface.sessionThinkingLevel = thinking; + panel.agentInterface.pendingThinkingLevel = null; + if (panel.agentInterface._messageEditor) { + panel.agentInterface._messageEditor.thinkingLevel = thinking; + } + } + } + } catch (err) { + console.warn("session sync failed", err); + } + } + + setInterval(syncFromSession, syncIntervalMs); }; startChat().catch((err) => { diff --git a/apps/macos/Sources/Clawdis/Resources/WebChat/webchat.bundle.js b/apps/macos/Sources/Clawdis/Resources/WebChat/webchat.bundle.js index 8a0436065..da7daf911 100644 --- a/apps/macos/Sources/Clawdis/Resources/WebChat/webchat.bundle.js +++ b/apps/macos/Sources/Clawdis/Resources/WebChat/webchat.bundle.js @@ -196294,6 +196294,12 @@ async function fetchBootstrap() { thinkingLevel: typeof info$1.thinkingLevel === "string" ? info$1.thinkingLevel : "off" }; } +function latestTimestamp(messages) { + if (!Array.isArray(messages) || messages.length === 0) return 0; + const withTs = messages.filter((m$3) => typeof m$3?.timestamp === "number"); + if (withTs.length === 0) return messages.length; + return withTs[withTs.length - 1].timestamp; +} var NativeTransport = class { constructor(sessionKey) { this.sessionKey = sessionKey; @@ -196448,6 +196454,37 @@ const startChat = async () => { mount.textContent = ""; mount.appendChild(panel); logStatus("boot: ready"); + let lastSyncedTs = latestTimestamp(initialMessages); + const syncIntervalMs = 3e3; + async function syncFromSession() { + if (agent.state.isStreaming) return; + try { + const infoUrl = new URL(`./info?session=${encodeURIComponent(sessionKey)}`, window.location.href); + const resp = await fetch(infoUrl, { credentials: "omit" }); + if (!resp.ok) return; + const info$1 = await resp.json(); + const messages = Array.isArray(info$1.initialMessages) ? info$1.initialMessages : []; + const ts = latestTimestamp(messages); + const thinking = typeof info$1.thinkingLevel === "string" ? info$1.thinkingLevel : "off"; + if (ts && ts !== lastSyncedTs) { + agent.replaceMessages(messages); + lastSyncedTs = ts; + } + if (thinking && thinking !== agent.state.thinkingLevel) { + agent.setThinkingLevel(thinking); + if (panel?.agentInterface) { + panel.agentInterface.sessionThinkingLevel = thinking; + panel.agentInterface.pendingThinkingLevel = null; + if (panel.agentInterface._messageEditor) { + panel.agentInterface._messageEditor.thinkingLevel = thinking; + } + } + } + } catch (err) { + console.warn("session sync failed", err); + } + } + setInterval(syncFromSession, syncIntervalMs); }; startChat().catch((err) => { const msg = err?.stack || err?.message || String(err);