mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-27 16:04:21 +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 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')
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user