feat(05-02): ship room-local clear semantics
- register clear as the room-context reset entrypoint when supported - keep save and context bound to room platform chat ids and clear old upstream state
This commit is contained in:
parent
df6d8bf628
commit
85e2fda6bc
2 changed files with 39 additions and 22 deletions
|
|
@ -47,13 +47,12 @@ def register_matrix_handlers(
|
||||||
dispatcher.register(IncomingCommand, "archive", make_handle_archive(client, store))
|
dispatcher.register(IncomingCommand, "archive", make_handle_archive(client, store))
|
||||||
dispatcher.register(IncomingCommand, "help", handle_help)
|
dispatcher.register(IncomingCommand, "help", handle_help)
|
||||||
dispatcher.register(IncomingCommand, "settings", handle_settings)
|
dispatcher.register(IncomingCommand, "settings", handle_settings)
|
||||||
dispatcher.register(
|
if prototype_state is not None:
|
||||||
IncomingCommand,
|
clear_handler = make_handle_reset(store, prototype_state)
|
||||||
"reset",
|
dispatcher.register(IncomingCommand, "clear", clear_handler)
|
||||||
make_handle_reset(store, prototype_state)
|
dispatcher.register(IncomingCommand, "reset", clear_handler)
|
||||||
if prototype_state is not None
|
else:
|
||||||
else handle_settings,
|
dispatcher.register(IncomingCommand, "reset", handle_settings)
|
||||||
)
|
|
||||||
dispatcher.register(IncomingCommand, "settings_skills", handle_settings_skills)
|
dispatcher.register(IncomingCommand, "settings_skills", handle_settings_skills)
|
||||||
dispatcher.register(IncomingCommand, "settings_connectors", handle_settings_connectors)
|
dispatcher.register(IncomingCommand, "settings_connectors", handle_settings_connectors)
|
||||||
dispatcher.register(IncomingCommand, "settings_soul", handle_settings_soul)
|
dispatcher.register(IncomingCommand, "settings_soul", handle_settings_soul)
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,17 @@ async def _resolve_context_scope(
|
||||||
return room_id, platform_chat_id
|
return room_id, platform_chat_id
|
||||||
|
|
||||||
|
|
||||||
|
async def _require_platform_context(
|
||||||
|
event: IncomingCommand,
|
||||||
|
store: StateStore,
|
||||||
|
chat_mgr,
|
||||||
|
) -> tuple[str, str]:
|
||||||
|
room_id, platform_chat_id = await _resolve_context_scope(event, store, chat_mgr)
|
||||||
|
if not platform_chat_id:
|
||||||
|
raise RuntimeError(f"matrix room context is incomplete: {room_id}")
|
||||||
|
return room_id, platform_chat_id
|
||||||
|
|
||||||
|
|
||||||
def make_handle_save(agent_api, store: StateStore, prototype_state: PrototypeStateStore):
|
def make_handle_save(agent_api, store: StateStore, prototype_state: PrototypeStateStore):
|
||||||
async def handle_save(
|
async def handle_save(
|
||||||
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
||||||
|
|
@ -85,11 +96,16 @@ def make_handle_save(agent_api, store: StateStore, prototype_state: PrototypeSta
|
||||||
logger.warning("save_agent_call_failed", error=str(exc))
|
logger.warning("save_agent_call_failed", error=str(exc))
|
||||||
return [OutgoingMessage(chat_id=event.chat_id, text=f"Ошибка при сохранении: {exc}")]
|
return [OutgoingMessage(chat_id=event.chat_id, text=f"Ошибка при сохранении: {exc}")]
|
||||||
|
|
||||||
_, platform_chat_id = await _resolve_context_scope(event, store, chat_mgr)
|
try:
|
||||||
|
_, platform_chat_id = await _require_platform_context(event, store, chat_mgr)
|
||||||
|
except RuntimeError as exc:
|
||||||
|
logger.warning("save_context_incomplete", error=str(exc))
|
||||||
|
return [OutgoingMessage(chat_id=event.chat_id, text="Контекст комнаты не готов. Попробуй позже.")]
|
||||||
|
|
||||||
await prototype_state.add_saved_session(
|
await prototype_state.add_saved_session(
|
||||||
event.user_id,
|
event.user_id,
|
||||||
name,
|
name,
|
||||||
source_context_id=platform_chat_id or event.chat_id,
|
source_context_id=platform_chat_id,
|
||||||
)
|
)
|
||||||
return [
|
return [
|
||||||
OutgoingMessage(
|
OutgoingMessage(
|
||||||
|
|
@ -132,9 +148,11 @@ def make_handle_reset(store: StateStore, prototype_state: PrototypeStateStore):
|
||||||
async def handle_reset(
|
async def handle_reset(
|
||||||
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
||||||
) -> list[OutgoingEvent]:
|
) -> list[OutgoingEvent]:
|
||||||
room_id = await _resolve_room_id(event, chat_mgr)
|
try:
|
||||||
room_meta = await get_room_meta(store, room_id)
|
room_id, old_chat_id = await _require_platform_context(event, store, chat_mgr)
|
||||||
old_chat_id = (room_meta or {}).get("platform_chat_id") or room_id
|
except RuntimeError as exc:
|
||||||
|
logger.warning("clear_context_incomplete", error=str(exc))
|
||||||
|
return [OutgoingMessage(chat_id=event.chat_id, text="Контекст комнаты не готов. Попробуй позже.")]
|
||||||
|
|
||||||
new_chat_id = await next_platform_chat_id(store)
|
new_chat_id = await next_platform_chat_id(store)
|
||||||
await set_platform_chat_id(store, room_id, new_chat_id)
|
await set_platform_chat_id(store, room_id, new_chat_id)
|
||||||
|
|
@ -143,6 +161,7 @@ def make_handle_reset(store: StateStore, prototype_state: PrototypeStateStore):
|
||||||
if callable(disconnect):
|
if callable(disconnect):
|
||||||
await disconnect(old_chat_id)
|
await disconnect(old_chat_id)
|
||||||
|
|
||||||
|
await prototype_state.clear_current_session(old_chat_id)
|
||||||
await prototype_state.clear_current_session(new_chat_id)
|
await prototype_state.clear_current_session(new_chat_id)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
@ -182,20 +201,19 @@ def make_handle_context(store: StateStore, prototype_state: PrototypeStateStore)
|
||||||
async def handle_context(
|
async def handle_context(
|
||||||
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
event: IncomingCommand, auth_mgr, platform, chat_mgr, settings_mgr
|
||||||
) -> list[OutgoingEvent]:
|
) -> list[OutgoingEvent]:
|
||||||
_, platform_chat_id = await _resolve_context_scope(event, store, chat_mgr)
|
try:
|
||||||
context_key = platform_chat_id or event.chat_id
|
_, platform_chat_id = await _require_platform_context(event, store, chat_mgr)
|
||||||
current_session = await prototype_state.get_current_session(context_key)
|
except RuntimeError as exc:
|
||||||
tokens_used = await prototype_state.get_last_tokens_used(context_key)
|
logger.warning("context_scope_incomplete", error=str(exc))
|
||||||
if platform_chat_id is not None and event.chat_id != platform_chat_id:
|
return [OutgoingMessage(chat_id=event.chat_id, text="Контекст комнаты не готов. Попробуй позже.")]
|
||||||
if current_session is None:
|
|
||||||
current_session = await prototype_state.get_current_session(event.chat_id)
|
current_session = await prototype_state.get_current_session(platform_chat_id)
|
||||||
if tokens_used == 0:
|
tokens_used = await prototype_state.get_last_tokens_used(platform_chat_id)
|
||||||
tokens_used = await prototype_state.get_last_tokens_used(event.chat_id)
|
|
||||||
sessions = await prototype_state.list_saved_sessions(event.user_id)
|
sessions = await prototype_state.list_saved_sessions(event.user_id)
|
||||||
|
|
||||||
lines = [
|
lines = [
|
||||||
"Контекст:",
|
"Контекст:",
|
||||||
f" Контекст чата: {platform_chat_id or event.chat_id}",
|
f" Контекст чата: {platform_chat_id}",
|
||||||
f" Сессия: {current_session or 'не загружена'}",
|
f" Сессия: {current_session or 'не загружена'}",
|
||||||
f" Токены (последний ответ): {tokens_used}",
|
f" Токены (последний ответ): {tokens_used}",
|
||||||
f" Сохранения ({len(sessions)}):",
|
f" Сохранения ({len(sessions)}):",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue