Skip to content

feat: ARS neighborhood finder and pathfinder - #65

Closed
SkyeAv wants to merge 0 commit into
chore/fastmcp-background-tasksfrom
query-ars
Closed

SkyeAv wants to merge 0 commit into
chore/fastmcp-background-tasksfrom
query-ars

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Sep 30, 2026

Copy link
Copy Markdown
Member

Second of three stacked PRs for ARS querying. Adds Autonomous Relay System querying to the library, built on @gloriachin's feat/ars-query-support branch, with merge-aware polling ported from @hodgesf's feat/ars-client. Follows the finder conventions landed in #44/#48.

Stacked on #64. The MCP/CLI tool PR stacks on this one.

What changed

  • TCT/Query_ARS.py: ARS_neighborhood_finder(node, neighbor_categories, json_file=...) and the new ARS_pathfinder(start, end, intermediate_categories, json_file=...) build one-hop and paths TRAPI queries, submit them to the ARS, wait for every ARA and the merge agent, and return an ARSResult. json_file passes an uploaded TRAPI query through unchanged (edges or paths query graphs). Guangrong's public names are kept: Query_ARS, check_ars_results, fetch_ars_results, format_query_json_forARS_neighborhood.
  • ARSResult extends FinderResult with pk, merged_pk, status (an ARSStatus), and summarize(top_n), which returns ranked rows: essence, bound nodes with names, predicates, primary sources, contributing ARAs. isinstance(r, FinderResult) holds, so existing consumers of .raw and .knowledge_graph work unchanged. The merged ARS TRAPI is kept as the ARS returns it, with its own ranking and ARA attribution.
  • Inputs resolve like the other finders: names and CURIEs through Name Resolver and Node Normalizer, categories normalized ("Drug" becomes "biolink:Drug"). json_file skips resolution.
  • Polling waits for the ars-ars-agent merge child (ARS delay in saving "Done" status on merged result Relay#621) and parses the Python-repr merged_versions_list the ARS actually sends. It uses a deadline instead of retry-count arithmetic and one shared requests.Session.
  • config.py: new ars endpoint for prod, ci, and test, selected by TCT_ENVIRONMENT or TCT.configure() (default ci, as before). This replaces the hardcoded URLs from the original branch. The Query_ARS function is not re-exported from TCT, because that would shadow the TCT.Query_ARS module.
  • Guangrong's unrelated fixes, as separate commits under his authorship: nodenorm CI-URL removal, informative node-normalizer HTTP errors, CATRAX test-URL fallbacks. A follow-up commit restores DEFAULT_ENVIRONMENT, which the nodenorm change dropped because it was written against an older base.
  • notebooks/Test_ARS.ipynb gains pathfinder cells and was re-executed end to end. New docs/source/ars.rst; README tool table updated.

Stats (for audit)

  • 9 commits, 14 files, +1900/-10.
  • Offline suite: 157 passed, 4 skipped (live tests gated behind TCT_LIVE_ARS=1).
  • New offline tests: 20 in tests/test_query_ars.py (Guangrong's uploaded-JSON and notebook-parity cases, plus merge-wait, finder-parity, and summarizer coverage) and 14 node-normalizer routing cases from his branch.
  • Live tests: 3 (neighborhood, pathfinder, fixture drift).
  • Fixture-drift check: offline fixtures verified as a structural subset of a live trace and merged envelope. During development it caught two real shape facts: the ARS sends merged_versions_list as a Python-repr string, and aragorn/bte merges omit essence and rank.

Performance (old branch vs this PR, same live CI query: asthma, ChemicalEntity)

Measure feat/ars-query-support This PR
15 sequential trace polls 4685 ms total, 312 ms mean (new connection each) 1814 ms total, 121 ms mean (shared session), 2.6x faster
End-to-end neighborhood finder 66.9 s, 476 results, 63.9 MB 66.5 s, 476 results, 63.9 MB (parity: time is spent in the ARAs)
Top 20 ranked rows from the merge no summarizer 0.7 ms on the 476-result merge
Polling limits 15 checks x 30 s, gives up around 425 s 900 s deadline, 15 s interval, waits for the merge agent

Verification

  • uv run pytest: 157 passed, 4 skipped.
  • Live run 1: TCT_LIVE_ARS=1 uv run pytest tests/test_ars_live.py -v: 3 passed in 199.00 s.
  • Live run 2, same command: 3 passed in 227.80 s.
  • Manual smoke: ARS_neighborhood_finder("asthma", ["ChemicalEntity"]) returned 476 results and ARS_pathfinder("asthma", "albuterol", intermediate_categories=["Gene"]) returned 1 path. Both reached Done, and isinstance(r, FinderResult) was True.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant