Files
scientific-agent-skills/tests/ontology-term-resolution
Timothy Kassis 87b598a51a Add ontology-term-resolution skill
Resolve free-text scientific labels to ontology term IDs and validate
existing CURIEs against the EBI Ontology Lookup Service (OLS4). Covers the
concepts whose identifiers are routinely invented rather than looked up:
tissue, cell type, disease, phenotype, assay, chemical, organism, sex, and
developmental stage.

Two stdlib-only scripts, one per direction:

  resolve_terms.py   text -> ID, escalating exact -> token -> fulltext and
                     labelling every hit exact_label / exact_synonym /
                     partial, so a fuzzy guess cannot pass as a match
  validate_terms.py  ID -> verdict (not_found, obsolete + replacement,
                     label_mismatch, wrong_ontology, wrong_branch), exiting
                     non-zero so it works as a CI gate on a metadata file

Behaviour verified against the live service, and the reason the skill ships
scripts rather than a recipe:

- exact=true is exact *token* matching, not exact label: "liver" returns 161
  hits in UBERON, 1 once queryFields is restricted to label
- /search never returns is_obsolete or term_replaced_by, even when they are
  named in fieldList, so only term detail can answer whether an ID is current
- ontology=efo returns MONDO and CL hits, because ontologies import each other
- the obo_id index has holes: MONDO:0000001 is live and defined by MONDO but
  unindexed, so an IRI fallback is needed to avoid a false not_found
- IRIs are not all OBO PURLs; EFO and Orphanet use their own namespaces
- OxO is retired and serves HTML with HTTP 200
- a branch check does not exclude cell types from anatomy, since CARO places
  cell under anatomical structure

Tests: 59 in tests/ontology-term-resolution, 53 offline with stubbed network
plus 6 live smoke tests gated behind OLS_LIVE_TESTS=1 that pin the API
behaviour above.
2026-07-26 14:45:44 -07:00
..