ComfyUI/custom_nodes/research/review_map.py
2026-04-12 18:10:53 +08:00

99 lines
3.5 KiB
Python

# custom_nodes/research/review_map.py
"""ReviewMap node - map review items to manuscript sections/claims."""
import json
from typing_extensions import override
from comfy_api.latest import ComfyNode, io
class ReviewMap(io.ComfyNode):
"""Map review items to claims, sections, and figures in the manuscript."""
@classmethod
def define_schema(cls) -> io.Schema:
return io.Schema(
node_id="ReviewMap",
display_name="Map to Manuscript",
category="Research",
inputs=[
io.String.Input(
"classified_items",
display_name="Classified Items (JSON)",
default="{}",
multiline=True,
),
io.String.Input(
"manuscript_sections",
display_name="Manuscript Sections (JSON)",
default="[]",
multiline=True,
),
io.String.Input(
"claims",
display_name="Claims (JSON)",
default="[]",
multiline=True,
),
],
outputs=[
io.String.Output(display_name="Item Mappings (JSON)"),
],
)
@classmethod
def execute(cls, classified_items: str, manuscript_sections: str, claims: str) -> io.NodeOutput:
try:
data = json.loads(classified_items) if classified_items else {}
items = data.get("items", [])
except json.JSONDecodeError:
items = []
try:
sections = json.loads(manuscript_sections) if manuscript_sections else []
except json.JSONDecodeError:
sections = []
try:
claims_list = json.loads(claims) if claims else []
except json.JSONDecodeError:
claims_list = []
mappings = []
for item in items:
item_text = item.get("text", "").lower()
item_type = item.get("type", "general")
# Find related claims
related_claims = []
for claim in claims_list:
claim_text = claim.get("text", "").lower()
# Simple keyword overlap
item_words = set(item_text.split())
claim_words = set(claim_text.split())
overlap = item_words & claim_words
if len(overlap) >= 3:
related_claims.append(claim.get("text", "")[:100])
# Find target section
target_section = item.get("target_section", "General")
mapping = {
"item_id": item.get("id"),
"item_text": item.get("text", ""),
"severity": item.get("severity"),
"target_section": target_section,
"related_claims": related_claims[:3],
"requires_citation": "citation" in item_text or "cite" in item_text,
"requires_experiment": any(w in item_text for w in ["experiment", "ablation", "baseline", "comparison"]),
"response_strategy": item.get("action", "consider"),
}
mappings.append(mapping)
result = {
"total_mappings": len(mappings),
"requires_revision": len([m for m in mappings if m["requires_experiment"]]),
"requires_citation": len([m for m in mappings if m["requires_citation"]]),
"mappings": mappings,
}
return io.NodeOutput(item_mappings=json.dumps(result, indent=2))