Improve latest assistant response landmark

This commit is contained in:
sheldon-im
2026-06-29 22:25:45 +09:00
committed by nesquena-hermes
parent 4ef9d7c5cb
commit 944d57eedc
4 changed files with 91 additions and 0 deletions
+29
View File
@@ -453,6 +453,9 @@ const _recycleResetAttrs=[
'data-transparent-turn-toggle-bound',
'data-anchor-scene-live-owner',
'data-anchor-stream-id',
'data-latest-assistant-response',
'role',
'aria-label',
// Defensive reset for legacy/restored shells that may still carry the fallback live-turn marker.
'data-live-assistant-turn',
];
@@ -8634,6 +8637,24 @@ function _createAssistantTurn(tsTitle='', tpsText=''){
row.innerHTML=`${_assistantRoleHtml(tsTitle, tpsText)}<div class="assistant-turn-blocks"></div>`;
return row;
}
function _setLatestAssistantTurnLandmark(turn, isLatest){
if(!turn) return;
const label='Latest Hermes response';
if(isLatest){
if(typeof document!=='undefined'){
document.querySelectorAll('.assistant-turn[data-latest-assistant-response="true"]').forEach(el=>{
if(el!==turn) _setLatestAssistantTurnLandmark(el, false);
});
}
turn.setAttribute('role','region');
turn.setAttribute('aria-label',label);
turn.dataset.latestAssistantResponse='true';
return;
}
if(turn.getAttribute('role')==='region') turn.removeAttribute('role');
if(turn.getAttribute('aria-label')===label) turn.removeAttribute('aria-label');
delete turn.dataset.latestAssistantResponse;
}
function _assistantTurnBlocks(turn){
return turn?turn.querySelector('.assistant-turn-blocks'):null;
}
@@ -12342,6 +12363,13 @@ function renderMessages(options){
}catch(e){}
}
const transparentToolResultsByTid=_transparentModeActive?_collectToolResultSnippetsByTid(S.messages):{};
const latestRenderedAssistantRawIdx=(()=>{
for(let i=renderVisWithIdx.length-1;i>=0;i--){
const entry=renderVisWithIdx[i];
if(entry&&entry.m&&entry.m.role==='assistant'&&!entry.m._live) return entry.rawIdx;
}
return -1;
})();
// Windowed render loop replaces the legacy full loop:
// for(let vi=0;vi<visWithIdx.length;vi++)
for(let vi=0;vi<renderVisWithIdx.length;vi++){
@@ -12529,6 +12557,7 @@ function renderMessages(options){
currentAssistantTurn.dataset.recycleKey=rawIdx;
inner.appendChild(currentAssistantTurn);
}
_setLatestAssistantTurnLandmark(currentAssistantTurn, !m._live&&rawIdx===latestRenderedAssistantRawIdx);
const seg=document.createElement('div');
if(Array.isArray(orderedTransparentParts)&&orderedTransparentParts.length){
const blocks=_assistantTurnBlocks(currentAssistantTurn);
+54
View File
@@ -0,0 +1,54 @@
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
INDEX_HTML = (ROOT / "static" / "index.html").read_text(encoding="utf-8")
UI_JS = (ROOT / "static" / "ui.js").read_text(encoding="utf-8")
def _function_body(source: str, name: str) -> str:
start = source.find(f"function {name}(")
assert start != -1, f"{name}() not found"
end = source.find("\nfunction ", start + 1)
if end == -1:
end = len(source)
return source[start:end]
def test_conversation_transcript_is_not_a_named_region():
match = re.search(r'<div class="messages" id="messages"[^>]*>', INDEX_HTML)
assert match, "#messages container not found"
tag = match.group(0)
assert 'role="region"' not in tag
assert 'Conversation transcript' not in tag
assert "tabindex" not in tag.lower()
def test_latest_assistant_landmark_helper_is_named_but_not_focusable():
helper = _function_body(UI_JS, "_setLatestAssistantTurnLandmark")
assert "Latest Hermes response" in helper
assert "setAttribute('role','region')" in helper
assert "setAttribute('aria-label',label)" in helper
assert "data-latest-assistant-response" in helper
assert "tabindex" not in helper.lower()
assert "<h" not in helper.lower()
def test_settled_render_marks_only_the_latest_assistant_turn():
render_messages = _function_body(UI_JS, "renderMessages")
assert "const latestRenderedAssistantRawIdx=(()=>{" in render_messages
assert "if(entry&&entry.m&&entry.m.role==='assistant'&&!entry.m._live) return entry.rawIdx;" in render_messages
assert "_setLatestAssistantTurnLandmark(currentAssistantTurn, !m._live&&rawIdx===latestRenderedAssistantRawIdx);" in render_messages
assert "seg.setAttribute('role','region')" not in render_messages
assert "orderedSeg.setAttribute('role','region')" not in render_messages
def test_live_assistant_turn_paths_do_not_own_final_response_landmark():
restore_live_turn = _function_body(UI_JS, "restoreLiveTurnHtmlForSession")
render_live_scene = _function_body(UI_JS, "renderLiveAnchorActivityScene")
append_thinking = _function_body(UI_JS, "appendThinking")
assert "_setLatestAssistantTurnLandmark(restored, true);" not in restore_live_turn
assert "_setLatestAssistantTurnLandmark(turn, true);" not in render_live_scene
assert "_setLatestAssistantTurnLandmark(turn, true);" not in append_thinking
+1
View File
@@ -604,6 +604,7 @@ def test_render_messages_keeps_anchor_owned_turn_out_of_legacy_activity_rebuilds
return turn;
}}
function _assistantTurnBlocks(turn) {{ return turn ? turn.querySelector('.assistant-turn-blocks') : null; }}
function _setLatestAssistantTurnLandmark() {{}}
function _assistantRoleHtml() {{ return ''; }}
function _userMessageDomId(rawIdx) {{ return `user-${{rawIdx}}`; }}
function _messageSessionIndexForRawIdx(rawIdx) {{ return rawIdx; }}
@@ -89,6 +89,8 @@ const S = { session: { session_id: 'sess-1' } };
const _assistantRoleHtml = (title, tps) => `role:${title}:${tps}`;
const isTpsDisplayEnabled = () => true;
const _formatTurnTps = value => `tps:${value}`;
const latestRenderedAssistantRawIdx = rawIdx;
function _setLatestAssistantTurnLandmark() {}
eval(recycleChunk);
console.log(JSON.stringify({
removedAttrs,
@@ -110,6 +112,9 @@ console.log(JSON.stringify({
"data-transparent-turn-toggle-bound",
"data-anchor-scene-live-owner",
"data-anchor-stream-id",
"data-latest-assistant-response",
"role",
"aria-label",
"data-live-assistant-turn",
}
assert set(result["resetAttrs"]) == expected_attrs
@@ -155,6 +160,8 @@ const S = { session: { session_id: 'sess-1' } };
const _assistantRoleHtml = (title, tps) => `role:${title}:${tps}`;
const isTpsDisplayEnabled = () => true;
const _formatTurnTps = value => `tps:${value}`;
const latestRenderedAssistantRawIdx = rawIdx;
function _setLatestAssistantTurnLandmark() {}
eval(recycleChunk);
console.log(JSON.stringify({
blocksInnerHTML: blocks.innerHTML,