diff --git a/src/flask/static/css/app.css b/src/flask/static/css/app.css index f99a72f..fb54866 100644 --- a/src/flask/static/css/app.css +++ b/src/flask/static/css/app.css @@ -716,6 +716,12 @@ table.data .comment { color: var(--text-muted); font-size: .84rem; } color: var(--amber-text); } +/* The advice on the active-beers card and the run detail page - the + full text, not the clamped table cell. */ +.advice--reading { + margin-top: .5rem; +} + /* Advice that could not be generated - it says why. */ .advice--failed { border-left-color: var(--danger); diff --git a/src/flask/views/brews.py b/src/flask/views/brews.py index 9c92aa9..5c6045b 100644 --- a/src/flask/views/brews.py +++ b/src/flask/views/brews.py @@ -60,7 +60,8 @@ def _start_advice(run_id: str, reading_id: str, corrected: bool = False) -> None comment is never touched. The background thread cannot use the request-scoped repository - that - client is closed when the request ends - so it builds its own. + client is closed when the request ends - so it uses the shared + process-wide one. """ if not reading_id: return @@ -130,7 +131,18 @@ def _start_advice(run_id: str, reading_id: str, corrected: bool = False) -> None try: shared = get_shared_repository() - shared.set_reading_advice(read_id, text, ok, expected_sg=advice_sg) + written = shared.set_reading_advice(read_id, text, ok, + expected_sg=advice_sg) + if not written: + # The reading was corrected while the advice was being + # generated, so the advice no longer matches it. That is + # the guard working - the fresh advice for the corrected + # reading will land in its own turn. + log.info( + "the advice for reading %s was not stored: the reading " + "no longer holds the gravity it was written for", + read_id, + ) except Exception: # noqa: BLE001 - never let the thread die noisily log.exception("could not store the generated advice") diff --git a/tests/test_brew_advice.py b/tests/test_brew_advice.py index 4222718..f5db183 100644 --- a/tests/test_brew_advice.py +++ b/tests/test_brew_advice.py @@ -498,6 +498,20 @@ def test_the_advice_is_about_the_reading_that_was_saved(): "the advice was generated about the wrong reading" ) + # And the PROMPT must ask about that reading - not just pass it + # through. Asserting only which dict was passed would not have + # caught the prompt still saying "give advice for the most recent + # reading", which is the bug that made the model advise about the + # wrong number. + prompt = brew_advice.build_prompt( + {"canonical_name": "Ale"}, + captured["reading"], + captured["history"], + ) + assert "THIS IS THE READING TO ADVISE ON" in prompt + assert "2026-01-01" in prompt + assert "most recent reading" not in prompt + def test_the_shared_repository_is_built_only_once(): """Concurrent advice threads must not each build their own client.