mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
fix(dm): Wait for msg JSON response and fix unread markers
Monitor: For .msg commands, keep waiting for expected_ack in response instead of completing on silence timeout. Waits up to half of cmd_timeout (5s) for the JSON to arrive before giving up. Unread: Apply 120s time-window dedup to outgoing messages in conversation listing, so retry messages don't inflate last_message_timestamp and cause permanent unread markers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -582,6 +582,20 @@ def get_dm_conversations(days: Optional[int] = 7) -> List[Dict]:
|
||||
"""
|
||||
messages, pubkey_to_name = read_dm_messages(days=days)
|
||||
|
||||
# Deduplicate outgoing retry messages: collapse same text+recipient within 120s
|
||||
deduped = []
|
||||
seen_outgoing = {} # (recipient, text) -> earliest timestamp
|
||||
for msg in messages:
|
||||
if msg.get('direction') == 'outgoing':
|
||||
key = (msg.get('recipient', ''), msg.get('content', ''))
|
||||
ts = msg.get('timestamp', 0)
|
||||
prev_ts = seen_outgoing.get(key)
|
||||
if prev_ts is not None and abs(ts - prev_ts) < 120:
|
||||
continue
|
||||
seen_outgoing[key] = ts
|
||||
deduped.append(msg)
|
||||
messages = deduped
|
||||
|
||||
# Build reverse mapping: name -> pubkey_prefix
|
||||
name_to_pubkey = {name: pk for pk, name in pubkey_to_name.items()}
|
||||
|
||||
|
||||
@@ -457,17 +457,16 @@ class MeshCLISession:
|
||||
# because meshcli may echo prompt immediately but real results come later
|
||||
is_slow_command = cmd_timeout >= 15
|
||||
# For .msg/.m commands, JSON response (with expected_ack) may arrive after prompt echo
|
||||
# with a gap > 300ms, so enforce a minimum wait to capture it
|
||||
# with a gap > 300ms, so keep waiting until JSON arrives or timeout
|
||||
cmd_str = response_dict.get("command", "")
|
||||
is_msg_command = cmd_str.lstrip('.').split()[0] in ('msg', 'm') if cmd_str.strip() else False
|
||||
if is_slow_command:
|
||||
min_elapsed = cmd_timeout * 0.7
|
||||
elif is_msg_command:
|
||||
min_elapsed = 1.5 # Wait at least 1.5s for JSON response
|
||||
else:
|
||||
min_elapsed = 0
|
||||
|
||||
logger.info(f"Monitor [{cmd_id}] started, cmd_timeout={cmd_timeout}s, min_elapsed={min_elapsed:.1f}s")
|
||||
logger.info(f"Monitor [{cmd_id}] started, cmd_timeout={cmd_timeout}s, "
|
||||
f"min_elapsed={min_elapsed:.1f}s, is_msg={is_msg_command}")
|
||||
|
||||
while not self.shutdown_flag.is_set():
|
||||
time.sleep(timeout_ms / 1000.0)
|
||||
@@ -481,6 +480,15 @@ class MeshCLISession:
|
||||
time_since_last_line = time.time() - response_dict.get("last_line_time", 0)
|
||||
total_elapsed = time.time() - start_time
|
||||
has_output = len(response_dict.get("response", [])) > 0
|
||||
response_lines = response_dict.get("response", [])
|
||||
|
||||
# For .msg commands: don't complete until we see expected_ack in response
|
||||
# or we've waited long enough (half of cmd_timeout)
|
||||
if is_msg_command and has_output:
|
||||
response_text = '\n'.join(response_lines)
|
||||
has_json = 'expected_ack' in response_text
|
||||
if not has_json and total_elapsed < cmd_timeout * 0.5:
|
||||
continue # Keep waiting for JSON response
|
||||
|
||||
# Can only complete if:
|
||||
# 1. Minimum elapsed time has passed (for slow commands), AND
|
||||
|
||||
Reference in New Issue
Block a user