Feats: Works mostly end to end and now prints full paper content as first step in the paper_review stage
This commit is contained in:
@@ -1079,9 +1079,14 @@ agents:
|
||||
- Work with the user to refine the content based on their feedback
|
||||
- If the user asks for changes, make them and present the revised content
|
||||
|
||||
IMPORTANT: When the user is satisfied with the section content, tell them to type !proofread to proceed to proofreading.
|
||||
RESPONSE FORMAT (MANDATORY):
|
||||
SECTION_CONTENT:
|
||||
<final section text>
|
||||
|
||||
Example ending: "Let me know if you'd like any changes. When you're satisfied, type !proofread to proceed to proofreading."
|
||||
NEXT_ACTION:
|
||||
Type !proofread when you are satisfied with this section.
|
||||
|
||||
Do NOT include any other commentary, explanations, or conversational text. The SECTION_CONTENT block must contain only the section prose that will be stored in the paper.
|
||||
|
||||
section_writer_saver:
|
||||
type: tool
|
||||
@@ -1092,9 +1097,20 @@ agents:
|
||||
path = context.get('current_section_path', 'unknown')
|
||||
# Only save actual content, not routing commands
|
||||
if input_data and not input_data.startswith('GOTO_'):
|
||||
context.setdefault('section_content', {})[path] = input_data
|
||||
context.setdefault('section_drafts', {})[path] = input_data
|
||||
context['last_written_section_content'] = input_data
|
||||
text = input_data.strip()
|
||||
section_text = text
|
||||
marker = 'SECTION_CONTENT:'
|
||||
if marker in text:
|
||||
remainder = text.split(marker, 1)[1]
|
||||
next_marker = 'NEXT_ACTION:'
|
||||
if next_marker in remainder:
|
||||
section_text = remainder.split(next_marker, 1)[0].strip()
|
||||
else:
|
||||
section_text = remainder.strip()
|
||||
if section_text:
|
||||
context.setdefault('section_content', {})[path] = section_text
|
||||
context.setdefault('section_drafts', {})[path] = section_text
|
||||
context['last_written_section_content'] = section_text
|
||||
result = input_data
|
||||
|
||||
section_accept_handler:
|
||||
@@ -1191,95 +1207,26 @@ agents:
|
||||
import sys
|
||||
print(f"DEBUG paper_review_controller", file=sys.stderr)
|
||||
|
||||
def looks_like_feedback(text: str) -> bool:
|
||||
if not isinstance(text, str):
|
||||
return False
|
||||
lowered = text.lower()
|
||||
markers = [
|
||||
"proofread",
|
||||
"proofreading",
|
||||
"grammatical errors",
|
||||
"type !accept",
|
||||
"command_output:",
|
||||
"review feedback",
|
||||
]
|
||||
return any(marker in lowered for marker in markers)
|
||||
|
||||
history_messages = None
|
||||
for key in ("__messages", "history", "conversation_history", "messages"):
|
||||
value = context.get(key)
|
||||
if isinstance(value, list):
|
||||
history_messages = value
|
||||
break
|
||||
if history_messages is None:
|
||||
graph_state = context.get('graph_state', {})
|
||||
if isinstance(graph_state, dict):
|
||||
msgs = graph_state.get('messages')
|
||||
if isinstance(msgs, list):
|
||||
history_messages = msgs
|
||||
if history_messages is None:
|
||||
history_messages = []
|
||||
|
||||
writer_history = {}
|
||||
current_section = None
|
||||
pending_writer_output = False
|
||||
for message in history_messages:
|
||||
if not isinstance(message, dict):
|
||||
continue
|
||||
role = (message.get('role') or '').lower()
|
||||
content = message.get('content')
|
||||
if not isinstance(content, str):
|
||||
continue
|
||||
stripped = content.strip()
|
||||
if role == 'assistant':
|
||||
if stripped.lower().startswith('now working on section:'):
|
||||
section_name = stripped.split(':', 1)[1].strip()
|
||||
if section_name:
|
||||
section_name = section_name.splitlines()[0].strip()
|
||||
current_section = section_name or current_section
|
||||
pending_writer_output = False
|
||||
elif pending_writer_output and current_section:
|
||||
writer_history[current_section] = content
|
||||
pending_writer_output = False
|
||||
elif role == 'user':
|
||||
if stripped.lower().startswith('!write'):
|
||||
pending_writer_output = True
|
||||
else:
|
||||
pending_writer_output = False
|
||||
|
||||
section_content = context.get('section_content', {})
|
||||
if not section_content:
|
||||
result = "ERROR: No sections found. Please complete section writing stage first."
|
||||
else:
|
||||
section_drafts = context.get('section_drafts', {})
|
||||
|
||||
# Build full paper text
|
||||
paper_topic = context.get('paper_details', {}).get('topic', 'Scientific Paper')
|
||||
full_text = f"# {paper_topic}\n\n"
|
||||
|
||||
# Add sections in order, repairing content when necessary
|
||||
section_paths = context.get('section_paths', [])
|
||||
for path in section_paths:
|
||||
text = section_content.get(path)
|
||||
if not text:
|
||||
replacement = section_drafts.get(path) or writer_history.get(path)
|
||||
if replacement:
|
||||
section_content[path] = replacement
|
||||
text = replacement
|
||||
elif looks_like_feedback(text):
|
||||
replacement = section_drafts.get(path) or writer_history.get(path)
|
||||
if replacement:
|
||||
section_content[path] = replacement
|
||||
text = replacement
|
||||
if text:
|
||||
full_text += f"## {path}\n\n{text}\n\n"
|
||||
if isinstance(text, str) and text.strip():
|
||||
full_text += f"## {path}\n\n{text.strip()}\n\n"
|
||||
|
||||
context['assembled_paper'] = full_text
|
||||
assembled = full_text.strip()
|
||||
context['assembled_paper'] = assembled
|
||||
|
||||
# Display the complete paper to the user before invoking the reviewer LLM
|
||||
preview_header = "# Full Paper\n"
|
||||
preview_body = full_text.strip()
|
||||
preview_output = f"{preview_header}\n{preview_body}" if preview_body else preview_header
|
||||
preview_output = (
|
||||
f"# Full Paper\n\n{assembled}" if assembled else "# Full Paper\n\n(No content available.)"
|
||||
)
|
||||
print(preview_output, flush=True)
|
||||
|
||||
instruction = (
|
||||
@@ -1298,28 +1245,27 @@ agents:
|
||||
max_history: 20
|
||||
system_prompt: |
|
||||
You are reviewing the complete assembled paper.
|
||||
|
||||
Here is the full paper content:
|
||||
|
||||
{{ context.get('assembled_paper', '') }}
|
||||
|
||||
|
||||
Here is the full paper content:
|
||||
|
||||
{{ context.get('assembled_paper', '') }}
|
||||
|
||||
The system already displayed the full paper verbatim before your turn.
|
||||
DO NOT repeat or summarize the paper content. Focus solely on analysis.
|
||||
Structure your response under a single top-level heading "Review Feedback" with clear bullets or subheadings.
|
||||
|
||||
When providing feedback, review the paper for:
|
||||
|
||||
- Consistency and logical flow between sections
|
||||
- Grammar, spelling, and style
|
||||
- Proper citation format and usage
|
||||
- Logical coherence and argument strength
|
||||
- Transitions between sections
|
||||
|
||||
Provide specific, actionable feedback tied to the relevant sections. The user can:
|
||||
- Discuss refinements to specific sections
|
||||
- Make changes across the document
|
||||
- Use !accept or !next when satisfied to proceed to LaTeX generation
|
||||
When providing feedback, review the paper for:
|
||||
|
||||
- Consistency and logical flow between sections
|
||||
- Grammar, spelling, and style
|
||||
- Proper citation format and usage
|
||||
- Logical coherence and argument strength
|
||||
- Transitions between sections
|
||||
|
||||
Provide specific, actionable feedback tied to the relevant sections. The user can:
|
||||
- Discuss refinements to specific sections
|
||||
- Make changes across the document
|
||||
- Use !accept or !next when satisfied to proceed to LaTeX generation
|
||||
|
||||
paper_review_saver:
|
||||
type: tool
|
||||
@@ -1330,6 +1276,7 @@ agents:
|
||||
context['reviewed_paper'] = input_data
|
||||
result = input_data
|
||||
|
||||
|
||||
# ============================================
|
||||
# LATEX GENERATION STAGE
|
||||
# ============================================
|
||||
@@ -1699,10 +1646,11 @@ routes:
|
||||
target: paper_review
|
||||
extract_message: true
|
||||
separator: ":"
|
||||
|
||||
|
||||
|
||||
|
||||
- match_type: prefix
|
||||
pattern: "GOTO_LATEX_GENERATION"
|
||||
|
||||
target: latex_generation
|
||||
extract_message: true
|
||||
separator: ":"
|
||||
@@ -1985,18 +1933,19 @@ routes:
|
||||
paper_review:
|
||||
type: AGENT
|
||||
agent: paper_review_controller
|
||||
|
||||
|
||||
paper_review_agent:
|
||||
type: AGENT
|
||||
agent: paper_review_agent
|
||||
metadata:
|
||||
max_history_messages: 10
|
||||
max_history_chars: 6000
|
||||
|
||||
|
||||
paper_review_saver:
|
||||
type: AGENT
|
||||
agent: paper_review_saver
|
||||
|
||||
|
||||
latex_generation:
|
||||
type: AGENT
|
||||
agent: latex_controller
|
||||
@@ -2208,6 +2157,13 @@ routes:
|
||||
value: section_accept_handler
|
||||
|
||||
# Paper review sub-routing
|
||||
- source: router
|
||||
target: paper_review
|
||||
condition:
|
||||
type: context_value
|
||||
key: next_node
|
||||
value: paper_review
|
||||
|
||||
- source: router
|
||||
target: paper_review_agent
|
||||
condition:
|
||||
@@ -2215,6 +2171,7 @@ routes:
|
||||
key: next_node
|
||||
value: paper_review_agent
|
||||
|
||||
|
||||
# LaTeX generation sub-routing
|
||||
- source: router
|
||||
target: latex_structure_gen
|
||||
|
||||
@@ -141,9 +141,6 @@ def run(
|
||||
context_manager = ContextManager(context, context_dir)
|
||||
context_manager.import_context(load_context)
|
||||
|
||||
if app.config:
|
||||
app.config.global_context["__messages"] = list(context_manager.messages)
|
||||
|
||||
# Restore the global context to the app
|
||||
saved_global_context = context_manager.get_global_context()
|
||||
if saved_global_context and app.config:
|
||||
@@ -173,11 +170,6 @@ def run(
|
||||
with open(load_context, "r", encoding="utf-8") as f:
|
||||
context_data = json.load(f)
|
||||
|
||||
if app.config:
|
||||
app.config.global_context["__messages"] = list(
|
||||
context_data.get("messages", [])
|
||||
)
|
||||
|
||||
# Apply global context to app if present
|
||||
if context_data.get("global_context") and app.config:
|
||||
app.config.global_context.update(context_data["global_context"])
|
||||
@@ -189,9 +181,6 @@ def run(
|
||||
# Use named context (existing behavior)
|
||||
context_manager = ContextManager(context, context_dir)
|
||||
|
||||
if app.config:
|
||||
app.config.global_context["__messages"] = list(context_manager.messages)
|
||||
|
||||
# If context exists, restore the global context to the app
|
||||
if context_manager.exists():
|
||||
saved_global_context = context_manager.get_global_context()
|
||||
@@ -312,11 +301,6 @@ def interactive(
|
||||
# Import the context from file
|
||||
temp_ctx_manager.import_context(load_context)
|
||||
|
||||
if app.config:
|
||||
app.config.global_context["__messages"] = list(
|
||||
temp_ctx_manager.messages
|
||||
)
|
||||
|
||||
# Apply global context to app if present
|
||||
saved_global_context = temp_ctx_manager.get_global_context()
|
||||
if saved_global_context and app.config:
|
||||
|
||||
Reference in New Issue
Block a user