bioguider 0.2.4__py3-none-any.whl → 0.2.6__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.

Potentially problematic release.


This version of bioguider might be problematic. Click here for more details.

@@ -0,0 +1,151 @@
1
+ import os
2
+ from pathlib import Path
3
+ import logging
4
+ from typing import Callable, Optional
5
+ from abc import ABC, abstractmethod
6
+ from langchain.prompts import ChatPromptTemplate
7
+ from langchain_openai.chat_models.base import BaseChatOpenAI
8
+ from pydantic import BaseModel, Field
9
+
10
+ from bioguider.agents.agent_utils import read_file
11
+ from bioguider.utils.constants import DEFAULT_TOKEN_USAGE, ProjectMetadata
12
+ from .common_agent_2step import CommonAgentTwoSteps, CommonAgentTwoChainSteps
13
+ from .common_agent import CommonConversation
14
+ from ..utils.pyphen_utils import PyphenReadability
15
+ from ..utils.gitignore_checker import GitignoreChecker
16
+ from .evaluation_task import EvaluationTask
17
+ from .agent_utils import read_file
18
+
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ EVALUATION_INSTALLATION_SYSTEM_PROMPT = """
23
+ You are an expert in evaluating the quality of **installation instructions** in software repositories.
24
+ Your task is to analyze the provided content of installation-related files and generate a **comprehensive, structured quality report**.
25
+
26
+ ---
27
+
28
+ ### Evaluation Criteria
29
+
30
+ Please assess the installation information using the following criteria. For each, provide a concise evaluation and specific feedback:
31
+
32
+ 1. **Ease of Access**
33
+ * Is the installation information clearly presented and easy to locate within the repository?
34
+ * Is it included in a top-level README, a dedicated INSTALL.md file, or other accessible locations?
35
+
36
+ 2. **Clarity of Dependency Specification**
37
+ * Are all software and library dependencies clearly listed?
38
+ * Are installation methods (e.g., `pip`, `conda`, `apt`) for those dependencies explicitly provided?
39
+
40
+ 3. **Hardware Requirements**
41
+ * Does the documentation specify hardware needs (e.g., GPU, memory, OS) if relevant?
42
+
43
+ 4. **Step-by-Step Installation Guide**
44
+ * Is there a clear, ordered set of instructions for installing the software?
45
+ * Are example commands or configuration steps provided to help users follow along?
46
+
47
+ ---
48
+
49
+ ### Output Format
50
+
51
+ Your response **must exactly follow** the structure below:
52
+
53
+ ```
54
+ **FinalAnswer**
55
+ **Overall Score:** [Poor / Fair / Good / Excellent]
56
+ **Ease of Access:** <your comments>
57
+ **Clarity of Dependency Specification:** <your comments>
58
+ **Hardware Requirements:** <your comments>
59
+ **Installation Guide:** <your comments>
60
+ ```
61
+
62
+ ---
63
+
64
+ ### Installation Files Provided:
65
+ {installation_file_contents}
66
+
67
+ """
68
+
69
+ class EvaluationInstallationResult(BaseModel):
70
+ ease_of_access: Optional[str]=Field(description="Is the installation information easy to access")
71
+ score: Optional[str]=Field(description="An overall score, could be Poor, Fair, Good or Excellent")
72
+ clarity_of_dependency: Optional[str]=Field(description="Are all dependencies clearly listed")
73
+ hardware_requirements: Optional[str]=Field(description="Are all hardware requirements clearly specified")
74
+ installation_guide: Optional[str]=Field(description="Is there a clear, ordered set of instructions for installing the software")
75
+
76
+ EvaluationInstallationResultSchema = {
77
+ "title": "EvaluationREADMEResult",
78
+ "type": "object",
79
+ "properties": {
80
+ "ease_of_access": {
81
+ "anyOf": [{"type": "string"}, {"type": "null"}],
82
+ "description": "Is the installation information easy to access",
83
+ "title": "Ease of Access"
84
+ },
85
+ "score": {
86
+ "anyOf": [{"type": "string"}, {"type": "null"}],
87
+ "description": "An overall score, could be Poor, Fair, Good or Excellent",
88
+ "title": "Score"
89
+ },
90
+ "clarity_of_dependency": {
91
+ "anyOf": [{"type": "string"}, {"type": "null"}],
92
+ "description": "Are all dependencies clearly listed",
93
+ "title": "Clarity of Dependency",
94
+ },
95
+ "hardware_requirements": {
96
+ "anyOf": [{"type": "string"}, {"type": "null"}],
97
+ "description": "Are all hardware requirements clearly specified",
98
+ "title": "Hardware Requirements"
99
+ },
100
+ "installation_guide": {
101
+ "anyOf": [{"type": "string"}, {"type": "null"}],
102
+ "description": "Is there a clear, ordered set of instructions for installing the software",
103
+ "title": "Installation Guide"
104
+ }
105
+ },
106
+ "required": ["ease_of_access", "score", "clarity_of_dependency", "hardware_requirements", "installation_guide"]
107
+ }
108
+
109
+ class EvaluationInstallationTask(EvaluationTask):
110
+ def __init__(
111
+ self,
112
+ llm,
113
+ repo_path,
114
+ gitignore_path,
115
+ meta_data = None,
116
+ step_callback = None,
117
+ ):
118
+ super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback)
119
+
120
+ def _evaluate(self, files: list[str] | None = None):
121
+ if files is None or len(files) == 0:
122
+ return None
123
+
124
+ files_content = ""
125
+ for f in files:
126
+ content = read_file(os.path.join(self.repo_path, f))
127
+ files_content += f"""
128
+ {f} content:
129
+ {content}
130
+
131
+ """
132
+ system_prompt = ChatPromptTemplate.from_template(EVALUATION_INSTALLATION_SYSTEM_PROMPT).format(
133
+ installation_file_contents=files_content
134
+ )
135
+ agent = CommonAgentTwoChainSteps(llm=self.llm)
136
+ res, _, token_usage, reasoning_process = agent.go(
137
+ system_prompt=system_prompt,
138
+ instruction_prompt="Before arriving at the conclusion, clearly explain your reasoning step by step. Now, let's begin the evaluation.",
139
+ schema=EvaluationInstallationResultSchema,
140
+ )
141
+ res = EvaluationInstallationResult(**res)
142
+ evaluation = {
143
+ "score": res.score,
144
+ "ease_of_access": res.ease_of_access,
145
+ "hardware_requirements": res.hardware_requirements,
146
+ "clarity_of_dependency": res.clarity_of_dependency,
147
+ "installation_guide": res.installation_guide,
148
+ "reasoning_process": reasoning_process,
149
+ }
150
+ return evaluation, token_usage
151
+
@@ -71,8 +71,22 @@ For each criterion below, provide a brief assessment followed by specific, actio
71
71
  * **Assessment**: Based on these scores, evaluate the overall readability and technical complexity of the language used.
