Version: 0.8.1.dev.260326

后端:
1.获取agent聊天历史记录接口做了如下更改:
(1)对reasoning_content也做了存储,同步更改了mysql和redis缓存的读写逻辑
(2)为了承接前端的重试/修改消息的逻辑,进行了一些代码和表单上的改动
前端:
1.agent页面新增了很多小组件,改善交互体验
2.新增重试消息/修改消息并重新发送功能,前者有bug,可能前后端都有问题,待修复。
This commit is contained in:
Losita
2026-03-26 22:15:16 +08:00
parent ddf4c09f69
commit ddb0d9cc17
13 changed files with 1828 additions and 322 deletions

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/cloudwego/eino/schema"
@@ -163,6 +164,79 @@ func (m *AgentCache) BackfillHistory(ctx context.Context, sessionID string, mess
return err
}
func (m *AgentCache) ApplyRetrySeed(ctx context.Context, sessionID, retryGroupID string, sourceUserMessageID, sourceAssistantMessageID int) error {
if m == nil || m.client == nil {
return nil
}
groupID := strings.TrimSpace(retryGroupID)
if groupID == "" {
return nil
}
vals, err := m.client.LRange(ctx, m.historyKey(sessionID), 0, -1).Result()
if err != nil {
return err
}
if len(vals) == 0 {
return nil
}
changed := false
targets := map[int]struct{}{}
if sourceUserMessageID > 0 {
targets[sourceUserMessageID] = struct{}{}
}
if sourceAssistantMessageID > 0 {
targets[sourceAssistantMessageID] = struct{}{}
}
if len(targets) == 0 {
return nil
}
indexOne := 1
for idx, raw := range vals {
var msg schema.Message
if err := json.Unmarshal([]byte(raw), &msg); err != nil {
return err
}
historyID := extractMessageHistoryID(&msg)
if historyID <= 0 {
continue
}
if _, ok := targets[historyID]; !ok {
continue
}
if msg.Extra == nil {
msg.Extra = make(map[string]any)
}
msg.Extra["retry_group_id"] = groupID
msg.Extra["retry_index"] = indexOne
updated, err := json.Marshal(&msg)
if err != nil {
return err
}
vals[idx] = string(updated)
changed = true
}
if !changed {
return nil
}
pipe := m.client.Pipeline()
key := m.historyKey(sessionID)
pipe.Del(ctx, key)
values := make([]interface{}, 0, len(vals))
for _, item := range vals {
values = append(values, item)
}
pipe.RPush(ctx, key, values...)
pipe.LTrim(ctx, key, 0, int64(len(vals)-1))
pipe.Expire(ctx, key, m.expiration)
_, err = pipe.Exec(ctx)
return err
}
func (m *AgentCache) ClearHistory(ctx context.Context, sessionID string) error {
historyKey := m.historyKey(sessionID)
windowKey := m.historyWindowKey(sessionID)
@@ -188,3 +262,46 @@ func (m *AgentCache) DeleteConversationStatus(ctx context.Context, sessionID str
key := fmt.Sprintf("smartflow:conversation_status:%s", sessionID)
return m.client.Del(ctx, key).Err()
}
func extractMessageHistoryID(msg *schema.Message) int {
if msg == nil || msg.Extra == nil {
return 0
}
raw, ok := msg.Extra["history_id"]
if !ok {
return 0
}
// 1. history_id 主要来自 DB 回填,正常情况下是 number。
// 2. 但 Redis 往返、灰度期数据修复或手工写入时,仍可能出现字符串数字。
// 3. 这里做一次宽松解析,避免重试分组补种时因为类型差异找不到源消息。
switch v := raw.(type) {
case int:
return v
case int32:
return int(v)
case int64:
return int(v)
case float64:
return int(v)
case json.Number:
if parsed, err := v.Int64(); err == nil {
return int(parsed)
}
if parsed, err := v.Float64(); err == nil {
return int(parsed)
}
return 0
case string:
trimmed := strings.TrimSpace(v)
if trimmed == "" {
return 0
}
parsed, err := strconv.Atoi(trimmed)
if err != nil {
return 0
}
return parsed
default:
return 0
}
}