- Replaced direct FastGPT client usage with a backend-neutral chat interface, allowing for improved flexibility and maintainability. - Introduced a new `ChatBackend` protocol and implemented `FastGPTBackend` to handle chat operations. - Updated the chat endpoint to utilize the new backend structure, enhancing the handling of chat requests and responses. - Added comprehensive tests to ensure compatibility and functionality of the new backend integration.
71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
import pytest
|
|
|
|
from src.api.endpoints import chat
|
|
from src.backends.chat import ChatInput, ChatResult, FormUpdate, TextDelta
|
|
from src.schemas.models import ProcessRequest_chat
|
|
|
|
|
|
class FakeBackend:
|
|
def __init__(self):
|
|
self.received = []
|
|
|
|
async def stream(self, chat_input: ChatInput):
|
|
self.received.append(chat_input)
|
|
yield TextDelta("<sta")
|
|
yield TextDelta("te>1002</state>你")
|
|
yield FormUpdate({"jdcsl": 2})
|
|
yield TextDelta("好")
|
|
|
|
async def complete(self, chat_input: ChatInput):
|
|
self.received.append(chat_input)
|
|
return ChatResult(
|
|
content="<state>1002</state>你好",
|
|
status_code="1002",
|
|
form_update={"jdcsl": 2},
|
|
)
|
|
|
|
|
|
def make_request():
|
|
return ProcessRequest_chat(
|
|
sessionId="session-001",
|
|
timeStamp="20260725120000",
|
|
text="发生了交通事故",
|
|
needFormUpdate=True,
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_non_stream_chat_uses_backend_neutral_result():
|
|
backend = FakeBackend()
|
|
|
|
response = await chat(make_request(), stream=False, backend=backend)
|
|
|
|
assert response.outputText == "你好"
|
|
assert response.nextStageCode == "1002"
|
|
assert response.formUpdate == {"jdcsl": 2}
|
|
assert backend.received == [
|
|
ChatInput(
|
|
session_id="session-001",
|
|
text="发生了交通事故",
|
|
need_form_update=True,
|
|
)
|
|
]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_stream_chat_keeps_state_prefix_buffering_in_fastapi_layer():
|
|
backend = FakeBackend()
|
|
|
|
response = await chat(make_request(), stream=True, backend=backend)
|
|
chunks = []
|
|
async for chunk in response.body_iterator:
|
|
chunks.append(chunk.decode() if isinstance(chunk, bytes) else chunk)
|
|
body = "".join(chunks)
|
|
|
|
assert body.index("event: stage_code") < body.index("event: text_delta")
|
|
assert '"nextStageCode": "1002"' in body
|
|
assert '"text": "你"' in body
|
|
assert '"text": "好"' in body
|
|
assert "event: formUpdate" in body
|
|
assert "event: done" in body
|