65 lines
2.2 KiB
Python
65 lines
2.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from abc import ABC, abstractmethod
|
||
|
|
from typing import TYPE_CHECKING
|
||
|
|
|
||
|
|
from yuxi.channels.models import SessionScope
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from yuxi.channels.models import ChannelMessage
|
||
|
|
|
||
|
|
|
||
|
|
class SessionRouter(ABC):
|
||
|
|
def __init__(self, channel_type: str, account_id: str = "default"):
|
||
|
|
self.channel_type = channel_type
|
||
|
|
self.account_id = account_id
|
||
|
|
|
||
|
|
@abstractmethod
|
||
|
|
def resolve_thread_key(self, message: ChannelMessage) -> str:
|
||
|
|
"""解析消息对应的线程键"""
|
||
|
|
|
||
|
|
@abstractmethod
|
||
|
|
def resolve_chat_id(self, message: ChannelMessage) -> str:
|
||
|
|
"""解析聊天ID"""
|
||
|
|
|
||
|
|
@abstractmethod
|
||
|
|
def resolve_session_scope(self, message: ChannelMessage) -> SessionScope:
|
||
|
|
"""解析会话范围级别"""
|
||
|
|
|
||
|
|
@abstractmethod
|
||
|
|
def normalize_target(self, target: str) -> str:
|
||
|
|
"""标准化目标地址"""
|
||
|
|
|
||
|
|
def resolve_agent_route(self, message: ChannelMessage) -> str:
|
||
|
|
thread_key = self.resolve_thread_key(message)
|
||
|
|
scope = self.resolve_session_scope(message)
|
||
|
|
return f"agent:main:{thread_key}:{scope.value}"
|
||
|
|
|
||
|
|
def _build_key(self, scope: str, type_str: str, id_str: str) -> str:
|
||
|
|
return f"{self.channel_type}:{self.account_id}:{scope}:{type_str}:{id_str}"
|
||
|
|
|
||
|
|
|
||
|
|
class BaseSessionRouter(SessionRouter):
|
||
|
|
def normalize_target(self, target: str) -> str:
|
||
|
|
if target.startswith(f"{self.channel_type}:"):
|
||
|
|
return target
|
||
|
|
return f"{self.channel_type}:{target}"
|
||
|
|
|
||
|
|
def resolve_thread_key(self, message: ChannelMessage) -> str:
|
||
|
|
identity = message.identity
|
||
|
|
chat_type = message.chat_type.value if hasattr(message.chat_type, "value") else str(message.chat_type)
|
||
|
|
return self._build_key("chat", chat_type, identity.channel_chat_id)
|
||
|
|
|
||
|
|
def resolve_chat_id(self, message: ChannelMessage) -> str:
|
||
|
|
return message.identity.channel_chat_id
|
||
|
|
|
||
|
|
def resolve_session_scope(self, message: ChannelMessage) -> SessionScope:
|
||
|
|
from yuxi.channels.models import ChatType
|
||
|
|
|
||
|
|
chat_type = message.chat_type
|
||
|
|
if chat_type == ChatType.DIRECT:
|
||
|
|
return SessionScope.DIRECT
|
||
|
|
if chat_type == ChatType.THREAD:
|
||
|
|
return SessionScope.THREAD
|
||
|
|
return SessionScope.GROUP
|