fix(assistant): #91 bulle utilisateur elargie (81% du fil) + ancrage de la question des l'envoi ; docs: feuille de route outils #92
CI / lint (push) Successful in 1m23s
CI / security (push) Successful in 58s
CI / test (push) Successful in 2m37s
CI / build (push) Successful in 51s
CI / e2e (push) Successful in 10m47s

This commit is contained in:
2026-09-15 19:34:05 -04:00
parent 0e9fcb78e0
commit 1ed0d52619
8 changed files with 182 additions and 9 deletions
+33
View File
@@ -235,6 +235,39 @@ async function main() {
panel.remove();
});
await test("the placeholder render keeps the anchor (no scroll reset before first token)", async () => {
// Regression: the assistant placeholder used to be rendered while
// `_isLoading` was still false, so it took the "restore previous
// scroll" branch and cancelled the anchor — the submitted post stayed
// at the bottom until the first streamed token.
const b = new BooksLM();
const panel = b._render();
b._panel = panel;
document.body.appendChild(panel);
const renders = [];
const realRender = b._renderMessages.bind(b);
b._renderMessages = (opts) => { renders.push(opts || {}); realRender(opts || {}); };
b._setActivity = () => {};
b._saveHistory = () => {};
b._postChat = async () => ({
ok: true,
status: 200,
body: { getReader: () => ({ read: async () => ({ done: true }) }) },
});
panel.querySelector("textarea").value = "Question ancrée";
await b._sendMessage();
// Two renders happen on send: the user post and the assistant
// placeholder — both must request the anchor.
assert.ok(renders.length >= 2, `expected >=2 renders, got ${renders.length}`);
assert.equal(renders[0].anchor, true, "user post render anchors");
assert.equal(renders[1].anchor, true, "placeholder render anchors too");
// Both must be instant: the question has to be at the top when the
// answer starts arriving, not after a scroll animation.
assert.equal(renders[0].instant, true, "user post anchors instantly");
assert.equal(renders[1].instant, true, "placeholder anchors instantly");
panel.remove();
});
await test("assistant answer shows a discreet provider/model tag", () => {
const b = new BooksLM();
const panel = b._render();