bioguider 0.2.21__tar.gz → 0.2.22__tar.gz
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.
- {bioguider-0.2.21 → bioguider-0.2.22}/PKG-INFO +1 -1
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/consistency_collection_step.py +9 -7
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/consistency_evaluation_task.py +3 -2
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/consistency_evaluation_task_utils.py +2 -1
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/consistency_observe_step.py +15 -13
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_task.py +0 -110
- bioguider-0.2.22/bioguider/agents/evaluation_tutorial_task.py +156 -0
- bioguider-0.2.22/bioguider/agents/evaluation_tutorial_task_prompts.py +114 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_userguide_task.py +4 -1
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/prompt_utils.py +9 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/database/code_structure_db.py +20 -9
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/database/summarized_file_db.py +6 -3
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/managers/evaluation_manager.py +14 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/rag/data_pipeline.py +1 -1
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/code_structure_builder.py +6 -4
- bioguider-0.2.22/bioguider/utils/notebook_utils.py +117 -0
- bioguider-0.2.22/bioguider/utils/r_file_handler.py +549 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/pyproject.toml +1 -1
- bioguider-0.2.21/bioguider/utils/r_file_handler.py +0 -368
- {bioguider-0.2.21 → bioguider-0.2.22}/LICENSE +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/README.md +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/__init__.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/__init__.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/agent_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/agent_tools.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/agent_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/collection_execute_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/collection_observe_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/collection_plan_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/collection_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/collection_task_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/common_agent.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/common_agent_2step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/common_conversation.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/common_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/consistency_query_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/dockergeneration_execute_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/dockergeneration_observe_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/dockergeneration_plan_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/dockergeneration_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/dockergeneration_task_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_installation_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_readme_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_submission_requirements_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/evaluation_userguide_prompts.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/identification_execute_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/identification_observe_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/identification_plan_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/identification_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/identification_task_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/peo_common_step.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/python_ast_repl_tool.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/agents/rag_collection_task.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/conversation.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/__init__.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/change_planner.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/document_renderer.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/llm_cleaner.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/llm_content_generator.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/llm_injector.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/models.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/output_manager.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/repo_reader.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/report_loader.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/style_analyzer.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/suggestion_extractor.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/generation/test_metrics.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/managers/generation_manager.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/managers/generation_test_manager.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/rag/__init__.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/rag/config.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/rag/embedder.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/rag/rag.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/settings.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/constants.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/default.gitignore +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/file_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/gitignore_checker.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/pyphen_utils.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/python_file_handler.py +0 -0
- {bioguider-0.2.21 → bioguider-0.2.22}/bioguider/utils/utils.py +0 -0
|
@@ -12,12 +12,12 @@ from bioguider.agents.peo_common_step import PEOCommonStep
|
|
|
12
12
|
CONSISTANCY_COLLECTION_SYSTEM_PROMPT = """
|
|
13
13
|
### **Goal**
|
|
14
14
|
You are an expert developer specializing in the biomedical domain.
|
|
15
|
-
You will be given a
|
|
15
|
+
You will be given a {domain} documentation. Your task is to collect all the functions, classes, and methods that the {domain} documentation mentions.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
### **Input
|
|
20
|
-
{
|
|
19
|
+
### **Input {domain} Documentation**
|
|
20
|
+
{documentation}
|
|
21
21
|
|
|
22
22
|
### **Output Format**
|
|
23
23
|
The collected functions, classes, and methods **must exactly match** the following format, **do not** make up anything:
|
|
@@ -52,12 +52,12 @@ parent: CommonAgent
|
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
class ConsistencyCollectionResult(BaseModel):
|
|
55
|
-
functions_and_classes: list[dict] = Field(description="A list of functions and classes that the
|
|
55
|
+
functions_and_classes: list[dict] = Field(description="A list of functions and classes that the documentation mentions")
|
|
56
56
|
|
|
57
57
|
ConsistencyCollectionResultJsonSchema = {
|
|
58
58
|
"properties": {
|
|
59
59
|
"functions_and_classes": {
|
|
60
|
-
"description": "A list of functions and classes that the
|
|
60
|
+
"description": "A list of functions and classes that the documentation mentions",
|
|
61
61
|
"items": {
|
|
62
62
|
"type": "object"
|
|
63
63
|
},
|
|
@@ -78,9 +78,11 @@ class ConsistencyCollectionStep(PEOCommonStep):
|
|
|
78
78
|
self.step_name = "Consistency Collection Step"
|
|
79
79
|
|
|
80
80
|
def _prepare_system_prompt(self, state: ConsistencyEvaluationState) -> str:
|
|
81
|
-
|
|
81
|
+
documentation = state["documentation"]
|
|
82
|
+
domain = state["domain"]
|
|
82
83
|
return ChatPromptTemplate.from_template(CONSISTANCY_COLLECTION_SYSTEM_PROMPT).format(
|
|
83
|
-
|
|
84
|
+
domain=domain,
|
|
85
|
+
documentation=documentation,
|
|
84
86
|
)
|
|
85
87
|
|
|
86
88
|
def _execute_directly(self, state: ConsistencyEvaluationState) -> tuple[dict, dict[str, int]]:
|
|
@@ -28,13 +28,14 @@ class ConsistencyEvaluationTask:
|
|
|
28
28
|
self.code_structure_db = code_structure_db
|
|
29
29
|
self.step_callback = step_callback
|
|
30
30
|
|
|
31
|
-
def evaluate(self,
|
|
31
|
+
def evaluate(self, domain: str, documentation: str) -> ConsistencyEvaluationResult:
|
|
32
32
|
collection_step = ConsistencyCollectionStep(llm=self.llm)
|
|
33
33
|
query_step = ConsistencyQueryStep(code_structure_db=self.code_structure_db)
|
|
34
34
|
observe_step = ConsistencyObserveStep(llm=self.llm)
|
|
35
35
|
|
|
36
36
|
state = ConsistencyEvaluationState(
|
|
37
|
-
|
|
37
|
+
domain=domain,
|
|
38
|
+
documentation=documentation,
|
|
38
39
|
step_output_callback=self.step_callback,
|
|
39
40
|
)
|
|
40
41
|
|
|
@@ -3,7 +3,8 @@ from typing import Callable, Optional, TypedDict
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class ConsistencyEvaluationState(TypedDict):
|
|
6
|
-
|
|
6
|
+
domain: str
|
|
7
|
+
documentation: str
|
|
7
8
|
step_output_callback: Optional[Callable]
|
|
8
9
|
functions_and_classes: Optional[list[dict]]
|
|
9
10
|
all_query_rows: Optional[list[any]]
|
|
@@ -10,8 +10,8 @@ from bioguider.agents.peo_common_step import PEOCommonStep
|
|
|
10
10
|
CONSISTENCY_OBSERVE_SYSTEM_PROMPT = """
|
|
11
11
|
You are an expert developer specializing in the biomedical domain.
|
|
12
12
|
Your task is to analyze both:
|
|
13
|
-
1. the provided file related to
|
|
14
|
-
2. the code definitions related to the
|
|
13
|
+
1. the provided file related to {domain} documentation,
|
|
14
|
+
2. the code definitions related to the {domain} documentation
|
|
15
15
|
and generate a structured consistency assessment based on the following criteria.
|
|
16
16
|
|
|
17
17
|
---
|
|
@@ -20,9 +20,9 @@ and generate a structured consistency assessment based on the following criteria
|
|
|
20
20
|
|
|
21
21
|
**Consistency**:
|
|
22
22
|
* **Score**: [Poor / Fair / Good / Excellent]
|
|
23
|
-
* **Assessment**: [Your evaluation of whether the
|
|
23
|
+
* **Assessment**: [Your evaluation of whether the {domain} documentation is consistent with the code definitions]
|
|
24
24
|
* **Development**: [A list of inconsistent function/class/method name and inconsistent docstring, and describe how they are inconsistent]
|
|
25
|
-
* **Strengths**: [A list of strengths of the
|
|
25
|
+
* **Strengths**: [A list of strengths of the {domain} documentation on consistency]
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -31,16 +31,16 @@ Your output **must exactly match** the following format:
|
|
|
31
31
|
```
|
|
32
32
|
**Consistency**:
|
|
33
33
|
* **Score**: [Poor / Fair / Good / Excellent]
|
|
34
|
-
* **Assessment**: [Your evaluation of whether the
|
|
34
|
+
* **Assessment**: [Your evaluation of whether the {domain} documentation is consistent with the code definitions]
|
|
35
35
|
* **Development**: [A list of inconsistent function/class/method name and inconsistent docstring, and describe how they are inconsistent]
|
|
36
|
-
* **Strengths**: [A list of strengths of the
|
|
36
|
+
* **Strengths**: [A list of strengths of the {domain} documentation on consistency]
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### **Output Example**
|
|
40
40
|
|
|
41
41
|
```
|
|
42
42
|
**Consistency**:
|
|
43
|
-
* **Assessment**: [Your evaluation of whether the
|
|
43
|
+
* **Assessment**: [Your evaluation of whether the {domain} documentation is consistent with the code definitions]
|
|
44
44
|
* **Development**:
|
|
45
45
|
- Inconsistent function/class/method name 1
|
|
46
46
|
- Inconsistent docstring 1
|
|
@@ -55,8 +55,8 @@ Your output **must exactly match** the following format:
|
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
58
|
-
### **Input
|
|
59
|
-
{
|
|
58
|
+
### **Input {domain} Documentation**
|
|
59
|
+
{documentation}
|
|
60
60
|
|
|
61
61
|
### **Code Definitions**
|
|
62
62
|
{code_definitions}
|
|
@@ -66,9 +66,9 @@ Your output **must exactly match** the following format:
|
|
|
66
66
|
|
|
67
67
|
class ConsistencyEvaluationObserveResult(BaseModel):
|
|
68
68
|
consistency_score: str=Field(description="A string value, could be `Poor`, `Fair`, `Good`, or `Excellent`")
|
|
69
|
-
consistency_assessment: str=Field(description="Your evaluation of whether the
|
|
69
|
+
consistency_assessment: str=Field(description="Your evaluation of whether the documentation is consistent with the code definitions")
|
|
70
70
|
consistency_development: list[str]=Field(description="A list of inconsistent function/class/method name and inconsistent docstring")
|
|
71
|
-
consistency_strengths: list[str]=Field(description="A list of strengths of the
|
|
71
|
+
consistency_strengths: list[str]=Field(description="A list of strengths of the documentation on consistency")
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
class ConsistencyObserveStep(PEOCommonStep):
|
|
@@ -78,7 +78,8 @@ class ConsistencyObserveStep(PEOCommonStep):
|
|
|
78
78
|
|
|
79
79
|
def _prepare_system_prompt(self, state: ConsistencyEvaluationState):
|
|
80
80
|
all_query_rows = state["all_query_rows"]
|
|
81
|
-
|
|
81
|
+
documentation = state["documentation"]
|
|
82
|
+
domain = state["domain"]
|
|
82
83
|
code_definition = ""
|
|
83
84
|
for row in all_query_rows:
|
|
84
85
|
content = f"name: {row['name']}\nfile_path: {row['path']}\nparent: {row['parent']}\nparameters: {row['params']}\ndoc_string: {row['doc_string']}"
|
|
@@ -86,7 +87,8 @@ class ConsistencyObserveStep(PEOCommonStep):
|
|
|
86
87
|
code_definition += "\n\n\n"
|
|
87
88
|
return ChatPromptTemplate.from_template(CONSISTENCY_OBSERVE_SYSTEM_PROMPT).format(
|
|
88
89
|
code_definitions=code_definition,
|
|
89
|
-
|
|
90
|
+
documentation=documentation,
|
|
91
|
+
domain=domain,
|
|
90
92
|
)
|
|
91
93
|
|
|
92
94
|
def _execute_directly(self, state: ConsistencyEvaluationState):
|
|
@@ -204,113 +204,3 @@ class EvaluationTask(ABC):
|
|
|
204
204
|
@abstractmethod
|
|
205
205
|
def _collect_files(self) -> list[str]:
|
|
206
206
|
pass
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
EVALUATION_TUTORIAL_SYSTEM_PROMPT="""
|
|
210
|
-
You are an expert in software documentation and developer education.
|
|
211
|
-
You are given the content of a tutorial file from a GitHub repository. Your task is to **critically evaluate** the quality of this tutorial based on best practices in technical writing and developer onboarding.
|
|
212
|
-
Please assess the tutorial using the following criteria. Provide your evaluation in structured sections:
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
### **Evaluation Criteria:**
|
|
217
|
-
1. **Readability**: You are provided the following metrics scores calculated with pyphen, please evaluate readability based on the scores:
|
|
218
|
-
* Flesch Reading Ease: {flesch_reading_ease} (206.835 - 1.015(words/sentences) - 84.6(syllables/words))
|
|
219
|
-
* Flesch-Kincaid Grade Level: {flesch_kincaid_grade} (0.39(words/sentences) + 11.8(syllables/words) - 15.59)
|
|
220
|
-
* Gunning Fog Index: {gunning_fog_index} (0.4[(words/sentences) + 100(complex words/words)])
|
|
221
|
-
* SMOG Index: {smog_index} (1.043*sqrt(polysyllables * (30/sentences)) + 3.1291)
|
|
222
|
-
2. **Coverage**
|
|
223
|
-
* Does the tutorial cover all major steps needed to get started?
|
|
224
|
-
* Are dependencies, prerequisites, setup steps, and example usage included?
|
|
225
|
-
3. **Structure & Organization**
|
|
226
|
-
* Is the content logically structured (e.g., introduction → setup → examples → summary)?
|
|
227
|
-
* Are sections well-labeled and easy to navigate?
|
|
228
|
-
4. **Balance Between Code and Explanation**
|
|
229
|
-
* Is there a good balance between code snippets and narrative explanation?
|
|
230
|
-
* Are code blocks properly annotated or explained?
|
|
231
|
-
5. **Terminology Consistency**
|
|
232
|
-
* Is technical terminology used consistently and accurately?
|
|
233
|
-
* Are key terms introduced and reused correctly?
|
|
234
|
-
6. **Example Quality**
|
|
235
|
-
* Are the examples relevant, correct, and representative of real usage?
|
|
236
|
-
* Are edge cases or typical user pitfalls addressed?
|
|
237
|
-
7. **Formatting and Style**
|
|
238
|
-
* Are headings, bullet points, code formatting, and markdown style used effectively?
|
|
239
|
-
* Are there any formatting issues that hurt clarity?
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
### **Output Format:**
|
|
243
|
-
Please respond in the following format:
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
**FinalAnswer**
|
|
247
|
-
**Readability**: Your comments here
|
|
248
|
-
**Coverage**: Your comments here
|
|
249
|
-
**Structure & Organization**: Your comments here
|
|
250
|
-
**Code vs. Explanation Balance**: Your comments here
|
|
251
|
-
**Terminology Consistency**: Your comments here
|
|
252
|
-
**Example Quality**: Your comments here
|
|
253
|
-
**Formatting and Style**: Your comments here
|
|
254
|
-
**Overall Rating**: [Poor / Fair / Good / Excellent]
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
### **Tutorial File Content:**
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
{tutorial_file_content}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
---
|
|
266
|
-
"""
|
|
267
|
-
class EvaluationTutorialTask(EvaluationTask):
|
|
268
|
-
def __init__(
|
|
269
|
-
self,
|
|
270
|
-
llm: BaseChatOpenAI,
|
|
271
|
-
repo_path: str,
|
|
272
|
-
gitignore_path: str,
|
|
273
|
-
meta_data: ProjectMetadata | None = None,
|
|
274
|
-
step_callback: Callable | None = None,
|
|
275
|
-
summarized_files_db = None,
|
|
276
|
-
):
|
|
277
|
-
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
278
|
-
self.evaluation_name = "Tutorial Evaluation"
|
|
279
|
-
|
|
280
|
-
def _evaluate(self, files: list[str]) -> tuple[dict, dict]:
|
|
281
|
-
if len(files) == 0:
|
|
282
|
-
return {}, {**DEFAULT_TOKEN_USAGE}
|
|
283
|
-
|
|
284
|
-
evaluations = {}
|
|
285
|
-
for file in files:
|
|
286
|
-
tutorial_path = Path(self.repo_path, file)
|
|
287
|
-
tutorial_content = read_file(tutorial_path)
|
|
288
|
-
if tutorial_content is None:
|
|
289
|
-
logging.error(f"Error in reading file {file}")
|
|
290
|
-
continue
|
|
291
|
-
|
|
292
|
-
readability = PyphenReadability()
|
|
293
|
-
flesch_reading_ease, flesch_kincaid_grade, gunning_fog_index, smog_index, \
|
|
294
|
-
_, _, _, _, _ = readability.readability_metrics(tutorial_content)
|
|
295
|
-
system_prompt = ChatPromptTemplate.from_template(
|
|
296
|
-
EVALUATION_TUTORIAL_SYSTEM_PROMPT
|
|
297
|
-
).format(
|
|
298
|
-
tutorial_file_content=tutorial_content,
|
|
299
|
-
flesch_reading_ease=flesch_reading_ease,
|
|
300
|
-
flesch_kincaid_grade=flesch_kincaid_grade,
|
|
301
|
-
gunning_fog_index=gunning_fog_index,
|
|
302
|
-
smog_index=smog_index,
|
|
303
|
-
)
|
|
304
|
-
conversation = CommonConversation(llm=self.llm)
|
|
305
|
-
response, token_usage = conversation.generate(
|
|
306
|
-
system_prompt=system_prompt,
|
|
307
|
-
instruction_prompt=EVALUATION_INSTRUCTION,
|
|
308
|
-
)
|
|
309
|
-
self.print_step(step_output=f"Tutorial: {file}")
|
|
310
|
-
self.print_step(step_output=response)
|
|
311
|
-
evaluations[file] = response
|
|
312
|
-
return evaluations, token_usage
|
|
313
|
-
|
|
314
|
-
def _collect_files(self):
|
|
315
|
-
return []
|
|
316
|
-
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Callable
|
|
6
|
+
from langchain.prompts import ChatPromptTemplate
|
|
7
|
+
from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from bioguider.agents.agent_utils import read_file
|
|
12
|
+
from bioguider.agents.common_agent_2step import CommonAgentTwoSteps
|
|
13
|
+
from bioguider.agents.consistency_evaluation_task import ConsistencyEvaluationResult, ConsistencyEvaluationTask
|
|
14
|
+
from bioguider.agents.evaluation_task import EvaluationTask
|
|
15
|
+
from bioguider.agents.collection_task import CollectionTask
|
|
16
|
+
from bioguider.agents.evaluation_tutorial_task_prompts import INDIVIDUAL_TUTORIAL_EVALUATION_SYSTEM_PROMPT
|
|
17
|
+
from bioguider.agents.prompt_utils import CollectionGoalItemEnum
|
|
18
|
+
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE, ProjectMetadata
|
|
19
|
+
from bioguider.utils.notebook_utils import extract_markdown_from_notebook, strip_notebook_to_code_and_markdown
|
|
20
|
+
from bioguider.utils.pyphen_utils import PyphenReadability
|
|
21
|
+
from bioguider.utils.utils import increase_token_usage
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
class TutorialEvaluationResult(BaseModel):
|
|
26
|
+
overall_score: str=Field(description="A string value, could be `Poor`, `Fair`, `Good`, or `Excellent`")
|
|
27
|
+
overall_key_strengths: str=Field(description="A string value, the key strengths of the tutorial")
|
|
28
|
+
overall_improvement_suggestions: str=Field(description="Suggestions to improve the overall score if necessary")
|
|
29
|
+
readability_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
30
|
+
readability_suggestions: str=Field(description="Suggestions to improve readability if necessary")
|
|
31
|
+
setup_and_dependencies_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
32
|
+
setup_and_dependencies_suggestions: str=Field(description="Suggestions to improve setup and dependencies if necessary")
|
|
33
|
+
reproducibility_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
34
|
+
reproducibility_suggestions: str=Field(description="Suggestions to improve reproducibility if necessary")
|
|
35
|
+
structure_and_navigation_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
36
|
+
structure_and_navigation_suggestions: str=Field(description="Suggestions to improve structure and navigation if necessary")
|
|
37
|
+
executable_code_quality_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
38
|
+
executable_code_quality_suggestions: str=Field(description="Suggestions to improve executable code quality if necessary")
|
|
39
|
+
result_verification_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
40
|
+
result_verification_suggestions: str=Field(description="Suggestions to improve result verification if necessary")
|
|
41
|
+
performance_and_resource_notes_score: str=Field(description="A string value, could be 'Poor', 'Fair', 'Good', or 'Excellent'")
|
|
42
|
+
performance_and_resource_notes_suggestions: str=Field(description="Suggestions to improve performance and resource notes if necessary")
|
|
43
|
+
|
|
44
|
+
class IndividualTutorialEvaluationResult(BaseModel):
|
|
45
|
+
tutorial_evaluation: TutorialEvaluationResult | None=Field(description="The evaluation result of the tutorial")
|
|
46
|
+
consistency_evaluation: ConsistencyEvaluationResult | None=Field(description="The evaluation result of the consistency of the tutorial")
|
|
47
|
+
|
|
48
|
+
class EvaluationTutorialTask(EvaluationTask):
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
llm: BaseChatOpenAI,
|
|
52
|
+
repo_path: str,
|
|
53
|
+
gitignore_path: str,
|
|
54
|
+
meta_data: ProjectMetadata | None = None,
|
|
55
|
+
step_callback: Callable | None = None,
|
|
56
|
+
summarized_files_db = None,
|
|
57
|
+
code_structure_db = None,
|
|
58
|
+
):
|
|
59
|
+
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
60
|
+
self.evaluation_name = "Tutorial Evaluation"
|
|
61
|
+
self.code_structure_db = code_structure_db
|
|
62
|
+
|
|
63
|
+
def _collect_files(self):
|
|
64
|
+
task = CollectionTask(
|
|
65
|
+
llm=self.llm,
|
|
66
|
+
step_callback=self.step_callback,
|
|
67
|
+
summarized_files_db=self.summarized_files_db,
|
|
68
|
+
)
|
|
69
|
+
task.compile(
|
|
70
|
+
repo_path=self.repo_path,
|
|
71
|
+
gitignore_path=Path(self.repo_path, ".gitignore"),
|
|
72
|
+
goal_item=CollectionGoalItemEnum.Tutorial.name,
|
|
73
|
+
)
|
|
74
|
+
files = task.collect()
|
|
75
|
+
return files
|
|
76
|
+
|
|
77
|
+
def _evaluate_consistency(self, file: str) -> ConsistencyEvaluationResult:
|
|
78
|
+
consistency_evaluation_task = ConsistencyEvaluationTask(
|
|
79
|
+
llm=self.llm,
|
|
80
|
+
code_structure_db=self.code_structure_db,
|
|
81
|
+
step_callback=self.step_callback,
|
|
82
|
+
)
|
|
83
|
+
file = file.strip()
|
|
84
|
+
with open(Path(self.repo_path, file), "r") as f:
|
|
85
|
+
tutorial_content = f.read()
|
|
86
|
+
return consistency_evaluation_task.evaluate(
|
|
87
|
+
domain="tutorial/vignette",
|
|
88
|
+
documentation=tutorial_content,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def _evaluate_consistency_on_content(self, content: str) -> ConsistencyEvaluationResult:
|
|
92
|
+
consistency_evaluation_task = ConsistencyEvaluationTask(
|
|
93
|
+
llm=self.llm,
|
|
94
|
+
code_structure_db=self.code_structure_db,
|
|
95
|
+
step_callback=self.step_callback,
|
|
96
|
+
)
|
|
97
|
+
return consistency_evaluation_task.evaluate(
|
|
98
|
+
domain="tutorial/vignette",
|
|
99
|
+
documentation=content,
|
|
100
|
+
), {**DEFAULT_TOKEN_USAGE}
|
|
101
|
+
|
|
102
|
+
def _evaluate_individual_tutorial(self, file: str) -> tuple[IndividualTutorialEvaluationResult | None, dict]:
|
|
103
|
+
content = read_file(Path(self.repo_path, file))
|
|
104
|
+
if content is None:
|
|
105
|
+
logger.error(f"Error in reading file {file}")
|
|
106
|
+
return None, {**DEFAULT_TOKEN_USAGE}
|
|
107
|
+
|
|
108
|
+
if file.endswith(".ipynb"):
|
|
109
|
+
readability_content = extract_markdown_from_notebook(Path(self.repo_path, file))
|
|
110
|
+
content = json.dumps(strip_notebook_to_code_and_markdown(Path(self.repo_path, file)))
|
|
111
|
+
else:
|
|
112
|
+
readability_content = content
|
|
113
|
+
readability = PyphenReadability()
|
|
114
|
+
flesch_reading_ease, flesch_kincaid_grade, gunning_fog_index, smog_index, \
|
|
115
|
+
_, _, _, _, _ = readability.readability_metrics(readability_content)
|
|
116
|
+
system_prompt = ChatPromptTemplate.from_template(
|
|
117
|
+
INDIVIDUAL_TUTORIAL_EVALUATION_SYSTEM_PROMPT
|
|
118
|
+
).format(
|
|
119
|
+
flesch_reading_ease=flesch_reading_ease,
|
|
120
|
+
flesch_kincaid_grade=flesch_kincaid_grade,
|
|
121
|
+
gunning_fog_index=gunning_fog_index,
|
|
122
|
+
smog_index=smog_index,
|
|
123
|
+
tutorial_file_content=readability_content,
|
|
124
|
+
)
|
|
125
|
+
agent = CommonAgentTwoSteps(llm=self.llm)
|
|
126
|
+
res, _, token_usage, reasoning_process = agent.go(
|
|
127
|
+
system_prompt=system_prompt,
|
|
128
|
+
instruction_prompt="Now, let's begin the tutorial evaluation.",
|
|
129
|
+
schema=TutorialEvaluationResult,
|
|
130
|
+
)
|
|
131
|
+
res: TutorialEvaluationResult = res
|
|
132
|
+
|
|
133
|
+
consistency_evaluation_result, _temp_token_usage = self._evaluate_consistency_on_content(content)
|
|
134
|
+
if consistency_evaluation_result is None:
|
|
135
|
+
# No sufficient information to evaluate the consistency of the tutorial
|
|
136
|
+
consistency_evaluation_result = ConsistencyEvaluationResult(
|
|
137
|
+
consistency_score="N/A",
|
|
138
|
+
consistency_assessment="No sufficient information to evaluate the consistency of the tutorial",
|
|
139
|
+
consistency_development=[],
|
|
140
|
+
consistency_strengths=[],
|
|
141
|
+
)
|
|
142
|
+
return IndividualTutorialEvaluationResult(
|
|
143
|
+
tutorial_evaluation=res,
|
|
144
|
+
consistency_evaluation=consistency_evaluation_result,
|
|
145
|
+
), token_usage
|
|
146
|
+
|
|
147
|
+
def _evaluate(self, files: list[str] | None = None) -> tuple[dict[str, IndividualTutorialEvaluationResult] | None, dict, list[str]]:
|
|
148
|
+
total_token_usage = {**DEFAULT_TOKEN_USAGE}
|
|
149
|
+
tutorial_evaluation_results = {}
|
|
150
|
+
for file in files:
|
|
151
|
+
tutorial_evaluation_result, token_usage = self._evaluate_individual_tutorial(file)
|
|
152
|
+
total_token_usage = increase_token_usage(total_token_usage, token_usage)
|
|
153
|
+
tutorial_evaluation_results[file] = tutorial_evaluation_result
|
|
154
|
+
return tutorial_evaluation_results, total_token_usage, files
|
|
155
|
+
|
|
156
|
+
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
INDIVIDUAL_TUTORIAL_EVALUATION_SYSTEM_PROMPT = """
|
|
2
|
+
|
|
3
|
+
You are an expert in evaluating the quality of tutorials in software repositories.
|
|
4
|
+
Your task is to analyze the provided tutorial file and generate a structured quality assessment based on the following criteria.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
### **Evaluation Criteria**
|
|
8
|
+
|
|
9
|
+
1. **Readability**:
|
|
10
|
+
* **Flesch Reading Ease**: `{flesch_reading_ease}` (A higher score is better, with 60-70 being easily understood by most adults).
|
|
11
|
+
* **Flesch-Kincaid Grade Level**: `{flesch_kincaid_grade}` (Represents the US school-grade level needed to understand the text).
|
|
12
|
+
* **Gunning Fog Index**: `{gunning_fog_index}` (A score above 12 is generally considered too hard for most people).
|
|
13
|
+
* **SMOG Index**: `{smog_index}` (Estimates the years of education needed to understand the text).
|
|
14
|
+
* **Assessment**: Based on these scores, evaluate the overall readability and technical complexity of the language used.
|
|
15
|
+
|
|
16
|
+
2. **Coverage**:
|
|
17
|
+
* **Assessment**: [Your evaluation of whether it covers all major steps needed to get started, and dependencies, prerequisites, setup steps, and example usage.]
|
|
18
|
+
* **Improvement Suggestions**:
|
|
19
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
20
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
21
|
+
|
|
22
|
+
3. **Reproducibility**:
|
|
23
|
+
* **Assessment**: [Your evaluation of whether it provides a clear **description** of reproducibility]
|
|
24
|
+
* **Improvement Suggestions**:
|
|
25
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
26
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
27
|
+
|
|
28
|
+
4. **Structure & Navigation**:
|
|
29
|
+
* **Assessment**: [Your evaluation of whether it provides logical sections (e.g., intro -> setup -> steps -> results -> next), TOC/anchors, estimated time, etc.]
|
|
30
|
+
* **Improvement Suggestions**:
|
|
31
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
32
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
33
|
+
|
|
34
|
+
5. **Executable Code Quality**:
|
|
35
|
+
* **Assessment**: [Your evaluation on whether the code snippets are executable and functional, idiomatic, no hard-coded paths, etc.]
|
|
36
|
+
* **Improvement Suggestions**:
|
|
37
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
38
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
39
|
+
|
|
40
|
+
6. **Result Verification**:
|
|
41
|
+
* **Assessment**: [Your evaluation on expected outputs shown (figures/tables/metrics), acceptance criteria, etc.]
|
|
42
|
+
* **Improvement Suggestions**:
|
|
43
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
44
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
45
|
+
|
|
46
|
+
7. **Performance & Resource Notes**:
|
|
47
|
+
* **Assessment**: [Your evaluation on performance and resource notes, e.g., CPU/GPU usage, memory usage, runtime estimates, small "lite" path provided.]
|
|
48
|
+
* **Improvement Suggestions**:
|
|
49
|
+
* **Original text:** [Quote a specific line/section from the tutorial.]
|
|
50
|
+
* **Improving comments:** [Provide your suggestions to improve clarity.]
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### **Final Report Ouput**
|
|
55
|
+
Your final report must **exactly match** the following format. Do not add or omit any sections.
|
|
56
|
+
|
|
57
|
+
**FinalAnswer**
|
|
58
|
+
* **Overall Score:** [Poor / Fair / Good / Excellent]
|
|
59
|
+
* **Overall Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
60
|
+
* **Overall Improvement Suggestions:**
|
|
61
|
+
- "Original text snippet 1" - Improving comment 1
|
|
62
|
+
- "Original text snippet 2" - Improving comment 2
|
|
63
|
+
- ...
|
|
64
|
+
* **Readability Score:** [Poor / Fair / Good / Excellent]
|
|
65
|
+
* **Readability Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
66
|
+
* **Readability Improvement Suggestions:**
|
|
67
|
+
- "Original text snippet 1" - Improving comment 1
|
|
68
|
+
- "Original text snippet 2" - Improving comment 2
|
|
69
|
+
- ...
|
|
70
|
+
* **Coverage Score:** [Poor / Fair / Good / Excellent]
|
|
71
|
+
* **Coverage Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
72
|
+
* **Coverage Improvement Suggestions:**
|
|
73
|
+
- "Original text snippet 1" - Improving comment 1
|
|
74
|
+
- "Original text snippet 2" - Improving comment 2
|
|
75
|
+
- ...
|
|
76
|
+
* **Reproducibility Score:** [Poor / Fair / Good / Excellent]
|
|
77
|
+
* **Reproducibility Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
78
|
+
* **Reproducibility Improvement Suggestions:**
|
|
79
|
+
- "Original text snippet 1" - Improving comment 1
|
|
80
|
+
- "Original text snippet 2" - Improving comment 2
|
|
81
|
+
- ...
|
|
82
|
+
* **Structure & Navigation Score:** [Poor / Fair / Good / Excellent]
|
|
83
|
+
* **Structure & Navigation Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
84
|
+
* **Structure & Navigation Improvement Suggestions:**
|
|
85
|
+
- "Original text snippet 1" - Improving comment 1
|
|
86
|
+
- "Original text snippet 2" - Improving comment 2
|
|
87
|
+
- ...
|
|
88
|
+
* **Executable Code Quality Score:** [Poor / Fair / Good / Excellent]
|
|
89
|
+
* **Executable Code Quality Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
90
|
+
* **Executable Code Quality Improvement Suggestions:**
|
|
91
|
+
- "Original text snippet 1" - Improving comment 1
|
|
92
|
+
- "Original text snippet 2" - Improving comment 2
|
|
93
|
+
- ...
|
|
94
|
+
* **Result Verification Score:** [Poor / Fair / Good / Excellent]
|
|
95
|
+
* **Result Verification Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
96
|
+
* **Result Verification Improvement Suggestions:**
|
|
97
|
+
- "Original text snippet 1" - Improving comment 1
|
|
98
|
+
- "Original text snippet 2" - Improving comment 2
|
|
99
|
+
- ...
|
|
100
|
+
* **Performance & Resource Notes Score:** [Poor / Fair / Good / Excellent]
|
|
101
|
+
* **Performance & Resource Notes Key Strengths**: <brief summary of the Tutorial's strongest points in 2-3 sentences>
|
|
102
|
+
* **Performance & Resource Notes Improvement Suggestions:**
|
|
103
|
+
- "Original text snippet 1" - Improving comment 1
|
|
104
|
+
- "Original text snippet 2" - Improving comment 2
|
|
105
|
+
- ...
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### **Tutorial File Content:**
|
|
110
|
+
{tutorial_file_content}
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
"""
|
|
@@ -75,7 +75,10 @@ class EvaluationUserGuideTask(EvaluationTask):
|
|
|
75
75
|
file = file.strip()
|
|
76
76
|
with open(Path(self.repo_path, file), "r") as f:
|
|
77
77
|
user_guide_api_documentation = f.read()
|
|
78
|
-
return consistency_evaluation_task.evaluate(
|
|
78
|
+
return consistency_evaluation_task.evaluate(
|
|
79
|
+
domain="user guide/API",
|
|
80
|
+
documentation=user_guide_api_documentation,
|
|
81
|
+
), {**DEFAULT_TOKEN_USAGE}
|
|
79
82
|
|
|
80
83
|
def _evaluate_individual_userguide(self, file: str) -> tuple[IndividualUserGuideEvaluationResult | None, dict]:
|
|
81
84
|
content = read_file(Path(self.repo_path, file))
|
|
@@ -135,6 +135,15 @@ If **any one** of these is present, the document should be classified as a User
|
|
|
135
135
|
- Interactive Elements: Features that allow users to experiment with the code in real-time, such as Jupyter notebooks or R Markdown files.
|
|
136
136
|
- Use Cases: Real-world applications or scenarios where the software can be applied effectively.
|
|
137
137
|
- You can include directory names if all files in the directory are relevant to the goal item.
|
|
138
|
+
**Important instructions**:
|
|
139
|
+
- **Do not** use **read_file_tool, summarize_file_tool, check_file_related_tool** on the python/R notebook files **(.ipynb, .Rmd)**, as they are too big to read.
|
|
140
|
+
""",
|
|
141
|
+
"plan_important_instructions": """ - **Do not** use **read_file_tool, summarize_file_tool, check_file_related_tool** on the python/R notebook files **(.ipynb, .Rmd)**, as they are too big to read.
|
|
142
|
+
- For python/R notebook files **(.ipynb, .Rmd)**, **only infer** if it is the tutorial/vignette from the file name and avoid reading the content of the file.
|
|
143
|
+
""",
|
|
144
|
+
"observe_important_instructions": """ - **Do not** use **read_file_tool, summarize_file_tool, check_file_related_tool** on the python/R notebook files **(.ipynb, .Rmd)**, as they are too big to read.
|
|
145
|
+
- For python/R notebook files **(.ipynb, .Rmd)**, **only infer** if it is the tutorial/vignette from the file name and avoid reading the content of the file.
|
|
146
|
+
- **Do not** include any binary files (e.g., `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`) in the final answer.s
|
|
138
147
|
""",
|
|
139
148
|
},
|
|
140
149
|
"DockerGeneration": {
|
|
@@ -123,15 +123,8 @@ class CodeStructureDb:
|
|
|
123
123
|
os.makedirs(db_path, exist_ok=True)
|
|
124
124
|
except Exception as e:
|
|
125
125
|
logging.error(e)
|
|
126
|
-
return False
|
|
127
|
-
db_path = os.path.join(db_path, "
|
|
128
|
-
# Ensure the local path exists
|
|
129
|
-
try:
|
|
130
|
-
os.makedirs(db_path, exist_ok=True)
|
|
131
|
-
except Exception as e:
|
|
132
|
-
logging.error(e)
|
|
133
|
-
return False
|
|
134
|
-
db_path = os.path.join(db_path, f"{self.author}_{self.repo_name}.db")
|
|
126
|
+
return False
|
|
127
|
+
db_path = os.path.join(db_path, f"{self.author}_{self.repo_name}_code_structure.db")
|
|
135
128
|
if not os.path.exists(db_path):
|
|
136
129
|
try:
|
|
137
130
|
with open(db_path, "w"):
|
|
@@ -142,6 +135,24 @@ class CodeStructureDb:
|
|
|
142
135
|
self.connection = sqlite3.connect(db_path)
|
|
143
136
|
return True
|
|
144
137
|
|
|
138
|
+
def is_database_built(self) -> bool:
|
|
139
|
+
res = self._connect_to_db()
|
|
140
|
+
if not res:
|
|
141
|
+
return False
|
|
142
|
+
res = self._ensure_tables()
|
|
143
|
+
if not res:
|
|
144
|
+
return False
|
|
145
|
+
try:
|
|
146
|
+
cursor = self.connection.cursor()
|
|
147
|
+
cursor.execute(f"SELECT * FROM {CODE_STRUCTURE_TABLE_NAME}")
|
|
148
|
+
return cursor.fetchone() is not None
|
|
149
|
+
except Exception as e:
|
|
150
|
+
logging.error(e)
|
|
151
|
+
return False
|
|
152
|
+
finally:
|
|
153
|
+
self.connection.close()
|
|
154
|
+
self.connection = None
|
|
155
|
+
|
|
145
156
|
def insert_code_structure(
|
|
146
157
|
self,
|
|
147
158
|
name: str,
|
|
@@ -38,10 +38,11 @@ where file_path = ? and instruction = ? and summarize_level = ? and summarize_pr
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
class SummarizedFilesDb:
|
|
41
|
-
def __init__(self, author: str, repo_name: str):
|
|
41
|
+
def __init__(self, author: str, repo_name: str, data_folder: str = None):
|
|
42
42
|
self.author = author
|
|
43
43
|
self.repo_name = repo_name
|
|
44
44
|
self.connection: Connection | None = None
|
|
45
|
+
self.data_folder = data_folder
|
|
45
46
|
|
|
46
47
|
def _ensure_tables(self) -> bool:
|
|
47
48
|
if self.connection is None:
|
|
@@ -60,7 +61,9 @@ class SummarizedFilesDb:
|
|
|
60
61
|
def _connect_to_db(self) -> bool:
|
|
61
62
|
if self.connection is not None:
|
|
62
63
|
return True
|
|
63
|
-
db_path =
|
|
64
|
+
db_path = self.data_folder
|
|
65
|
+
if db_path is None:
|
|
66
|
+
db_path = os.environ.get("DATA_FOLDER", "./data")
|
|
64
67
|
db_path = os.path.join(db_path, "databases")
|
|
65
68
|
# Ensure the local path exists
|
|
66
69
|
try:
|
|
@@ -68,7 +71,7 @@ class SummarizedFilesDb:
|
|
|
68
71
|
except Exception as e:
|
|
69
72
|
logging.error(e)
|
|
70
73
|
return False
|
|
71
|
-
db_path = os.path.join(db_path, f"{self.author}_{self.repo_name}.db")
|
|
74
|
+
db_path = os.path.join(db_path, f"{self.author}_{self.repo_name}_summarized_file.db")
|
|
72
75
|
if not os.path.exists(db_path):
|
|
73
76
|
try:
|
|
74
77
|
with open(db_path, "w"):
|