Spaces:
Sleeping
Sleeping
Fix revision loop: add critique_details to AgentState
Browse filesBug: critique_details was not defined in AgentState TypedDict, causing
LangGraph to drop it between nodes. Revisions never triggered because
analyzer couldn't see critic's REJECTED status.
- Add critique_details: Optional[dict] to AgentState
- Add analyzer_revision_skipped: Optional[bool] to AgentState
- Add debug logging to trace state flow
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- src/nodes/analyzer.py +3 -0
- src/nodes/critic.py +3 -0
- src/state.py +3 -0
src/nodes/analyzer.py
CHANGED
|
@@ -1489,6 +1489,9 @@ def analyzer_node(state, workflow_id=None, progress_store=None):
|
|
| 1489 |
critique_details = state.get("critique_details", {})
|
| 1490 |
is_revision = bool(critique_details) and critique_details.get("status") == "REJECTED"
|
| 1491 |
|
|
|
|
|
|
|
|
|
|
| 1492 |
if is_revision and critique_details:
|
| 1493 |
# REVISION MODE: Use enhanced revision prompt with Critic feedback
|
| 1494 |
current_revision = state.get("revision_count", 0) + 1
|
|
|
|
| 1489 |
critique_details = state.get("critique_details", {})
|
| 1490 |
is_revision = bool(critique_details) and critique_details.get("status") == "REJECTED"
|
| 1491 |
|
| 1492 |
+
# Debug: Log critique details presence
|
| 1493 |
+
print(f"[DEBUG] Analyzer: critique_details={bool(critique_details)}, status={critique_details.get('status')}, is_revision={is_revision}")
|
| 1494 |
+
|
| 1495 |
if is_revision and critique_details:
|
| 1496 |
# REVISION MODE: Use enhanced revision prompt with Critic feedback
|
| 1497 |
current_revision = state.get("revision_count", 0) + 1
|
src/nodes/critic.py
CHANGED
|
@@ -560,6 +560,9 @@ def critic_node(state, workflow_id=None, progress_store=None):
|
|
| 560 |
"actionable_feedback": result.get("actionable_feedback", []),
|
| 561 |
}
|
| 562 |
|
|
|
|
|
|
|
|
|
|
| 563 |
# Update progress
|
| 564 |
if workflow_id and progress_store:
|
| 565 |
progress_store[workflow_id].update({
|
|
|
|
| 560 |
"actionable_feedback": result.get("actionable_feedback", []),
|
| 561 |
}
|
| 562 |
|
| 563 |
+
# Debug: Log what's being set in critique_details
|
| 564 |
+
print(f"[DEBUG] Critic: Setting critique_details status={status}, score={weighted_score:.1f}")
|
| 565 |
+
|
| 566 |
# Update progress
|
| 567 |
if workflow_id and progress_store:
|
| 568 |
progress_store[workflow_id].update({
|
src/state.py
CHANGED
|
@@ -7,6 +7,7 @@ class AgentState(TypedDict):
|
|
| 7 |
raw_data: Optional[str]
|
| 8 |
draft_report: Optional[str]
|
| 9 |
critique: Optional[str]
|
|
|
|
| 10 |
revision_count: int
|
| 11 |
score: int
|
| 12 |
messages: List[str]
|
|
@@ -25,3 +26,5 @@ class AgentState(TypedDict):
|
|
| 25 |
# Metric reference for hallucination prevention (Layer 1)
|
| 26 |
metric_reference: Optional[dict] # {M01: {key, raw_value, formatted, as_of_date}, ...}
|
| 27 |
metric_reference_hash: Optional[str] # SHA256 hash for integrity verification
|
|
|
|
|
|
|
|
|
| 7 |
raw_data: Optional[str]
|
| 8 |
draft_report: Optional[str]
|
| 9 |
critique: Optional[str]
|
| 10 |
+
critique_details: Optional[dict] # Structured critique for revision loop
|
| 11 |
revision_count: int
|
| 12 |
score: int
|
| 13 |
messages: List[str]
|
|
|
|
| 26 |
# Metric reference for hallucination prevention (Layer 1)
|
| 27 |
metric_reference: Optional[dict] # {M01: {key, raw_value, formatted, as_of_date}, ...}
|
| 28 |
metric_reference_hash: Optional[str] # SHA256 hash for integrity verification
|
| 29 |
+
# Revision tracking
|
| 30 |
+
analyzer_revision_skipped: Optional[bool] # True if revision was skipped due to LLM failure
|