mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-07 00:30:20 +08:00
feat(message-processing-status): unified processing status indicator for Telegram, Slack, Discord, Feishu
- Add ChannelCapability.PROCESSING_STATUS and capability detection for supported channels - Implement mark_message_processing_started/finished in Telegram, Slack, Discord, Feishu modules - Telegram: manage typing lifecycle with max duration and explicit stop - Slack: add/remove reaction as processing indicator - Discord: start/stop typing indicator with async task management - Feishu: add/remove reaction for processing status - Refactor message chain to invoke processing status hooks for supported channels - Ensure processing status is properly finished on sync and async message handling paths - Add tests for processing status lifecycle and capability detection across channels
This commit is contained in:
@@ -8,6 +8,7 @@ from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any, Callable, Dict, List, Optional
|
||||
|
||||
from fastapi.concurrency import run_in_threadpool
|
||||
from langchain.agents import create_agent
|
||||
from langchain.agents.middleware import (
|
||||
SummarizationMiddleware,
|
||||
@@ -53,6 +54,40 @@ class AgentChain(ChainBase):
|
||||
pass
|
||||
|
||||
|
||||
def _finish_processing_status(status: Optional[dict], user_id: Optional[str] = None) -> None:
|
||||
"""结束入站消息的渠道处理状态。"""
|
||||
if not status:
|
||||
return
|
||||
try:
|
||||
channel = MessageChannel(status.get("channel"))
|
||||
except Exception:
|
||||
return
|
||||
try:
|
||||
AgentChain().run_module(
|
||||
"mark_message_processing_finished",
|
||||
channel=channel,
|
||||
source=status.get("source"),
|
||||
userid=status.get("userid") or user_id,
|
||||
message_id=status.get("message_id"),
|
||||
chat_id=status.get("chat_id"),
|
||||
status=status,
|
||||
)
|
||||
except Exception as err:
|
||||
logger.debug(f"结束Agent消息处理状态失败: {err}")
|
||||
|
||||
|
||||
async def _async_finish_processing_status(
|
||||
status: Optional[dict], user_id: Optional[str] = None
|
||||
) -> None:
|
||||
"""
|
||||
在 Agent worker 中结束渠道处理状态。
|
||||
渠道收口可能触发外部 API,同步实现需切到线程池避免阻塞事件循环。
|
||||
"""
|
||||
if not status:
|
||||
return
|
||||
await run_in_threadpool(_finish_processing_status, status, user_id)
|
||||
|
||||
|
||||
@dataclass
|
||||
class _SessionUsageSnapshot:
|
||||
model: Optional[str] = None
|
||||
@@ -901,6 +936,7 @@ class _MessageTask:
|
||||
username: Optional[str] = None
|
||||
original_message_id: Optional[str] = None
|
||||
original_chat_id: Optional[str] = None
|
||||
processing_status: Optional[dict] = None
|
||||
reply_mode: ReplyMode = ReplyMode.DISPATCH
|
||||
|
||||
|
||||
@@ -987,6 +1023,7 @@ class AgentManager:
|
||||
username: str = None,
|
||||
original_message_id: Optional[str] = None,
|
||||
original_chat_id: Optional[str] = None,
|
||||
processing_status: Optional[dict] = None,
|
||||
reply_mode: ReplyMode = ReplyMode.DISPATCH,
|
||||
) -> str:
|
||||
"""
|
||||
@@ -1004,6 +1041,7 @@ class AgentManager:
|
||||
username=username,
|
||||
original_message_id=original_message_id,
|
||||
original_chat_id=original_chat_id,
|
||||
processing_status=processing_status,
|
||||
reply_mode=reply_mode,
|
||||
)
|
||||
|
||||
@@ -1062,6 +1100,9 @@ class AgentManager:
|
||||
except Exception as e:
|
||||
logger.error(f"处理会话 {session_id} 的消息失败: {e}")
|
||||
finally:
|
||||
await _async_finish_processing_status(
|
||||
task.processing_status, task.user_id
|
||||
)
|
||||
queue.task_done()
|
||||
|
||||
except asyncio.CancelledError:
|
||||
|
||||
Reference in New Issue
Block a user