feat(memory): P2 读路径打分 + 桌面端记忆面板(看/改/删)
读路径(Generative Agents 公式的 Recency+Importance 两项,Relevance 待 P3): - memory.Get 改为 rankProfiles:Score=0.4·Recency+0.6·Importance,按分降序、截断 top-30。 Recency=0.98^天 指数衰减;未评分行用兜底 importance=5(不被不公平遗忘)。纯函数 + 单测。 - 新增 Store.List(结构化、不截断)+ memory_list 工具。 桌面端记忆面板: - gateway GET /memory(列表) + DELETE /memory?key=(软删),受保护组。 - api listMemory/deleteMemory;MemoryView 右侧从占位 → 真列表:按分排序展示 key/value/重要度/最近时间,可内联编辑(PUT)与删除(软删);左侧登记后自动刷新。 实测:PUT 两条 → GET 返回带 importance/last_seen 的有序列表(较新者靠前)→ DELETE 一条 (软删)→ 再 GET 已消失。rank/recency/兜底 importance 单测过;前端 tsc+构建通过。 至此记忆:召回(打分) + 历史 + 自动对账(P1) + 用户可管控(面板) 闭环。Relevance(Milvus) 留 P3。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
sharedbus "github.com/sundynix/sundynix-shared/bus"
|
||||
"github.com/sundynix/sundynix-shared/contract"
|
||||
@@ -75,6 +76,8 @@ func (g *Gateway) dispatch(ctx context.Context, call *contract.ToolCall) *contra
|
||||
return g.memoryUpsert(ctx, call)
|
||||
case "memory_delete":
|
||||
return g.memoryDelete(ctx, call)
|
||||
case "memory_list":
|
||||
return g.memoryList(ctx, call)
|
||||
case "history_get":
|
||||
return g.historyGet(ctx, call)
|
||||
case "history_append":
|
||||
@@ -136,6 +139,27 @@ func (g *Gateway) memoryUpsert(ctx context.Context, call *contract.ToolCall) *co
|
||||
return &contract.ToolResult{OK: true, Content: fmt.Sprintf("已记住 %s 的「%s」", uid, key)}
|
||||
}
|
||||
|
||||
// memoryList 返回某用户全部 active 偏好(结构化 JSON,供管理面板查看/编辑)。
|
||||
func (g *Gateway) memoryList(ctx context.Context, call *contract.ToolCall) *contract.ToolResult {
|
||||
uid, _ := call.Args["user_id"].(string)
|
||||
rows, err := g.memory.List(ctx, uid)
|
||||
if err != nil {
|
||||
return &contract.ToolResult{OK: false, Error: "memory_list: " + err.Error()}
|
||||
}
|
||||
type item struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Importance float64 `json:"importance"`
|
||||
LastSeen string `json:"last_seen"`
|
||||
}
|
||||
out := make([]item, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
out = append(out, item{Key: r.Key, Value: r.Value, Importance: r.Importance, LastSeen: r.LastSeenAt.Format(time.RFC3339)})
|
||||
}
|
||||
data, _ := json.Marshal(out)
|
||||
return &contract.ToolResult{OK: true, Content: string(data)}
|
||||
}
|
||||
|
||||
// memoryDelete 软删一条画像偏好(user_id + key)—— consolidate 判定过时/矛盾时调用。
|
||||
func (g *Gateway) memoryDelete(ctx context.Context, call *contract.ToolCall) *contract.ToolResult {
|
||||
uid, _ := call.Args["user_id"].(string)
|
||||
|
||||
Reference in New Issue
Block a user