aurelian 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. aurelian/__init__.py +9 -0
  2. aurelian/agents/__init__.py +0 -0
  3. aurelian/agents/amigo/__init__.py +3 -0
  4. aurelian/agents/amigo/amigo_agent.py +77 -0
  5. aurelian/agents/amigo/amigo_config.py +85 -0
  6. aurelian/agents/amigo/amigo_evals.py +73 -0
  7. aurelian/agents/amigo/amigo_gradio.py +52 -0
  8. aurelian/agents/amigo/amigo_mcp.py +152 -0
  9. aurelian/agents/amigo/amigo_tools.py +152 -0
  10. aurelian/agents/biblio/__init__.py +42 -0
  11. aurelian/agents/biblio/biblio_agent.py +94 -0
  12. aurelian/agents/biblio/biblio_config.py +40 -0
  13. aurelian/agents/biblio/biblio_gradio.py +67 -0
  14. aurelian/agents/biblio/biblio_mcp.py +115 -0
  15. aurelian/agents/biblio/biblio_tools.py +164 -0
  16. aurelian/agents/biblio_agent.py +46 -0
  17. aurelian/agents/checklist/__init__.py +44 -0
  18. aurelian/agents/checklist/checklist_agent.py +85 -0
  19. aurelian/agents/checklist/checklist_config.py +28 -0
  20. aurelian/agents/checklist/checklist_gradio.py +70 -0
  21. aurelian/agents/checklist/checklist_mcp.py +86 -0
  22. aurelian/agents/checklist/checklist_tools.py +141 -0
  23. aurelian/agents/checklist/content/checklists.yaml +7 -0
  24. aurelian/agents/checklist/content/streams.csv +136 -0
  25. aurelian/agents/checklist_agent.py +40 -0
  26. aurelian/agents/chemistry/__init__.py +3 -0
  27. aurelian/agents/chemistry/chemistry_agent.py +46 -0
  28. aurelian/agents/chemistry/chemistry_config.py +71 -0
  29. aurelian/agents/chemistry/chemistry_evals.py +79 -0
  30. aurelian/agents/chemistry/chemistry_gradio.py +50 -0
  31. aurelian/agents/chemistry/chemistry_mcp.py +120 -0
  32. aurelian/agents/chemistry/chemistry_tools.py +121 -0
  33. aurelian/agents/chemistry/image_agent.py +15 -0
  34. aurelian/agents/d4d/__init__.py +30 -0
  35. aurelian/agents/d4d/d4d_agent.py +72 -0
  36. aurelian/agents/d4d/d4d_config.py +46 -0
  37. aurelian/agents/d4d/d4d_gradio.py +58 -0
  38. aurelian/agents/d4d/d4d_mcp.py +71 -0
  39. aurelian/agents/d4d/d4d_tools.py +157 -0
  40. aurelian/agents/d4d_agent.py +64 -0
  41. aurelian/agents/diagnosis/__init__.py +33 -0
  42. aurelian/agents/diagnosis/diagnosis_agent.py +53 -0
  43. aurelian/agents/diagnosis/diagnosis_config.py +48 -0
  44. aurelian/agents/diagnosis/diagnosis_evals.py +76 -0
  45. aurelian/agents/diagnosis/diagnosis_gradio.py +52 -0
  46. aurelian/agents/diagnosis/diagnosis_mcp.py +141 -0
  47. aurelian/agents/diagnosis/diagnosis_tools.py +204 -0
  48. aurelian/agents/diagnosis_agent.py +28 -0
  49. aurelian/agents/draw/__init__.py +3 -0
  50. aurelian/agents/draw/draw_agent.py +39 -0
  51. aurelian/agents/draw/draw_config.py +26 -0
  52. aurelian/agents/draw/draw_gradio.py +50 -0
  53. aurelian/agents/draw/draw_mcp.py +94 -0
  54. aurelian/agents/draw/draw_tools.py +100 -0
  55. aurelian/agents/draw/judge_agent.py +18 -0
  56. aurelian/agents/filesystem/__init__.py +0 -0
  57. aurelian/agents/filesystem/filesystem_config.py +27 -0
  58. aurelian/agents/filesystem/filesystem_gradio.py +49 -0
  59. aurelian/agents/filesystem/filesystem_mcp.py +89 -0
  60. aurelian/agents/filesystem/filesystem_tools.py +95 -0
  61. aurelian/agents/filesystem/py.typed +0 -0
  62. aurelian/agents/github/__init__.py +0 -0
  63. aurelian/agents/github/github_agent.py +83 -0
  64. aurelian/agents/github/github_cli.py +248 -0
  65. aurelian/agents/github/github_config.py +22 -0
  66. aurelian/agents/github/github_gradio.py +152 -0
  67. aurelian/agents/github/github_mcp.py +252 -0
  68. aurelian/agents/github/github_tools.py +408 -0
  69. aurelian/agents/github/github_tools.py.tmp +413 -0
  70. aurelian/agents/goann/__init__.py +13 -0
  71. aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines.md +1000 -0
  72. aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines.pdf +0 -0
  73. aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines_Paper.md +693 -0
  74. aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines_Paper.pdf +0 -0
  75. aurelian/agents/goann/goann_agent.py +90 -0
  76. aurelian/agents/goann/goann_config.py +90 -0
  77. aurelian/agents/goann/goann_evals.py +104 -0
  78. aurelian/agents/goann/goann_gradio.py +62 -0
  79. aurelian/agents/goann/goann_mcp.py +0 -0
  80. aurelian/agents/goann/goann_tools.py +65 -0
  81. aurelian/agents/gocam/__init__.py +43 -0
  82. aurelian/agents/gocam/documents/DNA-binding transcription factor activity annotation guidelines.docx +0 -0
  83. aurelian/agents/gocam/documents/DNA-binding transcription factor activity annotation guidelines.pdf +0 -0
  84. aurelian/agents/gocam/documents/DNA-binding_transcription_factor_activity_annotation_guidelines.md +100 -0
  85. aurelian/agents/gocam/documents/E3 ubiquitin ligases.docx +0 -0
  86. aurelian/agents/gocam/documents/E3 ubiquitin ligases.pdf +0 -0
  87. aurelian/agents/gocam/documents/E3_ubiquitin_ligases.md +134 -0
  88. aurelian/agents/gocam/documents/GO-CAM annotation guidelines README.docx +0 -0
  89. aurelian/agents/gocam/documents/GO-CAM annotation guidelines README.pdf +0 -0
  90. aurelian/agents/gocam/documents/GO-CAM modelling guidelines TO DO.docx +0 -0
  91. aurelian/agents/gocam/documents/GO-CAM modelling guidelines TO DO.pdf +0 -0
  92. aurelian/agents/gocam/documents/GO-CAM_annotation_guidelines_README.md +1 -0
  93. aurelian/agents/gocam/documents/GO-CAM_modelling_guidelines_TO_DO.md +3 -0
  94. aurelian/agents/gocam/documents/How to annotate complexes in GO-CAM.docx +0 -0
  95. aurelian/agents/gocam/documents/How to annotate complexes in GO-CAM.pdf +0 -0
  96. aurelian/agents/gocam/documents/How to annotate molecular adaptors.docx +0 -0
  97. aurelian/agents/gocam/documents/How to annotate molecular adaptors.pdf +0 -0
  98. aurelian/agents/gocam/documents/How to annotate sequestering proteins.docx +0 -0
  99. aurelian/agents/gocam/documents/How to annotate sequestering proteins.pdf +0 -0
  100. aurelian/agents/gocam/documents/How_to_annotate_complexes_in_GO-CAM.md +29 -0
  101. aurelian/agents/gocam/documents/How_to_annotate_molecular_adaptors.md +31 -0
  102. aurelian/agents/gocam/documents/How_to_annotate_sequestering_proteins.md +42 -0
  103. aurelian/agents/gocam/documents/Molecular adaptor activity.docx +0 -0
  104. aurelian/agents/gocam/documents/Molecular adaptor activity.pdf +0 -0
  105. aurelian/agents/gocam/documents/Molecular carrier activity.docx +0 -0
  106. aurelian/agents/gocam/documents/Molecular carrier activity.pdf +0 -0
  107. aurelian/agents/gocam/documents/Molecular_adaptor_activity.md +51 -0
  108. aurelian/agents/gocam/documents/Molecular_carrier_activity.md +41 -0
  109. aurelian/agents/gocam/documents/Protein sequestering activity.docx +0 -0
  110. aurelian/agents/gocam/documents/Protein sequestering activity.pdf +0 -0
  111. aurelian/agents/gocam/documents/Protein_sequestering_activity.md +50 -0
  112. aurelian/agents/gocam/documents/Signaling receptor activity annotation guidelines.docx +0 -0
  113. aurelian/agents/gocam/documents/Signaling receptor activity annotation guidelines.pdf +0 -0
  114. aurelian/agents/gocam/documents/Signaling_receptor_activity_annotation_guidelines.md +187 -0
  115. aurelian/agents/gocam/documents/Transcription coregulator activity.docx +0 -0
  116. aurelian/agents/gocam/documents/Transcription coregulator activity.pdf +0 -0
  117. aurelian/agents/gocam/documents/Transcription_coregulator_activity.md +36 -0
  118. aurelian/agents/gocam/documents/Transporter activity annotation annotation guidelines.docx +0 -0
  119. aurelian/agents/gocam/documents/Transporter activity annotation annotation guidelines.pdf +0 -0
  120. aurelian/agents/gocam/documents/Transporter_activity_annotation_annotation_guidelines.md +43 -0
  121. Regulatory Processes in GO-CAM.docx +0 -0
  122. Regulatory Processes in GO-CAM.pdf +0 -0
  123. aurelian/agents/gocam/documents/WIP_-_Regulation_and_Regulatory_Processes_in_GO-CAM.md +31 -0
  124. aurelian/agents/gocam/documents/md/DNA-binding_transcription_factor_activity_annotation_guidelines.md +131 -0
  125. aurelian/agents/gocam/documents/md/E3_ubiquitin_ligases.md +166 -0
  126. aurelian/agents/gocam/documents/md/GO-CAM_annotation_guidelines_README.md +1 -0
  127. aurelian/agents/gocam/documents/md/GO-CAM_modelling_guidelines_TO_DO.md +5 -0
  128. aurelian/agents/gocam/documents/md/How_to_annotate_complexes_in_GO-CAM.md +28 -0
  129. aurelian/agents/gocam/documents/md/How_to_annotate_molecular_adaptors.md +19 -0
  130. aurelian/agents/gocam/documents/md/How_to_annotate_sequestering_proteins.md +38 -0
  131. aurelian/agents/gocam/documents/md/Molecular_adaptor_activity.md +52 -0
  132. aurelian/agents/gocam/documents/md/Molecular_carrier_activity.md +59 -0
  133. aurelian/agents/gocam/documents/md/Protein_sequestering_activity.md +52 -0
  134. aurelian/agents/gocam/documents/md/Signaling_receptor_activity_annotation_guidelines.md +271 -0
  135. aurelian/agents/gocam/documents/md/Transcription_coregulator_activity.md +54 -0
  136. aurelian/agents/gocam/documents/md/Transporter_activity_annotation_annotation_guidelines.md +38 -0
  137. aurelian/agents/gocam/documents/md/WIP_-_Regulation_and_Regulatory_Processes_in_GO-CAM.md +39 -0
  138. aurelian/agents/gocam/documents/pandoc_md/Signaling_receptor_activity_annotation_guidelines.md +334 -0
  139. aurelian/agents/gocam/gocam_agent.py +240 -0
  140. aurelian/agents/gocam/gocam_config.py +85 -0
  141. aurelian/agents/gocam/gocam_curator_agent.py +46 -0
  142. aurelian/agents/gocam/gocam_evals.py +67 -0
  143. aurelian/agents/gocam/gocam_gradio.py +89 -0
  144. aurelian/agents/gocam/gocam_mcp.py +224 -0
  145. aurelian/agents/gocam/gocam_tools.py +294 -0
  146. aurelian/agents/linkml/__init__.py +0 -0
  147. aurelian/agents/linkml/linkml_agent.py +62 -0
  148. aurelian/agents/linkml/linkml_config.py +48 -0
  149. aurelian/agents/linkml/linkml_evals.py +66 -0
  150. aurelian/agents/linkml/linkml_gradio.py +45 -0
  151. aurelian/agents/linkml/linkml_mcp.py +186 -0
  152. aurelian/agents/linkml/linkml_tools.py +102 -0
  153. aurelian/agents/literature/__init__.py +3 -0
  154. aurelian/agents/literature/literature_agent.py +55 -0
  155. aurelian/agents/literature/literature_config.py +35 -0
  156. aurelian/agents/literature/literature_gradio.py +52 -0
  157. aurelian/agents/literature/literature_mcp.py +174 -0
  158. aurelian/agents/literature/literature_tools.py +182 -0
  159. aurelian/agents/monarch/__init__.py +25 -0
  160. aurelian/agents/monarch/monarch_agent.py +44 -0
  161. aurelian/agents/monarch/monarch_config.py +45 -0
  162. aurelian/agents/monarch/monarch_gradio.py +51 -0
  163. aurelian/agents/monarch/monarch_mcp.py +65 -0
  164. aurelian/agents/monarch/monarch_tools.py +113 -0
  165. aurelian/agents/oak/__init__.py +0 -0
  166. aurelian/agents/oak/oak_config.py +27 -0
  167. aurelian/agents/oak/oak_gradio.py +57 -0
  168. aurelian/agents/ontology_mapper/__init__.py +31 -0
  169. aurelian/agents/ontology_mapper/ontology_mapper_agent.py +56 -0
  170. aurelian/agents/ontology_mapper/ontology_mapper_config.py +50 -0
  171. aurelian/agents/ontology_mapper/ontology_mapper_evals.py +108 -0
  172. aurelian/agents/ontology_mapper/ontology_mapper_gradio.py +58 -0
  173. aurelian/agents/ontology_mapper/ontology_mapper_mcp.py +81 -0
  174. aurelian/agents/ontology_mapper/ontology_mapper_tools.py +147 -0
  175. aurelian/agents/phenopackets/__init__.py +3 -0
  176. aurelian/agents/phenopackets/phenopackets_agent.py +58 -0
  177. aurelian/agents/phenopackets/phenopackets_config.py +72 -0
  178. aurelian/agents/phenopackets/phenopackets_evals.py +99 -0
  179. aurelian/agents/phenopackets/phenopackets_gradio.py +55 -0
  180. aurelian/agents/phenopackets/phenopackets_mcp.py +178 -0
  181. aurelian/agents/phenopackets/phenopackets_tools.py +127 -0
  182. aurelian/agents/rag/__init__.py +40 -0
  183. aurelian/agents/rag/rag_agent.py +83 -0
  184. aurelian/agents/rag/rag_config.py +80 -0
  185. aurelian/agents/rag/rag_gradio.py +67 -0
  186. aurelian/agents/rag/rag_mcp.py +107 -0
  187. aurelian/agents/rag/rag_tools.py +189 -0
  188. aurelian/agents/rag_agent.py +54 -0
  189. aurelian/agents/robot/__init__.py +0 -0
  190. aurelian/agents/robot/assets/__init__.py +3 -0
  191. aurelian/agents/robot/assets/template.md +384 -0
  192. aurelian/agents/robot/robot_config.py +25 -0
  193. aurelian/agents/robot/robot_gradio.py +46 -0
  194. aurelian/agents/robot/robot_mcp.py +100 -0
  195. aurelian/agents/robot/robot_ontology_agent.py +139 -0
  196. aurelian/agents/robot/robot_tools.py +50 -0
  197. aurelian/agents/talisman/__init__.py +3 -0
  198. aurelian/agents/talisman/talisman_agent.py +126 -0
  199. aurelian/agents/talisman/talisman_config.py +66 -0
  200. aurelian/agents/talisman/talisman_gradio.py +50 -0
  201. aurelian/agents/talisman/talisman_mcp.py +168 -0
  202. aurelian/agents/talisman/talisman_tools.py +720 -0
  203. aurelian/agents/ubergraph/__init__.py +40 -0
  204. aurelian/agents/ubergraph/ubergraph_agent.py +71 -0
  205. aurelian/agents/ubergraph/ubergraph_config.py +79 -0
  206. aurelian/agents/ubergraph/ubergraph_gradio.py +48 -0
  207. aurelian/agents/ubergraph/ubergraph_mcp.py +69 -0
  208. aurelian/agents/ubergraph/ubergraph_tools.py +118 -0
  209. aurelian/agents/uniprot/__init__.py +37 -0
  210. aurelian/agents/uniprot/uniprot_agent.py +43 -0
  211. aurelian/agents/uniprot/uniprot_config.py +43 -0
  212. aurelian/agents/uniprot/uniprot_evals.py +99 -0
  213. aurelian/agents/uniprot/uniprot_gradio.py +48 -0
  214. aurelian/agents/uniprot/uniprot_mcp.py +168 -0
  215. aurelian/agents/uniprot/uniprot_tools.py +136 -0
  216. aurelian/agents/web/__init__.py +0 -0
  217. aurelian/agents/web/web_config.py +27 -0
  218. aurelian/agents/web/web_gradio.py +48 -0
  219. aurelian/agents/web/web_mcp.py +50 -0
  220. aurelian/agents/web/web_tools.py +108 -0
  221. aurelian/chat.py +23 -0
  222. aurelian/cli.py +800 -0
  223. aurelian/dependencies/__init__.py +0 -0
  224. aurelian/dependencies/workdir.py +78 -0
  225. aurelian/mcp/__init__.py +0 -0
  226. aurelian/mcp/amigo_mcp_test.py +86 -0
  227. aurelian/mcp/config_generator.py +123 -0
  228. aurelian/mcp/example_config.json +43 -0
  229. aurelian/mcp/generate_sample_config.py +37 -0
  230. aurelian/mcp/gocam_mcp_test.py +126 -0
  231. aurelian/mcp/linkml_mcp_tools.py +190 -0
  232. aurelian/mcp/mcp_discovery.py +87 -0
  233. aurelian/mcp/mcp_test.py +31 -0
  234. aurelian/mcp/phenopackets_mcp_test.py +103 -0
  235. aurelian/tools/__init__.py +0 -0
  236. aurelian/tools/web/__init__.py +0 -0
  237. aurelian/tools/web/url_download.py +51 -0
  238. aurelian/utils/__init__.py +0 -0
  239. aurelian/utils/async_utils.py +15 -0
  240. aurelian/utils/data_utils.py +32 -0
  241. aurelian/utils/documentation_manager.py +59 -0
  242. aurelian/utils/doi_fetcher.py +238 -0
  243. aurelian/utils/ontology_utils.py +68 -0
  244. aurelian/utils/pdf_fetcher.py +23 -0
  245. aurelian/utils/process_logs.py +100 -0
  246. aurelian/utils/pubmed_utils.py +238 -0
  247. aurelian/utils/pytest_report_to_markdown.py +67 -0
  248. aurelian/utils/robot_ontology_utils.py +112 -0
  249. aurelian/utils/search_utils.py +95 -0
  250. aurelian-0.3.2.dist-info/LICENSE +22 -0
  251. aurelian-0.3.2.dist-info/METADATA +105 -0
  252. aurelian-0.3.2.dist-info/RECORD +254 -0
  253. aurelian-0.3.2.dist-info/WHEEL +4 -0
  254. aurelian-0.3.2.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,45 @@
