feat(04-02): add matrix context management commands
- add save/load/reset/context handlers and matrix interception flows - persist current session and last token usage in prototype state
This commit is contained in:
parent
da0b76882e
commit
b52fdc4670
7 changed files with 638 additions and 21 deletions
|
|
@ -33,6 +33,7 @@ class PrototypeStateStore:
|
|||
self._settings: dict[str, dict[str, Any]] = {}
|
||||
self._saved_sessions: dict[str, list[dict[str, str]]] = {}
|
||||
self._last_tokens_used: dict[str, int] = {}
|
||||
self._current_session: dict[str, str] = {}
|
||||
|
||||
async def get_or_create_user(
|
||||
self,
|
||||
|
|
@ -93,3 +94,12 @@ class PrototypeStateStore:
|
|||
|
||||
async def set_last_tokens_used(self, user_id: str, tokens: int) -> None:
|
||||
self._last_tokens_used[user_id] = tokens
|
||||
|
||||
async def get_current_session(self, user_id: str) -> str | None:
|
||||
return self._current_session.get(user_id)
|
||||
|
||||
async def set_current_session(self, user_id: str, name: str) -> None:
|
||||
self._current_session[user_id] = name
|
||||
|
||||
async def clear_current_session(self, user_id: str) -> None:
|
||||
self._current_session.pop(user_id, None)
|
||||
|
|
|
|||
51
sdk/real.py
51
sdk/real.py
|
|
@ -1,26 +1,27 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, AsyncIterator
|
||||
from typing import AsyncIterator
|
||||
|
||||
from sdk.agent_session import build_thread_key
|
||||
from sdk.agent_api_wrapper import AgentApiWrapper
|
||||
from sdk.interface import Attachment, MessageChunk, MessageResponse, PlatformClient, User, UserSettings
|
||||
from sdk.prototype_state import PrototypeStateStore
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sdk.agent_session import AgentSessionClient
|
||||
|
||||
|
||||
class RealPlatformClient(PlatformClient):
|
||||
def __init__(
|
||||
self,
|
||||
agent_sessions: AgentSessionClient,
|
||||
agent_api: AgentApiWrapper,
|
||||
prototype_state: PrototypeStateStore,
|
||||
platform: str = "matrix",
|
||||
) -> None:
|
||||
self._agent_sessions = agent_sessions
|
||||
self._agent_api = agent_api
|
||||
self._prototype_state = prototype_state
|
||||
self._platform = platform
|
||||
|
||||
@property
|
||||
def agent_api(self) -> AgentApiWrapper:
|
||||
return self._agent_api
|
||||
|
||||
async def get_or_create_user(
|
||||
self,
|
||||
external_id: str,
|
||||
|
|
@ -40,8 +41,23 @@ class RealPlatformClient(PlatformClient):
|
|||
text: str,
|
||||
attachments: list[Attachment] | None = None,
|
||||
) -> MessageResponse:
|
||||
thread_key = build_thread_key(self._platform, user_id, chat_id)
|
||||
return await self._agent_sessions.send_message(thread_key=thread_key, text=text)
|
||||
response_parts: list[str] = []
|
||||
tokens_used = 0
|
||||
message_id = user_id
|
||||
|
||||
async for chunk in self.stream_message(user_id, chat_id, text, attachments=attachments):
|
||||
message_id = chunk.message_id
|
||||
if chunk.delta:
|
||||
response_parts.append(chunk.delta)
|
||||
if chunk.finished:
|
||||
tokens_used = chunk.tokens_used
|
||||
|
||||
return MessageResponse(
|
||||
message_id=message_id,
|
||||
response="".join(response_parts),
|
||||
tokens_used=tokens_used,
|
||||
finished=True,
|
||||
)
|
||||
|
||||
async def stream_message(
|
||||
self,
|
||||
|
|
@ -50,9 +66,20 @@ class RealPlatformClient(PlatformClient):
|
|||
text: str,
|
||||
attachments: list[Attachment] | None = None,
|
||||
) -> AsyncIterator[MessageChunk]:
|
||||
thread_key = build_thread_key(self._platform, user_id, chat_id)
|
||||
async for chunk in self._agent_sessions.stream_message(thread_key=thread_key, text=text):
|
||||
yield chunk
|
||||
self._agent_api.last_tokens_used = 0
|
||||
async for event in self._agent_api.send_message(text):
|
||||
yield MessageChunk(
|
||||
message_id=user_id,
|
||||
delta=event.text,
|
||||
finished=False,
|
||||
)
|
||||
await self._prototype_state.set_last_tokens_used(user_id, self._agent_api.last_tokens_used)
|
||||
yield MessageChunk(
|
||||
message_id=user_id,
|
||||
delta="",
|
||||
finished=True,
|
||||
tokens_used=self._agent_api.last_tokens_used,
|
||||
)
|
||||
|
||||
async def get_settings(self, user_id: str) -> UserSettings:
|
||||
return await self._prototype_state.get_settings(user_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue