steering demoable: the Enter branch keys on BUSY (own-stream clears turnInFlight — Enter was swallowed during our own turn), and the button follows the text (owner live report 2026-10-03)
Root cause: doSteerOrSend branched on turnInFlight, but the local dedup (chat.tsx ~370) clears that flag the moment the own stream takes over — during our own turn busy was true and turnInFlight false, so Enter fell to the plain-send path whose busy guard returned silently. Branch on busy: own stream AND foreign/wake turns both have a live agent registered by the time the send's POST resolved, so the steer lands (a raced settle 409s and falls back to the plain send). The button now follows the text: busy + typed text = Send (click steers — steering must be clickable, not Enter-only); busy + empty = Stop. ESC keeps its confirm-popup abort in every state, so stop is never unreachable.
This commit is contained in:
@@ -40,9 +40,12 @@ describe("Composer", () => {
|
||||
assert.ok(!html.includes("Ask, answer"), "the session placeholder must not ride along");
|
||||
});
|
||||
|
||||
it("busy: send button becomes stop", () => {
|
||||
const html = render({ busy: true });
|
||||
assert.ok(html.includes('aria-label="Stop"'), "stop replaces send while streaming");
|
||||
it("busy with text: the button STAYS Send (click = steer); busy and empty: it becomes Stop", () => {
|
||||
const steering = render({ busy: true, canSend: true });
|
||||
assert.ok(steering.includes('aria-label="Send"'), "the steer affordance is clickable mid-turn");
|
||||
assert.ok(!steering.includes('aria-label="Stop"'), "no morph while there is text to steer with");
|
||||
const idleStop = render({ busy: true, canSend: false });
|
||||
assert.ok(idleStop.includes('aria-label="Stop"'), "empty composer: stop replaces send while streaming");
|
||||
});
|
||||
|
||||
it("send button radius is 10px = 25% of the 40px button (concentric with the shell)", () => {
|
||||
|
||||
Reference in New Issue
Block a user