mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-27 08:28:00 +00:00
* fix(streaming): expose custom events to astream_events * test(streaming): validate real custom event emitters --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
"""Compatibility helpers for DeerFlow custom stream events."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from collections.abc import Callable
|
|
from typing import Any
|
|
|
|
from langchain_core.callbacks import adispatch_custom_event, dispatch_custom_event
|
|
from langgraph.errors import GraphBubbleUp
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
StreamWriter = Callable[[Any], None]
|
|
|
|
|
|
def _event_name(payload: dict[str, Any]) -> str | None:
|
|
event_type = payload.get("type")
|
|
if isinstance(event_type, str) and event_type:
|
|
return event_type
|
|
logger.debug("Custom stream payload has no non-empty string 'type'; skipping callback dispatch")
|
|
return None
|
|
|
|
|
|
def emit_custom_event(payload: dict[str, Any], *, writer: StreamWriter) -> None:
|
|
"""Emit one event to LangGraph's custom stream and callback APIs.
|
|
|
|
The writer remains the primary compatibility path. Callback dispatch is
|
|
best-effort so an optional ``astream_events`` consumer cannot break an
|
|
existing DeerFlow run.
|
|
"""
|
|
|
|
writer(payload)
|
|
event_name = _event_name(payload)
|
|
if event_name is None:
|
|
return
|
|
try:
|
|
dispatch_custom_event(event_name, payload)
|
|
except GraphBubbleUp:
|
|
raise
|
|
except Exception:
|
|
logger.debug("Failed to dispatch custom callback event %s", event_name, exc_info=True)
|
|
|
|
|
|
async def aemit_custom_event(payload: dict[str, Any], *, writer: StreamWriter) -> None:
|
|
"""Async counterpart to :func:`emit_custom_event`."""
|
|
|
|
writer(payload)
|
|
event_name = _event_name(payload)
|
|
if event_name is None:
|
|
return
|
|
try:
|
|
await adispatch_custom_event(event_name, payload)
|
|
except GraphBubbleUp:
|
|
raise
|
|
except Exception:
|
|
logger.debug("Failed to dispatch async custom callback event %s", event_name, exc_info=True)
|