(
request: Request,
data: ChatData,
chat_engine: BaseChatEngine = Depends(get_chat_engine),
)
| 24 | # streaming endpoint - delete if not needed |
| 25 | @r.post("") |
| 26 | async def chat( |
| 27 | request: Request, |
| 28 | data: ChatData, |
| 29 | chat_engine: BaseChatEngine = Depends(get_chat_engine), |
| 30 | ): |
| 31 | try: |
| 32 | last_message_content = data.get_last_message_content() |
| 33 | messages = data.get_history_messages() |
| 34 | |
| 35 | event_handler = EventCallbackHandler() |
| 36 | chat_engine.callback_manager.handlers.append(event_handler) # type: ignore |
| 37 | |
| 38 | async def content_generator(): |
| 39 | # Yield the text response |
| 40 | async def _chat_response_generator(): |
| 41 | response = await chat_engine.astream_chat( |
| 42 | last_message_content, messages |
| 43 | ) |
| 44 | async for token in response.async_response_gen(): |
| 45 | yield VercelStreamResponse.convert_text(token) |
| 46 | # the text_generator is the leading stream, once it's finished, also finish the event stream |
| 47 | event_handler.is_done = True |
| 48 | |
| 49 | # Yield the source nodes |
| 50 | yield VercelStreamResponse.convert_data( |
| 51 | { |
| 52 | "type": "sources", |
| 53 | "data": { |
| 54 | "nodes": [ |
| 55 | SourceNodes.from_source_node(node).dict() |
| 56 | for node in response.source_nodes |
| 57 | ] |
| 58 | }, |
| 59 | } |
| 60 | ) |
| 61 | |
| 62 | # Yield the events from the event handler |
| 63 | async def _event_generator(): |
| 64 | async for event in event_handler.async_event_gen(): |
| 65 | event_response = event.to_response() |
| 66 | if event_response is not None: |
| 67 | yield VercelStreamResponse.convert_data(event_response) |
| 68 | |
| 69 | combine = stream.merge(_chat_response_generator(), _event_generator()) |
| 70 | is_stream_started = False |
| 71 | async with combine.stream() as streamer: |
| 72 | async for output in streamer: |
| 73 | if not is_stream_started: |
| 74 | is_stream_started = True |
| 75 | # Stream a blank message to start the stream |
| 76 | yield VercelStreamResponse.convert_text("") |
| 77 | |
| 78 | yield output |
| 79 | |
| 80 | if await request.is_disconnected(): |
| 81 | break |
| 82 | |
| 83 | return VercelStreamResponse(content=content_generator()) |
nothing calls this directly
no test coverage detected