feat: unify card runtime and event-driven web ui
This commit is contained in:
parent
0edf8c3fef
commit
4dfb7ca3cc
105 changed files with 17382 additions and 8505 deletions
128
web_runtime.py
Normal file
128
web_runtime.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue