Browse Source

补充话题摘要的最后发送者

LSamien 2 months ago
parent
commit
4c78f8c1cf

+ 39 - 0
hermes-plugins/yaoyao/dashboard/group_store.py

@@ -1938,6 +1938,18 @@ class GroupStore:
              WHERE latest.topic_id = topic.id AND latest.visible = 1
                AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
              ORDER BY latest.seq DESC LIMIT 1), '') AS preview,
+            (SELECT latest.sender_kind FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_kind,
+            (SELECT latest.sender_id FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_id,
+            (SELECT latest.sender_name FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_name,
             (SELECT COUNT(*) FROM group_messages AS unread
              WHERE unread.topic_id = topic.id AND unread.visible = 1
                AND unread.sender_kind = 'agent'
@@ -1993,6 +2005,18 @@ class GroupStore:
              WHERE latest.topic_id = topic.id AND latest.visible = 1
                AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
              ORDER BY latest.seq DESC LIMIT 1), '') AS preview,
+            (SELECT latest.sender_kind FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_kind,
+            (SELECT latest.sender_id FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_id,
+            (SELECT latest.sender_name FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_name,
             (SELECT COUNT(*) FROM group_messages AS unread
              WHERE unread.topic_id = topic.id AND unread.visible = 1
                AND unread.sender_kind = 'agent'
@@ -6104,6 +6128,18 @@ class GroupStore:
              WHERE latest.topic_id = topic.id AND latest.visible = 1
                AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
              ORDER BY latest.seq DESC LIMIT 1), '') AS preview,
+            (SELECT latest.sender_kind FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_kind,
+            (SELECT latest.sender_id FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_id,
+            (SELECT latest.sender_name FROM group_messages AS latest
+             WHERE latest.topic_id = topic.id AND latest.visible = 1
+               AND (TRIM(latest.content) != '' OR TRIM(latest.error) != '')
+             ORDER BY latest.seq DESC LIMIT 1) AS last_sender_name,
             (SELECT COUNT(*) FROM group_messages AS unread
              WHERE unread.topic_id = topic.id AND unread.visible = 1
                AND unread.sender_kind = 'agent'
@@ -7058,6 +7094,9 @@ class GroupStore:
             "roomId": row["room_id"],
             "title": row["title"],
             "preview": preview[:_TOPIC_PREVIEW_LENGTH],
+            "lastSenderKind": row["last_sender_kind"],
+            "lastSenderId": row["last_sender_id"],
+            "lastSenderName": row["last_sender_name"],
             "messageCount": int(row["message_count"]),
             "unreadCount": int(row["unread_count"]),
             "latestMessageSeq": int(row["latest_message_seq"]),

+ 54 - 0
hermes-plugins/yaoyao/dashboard/tests/test_group_topics_contract.py

@@ -159,6 +159,55 @@ class GroupTopicsContractTests(unittest.TestCase):
             with self.assertRaisesRegex(ValueError, "cursor is malformed"):
                 store.list_global_topics(limit=2, cursor="not-a-valid-cursor")
 
+    def test_topic_summaries_expose_the_latest_agent_sender(self) -> None:
+        with tempfile.TemporaryDirectory() as directory:
+            store = GroupStore(Path(directory) / "group.db")
+            store.initialize()
+            room = store.create_room({
+                "requestId": new_id(),
+                "name": "研究团队",
+                "cwd": "",
+                "agents": [{
+                    "profile": "researcher",
+                    "displayName": "研究 Agent",
+                }],
+            })
+            [agent] = room["agents"]
+            created = store.create_human_message(
+                room["id"],
+                request_id=new_id(),
+                client_message_id=new_id(),
+                topic_id=new_id(),
+                content="请整理结论",
+                mention_agent_ids=[agent["id"]],
+            )
+            [run] = created["runs"]
+            self.assertEqual(store.claim_next_runnable_run()["id"], run["id"])
+            reply = store.upsert_agent_message(
+                run["id"],
+                content="已经整理完成",
+                reasoning="",
+                tool_state=[],
+                status="completed",
+            )
+
+            [room_topic] = store.list_topics(
+                room["id"], limit=10, cursor=None
+            ).items
+            global_topic = next(
+                item for item in store.list_global_topics(
+                    limit=10, cursor=None
+                ).items
+                if item["id"] == room_topic["id"]
+            )
+            for summary in (room_topic, global_topic):
+                self.assertEqual(summary["preview"], "已经整理完成")
+                self.assertEqual(summary["lastSenderKind"], "agent")
+                self.assertEqual(summary["lastSenderId"], agent["id"])
+                self.assertEqual(
+                    summary["lastSenderName"], reply["senderName"]
+                )
+
     def test_group_upload_persists_server_readable_attachment(self) -> None:
         with tempfile.TemporaryDirectory() as directory:
             store = GroupStore(Path(directory) / "group.db")
@@ -537,6 +586,9 @@ class GroupTopicsContractTests(unittest.TestCase):
                     "roomId",
                     "title",
                     "preview",
+                    "lastSenderKind",
+                    "lastSenderId",
+                    "lastSenderName",
                     "messageCount",
                     "unreadCount",
                     "latestMessageSeq",
@@ -617,6 +669,8 @@ class GroupTopicsContractTests(unittest.TestCase):
             summary_a = next(item for item in summaries if item["id"] == topic_a)
             self.assertEqual(summary_a["title"], "第一个话题")
             self.assertEqual(summary_a["preview"], "第一个话题的后续")
+            self.assertEqual(summary_a["lastSenderKind"], "human")
+            self.assertEqual(summary_a["lastSenderName"], "你")
             self.assertEqual(summary_a["messageCount"], 4)
 
             other_room = store.create_room({

+ 6 - 0
src/client/utils/normalize.ts

@@ -425,9 +425,15 @@ export function normalizeGroupRun(value: unknown): GroupRun {
 
 export function normalizeGroupTopic(value: unknown): GroupTopicSummary {
   const source = record(value)
+  const lastSenderKind = string(pick(source, 'lastSenderKind', 'last_sender_kind'))
   return {
     id: string(source.id), roomId: string(pick(source, 'roomId', 'room_id')),
     title: string(source.title, '新话题'), preview: string(source.preview),
+    lastSenderKind: lastSenderKind === 'human' || lastSenderKind === 'agent'
+      || lastSenderKind === 'system' || lastSenderKind === 'unknown'
+      ? lastSenderKind : undefined,
+    lastSenderId: string(pick(source, 'lastSenderId', 'last_sender_id')) || undefined,
+    lastSenderName: string(pick(source, 'lastSenderName', 'last_sender_name')) || undefined,
     messageCount: number(pick(source, 'messageCount', 'message_count')),
     unreadCount: number(pick(source, 'unreadCount', 'unread_count')),
     latestMessageSeq: number(pick(source, 'latestMessageSeq', 'latest_message_seq')),

+ 3 - 0
src/shared/types.ts

@@ -400,6 +400,9 @@ export interface GroupTopicSummary {
   roomId: string
   title: string
   preview: string
+  lastSenderKind?: 'human' | 'agent' | 'system' | 'unknown'
+  lastSenderId?: string
+  lastSenderName?: string
   messageCount: number
   unreadCount?: number
   latestMessageSeq?: number