bioguider 0.2.29__py3-none-any.whl → 0.2.30__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.
- bioguider/generation/change_planner.py +176 -14
- bioguider/generation/document_renderer.py +5 -0
- bioguider/generation/llm_cleaner.py +16 -8
- bioguider/generation/llm_content_generator.py +59 -8
- bioguider/generation/models.py +4 -0
- bioguider/generation/report_loader.py +6 -0
- bioguider/generation/suggestion_extractor.py +345 -21
- bioguider/managers/generation_manager.py +353 -48
- {bioguider-0.2.29.dist-info → bioguider-0.2.30.dist-info}/METADATA +1 -1
- {bioguider-0.2.29.dist-info → bioguider-0.2.30.dist-info}/RECORD +12 -12
- {bioguider-0.2.29.dist-info → bioguider-0.2.30.dist-info}/LICENSE +0 -0
- {bioguider-0.2.29.dist-info → bioguider-0.2.30.dist-info}/WHEEL +0 -0
|
@@ -8,50 +8,132 @@ class SuggestionExtractor:
|
|
|
8
8
|
def extract(self, report: EvaluationReport) -> List[SuggestionItem]:
|
|
9
9
|
suggestions: List[SuggestionItem] = []
|
|
10
10
|
|
|
11
|
-
# README-related suggestions
|
|
11
|
+
# README-related suggestions - Extract specific suggestions
|
|
12
12
|
if report.readme_evaluation:
|
|
13
13
|
for file_name, evaluation in report.readme_evaluation.items():
|
|
14
14
|
structured = evaluation.get("structured_evaluation") if isinstance(evaluation, dict) else None
|
|
15
15
|
if structured:
|
|
16
|
+
# Extract specific dependency suggestions
|
|
17
|
+
dep_score = structured.get("dependency_score")
|
|
18
|
+
dep_suggestions = structured.get("dependency_suggestions")
|
|
19
|
+
if dep_score in ("Poor", "Fair") and dep_suggestions:
|
|
20
|
+
suggestions.append(SuggestionItem(
|
|
21
|
+
id=f"readme-dependencies-{file_name}",
|
|
22
|
+
category="readme.dependencies",
|
|
23
|
+
severity="should_fix",
|
|
24
|
+
source={"section": "readme", "field": "dependency_suggestions", "evidence": dep_suggestions, "score": dep_score},
|
|
25
|
+
target_files=[file_name],
|
|
26
|
+
action="add_dependencies_section",
|
|
27
|
+
anchor_hint="Dependencies",
|
|
28
|
+
content_guidance=dep_suggestions,
|
|
29
|
+
))
|
|
30
|
+
|
|
31
|
+
# Extract specific hardware/software suggestions
|
|
32
|
+
hw_sw_score = structured.get("hardware_and_software_spec_score")
|
|
33
|
+
hw_sw_suggestions = structured.get("hardware_and_software_spec_suggestions")
|
|
34
|
+
if hw_sw_score in ("Poor", "Fair") and hw_sw_suggestions:
|
|
35
|
+
suggestions.append(SuggestionItem(
|
|
36
|
+
id=f"readme-hardware-{file_name}",
|
|
37
|
+
category="readme.hardware",
|
|
38
|
+
severity="should_fix",
|
|
39
|
+
source={"section": "readme", "field": "hardware_and_software_spec_suggestions", "evidence": hw_sw_suggestions, "score": hw_sw_score},
|
|
40
|
+
target_files=[file_name],
|
|
41
|
+
action="add_system_requirements_section",
|
|
42
|
+
anchor_hint="System Requirements",
|
|
43
|
+
content_guidance=hw_sw_suggestions,
|
|
44
|
+
))
|
|
45
|
+
|
|
46
|
+
# Extract specific project purpose suggestions
|
|
47
|
+
purpose_score = structured.get("project_purpose_score")
|
|
48
|
+
purpose_suggestions = structured.get("project_purpose_suggestions")
|
|
49
|
+
if purpose_score in ("Poor", "Fair") and purpose_suggestions:
|
|
50
|
+
suggestions.append(SuggestionItem(
|
|
51
|
+
id=f"readme-purpose-{file_name}",
|
|
52
|
+
category="readme.purpose",
|
|
53
|
+
severity="should_fix",
|
|
54
|
+
source={"section": "readme", "field": "project_purpose_suggestions", "evidence": purpose_suggestions, "score": purpose_score},
|
|
55
|
+
target_files=[file_name],
|
|
56
|
+
action="add_overview_section",
|
|
57
|
+
anchor_hint="Overview",
|
|
58
|
+
content_guidance=purpose_suggestions,
|
|
59
|
+
))
|
|
60
|
+
|
|
61
|
+
# Extract specific readability suggestions
|
|
62
|
+
readability_score = structured.get("readability_score")
|
|
63
|
+
readability_suggestions = structured.get("readability_suggestions")
|
|
64
|
+
if readability_score in ("Poor", "Fair") and readability_suggestions:
|
|
65
|
+
suggestions.append(SuggestionItem(
|
|
66
|
+
id=f"readme-readability-{file_name}",
|
|
67
|
+
category="readme.readability",
|
|
68
|
+
severity="should_fix",
|
|
69
|
+
source={"section": "readme", "field": "readability_suggestions", "evidence": readability_suggestions, "score": readability_score},
|
|
70
|
+
target_files=[file_name],
|
|
71
|
+
action="improve_readability",
|
|
72
|
+
anchor_hint="Introduction",
|
|
73
|
+
content_guidance=readability_suggestions,
|
|
74
|
+
))
|
|
75
|
+
|
|
16
76
|
# Intro cleanup / overview enhancement beyond explicit suggestions
|
|
17
77
|
suggestions.append(SuggestionItem(
|
|
18
78
|
id=f"readme-intro-cleanup-{file_name}",
|
|
19
79
|
category="readme.intro_cleanup",
|
|
20
80
|
severity="should_fix",
|
|
21
|
-
source={"section": "readme", "field": "overview", "evidence": "Improve top-level overview for clarity and tone."},
|
|
81
|
+
source={"section": "readme", "field": "overview", "evidence": "Improve top-level overview for clarity and tone.", "score": "Fair"},
|
|
22
82
|
target_files=[file_name],
|
|
23
83
|
action="replace_intro",
|
|
24
84
|
anchor_hint="Overview",
|
|
25
85
|
content_guidance="Rewrite the opening summary to be clear, neutral, and typo-free.",
|
|
26
86
|
))
|
|
27
|
-
# Dependency clarity
|
|
87
|
+
# Dependency clarity - prioritize specific suggestions (avoid duplicates)
|
|
28
88
|
dep_score = structured.get("dependency_score")
|
|
29
89
|
dep_sugg = structured.get("dependency_suggestions")
|
|
30
|
-
if dep_score in ("Poor", "Fair")
|
|
90
|
+
if dep_sugg and dep_score in ("Poor", "Fair"): # Only if not already added above
|
|
31
91
|
suggestions.append(SuggestionItem(
|
|
32
|
-
id=f"readme-dependencies-{file_name}",
|
|
92
|
+
id=f"readme-dependencies-clarify-{file_name}",
|
|
33
93
|
category="readme.dependencies",
|
|
34
94
|
severity="should_fix",
|
|
35
|
-
source={"section": "readme", "field": "dependencies", "evidence": str(dep_sugg
|
|
95
|
+
source={"section": "readme", "field": "dependencies", "evidence": str(dep_sugg), "score": dep_score},
|
|
36
96
|
target_files=[file_name],
|
|
37
97
|
action="add_dependencies_section",
|
|
38
98
|
anchor_hint="Dependencies",
|
|
39
|
-
content_guidance=str(dep_sugg
|
|
99
|
+
content_guidance=str(dep_sugg),
|
|
100
|
+
))
|
|
101
|
+
elif dep_score in ("Poor", "Fair"): # Fallback to score-based approach
|
|
102
|
+
suggestions.append(SuggestionItem(
|
|
103
|
+
id=f"readme-dependencies-fallback-{file_name}",
|
|
104
|
+
category="readme.dependencies",
|
|
105
|
+
severity="should_fix",
|
|
106
|
+
source={"section": "readme", "field": "dependencies", "evidence": f"score={dep_score}", "score": dep_score},
|
|
107
|
+
target_files=[file_name],
|
|
108
|
+
action="add_dependencies_section",
|
|
109
|
+
anchor_hint="Dependencies",
|
|
110
|
+
content_guidance="List R library dependencies and provide installation guide.",
|
|
40
111
|
))
|
|
41
112
|
|
|
42
|
-
# Hardware/Software specs
|
|
113
|
+
# Hardware/Software specs - prioritize specific suggestions (avoid duplicates)
|
|
43
114
|
hw_score = structured.get("hardware_and_software_spec_score")
|
|
44
115
|
hw_sugg = structured.get("hardware_and_software_spec_suggestions")
|
|
45
|
-
if hw_score in ("Poor", "Fair")
|
|
116
|
+
if hw_sugg and hw_score in ("Poor", "Fair"): # Only if not already added above
|
|
46
117
|
suggestions.append(SuggestionItem(
|
|
47
|
-
id=f"readme-sysreq-{file_name}",
|
|
118
|
+
id=f"readme-sysreq-clarify-{file_name}",
|
|
48
119
|
category="readme.system_requirements",
|
|
49
120
|
severity="should_fix",
|
|
50
|
-
source={"section": "readme", "field": "hardware_and_software", "evidence": str(hw_sugg
|
|
121
|
+
source={"section": "readme", "field": "hardware_and_software", "evidence": str(hw_sugg), "score": hw_score},
|
|
51
122
|
target_files=[file_name],
|
|
52
123
|
action="add_system_requirements_section",
|
|
53
124
|
anchor_hint="System Requirements",
|
|
54
|
-
content_guidance=str(hw_sugg
|
|
125
|
+
content_guidance=str(hw_sugg),
|
|
126
|
+
))
|
|
127
|
+
elif hw_score in ("Poor", "Fair"): # Fallback to score-based approach
|
|
128
|
+
suggestions.append(SuggestionItem(
|
|
129
|
+
id=f"readme-sysreq-fallback-{file_name}",
|
|
130
|
+
category="readme.system_requirements",
|
|
131
|
+
severity="should_fix",
|
|
132
|
+
source={"section": "readme", "field": "hardware_and_software", "evidence": f"score={hw_score}", "score": hw_score},
|
|
133
|
+
target_files=[file_name],
|
|
134
|
+
action="add_system_requirements_section",
|
|
135
|
+
anchor_hint="System Requirements",
|
|
136
|
+
content_guidance="Specify R version requirements, recommend RAM/CPU configurations, and tailor installation instructions for platforms.",
|
|
55
137
|
))
|
|
56
138
|
|
|
57
139
|
# License mention
|
|
@@ -69,19 +151,31 @@ class SuggestionExtractor:
|
|
|
69
151
|
content_guidance=str(lic_sugg),
|
|
70
152
|
))
|
|
71
153
|
|
|
72
|
-
# Readability structuring
|
|
154
|
+
# Readability structuring - prioritize specific suggestions (avoid duplicates)
|
|
73
155
|
read_sugg = structured.get("readability_suggestions")
|
|
74
|
-
|
|
156
|
+
read_score = structured.get("readability_score")
|
|
157
|
+
if read_sugg and read_score in ("Poor", "Fair"): # Only if not already added above
|
|
75
158
|
suggestions.append(SuggestionItem(
|
|
76
|
-
id=f"readme-structure-{file_name}",
|
|
159
|
+
id=f"readme-structure-clarify-{file_name}",
|
|
77
160
|
category="readme.readability",
|
|
78
|
-
severity="
|
|
79
|
-
source={"section": "readability", "field": "readability_suggestions", "evidence": str(read_sugg)},
|
|
161
|
+
severity="should_fix",
|
|
162
|
+
source={"section": "readability", "field": "readability_suggestions", "evidence": str(read_sugg), "score": read_score},
|
|
80
163
|
target_files=[file_name],
|
|
81
164
|
action="normalize_headings_structure",
|
|
82
165
|
anchor_hint="Installation",
|
|
83
166
|
content_guidance=str(read_sugg),
|
|
84
167
|
))
|
|
168
|
+
elif read_score in ("Poor", "Fair"): # Fallback to score-based approach
|
|
169
|
+
suggestions.append(SuggestionItem(
|
|
170
|
+
id=f"readme-structure-fallback-{file_name}",
|
|
171
|
+
category="readme.readability",
|
|
172
|
+
severity="should_fix",
|
|
173
|
+
source={"section": "readability", "field": "readability_score", "evidence": f"score={read_score}", "score": read_score},
|
|
174
|
+
target_files=[file_name],
|
|
175
|
+
action="normalize_headings_structure",
|
|
176
|
+
anchor_hint="Installation",
|
|
177
|
+
content_guidance="Improve readability with better structure and formatting.",
|
|
178
|
+
))
|
|
85
179
|
# If suggestions mention Usage, add a usage section
|
|
86
180
|
if isinstance(read_sugg, str) and "Usage" in read_sugg:
|
|
87
181
|
suggestions.append(SuggestionItem(
|
|
@@ -101,8 +195,25 @@ class SuggestionExtractor:
|
|
|
101
195
|
if isinstance(report.installation_evaluation, dict):
|
|
102
196
|
structured = report.installation_evaluation.get("structured_evaluation")
|
|
103
197
|
if structured:
|
|
198
|
+
# If installation has deficits, full replace installation docs listed in installation_files
|
|
199
|
+
overall = structured.get("overall_score")
|
|
200
|
+
hw = structured.get("hardware_requirements")
|
|
201
|
+
compat = structured.get("compatible_os")
|
|
202
|
+
dep_sugg = structured.get("dependency_suggestions")
|
|
203
|
+
if overall in ("Poor", "Fair") or hw is False or compat is False or dep_sugg:
|
|
204
|
+
for target in report.installation_files or []:
|
|
205
|
+
suggestions.append(SuggestionItem(
|
|
206
|
+
id=f"install-full-replace-{target}",
|
|
207
|
+
category="installation.full_replace",
|
|
208
|
+
severity="should_fix",
|
|
209
|
+
source={"section": "installation", "field": "overall", "evidence": str(structured)},
|
|
210
|
+
target_files=[target],
|
|
211
|
+
action="full_replace",
|
|
212
|
+
anchor_hint=None,
|
|
213
|
+
content_guidance="Rewrite installation doc based on evaluation (dependencies, OS, hardware).",
|
|
214
|
+
))
|
|
104
215
|
dep_sugg = structured.get("dependency_suggestions")
|
|
105
|
-
if dep_sugg:
|
|
216
|
+
if dep_sugg: # Prioritize specific suggestions
|
|
106
217
|
for target in report.installation_files or []:
|
|
107
218
|
suggestions.append(SuggestionItem(
|
|
108
219
|
id=f"install-dep-clarify-{target}",
|
|
@@ -114,14 +225,14 @@ class SuggestionExtractor:
|
|
|
114
225
|
anchor_hint="Dependencies",
|
|
115
226
|
content_guidance=str(dep_sugg),
|
|
116
227
|
))
|
|
117
|
-
|
|
118
|
-
if
|
|
228
|
+
hw_score = structured.get("hardware_requirements")
|
|
229
|
+
if hw_score is False:
|
|
119
230
|
for target in report.installation_files or []:
|
|
120
231
|
suggestions.append(SuggestionItem(
|
|
121
232
|
id=f"install-hw-req-{target}",
|
|
122
233
|
category="installation.hardware",
|
|
123
234
|
severity="should_fix",
|
|
124
|
-
source={"section": "installation", "field": "hardware_requirements", "evidence": "not specified"},
|
|
235
|
+
source={"section": "installation", "field": "hardware_requirements", "score": "Poor", "evidence": "Hardware requirements not specified"},
|
|
125
236
|
target_files=[target],
|
|
126
237
|
action="add_hardware_requirements",
|
|
127
238
|
anchor_hint="Hardware Requirements",
|
|
@@ -131,6 +242,219 @@ class SuggestionExtractor:
|
|
|
131
242
|
# Submission requirements could drive expected output/dataset sections; use only if in files list
|
|
132
243
|
# Keep minimal to avoid speculative content
|
|
133
244
|
|
|
245
|
+
# Userguide/API docs suggestions (new interface) - Extract specific suggestions
|
|
246
|
+
if getattr(report, "userguide_evaluation", None) and isinstance(report.userguide_evaluation, dict):
|
|
247
|
+
for file_name, eval_block in report.userguide_evaluation.items():
|
|
248
|
+
ug_eval = eval_block.get("user_guide_evaluation") if isinstance(eval_block, dict) else None
|
|
249
|
+
consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
|
|
250
|
+
|
|
251
|
+
if isinstance(ug_eval, dict):
|
|
252
|
+
# Extract specific readability suggestions
|
|
253
|
+
readability_score = ug_eval.get("readability_score", "")
|
|
254
|
+
readability_suggestions = ug_eval.get("readability_suggestions", [])
|
|
255
|
+
if readability_score in ("Poor", "Fair") and readability_suggestions:
|
|
256
|
+
for i, suggestion in enumerate(readability_suggestions):
|
|
257
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
258
|
+
suggestions.append(SuggestionItem(
|
|
259
|
+
id=f"userguide-readability-{file_name}-{i}",
|
|
260
|
+
category="userguide.readability",
|
|
261
|
+
severity="should_fix",
|
|
262
|
+
source={"section": "userguide", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
|
|
263
|
+
target_files=[file_name],
|
|
264
|
+
action="improve_readability",
|
|
265
|
+
anchor_hint=f"Readability-{i+1}",
|
|
266
|
+
content_guidance=suggestion,
|
|
267
|
+
))
|
|
268
|
+
|
|
269
|
+
# Extract specific context and purpose suggestions
|
|
270
|
+
context_score = ug_eval.get("context_and_purpose_score", "")
|
|
271
|
+
context_suggestions = ug_eval.get("context_and_purpose_suggestions", [])
|
|
272
|
+
if context_score in ("Poor", "Fair") and context_suggestions:
|
|
273
|
+
for i, suggestion in enumerate(context_suggestions):
|
|
274
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
275
|
+
suggestions.append(SuggestionItem(
|
|
276
|
+
id=f"userguide-context-{file_name}-{i}",
|
|
277
|
+
category="userguide.context",
|
|
278
|
+
severity="should_fix",
|
|
279
|
+
source={"section": "userguide", "field": "context_and_purpose_suggestions", "evidence": suggestion, "score": context_score},
|
|
280
|
+
target_files=[file_name],
|
|
281
|
+
action="improve_context",
|
|
282
|
+
anchor_hint=f"Context-{i+1}",
|
|
283
|
+
content_guidance=suggestion,
|
|
284
|
+
))
|
|
285
|
+
|
|
286
|
+
# Extract specific error handling suggestions
|
|
287
|
+
error_score = ug_eval.get("error_handling_score", "")
|
|
288
|
+
error_suggestions = ug_eval.get("error_handling_suggestions", [])
|
|
289
|
+
if error_score in ("Poor", "Fair") and error_suggestions:
|
|
290
|
+
for i, suggestion in enumerate(error_suggestions):
|
|
291
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
292
|
+
suggestions.append(SuggestionItem(
|
|
293
|
+
id=f"userguide-error-{file_name}-{i}",
|
|
294
|
+
category="userguide.error_handling",
|
|
295
|
+
severity="should_fix",
|
|
296
|
+
source={"section": "userguide", "field": "error_handling_suggestions", "evidence": suggestion, "score": error_score},
|
|
297
|
+
target_files=[file_name],
|
|
298
|
+
action="improve_error_handling",
|
|
299
|
+
anchor_hint=f"Error-Handling-{i+1}",
|
|
300
|
+
content_guidance=suggestion,
|
|
301
|
+
))
|
|
302
|
+
|
|
303
|
+
# If consistency issues present, add targeted improvements
|
|
304
|
+
if isinstance(consistency_eval, dict):
|
|
305
|
+
score = consistency_eval.get("score")
|
|
306
|
+
if score in ("Poor", "Fair"):
|
|
307
|
+
suggestions.append(SuggestionItem(
|
|
308
|
+
id=f"userguide-consistency-{file_name}",
|
|
309
|
+
category="userguide.consistency",
|
|
310
|
+
severity="should_fix",
|
|
311
|
+
source={"section": "userguide", "field": "consistency", "evidence": f"score={score}"},
|
|
312
|
+
target_files=[file_name],
|
|
313
|
+
action="improve_consistency",
|
|
314
|
+
anchor_hint="Examples",
|
|
315
|
+
content_guidance="Improve consistency in examples, terminology, and formatting based on evaluation report.",
|
|
316
|
+
))
|
|
317
|
+
|
|
318
|
+
# Tutorials/vignettes suggestions (new interface) - ONLY Poor/Fair scores
|
|
319
|
+
if getattr(report, "tutorial_evaluation", None) and isinstance(report.tutorial_evaluation, dict):
|
|
320
|
+
for file_name, eval_block in report.tutorial_evaluation.items():
|
|
321
|
+
tut_eval = eval_block.get("tutorial_evaluation") if isinstance(eval_block, dict) else None
|
|
322
|
+
consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
|
|
323
|
+
if isinstance(tut_eval, dict):
|
|
324
|
+
# Only extract suggestions for Poor/Fair scores
|
|
325
|
+
|
|
326
|
+
# Readability suggestions - only if score is Poor/Fair
|
|
327
|
+
readability_score = tut_eval.get("readability_score", "")
|
|
328
|
+
readability_suggestions = tut_eval.get("readability_suggestions", [])
|
|
329
|
+
if readability_score in ("Poor", "Fair") and readability_suggestions:
|
|
330
|
+
for i, suggestion in enumerate(readability_suggestions):
|
|
331
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
332
|
+
suggestions.append(SuggestionItem(
|
|
333
|
+
id=f"tutorial-readability-{file_name}-{i}",
|
|
334
|
+
category="tutorial.readability",
|
|
335
|
+
severity="should_fix",
|
|
336
|
+
source={"section": "tutorial", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
|
|
337
|
+
target_files=[file_name],
|
|
338
|
+
action="improve_readability",
|
|
339
|
+
anchor_hint="Introduction",
|
|
340
|
+
content_guidance=suggestion,
|
|
341
|
+
))
|
|
342
|
+
|
|
343
|
+
# Setup and dependencies suggestions - only if score is Poor/Fair
|
|
344
|
+
setup_score = tut_eval.get("setup_and_dependencies_score", "")
|
|
345
|
+
setup_suggestions = tut_eval.get("setup_and_dependencies_suggestions", [])
|
|
346
|
+
if setup_score in ("Poor", "Fair") and setup_suggestions:
|
|
347
|
+
for i, suggestion in enumerate(setup_suggestions):
|
|
348
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
349
|
+
suggestions.append(SuggestionItem(
|
|
350
|
+
id=f"tutorial-setup-{file_name}-{i}",
|
|
351
|
+
category="tutorial.setup",
|
|
352
|
+
severity="should_fix",
|
|
353
|
+
source={"section": "tutorial", "field": "setup_and_dependencies_suggestions", "evidence": suggestion, "score": setup_score},
|
|
354
|
+
target_files=[file_name],
|
|
355
|
+
action="improve_setup",
|
|
356
|
+
anchor_hint="Setup",
|
|
357
|
+
content_guidance=suggestion,
|
|
358
|
+
))
|
|
359
|
+
|
|
360
|
+
# Reproducibility suggestions - only if score is Poor/Fair
|
|
361
|
+
reproducibility_score = tut_eval.get("reproducibility_score", "")
|
|
362
|
+
reproducibility_suggestions = tut_eval.get("reproducibility_suggestions", [])
|
|
363
|
+
if reproducibility_score in ("Poor", "Fair") and reproducibility_suggestions:
|
|
364
|
+
for i, suggestion in enumerate(reproducibility_suggestions):
|
|
365
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
366
|
+
suggestions.append(SuggestionItem(
|
|
367
|
+
id=f"tutorial-reproducibility-{file_name}-{i}",
|
|
368
|
+
category="tutorial.reproducibility",
|
|
369
|
+
severity="should_fix",
|
|
370
|
+
source={"section": "tutorial", "field": "reproducibility_suggestions", "evidence": suggestion, "score": reproducibility_score},
|
|
371
|
+
target_files=[file_name],
|
|
372
|
+
action="improve_reproducibility",
|
|
373
|
+
anchor_hint="Setup",
|
|
374
|
+
content_guidance=suggestion,
|
|
375
|
+
))
|
|
376
|
+
|
|
377
|
+
# Structure and navigation suggestions - only if score is Poor/Fair
|
|
378
|
+
structure_score = tut_eval.get("structure_and_navigation_score", "")
|
|
379
|
+
structure_suggestions = tut_eval.get("structure_and_navigation_suggestions", [])
|
|
380
|
+
if structure_score in ("Poor", "Fair") and structure_suggestions:
|
|
381
|
+
for i, suggestion in enumerate(structure_suggestions):
|
|
382
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
383
|
+
suggestions.append(SuggestionItem(
|
|
384
|
+
id=f"tutorial-structure-{file_name}-{i}",
|
|
385
|
+
category="tutorial.structure",
|
|
386
|
+
severity="should_fix",
|
|
387
|
+
source={"section": "tutorial", "field": "structure_and_navigation_suggestions", "evidence": suggestion, "score": structure_score},
|
|
388
|
+
target_files=[file_name],
|
|
389
|
+
action="improve_structure",
|
|
390
|
+
anchor_hint="Introduction",
|
|
391
|
+
content_guidance=suggestion,
|
|
392
|
+
))
|
|
393
|
+
|
|
394
|
+
# Executable code quality suggestions - only if score is Poor/Fair
|
|
395
|
+
code_score = tut_eval.get("executable_code_quality_score", "")
|
|
396
|
+
code_suggestions = tut_eval.get("executable_code_quality_suggestions", [])
|
|
397
|
+
if code_score in ("Poor", "Fair") and code_suggestions:
|
|
398
|
+
for i, suggestion in enumerate(code_suggestions):
|
|
399
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
400
|
+
suggestions.append(SuggestionItem(
|
|
401
|
+
id=f"tutorial-code-{file_name}-{i}",
|
|
402
|
+
category="tutorial.code_quality",
|
|
403
|
+
severity="should_fix",
|
|
404
|
+
source={"section": "tutorial", "field": "executable_code_quality_suggestions", "evidence": suggestion, "score": code_score},
|
|
405
|
+
target_files=[file_name],
|
|
406
|
+
action="improve_code_quality",
|
|
407
|
+
anchor_hint="Code Examples",
|
|
408
|
+
content_guidance=suggestion,
|
|
409
|
+
))
|
|
410
|
+
|
|
411
|
+
# Result verification suggestions - only if score is Poor/Fair
|
|
412
|
+
verification_score = tut_eval.get("result_verification_score", "")
|
|
413
|
+
verification_suggestions = tut_eval.get("result_verification_suggestions", [])
|
|
414
|
+
if verification_score in ("Poor", "Fair") and verification_suggestions:
|
|
415
|
+
for i, suggestion in enumerate(verification_suggestions):
|
|
416
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
417
|
+
suggestions.append(SuggestionItem(
|
|
418
|
+
id=f"tutorial-verification-{file_name}-{i}",
|
|
419
|
+
category="tutorial.verification",
|
|
420
|
+
severity="should_fix",
|
|
421
|
+
source={"section": "tutorial", "field": "result_verification_suggestions", "evidence": suggestion, "score": verification_score},
|
|
422
|
+
target_files=[file_name],
|
|
423
|
+
action="improve_verification",
|
|
424
|
+
anchor_hint="Results",
|
|
425
|
+
content_guidance=suggestion,
|
|
426
|
+
))
|
|
427
|
+
|
|
428
|
+
# Performance and resource notes suggestions - only if score is Poor/Fair
|
|
429
|
+
performance_score = tut_eval.get("performance_and_resource_notes_score", "")
|
|
430
|
+
performance_suggestions = tut_eval.get("performance_and_resource_notes_suggestions", [])
|
|
431
|
+
if performance_score in ("Poor", "Fair") and performance_suggestions:
|
|
432
|
+
for i, suggestion in enumerate(performance_suggestions):
|
|
433
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
434
|
+
suggestions.append(SuggestionItem(
|
|
435
|
+
id=f"tutorial-performance-{file_name}-{i}",
|
|
436
|
+
category="tutorial.performance",
|
|
437
|
+
severity="should_fix",
|
|
438
|
+
source={"section": "tutorial", "field": "performance_and_resource_notes_suggestions", "evidence": suggestion, "score": performance_score},
|
|
439
|
+
target_files=[file_name],
|
|
440
|
+
action="improve_performance",
|
|
441
|
+
anchor_hint="Performance",
|
|
442
|
+
content_guidance=suggestion,
|
|
443
|
+
))
|
|
444
|
+
if isinstance(consistency_eval, dict):
|
|
445
|
+
score = consistency_eval.get("score")
|
|
446
|
+
if score in ("Poor", "Fair"):
|
|
447
|
+
suggestions.append(SuggestionItem(
|
|
448
|
+
id=f"tutorial-consistency-{file_name}",
|
|
449
|
+
category="tutorial.consistency",
|
|
450
|
+
severity="should_fix",
|
|
451
|
+
source={"section": "tutorial", "field": "consistency", "evidence": f"score={score}"},
|
|
452
|
+
target_files=[file_name],
|
|
453
|
+
action="full_replace",
|
|
454
|
+
anchor_hint=None,
|
|
455
|
+
content_guidance="Align tutorial with code definitions; fix inconsistencies as per report.",
|
|
456
|
+
))
|
|
457
|
+
|
|
134
458
|
return suggestions
|
|
135
459
|
|
|
136
460
|
|