feat: thread_has_agent_participation + ACK reply linkage

1. thread_has_agent_participation (SOWA Priority 11):
   - New function has_agent_chat_participation() in behavior_policy.py
   - Checks if agent responded to ANY user in this chat within 30min
   - When active + user asks question/imperative → agent responds
   - Different from per-user conversation_context (Priority 12)
   - Wired into both detect_explicit_request() and analyze_message()

2. ACK reply_to_message_id:
   - When SOWA sends ACK ("NUTRA тут"), it now replies to the user's
     message instead of sending a standalone message
   - Better UX: visually linked to what the user wrote
   - Uses allow_sending_without_reply=True for safety

Known issue (not fixed - too risky):
- Lines 1368-1639 in http_api.py are dead code (brand commands /бренд)
  at incorrect indentation level (8 spaces, inside unreachable block)
- These commands never worked on NODE1, fixing 260 lines of indentation
  carries regression risk — deferred to separate cleanup PR

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Apple
2026-02-09 09:24:00 -08:00
parent 1f4472ec18
commit 27e66b90bf
2 changed files with 32 additions and 4 deletions

View File

@@ -118,6 +118,24 @@ def has_recent_interaction(agent_id: str, chat_id: str, user_id: str) -> bool:
return is_recent
def has_agent_chat_participation(agent_id: str, chat_id: str) -> bool:
"""
Check if agent has responded to ANY user in this chat recently.
Used for thread_has_agent_participation (SOWA Priority 11).
Different from has_recent_interaction():
- has_recent_interaction: THIS user talked to agent (per-user)
- has_agent_chat_participation: agent talked to ANYONE in this chat (per-chat)
"""
now = time.time()
str_chat_id = str(chat_id)
for (aid, cid, _uid), timestamp in _conversation_context.items():
if aid == agent_id and cid == str_chat_id:
if now - timestamp < CONVERSATION_CONTEXT_TIMEOUT:
return True
return False
def cleanup_old_contexts() -> None:
"""Remove old conversation contexts and ACK cooldowns to prevent memory leak."""
global _conversation_context, _ack_cooldown