feat: add local chat provider and CLI
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""Chat orchestration without interface or provider-specific details."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from javis.memory.sqlite_store import ChatSession, SQLiteSessionStore
|
||||
from javis.providers.base import ChatMessage, LocalModelProvider
|
||||
|
||||
|
||||
class SessionProviderMismatchError(RuntimeError):
|
||||
"""The active provider cannot safely continue the stored session."""
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class LoadedSession:
|
||||
session: ChatSession
|
||||
messages: list[ChatMessage]
|
||||
|
||||
|
||||
class ChatService:
|
||||
def __init__(
|
||||
self,
|
||||
store: SQLiteSessionStore,
|
||||
provider: LocalModelProvider,
|
||||
) -> None:
|
||||
self.store = store
|
||||
self.provider = provider
|
||||
|
||||
def new_session(self) -> ChatSession:
|
||||
return self.store.create_session(self.provider.name, self.provider.model)
|
||||
|
||||
def list_sessions(self) -> list[ChatSession]:
|
||||
return self.store.list_sessions()
|
||||
|
||||
def load_session(self, session_id: str) -> LoadedSession:
|
||||
session = self.store.get_session(session_id)
|
||||
if session.provider != self.provider.name or session.model != self.provider.model:
|
||||
raise SessionProviderMismatchError(
|
||||
"Die Sitzung verwendet "
|
||||
f"{session.provider}/{session.model}, aktiv ist "
|
||||
f"{self.provider.name}/{self.provider.model}."
|
||||
)
|
||||
return LoadedSession(session, self.store.get_messages(session_id))
|
||||
|
||||
def send(self, session_id: str, text: str) -> str:
|
||||
normalized = text.strip()
|
||||
if not normalized:
|
||||
raise ValueError("Eine leere Nachricht wird nicht gesendet.")
|
||||
loaded = self.load_session(session_id)
|
||||
messages = [*loaded.messages, ChatMessage("user", normalized)]
|
||||
response = self.provider.chat(messages)
|
||||
self.store.append_exchange(session_id, normalized, response)
|
||||
return response
|
||||
|
||||
def clear_session(self, session_id: str) -> None:
|
||||
self.store.clear_messages(session_id)
|
||||
Reference in New Issue
Block a user