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,413 @@
1
+ """
2
+ Tools for interacting with GitHub via command line tools (gh and git).
3
+ """
4
+ import json
5
+ import subprocess
6
+ import os
7
+ import asyncio
8
+ from typing import Dict, List, Optional, Union, Any, Protocol
9
+
10
+ from pydantic_ai import RunContext
11
+
12
+ from aurelian.dependencies.workdir import HasWorkdir
13
+
14
+ # Field constants for GitHub API responses
15
+ NUMBER = "number"
16
+ TITLE = "title"
17
+ AUTHOR = "author"
18
+ URL = "url"
19
+ STATE = "state"
20
+ CREATED_AT = "createdAt"
21
+ CLOSED_AT = "closedAt"
22
+ BODY = "body"
23
+ LABELS = "labels"
24
+ ASSIGNEES = "assignees"
25
+ COMMENTS = "comments"
26
+ BASE_REF_NAME = "baseRefName"
27
+ HEAD_REF_NAME = "headRefName"
28
+ IS_DRAFT = "isDraft"
29
+ COMMITS = "commits"
30
+ FILES = "files"
31
+ REVIEWS = "reviews"
32
+ CLOSING_ISSUES = "closingIssues"
33
+ PATH = "path"
34
+ REPOSITORY = "repository"
35
+ TEXT_MATCHES = "textMatches"
36
+
37
+ # Field groupings for common use cases
38
+ CORE_FIELDS = [NUMBER, TITLE, AUTHOR, URL, STATE, CREATED_AT, CLOSED_AT, BODY]
39
+ ISSUE_FIELDS = CORE_FIELDS + [LABELS, ASSIGNEES]
40
+ ISSUE_DETAIL_FIELDS = ISSUE_FIELDS + [COMMENTS]
41
+ PR_FIELDS = CORE_FIELDS + [BASE_REF_NAME, HEAD_REF_NAME, IS_DRAFT, LABELS]
42
+ PR_DETAIL_FIELDS = PR_FIELDS + [COMMITS, FILES, COMMENTS, REVIEWS]
43
+ SEARCH_CODE_FIELDS = [PATH, REPOSITORY, TEXT_MATCHES]
44
+
45
+ async def _run_gh_command(args: List[str], cwd: Optional[str] = None) -> str:
46
+ """
47
+ Run a GitHub CLI command and return the output.
48
+
49
+ Args:
50
+ args: List of command line arguments to pass to gh
51
+ cwd: Current working directory in which to run the command
52
+
53
+ Returns:
54
+ The command output as a string
55
+
56
+ Raises:
57
+ subprocess.CalledProcessError: If the command fails
58
+ """
59
+ cmd = ["gh"] + args
60
+ proc = await asyncio.create_subprocess_exec(
61
+ *cmd,
62
+ stdout=asyncio.subprocess.PIPE,
63
+ stderr=asyncio.subprocess.PIPE,
64
+ cwd=cwd
65
+ )
66
+ stdout, stderr = await proc.communicate()
67
+
68
+ if proc.returncode != 0:
69
+ error_msg = stderr.decode('utf-8').strip()
70
+ raise subprocess.CalledProcessError(proc.returncode, cmd, stdout + stderr, stderr)
71
+
72
+ return stdout.decode('utf-8').strip()
73
+
74
+ async def list_pull_requests(
75
+ ctx: RunContext[HasWorkdir],
76
+ state: str = "open",
77
+ limit: int = 10,
78
+ label: Optional[str] = None,
79
+ author: Optional[str] = None,
80
+ base_branch: Optional[str] = None,
81
+ repo: Optional[str] = None
82
+ ) -> List[Dict[str, Any]]:
83
+ """
84
+ List pull requests from GitHub.
85
+
86
+ Args:
87
+ ctx: Run context with workdir dependency
88
+ state: Filter by state (open, closed, merged, all)
89
+ limit: Maximum number of PRs to return
90
+ label: Filter by label
91
+ author: Filter by author
92
+ base_branch: Filter by base branch
93
+ repo: Repository to list PRs from (format: owner/repo), defaults to current repo
94
+
95
+ Returns:
96
+ List of pull requests as dictionaries
97
+ """
98
+ # Get workdir location - handle both string and object workdirs
99
+ workdir = ctx.deps.workdir
100
+ if hasattr(workdir, 'location'):
101
+ workdir = workdir.location
102
+
103
+ args = ["pr", "list", "--json", ",".join(PR_FIELDS)]
104
+
105
+ if state and state != "all":
106
+ args.extend(["--state", state])
107
+
108
+ if limit:
109
+ args.extend(["--limit", str(limit)])
110
+
111
+ if label:
112
+ args.extend(["--label", label])
113
+
114
+ if author:
115
+ args.extend(["--author", author])
116
+
117
+ if base_branch:
118
+ args.extend(["--base", base_branch])
119
+
120
+ if repo:
121
+ args.extend(["--repo", repo])
122
+
123
+ output = await _run_gh_command(args, cwd=workdir)
124
+ return json.loads(output)
125
+
126
+ async def view_pull_request(
127
+ ctx: RunContext[HasWorkdir],
128
+ pr_number: Union[int, str],
129
+ repo: Optional[str] = None
130
+ ) -> Dict[str, Any]:
131
+ """
132
+ Get detailed information about a specific pull request.
133
+
134
+ Args:
135
+ ctx: Run context with workdir dependency
136
+ pr_number: The pull request number
137
+ repo: Repository the PR belongs to (format: owner/repo), defaults to current repo
138
+
139
+ Returns:
140
+ Pull request details as a dictionary
141
+ """
142
+ # Get workdir location - handle both string and object workdirs
143
+ workdir = ctx.deps.workdir
144
+ if hasattr(workdir, 'location'):
145
+ workdir = workdir.location
146
+
147
+ args = ["pr", "view", str(pr_number), "--json", ",".join(PR_DETAIL_FIELDS)]
148
+
149
+ if repo:
150
+ args.extend(["--repo", repo])
151
+
152
+ output = await _run_gh_command(args, cwd=workdir)
153
+ return json.loads(output)
154
+
155
+ async def list_issues(
156
+ ctx: RunContext[HasWorkdir],
157
+ state: str = "open",
158
+ limit: int = 10,
159
+ label: Optional[str] = None,
160
+ author: Optional[str] = None,
161
+ assignee: Optional[str] = None,
162
+ repo: Optional[str] = None
163
+ ) -> List[Dict[str, Any]]:
164
+ """
165
+ List issues from GitHub.
166
+
167
+ Args:
168
+ ctx: Run context with workdir dependency
169
+ state: Filter by state (open, closed, all)
170
+ limit: Maximum number of issues to return
171
+ label: Filter by label
172
+ author: Filter by author
173
+ assignee: Filter by assignee
174
+ repo: Repository to list issues from (format: owner/repo), defaults to current repo
175
+
176
+ Returns:
177
+ List of issues as dictionaries
178
+ """
179
+ # Get workdir location - handle both string and object workdirs
180
+ workdir = ctx.deps.workdir
181
+ if hasattr(workdir, 'location'):
182
+ workdir = workdir.location
183
+
184
+ args = ["issue", "list", "--json", ",".join(ISSUE_FIELDS)]
185
+
186
+ if state and state != "all":
187
+ args.extend(["--state", state])
188
+
189
+ if limit:
190
+ args.extend(["--limit", str(limit)])
191
+
192
+ if label:
193
+ args.extend(["--label", label])
194
+
195
+ if author:
196
+ args.extend(["--author", author])
197
+
198
+ if assignee:
199
+ args.extend(["--assignee", assignee])
200
+
201
+ if repo:
202
+ args.extend(["--repo", repo])
203
+
204
+ output = await _run_gh_command(args, cwd=workdir)
205
+ return json.loads(output)
206
+
207
+ async def view_issue(
208
+ ctx: RunContext[HasWorkdir],
209
+ issue_number: Union[int, str],
210
+ repo: Optional[str] = None
211
+ ) -> Dict[str, Any]:
212
+ """
213
+ Get detailed information about a specific issue.
214
+
215
+ Args:
216
+ ctx: Run context with workdir dependency
217
+ issue_number: The issue number
218
+ repo: Repository the issue belongs to (format: owner/repo), defaults to current repo
219
+
220
+ Returns:
221
+ Issue details as a dictionary
222
+ """
223
+ # Get workdir location - handle both string and object workdirs
224
+ workdir = ctx.deps.workdir
225
+ if hasattr(workdir, 'location'):
226
+ workdir = workdir.location
227
+
228
+ args = ["issue", "view", str(issue_number), "--json", ",".join(ISSUE_DETAIL_FIELDS),
229
+ "--color", "never"]
230
+
231
+ if repo:
232
+ args.extend(["--repo", repo])
233
+
234
+ output = await _run_gh_command(args, cwd=workdir)
235
+ return json.loads(output)
236
+
237
+ async def get_pr_closing_issues(
238
+ ctx: RunContext[HasWorkdir],
239
+ pr_number: Union[int, str],
240
+ repo: Optional[str] = None
241
+ ) -> List[Dict[str, Any]]:
242
+ """
243
+ Get the issues that will be closed by a specific pull request.
244
+
245
+ Args:
246
+ ctx: Run context with workdir dependency
247
+ pr_number: The pull request number
248
+ repo: Repository the PR belongs to (format: owner/repo), defaults to current repo
249
+
250
+ Returns:
251
+ List of issues closed by the PR
252
+ """
253
+ pr_details = await view_pull_request(ctx, pr_number, repo)
254
+ return pr_details.get(CLOSING_ISSUES, [])
255
+
256
+ async def _run_git_command(args: List[str], cwd: Optional[str] = None) -> str:
257
+ """
258
+ Run a git command and return the output.
259
+
260
+ Args:
261
+ args: List of command line arguments to pass to git
262
+ cwd: Current working directory in which to run the command
263
+
264
+ Returns:
265
+ The command output as a string
266
+
267
+ Raises:
268
+ subprocess.CalledProcessError: If the command fails
269
+ """
270
+ cmd = ["git"] + args
271
+ proc = await asyncio.create_subprocess_exec(
272
+ *cmd,
273
+ stdout=asyncio.subprocess.PIPE,
274
+ stderr=asyncio.subprocess.PIPE,
275
+ cwd=cwd
276
+ )
277
+ stdout, stderr = await proc.communicate()
278
+
279
+ if proc.returncode != 0:
280
+ error_msg = stderr.decode('utf-8').strip()
281
+ raise subprocess.CalledProcessError(proc.returncode, cmd, stdout, stderr)
282
+
283
+ return stdout.decode('utf-8').strip()
284
+
285
+ async def get_commit_before_pr(
286
+ ctx: RunContext[HasWorkdir],
287
+ pr_number: Union[int, str],
288
+ repo: Optional[str] = None
289
+ ) -> Dict[str, str]:
290
+ """
291
+ Get the commit hash before a PR branch was created.
292
+ This identifies the commit from which the PR branch was created.
293
+
294
+ Args:
295
+ ctx: Run context with workdir dependency
296
+ pr_number: The pull request number
297
+ repo: Repository the PR belongs to (format: owner/repo), defaults to current repo
298
+
299
+ Returns:
300
+ Dictionary with commit hash and message
301
+ """
302
+ # Get workdir location - handle both string and object workdirs
303
+ workdir = ctx.deps.workdir
304
+ if hasattr(workdir, 'location'):
305
+ workdir = workdir.location
306
+
307
+ # First get PR details to identify the base and head branches
308
+ pr_details = await view_pull_request(ctx, pr_number, repo)
309
+ base_branch = pr_details["baseRefName"]
310
+ head_branch = pr_details["headRefName"]
311
+
312
+ # Get the first commit on the PR branch
313
+ first_pr_commit = await _run_git_command(
314
+ ["log", base_branch + ".." + head_branch, "--reverse", "--format=%H", "--max-count=1"],
315
+ cwd=workdir
316
+ )
317
+
318
+ # Get the parent commit of the first PR commit (the commit before the PR started)
319
+ base_commit = await _run_git_command(["rev-parse", first_pr_commit + "^"], cwd=workdir)
320
+ commit_message = await _run_git_command(["log", "-1", "--format=%B", base_commit], cwd=workdir)
321
+
322
+ return {
323
+ "hash": base_commit,
324
+ "message": commit_message
325
+ }
326
+
327
+ async def search_code(
328
+ ctx: RunContext[HasWorkdir],
329
+ query: str,
330
+ repo: Optional[str] = None
331
+ ) -> List[Dict[str, Any]]:
332
+ """
333
+ Search for code in a repository.
334
+
335
+ Args:
336
+ ctx: Run context with workdir dependency
337
+ query: The search query
338
+ repo: Repository to search in (format: owner/repo), defaults to current repo
339
+
340
+ Returns:
341
+ List of code matches as dictionaries
342
+ """
343
+ # Get workdir location - handle both string and object workdirs
344
+ workdir = ctx.deps.workdir
345
+ if hasattr(workdir, 'location'):
346
+ workdir = workdir.location
347
+
348
+ args = ["search", "code", query, "--json", ",".join(SEARCH_CODE_FIELDS)]
349
+
350
+ if repo:
351
+ query = f"repo:{repo} {query}"
352
+ args[2] = query
353
+
354
+ output = await _run_gh_command(args, cwd=workdir)
355
+ return json.loads(output)
356
+
357
+ async def clone_repository(
358
+ ctx: RunContext[HasWorkdir],
359
+ repo: str,
360
+ directory: Optional[str] = None,
361
+ branch: Optional[str] = None,
362
+ depth: Optional[int] = None
363
+ ) -> str:
364
+ """
365
+ Clone a GitHub repository to a local directory.
366
+
367
+ Args:
368
+ ctx: Run context with workdir dependency
369
+ repo: Repository to clone (format: owner/repo)
370
+ directory: Directory name to clone into (defaults to repo name)
371
+ branch: Branch to clone (defaults to default branch)
372
+ depth: Depth limit for clone (use for shallow clones)
373
+
374
+ Returns:
375
+ Path to the cloned repository
376
+ """
377
+ # Get workdir location - handle both string and object workdirs
378
+ workdir = ctx.deps.workdir
379
+ if hasattr(workdir, 'location'):
380
+ workdir = workdir.location
381
+
382
+ # Build command
383
+ args = ["repo", "clone", repo]
384
+
385
+ # Add optional directory
386
+ if directory:
387
+ args.append(directory)
388
+ else:
389
+ # Default to repo name
390
+ directory = repo.split("/")[-1]
391
+
392
+ # check if directory exists
393
+ if os.path.exists(os.path.join(workdir, directory)):
394
+ raise FileExistsError(f"Directory {directory} already exists.")
395
+
396
+ # Add branch if specified
397
+ if branch:
398
+ args.extend(["--branch", branch])
399
+
400
+ # Add depth if specified
401
+ if depth:
402
+ args.extend(["--depth", str(depth)])
403
+
404
+ # Run the clone command
405
+ await _run_gh_command(args, cwd=workdir)
406
+
407
+ # Return the full path to the cloned repo
408
+ if os.path.isabs(workdir):
409
+ return os.path.join(workdir, directory)
410
+ else:
411
+ # If workdir is relative, make it absolute
412
+ abs_workdir = os.path.abspath(workdir)
413
+ return os.path.join(abs_workdir, directory)
@@ -0,0 +1,13 @@
1
+ """
2
+ GO Annotation Review agent module for reviewing GO standard annotations.
3
+ """
4
+ from pathlib import Path
5
+
6
+ THIS_DIR = Path(__file__).parent
7
+ DOCUMENTS_DIR = THIS_DIR / "documents"
8
+
9
+ __all__ = [
10
+ # Constants
11
+ "THIS_DIR",
12
+ "DOCUMENTS_DIR",
13
+ ]