peer-review-response-drafter
Assist in drafting professional peer review response letters. Trigger when user mentions "reviewer comments", "response letter", "peer review", "revise and resubmit", "R&R", "reviewer feedback", or needs help responding to academic journal reviewers.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-peer-review-response-drafter
Repository
Skill path: skills/aipoch-ai/peer-review-response-drafter
Assist in drafting professional peer review response letters. Trigger when user mentions "reviewer comments", "response letter", "peer review", "revise and resubmit", "R&R", "reviewer feedback", or needs help responding to academic journal reviewers.
Open repositoryBest for
Primary workflow: Research & Ops.
Technical facets: Full Stack.
Target audience: everyone.
License: MIT.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install peer-review-response-drafter into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding peer-review-response-drafter to shared team environments
- Use peer-review-response-drafter for research workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: peer-review-response-drafter
description: Assist in drafting professional peer review response letters. Trigger
when user mentions "reviewer comments", "response letter", "peer review", "revise
and resubmit", "R&R", "reviewer feedback", or needs help responding to academic
journal reviewers.
version: 1.0.0
category: Research
tags: []
author: AIPOCH
license: MIT
status: Draft
risk_level: Medium
skill_type: Tool/Script
owner: AIPOCH
reviewer: ''
last_updated: '2026-02-06'
---
# Peer Review Response Drafter
Assist researchers in crafting professional, polite, and effective responses to peer reviewer comments for academic journal submissions.
## Overview
This skill parses reviewer comments, drafts structured responses, and adjusts tone to ensure:
- Professional and courteous language
- Clear point-by-point addressing of concerns
- Constructive framing of disagreements
- Consistent academic writing style
## When to Use
- Responding to peer reviewer comments after paper revision
- Preparing author response letters for journal resubmission
- Addressing major/minor revision requirements
- Drafting rebuttal letters for conference submissions
- Converting informal notes into formal response language
## Workflow
### Step 1: Parse Input
Collect and structure the following:
- **Reviewer comments**: Original text from reviewers (often numbered/sectioned)
- **Manuscript context**: Title, journal name, revision round (if applicable)
- **Author changes**: Brief notes on what was modified in response to each comment
- **Tone preference**: Formal academic / diplomatic / assertive (default: diplomatic)
### Step 2: Structure Response Letter
Standard academic response letter format:
```
Dear Editor and Reviewers,
Thank you for your constructive feedback on our manuscript titled
"[Title]" submitted to [Journal]. We have carefully addressed all
comments and revised the manuscript accordingly. Below is our
point-by-point response to each reviewer's comments.
Reviewer #1:
[Numbered responses]
Reviewer #2:
[Numbered responses]
...
Sincerely,
[Authors]
```
### Step 3: Draft Individual Responses
For each reviewer comment, generate a response containing:
1. **Acknowledgment**: Thank the reviewer for the observation
2. **Action taken**: Describe the change made (if applicable)
3. **Location indicator**: Page/line number where change appears
4. **Optional rationale**: Brief explanation if no change was made
#### Response Templates
**Accepting a suggestion:**
```
Comment: The methodology section lacks detail on data preprocessing.
Response: We thank the reviewer for this important observation.
We have expanded the methodology section to include detailed
descriptions of data preprocessing steps, including normalization,
outlier removal, and feature selection procedures (Page 5, Lines 120-135).
```
**Partial acceptance with modification:**
```
Comment: The authors should use Method X instead of Method Y.
Response: We appreciate the reviewer's suggestion. While Method X
is indeed widely used, we found that Method Y is more appropriate
for our specific dataset due to [brief rationale]. However, we have
added a comparative discussion of both methods in the revised
manuscript (Page 8, Lines 200-210) to acknowledge this alternative
approach.
```
**Politely declining:**
```
Comment: The authors should remove Figure 3 as it seems redundant.
Response: We thank the reviewer for this suggestion. Upon careful
consideration, we believe Figure 3 provides essential visual
support for the key finding discussed in Section 4.2. To enhance
clarity, we have revised the figure caption to better emphasize
its unique contribution (Page 10, Figure 3 caption).
```
### Step 4: Tone Adjustment
Adjust language based on context:
| Tone | Use Case | Example Phrasing |
|------|----------|------------------|
| Diplomatic | General revisions | "We thank..." / "We appreciate..." / "We have revised..." |
| Assertive | Defending methodology | "We respectfully note..." / "Our approach is justified because..." |
| Grateful | Major improvements | "We are grateful for..." / "This significantly improved..." |
## Input Format
Accept multiple input formats:
- Copy-pasted reviewer comments
- PDF extracted text
- Structured JSON with comment IDs
- Markdown with sections
## Output Format
Returns a complete response letter with:
- Proper salutation and closing
- Numbered responses matching reviewer comments
- Inline citations to manuscript locations
- Professional academic tone throughout
## Usage Example
```
User: Help me draft a response to these reviewer comments:
Reviewer 1:
1. The introduction should better motivate the problem
2. Figure 2 is unclear
3. Have you considered Smith et al. 2023?
My changes:
1. Added motivation paragraph
2. Redrew Figure 2 with clearer labels
3. Added citation and discussion
Journal: Nature Communications
```
## Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `--interactive` | flag | No | - | **Interactive mode**: Guided wizard with prompts (uses `input()`). Recommended for first-time users or complex responses |
| `--input-file` | str | No | - | Path to reviewer comments file (automation mode) |
| `--output` | str | No | - | Output file path for response letter |
| `--tone` | str | No | "diplomatic" | Response tone: "diplomatic", "formal", or "assertive" |
| `--format` | str | No | "markdown" | Output format: "markdown", "plain_text", or "latex" |
| `--include-diff` | bool | No | true | Whether to summarize changes made |
**Usage Modes:**
- **Interactive Mode**: Use `--interactive` for guided setup with prompts (recommended for first-time users)
- **File Mode (Recommended for automation)**: Use `--input-file` with pre-prepared reviewer comments
## Technical Notes
- **Difficulty**: High - Requires understanding of academic norms, context-aware tone adjustment, and nuanced handling of criticism
- **Limitations**: Does not verify factual accuracy of responses; human review required for technical content
- **Safety**: No external API calls; processes text locally
## References
- `references/response_templates.md` - Common response patterns
- `references/tone_guide.md` - Academic tone guidelines
- `references/examples/` - Sample response letters
## Quality Checklist
Before finalizing, verify:
- [ ] Every reviewer comment has a corresponding response
- [ ] Responses are numbered/lettered consistently with comments
- [ ] All changes are referenced with page/line numbers
- [ ] Disagreements are framed constructively
- [ ] No defensive or confrontational language
- [ ] Professional tone maintained throughout
## Risk Assessment
| Risk Indicator | Assessment | Level |
|----------------|------------|-------|
| Code Execution | Python/R scripts executed locally | Medium |
| Network Access | No external API calls | Low |
| File System Access | Read input files, write output files | Medium |
| Instruction Tampering | Standard prompt guidelines | Low |
| Data Exposure | Output files saved to workspace | Low |
## Security Checklist
- [ ] No hardcoded credentials or API keys
- [ ] No unauthorized file system access (../)
- [ ] Output does not expose sensitive information
- [ ] Prompt injection protections in place
- [ ] Input file paths validated (no ../ traversal)
- [ ] Output directory restricted to workspace
- [ ] Script execution in sandboxed environment
- [ ] Error messages sanitized (no stack traces exposed)
- [ ] Dependencies audited
## Prerequisites
```bash
# Python dependencies
pip install -r requirements.txt
```
## Evaluation Criteria
### Success Metrics
- [ ] Successfully executes main functionality
- [ ] Output meets quality standards
- [ ] Handles edge cases gracefully
- [ ] Performance is acceptable
### Test Cases
1. **Basic Functionality**: Standard input → Expected output
2. **Edge Case**: Invalid input → Graceful error handling
3. **Performance**: Large dataset → Acceptable processing time
## Lifecycle Status
- **Current Stage**: Draft
- **Next Review Date**: 2026-03-06
- **Known Issues**: None
- **Planned Improvements**:
- Performance optimization
- Additional feature support
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/response_templates.md
```markdown
# Response Templates for Peer Review Letters
This document provides templates for common response scenarios in academic peer review correspondence.
## General Principles
1. **Always express gratitude** - Even for critical comments
2. **Be specific** - Reference exact locations of changes
3. **Stay professional** - Never be defensive or dismissive
4. **Match the structure** - Respond to every point in order
---
## Scenario Templates
### 1. Accepting a Suggestion (Full Acceptance)
**When to use:** You agree with the reviewer and have implemented the change.
**Template:**
```
We thank the reviewer for this valuable suggestion. We have revised
the [section/figure/analysis] to [describe change]. Specifically,
we have [specific details of the change] (Page X, Lines Y-Z).
```
**Example:**
```
We thank the reviewer for this valuable suggestion. We have revised
the methodology section to include detailed descriptions of our data
preprocessing steps. Specifically, we have added a paragraph explaining
normalization procedures, outlier detection criteria, and feature
selection methods (Page 5, Lines 120-135).
```
---
### 2. Partial Acceptance (Modified Implementation)
**When to use:** You accept the spirit of the suggestion but implemented it differently.
**Template:**
```
We appreciate the reviewer's suggestion regarding [topic]. After
careful consideration, we have adopted a modified approach. While
[reviewer's suggestion], we found that [your approach] is more
appropriate for our study because [brief rationale]. We have
[describe what you did instead] (Page X, Lines Y-Z).
```
**Example:**
```
We appreciate the reviewer's suggestion regarding the statistical
analysis. After careful consideration, we have adopted a modified
approach. While the Wilcoxon test is commonly used, we found that
the Mann-Whitney U test is more appropriate for our study because
our groups are independent rather than paired. We have updated
the statistical methods section accordingly (Page 8, Lines 200-210).
```
---
### 3. Politely Declining (With Rationale)
**When to use:** You disagree with the suggestion but want to maintain a professional tone.
**Template:**
```
We thank the reviewer for this suggestion. Upon careful consideration,
we have maintained our original approach. [Brief, objective rationale].
However, we have [compromise/alternative if applicable] to address
the reviewer's concern about [specific aspect].
```
**Example:**
```
We thank the reviewer for suggesting the removal of Figure 3. Upon
careful consideration, we have maintained our original approach.
This figure provides essential visual support for the temporal
dynamics discussed in Section 4.2, which cannot be adequately
conveyed in text alone. However, we have revised the figure caption
to better emphasize its unique contribution and improved the color
contrast for better clarity (Page 10, Figure 3).
```
---
### 4. Request for Additional Analysis
**When to use:** The reviewer requests new experiments or analyses.
**Accepted:**
```
We thank the reviewer for this excellent suggestion. We have
conducted the additional analysis as requested. The results
[show/support/indicate] [key finding], which we have added to
[section] (Page X, Lines Y-Z, and new Figure/Table Z).
```
**Not feasible:**
```
We appreciate the reviewer's suggestion for additional analysis.
We agree that such analysis would provide valuable insights.
However, due to [specific constraint: data availability / time
constraints / sample limitations], we are unable to conduct this
analysis at this time. We have added a discussion of this limitation
and its implications in the [section] (Page X, Lines Y-Z).
```
---
### 5. Literature Citation Request
**When to use:** The reviewer suggests citing specific papers.
**Template:**
```
We thank the reviewer for bringing these important references to
our attention. We have now cited [Author et al., Year] and
[Author et al., Year] in the [section/context] (Page X, Lines Y-Z).
These papers indeed support our [argument/finding/approach] by [brief
explanation of relevance].
```
---
### 6. Clarification Requests
**When to use:** The reviewer asks for clarification on methodology, results, or interpretation.
**Template:**
```
We apologize for the lack of clarity regarding [topic]. We have
revised the text to provide a clearer explanation. Specifically,
[detailed clarification] (Page X, Lines Y-Z). We hope this revision
adequately addresses the reviewer's concern.
```
---
### 7. Major Concerns (Methodology, Validity)
**When to use:** Addressing fundamental concerns about the study design or conclusions.
**If making changes:**
```
We are grateful to the reviewer for raising this important concern.
We acknowledge that our original [method/analysis/conclusion] was
[problematic/limitation]. We have [describe major changes made].
These revisions have [impact on results/conclusions], which we have
fully updated throughout the manuscript (Pages X-Y).
```
**If defending:**
```
We thank the reviewer for this important concern regarding [topic].
We have carefully reconsidered our approach and would like to provide
the following clarification: [detailed explanation]. We believe our
[method/approach/conclusion] is appropriate because [rationale with
supporting evidence]. To address this concern, we have added a more
detailed explanation in [section] (Page X, Lines Y-Z).
```
---
## Tone Adjustments
### From Defensive to Diplomatic
| Defensive ❌ | Diplomatic ✅ |
|-------------|---------------|
| We already explained this... | We apologize for the lack of clarity. We have now... |
| This is not correct... | We respectfully note that... |
| We don't think this is necessary... | Upon careful consideration, we have maintained... |
| The reviewer misunderstood... | We apologize if our explanation was unclear. We have revised... |
### Emphasis Modifiers
Use these to adjust the strength of your response:
**Strong agreement:**
- "We completely agree..."
- "This is an excellent point..."
- "We are grateful for this insight..."
**Moderate agreement:**
- "We thank the reviewer for this suggestion..."
- "We appreciate this observation..."
- "This is a valuable comment..."
**Respectful disagreement:**
- "We respectfully maintain..."
- "Upon careful consideration..."
- "We believe our approach remains appropriate..."
---
## Special Cases
### Multiple Reviewers with Conflicting Suggestions
```
We thank both Reviewers for their suggestions regarding [topic].
Reviewer #1 suggested [approach A], while Reviewer #2 suggested
[approach B]. After careful consideration of both perspectives,
we have [chosen approach/decision]. We believe this approach best
addresses the concerns raised while [additional rationale].
```
### Revisions Beyond Scope
```
We thank the reviewer for this ambitious suggestion. While we agree
that [extended analysis] would be valuable, this extends beyond the
scope of the current study, which focuses on [current scope]. We have
added a note about this potential extension as future work in the
Discussion section (Page X, Lines Y-Z).
```
```
### references/tone_guide.md
```markdown
# Academic Tone Guidelines
## Overview
Academic response letters require a specific tone that balances professionalism, gratitude, and scholarly confidence. This guide helps maintain appropriate tone throughout your response.
## Core Principles
### 1. Gratitude First
Always begin responses with appreciation, regardless of the comment's nature.
**Formula:**
- "We thank the reviewer for..."
- "We appreciate the reviewer's..."
- "We are grateful for..."
### 2. Passive vs Active Voice
Use **active voice** for clarity about what YOU did:
- ✅ "We have revised..."
- ✅ "We added..."
- ❌ "It was decided that revisions would be made..."
Use **passive voice** sparingly, mainly for objective statements:
- "This was addressed by..."
### 3. Modal Verbs for Politeness
Use modal verbs to soften statements while maintaining authority:
| Direct | Polished |
|--------|----------|
| "This is wrong" | "This may benefit from clarification" |
| "We rejected this" | "We respectfully maintained our approach" |
| "You misunderstood" | "We apologize if our explanation was unclear" |
## Tone Levels
### Diplomatic (Default Recommended)
**Characteristics:**
- Warm but professional
- Humble yet confident
- Collaborative spirit
**Phrases:**
- "We thank the reviewer for this valuable suggestion."
- "We appreciate the reviewer's insightful comment."
- "This is an excellent point that we have now addressed."
- "We have carefully considered this suggestion."
**Best for:**
- Most journal revisions
- Early career researchers
- When uncertain about editor preferences
### Formal
**Characteristics:**
- More detached and objective
- Emphasizes scholarly tradition
- Higher register vocabulary
**Phrases:**
- "The authors wish to thank..."
- "The manuscript has been revised accordingly..."
- "This concern has been addressed..."
- "The authors maintain that..."
**Best for:**
- High-impact journals (Nature, Science)
- When addressing major methodological concerns
- Establishing authority in contentious areas
### Assertive
**Characteristics:**
- Direct and confident
- Minimal hedging
- Clear about decisions
**Phrases:**
- "We maintain that..."
- "Our analysis shows..."
- "We have retained..."
- "The evidence supports..."
**Best for:**
- Defending against incorrect criticisms
- When reviewer suggestions would harm the work
- Established researchers with strong track records
**Warning:** Use sparingly. When in doubt, default to diplomatic.
## Language Patterns to Avoid
### Emotional Language
❌ **Avoid:**
- "We were disappointed that..."
- "Unfortunately, we cannot..."
- "Sadly, this is not possible..."
✅ **Instead:**
- "We note that..."
- "Due to [constraint], we are unable to..."
- "This falls outside the scope of..."
### Defensive Language
❌ **Avoid:**
- "As we clearly stated..."
- "The reviewer missed that..."
- "Obviously,..."
- "Anyone familiar with the field would know..."
✅ **Instead:**
- "We have now clarified..."
- "We apologize if this was not clear..."
- "We have added an explanation..."
- "We have expanded the background to include..."
### Over-apologetic Language
❌ **Avoid:**
- "We are terribly sorry..."
- "We deeply regret..."
- "Please forgive us for..."
✅ **Instead:**
- "We apologize for..."
- "We have corrected..."
- "Thank you for catching this..."
## Structural Flow
### Standard Response Flow
1. **Acknowledge** (gratitude)
2. **Action** (what you did)
3. **Locate** (where to find it)
4. **Rationale** (if needed, brief and objective)
### Example Flows
**Simple acceptance:**
> Acknowledge → Action → Locate
>
> "We thank the reviewer for this suggestion. We have added the requested analysis (Page 5, Lines 20-30)."
**With rationale:**
> Acknowledge → Action → Rationale → Locate
>
> "We thank the reviewer for this comment. We have maintained our original approach, as the proposed alternative would [objective reason]. We have added a note explaining this choice (Page 8, Lines 45-50)."
## Cultural Considerations
### Addressing Reviewers
- Use "the reviewer" (third person) in formal letters
- Use "Reviewer #1" when distinguishing multiple reviewers
- Never use first names or informal references
### Addressing the Editor
Always include the editor in salutations:
- "Dear Editor and Reviewers,"
- "Dear Dr. [Editor Name] and Reviewers,"
Never single out the editor for criticism or special pleading.
## Consistency Checklist
Before submitting, verify:
- [ ] All responses begin with gratitude
- [ ] No defensive or emotional language
- [ ] Consistent tense (past tense for completed revisions)
- [ ] All page/line references are accurate
- [ ] Tone is consistent throughout (no sudden shifts)
- [ ] Responses match the level of the comment (major comments get more detail)
- [ ] No contradictions between responses to different reviewers
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "aipoch-ai",
"slug": "peer-review-response-drafter",
"displayName": "Peer Review Response Drafter",
"latest": {
"version": "1.0.0",
"publishedAt": 1772260934389,
"commit": "https://github.com/openclaw/skills/commit/0f2a78fccc5d2536608e02e66c151f4442a0c03b"
},
"history": []
}
```
### scripts/main.py
```python
#!/usr/bin/env python3
"""
Peer Review Response Drafter
Assists researchers in drafting professional, polite, and structured
responses to peer reviewer comments for academic journal submissions.
Usage:
python main.py --input reviewer_comments.txt --journal "Nature" --output response.md
python main.py --interactive
"""
import argparse
import json
import re
import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import List, Optional, Dict
class ToneStyle(Enum):
"""Available tone styles for response drafting."""
DIPLOMATIC = "diplomatic"
FORMAL = "formal"
ASSERTIVE = "assertive"
@dataclass
class ReviewerComment:
"""Represents a single reviewer comment."""
reviewer_id: int
comment_id: str
text: str
is_major: bool = False
category: Optional[str] = None
@dataclass
class AuthorChange:
"""Represents an author's change in response to a comment."""
comment_ref: str
description: str
location: Optional[str] = None
@dataclass
class ResponseSection:
"""A drafted response to a reviewer comment."""
comment: ReviewerComment
change: Optional[AuthorChange]
response_text: str
class ResponseDrafter:
"""Main class for drafting peer review response letters."""
# Templates for different response scenarios
TEMPLATES = {
"accepted": {
"openers": [
"We thank the reviewer for this valuable suggestion.",
"We appreciate the reviewer's insightful comment.",
"Thank you for bringing this to our attention.",
"We are grateful for this constructive feedback."
],
"actions": [
"We have revised the manuscript accordingly.",
"This has been addressed in the revised version.",
"We have incorporated this suggestion.",
"The manuscript has been updated to reflect this."
]
},
"partial": {
"openers": [
"We thank the reviewer for this thoughtful suggestion.",
"We appreciate the reviewer's perspective on this matter.",
"Thank you for raising this important point."
],
"actions": [
"We have carefully considered this suggestion.",
"After careful evaluation, we have adopted a modified approach.",
"We have partially implemented this suggestion."
]
},
"declined": {
"openers": [
"We thank the reviewer for this suggestion.",
"We appreciate the reviewer's perspective.",
"Thank you for raising this point."
],
"actions": [
"Upon careful consideration, we have maintained our original approach.",
"We respectfully maintain our current formulation.",
"After careful evaluation, we believe our current approach is appropriate."
],
"rationales": [
"This is because",
"Our reasoning is that",
"This choice was made because"
]
}
}
def __init__(self, tone: ToneStyle = ToneStyle.DIPLOMATIC):
self.tone = tone
self.response_counter = 0
def parse_reviewer_comments(self, text: str) -> List[ReviewerComment]:
"""
Parse reviewer comments from text.
Supports various formats:
- "Reviewer 1:" or "Referee 1:"
- "R1:" or "R1."
- Numbered lists (1., 1), etc.)
"""
comments = []
# Pattern to detect reviewer sections
reviewer_pattern = r'(?:Reviewer|Referee)\s*#?\s*(\d+)[:.\s]'
# Split by reviewer headers
sections = re.split(reviewer_pattern, text, flags=re.IGNORECASE)
current_reviewer = 0
for i, section in enumerate(sections):
if section.isdigit():
current_reviewer = int(section)
continue
if current_reviewer == 0:
continue
# Extract individual comments (numbered items)
comment_pattern = r'(?:^|\n)\s*(\d+)[:.\)\]]\s*([^\n]+(?:\n(?!(?:^|\n)\s*\d+[:.\)\]])[^\n]+)*)'
comment_matches = re.findall(comment_pattern, section, re.MULTILINE)
if comment_matches:
for comment_num, comment_text in comment_matches:
comments.append(ReviewerComment(
reviewer_id=current_reviewer,
comment_id=comment_num,
text=comment_text.strip(),
is_major=self._is_major_comment(comment_text)
))
else:
# If no numbered comments, treat entire section as one comment
comments.append(ReviewerComment(
reviewer_id=current_reviewer,
comment_id="General",
text=section.strip(),
is_major=False
))
return comments
def _is_major_comment(self, text: str) -> bool:
"""Detect if a comment addresses a major issue."""
major_indicators = [
"major", "significant", "fundamental", "critical",
"essential", "important concern", "serious"
]
return any(indicator in text.lower() for indicator in major_indicators)
def draft_response(
self,
comment: ReviewerComment,
change: Optional[AuthorChange] = None,
rationale: Optional[str] = None
) -> ResponseSection:
"""Draft a response to a single reviewer comment."""
self.response_counter += 1
# Determine response type
if change is None:
response_type = "declined"
elif rationale:
response_type = "partial"
else:
response_type = "accepted"
templates = self.TEMPLATES[response_type]
# Build response
opener = templates["openers"][(self.response_counter - 1) % len(templates["openers"])]
action = templates["actions"][(self.response_counter - 1) % len(templates["actions"])]
response_parts = [opener]
if response_type == "accepted":
if change and change.description:
response_parts.append(f"{action} {change.description}")
else:
response_parts.append(action)
if change and change.location:
response_parts.append(f"({change.location})")
elif response_type == "partial":
response_parts.append(action)
if change and change.description:
response_parts.append(change.description)
if rationale:
response_parts.append(rationale)
if change and change.location:
response_parts.append(f"({change.location})")
elif response_type == "declined":
response_parts.append(action)
if rationale:
rationale_opener = templates["rationales"][0]
response_parts.append(f"{rationale_opener} {rationale}")
response_text = " ".join(response_parts)
return ResponseSection(
comment=comment,
change=change,
response_text=response_text
)
def generate_full_letter(
self,
responses: List[ResponseSection],
manuscript_title: str,
journal_name: str,
authors: Optional[str] = None
) -> str:
"""Generate a complete response letter."""
# Group responses by reviewer
by_reviewer: Dict[int, List[ResponseSection]] = {}
for resp in responses:
reviewer_id = resp.comment.reviewer_id
if reviewer_id not in by_reviewer:
by_reviewer[reviewer_id] = []
by_reviewer[reviewer_id].append(resp)
# Build letter
lines = [
"Dear Editor and Reviewers,",
"",
f'Thank you for your constructive feedback on our manuscript titled '
f'"{manuscript_title}" submitted to {journal_name}. We have carefully '
'addressed all comments and revised the manuscript accordingly. Below is '
"our point-by-point response to each reviewer's comments.",
""
]
# Add responses by reviewer
for reviewer_id in sorted(by_reviewer.keys()):
lines.append(f"## Reviewer #{reviewer_id}")
lines.append("")
for resp in by_reviewer[reviewer_id]:
lines.append(f"**Comment {resp.comment.comment_id}:** {resp.comment.text}")
lines.append("")
lines.append(f"**Response:** {resp.response_text}")
lines.append("")
# Closing
lines.extend([
"---",
"",
"We hope that our revisions satisfactorily address all the reviewers' concerns. "
"We are grateful for the opportunity to improve our manuscript.",
"",
"Sincerely,",
"",
authors or "[Author Names]"
])
return "\n".join(lines)
def adjust_tone(self, text: str, target_tone: ToneStyle) -> str:
"""Adjust the tone of a drafted response."""
tone_adjustments = {
ToneStyle.FORMAL: {
"We thank": "The authors wish to thank",
"have revised": "have revised and updated",
"added": "incorporated"
},
ToneStyle.ASSERTIVE: {
"We respectfully": "We",
"Upon careful consideration": "After evaluation",
"we believe": "we maintain that"
}
}
adjusted = text
if target_tone in tone_adjustments:
for original, replacement in tone_adjustments[target_tone].items():
adjusted = adjusted.replace(original, replacement)
return adjusted
def interactive_mode():
"""Run in interactive mode to collect input from user."""
print("=" * 60)
print("Peer Review Response Drafter - Interactive Mode")
print("=" * 60)
print()
# Collect manuscript info
title = input("Manuscript title: ").strip()
journal = input("Journal name: ").strip()
authors = input("Author names (comma-separated): ").strip()
print("\nTone preference:")
print("1. Diplomatic (recommended)")
print("2. Formal")
print("3. Assertive")
tone_choice = input("Select (1-3): ").strip()
tone_map = {"1": ToneStyle.DIPLOMATIC, "2": ToneStyle.FORMAL, "3": ToneStyle.ASSERTIVE}
tone = tone_map.get(tone_choice, ToneStyle.DIPLOMATIC)
# Collect reviewer comments
print("\n" + "=" * 60)
print("Paste reviewer comments below.")
print("Format: Reviewer 1: then numbered comments")
print("Type 'END' on a new line when finished:")
print("=" * 60)
lines = []
while True:
line = input()
if line.strip() == "END":
break
lines.append(line)
comments_text = "\n".join(lines)
# Process
drafter = ResponseDrafter(tone=tone)
comments = drafter.parse_reviewer_comments(comments_text)
print(f"\nFound {len(comments)} comments from {len(set(c.reviewer_id for c in comments))} reviewer(s).")
# Collect changes
changes = {}
print("\n" + "=" * 60)
print("For each comment, describe what you changed (or leave blank if no change):")
print("=" * 60)
for comment in comments:
print(f"\nReviewer {comment.reviewer_id}, Comment {comment.comment_id}:")
print(f" {comment.text[:100]}{'...' if len(comment.text) > 100 else ''}")
change_desc = input(" Your change: ").strip()
if change_desc:
location = input(" Location (e.g., 'Page 5, Lines 120-135'): ").strip()
changes[f"{comment.reviewer_id}.{comment.comment_id}"] = AuthorChange(
comment_ref=f"{comment.reviewer_id}.{comment.comment_id}",
description=change_desc,
location=location if location else None
)
# Generate responses
responses = []
for comment in comments:
change = changes.get(f"{comment.reviewer_id}.{comment.comment_id}")
response = drafter.draft_response(comment, change)
responses.append(response)
# Generate full letter
letter = drafter.generate_full_letter(responses, title, journal, authors)
print("\n" + "=" * 60)
print("GENERATED RESPONSE LETTER:")
print("=" * 60)
print(letter)
# Save option
save = input("\nSave to file? (filename or 'n'): ").strip()
if save and save.lower() != 'n':
with open(save, 'w') as f:
f.write(letter)
print(f"Saved to {save}")
def main():
parser = argparse.ArgumentParser(
description="Draft professional peer review response letters"
)
parser.add_argument(
"--input", "-i",
help="Input file containing reviewer comments"
)
parser.add_argument(
"--output", "-o",
help="Output file for the response letter"
)
parser.add_argument(
"--title", "-t",
required=True,
help="Manuscript title"
)
parser.add_argument(
"--journal", "-j",
required=True,
help="Journal name"
)
parser.add_argument(
"--authors", "-a",
help="Author names"
)
parser.add_argument(
"--tone",
choices=["diplomatic", "formal", "assertive"],
default="diplomatic",
help="Response tone (default: diplomatic)"
)
parser.add_argument(
"--interactive",
action="store_true",
help="Run in interactive mode"
)
args = parser.parse_args()
if args.interactive or (not args.input and sys.stdin.isatty()):
interactive_mode()
return
# Read input
if args.input:
with open(args.input, 'r') as f:
comments_text = f.read()
else:
comments_text = sys.stdin.read()
# Process
tone_map = {
"diplomatic": ToneStyle.DIPLOMATIC,
"formal": ToneStyle.FORMAL,
"assertive": ToneStyle.ASSERTIVE
}
drafter = ResponseDrafter(tone=tone_map[args.tone])
comments = drafter.parse_reviewer_comments(comments_text)
# For command-line mode, generate placeholder responses
responses = []
for comment in comments:
response = drafter.draft_response(comment, None)
responses.append(response)
letter = drafter.generate_full_letter(
responses, args.title, args.journal, args.authors
)
# Apply tone adjustment
letter = drafter.adjust_tone(letter, tone_map[args.tone])
# Output
if args.output:
with open(args.output, 'w') as f:
f.write(letter)
print(f"Response letter saved to {args.output}")
else:
print(letter)
if __name__ == "__main__":
main()
```