fix: strip bullet-glyph artifacts and redundant stitching from served answers#469
Conversation
…stitching Adds a shared normalizeInlineBulletGlyphs sanitizer (bullet glyphs and the PDF/Word sub-bullet "o") applied across the extractive answer path, answer prose polish, source snippets, and display text; sub-bullets become fact boundaries in evidence splitting with short headings merged as context; and sentenceFromFact completes facts before entity prefixing so "For lithium, ... The guidance is that for lithium," can no longer compound. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ssions Adds the lithium source-only regression cases (sub-bullet fact boundary, heading-as-context merge, entity de-duplication), normalizeInlineBulletGlyphs unit coverage including the 37-o-C guards, and snippet/answer-prose bullet assertions; prettier-formats the touched files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Evidence segments joined for fact extraction now carry terminal punctuation,
and the section heading becomes a "Heading:" label (skipped when the content
already opens with it) so the prose collapse can no longer fuse a bare
heading onto the first sentence ("Dosing Twice daily dosing...") or fabricate
a contentless "Label: Label." fact. Adds a buildExtractiveAnswer end-to-end
regression for the lithium source-only case.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tting-cleanup-b57a9c
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds reusable inline bullet normalization across clinical and RAG text paths, and improves extractive answer formatting by rewriting headings, preserving evidence boundaries, normalizing punctuation, and suppressing repeated entity prefixes. ChangesClinical text formatting
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SearchResult
participant splitClinicalEvidenceSentences
participant clinicalFactExtraction
participant sentenceFromFact
participant buildExtractiveAnswer
SearchResult->>splitClinicalEvidenceSentences: evidence text
splitClinicalEvidenceSentences->>clinicalFactExtraction: normalized evidence segments
clinicalFactExtraction->>sentenceFromFact: extracted facts and query
sentenceFromFact->>buildExtractiveAnswer: completed sentences
buildExtractiveAnswer->>buildExtractiveAnswer: suppress repeated entity prefixes
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 1 warning)
✅ Passed checks (9 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba91a5eaed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/lib/rag-extractive-answer.ts (1)
975-987: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winKeep entity-prefix gating on one intent path.
buildExtractiveAnswer()uses the routedqueryClassto deriveargs.intent, butsentenceFromFact()recomputes intent fromclassifyRagQuery(query). When clinical mode overrides the class, the suppression check can use a different entity than the sentence builder. Pass the resolved intent/entity intosentenceFromFact()so both use the same source of truth.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lib/rag-extractive-answer.ts` around lines 975 - 987, Entity-prefix suppression derives intent differently from sentence generation, causing inconsistent behavior when clinical mode overrides the routed class. In buildExtractiveAnswer(), derive the resolved intent/entity once and pass it through sentenceFromFact() (and its callers) so queryTokenMatchesText and sentence construction use the same source of truth instead of recomputing classifyRagQuery(query).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/rag-extractive-answer.ts`:
- Around line 83-87: Restrict doseLabelColonPattern so it does not rewrite
non-heading phrases ending in common prepositions or verbs such as “to”, “by”,
“at”, “of”, “with”, “into”, “onto”, or “towards”. Update the label’s final-word
matching while preserving existing heading and dose matches, including the
mid-string “IR product:” case, and ensure the corresponding replacement logic at
the later use remains consistent.
---
Nitpick comments:
In `@src/lib/rag-extractive-answer.ts`:
- Around line 975-987: Entity-prefix suppression derives intent differently from
sentence generation, causing inconsistent behavior when clinical mode overrides
the routed class. In buildExtractiveAnswer(), derive the resolved intent/entity
once and pass it through sentenceFromFact() (and its callers) so
queryTokenMatchesText and sentence construction use the same source of truth
instead of recomputing classifyRagQuery(query).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 63cdbfb2-aa9f-419f-81dc-38ccbb4607fa
📒 Files selected for processing (9)
src/components/clinical-dashboard/display-text.tssrc/lib/rag-answer-text.tssrc/lib/rag-extractive-answer.tssrc/lib/smart-rag-api.tssrc/lib/source-text-sanitizer.tstests/extractive-answer-formatting.test.tstests/rag-answer-text.test.tstests/smart-rag-api.test.tstests/source-text-sanitizer.test.ts
Review follow-ups for PR #469: the sub-bullet "o" converter now skips blood-group/type contexts ("blood group o RhD negative" stays intact), the dose-label copula rewrite no longer fires on preposition-ended phrases ("reduce dose to: 500mg"), and the lead-answer entity suppression derives the entity exactly the way sentenceFromFact does so the gate cannot disagree with the prefix it gates. Regression tests for all three. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f4afc93513
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…n form
"Do not use: o Pregnancy" previously dropped both fragments (heading was
stoplisted from merging) and "Avoid:" was rewritten into noun context ("For
avoid,"). Directive headings now merge with their items and keep the colon
form; the merge stoplist is boilerplate-only. Regression tests for both.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 33ecff7ab4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@coderabbitai review |
✅ Action performedReview finished.
|
"blood type: o Rh positive" / "blood group: o Negative" now keep their clinical O value; the lookbehind accepts an optional colon after group/type. Regression tests added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 367ab0b8b3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Blood Group o RhD negative", "Blood Type: o Negative", and "BLOOD GROUP: o Rh positive" now keep their clinical O value. Explicit case classes are used instead of the i flag so the bullet "o" itself never matches a clinical capital "O". Title-case and upper-case regression tests added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f502c5a78e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Caution: o Pregnancy..." previously dropped the Caution heading (it was in the merge stoplist), losing the caveat qualifier. The stoplist is now split: structural labels (source/section/table/...) still never merge; advisory labels (note/warning/caution/important/nb) merge with their items and keep their colon form. Regression test added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 945ee11e31
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…mption
Digit-bearing schedule headings ("Day 1:", "Step 2:") now merge with their
bullet items so a dose is never presented without its day/step; structural
labels stay excluded. The sub-bullet "o" exemption is narrowed to genuine
blood contexts (a "blood group/type" label, or group/type followed by an
Rh/positive/negative value), so "patient group o Adults" and "risk group: o
Pregnant patients" convert normally. Regression tests for both.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5df355325e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Day 1: o 25 mg nightly" and "o 12.5 mg twice daily" now normalize (the lookahead accepts a numeric dose start); "37 o C" stays protected by the not-after-a-digit lookbehind. Schedule-dose regression tests now assert the artifact is gone rather than merely that context is attached. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9cbe15fae6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A chunk that begins with the bare "o" sub-bullet ("o 12.5 mg twice daily")
now normalizes via a string-start lookbehind alternative, with a leading
separator strip so the joiner never dangles. Lowercase OCR headings ("day
1:", "do not use:") now merge with their bullet items, sentence-cased so the
merged fact passes the lowercase-start quality gate. Regression tests added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dismissed with repo owner approval: the single actionable finding (doseLabelColonPattern overreach) was fixed in f4afc93 with a regression test, the thread is resolved, and CodeRabbit re-reviews of subsequent commits raised no new actionable findings.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a811c6ace
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Dose:\no Start 750 mg" now normalizes in break-preserving display paths via
a newline alternative in the lookbehind, with a line-leading separator strip.
Lowercase followers ("o pregnancy") remain unconverted by design: deleting a
genuine clinical "o" value is worse than the cosmetic artifact.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b51def5a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8ca4e052bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"48-72 hours: o Restart clozapine at 12.5 mg" now keeps the time window on the restart fact (heading grammar accepts digit/comparator-leading labels); structural labels stay stoplisted. Regression test added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 943b3a1ff6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"K+ >5.5 mmol/L: o Withhold..." keeps the electrolyte threshold attached to the action fact. Regression test added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion Clinical threshold headings are too varied to enumerate character-by- character (comparators, electrolyte +, degrees, micro signs), so any short colon-terminated fragment with alphanumeric content and no sentence punctuation now qualifies for the merge; the word cap and structural stoplist still bound it. Degree/micro regression added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 918e45bb87
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ullets "Avoid: o 12.5 mg" stays "Avoid: 12.5 mg..." (directive/advisory labels skip the copula rewrite), and bold markers come off before bullet normalization so "o **Reduce dose**" converts. Regression tests for both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4ca48d9df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…toplist "Source control: o Review antibiotics..." keeps its heading (infection-source management, not a provenance label). Regression test added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db69e58318
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"o RhD negative" / "o Negative" at a string or line start are the blood value itself, not a bullet item; an Rh/positive/negative follower at an item start is now exempt. Regression tests added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 35b529dcaa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Reference range: o 0.6-1.0 mmol/L" keeps its heading (lab evidence, not a bibliography label), and ABO/Rh-qualified group/type labels count as blood context so "ABO group: o Negative" keeps its O value while "risk group: o Positive" still converts. Regression tests for both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4327729732
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The item-start blood exemption now requires the whole line to be the ABO
value ("o RhD negative"), so "o Positive symptoms require urgent review"
converts as the list bullet it is. The structural "section" stoplist word is
anchored to the label start, so "Caesarean section:" merges while
"Section 2:" stays excluded. Regression tests for both.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f1864308e0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@anthropic-code-agent[agent] Please resolve all open comments after fixing them |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 415ef60b28
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b20165e10
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a40156b72
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # docs/branch-review-ledger.md # tests/ui-smoke.spec.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3a252e7cd5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
normalizeInlineBulletGlyphssanitizer (bullet glyphs•◦▪‣●and the bare "o" sub-bullet, with the existing "37 o C" / "blood group o positive" guards preserved verbatim) and applies it across every serving path: extractive evidence splitting (sub-bullets become fact boundaries), extractive point cleaning,sanitizeAnswerText(final net for LLM answers too), the APIsnippetfield (also fixes "Copy with sources"), and the display layer for cached answers.sentenceFromFactcompletes the sentence before attaching the query entity (once), and the second lead sentence suppresses the entity prefix when the answer already names it.docs/production-readiness-checklist.md, Next.js 16.2.9 → 16.2.10 + review date) that this branch was seeded on.Verification
npm run verify:pr-local— not runnable as a single command in this worktree (no local node_modules; scripts hard-codenode_modules/vitest/vitest.mjs). Every component gate was run individually instead, post-merge with origin/main:npx vitest run)npm run lint): clean--checkon all PR-diff files: cleancheck:runtime,check:github-actions,sitemap:check: passnext.config.ts→@next/bundle-analyzerresolution — a stale local install inherited from main's perf: bundle analyzer + Server-Timing measurement rail (perf round 2, phase 0) #458 (dependency is in package.json + lockfile; not touched by this diff); CI's fresh install is the arbiternpm run verify:ui— not runnable in this worktree (no dependency install; dev server cannot boot). Change is text-content sanitization, not styling/routing; relying on the required ui-smoke CI checknpm run verify:release— not applicablenpm run eval:retrieval:quality— not run: no retrieval, ranking, selection, chunking, or scoring behavior changed (answer post-processing and display sanitization only)npm run eval:rag -- --limit 15/eval:quality --rag-only— not run: live-provider evals, no keys in this worktree. Offline equivalent ran instead:eval:rag:offlinefixture schema passed (36 golden cases) + all 5 offline contract suites (58 tests) greennpm run check:production-readiness— file/runtime checks pass; the only failures are missingNEXT_PUBLIC_SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY/OPENAI_API_KEYbecause this worktree has no.env.local(expected per repo docs; no env behavior changed)Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy) — no Supabase config touchedNotes
clinicalProseUsefulnessgate (H2 regression history) was deliberately not touched.tests/extractive-answer-formatting.test.tsincludes the exact lithium case end-to-end throughbuildExtractiveAnswer.🤖 Generated with Claude Code