mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-02 03:55:55 +00:00
fix:webchat stream judge bug and frontend bug
This commit is contained in:
@@ -15,7 +15,7 @@ class WebChatDebugRouterGroup(group.RouterGroup):
|
||||
async def stream_generator(generator):
|
||||
async for message in generator:
|
||||
yield rf"data:{json.dumps({'message': message})}\n\n"
|
||||
yield "data:{'type': 'end'}\n\n''"
|
||||
yield "data:{type: end}\n\n''"
|
||||
try:
|
||||
data = await quart.request.get_json()
|
||||
session_type = data.get('session_type', 'person')
|
||||
|
||||
@@ -19,6 +19,7 @@ class WebChatMessage(BaseModel):
|
||||
content: str
|
||||
message_chain: list[dict]
|
||||
timestamp: str
|
||||
is_final: bool = False
|
||||
|
||||
|
||||
class WebChatSession:
|
||||
@@ -117,10 +118,10 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
|
||||
async def reply_message_chunk(
|
||||
self,
|
||||
message_source: platform_events.MessageEvent,
|
||||
message_id: str,
|
||||
message_id: int,
|
||||
message: platform_message.MessageChain,
|
||||
quote_origin: bool = False,
|
||||
is_fianl: bool = False,
|
||||
is_final: bool = False,
|
||||
) -> dict:
|
||||
"""回复消息"""
|
||||
message_data = WebChatMessage(
|
||||
@@ -132,14 +133,21 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
|
||||
)
|
||||
|
||||
# notify waiter
|
||||
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]
|
||||
session = (self.webchat_group_session if isinstance(message_source, platform_events.GroupMessage) else self.webchat_person_session)
|
||||
if message_source.message_chain.message_id not in session.resp_waiters:
|
||||
# session.resp_waiters[message_source.message_chain.message_id] = asyncio.Queue()
|
||||
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()
|
||||
|
||||
@@ -192,6 +200,10 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
|
||||
|
||||
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(
|
||||
WebChatMessage(
|
||||
id=message_id,
|
||||
@@ -232,9 +244,11 @@ class WebChatAdapter(msadapter.MessagePlatformAdapter):
|
||||
queue = use_session.resp_queues[message_id]
|
||||
while True:
|
||||
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
|
||||
use_session.get_message_list(pipeline_uuid).append(resp_message)
|
||||
yield resp_message.model_dump()
|
||||
break
|
||||
yield resp_message.model_dump()
|
||||
|
||||
|
||||
@@ -46,17 +46,20 @@ export default function DebugDialog({
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
};
|
||||
|
||||
const loadMessages = useCallback(async (pipelineId: string) => {
|
||||
try {
|
||||
const response = await httpClient.getWebChatHistoryMessages(
|
||||
pipelineId,
|
||||
sessionType,
|
||||
);
|
||||
setMessages(response.messages);
|
||||
} catch (error) {
|
||||
console.error('Failed to load messages:', error);
|
||||
}
|
||||
}, [sessionType]);
|
||||
const loadMessages = useCallback(
|
||||
async (pipelineId: string) => {
|
||||
try {
|
||||
const response = await httpClient.getWebChatHistoryMessages(
|
||||
pipelineId,
|
||||
sessionType,
|
||||
);
|
||||
setMessages(response.messages);
|
||||
} catch (error) {
|
||||
console.error('Failed to load messages:', error);
|
||||
}
|
||||
},
|
||||
[sessionType],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
scrollToBottom();
|
||||
@@ -242,7 +245,6 @@ export default function DebugDialog({
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
setMessages((prevMessages) => [...prevMessages, userMessage]);
|
||||
setInputValue('');
|
||||
setHasAt(false);
|
||||
@@ -388,10 +390,7 @@ export default function DebugDialog({
|
||||
<span className="text-sm text-gray-600">
|
||||
{t('pipelines.debugDialog.streaming')}
|
||||
</span>
|
||||
<Switch
|
||||
checked={isStreaming}
|
||||
onCheckedChange={setIsStreaming}
|
||||
/>
|
||||
<Switch checked={isStreaming} onCheckedChange={setIsStreaming} />
|
||||
</div>
|
||||
<div className="flex-1 flex items-center gap-2">
|
||||
{hasAt && (
|
||||
@@ -434,12 +433,12 @@ export default function DebugDialog({
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
onClick={sendMessage}
|
||||
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"
|
||||
>
|
||||
<>{t('pipelines.debugDialog.send')}</>
|
||||
</Button>
|
||||
onClick={sendMessage}
|
||||
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"
|
||||
>
|
||||
<>{t('pipelines.debugDialog.send')}</>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -333,13 +333,20 @@ class HttpClient {
|
||||
onError: (error: Error) => void,
|
||||
): Promise<void> {
|
||||
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在浏览器环境中不直接支持流式响应
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${this.getSessionSync()}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
session_type: sessionType,
|
||||
|
||||
Reference in New Issue
Block a user