mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-09 12:40:59 +00:00
fix(cloud): preserve pipeline routing in debug chat (#2380)
Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
This commit is contained in:
@@ -707,28 +707,37 @@ class WebSocketAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter)
|
|||||||
if len(listener_tasks) >= 100:
|
if len(listener_tasks) >= 100:
|
||||||
await self.logger.warning('WebSocket inbound listener capacity reached; dropping message')
|
await self.logger.warning('WebSocket inbound listener capacity reached; dropping message')
|
||||||
return
|
return
|
||||||
token = _current_pipeline_uuid.set(pipeline_uuid)
|
listener = typing.cast(
|
||||||
try:
|
typing.Callable[[typing.Any, typing.Any], typing.Awaitable[None]],
|
||||||
task_manager = getattr(self.ap, 'task_mgr', None)
|
listeners[event.__class__],
|
||||||
if task_manager is None or not isinstance(getattr(task_manager, 'tasks', None), list):
|
)
|
||||||
listener_task = asyncio.create_task(listeners[event.__class__](event, callback_adapter))
|
|
||||||
else:
|
async def run_listener():
|
||||||
listener_task = task_manager.create_task(
|
token = _current_pipeline_uuid.set(pipeline_uuid)
|
||||||
listeners[event.__class__](event, callback_adapter),
|
try:
|
||||||
kind='websocket-message',
|
await listener(event, callback_adapter)
|
||||||
name=f'websocket-message-{connection.connection_id}',
|
finally:
|
||||||
scopes=[
|
_current_pipeline_uuid.reset(token)
|
||||||
core_entities.LifecycleControlScope.APPLICATION,
|
|
||||||
core_entities.LifecycleControlScope.PLATFORM,
|
listener_coro = run_listener()
|
||||||
],
|
task_manager = getattr(self.ap, 'task_mgr', None)
|
||||||
instance_uuid=connection.instance_uuid,
|
if task_manager is None or not isinstance(getattr(task_manager, 'tasks', None), list):
|
||||||
workspace_uuid=connection.workspace_uuid,
|
listener_task = asyncio.create_task(listener_coro)
|
||||||
placement_generation=connection.placement_generation,
|
else:
|
||||||
).task
|
listener_task = task_manager.create_task(
|
||||||
listener_tasks.add(listener_task)
|
listener_coro,
|
||||||
listener_task.add_done_callback(self._listener_task_done)
|
kind='websocket-message',
|
||||||
finally:
|
name=f'websocket-message-{connection.connection_id}',
|
||||||
_current_pipeline_uuid.reset(token)
|
scopes=[
|
||||||
|
core_entities.LifecycleControlScope.APPLICATION,
|
||||||
|
core_entities.LifecycleControlScope.PLATFORM,
|
||||||
|
],
|
||||||
|
instance_uuid=connection.instance_uuid,
|
||||||
|
workspace_uuid=connection.workspace_uuid,
|
||||||
|
placement_generation=connection.placement_generation,
|
||||||
|
).task
|
||||||
|
listener_tasks.add(listener_task)
|
||||||
|
listener_task.add_done_callback(self._listener_task_done)
|
||||||
|
|
||||||
def get_websocket_messages(
|
def get_websocket_messages(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"""Regression tests for isolated embed-widget conversations."""
|
"""Regression tests for isolated embed-widget conversations."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import contextvars
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest.mock import AsyncMock, Mock
|
from unittest.mock import AsyncMock, Mock
|
||||||
|
|
||||||
@@ -204,6 +205,48 @@ async def test_embed_event_uses_stable_session_launcher(monkeypatch):
|
|||||||
assert received[0].sender.id == f'websocket_pipeline-1:{session_id}'
|
assert received[0].sender.id == f'websocket_pipeline-1:{session_id}'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_pipeline_override_survives_detached_listener_task(monkeypatch):
|
||||||
|
manager = WebSocketConnectionManager()
|
||||||
|
connection = await manager.add_connection(
|
||||||
|
websocket=Mock(),
|
||||||
|
scope=SCOPE_A,
|
||||||
|
pipeline_uuid='pipeline-1',
|
||||||
|
session_type='person',
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(websocket_adapter_module, 'ws_connection_manager', manager)
|
||||||
|
|
||||||
|
class DetachedTaskManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.tasks = []
|
||||||
|
|
||||||
|
def create_task(self, coro, **_kwargs):
|
||||||
|
task = asyncio.create_task(coro, context=contextvars.Context())
|
||||||
|
self.tasks.append(task)
|
||||||
|
return Mock(task=task)
|
||||||
|
|
||||||
|
task_manager = DetachedTaskManager()
|
||||||
|
adapter = WebSocketAdapter.model_construct(
|
||||||
|
ap=Mock(task_mgr=task_manager),
|
||||||
|
logger=_adapter_logger(),
|
||||||
|
)
|
||||||
|
adapter.websocket_person_session = WebSocketSession(id='person')
|
||||||
|
adapter.websocket_group_session = WebSocketSession(id='group')
|
||||||
|
pipeline_overrides = []
|
||||||
|
|
||||||
|
async def listener(_event, callback_adapter):
|
||||||
|
pipeline_overrides.append(callback_adapter.get_pipeline_uuid_override())
|
||||||
|
|
||||||
|
adapter.listeners = {platform_events.FriendMessage: listener}
|
||||||
|
await adapter.handle_websocket_message(
|
||||||
|
connection,
|
||||||
|
{'message': [{'type': 'Plain', 'text': 'hello'}], 'stream': False},
|
||||||
|
)
|
||||||
|
await asyncio.gather(*task_manager.tasks)
|
||||||
|
|
||||||
|
assert pipeline_overrides == ['pipeline-1']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_embed_group_event_uses_stable_session_launcher(monkeypatch):
|
async def test_embed_group_event_uses_stable_session_launcher(monkeypatch):
|
||||||
manager = WebSocketConnectionManager()
|
manager = WebSocketConnectionManager()
|
||||||
|
|||||||
Reference in New Issue
Block a user