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
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
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.htmlmaziyarpanahi/openmed
00e9efd
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.