psyclaw 0.28.1 → 0.28.2
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.
- package/README.md +5 -5
- package/agents/recommended/catalog.json +1 -1
- package/dist/src/adapters/pi/extension.js +43 -9
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/ars/mode-editor.d.ts +20 -0
- package/dist/src/ars/mode-editor.js +57 -0
- package/dist/src/ars/mode-editor.js.map +1 -0
- package/dist/src/ars/profile.d.ts +4 -1
- package/dist/src/ars/profile.js +23 -6
- package/dist/src/ars/profile.js.map +1 -1
- package/package.json +10 -3
- package/vendor/academic-paper-skills/LICENSE +21 -0
- package/vendor/academic-paper-skills/NOTICE.md +7 -0
- package/vendor/academic-paper-skills/PSYCLAW_SOURCE.json +14 -0
- package/vendor/academic-paper-skills/academic-paper-composer/SKILL.md +840 -0
- package/vendor/academic-paper-skills/academic-paper-composer/references/section_guides.md +675 -0
- package/vendor/academic-paper-skills/academic-paper-composer/references/writing_standards.md +629 -0
- package/vendor/academic-paper-skills/academic-paper-composer/scripts/chapter_quality_check.py +470 -0
- package/vendor/academic-paper-skills/academic-paper-composer/scripts/final_evaluation.py +550 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/SKILL.md +670 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/references/quality_standards.md +336 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/references/search_strategy.md +459 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/scripts/evaluate_samples.py +300 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/scripts/gap_analysis.py +399 -0
- package/vendor/ars/pi/wrapper.js +9 -0
- package/vendor/nature-skills/LICENSE +201 -0
- package/vendor/nature-skills/NOTICE.md +7 -0
- package/vendor/nature-skills/PSYCLAW_SOURCE.json +19 -0
- package/vendor/nature-skills/skills/nature-figure/README.md +107 -0
- package/vendor/nature-skills/skills/nature-figure/README_EN.md +107 -0
- package/vendor/nature-skills/skills/nature-figure/SKILL.md +154 -0
- package/vendor/nature-skills/skills/nature-figure/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-figure/evals/evals.json +325 -0
- package/vendor/nature-skills/skills/nature-figure/manifest.yaml +103 -0
- package/vendor/nature-skills/skills/nature-figure/references/ai-graphical-abstract-workflow.md +129 -0
- package/vendor/nature-skills/skills/nature-figure/references/api.md +576 -0
- package/vendor/nature-skills/skills/nature-figure/references/asset-adaptation.md +72 -0
- package/vendor/nature-skills/skills/nature-figure/references/backend-selection.md +118 -0
- package/vendor/nature-skills/skills/nature-figure/references/chart-types.md +348 -0
- package/vendor/nature-skills/skills/nature-figure/references/common-patterns.md +371 -0
- package/vendor/nature-skills/skills/nature-figure/references/demos.md +58 -0
- package/vendor/nature-skills/skills/nature-figure/references/design-theory.md +467 -0
- package/vendor/nature-skills/skills/nature-figure/references/figure-contract.md +122 -0
- package/vendor/nature-skills/skills/nature-figure/references/figure-legend-conventions.md +90 -0
- package/vendor/nature-skills/skills/nature-figure/references/multipanel-evidence-architecture.md +268 -0
- package/vendor/nature-skills/skills/nature-figure/references/nature-2026-observations.md +124 -0
- package/vendor/nature-skills/skills/nature-figure/references/nature-article-requirements.md +149 -0
- package/vendor/nature-skills/skills/nature-figure/references/openrouter-image-generation.md +141 -0
- package/vendor/nature-skills/skills/nature-figure/references/qa-contract.md +344 -0
- package/vendor/nature-skills/skills/nature-figure/references/r-template-index.md +66 -0
- package/vendor/nature-skills/skills/nature-figure/references/r-workflow.md +234 -0
- package/vendor/nature-skills/skills/nature-figure/references/template-catalog.md +33 -0
- package/vendor/nature-skills/skills/nature-figure/references/tutorials.md +260 -0
- package/vendor/nature-skills/skills/nature-figure/requirements.txt +1 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_figure_collisions.py +742 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_panel_alignment.py +933 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_pdf_text.py +152 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/figure_safety.py +50 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/generate_openrouter_schematic.py +260 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/nature_figure_backend.py +93 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/panel_alignment.R +188 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/plot_templates.py +604 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/validate_figure.py +835 -0
- package/vendor/nature-skills/skills/nature-figure/static/core/contract.md +55 -0
- package/vendor/nature-skills/skills/nature-figure/static/core/stance.md +41 -0
- package/vendor/nature-skills/skills/nature-figure/static/fragments/backend/python.md +56 -0
- package/vendor/nature-skills/skills/nature-figure/static/fragments/backend/r.md +63 -0
- package/vendor/nature-skills/skills/nature-figure/tests/test_figure_safety.py +209 -0
- package/vendor/nature-skills/skills/nature-polishing/README.md +58 -0
- package/vendor/nature-skills/skills/nature-polishing/README_EN.md +58 -0
- package/vendor/nature-skills/skills/nature-polishing/SKILL.md +111 -0
- package/vendor/nature-skills/skills/nature-polishing/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-polishing/manifest.yaml +101 -0
- package/vendor/nature-skills/skills/nature-polishing/references/latex-layout.md +211 -0
- package/vendor/nature-skills/skills/nature-polishing/references/nat-comms-2025-diction.md +73 -0
- package/vendor/nature-skills/skills/nature-polishing/references/phrasebank-playbook.md +175 -0
- package/vendor/nature-skills/skills/nature-polishing/references/published-article-patterns.md +126 -0
- package/vendor/nature-skills/skills/nature-polishing/references/section-moves.md +252 -0
- package/vendor/nature-skills/skills/nature-polishing/references/style-guardrails.md +94 -0
- package/vendor/nature-skills/skills/nature-polishing/references/writing-strategy.md +160 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/failure-modes.md +29 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/output-format.md +21 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/stance.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/generic.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nat-comms.md +38 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nat-mach-intell.md +102 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nature.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/language/en.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/language/zh-to-en.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/algorithmic.md +18 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/hypothesis.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/methods.md +35 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/research.md +29 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/review.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/abstract.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/conclusion.md +15 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/discussion.md +48 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/intro.md +33 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/methods.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/results.md +61 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/title.md +17 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/README.md +44 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/README_EN.md +44 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/SKILL.md +196 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/manifest.yaml +19 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/references/common-patterns.md +96 -0
- package/vendor/nature-skills/skills/nature-shared/README.md +43 -0
- package/vendor/nature-skills/skills/nature-shared/README_EN.md +43 -0
- package/vendor/nature-skills/skills/nature-shared/SKILL.md +33 -0
- package/vendor/nature-skills/skills/nature-shared/agents/openai.yaml +6 -0
- package/vendor/nature-skills/skills/nature-shared/core/consistency-sweep.md +122 -0
- package/vendor/nature-skills/skills/nature-shared/core/discussion-argument-language.md +192 -0
- package/vendor/nature-skills/skills/nature-shared/core/ethics.md +88 -0
- package/vendor/nature-skills/skills/nature-shared/core/main-text-discipline.md +179 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-abstract.md +171 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-introduction.md +164 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-results-discussion.md +215 -0
- package/vendor/nature-skills/skills/nature-shared/core/paper-type-taxonomy.md +41 -0
- package/vendor/nature-skills/skills/nature-shared/core/reader-workflow.md +21 -0
- package/vendor/nature-skills/skills/nature-shared/core/research-compliance.md +192 -0
- package/vendor/nature-skills/skills/nature-shared/core/terminology-ledger.md +58 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nat-comms.md +139 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nature-machine-intelligence.md +431 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nature.md +313 -0
- package/vendor/nature-skills/skills/nature-shared/manifest.yaml +52 -0
- package/vendor/nature-skills/skills/nature-shared/scripts/check_consistency.py +273 -0
- package/vendor/nature-skills/skills/nature-shared/tests/test_check_consistency.py +63 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Final Paper Evaluation Script
|
|
4
|
+
|
|
5
|
+
This script evaluates the complete paper against quality standards before submission.
|
|
6
|
+
Uses 7-dimension assessment (10 points each, 70 total).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Dict, List
|
|
12
|
+
|
|
13
|
+
def create_final_evaluation_template() -> Dict:
|
|
14
|
+
"""Create template for final paper evaluation."""
|
|
15
|
+
return {
|
|
16
|
+
"paper_title": "",
|
|
17
|
+
"total_word_count": 0,
|
|
18
|
+
"target_platform": "",
|
|
19
|
+
"evaluation_date": "",
|
|
20
|
+
"evaluation": {
|
|
21
|
+
"overall_argument_quality": {
|
|
22
|
+
"score": 0, # 1-10
|
|
23
|
+
"notes": ""
|
|
24
|
+
},
|
|
25
|
+
"literature_integration": {
|
|
26
|
+
"score": 0, # 1-10
|
|
27
|
+
"citation_count": 0,
|
|
28
|
+
"notes": ""
|
|
29
|
+
},
|
|
30
|
+
"clarity_accessibility": {
|
|
31
|
+
"score": 0, # 1-10
|
|
32
|
+
"notes": ""
|
|
33
|
+
},
|
|
34
|
+
"originality_contribution": {
|
|
35
|
+
"score": 0, # 1-10
|
|
36
|
+
"notes": ""
|
|
37
|
+
},
|
|
38
|
+
"methodological_rigor": {
|
|
39
|
+
"score": 0, # 1-10
|
|
40
|
+
"notes": ""
|
|
41
|
+
},
|
|
42
|
+
"structure_organization": {
|
|
43
|
+
"score": 0, # 1-10
|
|
44
|
+
"notes": ""
|
|
45
|
+
},
|
|
46
|
+
"platform_conformity": {
|
|
47
|
+
"score": 0, # 1-10
|
|
48
|
+
"notes": ""
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"completeness_checklist": {
|
|
52
|
+
"structural": {
|
|
53
|
+
"abstract": False,
|
|
54
|
+
"introduction": False,
|
|
55
|
+
"main_chapters": False,
|
|
56
|
+
"conclusion": False,
|
|
57
|
+
"references": False
|
|
58
|
+
},
|
|
59
|
+
"content": {
|
|
60
|
+
"promises_fulfilled": False,
|
|
61
|
+
"claims_supported": False,
|
|
62
|
+
"terms_defined": False,
|
|
63
|
+
"objections_addressed": False,
|
|
64
|
+
"limitations_acknowledged": False
|
|
65
|
+
},
|
|
66
|
+
"citations": {
|
|
67
|
+
"text_has_bibliography": False,
|
|
68
|
+
"bibliography_cited": False,
|
|
69
|
+
"format_consistent": False,
|
|
70
|
+
"complete_information": False
|
|
71
|
+
},
|
|
72
|
+
"format": {
|
|
73
|
+
"title_page": False,
|
|
74
|
+
"section_numbering": False,
|
|
75
|
+
"heading_hierarchy": False,
|
|
76
|
+
"platform_requirements": False
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"identified_issues": [],
|
|
80
|
+
"submission_ready": False
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
def calculate_final_score(evaluation: Dict) -> Dict:
|
|
84
|
+
"""Calculate total score and determine submission readiness."""
|
|
85
|
+
scores = evaluation.get("evaluation", {})
|
|
86
|
+
|
|
87
|
+
total = sum([
|
|
88
|
+
scores.get("overall_argument_quality", {}).get("score", 0),
|
|
89
|
+
scores.get("literature_integration", {}).get("score", 0),
|
|
90
|
+
scores.get("clarity_accessibility", {}).get("score", 0),
|
|
91
|
+
scores.get("originality_contribution", {}).get("score", 0),
|
|
92
|
+
scores.get("methodological_rigor", {}).get("score", 0),
|
|
93
|
+
scores.get("structure_organization", {}).get("score", 0),
|
|
94
|
+
scores.get("platform_conformity", {}).get("score", 0)
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
percentage = (total / 70) * 100
|
|
98
|
+
passes = total >= 56 # 80% threshold
|
|
99
|
+
|
|
100
|
+
# Categorize quality
|
|
101
|
+
if total >= 63: # 90%
|
|
102
|
+
quality_level = "Excellent"
|
|
103
|
+
recommendation = "Ready for immediate submission"
|
|
104
|
+
elif total >= 56: # 80%
|
|
105
|
+
quality_level = "Good"
|
|
106
|
+
recommendation = "Ready for submission with minor optional improvements"
|
|
107
|
+
elif total >= 49: # 70%
|
|
108
|
+
quality_level = "Acceptable"
|
|
109
|
+
recommendation = "Moderate revisions recommended before submission"
|
|
110
|
+
else:
|
|
111
|
+
quality_level = "Needs Improvement"
|
|
112
|
+
recommendation = "Major revisions required before submission"
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
"total_score": total,
|
|
116
|
+
"max_score": 70,
|
|
117
|
+
"percentage": round(percentage, 1),
|
|
118
|
+
"passes_threshold": passes,
|
|
119
|
+
"quality_level": quality_level,
|
|
120
|
+
"recommendation": recommendation
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
def evaluate_completeness(checklist: Dict) -> Dict:
|
|
124
|
+
"""Evaluate completeness across all categories."""
|
|
125
|
+
categories = ["structural", "content", "citations", "format"]
|
|
126
|
+
|
|
127
|
+
results = {}
|
|
128
|
+
total_items = 0
|
|
129
|
+
completed_items = 0
|
|
130
|
+
|
|
131
|
+
for category in categories:
|
|
132
|
+
cat_data = checklist.get(category, {})
|
|
133
|
+
cat_total = len(cat_data)
|
|
134
|
+
cat_completed = sum(1 for v in cat_data.values() if v)
|
|
135
|
+
|
|
136
|
+
results[category] = {
|
|
137
|
+
"completed": cat_completed,
|
|
138
|
+
"total": cat_total,
|
|
139
|
+
"percentage": (cat_completed / cat_total * 100) if cat_total > 0 else 0,
|
|
140
|
+
"complete": cat_completed == cat_total
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
total_items += cat_total
|
|
144
|
+
completed_items += cat_completed
|
|
145
|
+
|
|
146
|
+
overall_complete = completed_items == total_items
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
"by_category": results,
|
|
150
|
+
"overall": {
|
|
151
|
+
"completed": completed_items,
|
|
152
|
+
"total": total_items,
|
|
153
|
+
"percentage": (completed_items / total_items * 100) if total_items > 0 else 0,
|
|
154
|
+
"complete": overall_complete
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
def identify_weak_dimensions(evaluation: Dict) -> List[Dict]:
|
|
159
|
+
"""Identify dimensions scoring below 7."""
|
|
160
|
+
scores = evaluation.get("evaluation", {})
|
|
161
|
+
weak_dimensions = []
|
|
162
|
+
|
|
163
|
+
dimensions = [
|
|
164
|
+
("overall_argument_quality", "Overall Argument Quality"),
|
|
165
|
+
("literature_integration", "Literature Integration"),
|
|
166
|
+
("clarity_accessibility", "Clarity & Accessibility"),
|
|
167
|
+
("originality_contribution", "Originality & Contribution"),
|
|
168
|
+
("methodological_rigor", "Methodological Rigor"),
|
|
169
|
+
("structure_organization", "Structure & Organization"),
|
|
170
|
+
("platform_conformity", "Platform & Style Conformity")
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
for key, name in dimensions:
|
|
174
|
+
dim_data = scores.get(key, {})
|
|
175
|
+
score = dim_data.get("score", 0)
|
|
176
|
+
|
|
177
|
+
if score < 7:
|
|
178
|
+
severity = "high" if score <= 4 else "medium"
|
|
179
|
+
weak_dimensions.append({
|
|
180
|
+
"dimension": name,
|
|
181
|
+
"score": score,
|
|
182
|
+
"max_score": 10,
|
|
183
|
+
"notes": dim_data.get("notes", ""),
|
|
184
|
+
"severity": severity
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
return weak_dimensions
|
|
188
|
+
|
|
189
|
+
def generate_recommendations(evaluation: Dict, weak_dims: List[Dict],
|
|
190
|
+
completeness: Dict) -> List[Dict]:
|
|
191
|
+
"""Generate prioritized revision recommendations."""
|
|
192
|
+
recommendations = []
|
|
193
|
+
|
|
194
|
+
# Completeness issues
|
|
195
|
+
if not completeness['overall']['complete']:
|
|
196
|
+
for category, data in completeness['by_category'].items():
|
|
197
|
+
if not data['complete']:
|
|
198
|
+
recommendations.append({
|
|
199
|
+
"category": "completeness",
|
|
200
|
+
"priority": "high",
|
|
201
|
+
"issue": f"{category.title()} completeness: {data['completed']}/{data['total']} items",
|
|
202
|
+
"action": f"Complete all {category} checklist items before submission"
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
# Weak dimensions
|
|
206
|
+
for dim in weak_dims:
|
|
207
|
+
recommendations.append({
|
|
208
|
+
"category": dim["dimension"],
|
|
209
|
+
"priority": dim["severity"],
|
|
210
|
+
"issue": f"{dim['dimension']} scored {dim['score']}/10",
|
|
211
|
+
"action": f"Address: {dim['notes']}" if dim['notes'] else f"Improve {dim['dimension'].lower()}"
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
# Citation count check
|
|
215
|
+
lit_data = evaluation.get("evaluation", {}).get("literature_integration", {})
|
|
216
|
+
citation_count = lit_data.get("citation_count", 0)
|
|
217
|
+
|
|
218
|
+
if citation_count < 20:
|
|
219
|
+
recommendations.append({
|
|
220
|
+
"category": "citations",
|
|
221
|
+
"priority": "high",
|
|
222
|
+
"issue": f"Only {citation_count} citations (minimum 20 recommended)",
|
|
223
|
+
"action": "Expand literature review and add supporting citations"
|
|
224
|
+
})
|
|
225
|
+
elif citation_count < 30:
|
|
226
|
+
recommendations.append({
|
|
227
|
+
"category": "citations",
|
|
228
|
+
"priority": "medium",
|
|
229
|
+
"issue": f"{citation_count} citations (30-40 recommended for philosophy)",
|
|
230
|
+
"action": "Consider adding more citations to strengthen arguments"
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
# Custom issues
|
|
234
|
+
for issue in evaluation.get("identified_issues", []):
|
|
235
|
+
recommendations.append({
|
|
236
|
+
"category": "custom",
|
|
237
|
+
"priority": "high",
|
|
238
|
+
"issue": issue,
|
|
239
|
+
"action": "Address this specific issue"
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
# Sort by priority
|
|
243
|
+
priority_order = {"high": 0, "medium": 1, "low": 2}
|
|
244
|
+
recommendations.sort(key=lambda x: priority_order.get(x["priority"], 3))
|
|
245
|
+
|
|
246
|
+
return recommendations
|
|
247
|
+
|
|
248
|
+
def generate_final_report(evaluation: Dict) -> str:
|
|
249
|
+
"""Generate comprehensive final evaluation report."""
|
|
250
|
+
score_result = calculate_final_score(evaluation)
|
|
251
|
+
completeness = evaluate_completeness(evaluation.get("completeness_checklist", {}))
|
|
252
|
+
weak_dims = identify_weak_dimensions(evaluation)
|
|
253
|
+
recommendations = generate_recommendations(evaluation, weak_dims, completeness)
|
|
254
|
+
|
|
255
|
+
report = f"""
|
|
256
|
+
# Final Paper Evaluation Report
|
|
257
|
+
|
|
258
|
+
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}
|
|
259
|
+
|
|
260
|
+
## Paper Information
|
|
261
|
+
|
|
262
|
+
- **Title**: {evaluation.get('paper_title', 'N/A')}
|
|
263
|
+
- **Total word count**: {evaluation.get('total_word_count', 'N/A')}
|
|
264
|
+
- **Target platform**: {evaluation.get('target_platform', 'N/A')}
|
|
265
|
+
- **Evaluation date**: {evaluation.get('evaluation_date', datetime.now().strftime('%Y-%m-%d'))}
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Overall Assessment
|
|
270
|
+
|
|
271
|
+
- **Total Score**: {score_result['total_score']}/{score_result['max_score']} ({score_result['percentage']}%)
|
|
272
|
+
- **Quality Level**: {score_result['quality_level']}
|
|
273
|
+
- **Passes Threshold**: {'✓ YES' if score_result['passes_threshold'] else '✗ NO (56/70 required)'}
|
|
274
|
+
- **Recommendation**: {score_result['recommendation']}
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 7-Dimension Evaluation
|
|
279
|
+
|
|
280
|
+
"""
|
|
281
|
+
|
|
282
|
+
# Dimension scores
|
|
283
|
+
scores = evaluation.get("evaluation", {})
|
|
284
|
+
dimensions = [
|
|
285
|
+
("overall_argument_quality", "Overall Argument Quality"),
|
|
286
|
+
("literature_integration", "Literature Integration"),
|
|
287
|
+
("clarity_accessibility", "Clarity & Accessibility"),
|
|
288
|
+
("originality_contribution", "Originality & Contribution"),
|
|
289
|
+
("methodological_rigor", "Methodological Rigor"),
|
|
290
|
+
("structure_organization", "Structure & Organization"),
|
|
291
|
+
("platform_conformity", "Platform & Style Conformity")
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
for key, name in dimensions:
|
|
295
|
+
dim_data = scores.get(key, {})
|
|
296
|
+
score = dim_data.get("score", 0)
|
|
297
|
+
notes = dim_data.get("notes", "No notes provided")
|
|
298
|
+
|
|
299
|
+
icon = "✓" if score >= 7 else "⚠"
|
|
300
|
+
report += f"### {icon} {name}: {score}/10\n\n"
|
|
301
|
+
report += f"{notes}\n\n"
|
|
302
|
+
|
|
303
|
+
# Add citation count for literature dimension
|
|
304
|
+
if key == "literature_integration":
|
|
305
|
+
citation_count = dim_data.get("citation_count", 0)
|
|
306
|
+
report += f"**Citation count**: {citation_count}\n\n"
|
|
307
|
+
|
|
308
|
+
# Completeness assessment
|
|
309
|
+
report += "---\n\n## Completeness Assessment\n\n"
|
|
310
|
+
|
|
311
|
+
overall_comp = completeness['overall']
|
|
312
|
+
report += f"**Overall**: {overall_comp['completed']}/{overall_comp['total']} items complete ({overall_comp['percentage']:.1f}%)\n\n"
|
|
313
|
+
|
|
314
|
+
for category, data in completeness['by_category'].items():
|
|
315
|
+
icon = "✓" if data['complete'] else "⚠"
|
|
316
|
+
report += f"### {icon} {category.title()}: {data['completed']}/{data['total']} ({data['percentage']:.1f}%)\n\n"
|
|
317
|
+
|
|
318
|
+
# List incomplete items
|
|
319
|
+
cat_checklist = evaluation.get("completeness_checklist", {}).get(category, {})
|
|
320
|
+
incomplete = [item for item, done in cat_checklist.items() if not done]
|
|
321
|
+
|
|
322
|
+
if incomplete:
|
|
323
|
+
report += "**Incomplete items**:\n"
|
|
324
|
+
for item in incomplete:
|
|
325
|
+
report += f"- {item.replace('_', ' ').title()}\n"
|
|
326
|
+
report += "\n"
|
|
327
|
+
|
|
328
|
+
# Weak dimensions
|
|
329
|
+
if weak_dims:
|
|
330
|
+
report += "---\n\n## Weak Dimensions (Score <7)\n\n"
|
|
331
|
+
for dim in weak_dims:
|
|
332
|
+
report += f"### {dim['dimension']}: {dim['score']}/10 ({dim['severity'].upper()} priority)\n\n"
|
|
333
|
+
if dim['notes']:
|
|
334
|
+
report += f"{dim['notes']}\n\n"
|
|
335
|
+
|
|
336
|
+
# Recommendations
|
|
337
|
+
if recommendations:
|
|
338
|
+
report += "---\n\n## Revision Recommendations\n\n"
|
|
339
|
+
report += "Prioritized list of recommended revisions:\n\n"
|
|
340
|
+
|
|
341
|
+
for i, rec in enumerate(recommendations, 1):
|
|
342
|
+
priority_icon = {"high": "🔴", "medium": "🟡", "low": "🟢"}.get(rec['priority'], "⚪")
|
|
343
|
+
report += f"{i}. {priority_icon} **{rec['category'].title()}** ({rec['priority'].upper()} priority)\n"
|
|
344
|
+
report += f" - Issue: {rec['issue']}\n"
|
|
345
|
+
report += f" - Action: {rec['action']}\n\n"
|
|
346
|
+
|
|
347
|
+
# Submission decision
|
|
348
|
+
report += "---\n\n## Submission Decision\n\n"
|
|
349
|
+
|
|
350
|
+
submission_ready = evaluation.get('submission_ready', False)
|
|
351
|
+
|
|
352
|
+
if score_result['passes_threshold'] and completeness['overall']['complete']:
|
|
353
|
+
report += f"✓ **READY FOR SUBMISSION**: Paper meets quality threshold ({score_result['percentage']}%) and all completeness checks passed.\n\n"
|
|
354
|
+
|
|
355
|
+
if score_result['percentage'] >= 90:
|
|
356
|
+
report += "**Quality**: Excellent. No revisions required.\n\n"
|
|
357
|
+
else:
|
|
358
|
+
report += "**Optional improvements**:\n"
|
|
359
|
+
if recommendations:
|
|
360
|
+
for rec in recommendations[:3]: # Top 3
|
|
361
|
+
report += f"- {rec['action']}\n"
|
|
362
|
+
else:
|
|
363
|
+
report += "- No critical issues identified\n"
|
|
364
|
+
report += "\n**Note**: These improvements are optional. Paper is ready for submission as is.\n"
|
|
365
|
+
|
|
366
|
+
else:
|
|
367
|
+
report += f"✗ **NOT READY**: Paper requires revisions before submission.\n\n"
|
|
368
|
+
|
|
369
|
+
if not score_result['passes_threshold']:
|
|
370
|
+
report += f"**Quality issue**: Score {score_result['total_score']}/70 is below 56/70 threshold.\n"
|
|
371
|
+
|
|
372
|
+
if not completeness['overall']['complete']:
|
|
373
|
+
report += f"**Completeness issue**: {overall_comp['total'] - overall_comp['completed']} checklist items incomplete.\n"
|
|
374
|
+
|
|
375
|
+
report += "\n**Required actions**:\n"
|
|
376
|
+
report += "1. Address all HIGH priority recommendations\n"
|
|
377
|
+
report += "2. Complete all checklist items\n"
|
|
378
|
+
report += "3. Re-evaluate paper after revisions\n"
|
|
379
|
+
report += "4. Verify score ≥56/70 and all items complete\n"
|
|
380
|
+
|
|
381
|
+
# Platform-specific submission checklist
|
|
382
|
+
report += "\n---\n\n## Platform-Specific Submission Checklist\n\n"
|
|
383
|
+
|
|
384
|
+
platform = evaluation.get('target_platform', '').lower()
|
|
385
|
+
|
|
386
|
+
if 'philarchive' in platform or 'philpapers' in platform:
|
|
387
|
+
report += """**PhilArchive/PhilPapers**:
|
|
388
|
+
- [ ] PDF format
|
|
389
|
+
- [ ] Abstract <500 words
|
|
390
|
+
- [ ] Proper metadata (title, keywords, AMS classification)
|
|
391
|
+
- [ ] Author information complete
|
|
392
|
+
- [ ] No formatting issues in PDF
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
elif 'arxiv' in platform:
|
|
396
|
+
report += """**arXiv**:
|
|
397
|
+
- [ ] LaTeX or PDF format
|
|
398
|
+
- [ ] Abstract <1920 characters
|
|
399
|
+
- [ ] Proper category selection (cs.AI, q-bio.NC, etc.)
|
|
400
|
+
- [ ] No embedded fonts issues
|
|
401
|
+
- [ ] Author affiliations included
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
elif 'philsci' in platform:
|
|
405
|
+
report += """**PhilSci-Archive**:
|
|
406
|
+
- [ ] PDF format
|
|
407
|
+
- [ ] Proper subject classification
|
|
408
|
+
- [ ] Keywords provided (3-5 recommended)
|
|
409
|
+
- [ ] No copyrighted material without permission
|
|
410
|
+
- [ ] Author contact information
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
else:
|
|
414
|
+
report += f"**{evaluation.get('target_platform', 'Platform')}**:\n"
|
|
415
|
+
report += "- [ ] Check platform-specific requirements\n"
|
|
416
|
+
report += "- [ ] Verify format compliance\n"
|
|
417
|
+
report += "- [ ] Prepare all required metadata\n"
|
|
418
|
+
|
|
419
|
+
report += "\n---\n\n## Next Steps\n\n"
|
|
420
|
+
|
|
421
|
+
if score_result['passes_threshold'] and completeness['overall']['complete']:
|
|
422
|
+
report += "1. Review optional improvements (if desired)\n"
|
|
423
|
+
report += "2. Complete platform-specific submission checklist\n"
|
|
424
|
+
report += "3. Generate final PDF\n"
|
|
425
|
+
report += "4. Submit to platform\n"
|
|
426
|
+
report += "5. Monitor for feedback/acceptance\n"
|
|
427
|
+
else:
|
|
428
|
+
report += "1. Implement HIGH priority revisions\n"
|
|
429
|
+
report += "2. Complete all checklist items\n"
|
|
430
|
+
report += "3. Re-run final evaluation\n"
|
|
431
|
+
report += "4. When passing, proceed with submission steps\n"
|
|
432
|
+
|
|
433
|
+
return report
|
|
434
|
+
|
|
435
|
+
def validate_evaluation(evaluation: Dict) -> Dict:
|
|
436
|
+
"""Validate that evaluation is complete and properly formatted."""
|
|
437
|
+
issues = []
|
|
438
|
+
warnings = []
|
|
439
|
+
|
|
440
|
+
# Check required fields
|
|
441
|
+
required_fields = ["paper_title", "total_word_count", "target_platform"]
|
|
442
|
+
for field in required_fields:
|
|
443
|
+
if not evaluation.get(field):
|
|
444
|
+
warnings.append(f"Missing recommended field: {field}")
|
|
445
|
+
|
|
446
|
+
# Check all dimensions scored
|
|
447
|
+
eval_data = evaluation.get("evaluation", {})
|
|
448
|
+
dimensions = ["overall_argument_quality", "literature_integration",
|
|
449
|
+
"clarity_accessibility", "originality_contribution",
|
|
450
|
+
"methodological_rigor", "structure_organization",
|
|
451
|
+
"platform_conformity"]
|
|
452
|
+
|
|
453
|
+
for dim in dimensions:
|
|
454
|
+
if dim not in eval_data:
|
|
455
|
+
issues.append(f"Missing dimension: {dim}")
|
|
456
|
+
else:
|
|
457
|
+
score = eval_data[dim].get("score", 0)
|
|
458
|
+
if not isinstance(score, int) or score < 1 or score > 10:
|
|
459
|
+
issues.append(f"Invalid score for {dim}: {score} (must be 1-10)")
|
|
460
|
+
|
|
461
|
+
if not eval_data[dim].get("notes"):
|
|
462
|
+
warnings.append(f"No notes provided for {dim} (recommended)")
|
|
463
|
+
|
|
464
|
+
# Check completeness checklist
|
|
465
|
+
checklist = evaluation.get("completeness_checklist", {})
|
|
466
|
+
if not checklist:
|
|
467
|
+
issues.append("Missing completeness_checklist")
|
|
468
|
+
|
|
469
|
+
return {
|
|
470
|
+
"valid": len(issues) == 0,
|
|
471
|
+
"issues": issues,
|
|
472
|
+
"warnings": warnings
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
def main():
|
|
476
|
+
"""Interactive final evaluation interface."""
|
|
477
|
+
print("=" * 60)
|
|
478
|
+
print("Final Paper Evaluation Tool")
|
|
479
|
+
print("=" * 60)
|
|
480
|
+
print()
|
|
481
|
+
|
|
482
|
+
print("Options:")
|
|
483
|
+
print("1. Create evaluation template")
|
|
484
|
+
print("2. Evaluate paper from JSON")
|
|
485
|
+
print()
|
|
486
|
+
|
|
487
|
+
choice = input("Select option (1-2): ").strip()
|
|
488
|
+
|
|
489
|
+
if choice == "1":
|
|
490
|
+
# Create template
|
|
491
|
+
title = input("Paper title: ").strip()
|
|
492
|
+
word_count = int(input("Total word count: ").strip())
|
|
493
|
+
platform = input("Target platform: ").strip()
|
|
494
|
+
|
|
495
|
+
template = create_final_evaluation_template()
|
|
496
|
+
template["paper_title"] = title
|
|
497
|
+
template["total_word_count"] = word_count
|
|
498
|
+
template["target_platform"] = platform
|
|
499
|
+
template["evaluation_date"] = datetime.now().strftime('%Y-%m-%d')
|
|
500
|
+
|
|
501
|
+
filename = "final_evaluation.json"
|
|
502
|
+
with open(filename, 'w') as f:
|
|
503
|
+
json.dump(template, f, indent=2)
|
|
504
|
+
|
|
505
|
+
print(f"\nTemplate saved to {filename}")
|
|
506
|
+
print("Fill in the evaluation scores, notes, and checklist, then use option 2 to generate report.")
|
|
507
|
+
|
|
508
|
+
elif choice == "2":
|
|
509
|
+
# Evaluate paper
|
|
510
|
+
filename = input("Enter evaluation JSON filename: ").strip()
|
|
511
|
+
try:
|
|
512
|
+
with open(filename, 'r') as f:
|
|
513
|
+
evaluation = json.load(f)
|
|
514
|
+
|
|
515
|
+
# Validate
|
|
516
|
+
validation = validate_evaluation(evaluation)
|
|
517
|
+
|
|
518
|
+
if not validation['valid']:
|
|
519
|
+
print("\n⚠ Validation Issues:")
|
|
520
|
+
for issue in validation['issues']:
|
|
521
|
+
print(f" - {issue}")
|
|
522
|
+
print("\nPlease fix issues before generating report.")
|
|
523
|
+
return
|
|
524
|
+
|
|
525
|
+
if validation['warnings']:
|
|
526
|
+
print("\nℹ️ Warnings:")
|
|
527
|
+
for warning in validation['warnings']:
|
|
528
|
+
print(f" - {warning}")
|
|
529
|
+
print()
|
|
530
|
+
|
|
531
|
+
# Generate report
|
|
532
|
+
report = generate_final_report(evaluation)
|
|
533
|
+
print("\n" + report)
|
|
534
|
+
|
|
535
|
+
# Save report
|
|
536
|
+
report_filename = filename.replace('.json', '_report.md')
|
|
537
|
+
with open(report_filename, 'w') as f:
|
|
538
|
+
f.write(report)
|
|
539
|
+
print(f"\nReport saved to {report_filename}")
|
|
540
|
+
|
|
541
|
+
except FileNotFoundError:
|
|
542
|
+
print(f"Error: File '{filename}' not found")
|
|
543
|
+
except json.JSONDecodeError:
|
|
544
|
+
print(f"Error: '{filename}' is not valid JSON")
|
|
545
|
+
|
|
546
|
+
else:
|
|
547
|
+
print("Invalid option")
|
|
548
|
+
|
|
549
|
+
if __name__ == "__main__":
|
|
550
|
+
main()
|