Fix sidechat CDP and button selectors\n\n- sidechat_manager._ev: use id=1 and returnByValue to match ev()\n- cmd_sidechat_create: find + button via Side chats header proximity\n- cmd_sidechat_create: use cmd_send for initial message (not DOM hack)\n- Integrate ensure_sidebar with retry
This commit is contained in:
+34
-20
@@ -279,16 +279,40 @@ def cmd_sidechat_create(ws):
|
||||
if (btn) btn.click();
|
||||
})()""")
|
||||
_time.sleep(2)
|
||||
# The + button sits next to the "Side chats" header (see screenshot 2026-10-04).
|
||||
# It's not labeled "New side chat" - find it by proximity to the header text.
|
||||
result = ev(ws, """(() => {
|
||||
const btn = [...document.querySelectorAll('button')].find(b =>
|
||||
// Strategy 1: Find button with "+" text near "Side chats"
|
||||
const header = [...document.querySelectorAll('*')].find(el =>
|
||||
el.textContent.trim() === 'Side chats' && el.children.length === 0);
|
||||
if (header) {
|
||||
// Look for + button in the header's parent or siblings
|
||||
const parent = header.parentElement;
|
||||
if (parent) {
|
||||
const plus = [...parent.querySelectorAll('button')].find(b =>
|
||||
(b.textContent||'').includes('+') || (b.getAttribute('aria-label')||'').toLowerCase().includes('add'));
|
||||
if (plus) { plus.click(); return 'CLICKED_VIA_HEADER'; }
|
||||
}
|
||||
}
|
||||
// Strategy 2: Find any button with "+" that's near the top
|
||||
const plusBtn = [...document.querySelectorAll('button')].find(b => {
|
||||
const t = (b.textContent||'').trim();
|
||||
const al = (b.getAttribute('aria-label')||'').toLowerCase();
|
||||
return t === '+' || al.includes('new side') || al.includes('add chat');
|
||||
});
|
||||
if (plusBtn) { plusBtn.click(); return 'CLICKED_VIA_PLUS'; }
|
||||
// Strategy 3 (fallback): old aria-label exact match
|
||||
const oldBtn = [...document.querySelectorAll('button')].find(b =>
|
||||
(b.getAttribute('aria-label')||'') === 'New side chat');
|
||||
if (!btn) return 'NOT_FOUND';
|
||||
btn.click();
|
||||
return 'CLICKED';
|
||||
if (oldBtn) { oldBtn.click(); return 'CLICKED_VIA_ARIA'; }
|
||||
return 'NOT_FOUND';
|
||||
})()""")
|
||||
if result == 'NOT_FOUND':
|
||||
print("ERROR: 'New side chat' button not found (sidebar may be closed)", file=sys.stderr)
|
||||
print("ERROR: New side chat + button not found (sidebar may be closed)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
# Log which strategy worked for debugging
|
||||
import sys as _sys
|
||||
print(f"Sidechat create: {result}", file=_sys.stderr)
|
||||
import time as _time
|
||||
# Poll for URL to change to a thread URL (up to 15s)
|
||||
# Fixed 2026-10-04: was sleeping 5s and reading once, often captured
|
||||
@@ -306,21 +330,11 @@ def cmd_sidechat_create(ws):
|
||||
# the first message. Send a system message to trigger ID assignment,
|
||||
# then re-read the URL.
|
||||
if url.endswith("/thread/new"):
|
||||
ev(ws, """(() => {
|
||||
const input = document.querySelector('[contenteditable="true"]');
|
||||
if (!input) return 'NO_INPUT';
|
||||
input.focus();
|
||||
document.execCommand('insertText', false, '[System: Side chat created]');
|
||||
return 'READY';
|
||||
})()""")
|
||||
_time.sleep(1)
|
||||
# Click send
|
||||
ev(ws, """(() => {
|
||||
const btn = [...document.querySelectorAll('button')].find(b =>
|
||||
(b.getAttribute('aria-label')||'').toLowerCase().includes('send'));
|
||||
if (btn) { btn.click(); return 'SENT'; }
|
||||
return 'NO_BTN';
|
||||
})()""")
|
||||
# Use proven cmd_send to trigger real thread ID
|
||||
try:
|
||||
cmd_send(ws, "[System: Side chat created]")
|
||||
except Exception as e:
|
||||
print(f"Warning: initial send failed: {e}", file=sys.stderr)
|
||||
# Poll for URL to change from /thread/new to /thread/<uuid>
|
||||
for i in range(15):
|
||||
_time.sleep(1)
|
||||
|
||||
@@ -15,13 +15,13 @@ import json
|
||||
|
||||
def _ev(ws, js, await_result=True):
|
||||
"""Evaluate JS via CDP, return result.
|
||||
Uses id=1 to match muse-chat-api.py's ev() on shared websocket.
|
||||
Fixed 2026-10-04: was using id=100, causing response mismatch.
|
||||
Matches muse-chat-api.py's ev() exactly (id=1, returnByValue).
|
||||
Fixed 2026-10-04: was using id=100, missing returnByValue.
|
||||
"""
|
||||
import json as _json
|
||||
ws.send(_json.dumps({
|
||||
"id": 1, "method": "Runtime.evaluate",
|
||||
"params": {"expression": js, "awaitPromise": True}
|
||||
"params": {"expression": js, "returnByValue": True, "awaitPromise": await_result}
|
||||
}))
|
||||
resp = _json.loads(ws.recv())
|
||||
result = resp.get("result", {}).get("result", {})
|
||||
|
||||
Reference in New Issue
Block a user