/* Endoxa — arbejdsværktøj (prototype). Klinisk beslutningsstøtte, RAG-stil. Pilotdomæne: hæmatologi · myelomatose & MGUS. */ const { useState, useRef, useEffect, useCallback } = React; const KB = window.ENDOXA_KB; /* ── Matchning af fri-tekst mod vidensgrundlaget ── */ function matchResponse(raw) { const t = raw.toLowerCase(); // scenarie først if (KB.scenario.keywords.some((k) => t.includes(k))) { return { kind: "scenario", question: KB.scenario.question, answer: KB.scenario.answer }; } // emner for (const topic of KB.topics) { if (topic.keywords.some((k) => t.includes(k))) { return { kind: "topic", question: topic.question, answer: topic.answer }; } } // out of scope if (KB.outOfScopeKeywords.some((k) => t.includes(k.trim()))) { return { kind: "oos" }; } return { kind: "fallback" }; } /* ── Render af svar-blokke ── */ function Blocks({ blocks }) { return blocks.map((b, i) => b.type === "para" ? (

{b.text}

) : (
{b.title}
) ); } /* ── Kilde-chips ── */ function Citations({ ids, onOpen }) { if (!ids || !ids.length) return null; return (
Kilder {ids.map((id) => { const s = KB.sources[id]; return ( ); })}
); } /* ── En AI-besked ── */ function AiMessage({ msg, onOpen, onAction, onFollowup }) { if (msg.kind === "oos") { return (
E
Uden for vidensgrundlaget

Det spørgsmål ligger uden for det aktuelle vidensgrundlag (hæmatologi: myelomatose og MGUS). Jeg finder ikke på et svar her. Kontakt relevant instans — fx hæmatologisk bagvagt eller den relevante specialrådgivning — eller vælg et hæmatologisk emne nedenfor.

); } if (msg.kind === "referral") { const d = KB.referralDraft; return (
E
{d.title}
{d.fields.map(([k, v], i) => (
{k} {v}
))}
{d.note}
); } return (
E
{msg.note &&
{msg.note}
} {msg.answer.followup && !msg.followAnswered && (
{msg.answer.followup.question}
{msg.answer.followup.options.map((o) => ( ))}
)} {msg.answer.actions && msg.answer.actions.includes("referral") && (
)}
); } /* ── Kilde-panel (skydeind) ── */ function SourcePanel({ id, onClose }) { if (!id) return null; const s = KB.sources[id]; return ( <>
); } /* ── Composer ── */ function Composer({ onSend, onImage }) { const [text, setText] = useState(""); const [cpr, setCpr] = useState(false); const taRef = useRef(null); const check = (v) => { setText(v); setCpr(KB.cprRegex.test(v)); }; const redact = () => { const v = text.replace(KB.cprRegex, "●●●●●●-●●●●"); setText(v); setCpr(false); }; const submit = () => { if (!text.trim() || cpr) return; onSend(text.trim()); setText(""); setCpr(false); }; const onKey = (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); submit(); } }; useEffect(() => { const ta = taRef.current; if (!ta) return; ta.style.height = "auto"; ta.style.height = Math.min(ta.scrollHeight, 160) + "px"; }, [text]); return (
{cpr && (
! Personhenførbare oplysninger registreret (CPR-mønster). Fjern dem, før du sender.
)}