129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from collections.abc import Callable
|
||
|
|
from dataclasses import dataclass
|
||
|
|
from pathlib import Path
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from card_store import (
|
||
|
|
delete_cards_for_chat,
|
||
|
|
ensure_card_store_dirs,
|
||
|
|
sync_templates_context_file,
|
||
|
|
)
|
||
|
|
from inbox_service import InboxService
|
||
|
|
from nanobot_api_client import send_nanobot_api_request
|
||
|
|
from rtc_manager import RtcSessionManager
|
||
|
|
from session_store import ensure_session_store_dirs
|
||
|
|
from supertonic_gateway import SuperTonicGateway
|
||
|
|
from tool_job_service import ToolJobService
|
||
|
|
from ui_event_bus import UiEventBus
|
||
|
|
from workbench_store import ensure_workbench_store_dirs
|
||
|
|
|
||
|
|
|
||
|
|
def normalize_event_chat_id(normalize_chat_id, raw_chat_id: Any) -> str | None:
|
||
|
|
chat_id = normalize_chat_id(str(raw_chat_id or ""))
|
||
|
|
return chat_id or None
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(slots=True)
|
||
|
|
class WebAppRuntime:
|
||
|
|
gateway: SuperTonicGateway
|
||
|
|
event_bus: UiEventBus
|
||
|
|
inbox_service: InboxService
|
||
|
|
tool_job_service: ToolJobService
|
||
|
|
rtc_manager: RtcSessionManager | None
|
||
|
|
list_sessions: Callable[[], list[dict[str, Any]]]
|
||
|
|
normalize_chat_id: Callable[[str], str]
|
||
|
|
|
||
|
|
def open_inbox_items(self, *, limit: int = 4) -> list[dict[str, Any]]:
|
||
|
|
return self.inbox_service.open_items(limit=limit)
|
||
|
|
|
||
|
|
async def publish_sessions_changed(self) -> None:
|
||
|
|
await self.event_bus.publish(
|
||
|
|
{
|
||
|
|
"type": "sessions.changed",
|
||
|
|
"sessions": self.list_sessions(),
|
||
|
|
},
|
||
|
|
broadcast=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
async def publish_cards_changed(self, chat_id: Any = None) -> None:
|
||
|
|
target_chat_id = normalize_event_chat_id(self.normalize_chat_id, chat_id)
|
||
|
|
await self.event_bus.publish(
|
||
|
|
{"type": "cards.changed", "chat_id": target_chat_id},
|
||
|
|
chat_id=target_chat_id,
|
||
|
|
broadcast=target_chat_id is None,
|
||
|
|
)
|
||
|
|
|
||
|
|
async def publish_workbench_changed(self, chat_id: Any = None) -> None:
|
||
|
|
target_chat_id = normalize_event_chat_id(self.normalize_chat_id, chat_id)
|
||
|
|
await self.event_bus.publish(
|
||
|
|
{"type": "workbench.changed", "chat_id": target_chat_id},
|
||
|
|
chat_id=target_chat_id,
|
||
|
|
broadcast=target_chat_id is None,
|
||
|
|
)
|
||
|
|
|
||
|
|
async def publish_inbox_changed(self) -> None:
|
||
|
|
await self.event_bus.publish(
|
||
|
|
{
|
||
|
|
"type": "inbox.changed",
|
||
|
|
"items": self.open_inbox_items(),
|
||
|
|
},
|
||
|
|
broadcast=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
async def shutdown(self) -> None:
|
||
|
|
await self.tool_job_service.shutdown()
|
||
|
|
if self.rtc_manager is not None:
|
||
|
|
await self.rtc_manager.shutdown()
|
||
|
|
await self.gateway.shutdown()
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def delete_cards_for_chat(chat_id: str) -> int:
|
||
|
|
return delete_cards_for_chat(chat_id)
|
||
|
|
|
||
|
|
|
||
|
|
def create_web_runtime(
|
||
|
|
*,
|
||
|
|
repo_dir: Path,
|
||
|
|
inbox_dir: Path,
|
||
|
|
tool_job_timeout_seconds: float,
|
||
|
|
tool_job_retention_seconds: float,
|
||
|
|
list_sessions,
|
||
|
|
normalize_chat_id,
|
||
|
|
) -> WebAppRuntime:
|
||
|
|
ensure_card_store_dirs()
|
||
|
|
ensure_session_store_dirs()
|
||
|
|
ensure_workbench_store_dirs()
|
||
|
|
inbox_dir.mkdir(parents=True, exist_ok=True)
|
||
|
|
sync_templates_context_file()
|
||
|
|
|
||
|
|
gateway = SuperTonicGateway()
|
||
|
|
event_bus = UiEventBus()
|
||
|
|
inbox_service = InboxService(repo_dir=repo_dir, inbox_dir=inbox_dir)
|
||
|
|
tool_job_service = ToolJobService(
|
||
|
|
send_request=lambda method, params: send_nanobot_api_request(
|
||
|
|
method,
|
||
|
|
params,
|
||
|
|
timeout_seconds=tool_job_timeout_seconds,
|
||
|
|
),
|
||
|
|
timeout_seconds=tool_job_timeout_seconds,
|
||
|
|
retention_seconds=tool_job_retention_seconds,
|
||
|
|
)
|
||
|
|
runtime = WebAppRuntime(
|
||
|
|
gateway=gateway,
|
||
|
|
event_bus=event_bus,
|
||
|
|
inbox_service=inbox_service,
|
||
|
|
tool_job_service=tool_job_service,
|
||
|
|
rtc_manager=None,
|
||
|
|
list_sessions=list_sessions,
|
||
|
|
normalize_chat_id=normalize_chat_id,
|
||
|
|
)
|
||
|
|
runtime.rtc_manager = RtcSessionManager(
|
||
|
|
gateway=gateway,
|
||
|
|
publish_cards_changed=runtime.publish_cards_changed,
|
||
|
|
publish_workbench_changed=runtime.publish_workbench_changed,
|
||
|
|
publish_sessions_changed=runtime.publish_sessions_changed,
|
||
|
|
)
|
||
|
|
return runtime
|