92 lines
2.9 KiB
Python
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)
|