fix(agent): recover front-loaded answer past a citations-only terminal turn #11

Merged
steve merged 5 commits from fix/finalize-citations-only-terminal into main 2026-07-10 16:47:32 +00:00

5 Commits

Author SHA1 Message Date
steve 440bff7bdd test(agent): guard the no-preamble-veto-for-long-answers case; reword comments (gadfly)
CI / Build & Test (pull_request) Successful in 10m24s
CI / Tidy (pull_request) Successful in 9m31s
Add "long answer opening with a conversational word is still recovered"
(regression guard); retarget the skipped-preamble case to the borderline band;
drop the external "#N" annotations in favor of self-explanatory comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:33:31 +00:00
steve 88b94576af fix(agent): address gadfly — don't preamble-veto long answers; dedup ignores <url> wrappers
CI / Build & Test (pull_request) Failing after 5m40s
CI / Tidy (pull_request) Successful in 9m27s
- isSubstantiveAnswer: restore the original "≥200 chars ⇒ real answer"
  unconditional accept (the preamble filter now applies only in the
  borderline 80–200 band). Applying preambleRe regardless of length regressed
  the recovery path: a long front-loaded answer opening with a conversational
  word ("Sure,", "Let me explain:", "First,") was wrongly discarded
  (flagged by glm-5.2 + claude-code/opus). The NVD-style planning-narration
  case is already handled by the citation-dominance check, not this filter.
- citations dedup: compare with <url> angle-bracket wrappers stripped, so a
  front-loaded turn that listed the same sources unwrapped still suppresses the
  duplicate block.
- doc: spell out the citationLabelRe leading class members (+ list markers);
  drop the stale "gated by preamble" note on recoverMinChars.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:31:25 +00:00
steve a868863d24 test(agent): cover citations-only terminal recovery + edge cases (#1418)
CI / Tidy (pull_request) Successful in 9m28s
CI / Build & Test (pull_request) Successful in 10m19s
Adversarial Review (Gadfly) / review (pull_request) Successful in 14m12s
TestIsCitationsOnly (19 cases: bold/ATX/dash/backref positives; source-led
prose, bare-domain, prose-then-sources negatives), 4 new TestFinalOutput cases
(concise+long-citations, source-led-not-hijacked, long-preamble-skipped, dedup),
and end-to-end TestRun_RecoversFrontLoadedAnswerWithCitations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 15:19:48 +00:00
steve 68ae064c48 fix(agent): store finalize.go as raw source (was double-encoded) 2026-07-10 15:18:29 +00:00
steve 3f21a676ab fix(agent): recover front-loaded answer past a citations-only terminal
finalOutput already recovered a front-loaded answer when the terminal
(no-tool-call) turn was empty or a short back-reference. But some models
(glm-5.2 via a "cite" tool) front-load the prose answer into an earlier
tool-call turn and close with a terminal turn that is ONLY their sources
("Sources: [pcprice.watch](url) (...), [ebay](url) (...)"). That list is
neither empty nor a back-reference, so it was returned verbatim and the real
answer was discarded (mort issue #1418: the user got a bare sources list; the
good answer was only visible in the trace).

Add isCitationsOnly: a terminal that OPENS with a sources/citations heading,
carries a link, and is dominated by that citation structure (once heading+links
are stripped, little prose remains). Unlike a back-reference the citations are
real content, so finalOutput recovers the prior substantive answer and APPENDS
the citations below it (deduped). The dominance check keeps a real prose answer
that merely opens with "Source: ... http://..." from being misclassified; the ^
anchor keeps an answer that ends with a Sources section from matching; the
citations branch is decoupled from the terminal-length ratio so a CONCISE
front-loaded answer is still recovered; and preambleRe now applies regardless of
length so planning narration is never recovered. Healthy terminal answers are
unchanged; zero extra model calls.

Tests: TestIsCitationsOnly (19 cases incl. bold/ATX/backref/prose negatives),
new TestFinalOutput cases (concise+long-citations, source-led-not-hijacked,
long-preamble-skipped, dedup), and end-to-end
TestRun_RecoversFrontLoadedAnswerWithCitations. Full agent suite green (-race).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 15:16:46 +00:00