mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-15 21:12:30 +08:00
129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
"""ConsistencyCheck node - check manuscript consistency."""
|
|
import json
|
|
import re
|
|
from typing_extensions import override
|
|
from comfy_api.latest import ComfyNode, io
|
|
|
|
|
|
class ConsistencyCheck(io.ComfyNode):
|
|
"""Check consistency between claims, text, numbers, and figures in manuscript."""
|
|
|
|
@classmethod
|
|
def define_schema(cls) -> io.Schema:
|
|
return io.Schema(
|
|
node_id="ConsistencyCheck",
|
|
display_name="Check Consistency",
|
|
category="Research",
|
|
inputs=[
|
|
io.String.Input(
|
|
"claims",
|
|
display_name="Claims (JSON)",
|
|
default="[]",
|
|
multiline=True,
|
|
),
|
|
io.String.Input(
|
|
"abstract",
|
|
display_name="Abstract Text",
|
|
default="",
|
|
multiline=True,
|
|
),
|
|
io.String.Input(
|
|
"methods",
|
|
display_name="Methods Text",
|
|
default="",
|
|
multiline=True,
|
|
),
|
|
io.String.Input(
|
|
"results",
|
|
display_name="Results Text",
|
|
default="",
|
|
multiline=True,
|
|
),
|
|
],
|
|
outputs=[
|
|
io.String.Output(display_name="Issues List (JSON)"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, claims: str, abstract: str, methods: str, results: str) -> io.NodeOutput:
|
|
try:
|
|
claims_list = json.loads(claims) if claims else []
|
|
except json.JSONDecodeError:
|
|
claims_list = []
|
|
|
|
issues = []
|
|
|
|
# Check 1: Claims mentioned in abstract should appear in results
|
|
for claim in claims_list:
|
|
claim_text = claim.get("text", "").lower()
|
|
claim_keywords = [w for w in claim_text.split() if len(w) > 4][:3]
|
|
|
|
if claim_keywords:
|
|
results_lower = results.lower()
|
|
keyword_matches = sum(1 for kw in claim_keywords if kw in results_lower)
|
|
|
|
if keyword_matches < len(claim_keywords) / 2:
|
|
issues.append({
|
|
"severity": "warning",
|
|
"type": "claim_not_in_results",
|
|
"message": f"Claim may not be supported in results: {claim.get('text', '')[:50]}...",
|
|
"claim_id": claim.get("id", "unknown"),
|
|
})
|
|
|
|
# Check 2: Numbers should be consistent across sections
|
|
full_text = f"{abstract} {methods} {results}"
|
|
numbers_found = re.findall(r'\b(\d+\.?\d*)%?\b', full_text)
|
|
|
|
if len(numbers_found) > 10:
|
|
issues.append({
|
|
"severity": "info",
|
|
"type": "many_numbers",
|
|
"message": f"Found {len(numbers_found)} numbers in text. Verify all are accurate.",
|
|
})
|
|
|
|
# Check 3: Abstract length
|
|
abstract_words = len(abstract.split())
|
|
if abstract_words > 300:
|
|
issues.append({
|
|
"severity": "warning",
|
|
"type": "abstract_too_long",
|
|
"message": f"Abstract is {abstract_words} words. Most venues prefer 150-250 words.",
|
|
})
|
|
elif abstract_words < 100:
|
|
issues.append({
|
|
"severity": "warning",
|
|
"type": "abstract_too_short",
|
|
"message": f"Abstract is only {abstract_words} words. Consider adding more detail.",
|
|
})
|
|
|
|
# Check 4: Claims without support level
|
|
unsupported_claims = [c for c in claims_list if c.get("support_level") == "unsupported"]
|
|
if len(unsupported_claims) > 3:
|
|
issues.append({
|
|
"severity": "error",
|
|
"type": "many_unsupported_claims",
|
|
"message": f"{len(unsupported_claims)} claims lack evidence support. Add experiments or citations.",
|
|
})
|
|
|
|
# Check 5: Section references
|
|
section_refs = re.findall(r'Section (\d+)', full_text)
|
|
if section_refs:
|
|
max_section = max(int(s) for s in section_refs if s.isdigit())
|
|
if max_section > 5:
|
|
issues.append({
|
|
"severity": "info",
|
|
"type": "section_references",
|
|
"message": f"References to Section {max_section} found. Verify all referenced sections exist.",
|
|
})
|
|
|
|
report = {
|
|
"total_issues": len(issues),
|
|
"errors": len([i for i in issues if i.get("severity") == "error"]),
|
|
"warnings": len([i for i in issues if i.get("severity") == "warning"]),
|
|
"info": len([i for i in issues if i.get("severity") == "info"]),
|
|
"issues": issues,
|
|
}
|
|
|
|
return io.NodeOutput(issues_list=json.dumps(report, indent=2))
|