1
+ """
2
+ Configuration for the Monarch agent.
3
+ """
4
+ from dataclasses import dataclass, field
5
+ import os
6
+ from typing import Dict, List, Optional
7
+
8
+ from oaklib import get_adapter
9
+ from oaklib.interfaces import OboGraphInterface
10
+
11
+ from aurelian.dependencies.workdir import HasWorkdir, WorkDir
12
+
13
+
14
+ @dataclass
15
+ class MonarchDependencies(HasWorkdir):
16
+ """Configuration for the Monarch agent."""
17
+
18
+ # Default taxon ID for humans
19
+ taxon: str = "9606"
20
+
21
+ def __post_init__(self):
22
+ """Initialize the config with default values."""
23
+ # HasWorkdir doesn't have a __post_init__ method, so we don't call super()
24
+ if self.workdir is None:
25
+ self.workdir = WorkDir()
26
+
27
+ def get_monarch_adapter(self) -> OboGraphInterface:
28
+ """Get a configured Monarch adapter."""
29
+ return get_adapter("monarch:")
30
+
31
+ def get_mondo_adapter(self) -> OboGraphInterface:
32
+ """Get a configured Mondo adapter."""
33
+ return get_adapter("sqlite:obo:mondo")
34
+
35
+
36
+ def get_config() -> MonarchDependencies:
37
+ """Get the Monarch configuration from environment variables or defaults."""
38
+ workdir_path = os.environ.get("AURELIAN_WORKDIR", None)
39
+ workdir = WorkDir(location=workdir_path) if workdir_path else None
40
+ taxon = os.environ.get("MONARCH_TAXON", "9606")
41
+
42
+ return MonarchDependencies(
43
+ workdir=workdir,
44
+ taxon=taxon
45
+ )
@@ -0,0 +1,51 @@
1
+ """
2
+ Gradio interface for the Monarch agent.
3
+ """
4
+ from typing import List, Optional
5
+
6
+ import gradio as gr
7
+
8
+ from aurelian.utils.async_utils import run_sync
9
+ from .monarch_agent import monarch_agent
10
+ from .monarch_config import MonarchDependencies
11
+
12
+
13
+ def chat(deps: Optional[MonarchDependencies] = None, taxon: Optional[str] = None, **kwargs):
14
+ """
15
+ Initialize a chat interface for the Monarch agent.
16
+
17
+ Args:
18
+ deps: Optional dependencies configuration
19
+ taxon: Optional taxon ID to use, defaults to human (9606)
20
+ **kwargs: Additional arguments to pass to the agent
21
+
22
+ Returns:
23
+ A Gradio chat interface
24
+ """
25
+ if deps is None:
26
+ deps = MonarchDependencies()
27
+
28
+ if taxon:
29
+ deps.taxon = taxon
30
+
31
+ def get_info(query: str, history: List[str]) -> str:
32
+ print(f"QUERY: {query}")
33
+ print(f"HISTORY: {history}")
34
+ if history:
35
+ query += "## History"
36
+ for h in history:
37
+ query += f"\n{h}"
38
+ result = run_sync(lambda: monarch_agent.run_sync(query, deps=deps, **kwargs))
39
+ return result.data
40
+
41
+ return gr.ChatInterface(
42
+ fn=get_info,
43
+ type="messages",
44
+ title="Monarch Knowledge Base AI Assistant",
45
+ examples=[
46
+ ["Find associations for gene BRCA1"],
47
+ ["What diseases are associated with the APOE gene?"],
48
+ ["Find information about disease MONDO:0007254"],
49
+ ["What genes are associated with Alzheimer's disease?"]
50
+ ]
51
+ )
@@ -0,0 +1,65 @@
1
+ """
2
+ MCP tools for interacting with the Monarch Knowledge Base.
3
+ """
4
+ import os
5
+ from typing import Dict, List, Optional
6
+
7
+ from mcp.server.fastmcp import FastMCP
8
+
9
+ import aurelian.agents.monarch.monarch_tools as mt
10
+ from aurelian.agents.monarch.monarch_agent import MONARCH_SYSTEM_PROMPT
11
+ from aurelian.agents.monarch.monarch_config import MonarchDependencies, get_config
12
+ from pydantic_ai import RunContext
13
+
14
+ # Initialize FastMCP server
15
+ mcp = FastMCP("monarch", instructions=MONARCH_SYSTEM_PROMPT)
16
+
17
+
18
+ from aurelian.dependencies.workdir import WorkDir
19
+
20
+ def deps() -> MonarchDependencies:
21
+ deps = get_config()
22
+ # Set the location from environment variable or default
23
+ loc = os.getenv("AURELIAN_WORKDIR", "/tmp/aurelian")
24
+ deps.workdir = WorkDir(loc)
25
+ return deps
26
+
27
+ def ctx() -> RunContext[MonarchDependencies]:
28
+ rc: RunContext[MonarchDependencies] = RunContext[MonarchDependencies](
29
+ deps=deps(),
30
+ model=None, usage=None, prompt=None,
31
+ )
32
+ return rc
33
+
34
+
35
+ @mcp.tool()
36
+ async def find_gene_associations(gene_id: str) -> List[Dict]:
37
+ """
38
+ Find associations for a given gene or gene product.
39
+
40
+ Args:
41
+ gene_id: Gene identifier (e.g., HGNC symbol like "BRCA1")
42
+
43
+ Returns:
44
+ List of association objects containing subject, predicate, object details
45
+ """
46
+ return await mt.find_gene_associations(ctx(), gene_id)
47
+
48
+
49
+ @mcp.tool()
50
+ async def find_disease_associations(disease_id: str) -> List[Dict]:
51
+ """
52
+ Find associations for a given disease.
53
+
54
+ Args:
55
+ disease_id: Disease identifier (e.g., MONDO:0007254)
56
+
57
+ Returns:
58
+ List of association objects containing subject, predicate, object details
59
+ """
60
+ return await mt.find_disease_associations(ctx(), disease_id)
61
+
62
+
63
+ if __name__ == "__main__":
64
+ # Initialize and run the server
65
+ mcp.run(transport='stdio')
@@ -0,0 +1,113 @@
1
+ """
2
+ Tools for interacting with the Monarch Knowledge Base.
3
+ """
4
+ import asyncio
5
+ from typing import Dict, List, Optional
6
+
7
+ from pydantic_ai import RunContext, ModelRetry
8
+
9
+ from aurelian.utils.data_utils import obj_to_dict
10
+ from aurelian.utils.async_utils import run_sync
11
+ from .monarch_config import MonarchDependencies, get_config
12
+
13
+
14
+ def get_gene_id(ctx: RunContext[MonarchDependencies], gene_term: str) -> str:
15
+ """
16
+ Normalize a gene identifier.
17
+
18
+ Args:
19
+ ctx: Run context with dependencies
20
+ gene_term: The gene term to normalize
21
+
22
+ Returns:
23
+ Normalized gene ID
24
+ """
25
+ # Currently just a pass-through, but could be enhanced with ID normalization
26
+ return gene_term
27
+
28
+
29
+ async def find_gene_associations(ctx: RunContext[MonarchDependencies], gene_id: str) -> List[Dict]:
30
+ """
31
+ Find associations for a given gene ID.
32
+
33
+ Args:
34
+ ctx: Run context with dependencies
35
+ gene_id: The gene ID to find associations for
36
+
37
+ Returns:
38
+ List of associations for the gene
39
+ """
40
+ config = ctx.deps or get_config()
41
+ adapter = config.get_monarch_adapter()
42
+
43
+ try:
44
+ normalized_gene_id = get_gene_id(ctx, gene_id)
45
+
46
+ # Execute the potentially blocking operation in a thread pool
47
+ associations = await asyncio.to_thread(adapter.associations, [normalized_gene_id])
48
+
49
+ if not associations:
50
+ raise ModelRetry(f"No gene associations found for {gene_id}. Try a different gene identifier.")
51
+
52
+ # Convert associations to dictionaries asynchronously
53
+ result = []
54
+ for assoc in associations:
55
+ dict_assoc = await asyncio.to_thread(obj_to_dict, assoc)
56
+ result.append(dict_assoc)
57
+
58
+ return result
59
+ except Exception as e:
60
+ if "ModelRetry" in str(type(e)):
61
+ raise e
62
+ raise ModelRetry(f"Error retrieving gene associations: {str(e)}")
63
+
64
+
65
+ def get_disease_id(ctx: RunContext[MonarchDependencies], term: str) -> str:
66
+ """
67
+ Normalize a disease identifier.
68
+
69
+ Args:
70
+ ctx: Run context with dependencies
71
+ term: The disease term to normalize
72
+
73
+ Returns:
74
+ Normalized disease ID
75
+ """
76
+ # Currently just a pass-through, but could be enhanced with ID normalization
77
+ return term
78
+
79
+
80
+ async def find_disease_associations(ctx: RunContext[MonarchDependencies], disease_id: str) -> List[Dict]:
81
+ """
82
+ Find associations for a given disease ID.
83
+
84
+ Args:
85
+ ctx: Run context with dependencies
86
+ disease_id: The disease ID to find associations for
87
+
88
+ Returns:
89
+ List of associations for the disease
90
+ """
91
+ config = ctx.deps or get_config()
92
+ adapter = config.get_monarch_adapter()
93
+
94
+ try:
95
+ normalized_disease_id = get_disease_id(ctx, disease_id)
96
+
97
+ # Execute the potentially blocking operation in a thread pool
98
+ associations = await asyncio.to_thread(adapter.associations, [normalized_disease_id])
99
+
100
+ if not associations:
101
+ raise ModelRetry(f"No disease associations found for {disease_id}. Try a different disease identifier.")
102
+
103
+ # Convert associations to dictionaries asynchronously
104
+ result = []
105
+ for assoc in associations:
106
+ dict_assoc = await asyncio.to_thread(obj_to_dict, assoc)
107
+ result.append(dict_assoc)
108
+
109
+ return result
110
+ except Exception as e:
111
+ if "ModelRetry" in str(type(e)):
112
+ raise e
113
+ raise ModelRetry(f"Error retrieving disease associations: {str(e)}")
File without changes
@@ -0,0 +1,27 @@
1
+ """
2
+ Configuration for the OAK agent.
3
+ """
4
+ import os
5
+
6
+ from aurelian.dependencies.workdir import HasWorkdir, WorkDir
7
+
8
+
9
+ class OakDependencies(HasWorkdir):
10
+ """
11
+ OAK agent dependencies that include a working directory.
12
+
13
+ This allows the agent to maintain state and access files on the local filesystem.
14
+ """
15
+ pass
16
+
17
+
18
+ def get_config() -> OakDependencies:
19
+ """Get a default configuration for the OAK agent.
20
+
21
+ Returns:
22
+ OakDependencies object with default settings
23
+ """
24
+ workdir_path = os.environ.get("AURELIAN_WORKDIR", None)
25
+ workdir = WorkDir(location=workdir_path) if workdir_path else None
26
+
27
+ return OakDependencies(workdir=workdir)
@@ -0,0 +1,57 @@
1
+ """
2
+ Gradio UI for the OAK agent.
3
+ """
4
+ from typing import List, Optional
5
+
6
+ import gradio as gr
7
+
8
+ from aurelian.dependencies.workdir import HasWorkdir
9
+ from aurelian.utils.async_utils import run_sync
10
+ from pydantic_ai import Agent, Tool
11
+
12
+ # Create an Agent
13
+ oak_agent = Agent(
14
+ model="openai:gpt-4o",
15
+ deps_type=HasWorkdir,
16
+ system_prompt="""
17
+ You are an expert OAK (Ontology Access Kit) assistant. You can help users interact with ontology databases,
18
+ search ontologies, and perform common ontology operations.
19
+ Always provide clear explanations of what you're doing.
20
+ """,
21
+ tools=[] # OAK tools would be added here
22
+ )
23
+
24
+ def chat(deps: Optional[HasWorkdir] = None, **kwargs):
25
+ """
26
+ Initialize a chat interface for the OAK agent.
27
+
28
+ Args:
29
+ deps: Optional dependencies configuration
30
+ **kwargs: Additional arguments to pass to the agent
31
+
32
+ Returns:
33
+ A Gradio chat interface
34
+ """
35
+ if deps is None:
36
+ deps = HasWorkdir()
37
+
38
+ def get_info(query: str, history: List[str]) -> str:
39
+ print(f"QUERY: {query}")
40
+ print(f"HISTORY: {history}")
41
+ if history:
42
+ query += "## History"
43
+ for h in history:
44
+ query += f"\n{h}"
45
+ result = run_sync(lambda: oak_agent.run_sync(query, deps=deps, **kwargs))
46
+ return result.data
47
+
48
+ return gr.ChatInterface(
49
+ fn=get_info,
50
+ type="messages",
51
+ title="OAK AI Assistant",
52
+ examples=[
53
+ ["Search for 'diabetes' in the Human Phenotype Ontology"],
54
+ ["Find terms related to 'heart' in GO"],
55
+ ["Get information about the term 'HP:0001250'"]
56
+ ]
57
+ )
@@ -0,0 +1,31 @@
1
+ """
2
+ Ontology Mapper agent package for working with ontology term mappings.
3
+ """
4
+
5
+ from .ontology_mapper_agent import ontology_mapper_agent, add_ontologies
6
+ from .ontology_mapper_config import OntologyMapperDependencies
7
+ from .ontology_mapper_gradio import chat
8
+ from .ontology_mapper_tools import (
9
+ search_terms,
10
+ search_web,
11
+ retrieve_web_page,
12
+ get_ontology_adapter,
13
+ )
14
+
15
+ __all__ = [
16
+ # Agent
17
+ "ontology_mapper_agent",
18
+ "add_ontologies",
19
+
20
+ # Config
21
+ "OntologyMapperDependencies",
22
+
23
+ # Tools
24
+ "search_terms",
25
+ "search_web",
26
+ "retrieve_web_page",
27
+ "get_ontology_adapter",
28
+
29
+ # Gradio
30
+ "chat",
31
+ ]
@@ -0,0 +1,56 @@
1
+ """
2
+ Agent for creating ontology mappings.
3
+ """
4
+ from pydantic_ai import Agent, RunContext
5
+
6
+ from .ontology_mapper_config import OntologyMapperDependencies, get_config
7
+ from .ontology_mapper_tools import (
8
+ search_terms,
9
+ search_web,
10
+ retrieve_web_page,
11
+ )
12
+
13
+ # System prompt for the ontology mapper agent
14
+ ONTOLOGY_MAPPER_SYSTEM_PROMPT = (
15
+ "You are an expert on OBO ontologies."
16
+ " Your task is to assist the user in finding the relevant ontology terms,"
17
+ " given inputs such as search queries, lists of terms to map, alternate ontology classes, etc."
18
+ " You have access to a limited set of ontologies, which you can search using the `search_terms` function."
19
+ " This uses embedding-based search, so you can use partial terms, alternate names, etc."
20
+ " You can also expand the users search terms as appropriate, making use of any context provided."
21
+ " You should show your reasoning, and your candidate list (as many as appropriate)."
22
+ " Do not be completely literal in the task of matching ontology terms. If something seems out of scope"
23
+ " for an ontology, give the appropriate response and recommendation. "
24
+ " If a term is in scope and can't be found, suggest a term request."
25
+ " Give detailed provenance chains in <details> tags."
26
+ " Show ontology term IDs together with labels whenever possible."
27
+ " IMPORTANT: precision is important. If a user makes a query for a term then you should only return terms"
28
+ " that represent the SAME CONCEPT. Sometimes this will not be possible, and only close concepts can be found."
29
+ " Here you can report the close terms, but make it clear these are NOT THE SAME. Before doing this, you should"
30
+ " try strategies like varying your search term, based on your knowledge of that ontology"
31
+ " You must NEVER guess ontology term IDs, the query results should always be the source of truth."
32
+ "Stick to markdown, and all prefixed IDs should by hyperlinked with bioregistry,"
33
+ " i.e https://bioregistry.io/{curie}."
34
+ )
35
+
36
+ # Create the agent with the system prompt
37
+ ontology_mapper_agent = Agent(
38
+ model="openai:gpt-4o",
39
+ deps_type=OntologyMapperDependencies,
40
+ result_type=str,
41
+ system_prompt=ONTOLOGY_MAPPER_SYSTEM_PROMPT,
42
+ )
43
+
44
+ # Register the tools with the agent
45
+ ontology_mapper_agent.tool(search_terms)
46
+ ontology_mapper_agent.tool_plain(search_web)
47
+ ontology_mapper_agent.tool_plain(retrieve_web_page)
48
+
49
+
50
+ @ontology_mapper_agent.system_prompt
51
+ def add_ontologies(ctx: RunContext[OntologyMapperDependencies]) -> str:
52
+ """Add the list of allowed ontologies to the system prompt."""
53
+ allowed_ontologies = ctx.deps.ontologies
54
+ if allowed_ontologies:
55
+ return f"Allowed ontologies: {allowed_ontologies}"
56
+ return "Use any ontology (ideally in OBO repository)"
@@ -0,0 +1,50 @@
1
+ """
2
+ Configuration for the Ontology Mapper agent.
3
+ """
4
+ from dataclasses import dataclass, field
5
+ import os
6
+ from typing import List, Optional
7
+
8
+ from aurelian.dependencies.workdir import HasWorkdir, WorkDir
9
+
10
+
11
+ @dataclass
12
+ class OntologyMapperDependencies(HasWorkdir):
13
+ """
14
+ Configuration for the ontology mapper agent.
15
+
16
+ We include a default set of ontologies because the initial text embedding index is slow..
17
+ this can easily be changed e.g. in command line
18
+ """
19
+ max_search_results: int = 30
20
+ ontologies: List[str] = field(
21
+ default_factory=lambda: ["mondo", "hp", "go", "uberon", "cl", "mp", "envo", "obi"]
22
+ )
23
+
24
+ def __post_init__(self):
25
+ """Initialize the config with default values."""
26
+ # HasWorkdir doesn't have a __post_init__ method, so we don't call super()
27
+ if self.workdir is None:
28
+ self.workdir = WorkDir()
29
+
30
+
31
+ def get_config(ontologies: Optional[List[str]] = None) -> OntologyMapperDependencies:
32
+ """Get the Ontology Mapper configuration from environment variables or defaults."""
33
+ workdir_path = os.environ.get("AURELIAN_WORKDIR", None)
34
+ workdir = WorkDir(location=workdir_path) if workdir_path else None
35
+
36
+ config = OntologyMapperDependencies(workdir=workdir)
37
+
38
+ # Set ontologies if specified
39
+ if ontologies:
40
+ config.ontologies = ontologies
41
+
42
+ # Allow environment variable to override max search results
43
+ max_results_env = os.environ.get("MAX_SEARCH_RESULTS")
44
+ if max_results_env:
45
+ try:
46
+ config.max_search_results = int(max_results_env)
47
+ except ValueError:
48
+ pass
49
+
50
+ return config
@@ -0,0 +1,108 @@
1
+ """
2
+ Evaluation module for the Ontology Mapper agent.
3
+
4
+ This module implements evaluations for the Ontology Mapper agent using the pydantic-ai-evals framework.
5
+ """
6
+ import asyncio
7
+ import sys
8
+ from typing import Optional, Any, Dict, Callable, Awaitable
9
+
10
+ from aurelian.evaluators.model import MetadataDict, metadata
11
+ from aurelian.evaluators.substring_evaluator import SubstringEvaluator
12
+ from pydantic_evals import Case, Dataset
13
+ from pydantic_evals.evaluators import LLMJudge
14
+
15
+ from aurelian.agents.ontology_mapper.ontology_mapper_agent import ontology_mapper_agent
16
+ from aurelian.agents.ontology_mapper.ontology_mapper_config import OntologyMapperDependencies, get_config
17
+
18
+ class OntologyMapperMetadata(Dict[str, Any]):
19
+ """Simple metadata dictionary for Ontology Mapper evaluations."""
20
+ pass
21
+
22
+ # Define individual evaluation cases
23
+ case1 = Case(
24
+ name="cell_ontology_neuron",
25
+ inputs="Find the term in the cell ontology for neuron",
26
+ expected_output="CL:0000540", # Neuron ID in Cell Ontology
27
+ metadata=metadata("easy", "basic_term_lookup")
28
+ )
29
+
30
+ case2 = Case(
31
+ name="middle_fingers_terms",
32
+ inputs="Best terms to use for the middle 3 fingers",
33
+ expected_output="digit", # Should mention digit terms
34
+ metadata=metadata("medium", "anatomical_term_suggestion"),
35
+ evaluators=[
36
+ LLMJudge(
37
+ rubric="""
38
+ Answer should:
39
+ 1. Identify appropriate anatomical terms for index, middle, and ring fingers
40
+ 2. Include ontology IDs where possible
41
+ 3. Explain why these terms are appropriate
42
+ """,
43
+ include_input=True
44
+ )
45
+ ]
46
+ )
47
+
48
+ case3 = Case(
49
+ name="go_cell_division",
50
+ inputs="What is the term for the process of cell division in GO?",
51
+ expected_output="GO:0051301", # Cell division GO term
52
+ metadata=metadata("easy", "go_term_lookup")
53
+ )
54
+
55
+ case4 = Case(
56
+ name="mp_term_mapping",
57
+ inputs="""
58
+ Find good MP terms for the following. If no matches can be found, suggest appropriate action
59
+
60
+ * CA1 TBS Reduced
61
+ * CA1 TBS Increased
62
+ * Surface righting Reduced
63
+ * Contextual fear conditioning (shock context/context shock) Reduced
64
+ * Morris water maze Reduced
65
+ * Rotarod Increased
66
+ * Rotarod Reduced
67
+ """,
68
+ expected_output="MP:", # Should provide MP IDs
69
+ metadata=metadata("hard", "complex_term_mapping")
70
+ )
71
+
72
+ case5 = Case(
73
+ name="cross_ontology_mapping",
74
+ inputs="Map the Human Phenotype Ontology term for 'Seizure' (HP:0001250) to Mouse Phenotype Ontology",
75
+ expected_output="MP:0002064", # Seizure in MP
76
+ metadata=metadata("medium", "cross_ontology_mapping")
77
+ )
78
+
79
+ def create_eval_dataset() -> Dataset[str, str, MetadataDict]:
80
+ """
81
+ Create a dataset for evaluating the Ontology Mapper agent.
82
+
83
+ Returns:
84
+ Dataset of Ontology Mapper evaluation cases with appropriate evaluators
85
+ """
86
+ # Collect all cases
87
+ cases = [case1, case2, case3, case4, case5]
88
+
89
+ # Dataset-level evaluators
90
+ evaluators = [
91
+ SubstringEvaluator(),
92
+ LLMJudge(
93
+ rubric="""
94
+ Evaluate the answer based on:
95
+ 1. Accuracy of ontology term identification
96
+ 2. Correctness of ontology IDs provided
97
+ 3. Appropriateness of term selection for the given context
98
+ 4. Clear explanation of term selection logic and relationships
99
+ 5. Suitable handling of cases where no exact match exists
100
+ """,
101
+ model="anthropic:claude-3-7-sonnet-latest"
102
+ )
103
+ ]
104
+
105
+ return Dataset(
106
+ cases=cases,
107
+ evaluators=evaluators
108
+ )
@@ -0,0 +1,58 @@
1
+ """
2
+ Gradio interface for the Ontology Mapper agent.
3
+ """
4
+ import os
5
+ from typing import List, Optional
6
+
7
+ import gradio as gr
8
+
9
+ from aurelian.utils.async_utils import run_sync
10
+ from .ontology_mapper_agent import ontology_mapper_agent
11
+ from .ontology_mapper_config import OntologyMapperDependencies, get_config
12
+
13
+
14
+ def chat(deps: Optional[OntologyMapperDependencies] = None, **kwargs):
15
+ """
16
+ Initialize a chat interface for the Ontology Mapper agent.
17
+
18
+ Args:
19
+ deps: Optional dependencies configuration
20
+ **kwargs: Additional arguments to pass to the agent
21
+
22
+ Returns:
23
+ A Gradio chat interface
24
+ """
25
+ if deps is None:
26
+ deps = get_config()
27
+
28
+ def get_info(query: str, history: List[str]) -> str:
29
+ print(f"QUERY: {query}")
30
+ print(f"HISTORY: {history}")
31
+ if history:
32
+ query += "## History"
33
+ for h in history:
34
+ query += f"\n{h}"
35
+ result = run_sync(lambda: ontology_mapper_agent.run_sync(query, deps=deps, **kwargs))
36
+ return result.data
37
+
38
+ return gr.ChatInterface(
39
+ fn=get_info,
40
+ type="messages",
41
+ title="Ontology Mapper AI Assistant",
42
+ examples=[
43
+ "Find the term in the cell ontology for neuron",
44
+ "Best terms to use for the middle 3 fingers",
45
+ "What is the term for the process of cell division in GO?",
46
+ """
47
+ Find good MP terms for the following. If no matches can be found, suggest appropriate action
48
+
49
+ * CA1 TBS Reduced
50
+ * CA1 TBS Increased
51
+ * Surface righting Reduced
52
+ * Contextual fear conditioning (shock context/context shock) Reduced
53
+ * Morris water maze Reduced
54
+ * Rotarod Increased
55
+ * Rotarod Reduced
56
+ """,
57
+ ]
58
+ )