Skip to content

Commit d67e1f7

Browse files
scszcoderclaude
andcommitted
ws040: deliver name-less card reply by resolving its sidebar row (real fix)
Root cause of the card stall (confirmed via ws038/039 probe + live DOM): a name-less card dispatches under a synthetic 'card:<conv>' name (ws033c), but feige_send_message matches the sidebar row BY NAME, and the real row is 'sc' -> "Session not found" -> requeue loop. There is NO shared id to map the WS card to its DOM row: the row exposes only name + btm tracking ids + avatar; the talk_id/uid appear nowhere on it, and the display name is DOM/HTTP-only (the avatar uid is in an HTTP answerRecommend call, not WS). Fix: when the synthetic 'card:' name can't be matched, resolve the card's conversation ROW directly — the UNIQUE sidebar row whose preview starts '[商品' AND whose class has 'needReply'. If exactly one -> deliver to its real name (rebind expectedCustomer so all crosstalk guards verify the actual conv). If 0 or >1 -> fall through to not-found + requeue (NEVER guess -> mis-delivery-safe). Gated to synthetic 'card:' names only; named-customer + text delivery untouched. Selectors verified against the live sidebar DOM (msgContent '[商品]', nameLine/newNameContent 'sc', needReply-* class). Needs a live run to confirm the full send flow (browser JS can't be simulated offline). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent fa2ee0b commit d67e1f7

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

agent/ec_skills/browser_use_extension/extension_tools_service.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,6 +4576,33 @@ async def feige_get_chat_thread(params: FeigeGetChatThreadAction, browser_sessio
45764576
for (var oi = 0; oi < items.length; oi++) {
45774577
if (readRowName(items[oi]) === expectedCustomer) { target = items[oi]; break; }
45784578
}
4579+
// ws040: a name-less product card dispatches under a synthetic 'card:<conv>'
4580+
// name (the WS card frame carries no nickname; the display name lives ONLY in
4581+
// the DOM/HTTP, with NO id to map the WS card back to its sidebar row). So when
4582+
// the synthetic name can't be matched by name above, fall back to the card's
4583+
// CONVERSATION ROW: the UNIQUE sidebar row that is a product card needing reply
4584+
// (preview starts '[商品' AND className has 'needReply'). Mis-delivery-safe by
4585+
// construction — if 0 or >1 such rows exist we DON'T guess; we fall through to
4586+
// the not-found return and requeue. Only the synthetic 'card:' name reaches
4587+
// here (named customers + text matched by name above), so normal delivery is
4588+
// untouched. On a hit we rebind expectedCustomer to the row's REAL name so
4589+
// every crosstalk/active-session guard below verifies the actual conversation.
4590+
if (!target && expectedCustomer.indexOf('card:') === 0) {
4591+
var cardRows = [];
4592+
for (var ci = 0; ci < items.length; ci++) {
4593+
var pv = readRowPreview(items[ci]);
4594+
var cls = String(items[ci].className || '');
4595+
if (pv && pv.indexOf('[商品') === 0 && /needReply/.test(cls)) {
4596+
cardRows.push(items[ci]);
4597+
}
4598+
}
4599+
if (cardRows.length === 1) {
4600+
target = cardRows[0];
4601+
var resolvedCardName = readRowName(target);
4602+
if (resolvedCardName) expectedCustomer = resolvedCardName;
4603+
markPhase('card_row_resolved');
4604+
}
4605+
}
45794606
if (!target) {
45804607
markPhase('target_not_found');
45814608
return finish({

0 commit comments

Comments
 (0)