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,89 @@
1
+ """
2
+ MCP tools for filesystem operations.
3
+ """
4
+ import os
5
+ from typing import Any
6
+
7
+ from mcp.server.fastmcp import FastMCP
8
+
9
+ import aurelian.agents.filesystem.filesystem_tools as ft
10
+ from aurelian.dependencies.workdir import WorkDir, HasWorkdir
11
+ from pydantic_ai import RunContext
12
+
13
+ # Initialize FastMCP server
14
+ mcp = FastMCP("filesystem", instructions="Filesystem operations")
15
+
16
+
17
+ def deps() -> HasWorkdir:
18
+ deps = HasWorkdir()
19
+ # Set the location from environment variable or default
20
+ loc = os.getenv("AURELIAN_WORKDIR", "/tmp/aurelian")
21
+ deps.workdir = WorkDir(loc)
22
+ return deps
23
+
24
+ def ctx() -> RunContext[HasWorkdir]:
25
+ rc: RunContext[HasWorkdir] = RunContext[HasWorkdir](
26
+ deps=deps(),
27
+ model=None, usage=None, prompt=None,
28
+ )
29
+ return rc
30
+
31
+
32
+ @mcp.tool()
33
+ async def inspect_file(data_file: str) -> str:
34
+ """
35
+ Inspect a file in the working directory.
36
+
37
+ Args:
38
+ data_file: name of file
39
+
40
+ Returns:
41
+ Contents of the file
42
+ """
43
+ return await ft.inspect_file(ctx(), data_file)
44
+
45
+
46
+ @mcp.tool()
47
+ async def download_url_as_markdown(url: str, local_file_name: str) -> ft.DownloadResult:
48
+ """
49
+ Download a URL and convert to markdown.
50
+
51
+ Args:
52
+ url: The URL to download
53
+ local_file_name: The name to save the file as
54
+
55
+ Returns:
56
+ DownloadResult with file name and number of lines
57
+ """
58
+ return await ft.download_url_as_markdown(ctx(), url, local_file_name)
59
+
60
+
61
+ @mcp.tool()
62
+ async def list_files() -> str:
63
+ """
64
+ List files in the working directory.
65
+
66
+ Returns:
67
+ A string listing the files in the working directory
68
+ """
69
+ return await ft.list_files(ctx())
70
+
71
+
72
+ @mcp.tool()
73
+ async def write_to_file(file_name: str, data: str) -> str:
74
+ """
75
+ Write data to a file in the working directory.
76
+
77
+ Args:
78
+ file_name: Name of file to write
79
+ data: Data to write to the file
80
+
81
+ Returns:
82
+ Confirmation message
83
+ """
84
+ return await ft.write_to_file(ctx(), file_name, data)
85
+
86
+
87
+ if __name__ == "__main__":
88
+ # Initialize and run the server
89
+ mcp.run(transport='stdio')
@@ -0,0 +1,95 @@
1
+ import re
2
+ from typing import Any
3
+
4
+ import httpx
5
+ from pydantic import BaseModel
6
+ from pydantic_ai import RunContext
7
+
8
+ from aurelian.dependencies.workdir import WorkDir, HasWorkdir
9
+
10
+
11
+ class DownloadResult(BaseModel):
12
+ file_name: str
13
+ num_lines: int
14
+
15
+ async def inspect_file(ctx: RunContext[HasWorkdir], data_file: str) -> str:
16
+ """
17
+ Inspect a file in the working directory.
18
+
19
+ Args:
20
+ ctx:
21
+ data_file: name of file
22
+
23
+ Returns:
24
+
25
+ """
26
+ print(f"Inspecting file: {data_file}")
27
+ return ctx.deps.workdir.read_file(data_file)
28
+
29
+
30
+ async def download_url_as_markdown(ctx: RunContext[HasWorkdir], url: str, local_file_name: str) -> DownloadResult:
31
+ """
32
+ Download contents of a web page.
33
+
34
+ Args:
35
+ ctx: context
36
+ url: URL of the web page
37
+ local_file_name: Name of the local file to save the
38
+
39
+ Returns:
40
+ DownloadResult: information about the downloaded file
41
+ """
42
+ workdir: WorkDir = ctx.deps.workdir
43
+ from markdownify import markdownify
44
+
45
+ async with httpx.AsyncClient() as client:
46
+ response = await client.get(url, timeout=20.0)
47
+ response.raise_for_status() # Raise an exception for bad status codes
48
+
49
+ # Convert the HTML content to Markdown
50
+ markdown_content = markdownify(response.text).strip()
51
+
52
+ # Remove multiple line breaks
53
+ markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
54
+
55
+ # Assuming write_file is also async
56
+ workdir.write_file(local_file_name, markdown_content)
57
+
58
+ return DownloadResult(file_name=local_file_name, num_lines=len(markdown_content.split("\n")))
59
+
60
+
61
+ async def list_files(ctx: RunContext[HasWorkdir]) -> str:
62
+ """
63
+ List files in the working directory.
64
+
65
+ Args:
66
+ ctx:
67
+
68
+ Returns:
69
+
70
+ """
71
+ return "\n".join(ctx.deps.workdir.list_file_names())
72
+
73
+
74
+ async def write_to_file(ctx: RunContext[HasWorkdir], file_name: str, data: str) -> str:
75
+ """
76
+ Write data to a file in the working directory.
77
+
78
+ Args:
79
+ ctx:
80
+ file_name:
81
+ data:
82
+
83
+ Returns:
84
+
85
+ """
86
+ print(f"Writing data to file: {file_name}")
87
+ ctx.deps.workdir.write_file(file_name, data)
88
+ return f"Data written to {file_name}"
89
+
90
+
91
+ async def show_local_files(ctx: RunContext[HasWorkdir]) -> str:
92
+ file_names = ctx.deps.workdir.list_file_names()
93
+ if file_names:
94
+ return f"Local files: {file_names}"
95
+ return "No files currently in the working directory"
File without changes
File without changes
@@ -0,0 +1,83 @@
1
+ """
2
+ Agent for working with GitHub repositories, issues, and pull requests.
3
+ """
4
+ from pydantic import BaseModel
5
+ from typing import List, Optional, Dict, Any, Union
6
+
7
+ from pydantic_ai import Agent, Tool, RunContext
8
+
9
+ from aurelian.agents.github.github_config import GitHubDependencies
10
+ from aurelian.agents.github.github_tools import (
11
+ list_pull_requests,
12
+ view_pull_request,
13
+ list_issues,
14
+ view_issue,
15
+ get_pr_closing_issues,
16
+ get_commit_before_pr,
17
+ search_code,
18
+ clone_repository
19
+ )
20
+ from aurelian.agents.filesystem.filesystem_tools import inspect_file, list_files
21
+
22
+
23
+ class GitHubRepoSummary(BaseModel):
24
+ """
25
+ Summary of a GitHub repository.
26
+ """
27
+ repo_name: str
28
+ owner: str
29
+ description: Optional[str] = None
30
+ stars: Optional[int] = None
31
+ forks: Optional[int] = None
32
+ open_issues: Optional[int] = None
33
+ open_prs: Optional[int] = None
34
+
35
+
36
+ SYSTEM = """
37
+ You are a GitHub repository assistant with access to GitHub data through the GitHub CLI.
38
+
39
+ I can help you with:
40
+ - Listing and viewing pull requests
41
+ - Examining issues and their status
42
+ - Finding what issues are closed by pull requests
43
+ - Searching code within repositories
44
+ - Cloning repositories locally
45
+ - Examining commit history, especially commits before a PR was created
46
+
47
+ When answering questions about GitHub repositories, I'll use the GitHub CLI to get
48
+ the most up-to-date information. If you want to work with a specific repository,
49
+ I can clone it and then work with the files directly.
50
+
51
+ You can ask me to:
52
+ - List recent PRs or issues
53
+ - View details of specific PRs or issues
54
+ - Find what issues a PR closes
55
+ - Search for code patterns in repositories
56
+ - Clone repositories for deeper analysis
57
+ - Identify the commit before a PR branch was created
58
+
59
+ I'm best at answering specific questions that make use of GitHub's structure,
60
+ for example finding connections between PRs and issues, or examining code across
61
+ a repository.
62
+ """
63
+
64
+
65
+ github_tools = [
66
+ Tool(list_pull_requests),
67
+ Tool(view_pull_request),
68
+ Tool(list_issues),
69
+ Tool(view_issue),
70
+ Tool(get_pr_closing_issues),
71
+ Tool(get_commit_before_pr),
72
+ Tool(search_code),
73
+ Tool(clone_repository),
74
+ Tool(inspect_file),
75
+ Tool(list_files),
76
+ ]
77
+
78
+ github_agent = Agent(
79
+ model="openai:gpt-4o",
80
+ deps_type=GitHubDependencies,
81
+ system_prompt=SYSTEM,
82
+ tools=github_tools,
83
+ )
@@ -0,0 +1,248 @@
1
+ """
2
+ Command-line interface for the GitHub agent.
3
+ """
4
+ import os
5
+ import sys
6
+ import json
7
+ import click
8
+ import tempfile
9
+ import logging
10
+ from pathlib import Path
11
+ from typing import Optional
12
+
13
+ from aurelian.agents.github.github_agent import github_agent
14
+ from aurelian.agents.github.github_config import GitHubDependencies
15
+ from aurelian.dependencies.workdir import WorkDir
16
+
17
+
18
+ def setup_logging():
19
+ """Set up logging for the CLI."""
20
+ logging.basicConfig(
21
+ level=logging.INFO,
22
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
23
+ handlers=[logging.StreamHandler(sys.stdout)]
24
+ )
25
+
26
+
27
+ def create_deps(workdir: Optional[str] = None) -> GitHubDependencies:
28
+ """
29
+ Create dependencies for the GitHub agent.
30
+
31
+ Args:
32
+ workdir: Working directory path. If None, uses current directory.
33
+
34
+ Returns:
35
+ GitHubDependencies instance
36
+ """
37
+ deps = GitHubDependencies()
38
+ if workdir:
39
+ wd_path = Path(workdir)
40
+ # Create directory if it doesn't exist
41
+ if not wd_path.exists():
42
+ wd_path.mkdir(parents=True)
43
+ else:
44
+ workdir = os.getcwd()
45
+
46
+ deps.workdir = WorkDir(location=workdir)
47
+ return deps
48
+
49
+
50
+ @click.group()
51
+ @click.option('--workdir', '-w', help='Working directory path')
52
+ @click.pass_context
53
+ def cli(ctx, workdir):
54
+ """GitHub repository assistant CLI."""
55
+ setup_logging()
56
+ ctx.obj = create_deps(workdir)
57
+
58
+
59
+ @cli.command()
60
+ @click.argument('repo')
61
+ @click.option('--directory', '-d', help='Directory name to clone into')
62
+ @click.option('--branch', '-b', help='Branch to clone')
63
+ @click.option('--depth', type=int, help='Depth limit for clone (for shallow clones)')
64
+ @click.pass_obj
65
+ def clone(deps, repo, directory, branch, depth):
66
+ """Clone a GitHub repository."""
67
+ from aurelian.agents.github.github_tools import clone_repository
68
+ from pydantic_ai import RunContext
69
+
70
+ ctx = RunContext[GitHubDependencies](deps=deps, model="openai:gpt-4o", usage=None, prompt="")
71
+
72
+ try:
73
+ clone_dir = clone_repository(ctx, repo, directory, branch, depth)
74
+ click.echo(f"Successfully cloned {repo} to {clone_dir}")
75
+
76
+ # Optionally update workdir to the cloned repo
77
+ if click.confirm("Do you want to set the working directory to the cloned repository?"):
78
+ deps.workdir = WorkDir(location=clone_dir)
79
+ click.echo(f"Working directory updated to: {clone_dir}")
80
+ except Exception as e:
81
+ click.echo(f"Error cloning repository: {str(e)}", err=True)
82
+ sys.exit(1)
83
+
84
+
85
+ @cli.command()
86
+ @click.option('--state', '-s', default='open', help='Filter by state (open, closed, merged, all)')
87
+ @click.option('--limit', '-l', default=10, type=int, help='Maximum number of PRs to return')
88
+ @click.option('--label', help='Filter by label')
89
+ @click.option('--author', '-a', help='Filter by author')
90
+ @click.option('--base', help='Filter by base branch')
91
+ @click.option('--repo', '-r', help='Repository (format: owner/repo)')
92
+ @click.option('--output', '-o', help='Output file path')
93
+ @click.option('--format', 'format_', type=click.Choice(['pretty', 'json']), default='pretty',
94
+ help='Output format (pretty or json)')
95
+ @click.pass_obj
96
+ def list_prs(deps, state, limit, label, author, base, repo, output, format_):
97
+ """List pull requests from GitHub."""
98
+ from aurelian.agents.github.github_tools import list_pull_requests
99
+ from pydantic_ai import RunContext
100
+
101
+ ctx = RunContext[GitHubDependencies](deps=deps, model="openai:gpt-4o", usage=None, prompt="")
102
+
103
+ try:
104
+ results = list_pull_requests(ctx, state, limit, label, author, base, repo)
105
+
106
+ if format_ == 'json':
107
+ output_data = json.dumps(results, indent=2)
108
+ else:
109
+ output_data = "Pull Requests:\n"
110
+ for i, pr in enumerate(results, 1):
111
+ output_data += f"{i}. #{pr['number']} - {pr['title']} ({pr['state']})\n"
112
+ output_data += f" Author: {pr['author']['login']}\n"
113
+ output_data += f" Created: {pr['createdAt']}\n"
114
+ output_data += f" URL: {pr['url']}\n\n"
115
+
116
+ if output:
117
+ with open(output, 'w') as f:
118
+ f.write(output_data)
119
+ click.echo(f"Results written to {output}")
120
+ else:
121
+ click.echo(output_data)
122
+ except Exception as e:
123
+ click.echo(f"Error listing pull requests: {str(e)}", err=True)
124
+ sys.exit(1)
125
+
126
+
127
+ @cli.command()
128
+ @click.argument('pr_number')
129
+ @click.option('--repo', '-r', help='Repository (format: owner/repo)')
130
+ @click.option('--output', '-o', help='Output file path')
131
+ @click.option('--format', 'format_', type=click.Choice(['pretty', 'json']), default='pretty',
132
+ help='Output format (pretty or json)')
133
+ @click.pass_obj
134
+ def view_pr(deps, pr_number, repo, output, format_):
135
+ """View a specific pull request."""
136
+ from aurelian.agents.github.github_tools import view_pull_request
137
+ from pydantic_ai import RunContext
138
+
139
+ ctx = RunContext[GitHubDependencies](deps=deps, model="openai:gpt-4o", usage=None, prompt="")
140
+
141
+ try:
142
+ result = view_pull_request(ctx, pr_number, repo)
143
+
144
+ if format_ == 'json':
145
+ output_data = json.dumps(result, indent=2)
146
+ else:
147
+ output_data = f"PR #{result['number']}: {result['title']}\n"
148
+ output_data += f"State: {result['state']}\n"
149
+ output_data += f"Author: {result['author']['login']}\n"
150
+ output_data += f"Created: {result['createdAt']}\n"
151
+ output_data += f"URL: {result['url']}\n"
152
+ output_data += f"Base: {result['baseRefName']} <- Head: {result['headRefName']}\n\n"
153
+ output_data += f"Description:\n{result['body']}\n\n"
154
+
155
+ if result.get('closingIssues'):
156
+ output_data += "Closes Issues:\n"
157
+ for issue in result['closingIssues']:
158
+ output_data += f"- #{issue['number']}: {issue['title']}\n"
159
+
160
+ if output:
161
+ with open(output, 'w') as f:
162
+ f.write(output_data)
163
+ click.echo(f"Results written to {output}")
164
+ else:
165
+ click.echo(output_data)
166
+ except Exception as e:
167
+ click.echo(f"Error viewing pull request: {str(e)}", err=True)
168
+ sys.exit(1)
169
+
170
+
171
+ @cli.command()
172
+ @click.argument('pr_number')
173
+ @click.option('--repo', '-r', help='Repository (format: owner/repo)')
174
+ @click.pass_obj
175
+ def commit_before_pr(deps, pr_number, repo):
176
+ """Get the commit before a PR branch was created."""
177
+ from aurelian.agents.github.github_tools import get_commit_before_pr
178
+ from pydantic_ai import RunContext
179
+
180
+ ctx = RunContext[GitHubDependencies](deps=deps, model="openai:gpt-4o", usage=None, prompt="")
181
+
182
+ try:
183
+ result = get_commit_before_pr(ctx, pr_number, repo)
184
+ click.echo(f"Commit before PR #{pr_number} was created:")
185
+ click.echo(f"Hash: {result['hash']}")
186
+ click.echo(f"Message:\n{result['message']}")
187
+ except Exception as e:
188
+ click.echo(f"Error getting commit before PR: {str(e)}", err=True)
189
+ sys.exit(1)
190
+
191
+
192
+ @cli.command()
193
+ @click.argument('query')
194
+ @click.option('--repo', '-r', help='Repository (format: owner/repo)')
195
+ @click.option('--output', '-o', help='Output file path')
196
+ @click.pass_obj
197
+ def search(deps, query, repo, output):
198
+ """Search for code in a repository."""
199
+ from aurelian.agents.github.github_tools import search_code
200
+ from pydantic_ai import RunContext
201
+
202
+ ctx = RunContext[GitHubDependencies](deps=deps, model="openai:gpt-4o", usage=None, prompt="")
203
+
204
+ try:
205
+ results = search_code(ctx, query, repo)
206
+
207
+ output_data = f"Search results for: {query}\n\n"
208
+ for i, match in enumerate(results, 1):
209
+ output_data += f"{i}. {match['path']}\n"
210
+ for text_match in match.get('textMatches', []):
211
+ if 'fragment' in text_match:
212
+ output_data += f" ...{text_match['fragment']}...\n"
213
+ output_data += "\n"
214
+
215
+ if output:
216
+ with open(output, 'w') as f:
217
+ f.write(output_data)
218
+ click.echo(f"Results written to {output}")
219
+ else:
220
+ click.echo(output_data)
221
+ except Exception as e:
222
+ click.echo(f"Error searching code: {str(e)}", err=True)
223
+ sys.exit(1)
224
+
225
+
226
+ @cli.command()
227
+ @click.option('--query', '-q', help='Initial question or prompt for the agent')
228
+ @click.pass_obj
229
+ def chat(deps, query):
230
+ """Start an interactive chat with the GitHub agent."""
231
+ click.echo("Starting chat with GitHub agent. Type 'exit' or 'quit' to end.")
232
+
233
+ if query:
234
+ response = github_agent.chat(query, deps=deps)
235
+ click.echo(f"Agent: {response.content}")
236
+
237
+ while True:
238
+ user_input = click.prompt("You", type=str)
239
+ if user_input.lower() in ('exit', 'quit'):
240
+ click.echo("Exiting chat.")
241
+ break
242
+
243
+ response = github_agent.chat(user_input, deps=deps)
244
+ click.echo(f"Agent: {response.content}")
245
+
246
+
247
+ if __name__ == '__main__':
248
+ cli()
@@ -0,0 +1,22 @@
1
+ """
2
+ Configuration for the GitHub agent.
3
+ """
4
+ import os
5
+
6
+ from aurelian.dependencies.workdir import HasWorkdir, WorkDir
7
+
8
+
9
+ class GitHubDependencies(HasWorkdir):
10
+ """
11
+ GitHub 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() -> GitHubDependencies:
19
+ workdir_path = os.environ.get("AURELIAN_WORKDIR", None)
20
+ workdir = WorkDir(location=workdir_path) if workdir_path else None
21
+
22
+ return GitHubDependencies(workdir=workdir)
@@ -0,0 +1,152 @@
1
+ """
2
+ Gradio UI for the GitHub agent.
3
+ """
4
+ from typing import List, Optional
5
+ import tempfile
6
+ import os
7
+ import shutil
8
+
9
+ import gradio as gr
10
+
11
+ from aurelian.agents.github.github_config import GitHubDependencies
12
+ from aurelian.agents.github.github_agent import github_agent
13
+ from aurelian.utils.async_utils import run_sync
14
+ from aurelian.dependencies.workdir import WorkDir
15
+
16
+
17
+ def create_demo(workspace_dir: Optional[str] = None) -> gr.Blocks:
18
+ """
19
+ Create a Gradio demo for the GitHub agent.
20
+
21
+ Args:
22
+ workspace_dir: Directory to use as workspace. If None, a temporary directory is created.
23
+
24
+ Returns:
25
+ Gradio Blocks interface
26
+ """
27
+ temp_dir = None
28
+ if workspace_dir is None:
29
+ temp_dir = tempfile.mkdtemp()
30
+ workspace_dir = temp_dir
31
+
32
+ deps = GitHubDependencies()
33
+ deps.workdir = WorkDir(location=workspace_dir)
34
+
35
+ with gr.Blocks(title="GitHub Agent") as demo:
36
+ gr.Markdown("# GitHub Repository Agent")
37
+ gr.Markdown("""
38
+ This agent helps you work with GitHub repositories, issues, and pull requests.
39
+
40
+ You can:
41
+ - List and view pull requests and issues
42
+ - Find connections between PRs and issues
43
+ - Search code in repositories
44
+ - Clone repositories for deeper analysis
45
+ - Examine commit history
46
+
47
+ The agent uses the GitHub CLI, so you need to have it installed and authenticated.
48
+ """)
49
+
50
+ current_dir_md = gr.Markdown(f"**Working Directory**: {workspace_dir}")
51
+
52
+ def update_current_dir():
53
+ return f"**Working Directory**: {deps.workdir.location}"
54
+
55
+ with gr.Row():
56
+ with gr.Column():
57
+ repo_input = gr.Textbox(label="Repository (owner/repo)")
58
+ clone_btn = gr.Button("Clone Repository")
59
+
60
+ with gr.Column():
61
+ directory_input = gr.Textbox(label="Directory Name (optional)")
62
+ branch_input = gr.Textbox(label="Branch (optional)")
63
+
64
+ def clone_repo(repo: str, directory: Optional[str] = None, branch: Optional[str] = None):
65
+ from aurelian.agents.github.github_tools import clone_repository
66
+ from pydantic_ai import RunContext
67
+
68
+ ctx = RunContext[GitHubDependencies](
69
+ deps=deps,
70
+ model="openai:gpt-4o",
71
+ usage=None,
72
+ prompt=""
73
+ )
74
+
75
+ if not repo:
76
+ return "Please enter a repository name in the format owner/repo", update_current_dir()
77
+
78
+ try:
79
+ clone_dir = clone_repository(ctx, repo, directory, branch)
80
+ # Set workdir to the cloned repo
81
+ deps.workdir = WorkDir(location=clone_dir)
82
+ return f"Successfully cloned {repo} to {clone_dir}", update_current_dir()
83
+ except Exception as e:
84
+ return f"Error cloning repository: {str(e)}", update_current_dir()
85
+
86
+ clone_result = gr.Textbox(label="Clone Result")
87
+ clone_btn.click(clone_repo, inputs=[repo_input, directory_input, branch_input], outputs=[clone_result, current_dir_md])
88
+
89
+ def get_info(query: str, history: List[List[str]]) -> str:
90
+ flattened_history = []
91
+ for h in history:
92
+ flattened_history.extend(h)
93
+
94
+ return run_sync(lambda: github_agent.chat(
95
+ query,
96
+ deps=deps
97
+ ).content)
98
+
99
+ chatbot = gr.Chatbot()
100
+ msg = gr.Textbox(label="Your question about GitHub repositories")
101
+
102
+ msg.submit(get_info, inputs=[msg, chatbot], outputs=chatbot)
103
+
104
+ examples = [
105
+ "List the most recent open pull requests",
106
+ "What issues will be closed by PR #31?",
107
+ "What was the commit before PR #31 was created?",
108
+ "Search for code related to 'RunContext'",
109
+ "Clone the repository 'obophenotype/cell-ontology' and list its files",
110
+ ]
111
+ gr.Examples(examples=examples, inputs=msg)
112
+
113
+ # Cleanup temporary directory when demo is closed
114
+ if temp_dir:
115
+ def cleanup():
116
+ if os.path.exists(temp_dir):
117
+ shutil.rmtree(temp_dir)
118
+
119
+ demo.close_callbacks.append(cleanup)
120
+
121
+ return demo
122
+
123
+
124
+ def chat(deps: Optional[GitHubDependencies] = None, **kwargs):
125
+ """
126
+ Initialize a chat interface for the GitHub agent.
127
+
128
+ Args:
129
+ deps: Optional dependencies configuration
130
+ **kwargs: Additional arguments to pass to the agent
131
+
132
+ Returns:
133
+ A Gradio chat interface
134
+ """
135
+ if deps is None:
136
+ deps = GitHubDependencies()
137
+ deps.workdir = WorkDir(location=os.getcwd())
138
+
139
+ def get_info(query: str, history: List[str]) -> str:
140
+ result = run_sync(lambda: github_agent.chat(query, deps=deps, **kwargs))
141
+ return result.content
142
+
143
+ return gr.ChatInterface(
144
+ fn=get_info,
145
+ title="GitHub AI Assistant",
146
+ examples=[
147
+ "List all open issues in monarch-initiative/aurelian",
148
+ "Show me pull request #31 in monarch-initiative/aurelian",
149
+ "Search for code related to RunContext in monarch-initiative/aurelian",
150
+ "Get the commit before PR #31 was created"
151
+ ]
152
+ )