mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
fix(insights): screen the medication-adherence card and background lines uniformly
Route the medication-compliance status card through finalizeStatusSummary so it enforces the same dose / risk / causal outbound contracts its seven sibling status cards do, not only the unparseable-envelope withhold it already had. A dose-change imperative or a fabricated figure is now withheld to the controlled fallback on this surface too. Add the status cards' structured-envelope detection to the two background hero lines (arrival reaction, coach nudge): a brace-led or fenced JSON reply, or a truncated envelope under the char cap, now resolves to the deterministic lead rather than rendering raw. Fold in the residuals from the same sweep: strip a truncated SUGGEST-ACTION marker from the Coach prose tail, drop an unreachable zero-rate branch in the adherence fold, and document why the internal conversation summary stays off the render-boundary screen.
This commit is contained in:
1 parent
1d3963bebf
commit
0baffe04cd
6 files changed
+73
-10
No files matched your search
@@ -205,6 +205,16 @@ export async function refreshConversationSummary(
|
||||
if (trimmed.length === 0) {
|
||||
return { status: "skipped" };
|
||||
}
|
||||
// v1.32.20 — deliberately NOT routed through `screenModelOutput`. This
|
||||
// summary is internal memory only: it is stored encrypted and read back
|
||||
// solely as `priorSummary` to prime the NEXT summary/chat prompt
|
||||
// (`persistence.ts` decrypt → `chat/route.ts` priorSummary). It is never
|
||||
// rendered to a user surface. Any dose/risk/causal phrasing it might carry
|
||||
// cannot reach a person here, and the next Coach reply that could echo it is
|
||||
// itself screened (`screenCoachReply` in the chat route) before it ships.
|
||||
// Screening here would only risk withholding a legitimate internal summary
|
||||
// (memory loss) with no user-facing safety gain — so the screen stays on the
|
||||
// rendering boundaries, not this internal-memory write.
|
||||
// Backstop the stored length even if the provider over-ran the prompt's
|
||||
// "short paragraph" instruction.
|
||||
const text =
|
||||
|
||||
@@ -213,11 +213,35 @@ function resolveActionParams(
|
||||
* invalid param, drops the action (`malformed: true`) while still removing the
|
||||
* raw marker from the prose.
|
||||
*/
|
||||
/**
|
||||
* Strip a TRUNCATED (partial) open sentinel left at the tail of the model's
|
||||
* output. A reply cut off mid-marker — e.g. "…worth a look.\n---SUGGEST-ACTIO"
|
||||
* — never contains the full `OPEN_SENTINEL`, so the block strip below misses it
|
||||
* and the fragment renders raw (the #608 malformed-output class). Remove any
|
||||
* trailing run that is a non-empty proper prefix of the open sentinel of at
|
||||
* least `---S`, so a legitimate bare "---" separator is left untouched.
|
||||
*/
|
||||
function stripTruncatedOpenSentinel(prose: string): string {
|
||||
const trimmedEnd = prose.replace(/\s+$/u, "");
|
||||
for (let len = OPEN_SENTINEL.length - 1; len >= 4; len--) {
|
||||
const partial = OPEN_SENTINEL.slice(0, len);
|
||||
if (trimmedEnd.endsWith(partial)) {
|
||||
return trimmedEnd.slice(0, trimmedEnd.length - partial.length).trimEnd();
|
||||
}
|
||||
}
|
||||
return prose;
|
||||
}
|
||||
|
||||
export function parseSuggestAction(raw: string): SuggestActionParseResult {
|
||||
if (!raw) return { prose: "", action: null, malformed: false };
|
||||
|
||||
const openIdx = raw.indexOf(OPEN_SENTINEL);
|
||||
if (openIdx === -1) return { prose: raw, action: null, malformed: false };
|
||||
if (openIdx === -1) {
|
||||
// No full block — but a truncated open marker at the tail must still be
|
||||
// scrubbed so the raw fragment never reaches the user's prose.
|
||||
const prose = stripTruncatedOpenSentinel(raw);
|
||||
return { prose, action: null, malformed: prose !== raw };
|
||||
}
|
||||
|
||||
const before = raw.slice(0, openIdx);
|
||||
const afterOpen = raw.slice(openIdx + OPEN_SENTINEL.length);
|
||||
|
||||
Reference in new issue
Block a user