fix(advice): the stripper must DROP the working, and the token is the guard
Two findings from the fourth review. The stripper was a no-op in the case it was written for --------------------------------------------------- The "all working" branch returned the text UNCHANGED, which is byte-identical to the old fallthrough. And in the case where a preamble marker WAS present and no paragraph read like advice, it returned the whole reply - working included - so the branch made the "store the working instead of the advice" failure MORE likely, not less. Measured on a realistic 5-paragraph reasoning reply: the old code stored 80 chars (one paragraph), the new code stored 612 chars (five paragraphs) of the model's working. It now DROPS the working, so the reply is empty and the brewer sees a clear "could not be generated" rather than the model thinking about their beer. "keep" alone is not an advice marker ------------------------------------ "I need to keep in mind that the hydrometer was read at a different temperature" is the model thinking, not advice. The bare words "keep", "raise", "lower", "take the" were matching ordinary reasoning phrasing, so the "all working" detection almost never fired on real reasoning text. They are now matched as phrases - "you should keep", "raise it to", "take another reading" - and "i need to keep in mind" is explicitly working. The token is the primary guard ------------------------------ The gravity can be unparseable for some readings, so `expected_sg` can be None - and then the write was becoming unconditional, reintroducing the stale-overwrite bug on those readings. The editing token is the primary guard: it changes on EVERY edit, so it catches a stale generation whatever else changed - the gravity, the comment, or nothing. The gravity is now a secondary check, used only when there is no token. 177 tests (up from 174).
This commit is contained in:
+25
-13
@@ -271,11 +271,13 @@ def _strip_reasoning(text: str) -> str:
|
||||
# A reply that is ALL working - no advice paragraph at all - has to
|
||||
# be caught too. The marker phrases are a hint, not the only signal:
|
||||
# a reply can be pure working without ever saying "let me think".
|
||||
#
|
||||
# The working is DROPPED, not returned. Returning it unchanged would
|
||||
# be a no-op, and the brewer would be shown the model thinking about
|
||||
# their beer instead of any advice at all.
|
||||
paragraphs = [p.strip() for p in text.split("\n\n") if p.strip()]
|
||||
if len(paragraphs) > 1 and not any(_looks_like_advice(p) for p in paragraphs):
|
||||
# No paragraph reads like advice, so the whole thing is working.
|
||||
# There is nothing to keep - the caller stores what is left.
|
||||
return text
|
||||
return ""
|
||||
|
||||
for marker in _PREAMBLE_MARKERS:
|
||||
index = lowered.find(marker)
|
||||
@@ -309,21 +311,29 @@ def _strip_reasoning(text: str) -> str:
|
||||
|
||||
#: Words that mark a paragraph as the ADVICE rather than the model's
|
||||
#: working. The advice talks about what the brewer should DO.
|
||||
#: Phrases that mark a paragraph as the ADVICE rather than the model's
|
||||
#: working. They are matched as PHRASES, not bare words - "keep" alone
|
||||
#: matches "I need to keep in mind that the hydrometer was read at a
|
||||
#: different temperature", which is working, not advice.
|
||||
_ADVICE_MARKERS = (
|
||||
"you should",
|
||||
"you could",
|
||||
"you may want",
|
||||
"you might",
|
||||
"you will want",
|
||||
"give it",
|
||||
"let it",
|
||||
"take another",
|
||||
"take the",
|
||||
"raise",
|
||||
"lower",
|
||||
"rack",
|
||||
"keep",
|
||||
"suggest",
|
||||
"recommend",
|
||||
"let it sit",
|
||||
"let it ferment",
|
||||
"take another reading",
|
||||
"take a reading",
|
||||
"raise it to",
|
||||
"raise the",
|
||||
"lower the",
|
||||
"rack it",
|
||||
"you could repitch",
|
||||
"i would suggest",
|
||||
"i suggest",
|
||||
"i recommend",
|
||||
"in your case",
|
||||
"here is",
|
||||
"here's",
|
||||
@@ -348,7 +358,9 @@ def _looks_like_advice(paragraph: str) -> bool:
|
||||
working_words = ("perhaps", "maybe", "possibly", "could be", "might be",
|
||||
"i think", "i am not sure", "actually", "hmm", "wait",
|
||||
"let me", "so on brew day", "there is a discrepancy",
|
||||
"that is a discrepancy", "but the", "which means")
|
||||
"that is a discrepancy", "which means",
|
||||
"i need to keep in mind", "the question is",
|
||||
"this could mean", "it could be", "or maybe")
|
||||
if any(word in lowered for word in working_words):
|
||||
return False
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user