feat: Enhance review process with streaming events and detailed logging

This commit is contained in:
Primakov Alexandr Alexandrovich
2025-10-13 17:26:41 +03:00
parent a762d09b3b
commit 2f29ccff74
10 changed files with 309 additions and 205 deletions

View File

@@ -526,7 +526,11 @@ class ReviewerAgent:
on_event: callable = None
) -> Dict[str, Any]:
"""Run the review workflow with streaming events"""
print(f"\n{'='*80}")
print(f"🎬 Starting review stream for PR #{pr_number}")
print(f" Review ID: {review_id}")
print(f" Callback: {on_event is not None}")
print(f"{'='*80}\n")
# Store callback in instance for access in nodes
self._stream_callback = on_event
@@ -545,9 +549,10 @@ class ReviewerAgent:
final_state = None
event_count = 0
callback_count = 0
# Stream through the graph
print(f"📊 Starting graph stream with mode=['updates']")
print(f"📊 Starting graph.astream() with mode=['updates']\n")
try:
async for event in self.graph.astream(
@@ -555,33 +560,59 @@ class ReviewerAgent:
stream_mode=["updates"]
):
event_count += 1
print(f"📨 Event #{event_count} received from graph")
print(f" Type: {type(event)}")
print(f" Event content: {event}")
print(f"\n{''*80}")
print(f"📨 STREAM Event #{event_count}")
print(f" Type: {type(event).__name__}")
print(f" Is tuple: {isinstance(event, tuple)}")
print(f" Content: {event}")
print(f"{''*80}")
# LangGraph returns events as dict: {node_name: node_output}
if isinstance(event, dict):
for node_name, node_data in event.items():
print(f" 🔔 Node update: {node_name}")
print(f" 🔔 Node data type: {type(node_data)}")
if on_event:
print(f" 📤 Sending event to callback for node: {node_name}")
await on_event({
"type": "agent_step",
"step": node_name,
"message": f"Шаг: {node_name}",
"data": {
"status": node_data.get("status") if isinstance(node_data, dict) else None
}
})
# Store final state
if isinstance(node_data, dict):
final_state = node_data
# LangGraph returns events as tuple: ('updates', {node_name: node_output})
if isinstance(event, tuple) and len(event) == 2:
event_type, event_data = event[0], event[1]
print(f"✓ Tuple detected:")
print(f" [0] event_type: '{event_type}'")
print(f" [1] event_data type: {type(event_data).__name__}")
# Handle 'updates' events
if event_type == 'updates' and isinstance(event_data, dict):
print(f"✓ Updates event with dict data")
for node_name, node_state in event_data.items():
print(f"\n 🔔 Node: '{node_name}'")
print(f" State type: {type(node_state).__name__}")
if on_event:
callback_count += 1
print(f" 📤 Calling callback #{callback_count}...")
try:
await on_event({
"type": "agent_step",
"step": node_name,
"message": f"Шаг: {node_name}",
"data": {
"status": node_state.get("status") if isinstance(node_state, dict) else None
}
})
print(f" ✓ Callback executed successfully")
except Exception as e:
print(f" ❌ Callback error: {e}")
import traceback
traceback.print_exc()
else:
print(f" ⚠️ No callback set!")
# Store final state
if isinstance(node_state, dict):
final_state = node_state
else:
print(f" ⚠️ Not an 'updates' event or data is not dict")
print(f" event_type={event_type}, isinstance(event_data, dict)={isinstance(event_data, dict)}")
else:
print(f" ⚠️ Unexpected event format (not dict): {type(event)}")
print(f" ❌ NOT a tuple or wrong length!")
print(f" isinstance(event, tuple)={isinstance(event, tuple)}")
if isinstance(event, tuple):
print(f" len(event)={len(event)}")
except Exception as e:
print(f"❌ Error in graph streaming: {e}")