Skip to content

Commit 04be4ee

Browse files
mrveissclaude
andauthored
fix(backend): load workflow notification_config from execution_context (#3168) (#3171)
Replace empty NotificationConfig with _resolve_notification_config() that reads notification_config from execution_context. Notifications now only fire when the workflow has a configured notification_config, preventing silent no-ops. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2983cc6 commit 04be4ee

1 file changed

Lines changed: 37 additions & 13 deletions

File tree

autobot-backend/orchestration/workflow_executor.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,35 @@ def _determine_workflow_status(
192192
execution_context["agents_involved"]
193193
)
194194

195+
def _resolve_notification_config(
196+
self, workflow_id: str, execution_context: Dict[str, Any]
197+
):
198+
"""Resolve the workflow's NotificationConfig (#3168).
199+
200+
Looks for ``notification_config`` in ``execution_context`` (injected
201+
by the workflow manager). Returns None when no config is present,
202+
which causes notification methods to skip silently.
203+
"""
204+
from services.notification_service import NotificationConfig
205+
206+
raw = execution_context.get("notification_config")
207+
if raw is None:
208+
return None
209+
if isinstance(raw, NotificationConfig):
210+
return raw
211+
if isinstance(raw, dict):
212+
return NotificationConfig(workflow_id=workflow_id, **raw)
213+
return None
214+
195215
async def _send_workflow_notification(
196216
self, workflow_id: str, execution_context: Dict[str, Any]
197217
) -> None:
198-
"""Fire a notification for a terminal workflow status (#3101)."""
199-
from services.notification_service import (
200-
NotificationConfig,
201-
NotificationEvent,
202-
)
218+
"""Fire a notification for a terminal workflow status (#3101, #3168)."""
219+
from services.notification_service import NotificationEvent
220+
221+
config = self._resolve_notification_config(workflow_id, execution_context)
222+
if config is None:
223+
return
203224

204225
status = execution_context.get("status", "")
205226
event_map = {
@@ -211,7 +232,6 @@ async def _send_workflow_notification(
211232
return
212233
try:
213234
svc = _get_notification_service()
214-
config = NotificationConfig(workflow_id=workflow_id)
215235
payload = {
216236
"workflow_id": workflow_id,
217237
"status": status,
@@ -227,17 +247,20 @@ async def _send_workflow_notification(
227247
)
228248

229249
async def _send_step_failure_notification(
230-
self, workflow_id: str, step_id: str, error: str
250+
self, workflow_id: str, step_id: str, error: str,
251+
execution_context: Optional[Dict[str, Any]] = None,
231252
) -> None:
232-
"""Fire a STEP_FAILED notification (#3101)."""
233-
from services.notification_service import (
234-
NotificationConfig,
235-
NotificationEvent,
253+
"""Fire a STEP_FAILED notification (#3101, #3168)."""
254+
from services.notification_service import NotificationEvent
255+
256+
config = self._resolve_notification_config(
257+
workflow_id, execution_context or {}
236258
)
259+
if config is None:
260+
return
237261

238262
try:
239263
svc = _get_notification_service()
240-
config = NotificationConfig(workflow_id=workflow_id)
241264
payload = {
242265
"workflow_id": workflow_id,
243266
"step_name": step_id,
@@ -330,12 +353,13 @@ async def _execute_step_with_agent(
330353
step["result"] = step_result
331354
execution_context["step_results"][step_id] = step_result
332355

333-
# Issue #3101: notify on step failure.
356+
# Issue #3101/#3168: notify on step failure.
334357
if not step_result.get("success"):
335358
await self._send_step_failure_notification(
336359
execution_context.get("workflow_id", ""),
337360
step_id,
338361
step_result.get("error", "unknown"),
362+
execution_context=execution_context,
339363
)
340364

341365
# Issue #2141: Record typed StepOutput so later steps can reference it.

0 commit comments

Comments
 (0)