From eab5b73846f70cb4102191f7c54e11165801dbf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Fri, 15 May 2026 11:46:02 +0800 Subject: [PATCH] Add files via upload --- internal/database/conversation.go | 4 +++- internal/database/process_detail_dedupe.go | 28 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 internal/database/process_detail_dedupe.go diff --git a/internal/database/conversation.go b/internal/database/conversation.go index d23506a4..7c3ffff0 100644 --- a/internal/database/conversation.go +++ b/internal/database/conversation.go @@ -26,7 +26,7 @@ type Conversation struct { // Message 消息 type Message struct { ID string `json:"id"` - ConversationID string `json:"conversationId"` + ConversationID string `json:"conversationId"` Role string `json:"role"` Content string `json:"content"` ReasoningContent string `json:"reasoningContent,omitempty"` @@ -117,6 +117,7 @@ func (db *DB) GetConversationByWebshellConnectionID(connectionID string) (*Conve } for i := range conv.Messages { if details, ok := processDetailsMap[conv.Messages[i].ID]; ok { + details = DedupeConsecutiveProcessDetails(details) detailsJSON := make([]map[string]interface{}, len(details)) for j, detail := range details { var data interface{} @@ -235,6 +236,7 @@ func (db *DB) GetConversation(id string) (*Conversation, error) { // 将过程详情附加到对应的消息上 for i := range conv.Messages { if details, ok := processDetailsMap[conv.Messages[i].ID]; ok { + details = DedupeConsecutiveProcessDetails(details) // 将ProcessDetail转换为JSON格式,以便前端使用 detailsJSON := make([]map[string]interface{}, len(details)) for j, detail := range details { diff --git a/internal/database/process_detail_dedupe.go b/internal/database/process_detail_dedupe.go new file mode 100644 index 00000000..8faa11d3 --- /dev/null +++ b/internal/database/process_detail_dedupe.go @@ -0,0 +1,28 @@ +package database + +import ( + "fmt" + "strings" +) + +// DedupeConsecutiveProcessDetails 去掉相邻且语义相同的过程详情(使用 DB 中 data 列原始 JSON 作指纹,避免 map 序列化键序不稳定)。 +func DedupeConsecutiveProcessDetails(rows []ProcessDetail) []ProcessDetail { + if len(rows) < 2 { + return rows + } + out := make([]ProcessDetail, 0, len(rows)) + var lastKey string + for _, d := range rows { + key := processDetailRowKey(d) + if len(out) > 0 && key != "" && key == lastKey { + continue + } + out = append(out, d) + lastKey = key + } + return out +} + +func processDetailRowKey(d ProcessDetail) string { + return fmt.Sprintf("%s\x00%s\x00%s", d.EventType, strings.TrimSpace(d.Message), d.Data) +}