Skip to content

Commit fd46060

Browse files
committed
feat(bot): auto-continue on session.idle with guard limit
1 parent 663644a commit fd46060

1 file changed

Lines changed: 34 additions & 3 deletions

File tree

bot/vk_longpoll.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ def __init__(
127127
self.seen_permissions: Dict[str, set] = {}
128128
self.seen_questions: Dict[str, set] = {}
129129

130+
# Защита от бесконечного цикла auto-continue: session_id -> count
131+
self.auto_continue_count: Dict[str, int] = {}
132+
self.AUTO_CONTINUE_MAX = 5
133+
130134
# ---------- SSE callbacks ----------
131135

132136
def _register_sse_callbacks(self):
@@ -375,8 +379,18 @@ async def _on_session_idle(self, event_type: str, data: dict):
375379
title = child_info.get("title", session_id[:12])
376380
await self.vk.send_message(target, f"✅ Subagent завершён: {title}")
377381
else:
378-
# Для основной сессии — тихо (последний text.ended уже отправил ответ)
379-
logger.debug(f"Session idle: {session_id}")
382+
# Для основной сессии — пытаемся продолжить работу агента (с защитой от бесконечного цикла)
383+
count = self.auto_continue_count.get(session_id, 0)
384+
if count >= self.AUTO_CONTINUE_MAX:
385+
logger.info(f"Session idle — max auto-continue ({self.AUTO_CONTINUE_MAX}) reached for {session_id}, stopping")
386+
target = THINKING_PEER_ID if THINKING_PEER_ID else user_id
387+
await self.vk.send_message(target, "✅ Агент завершил работу (достигнут лимит автопродолжений).")
388+
return
389+
self.auto_continue_count[session_id] = count + 1
390+
logger.info(f"Session idle — auto-continue {self.auto_continue_count[session_id]}/{self.AUTO_CONTINUE_MAX} for {session_id}")
391+
target = THINKING_PEER_ID if THINKING_PEER_ID else user_id
392+
await self.vk.send_message(target, f"⏳ Агент на паузе, продолжаю… ({self.auto_continue_count[session_id]}/{self.AUTO_CONTINUE_MAX})")
393+
await self.opencode_client.send_prompt(session_id, "Продолжи работу, выполни оставшиеся задачи из плана.")
380394

381395
async def _on_session_status(self, event_type: str, data: dict):
382396
"""Обрабатывает изменение статуса сессии (session.status)"""
@@ -441,7 +455,20 @@ async def _on_any_event(self, event_type: str, data: dict):
441455
"""Логирует все SSE события для отладки"""
442456
if event_type in self._NOISY_EVENTS:
443457
return
444-
logger.debug(f"SSE event: {event_type} keys={list(data.keys()) if isinstance(data, dict) else '?'}")
458+
# Логируем важные поля с реальными значениями
459+
extra = ""
460+
if event_type.endswith(".step.ended") and isinstance(data, dict):
461+
finish = data.get("finish", "?")
462+
extra = f" finish={finish}"
463+
elif event_type == "session.status" and isinstance(data, dict):
464+
status = data.get("status", {})
465+
if isinstance(status, dict):
466+
extra = f" status_type={status.get('type', '?')} status_message={status.get('message', '')}"
467+
else:
468+
extra = f" status={status}"
469+
elif event_type == "session.idle" and isinstance(data, dict):
470+
extra = f" sessionID={data.get('sessionID', '?')[:16]}"
471+
logger.debug(f"SSE event: {event_type}{extra} keys={list(data.keys()) if isinstance(data, dict) else '?'}")
445472

446473
# ---------- Обработка разрешений ----------
447474
def _format_permission_message(self, perm: dict) -> str:
@@ -765,6 +792,9 @@ async def _handle_user_message(self, user_id: int, message: dict):
765792
# Регистрируем маппинг session -> user для маршрутизации SSE событий
766793
self.session_to_user[session_id] = user_id
767794

795+
# Сброс счётчика автопродолжения при новом сообщении пользователя
796+
self.auto_continue_count[session_id] = 0
797+
768798
# Обрабатываем аттачи
769799
attachment_info = ""
770800
if attachments:
@@ -846,6 +876,7 @@ async def _handle_restart_command(self, user_id: int, text: str):
846876
if old_session_id and old_session_id in self.session_to_user:
847877
del self.session_to_user[old_session_id]
848878
self.session_to_user[new_session_id] = user_id
879+
self.auto_continue_count[new_session_id] = 0
849880

850881
await self.vk.send_message(user_id, f"✅ Модель {model_info} загружена")
851882

0 commit comments

Comments
 (0)