Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 46 additions & 33 deletions astrbot/dashboard/routes/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,44 @@ async def stream():
message_accumulator = BotMessageAccumulator()
agent_stats = {}
refs = {}

async def flush_pending_bot_message():
nonlocal message_accumulator, agent_stats, refs
if not (message_accumulator.has_content() or refs or agent_stats):
return None

message_parts_to_save = message_accumulator.build_message_parts(
include_pending_tool_calls=True
)
plain_text = collect_plain_text_from_message_parts(
message_parts_to_save
)

try:
extracted_refs = self._extract_web_search_refs(
plain_text,
message_parts_to_save,
)
except Exception as e:
logger.exception(
f"Failed to extract web search refs: {e}",
exc_info=True,
)
extracted_refs = refs

saved_record = await self._save_bot_message(
webchat_conv_id,
message_parts_to_save,
agent_stats,
extracted_refs,
llm_checkpoint_id,
platform_history_id,
)
message_accumulator = BotMessageAccumulator()
agent_stats = {}
refs = {}
return saved_record

try:
# Emit session_id first so clients can bind the stream immediately.
session_info = {
Expand Down Expand Up @@ -900,35 +938,7 @@ async def stream():
should_save = True

if should_save:
message_parts_to_save = (
message_accumulator.build_message_parts(
include_pending_tool_calls=True
)
)
plain_text = collect_plain_text_from_message_parts(
message_parts_to_save
)

# 提取 web_search_tavily 引用
try:
refs = self._extract_web_search_refs(
plain_text,
message_parts_to_save,
)
except Exception as e:
logger.exception(
f"Failed to extract web search refs: {e}",
exc_info=True,
)

saved_record = await self._save_bot_message(
webchat_conv_id,
message_parts_to_save,
agent_stats,
refs,
llm_checkpoint_id,
platform_history_id,
)
saved_record = await flush_pending_bot_message()
# 发送保存的消息信息给前端
if saved_record and not client_disconnected:
saved_info = {
Expand All @@ -945,15 +955,18 @@ async def stream():
yield f"data: {json.dumps(saved_info, ensure_ascii=False)}\n\n"
except Exception:
pass
message_accumulator = BotMessageAccumulator()
agent_stats = {}
refs = {}

if msg_type == "end":
break
except BaseException as e:
logger.exception(f"WebChat stream unexpected error: {e}", exc_info=True)
finally:
try:
await flush_pending_bot_message()
except Exception as e:
logger.exception(
f"Failed to persist pending webchat message: {e}",
exc_info=True,
)
webchat_queue_mgr.remove_back_queue(message_id)

# 将消息放入会话特定的队列
Expand Down
76 changes: 48 additions & 28 deletions astrbot/dashboard/routes/live_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ async def _handle_chat_message(
llm_checkpoint_id = str(uuid.uuid4())

try:
pending_bot_message_flusher = None
chat_queue = webchat_queue_mgr.get_or_create_queue(session_id)
await chat_queue.put(
(
Expand Down Expand Up @@ -499,9 +500,47 @@ async def _handle_chat_message(
agent_stats = {}
refs = {}

async def flush_pending_bot_message():
nonlocal message_accumulator, agent_stats, refs
if not (message_accumulator.has_content() or refs or agent_stats):
return None

message_parts_to_save = message_accumulator.build_message_parts(
include_pending_tool_calls=True
)
plain_text = collect_plain_text_from_message_parts(
message_parts_to_save
)
try:
extracted_refs = self._extract_web_search_refs(
plain_text,
message_parts_to_save,
)
except Exception as e:
logger.exception(
f"[Live Chat] Failed to extract web search refs: {e}",
exc_info=True,
)
extracted_refs = refs

saved_record = await self._save_bot_message(
session_id,
message_parts_to_save,
agent_stats,
extracted_refs,
llm_checkpoint_id,
)
message_accumulator = BotMessageAccumulator()
agent_stats = {}
refs = {}
return saved_record

pending_bot_message_flusher = flush_pending_bot_message

while True:
if session.should_interrupt:
session.should_interrupt = False
await flush_pending_bot_message()
break

try:
Expand Down Expand Up @@ -574,30 +613,7 @@ async def _handle_chat_message(
should_save = True

if should_save:
message_parts_to_save = message_accumulator.build_message_parts(
include_pending_tool_calls=True
)
plain_text = collect_plain_text_from_message_parts(
message_parts_to_save
)
try:
refs = self._extract_web_search_refs(
plain_text,
message_parts_to_save,
)
except Exception as e:
logger.exception(
f"[Live Chat] Failed to extract web search refs: {e}",
exc_info=True,
)

saved_record = await self._save_bot_message(
session_id,
message_parts_to_save,
agent_stats,
refs,
llm_checkpoint_id,
)
saved_record = await flush_pending_bot_message()
if saved_record:
await self._send_chat_payload(
session,
Expand All @@ -614,10 +630,6 @@ async def _handle_chat_message(
},
)

message_accumulator = BotMessageAccumulator()
agent_stats = {}
refs = {}

if msg_type == "end":
break

Expand All @@ -633,6 +645,14 @@ async def _handle_chat_message(
},
)
finally:
try:
if pending_bot_message_flusher is not None:
await pending_bot_message_flusher()
except Exception as e:
logger.exception(
f"[Live Chat] Failed to persist pending chat message: {e}",
exc_info=True,
)
session.is_processing = False
webchat_queue_mgr.remove_back_queue(message_id)

Expand Down
2 changes: 1 addition & 1 deletion dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<meta name="robots" content="noindex, nofollow" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Outfit&family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap"
href="https://fonts.googleapis.com/css2?family=Outfit&family=Noto+Sans+SC:wght@100..900&display=swap"
/>
<!-- VAD (Voice Activity Detection) Libraries -->
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/ort.wasm.min.js"></script>
Expand Down
66 changes: 61 additions & 5 deletions dashboard/src/assets/mdi-subset/materialdesignicons-subset.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Auto-generated MDI subset – 247 icons */
/* Auto-generated MDI subset – 261 icons */
/* Do not edit manually. Run: pnpm run subset-icons */

@font-face {
Expand Down Expand Up @@ -236,6 +236,10 @@
content: "\F0167";
}

.mdi-code-braces::before {
content: "\F0169";
}

.mdi-code-json::before {
content: "\F0626";
}
Expand Down Expand Up @@ -324,6 +328,10 @@
content: "\F1634";
}

.mdi-database-search-outline::before {
content: "\F1636";
}

.mdi-delete::before {
content: "\F01B4";
}
Expand Down Expand Up @@ -396,6 +404,10 @@
content: "\F022E";
}

.mdi-file-delimited-outline::before {
content: "\F0EA5";
}

.mdi-file-document::before {
content: "\F0219";
}
Expand All @@ -416,6 +428,10 @@
content: "\F021C";
}

.mdi-file-music-outline::before {
content: "\F0E2A";
}

.mdi-file-outline::before {
content: "\F0224";
}
Expand All @@ -436,6 +452,10 @@
content: "\F0A4D";
}

.mdi-file-video-outline::before {
content: "\F0E2C";
}

.mdi-file-word-box::before {
content: "\F022D";
}
Expand Down Expand Up @@ -536,6 +556,10 @@
content: "\F0EFE";
}

.mdi-image-outline::before {
content: "\F0976";
}

.mdi-import::before {
content: "\F02FA";
}
Expand Down Expand Up @@ -564,10 +588,38 @@
content: "\F0315";
}

