Spaces:
Sleeping
Sleeping
Add null checks for partial metrics and research result
Browse files- research_gateway.py: Skip None/invalid metrics in partial_metrics array
- researcher.py: Validate result is a valid dict before processing
Fixes: 'NoneType' object has no attribute 'get' error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- src/nodes/research_gateway.py +11 -7
- src/nodes/researcher.py +5 -0
src/nodes/research_gateway.py
CHANGED
|
@@ -135,16 +135,20 @@ async def wait_for_completion(
|
|
| 135 |
|
| 136 |
# Emit partial metrics during WORKING status
|
| 137 |
if status == "working" and progress_callback:
|
| 138 |
-
partial_metrics = task.get("partial_metrics", [])
|
| 139 |
for metric in partial_metrics:
|
|
|
|
|
|
|
|
|
|
| 140 |
# Create unique key to avoid duplicate emissions
|
| 141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
if metric_key not in emitted_metrics:
|
| 143 |
-
progress_callback(
|
| 144 |
-
metric.get("source"),
|
| 145 |
-
metric.get("metric"),
|
| 146 |
-
metric.get("value")
|
| 147 |
-
)
|
| 148 |
emitted_metrics.add(metric_key)
|
| 149 |
|
| 150 |
if status == "completed":
|
|
|
|
| 135 |
|
| 136 |
# Emit partial metrics during WORKING status
|
| 137 |
if status == "working" and progress_callback:
|
| 138 |
+
partial_metrics = task.get("partial_metrics", []) or []
|
| 139 |
for metric in partial_metrics:
|
| 140 |
+
# Skip None or invalid metrics
|
| 141 |
+
if not metric or not isinstance(metric, dict):
|
| 142 |
+
continue
|
| 143 |
# Create unique key to avoid duplicate emissions
|
| 144 |
+
source = metric.get("source")
|
| 145 |
+
metric_name = metric.get("metric")
|
| 146 |
+
value = metric.get("value")
|
| 147 |
+
if not source or not metric_name:
|
| 148 |
+
continue
|
| 149 |
+
metric_key = f"{source}:{metric_name}:{value}"
|
| 150 |
if metric_key not in emitted_metrics:
|
| 151 |
+
progress_callback(source, metric_name, value)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
emitted_metrics.add(metric_key)
|
| 153 |
|
| 154 |
if status == "completed":
|
src/nodes/researcher.py
CHANGED
|
@@ -91,6 +91,11 @@ def researcher_node(state, workflow_id=None, progress_store=None):
|
|
| 91 |
progress_callback=progress_callback,
|
| 92 |
add_log=add_log
|
| 93 |
))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
state["data_source"] = "a2a"
|
| 95 |
# Note: Metrics are streamed via partial_metrics during A2A polling
|
| 96 |
|
|
|
|
| 91 |
progress_callback=progress_callback,
|
| 92 |
add_log=add_log
|
| 93 |
))
|
| 94 |
+
|
| 95 |
+
# Validate result
|
| 96 |
+
if not result or not isinstance(result, dict):
|
| 97 |
+
raise RuntimeError(f"Research Service returned invalid data for {company}")
|
| 98 |
+
|
| 99 |
state["data_source"] = "a2a"
|
| 100 |
# Note: Metrics are streamed via partial_metrics during A2A polling
|
| 101 |
|