from __future__ import annotations from typing import Any, Literal from yuxi.channels.models import ChannelMessage, ChannelResponse ReplyToMode = Literal["off", "first", "all", "batched"] class WeChatThreadingAdapter: @staticmethod def resolve_reply_to_mode(config: dict[str, Any], chat_type: str) -> ReplyToMode: if chat_type == "direct": return config.get("dm_reply_to_mode", "first") return config.get("group_reply_to_mode", "off") @staticmethod def allow_explicit_reply_tags_when_off(config: dict[str, Any]) -> bool: return config.get("allow_explicit_reply_tags_when_off", False) @staticmethod def build_tool_context(message: ChannelMessage, agent_id: str) -> dict[str, Any]: return { "channel": "wechat", "mode": message.metadata.get("wechat_mode", "personal"), "chat_type": message.metadata.get("chat_type", "direct"), "sender_id": message.identity.channel_user_id, "chat_id": message.identity.channel_chat_id, "agent_id": agent_id, } @staticmethod def resolve_auto_thread_id(message: ChannelMessage) -> str | None: if message.chat_type.value != "group": return None sender_id = message.identity.channel_user_id chat_id = message.identity.channel_chat_id return f"auto:{chat_id}:{sender_id}" @staticmethod def resolve_current_channel_id(mode: str, account_id: str) -> str: return f"wechat:{mode}:{account_id}" @staticmethod def resolve_reply_transport(response: ChannelResponse) -> dict[str, Any]: transport: dict[str, Any] = {} reply_to = response.metadata.get("reply_to_message_id") if reply_to: transport["reply_to_message_id"] = reply_to at_list = response.metadata.get("at_list") if at_list: transport["at_list"] = at_list return transport @staticmethod def resolve_focused_binding(config: dict[str, Any], message: ChannelMessage) -> dict[str, Any] | None: peer_id = message.identity.channel_user_id bindings = config.get("bindings", []) for binding in bindings: peer = binding.get("peer", {}) if peer.get("id") == peer_id: return {"peer": peer, "agent_id": binding.get("agentId")} return None