Inbox: people before system notices and newest first; wait wakes on new or human messages, not an old notice backlog; mark_read MCP tool

DeepSeek's inbox was buried under 78 automatic baseline notices read oldest
first, so it missed direct answers.
This commit is contained in:
KeelrLeek committed 2026-10-05 18:19:19 -05:00
1 parent f708e3025c
commit f1241c19a3
4 files changed
+50 -8

No files matched your search

+24 -5
View File
@@ -447,15 +447,21 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin):
out.setdefault(r["corrects"], []).append(r["id"])
return out
def inbox(self, agent, unread_only=True, limit=30, mark_read=True):
def inbox(self, agent, unread_only=True, limit=30, mark_read=True, after_id=None):
self._check_agent(agent)
query = ("SELECT m.*, t.topic, t.subject, d.read_at, d.acked_at FROM deliveries d "
"JOIN messages m ON m.id=d.message_id JOIN threads t ON t.id=m.thread_id WHERE d.agent=?")
args = [agent]
if unread_only:
query += " AND d.read_at IS NULL"
query += (" ORDER BY CASE m.importance WHEN 'urgent' THEN 0 WHEN 'high' THEN 1 ELSE 2 END, m.id"
if unread_only else " ORDER BY m.id DESC")
rows = [self._message_dict(r) for r in self.conn.execute(query + " LIMIT ?", (agent, int(limit)))]
if after_id is not None:
query += " AND m.id > ?"
args.append(int(after_id))
# urgent, then high, then the rest; within each, people before system notices, newest first, so a backlog
# of old automatic notices never hides what arrived since
query += (" ORDER BY CASE m.importance WHEN 'urgent' THEN 0 WHEN 'high' THEN 1 ELSE 2 END,"
" (m.origin = 'system'), m.id DESC" if unread_only else " ORDER BY m.id DESC")
rows = [self._message_dict(r) for r in self.conn.execute(query + " LIMIT ?", (*args, int(limit)))]
if mark_read and rows:
self.mark_read(agent, [r["id"] for r in rows])
return rows
@@ -472,6 +478,18 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin):
self._touch(c, agent)
self._write(mark)
def last_delivered_id(self, agent):
row = self.conn.execute("SELECT MAX(message_id) m FROM deliveries WHERE agent=?", (agent,)).fetchone()
return row["m"] or 0
def unread_count_after(self, agent, after_id):
"""Unread messages worth waking for: anything that arrived after after_id, and any unread message from a
person or agent however old (only an old backlog of automatic system notices is ignored)."""
row = self.conn.execute("SELECT COUNT(*) n FROM deliveries d JOIN messages m ON m.id=d.message_id "
"WHERE d.agent=? AND d.read_at IS NULL AND (d.message_id > ? OR m.origin <> 'system')",
(agent, int(after_id))).fetchone()
return row["n"]
def unread_count(self, agent):
row = self.conn.execute("SELECT COUNT(*) n, SUM(m.importance='urgent') u FROM deliveries d JOIN messages m "
"ON m.id=d.message_id WHERE d.agent=? AND d.read_at IS NULL", (agent,)).fetchone()
@@ -483,9 +501,10 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin):
timeout = max(0.0, min(float(timeout), 3600.0))
deadline = time.monotonic() + timeout
self.touch(agent)
since = self.last_delivered_id(agent) # wake on what arrives from now on, not on an old backlog
while True:
stops = self.stopped(agent)
n, _ = self.unread_count(agent)
n = self.unread_count_after(agent, since)
if n or stops or time.monotonic() >= deadline:
messages = self.inbox(agent, unread_only=True, limit=30, mark_read=mark_read) if n else []
return {"messages": messages, "stopped": [f["key"] for f in stops],