feat(chat): stop an in-flight answer — Send becomes Stop, the partial is kept and persisted, the model stream is torn down

This commit is contained in:
2026-08-29 17:27:04 -04:00
parent 6bf7f456d4
commit 1a60ecbd8b
186 changed files with 1738 additions and 7796 deletions
@@ -1,60 +0,0 @@
# Task 01 — Diagnose and fix the animated background (styles.css)
**Phase:** `22_background_animation` · **Source:** `TODO.md` L5 —
*"Fix background animation not working, just blinking"*
## Objective
Find why the phase-08 animated background reads as "just blinking" and
fix `styles.css` so the grid drift and the glow breathe are both visibly
and smoothly alive, per the phase-08 design comments (pure CSS, zero JS).
## Work
1. **Reproduce:** `uv run uvicorn app.main:app --reload` (db up), open `/`
in a visible Chromium window (Playwright or the interactive browser),
observe ≥15s. Note exactly what moves and what doesn't.
2. **Diagnose per the `00_phase.md` checklist** (per-layer visibility
toggles, `background-position` samples on `body::before`, mask
inspection, occlusion check against `html`/`body` rules, glow
opacity-swing perception). Record findings + before-screenshot in
`.agent/reports/22_background_animation/` and
`.agent/screenshots/22_background_animation/`.
**ASSUMPTION (to verify, not assume):** the likely culprits, in
order — (a) the masked grid drift is too faint/slow to perceive,
(b) only the glow opacity swing is visible and it reads as a blink,
(c) a later rule occludes the `z-index: -1` layers. Confirm which
one actually fires before touching CSS; the fix must match the found
cause.
3. **Fix in `frontend/assets/styles.css`** (smallest change that makes
the design read):
- grid: raise line alpha and/or the mask's visible radius and/or the
drift speed as needed for a clearly visible, seamless drift
(drift delta must still equal one 44px cell for a seamless loop —
if the speed changes, keep `background-position` 0→44px and only
move the duration);
- glow: if the breathe reads as a blink, narrow the opacity delta
(e.g. 0.8↔1) and/or lengthen the period — it must read as
breathing, not pulsing;
- keep: both layers `position: fixed; inset: 0; z-index: -1;
pointer-events: none`; no `filter: blur`; no JS; palette/contrast
untouched.
4. **After-screenshot** (same viewport, two frames a few seconds apart
showing motion) into the same screenshots dir.
5. `tests/unit/test_background_animation.py` (new — repo source-pin
pattern): pin the **final** `styles.css` values — both
`@keyframes` present, `body::before` → `bg-grid-drift linear
infinite`, `body::after` → `bg-glow-breathe`, both layers
`fixed`/`z-index: -1`/`pointer-events: none`, `html` keeps
`background: var(--bg)`, `body` keeps `background: transparent`.
6. Manual re-verify: the "just blinking" perception is gone — smooth
drift + gentle breathe, no jank, no static frame.
## Testing & Quality
- `uv run pytest tests/unit/test_background_animation.py -v` green.
- `uv run ruff check . && uv run pyright` clean.
## Completion Criteria
- [ ] Root cause documented (with before/after screenshots) in the
phase report dir.
- [ ] Both layers visibly animate as the phase-08 design describes;
pure CSS, zero JS, no blur.
- [ ] Unit pins green against the final values; lint/types clean.