.mdi-language-css3::before {
content: "\F031C";
}

.mdi-language-html5::before {
content: "\F031D";
}

.mdi-language-java::before {
content: "\F0B37";
}

.mdi-language-javascript::before {
content: "\F031E";
}

.mdi-language-markdown::before {
content: "\F0354";
}

.mdi-language-markdown-outline::before {
content: "\F0F5B";
}

.mdi-language-python::before {
content: "\F0320";
}

.mdi-language-typescript::before {
content: "\F06E6";
}

.mdi-layers-outline::before {
content: "\F09FE";
}
Expand Down Expand Up @@ -688,6 +740,10 @@
content: "\F03D6";
}

.mdi-package-variant-closed::before {
content: "\F03D7";
}

.mdi-page-first::before {
content: "\F0600";
}
Expand Down Expand Up @@ -812,10 +868,6 @@
content: "\F167A";
}

.mdi-send::before {
content: "\F048A";
}

.mdi-server::before {
content: "\F048B";
}
Expand Down Expand Up @@ -1004,6 +1056,10 @@
content: "\F05B7";
}

.mdi-wrench-outline::before {
content: "\F0BE0";
}

.mdi-zip-box::before {
content: "\F05C4";
}
Expand Down
Binary file not shown.
Binary file not shown.
Loading
Loading