chore: snapshot current state before cleanup
This commit is contained in:
parent
db4ce8b14f
commit
94e62c9456
14 changed files with 489 additions and 3929 deletions
|
|
@ -62,6 +62,7 @@ class NanobotApiProcess:
|
|||
self._reader: asyncio.StreamReader | None = None
|
||||
self._writer: asyncio.StreamWriter | None = None
|
||||
self._read_task: asyncio.Task | None = None
|
||||
self._socket_inode: int | None = None
|
||||
|
||||
@property
|
||||
def running(self) -> bool:
|
||||
|
|
@ -72,6 +73,16 @@ class NanobotApiProcess:
|
|||
and not self._read_task.done()
|
||||
)
|
||||
|
||||
def matches_current_socket(self) -> bool:
|
||||
if self._socket_inode is None:
|
||||
return False
|
||||
try:
|
||||
return self._socket_path.stat().st_ino == self._socket_inode
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
async def start(self) -> None:
|
||||
if self.running:
|
||||
await self._bus.publish(WisperEvent(role="system", text="Already connected to nanobot."))
|
||||
|
|
@ -95,6 +106,7 @@ class NanobotApiProcess:
|
|||
self._reader, self._writer = await asyncio.open_unix_connection(
|
||||
path=str(self._socket_path)
|
||||
)
|
||||
self._socket_inode = self._socket_path.stat().st_ino
|
||||
except OSError as exc:
|
||||
await self._bus.publish(
|
||||
WisperEvent(role="system", text=f"Could not connect to nanobot API socket: {exc}")
|
||||
|
|
@ -107,7 +119,7 @@ class NanobotApiProcess:
|
|||
async def send(self, text: str, metadata: dict[str, Any] | None = None) -> None:
|
||||
if not self.running or self._writer is None:
|
||||
await self._bus.publish(WisperEvent(role="system", text="Not connected to nanobot."))
|
||||
return
|
||||
raise RuntimeError("Not connected to nanobot.")
|
||||
try:
|
||||
await self._send_notification(
|
||||
"message.send",
|
||||
|
|
@ -120,10 +132,11 @@ class NanobotApiProcess:
|
|||
except OSError as exc:
|
||||
await self._bus.publish(WisperEvent(role="system", text=f"Send failed: {exc}"))
|
||||
await self._cleanup()
|
||||
raise RuntimeError(f"Send failed: {exc}") from exc
|
||||
|
||||
async def send_card_response(self, card_id: str, value: str) -> None:
|
||||
if not self.running or self._writer is None:
|
||||
return
|
||||
raise RuntimeError("Not connected to nanobot.")
|
||||
try:
|
||||
await self._send_notification(
|
||||
"card.respond",
|
||||
|
|
@ -135,11 +148,12 @@ class NanobotApiProcess:
|
|||
except OSError as exc:
|
||||
await self._bus.publish(WisperEvent(role="system", text=f"Send failed: {exc}"))
|
||||
await self._cleanup()
|
||||
raise RuntimeError(f"Send failed: {exc}") from exc
|
||||
|
||||
async def send_command(self, command: str) -> None:
|
||||
if not self.running or self._writer is None:
|
||||
await self._bus.publish(WisperEvent(role="system", text="Not connected to nanobot."))
|
||||
return
|
||||
raise RuntimeError("Not connected to nanobot.")
|
||||
try:
|
||||
await self._send_notification(
|
||||
"command.execute",
|
||||
|
|
@ -151,6 +165,7 @@ class NanobotApiProcess:
|
|||
except OSError as exc:
|
||||
await self._bus.publish(WisperEvent(role="system", text=f"Send failed: {exc}"))
|
||||
await self._cleanup()
|
||||
raise RuntimeError(f"Send failed: {exc}") from exc
|
||||
|
||||
async def stop(self) -> None:
|
||||
await self._cleanup()
|
||||
|
|
@ -173,6 +188,7 @@ class NanobotApiProcess:
|
|||
pass
|
||||
self._writer = None
|
||||
self._reader = None
|
||||
self._socket_inode = None
|
||||
|
||||
async def _send_notification(self, method: str, params: dict[str, Any]) -> None:
|
||||
assert self._writer is not None
|
||||
|
|
@ -264,26 +280,35 @@ class SuperTonicGateway:
|
|||
self._process = NanobotApiProcess(bus=self.bus, socket_path=self._socket_path)
|
||||
await self._process.start()
|
||||
|
||||
async def _ensure_connected_process(self) -> NanobotApiProcess:
|
||||
if self._process and self._process.running and self._process.matches_current_socket():
|
||||
return self._process
|
||||
if self._process:
|
||||
await self._process.stop()
|
||||
self._process = NanobotApiProcess(bus=self.bus, socket_path=self._socket_path)
|
||||
await self._process.start()
|
||||
if not self._process.running or not self._process.matches_current_socket():
|
||||
raise RuntimeError("Not connected to nanobot.")
|
||||
return self._process
|
||||
|
||||
async def send_user_message(self, text: str, metadata: dict[str, Any] | None = None) -> None:
|
||||
message = text.strip()
|
||||
if not message:
|
||||
return
|
||||
await self.bus.publish(WisperEvent(role="user", text=message))
|
||||
async with self._lock:
|
||||
if not self._process:
|
||||
await self.bus.publish(WisperEvent(role="system", text="Not connected to nanobot."))
|
||||
return
|
||||
await self._process.send(message, metadata=metadata)
|
||||
process = await self._ensure_connected_process()
|
||||
await process.send(message, metadata=metadata)
|
||||
|
||||
async def send_card_response(self, card_id: str, value: str) -> None:
|
||||
async with self._lock:
|
||||
if self._process:
|
||||
await self._process.send_card_response(card_id, value)
|
||||
process = await self._ensure_connected_process()
|
||||
await process.send_card_response(card_id, value)
|
||||
|
||||
async def send_command(self, command: str) -> None:
|
||||
async with self._lock:
|
||||
if self._process:
|
||||
await self._process.send_command(command)
|
||||
process = await self._ensure_connected_process()
|
||||
await process.send_command(command)
|
||||
|
||||
async def disconnect_nanobot(self) -> None:
|
||||
async with self._lock:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue