feat: add multi-channel Devii sessions with docs search mode and channel-aware conversation persistence
This commit is contained in:
@@ -30,7 +30,7 @@ class DeviiHub:
|
||||
"ledger": UsageLedger(),
|
||||
"turns": TurnAudit(),
|
||||
}
|
||||
self._sessions: dict[tuple[str, str], DeviiSession] = {}
|
||||
self._sessions: dict[tuple[str, str, str], DeviiSession] = {}
|
||||
|
||||
@property
|
||||
def ledger(self) -> UsageLedger:
|
||||
@@ -44,15 +44,20 @@ class DeviiHub:
|
||||
api_key: str,
|
||||
base_url: str,
|
||||
is_admin: bool = False,
|
||||
channel: str = "main",
|
||||
) -> DeviiSession:
|
||||
key = (owner_kind, owner_id)
|
||||
key = (owner_kind, owner_id, channel)
|
||||
session = self._sessions.get(key)
|
||||
if session is not None:
|
||||
return session
|
||||
settings, pricing = self._build(api_key, base_url, owner_kind, is_admin)
|
||||
llm = LLMClient(settings)
|
||||
# Persistent, owner-isolated stores for signed-in users; ephemeral in-memory for guests.
|
||||
owned_db = db if owner_kind == "user" else memory_db()
|
||||
# The `docs` channel (Docii) is a self-contained documentation assistant: it gets its own
|
||||
# ephemeral stores so Devii's tasks, lessons, behavior and virtual tools never leak into it
|
||||
# (and a Docii reflection never pollutes the user's Devii memory). Only the conversation
|
||||
# thread persists, keyed per channel in the shared ConversationStore.
|
||||
owned_db = db if (owner_kind == "user" and channel == "main") else memory_db()
|
||||
task_store = TaskStore(owned_db, owner_kind, owner_id)
|
||||
lessons = LessonStore(owned_db, owner_kind, owner_id)
|
||||
virtual_tool_store = VirtualToolStore(owned_db, owner_kind, owner_id)
|
||||
@@ -70,22 +75,26 @@ class DeviiHub:
|
||||
behavior_store,
|
||||
self._stores,
|
||||
is_admin=is_admin,
|
||||
channel=channel,
|
||||
)
|
||||
if owner_kind == "user":
|
||||
saved = self._stores["conversations"].load(owner_kind, owner_id)
|
||||
saved = self._stores["conversations"].load(owner_kind, owner_id, channel)
|
||||
if saved:
|
||||
session.restore_history(saved)
|
||||
self._sessions[key] = session
|
||||
logger.info(
|
||||
"Created session %s/%s (total %d)",
|
||||
"Created session %s/%s [%s] (total %d)",
|
||||
owner_kind,
|
||||
owner_id,
|
||||
channel,
|
||||
len(self._sessions),
|
||||
)
|
||||
return session
|
||||
|
||||
def find(self, owner_kind: str, owner_id: str) -> DeviiSession | None:
|
||||
return self._sessions.get((owner_kind, owner_id))
|
||||
def find(
|
||||
self, owner_kind: str, owner_id: str, channel: str = "main"
|
||||
) -> DeviiSession | None:
|
||||
return self._sessions.get((owner_kind, owner_id, channel))
|
||||
|
||||
def active_sessions(self) -> int:
|
||||
return len(self._sessions)
|
||||
|
||||
Reference in New Issue
Block a user