mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-15 04:52:31 +08:00
feat: add EvidenceGapDetect and ActionRoute nodes
This commit is contained in:
parent
0a7eb94ebc
commit
810756ecd6
114
custom_nodes/research/action_route.py
Normal file
114
custom_nodes/research/action_route.py
Normal file
@ -0,0 +1,114 @@
|
||||
"""ActionRoute node - route gaps to appropriate response actions."""
|
||||
import json
|
||||
from typing_extensions import override
|
||||
from comfy_api.latest import ComfyNode, io
|
||||
|
||||
|
||||
class ActionRoute(io.ComfyNode):
|
||||
"""Route review gaps to Respond/Revise/Citation/Experiment actions."""
|
||||
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="ActionRoute",
|
||||
display_name="Route Actions",
|
||||
category="Research",
|
||||
inputs=[
|
||||
io.String.Input(
|
||||
"gap_report",
|
||||
display_name="Gap Report (JSON)",
|
||||
default="{}",
|
||||
multiline=True,
|
||||
),
|
||||
],
|
||||
outputs=[
|
||||
io.String.Output(display_name="Action Routes (JSON)"),
|
||||
],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, gap_report: str) -> io.NodeOutput:
|
||||
try:
|
||||
data = json.loads(gap_report) if gap_report else {}
|
||||
gaps = data.get("gaps", [])
|
||||
except json.JSONDecodeError:
|
||||
gaps = []
|
||||
|
||||
routes = []
|
||||
|
||||
for gap in gaps:
|
||||
gap_type = gap.get("gap_type", "")
|
||||
suggested_action = gap.get("suggested_action", "")
|
||||
|
||||
# Determine route
|
||||
if gap_type == "missing_experiment" or suggested_action == "add_experiment":
|
||||
route = {
|
||||
"gap_id": gap.get("gap_id"),
|
||||
"action_type": "experiment",
|
||||
"route": "perform_experiment",
|
||||
"description": f"Perform additional experiments to address: {gap.get('description', '')[:80]}...",
|
||||
"estimated_effort": "high",
|
||||
"action_items": [
|
||||
"Design experiment protocol",
|
||||
"Run experiments",
|
||||
"Analyze results",
|
||||
"Update manuscript",
|
||||
],
|
||||
}
|
||||
elif gap_type == "missing_citation" or suggested_action == "add_citation":
|
||||
route = {
|
||||
"gap_id": gap.get("gap_id"),
|
||||
"action_type": "citation",
|
||||
"route": "add_citation",
|
||||
"description": f"Add citation to address: {gap.get('description', '')[:80]}...",
|
||||
"estimated_effort": "low",
|
||||
"action_items": [
|
||||
"Search for relevant papers",
|
||||
"Add citations",
|
||||
"Update reference list",
|
||||
],
|
||||
}
|
||||
elif suggested_action == "strengthen_argument":
|
||||
route = {
|
||||
"gap_id": gap.get("gap_id"),
|
||||
"action_type": "revise",
|
||||
"route": "revise_manuscript",
|
||||
"description": f"Revise manuscript to address: {gap.get('description', '')[:80]}...",
|
||||
"estimated_effort": "medium",
|
||||
"action_items": [
|
||||
"Rewrite affected sections",
|
||||
"Add supporting discussion",
|
||||
"Verify consistency",
|
||||
],
|
||||
}
|
||||
else:
|
||||
route = {
|
||||
"gap_id": gap.get("gap_id"),
|
||||
"action_type": "respond",
|
||||
"route": "write_response",
|
||||
"description": f"Write response to: {gap.get('description', '')[:80]}...",
|
||||
"estimated_effort": "medium",
|
||||
"action_items": [
|
||||
"Draft response text",
|
||||
"Gather supporting evidence",
|
||||
"Finalize response",
|
||||
],
|
||||
}
|
||||
|
||||
routes.append(route)
|
||||
|
||||
# Group by action type
|
||||
by_action = {
|
||||
"experiment": [r for r in routes if r["action_type"] == "experiment"],
|
||||
"citation": [r for r in routes if r["action_type"] == "citation"],
|
||||
"revise": [r for r in routes if r["action_type"] == "revise"],
|
||||
"respond": [r for r in routes if r["action_type"] == "respond"],
|
||||
}
|
||||
|
||||
result = {
|
||||
"total_routes": len(routes),
|
||||
"by_action": {k: len(v) for k, v in by_action.items()},
|
||||
"routes": routes,
|
||||
}
|
||||
|
||||
return io.NodeOutput(action_routes=json.dumps(result, indent=2))
|
||||
97
custom_nodes/research/evidence_gap_detect.py
Normal file
97
custom_nodes/research/evidence_gap_detect.py
Normal file
@ -0,0 +1,97 @@
|
||||
"""EvidenceGapDetect node - detect evidence gaps from review mappings."""
|
||||
import json
|
||||
from typing_extensions import override
|
||||
from comfy_api.latest import ComfyNode, io
|
||||
|
||||
|
||||
class EvidenceGapDetect(io.ComfyNode):
|
||||
"""Detect evidence gaps based on review item mappings."""
|
||||
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
return io.Schema(
|
||||
node_id="EvidenceGapDetect",
|
||||
display_name="Detect Evidence Gaps",
|
||||
category="Research",
|
||||
inputs=[
|
||||
io.String.Input(
|
||||
"item_mappings",
|
||||
display_name="Item Mappings (JSON)",
|
||||
default="{}",
|
||||
multiline=True,
|
||||
),
|
||||
],
|
||||
outputs=[
|
||||
io.String.Output(display_name="Gap Report (JSON)"),
|
||||
],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(cls, item_mappings: str) -> io.NodeOutput:
|
||||
try:
|
||||
data = json.loads(item_mappings) if item_mappings else {}
|
||||
mappings = data.get("mappings", [])
|
||||
except json.JSONDecodeError:
|
||||
mappings = []
|
||||
|
||||
gaps = []
|
||||
gap_id = 1
|
||||
|
||||
for mapping in mappings:
|
||||
severity = mapping.get("severity", 1)
|
||||
requires_experiment = mapping.get("requires_experiment", False)
|
||||
requires_citation = mapping.get("requires_citation", False)
|
||||
related_claims = mapping.get("related_claims", [])
|
||||
|
||||
# Check for evidence gaps
|
||||
if requires_experiment and len(related_claims) == 0:
|
||||
gaps.append({
|
||||
"gap_id": f"gap_{gap_id}",
|
||||
"item_id": mapping.get("item_id"),
|
||||
"gap_type": "missing_experiment",
|
||||
"severity": severity,
|
||||
"description": f"Review concern requires experimental evidence: {mapping.get('item_text', '')[:100]}...",
|
||||
"suggested_action": "add_experiment",
|
||||
"priority": "high" if severity >= 3 else "medium",
|
||||
})
|
||||
gap_id += 1
|
||||
|
||||
if requires_citation and len(related_claims) == 0:
|
||||
gaps.append({
|
||||
"gap_id": f"gap_{gap_id}",
|
||||
"item_id": mapping.get("item_id"),
|
||||
"gap_type": "missing_citation",
|
||||
"severity": severity,
|
||||
"description": f"Review concern requires citation to supporting work: {mapping.get('item_text', '')[:100]}...",
|
||||
"suggested_action": "add_citation",
|
||||
"priority": "medium",
|
||||
})
|
||||
gap_id += 1
|
||||
|
||||
# Check for unsupported high-severity claims
|
||||
if severity >= 3 and len(related_claims) == 0:
|
||||
gaps.append({
|
||||
"gap_id": f"gap_{gap_id}",
|
||||
"item_id": mapping.get("item_id"),
|
||||
"gap_type": "unsupported_major_claim",
|
||||
"severity": severity,
|
||||
"description": f"Major concern lacks supporting evidence: {mapping.get('item_text', '')[:100]}...",
|
||||
"suggested_action": "strengthen_argument",
|
||||
"priority": "high",
|
||||
})
|
||||
gap_id += 1
|
||||
|
||||
# Summarize
|
||||
gap_summary = {
|
||||
"total_gaps": len(gaps),
|
||||
"high_priority": len([g for g in gaps if g["priority"] == "high"]),
|
||||
"medium_priority": len([g for g in gaps if g["priority"] == "medium"]),
|
||||
"by_type": {
|
||||
"missing_experiment": len([g for g in gaps if g["gap_type"] == "missing_experiment"]),
|
||||
"missing_citation": len([g for g in gaps if g["gap_type"] == "missing_citation"]),
|
||||
"unsupported_major_claim": len([g for g in gaps if g["gap_type"] == "unsupported_major_claim"]),
|
||||
},
|
||||
"gaps": gaps,
|
||||
}
|
||||
|
||||
return io.NodeOutput(gap_report=json.dumps(gap_summary, indent=2))
|
||||
Loading…
Reference in New Issue
Block a user