ForcePilot/backend/package/yuxi/channels/adapters/matrix/acp_bindings.py
Kris 2063145ce1 feat(matrix): 新增完整的Matrix适配器工具集
新增了20+个Matrix相关工具模块,包含线程处理、自动加入、消息去重、配置管理、安全策略、媒体处理、命令解析等功能,完善Matrix适配器基础能力
2026-05-12 00:45:54 +08:00

92 lines
2.9 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING, Any
from yuxi.utils.logging_config import logger
if TYPE_CHECKING:
from nio import AsyncClient
class ACPBinding:
def __init__(
self,
room_id: str,
thread_root: str,
acp_session_id: str = "",
bind_mode: str = "thread",
):
self.room_id = room_id
self.thread_root = thread_root
self.acp_session_id = acp_session_id
self.bind_mode = bind_mode
self.bound = False
async def spawn(self, client: AsyncClient) -> dict[str, Any]:
self.bound = True
logger.info(f"ACP session spawned: {self.acp_session_id} -> {self.thread_root}")
return {
"status": "spawned",
"room_id": self.room_id,
"thread_root": self.thread_root,
"acp_session_id": self.acp_session_id,
}
async def bind(self, client: AsyncClient) -> dict[str, Any]:
if self.bound:
return {"status": "already_bound", "room_id": self.room_id}
self.bound = True
logger.info(f"ACP session bound: {self.acp_session_id} -> {self.thread_root}")
return {"status": "bound", "room_id": self.room_id, "thread_root": self.thread_root}
async def unbind(self) -> dict[str, Any]:
self.bound = False
return {"status": "unbound", "room_id": self.room_id}
def to_dict(self) -> dict[str, Any]:
return {
"room_id": self.room_id,
"thread_root": self.thread_root,
"acp_session_id": self.acp_session_id,
"bind_mode": self.bind_mode,
"bound": self.bound,
}
class ACPBindingManager:
def __init__(self, config: dict[str, Any]):
self._config = config
self._bindings: dict[str, ACPBinding] = {}
def create_binding(self, room_id: str, thread_root: str, session_id: str = "", mode: str = "thread") -> ACPBinding:
key = f"{room_id}:{thread_root}" if thread_root else room_id
if key in self._bindings:
return self._bindings[key]
binding = ACPBinding(
room_id=room_id,
thread_root=thread_root,
acp_session_id=session_id,
bind_mode=mode,
)
self._bindings[key] = binding
return binding
def get(self, room_id: str, thread_root: str = "") -> ACPBinding | None:
key = f"{room_id}:{thread_root}" if thread_root else room_id
return self._bindings.get(key)
def remove(self, room_id: str, thread_root: str = "") -> bool:
key = f"{room_id}:{thread_root}" if thread_root else room_id
if key in self._bindings:
del self._bindings[key]
return True
return False
def list_bindings(self) -> list[ACPBinding]:
return list(self._bindings.values())
@property
def binding_count(self) -> int:
return len(self._bindings)