72
72
 
73
73
  **Final Answer**
74
- * Project-Level README: Yes / No
75
- * Provide a final, overall assessment of the README file's quality, summarizing the key strengths and areas for improvement.
74
+ The final answer **must exactly match** the following format:
75
+ ```
76
+ * Project-Level README: Yes / No
77
+ * **Score:** <number from 0 to 100>
78
+ * **Key Strengths**: <brief summary of the README's strongest points in 2-3 sentences>
79
+ * **Overall Improvement Suggestions:**
80
+ - "Original text snippet 1" - Improving comment 1
81
+ - "Original text snippet 2" - Improving comment 2
82
+ - ...
83
+ ```
84
+
85
+ * **Project-Level README**: Indicate “Yes” if the README is project-level, otherwise “No.”
86
+ * **Score**: Provide an overall quality score (100 = perfect).
87
+ * **Key Strengths**: Provide the README's strongest points in 2-3 sentences
88
+ * **Overall Improvement Suggestions**:
89
+ * List each original text snippet that needs improvement, followed by your suggestion.
76
90
 
77
91
  ---
78
92
 
@@ -108,8 +122,14 @@ For each criterion below, provide a brief assessment followed by specific, actio
108
122
  * **Assessment**: Based on these scores, evaluate the overall readability and technical complexity of the language used.
109
123
 
110
124
  **Final Answer**
125
+ The final answer **must exactly match** the following format:
111
126
  * Project-Level README: Yes / No
