- 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.
124 lines
3.4 KiB
Python
124 lines
3.4 KiB
Python
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from src.backends.chat import ChatInput, FormUpdate, TextDelta
|
|
from src.backends.fastgpt import FastGPTBackend
|
|
|
|
|
|
class FakeResponse:
|
|
def __init__(self, data):
|
|
self._data = data
|
|
self.raise_for_status_called = False
|
|
|
|
def raise_for_status(self):
|
|
self.raise_for_status_called = True
|
|
|
|
def json(self):
|
|
return self._data
|
|
|
|
|
|
class FakeClient:
|
|
def __init__(self, response):
|
|
self.response = response
|
|
self.calls = []
|
|
|
|
async def create_chat_completion(self, **kwargs):
|
|
self.calls.append(kwargs)
|
|
return self.response
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_complete_translates_fastgpt_response_to_neutral_result():
|
|
response = FakeResponse(
|
|
{
|
|
"choices": [
|
|
{
|
|
"message": {
|
|
"content": "<state>1002</state>请描述事故经过。"
|
|
}
|
|
}
|
|
],
|
|
"newVariables": {"status_code": "1002"},
|
|
"responseData": [
|
|
{
|
|
"moduleName": "文本内容提取事故信息",
|
|
"extractResult": {
|
|
"formUpdate": '{"jdcsl": 2, "ywrysw": false}'
|
|
},
|
|
}
|
|
],
|
|
}
|
|
)
|
|
client = FakeClient(response)
|
|
backend = FastGPTBackend(client)
|
|
|
|
result = await backend.complete(
|
|
ChatInput(
|
|
session_id="session-001",
|
|
text="发生了交通事故",
|
|
need_form_update=True,
|
|
)
|
|
)
|
|
|
|
assert response.raise_for_status_called is True
|
|
assert result.content == "<state>1002</state>请描述事故经过。"
|
|
assert result.status_code == "1002"
|
|
assert result.form_update == {"jdcsl": 2, "ywrysw": False}
|
|
assert client.calls == [
|
|
{
|
|
"messages": [{"role": "user", "content": "发生了交通事故"}],
|
|
"chatId": "session-001",
|
|
"stream": False,
|
|
"detail": True,
|
|
"variables": {"needFormUpdate": True},
|
|
}
|
|
]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_stream_translates_fastgpt_events_to_neutral_events(monkeypatch):
|
|
response = object()
|
|
client = FakeClient(response)
|
|
backend = FastGPTBackend(client)
|
|
|
|
async def fake_aiter_stream_events(actual_response):
|
|
assert actual_response is response
|
|
yield SimpleNamespace(
|
|
kind="answer",
|
|
data={"choices": [{"delta": {"content": "<state>1002"}}]},
|
|
)
|
|
yield SimpleNamespace(
|
|
kind="flowResponses",
|
|
data=[
|
|
{
|
|
"moduleName": "文本内容提取事故信息",
|
|
"extractResult": {"formUpdate": '{"jdcsl": 2}'},
|
|
}
|
|
],
|
|
)
|
|
yield SimpleNamespace(
|
|
kind="answer",
|
|
data={"choices": [{"delta": {"content": "</state>你好"}}]},
|
|
)
|
|
yield SimpleNamespace(kind="ignored", data={})
|
|
|
|
monkeypatch.setattr(
|
|
"src.backends.fastgpt.aiter_stream_events",
|
|
fake_aiter_stream_events,
|
|
)
|
|
|
|
events = [
|
|
event
|
|
async for event in backend.stream(
|
|
ChatInput(session_id="session-001", text="你好")
|
|
)
|
|
]
|
|
|
|
assert events == [
|
|
TextDelta("<state>1002"),
|
|
FormUpdate({"jdcsl": 2}),
|
|
TextDelta("</state>你好"),
|
|
]
|
|
assert client.calls[0]["stream"] is True
|