bioguider 0.2.29__py3-none-any.whl → 0.2.31__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 +63 -14
- bioguider/generation/document_renderer.py +111 -1
- bioguider/generation/llm_cleaner.py +32 -8
- bioguider/generation/llm_content_generator.py +117 -9
- bioguider/generation/models.py +4 -0
- bioguider/generation/report_loader.py +6 -0
- bioguider/generation/suggestion_extractor.py +336 -36
- bioguider/managers/generation_manager.py +389 -48
- {bioguider-0.2.29.dist-info → bioguider-0.2.31.dist-info}/METADATA +1 -1
- {bioguider-0.2.29.dist-info → bioguider-0.2.31.dist-info}/RECORD +12 -12
- {bioguider-0.2.29.dist-info → bioguider-0.2.31.dist-info}/LICENSE +0 -0
- {bioguider-0.2.29.dist-info → bioguider-0.2.31.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="full_replace",
|
|
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="full_replace",
|
|
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}",
|
|
93
|
+
category="readme.dependencies",
|
|
94
|
+
severity="should_fix",
|
|
95
|
+
source={"section": "readme", "field": "dependencies", "evidence": str(dep_sugg), "score": dep_score},
|
|
96
|
+
target_files=[file_name],
|
|
97
|
+
action="add_dependencies_section",
|
|
98
|
+
anchor_hint="Dependencies",
|
|
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}",
|
|
33
104
|
category="readme.dependencies",
|
|
34
105
|
severity="should_fix",
|
|
35
|
-
source={"section": "readme", "field": "dependencies", "evidence":
|
|
106
|
+
source={"section": "readme", "field": "dependencies", "evidence": f"score={dep_score}", "score": dep_score},
|
|
36
107
|
target_files=[file_name],
|
|
37
108
|
action="add_dependencies_section",
|
|
38
109
|
anchor_hint="Dependencies",
|
|
39
|
-
content_guidance=
|
|
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,35 +195,241 @@ class SuggestionExtractor:
|
|
|
101
195
|
if isinstance(report.installation_evaluation, dict):
|
|
102
196
|
structured = report.installation_evaluation.get("structured_evaluation")
|
|
103
197
|
if structured:
|
|
198
|
+
# Use full_replace mode for all installation files
|
|
104
199
|
dep_sugg = structured.get("dependency_suggestions")
|
|
105
|
-
|
|
200
|
+
hw_req = structured.get("hardware_requirements")
|
|
201
|
+
compat_os = structured.get("compatible_os")
|
|
202
|
+
overall = structured.get("overall_score")
|
|
203
|
+
|
|
204
|
+
# Trigger full_replace for all installation files when needed
|
|
205
|
+
if overall in ("Poor", "Fair") or hw_req is False or compat_os is False or dep_sugg:
|
|
106
206
|
for target in report.installation_files or []:
|
|
107
207
|
suggestions.append(SuggestionItem(
|
|
108
|
-
id=f"install-
|
|
109
|
-
category="installation.
|
|
208
|
+
id=f"install-full-replace-{target}",
|
|
209
|
+
category="installation.full_replace",
|
|
110
210
|
severity="should_fix",
|
|
111
|
-
source={"section": "installation", "field": "
|
|
211
|
+
source={"section": "installation", "field": "overall", "evidence": str(structured)},
|
|
112
212
|
target_files=[target],
|
|
113
|
-
action="
|
|
114
|
-
anchor_hint=
|
|
115
|
-
content_guidance=
|
|
213
|
+
action="full_replace",
|
|
214
|
+
anchor_hint=None,
|
|
215
|
+
content_guidance="Comprehensive rewrite preserving original structure while adding improved dependencies, hardware requirements, and installation instructions.",
|
|
116
216
|
))
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
217
|
+
|
|
218
|
+
# Submission requirements could drive expected output/dataset sections; use only if in files list
|
|
219
|
+
# Keep minimal to avoid speculative content
|
|
220
|
+
|
|
221
|
+
# Userguide/API docs suggestions (new interface) - Extract specific suggestions
|
|
222
|
+
if getattr(report, "userguide_evaluation", None) and isinstance(report.userguide_evaluation, dict):
|
|
223
|
+
for file_name, eval_block in report.userguide_evaluation.items():
|
|
224
|
+
ug_eval = eval_block.get("user_guide_evaluation") if isinstance(eval_block, dict) else None
|
|
225
|
+
consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
|
|
226
|
+
|
|
227
|
+
if isinstance(ug_eval, dict):
|
|
228
|
+
# Extract specific readability suggestions
|
|
229
|
+
readability_score = ug_eval.get("readability_score", "")
|
|
230
|
+
readability_suggestions = ug_eval.get("readability_suggestions", [])
|
|
231
|
+
if readability_score in ("Poor", "Fair") and readability_suggestions:
|
|
232
|
+
for i, suggestion in enumerate(readability_suggestions):
|
|
233
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
234
|
+
suggestions.append(SuggestionItem(
|
|
235
|
+
id=f"userguide-readability-{file_name}-{i}",
|
|
236
|
+
category="userguide.readability",
|
|
237
|
+
severity="should_fix",
|
|
238
|
+
source={"section": "userguide", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
|
|
239
|
+
target_files=[file_name],
|
|
240
|
+
action="full_replace",
|
|
241
|
+
anchor_hint=f"Readability-{i+1}",
|
|
242
|
+
content_guidance=suggestion,
|
|
243
|
+
))
|
|
244
|
+
|
|
245
|
+
# Extract specific context and purpose suggestions
|
|
246
|
+
context_score = ug_eval.get("context_and_purpose_score", "")
|
|
247
|
+
context_suggestions = ug_eval.get("context_and_purpose_suggestions", [])
|
|
248
|
+
if context_score in ("Poor", "Fair") and context_suggestions:
|
|
249
|
+
for i, suggestion in enumerate(context_suggestions):
|
|
250
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
251
|
+
suggestions.append(SuggestionItem(
|
|
252
|
+
id=f"userguide-context-{file_name}-{i}",
|
|
253
|
+
category="userguide.context",
|
|
254
|
+
severity="should_fix",
|
|
255
|
+
source={"section": "userguide", "field": "context_and_purpose_suggestions", "evidence": suggestion, "score": context_score},
|
|
256
|
+
target_files=[file_name],
|
|
257
|
+
action="full_replace",
|
|
258
|
+
anchor_hint=f"Context-{i+1}",
|
|
259
|
+
content_guidance=suggestion,
|
|
260
|
+
))
|
|
261
|
+
|
|
262
|
+
# Extract specific error handling suggestions
|
|
263
|
+
error_score = ug_eval.get("error_handling_score", "")
|
|
264
|
+
error_suggestions = ug_eval.get("error_handling_suggestions", [])
|
|
265
|
+
if error_score in ("Poor", "Fair") and error_suggestions:
|
|
266
|
+
for i, suggestion in enumerate(error_suggestions):
|
|
267
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
268
|
+
suggestions.append(SuggestionItem(
|
|
269
|
+
id=f"userguide-error-{file_name}-{i}",
|
|
270
|
+
category="userguide.error_handling",
|
|
271
|
+
severity="should_fix",
|
|
272
|
+
source={"section": "userguide", "field": "error_handling_suggestions", "evidence": suggestion, "score": error_score},
|
|
273
|
+
target_files=[file_name],
|
|
274
|
+
action="full_replace",
|
|
275
|
+
anchor_hint=f"Error-Handling-{i+1}",
|
|
276
|
+
content_guidance=suggestion,
|
|
277
|
+
))
|
|
278
|
+
|
|
279
|
+
# If consistency issues present, add targeted improvements
|
|
280
|
+
if isinstance(consistency_eval, dict):
|
|
281
|
+
score = consistency_eval.get("score")
|
|
282
|
+
if score in ("Poor", "Fair"):
|
|
120
283
|
suggestions.append(SuggestionItem(
|
|
121
|
-
id=f"
|
|
122
|
-
category="
|
|
284
|
+
id=f"userguide-consistency-{file_name}",
|
|
285
|
+
category="userguide.consistency",
|
|
123
286
|
severity="should_fix",
|
|
124
|
-
source={"section": "
|
|
125
|
-
target_files=[
|
|
126
|
-
action="
|
|
127
|
-
anchor_hint="
|
|
128
|
-
content_guidance="
|
|
287
|
+
source={"section": "userguide", "field": "consistency", "evidence": f"score={score}"},
|
|
288
|
+
target_files=[file_name],
|
|
289
|
+
action="full_replace",
|
|
290
|
+
anchor_hint="Examples",
|
|
291
|
+
content_guidance="Improve consistency in examples, terminology, and formatting based on evaluation report.",
|
|
129
292
|
))
|
|
130
293
|
|
|
131
|
-
#
|
|
132
|
-
|
|
294
|
+
# Tutorials/vignettes suggestions (new interface) - ONLY Poor/Fair scores
|
|
295
|
+
if getattr(report, "tutorial_evaluation", None) and isinstance(report.tutorial_evaluation, dict):
|
|
296
|
+
for file_name, eval_block in report.tutorial_evaluation.items():
|
|
297
|
+
tut_eval = eval_block.get("tutorial_evaluation") if isinstance(eval_block, dict) else None
|
|
298
|
+
consistency_eval = eval_block.get("consistency_evaluation") if isinstance(eval_block, dict) else None
|
|
299
|
+
if isinstance(tut_eval, dict):
|
|
300
|
+
# Only extract suggestions for Poor/Fair scores
|
|
301
|
+
|
|
302
|
+
# Readability suggestions - only if score is Poor/Fair
|
|
303
|
+
readability_score = tut_eval.get("readability_score", "")
|
|
304
|
+
readability_suggestions = tut_eval.get("readability_suggestions", [])
|
|
305
|
+
if readability_score in ("Poor", "Fair") and readability_suggestions:
|
|
306
|
+
for i, suggestion in enumerate(readability_suggestions):
|
|
307
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
308
|
+
suggestions.append(SuggestionItem(
|
|
309
|
+
id=f"tutorial-readability-{file_name}-{i}",
|
|
310
|
+
category="tutorial.readability",
|
|
311
|
+
severity="should_fix",
|
|
312
|
+
source={"section": "tutorial", "field": "readability_suggestions", "evidence": suggestion, "score": readability_score},
|
|
313
|
+
target_files=[file_name],
|
|
314
|
+
action="full_replace",
|
|
315
|
+
anchor_hint="Introduction",
|
|
316
|
+
content_guidance=suggestion,
|
|
317
|
+
))
|
|
318
|
+
|
|
319
|
+
# Setup and dependencies suggestions - only if score is Poor/Fair
|
|
320
|
+
setup_score = tut_eval.get("setup_and_dependencies_score", "")
|
|
321
|
+
setup_suggestions = tut_eval.get("setup_and_dependencies_suggestions", [])
|
|
322
|
+
if setup_score in ("Poor", "Fair") and setup_suggestions:
|
|
323
|
+
for i, suggestion in enumerate(setup_suggestions):
|
|
324
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
325
|
+
suggestions.append(SuggestionItem(
|
|
326
|
+
id=f"tutorial-setup-{file_name}-{i}",
|
|
327
|
+
category="tutorial.setup",
|
|
328
|
+
severity="should_fix",
|
|
329
|
+
source={"section": "tutorial", "field": "setup_and_dependencies_suggestions", "evidence": suggestion, "score": setup_score},
|
|
330
|
+
target_files=[file_name],
|
|
331
|
+
action="full_replace",
|
|
332
|
+
anchor_hint="Setup",
|
|
333
|
+
content_guidance=suggestion,
|
|
334
|
+
))
|
|
335
|
+
|
|
336
|
+
# Reproducibility suggestions - only if score is Poor/Fair
|
|
337
|
+
reproducibility_score = tut_eval.get("reproducibility_score", "")
|
|
338
|
+
reproducibility_suggestions = tut_eval.get("reproducibility_suggestions", [])
|
|
339
|
+
if reproducibility_score in ("Poor", "Fair") and reproducibility_suggestions:
|
|
340
|
+
for i, suggestion in enumerate(reproducibility_suggestions):
|
|
341
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
342
|
+
suggestions.append(SuggestionItem(
|
|
343
|
+
id=f"tutorial-reproducibility-{file_name}-{i}",
|
|
344
|
+
category="tutorial.reproducibility",
|
|
345
|
+
severity="should_fix",
|
|
346
|
+
source={"section": "tutorial", "field": "reproducibility_suggestions", "evidence": suggestion, "score": reproducibility_score},
|
|
347
|
+
target_files=[file_name],
|
|
348
|
+
action="full_replace",
|
|
349
|
+
anchor_hint="Setup",
|
|
350
|
+
content_guidance=suggestion,
|
|
351
|
+
))
|
|
352
|
+
|
|
353
|
+
# Structure and navigation suggestions - only if score is Poor/Fair
|
|
354
|
+
structure_score = tut_eval.get("structure_and_navigation_score", "")
|
|
355
|
+
structure_suggestions = tut_eval.get("structure_and_navigation_suggestions", [])
|
|
356
|
+
if structure_score in ("Poor", "Fair") and structure_suggestions:
|
|
357
|
+
for i, suggestion in enumerate(structure_suggestions):
|
|
358
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
359
|
+
suggestions.append(SuggestionItem(
|
|
360
|
+
id=f"tutorial-structure-{file_name}-{i}",
|
|
361
|
+
category="tutorial.structure",
|
|
362
|
+
severity="should_fix",
|
|
363
|
+
source={"section": "tutorial", "field": "structure_and_navigation_suggestions", "evidence": suggestion, "score": structure_score},
|
|
364
|
+
target_files=[file_name],
|
|
365
|
+
action="full_replace",
|
|
366
|
+
anchor_hint="Introduction",
|
|
367
|
+
content_guidance=suggestion,
|
|
368
|
+
))
|
|
369
|
+
|
|
370
|
+
# Executable code quality suggestions - only if score is Poor/Fair
|
|
371
|
+
code_score = tut_eval.get("executable_code_quality_score", "")
|
|
372
|
+
code_suggestions = tut_eval.get("executable_code_quality_suggestions", [])
|
|
373
|
+
if code_score in ("Poor", "Fair") and code_suggestions:
|
|
374
|
+
for i, suggestion in enumerate(code_suggestions):
|
|
375
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
376
|
+
suggestions.append(SuggestionItem(
|
|
377
|
+
id=f"tutorial-code-{file_name}-{i}",
|
|
378
|
+
category="tutorial.code_quality",
|
|
379
|
+
severity="should_fix",
|
|
380
|
+
source={"section": "tutorial", "field": "executable_code_quality_suggestions", "evidence": suggestion, "score": code_score},
|
|
381
|
+
target_files=[file_name],
|
|
382
|
+
action="full_replace",
|
|
383
|
+
anchor_hint="Code Examples",
|
|
384
|
+
content_guidance=suggestion,
|
|
385
|
+
))
|
|
386
|
+
|
|
387
|
+
# Result verification suggestions - only if score is Poor/Fair
|
|
388
|
+
verification_score = tut_eval.get("result_verification_score", "")
|
|
389
|
+
verification_suggestions = tut_eval.get("result_verification_suggestions", [])
|
|
390
|
+
if verification_score in ("Poor", "Fair") and verification_suggestions:
|
|
391
|
+
for i, suggestion in enumerate(verification_suggestions):
|
|
392
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
393
|
+
suggestions.append(SuggestionItem(
|
|
394
|
+
id=f"tutorial-verification-{file_name}-{i}",
|
|
395
|
+
category="tutorial.verification",
|
|
396
|
+
severity="should_fix",
|
|
397
|
+
source={"section": "tutorial", "field": "result_verification_suggestions", "evidence": suggestion, "score": verification_score},
|
|
398
|
+
target_files=[file_name],
|
|
399
|
+
action="full_replace",
|
|
400
|
+
anchor_hint="Results",
|
|
401
|
+
content_guidance=suggestion,
|
|
402
|
+
))
|
|
403
|
+
|
|
404
|
+
# Performance and resource notes suggestions - only if score is Poor/Fair
|
|
405
|
+
performance_score = tut_eval.get("performance_and_resource_notes_score", "")
|
|
406
|
+
performance_suggestions = tut_eval.get("performance_and_resource_notes_suggestions", [])
|
|
407
|
+
if performance_score in ("Poor", "Fair") and performance_suggestions:
|
|
408
|
+
for i, suggestion in enumerate(performance_suggestions):
|
|
409
|
+
if isinstance(suggestion, str) and suggestion.strip():
|
|
410
|
+
suggestions.append(SuggestionItem(
|
|
411
|
+
id=f"tutorial-performance-{file_name}-{i}",
|
|
412
|
+
category="tutorial.performance",
|
|
413
|
+
severity="should_fix",
|
|
414
|
+
source={"section": "tutorial", "field": "performance_and_resource_notes_suggestions", "evidence": suggestion, "score": performance_score},
|
|
415
|
+
target_files=[file_name],
|
|
416
|
+
action="full_replace",
|
|
417
|
+
anchor_hint="Performance",
|
|
418
|
+
content_guidance=suggestion,
|
|
419
|
+
))
|
|
420
|
+
if isinstance(consistency_eval, dict):
|
|
421
|
+
score = consistency_eval.get("score")
|
|
422
|
+
if score in ("Poor", "Fair"):
|
|
423
|
+
suggestions.append(SuggestionItem(
|
|
424
|
+
id=f"tutorial-consistency-{file_name}",
|
|
425
|
+
category="tutorial.consistency",
|
|
426
|
+
severity="should_fix",
|
|
427
|
+
source={"section": "tutorial", "field": "consistency", "evidence": f"score={score}"},
|
|
428
|
+
target_files=[file_name],
|
|
429
|
+
action="full_replace",
|
|
430
|
+
anchor_hint=None,
|
|
431
|
+
content_guidance="Align tutorial with code definitions; fix inconsistencies as per report.",
|
|
432
|
+
))
|
|
133
433
|
|
|
134
434
|
return suggestions
|
|
135
435
|
|