Deduplicate and reconcile OpenMed-extracted conditions into one clean active problem list with clinical status (active / resolved / historical). Use after NER and context resolution when the user wants a problem list, condition reconciliation, dedup of synonymous diagnosis mentions, or active-vs-resolved status from a note. Covers clustering synonymous mentions into one concept, excluding negated mentions, applying clinical context (historical / hypothetical / recent) to set status, and emitting a USCDI-Problem-shaped list. SNOMED CT concept grounding is user-supplied and out-of-process. Hand-off: consume openmed.analyze_text Disease entities plus resolving-clinical-context axes. Pairs after extracting-clinical-entities.
72
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
A single note mentions the same condition many ways — "DM2," "type 2 diabetes," "diabetes mellitus" — across PMH, HPI, and A&P, some negated, some historical. A usable problem list collapses those mentions into one concept per problem, drops what the patient does not have, and assigns a clinical status (active / resolved / historical). This skill turns OpenMed's per-mention entity stream plus ConText axes into that reconciled, de-duplicated list, shaped for USCDI "Problem" exchange.
extracting-clinical-entities and resolving-clinical-context, when the
user wants a clean problem list, condition reconciliation, or dedup of repeated
diagnosis mentions.import openmed
from openmed.clinical import resolve_span_context, NEGATED, HISTORICAL, HYPOTHETICAL
note = ("PMH: type 2 diabetes, prior MI 2019 (resolved). "
"A&P: poorly controlled DM2; denies chest pain.")
ents = openmed.analyze_text(note, model_name="disease_detection_superclinical",
output_format="dict")
def normalize(surface: str) -> str:
# Cheap synonym folding; replace with SNOMED grounding (out-of-process).
s = surface.lower().strip()
return {"dm2": "type 2 diabetes", "diabetes mellitus": "type 2 diabetes"}.get(s, s)
problems = {} # concept -> reconciled record
for e in ents:
surface = e["word"]
ctx = resolve_span_context(surface, note)
if ctx.negation == NEGATED:
continue # patient does NOT have it -> exclude
concept = normalize(surface)
status = ("resolved" if ctx.temporality == HISTORICAL else
"active")
if ctx.temporality == HYPOTHETICAL:
continue # not asserted as present
rec = problems.setdefault(concept, {"concept": concept, "status": status,
"mentions": 0})
rec["mentions"] += 1
# Active anywhere wins over a historical mention of the same concept.
if status == "active":
rec["status"] = "active"
problem_list = list(problems.values())
# -> [{"concept": "type 2 diabetes", "status": "active", "mentions": 2}, ...]
# "chest pain" excluded (negated); "MI" -> historical/resolved.analyze_text across the whole
note (or per section if you ran segmenting-clinical-sections).resolve_span_context (or the
axes from resolving-clinical-context): negation, temporality, uncertainty.NEGATED mentions (patient denies /
no evidence of) and HYPOTHETICAL mentions (conditional, not asserted). These
must never land on the active list.RECENT/active
anywhere (typically A&P) is active; one seen only as HISTORICAL
("history of," "resolved," PMH-only) is resolved/historical. Active wins
over historical when the same concept appears both ways.extracting-clinical-entities: consumes analyze_text Disease
entities. Run on a sectioned note (segmenting-clinical-sections) for best
active-vs-historical signal.resolving-clinical-context: this skill depends on the negation /
temporality / uncertainty axes — reconciliation without them would put "denies
chest pain" on the active list.from openmed import analyze_text and
from openmed.clinical import resolve_span_context, NEGATED, HISTORICAL, HYPOTHETICAL.clinicalStatus active/resolved (from temporality) and verificationStatus
refuted/provisional (from negation/uncertainty). SNOMED CT codes are
user-supplied and grounded out-of-process — OpenMed produces the dedup'd
concept and status, not the terminology binding.HISTORICAL /
"resolved" stays resolved; don't promote it to active just because it appears.clinicalStatus (active/resolved) and
verificationStatus: https://hl7.org/fhir/R4/condition.html80da98c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.