112
- * Provide a final, overall assessment of the README file's quality, summarizing the key strengths and areas for improvement.
127
+ * **Score:** <number from 0 to 100>
128
+ * **Key Strengths**: <brief summary of the README's strongest points in 2-3 sentences>
129
+ * **Overall Improvement Suggestions:**
130
+ - "Original text snippet 1" - Improving comment 1
131
+ - "Original text snippet 2" - Improving comment 2
132
+ - ...
113
133
  ---
114
134
 
115
135
  ### **README path:**
@@ -167,8 +187,38 @@ class EvaluationTask(ABC):
167
187
  pass
168
188
 
169
189
  class EvaluationREADMEResult(BaseModel):
170
- project_level: Optional[bool]=Field(description="a boolean value specifying if the README file is **project-level** README. TRUE: project-level, FALSE, folder-level")
171
- overall_assessment: Optional[str]=Field(description="an overall assessment")
190
+ project_level: Optional[bool]=Field(description="A boolean value specifying if the README file is **project-level** README. TRUE: project-level, FALSE, folder-level")
191
+ score: Optional[float]=Field(description="An overall score")
192
+ key_strengths: Optional[str]=Field(description="A string specifying the key strengths of README file.")
193
+ overall_improvement_suggestions: Optional[list[str]]=Field(description="A list of overall improvement suggestions")
194
+
195
+ EvaluationREADMEResultSchema = {
196
+ "title": "EvaluationREADMEResult",
197
+ "type": "object",
198
+ "properties": {
199
+ "project_level": {
200
+ "anyOf": [{"type": "boolean"}, {"type": "null"}],
201
+ "description": "A boolean value specifying if the README file is **project-level** README. TRUE: project-level, FALSE: folder-level.",
202
+ "title": "Project Level"
203
+ },
204
+ "score": {
205
+ "anyOf": [{"type": "number"}, {"type": "null"}],
206
+ "description": "An overall score",
207
+ "title": "Score"
208
+ },
209
+ "key_strengths": {
210
+ "anyOf": [{"type": "string"}, {"type": "null"}],
211
+ "description": "A string specifying the key strengths of README file.",
212
+ "title": "Key Strengths",
213
+ },
214
+ "overall_improvement_suggestions": {
215
+ "anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}],
216
+ "description": "A list of improvement suggestions",
217
+ "title": "Overall Improvement Suggestions"
218
+ }
219
+ },
220
+ "required": ["project_level", "score", "key_strengths", "overall_improvement_suggestions"]
221
+ }
172
222
 
173
223
  class EvaluationREADMETask(EvaluationTask):
174
224
  def __init__(
@@ -195,7 +245,16 @@ class EvaluationREADMETask(EvaluationTask):
195
245
  logger.error(f"Error in reading file {readme_file}")
196
246
  continue
197
247
  if len(readme_content.strip()) == 0:
198
- readme_content = "empty file"
248
+ readme_evaluations[readme_file] = {
249
+ "evaluation": {
250
+ "project_level": "/" in readme_file,
251
+ "score": 0,
252
+ "key_strengths": f"{readme_file} is an empty file.",
253
+ "overall_improvement_suggestions": f"{readme_file} is an empty file.",
254
+ },
255
+ "reasoning_process": f"{readme_file} is an empty file.",
256
+ }
257
+ continue
199
258
 
200
259
  readability = PyphenReadability()
201
260
  flesch_reading_ease, flesch_kincaid_grade, gunning_fog_index, smog_index, \
@@ -215,14 +274,17 @@ class EvaluationREADMETask(EvaluationTask):
215
274
  response, _, token_usage, reasoning_process = agent.go(
216
275
  system_prompt=system_prompt,
217
276
  instruction_prompt="Before arriving at the conclusion, clearly explain your reasoning step by step. Now, let's begin the evaluation.",
218
- schema=EvaluationREADMEResult,
277
+ schema=EvaluationREADMEResultSchema,
219
278
  )
279
+ response = EvaluationREADMEResult(**response)
220
280
  self.print_step(step_output=f"README: {readme_file}")
221
281
  self.print_step(step_output=reasoning_process)
222
282
  readme_evaluations[readme_file] = {
223
283
  "evaluation": {
224
284
  "project_level": response.project_level,
225
- "overall_assessment": response.overall_assessment,
285
+ "score": response.score,
286
+ "key_strengths": response.key_strengths,
287
+ "overall_improvement_suggestions": response.overall_improvement_suggestions,
226
288
  },
227
289
  "reasoning_process": reasoning_process
228
290
  }
@@ -165,7 +165,7 @@ If **any one** of these is present, the document should be classified as Install
165
165
  "important_instructions": """- Give priority to analyzing README file that contain installation instructions and the files whose names include **"install"** or **"setup"**.
166
166
  - If multiple files are found, select the most comprehensive one that covers the installation process.
167
167
  - The total number of collected files should **not exceed 3**.
168
- - Make sure to include **only one installation instruction file**, selecting the most comprehensive and representative one.
168
+ - Identify and select **no more than three** installation instruction files choose the most comprehensive and representative ones.
169
169
  """
170
170
  },
