from __future__ import annotations import logging from yuxi.channel.extensions.feishu.types import FeishuGroupSessionScope logger = logging.getLogger(__name__) class FeishuSessionAdapter: def resolve_session(self, msg: object): from yuxi.channel.message.models import PeerKind from yuxi.channel.protocols import SessionResolution if hasattr(msg, "sender") and hasattr(msg.sender, "kind"): if msg.sender.kind == PeerKind.DIRECT: return SessionResolution( kind="direct", conversation_id=getattr(msg.sender, "id", "unknown"), ) group = getattr(msg, "group", None) if group: chat_id = getattr(group, "id", "unknown") return SessionResolution( kind="group", conversation_id=chat_id, ) return SessionResolution(kind="group", conversation_id="unknown") def build_session_key( self, chat_id: str, *, sender_id: str | None = None, thread_id: str | None = None, scope: str = "group", ) -> str: if scope == FeishuGroupSessionScope.GROUP_SENDER and sender_id: return f"{chat_id}:sender:{sender_id}" elif scope == FeishuGroupSessionScope.GROUP_TOPIC and thread_id: return f"{chat_id}:topic:{thread_id}" elif scope == FeishuGroupSessionScope.GROUP_TOPIC_SENDER and thread_id and sender_id: return f"{chat_id}:topic:{thread_id}:sender:{sender_id}" else: return chat_id def extract_thread_id(self, msg: object) -> str | None: if hasattr(msg, "thread_id"): return msg.thread_id if hasattr(msg, "raw_payload"): raw = msg.raw_payload if isinstance(raw, dict): return raw.get("thread_id") return None def resolve_reply_transport(self, msg: object, thread_id: str | None): from yuxi.channel.protocols import ReplyTransport transport = ReplyTransport() if thread_id: transport.thread_id = thread_id if hasattr(msg, "reply_to_id"): transport.reply_to_id = msg.reply_to_id return transport