fix:webchat stream judge bug and frontend bug

This commit is contained in:
Dong_master
2025-07-31 14:49:12 +08:00
parent cb88da7f02
commit d9a2bb9a06
4 changed files with 54 additions and 34 deletions
@@ -15,7 +15,7 @@ class WebChatDebugRouterGroup(group.RouterGroup):
async def stream_generator(generator): async def stream_generator(generator):
async for message in generator: async for message in generator:
yield rf"data:{json.dumps({'message': message})}\n\n" yield rf"data:{json.dumps({'message': message})}\n\n"
yield "data:{'type': 'end'}\n\n''" yield "data:{type: end}\n\n''"
try: try:
data = await quart.request.get_json() data = await quart.request.get_json()
session_type = data.get('session_type', 'person') session_type = data.get('session_type', 'person')
+24 -10
View File
@@ -19,6 +19,7 @@ class WebChatMessage(BaseModel):
content: str content: str
message_chain: list[dict] message_chain: list[dict]
timestamp: str timestamp: str
is_final: bool = False
class WebChatSession: class WebChatSession:
@@ -117,10 +118,10 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
async def reply_message_chunk( async def reply_message_chunk(
self, self,
message_source: platform_events.MessageEvent, message_source: platform_events.MessageEvent,
message_id: str, message_id: int,
message: platform_message.MessageChain, message: platform_message.MessageChain,
quote_origin: bool = False, quote_origin: bool = False,
is_fianl: bool = False, is_final: bool = False,
) -> dict: ) -> dict:
"""回复消息""" """回复消息"""
message_data = WebChatMessage( message_data = WebChatMessage(
@@ -132,14 +133,21 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
) )
# notify waiter # notify waiter
if isinstance(message_source, platform_events.FriendMessage): session = (self.webchat_group_session if isinstance(message_source, platform_events.GroupMessage) else self.webchat_person_session)
queue = self.webchat_person_session.resp_queues[message_source.message_chain.message_id] if message_source.message_chain.message_id not in session.resp_waiters:
elif isinstance(message_source, platform_events.GroupMessage): # session.resp_waiters[message_source.message_chain.message_id] = asyncio.Queue()
queue = self.webchat_group_session.resp_queues[message_source.message_chain.message_id] queue = session.resp_queues[message_source.message_chain.message_id]
# if isinstance(message_source, platform_events.FriendMessage):
# queue = self.webchat_person_session.resp_queues[message_source.message_chain.message_id]
# elif isinstance(message_source, platform_events.GroupMessage):
# queue = self.webchat_group_session.resp_queues[message_source.message_chain.message_id]
if is_final:
message_data.is_final = True
# print(message_data)
await queue.put(message_data)
queue.put(message_data)
if is_fianl:
queue.put(None)
return message_data.model_dump() return message_data.model_dump()
@@ -192,6 +200,10 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
message_id = len(use_session.get_message_list(pipeline_uuid)) + 1 message_id = len(use_session.get_message_list(pipeline_uuid)) + 1
if is_stream:
use_session.resp_queues[message_id] = asyncio.Queue()
logger.debug(f"Initialized queue for message_id: {message_id}")
use_session.get_message_list(pipeline_uuid).append( use_session.get_message_list(pipeline_uuid).append(
WebChatMessage( WebChatMessage(
id=message_id, id=message_id,
@@ -232,9 +244,11 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
queue = use_session.resp_queues[message_id] queue = use_session.resp_queues[message_id]
while True: while True:
resp_message = await queue.get() resp_message = await queue.get()
if resp_message is None: print(resp_message)
if resp_message.is_final:
resp_message.id = len(use_session.get_message_list(pipeline_uuid)) + 1 resp_message.id = len(use_session.get_message_list(pipeline_uuid)) + 1
use_session.get_message_list(pipeline_uuid).append(resp_message) use_session.get_message_list(pipeline_uuid).append(resp_message)
yield resp_message.model_dump()
break break
yield resp_message.model_dump() yield resp_message.model_dump()
@@ -46,17 +46,20 @@ export default function DebugDialog({
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}; };
const loadMessages = useCallback(async (pipelineId: string) => { const loadMessages = useCallback(
try { async (pipelineId: string) => {
const response = await httpClient.getWebChatHistoryMessages( try {
pipelineId, const response = await httpClient.getWebChatHistoryMessages(
sessionType, pipelineId,
); sessionType,
setMessages(response.messages); );
} catch (error) { setMessages(response.messages);
console.error('Failed to load messages:', error); } catch (error) {
} console.error('Failed to load messages:', error);
}, [sessionType]); }
},
[sessionType],
);
useEffect(() => { useEffect(() => {
scrollToBottom(); scrollToBottom();
@@ -242,7 +245,6 @@ export default function DebugDialog({
} }
} }
} else { } else {
setMessages((prevMessages) => [...prevMessages, userMessage]); setMessages((prevMessages) => [...prevMessages, userMessage]);
setInputValue(''); setInputValue('');
setHasAt(false); setHasAt(false);
@@ -388,10 +390,7 @@ export default function DebugDialog({
<span className="text-sm text-gray-600"> <span className="text-sm text-gray-600">
{t('pipelines.debugDialog.streaming')} {t('pipelines.debugDialog.streaming')}
</span> </span>
<Switch <Switch checked={isStreaming} onCheckedChange={setIsStreaming} />
checked={isStreaming}
onCheckedChange={setIsStreaming}
/>
</div> </div>
<div className="flex-1 flex items-center gap-2"> <div className="flex-1 flex items-center gap-2">
{hasAt && ( {hasAt && (
@@ -434,12 +433,12 @@ export default function DebugDialog({
</div> </div>
</div> </div>
<Button <Button
onClick={sendMessage} onClick={sendMessage}
disabled={!inputValue.trim() && !hasAt} disabled={!inputValue.trim() && !hasAt}
className="rounded-md bg-[#2288ee] hover:bg-[#2288ee] w-20 text-white px-6 py-2 text-base font-medium transition-none flex items-center gap-2 shadow-none" className="rounded-md bg-[#2288ee] hover:bg-[#2288ee] w-20 text-white px-6 py-2 text-base font-medium transition-none flex items-center gap-2 shadow-none"
> >
<>{t('pipelines.debugDialog.send')}</> <>{t('pipelines.debugDialog.send')}</>
</Button> </Button>
</div> </div>
</div> </div>
</div> </div>
+8 -1
View File
@@ -333,13 +333,20 @@ class HttpClient {
onError: (error: Error) => void, onError: (error: Error) => void,
): Promise<void> { ): Promise<void> {
try { try {
const url = `${this.baseURL}/api/v1/pipelines/${pipelineId}/chat/send`; // 构造完整的URL,处理相对路径的情况
let url = `${this.baseURL}/api/v1/pipelines/${pipelineId}/chat/send`;
if (this.baseURL === '/') {
// 获取用户访问的完整URL
const baseURL = window.location.origin;
url = `${baseURL}/api/v1/pipelines/${pipelineId}/chat/send`;
}
// 使用fetch发送流式请求,因为axios在浏览器环境中不直接支持流式响应 // 使用fetch发送流式请求,因为axios在浏览器环境中不直接支持流式响应
const response = await fetch(url, { const response = await fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${this.getSessionSync()}`,
}, },
body: JSON.stringify({ body: JSON.stringify({
session_type: sessionType, session_type: sessionType,