171
171
  "License": {
@@ -10,6 +10,7 @@ from ..rag.rag import RAG
10
10
  from ..utils.file_utils import parse_repo_url
11
11
  from ..database.summarized_file_db import SummarizedFilesDb
12
12
  from ..agents.evaluation_task import EvaluationREADMETask
13
+ from ..agents.evaluation_installation_task import EvaluationInstallationTask
13
14
  from ..agents.collection_task import CollectionTask
14
15
 
15
16
  class EvaluationManager:
@@ -84,6 +85,30 @@ class EvaluationManager:
84
85
  if s is None or 'final_answer' not in s:
85
86
  return None
86
87
 
88
+ def evaluate_installation(self):
89
+ task = CollectionTask(
90
+ llm=self.llm,
91
+ step_callback=self.step_callback,
92
+ )
93
+ task.compile(
94
+ repo_path=self.rag.repo_dir,
95
+ gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
96
+ db=self.summary_file_db,
97
+ goal_item=CollectionGoalItemEnum.Installation.name,
98
+ )
99
+ files = task.collect()
100
+ if files is None or len(files) == 0:
101
+ return None
102
+ evaluation_task = EvaluationInstallationTask(
103
+ llm=self.llm,
104
+ repo_path=self.rag.repo_dir,
105
+ gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
106
+ meta_data=self.project_metadata,
107
+ step_callback=self.step_callback,
108
+ )
109
+ evaluation = evaluation_task.evaluate(files)
110
+ return evaluation, files
111
+
87
112
  def _find_readme_files(self) -> list[str]:
88
113
  """
89
114
  Search for a README file in the repository directory.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bioguider
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: An AI-Powered package to help biomedical developers to generate clear documentation
5
5
  License: MIT
6
6
  Author: Cankun Wang
@@ -16,19 +16,20 @@ bioguider/agents/dockergeneration_observe_step.py,sha256=93PO_Y4YyUShVTKRt0nErcj
16
16
  bioguider/agents/dockergeneration_plan_step.py,sha256=SB8tQM9PkIKsD2o1DFD7bedcxz6r6hSy8n_EVK60Fz0,7235
17
17
  bioguider/agents/dockergeneration_task.py,sha256=ezsweVHJsFpOyOI6rYMt1DZ3PE19dcq4J3Lm-d0IA8M,6220
18
18
  bioguider/agents/dockergeneration_task_utils.py,sha256=v7emqrJlVW-A5ZdLmPSdiaMSKCR8uzy9UYzx_1cgzyo,9041
19
- bioguider/agents/evaluation_task.py,sha256=RRcbw4qTUPElZuiBAMj7heGsDV3t93l_IrioudMTGpc,14316
19
+ bioguider/agents/evaluation_installation_task.py,sha256=ULxlw5VvW_w-tH7mVWbvOFjKYzjpUz2dVTCHKqzU_8w,5922
20
+ bioguider/agents/evaluation_task.py,sha256=8tjRPGsRQ9qDxVgYYDo-GhhEiwW71zSS-iyLZUPRbBA,17178
20
21
  bioguider/agents/identification_execute_step.py,sha256=_9x_KITVtNJjQlgjfq-LazoUl46Tctaj_W_AVxz5q-w,5488
21
22
  bioguider/agents/identification_observe_step.py,sha256=OENwf9XyOSIHvJMp7eoyQOYGjjtPnPT2S29xf1rCATk,3667
22
23
  bioguider/agents/identification_plan_step.py,sha256=p0BKziXdB4ph4D_T9FU5bH8CbHD5Gv0YuszMds_xh-Y,5224
23
24
  bioguider/agents/identification_task.py,sha256=-4bnw39OSkhu8RkDVQPRpmu0g8K79dji3HXTybch5As,8329
24
25
  bioguider/agents/identification_task_utils.py,sha256=5gevknha9hJiiQN5L7Yp9-pyhAlbR_j31aGRK5j0D_w,522
25
26
  bioguider/agents/peo_common_step.py,sha256=iw2c1h7X11WJzSE2tSRg0UAoXH0QOlQDxW9CCzSVMOY,2677
26
- bioguider/agents/prompt_utils.py,sha256=KBNWsUJMjZAczD_y7nFMnjfJv4dVBPI3cAlQDMbFHec,12379
27
+ bioguider/agents/prompt_utils.py,sha256=udl4PSTZtAc6vBRYJJq4ZGB2iy3ihRE4i9afFJLT5kM,12390
27
28
  bioguider/agents/python_ast_repl_tool.py,sha256=o7-4P1h8jS8ikhGSA4CI_OWQ2a0Eg5tEdmuAp_qrO-0,2519
28
29
  bioguider/agents/rag_collection_task.py,sha256=r_jPAMjQcC7dIydKxX77UuMqjJ3MiVKswNZ-yNw7yx8,5199
29
30
  bioguider/conversation.py,sha256=DIvk_d7pz_guuORByK1eaaF09FAK-8shcNTrbSUHz9Y,1779
30
31
  bioguider/database/summarized_file_db.py,sha256=9Iyin5BChlFjDJlFamTwmzkYZvO3BzFu7M8AbikyPXw,4441
31
- bioguider/managers/evaluation_manager.py,sha256=h-I-ot41pvXsy1Q8vXfJAS_Znb4-68vnwrdIC-OBXeA,3954
32
+ bioguider/managers/evaluation_manager.py,sha256=93XOE2Q2a-mRa8DMF3IZC7mhE2CxxqOZZ5MLbWlPsjo,4904
32
33
  bioguider/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
34
  bioguider/rag/config.py,sha256=5g4IqTzgyfZfax9Af9CTkXShgItPOt4_9TEMSekCPik,4602
34
35
  bioguider/rag/data_pipeline.py,sha256=OXnsqETVytHBMXHerg9gACtNhwpWSODYWvzxVDTP_So,27767
@@ -41,7 +42,7 @@ bioguider/utils/file_utils.py,sha256=9VfAHsz1UkFPtzAmvWZvPl1TMaKIYNjNlLgsfB8tNjg
41
42
  bioguider/utils/gitignore_checker.py,sha256=pOYUwsS9D5014LxcZb0cj3s2CAYaD2uF_pYJpaNKcho,6532
42
43
  bioguider/utils/pyphen_utils.py,sha256=cdZc3qphkvMDeL5NiZ8Xou13M_uVNP7ifJ-FwxO-0BE,2680
43
44
  bioguider/utils/utils.py,sha256=YP3HXgU_rvYDWkEcTzWGiYZw-mlfVrqGhUGSc0_4Pms,900
44
- bioguider-0.2.4.dist-info/LICENSE,sha256=qzkvZcKwwA5DuSuhXMOm2LcO6BdEr4V7jwFZVL2-jL4,1065
45
- bioguider-0.2.4.dist-info/METADATA,sha256=VD_LpYetLIYKw2y-JH7_OZZT8D5oIbmzSCx8t5kgyJY,1823
46
- bioguider-0.2.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
47
- bioguider-0.2.4.dist-info/RECORD,,
45
+ bioguider-0.2.6.dist-info/LICENSE,sha256=qzkvZcKwwA5DuSuhXMOm2LcO6BdEr4V7jwFZVL2-jL4,1065
46
+ bioguider-0.2.6.dist-info/METADATA,sha256=MBcrwDU4pJKKEkd1jBvtBYd0WDUrbIZjKJuwOk_TQ3Y,1823
47
+ bioguider-0.2.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
48
+ bioguider-0.2.6.dist-info/RECORD,,