mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 17:27:31 +00:00
feat: 段页式记忆流转、coldcontext 重命名与安全治理
记忆层: - MemoryBlock 承载 FrameTS/PageSeq/PageKind/BlockRole/CallID - coldcontext 归档与回填按完整页传递,工具调用参数和配对键不丢失 - 召回先估算总 token,超预算时按全局页相似度标记 inactive - inactive 仅是 context 渲染期状态,不落盘、不进入 coldcontext,Prune 后重置 - Peek/确认/Remove 两阶段召回,失败保留冷上下文副本 - stablemem 记录 last_recalled_at,删块连带清理边 命名: - internal/memory/document → internal/memory/coldcontext - Doc/DocEvent/DocHit → ColdDoc/ColdEvent/ColdHit - ContextToColdContext/RecentColdContexts/FindColdContexts - 保留既有 JSON 标签、doc_ 文件前缀与 doc_count 状态键,兼容存量数据 安全治理: - 工具策略门禁、安全配置、事件总线发布者身份与入站脱敏 - 声明式 SecurityAPI 与 QQ owner/guest profile - 日志保留策略与相关 e2e/回归判据 验证:go build ./...、go vet ./...、go test ./...(62 包); 生产副本 e2e:7013 块迁移后 ID/向量/指纹 0 变化、0 缺失。
This commit is contained in:
@ -10,7 +10,7 @@ import (
|
||||
|
||||
agentAPI "github.com/JianFeeeee/HologramAgent/internal/agent/api"
|
||||
"github.com/JianFeeeee/HologramAgent/internal/memory"
|
||||
"github.com/JianFeeeee/HologramAgent/internal/memory/document"
|
||||
"github.com/JianFeeeee/HologramAgent/internal/memory/coldcontext"
|
||||
)
|
||||
|
||||
// 媒体记忆接线测试(块 union 化之后):验证媒体从对话进入块、挂到 L0 事件、
|
||||
@ -211,8 +211,8 @@ func TestPrune_NilDocStoreStillArchives(t *testing.T) {
|
||||
// 归档链路不依赖任何外部媒体存储:块随事件走,归档时整体迁移。
|
||||
dir := t.TempDir()
|
||||
emb := memory.NewStaticEmbedder()
|
||||
docStore := document.NewStore(filepath.Join(dir, "docs"), memory.TokenizeWords)
|
||||
if err := docStore.Start(); err != nil {
|
||||
coldcontextStore := coldcontext.NewStore(filepath.Join(dir, "docs"), memory.TokenizeWords)
|
||||
if err := coldcontextStore.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rc := NewRelevanceContext(filepath.Join(dir, "context.json"), emb)
|
||||
@ -224,7 +224,7 @@ func TestPrune_NilDocStoreStillArchives(t *testing.T) {
|
||||
Input: "内容",
|
||||
})
|
||||
}
|
||||
if n := rc.Prune("查询", 5, docStore); n == 0 {
|
||||
if n := rc.Prune("查询", 5, coldcontextStore); n == 0 {
|
||||
t.Fatal("无媒体参与时归档也应正常")
|
||||
}
|
||||
}
|
||||
@ -275,8 +275,8 @@ func TestPruneMigratesBlocksToDocument(t *testing.T) {
|
||||
// 这条路径不依赖任何引用账本。
|
||||
dir := t.TempDir()
|
||||
emb := memory.NewStaticEmbedder()
|
||||
docStore := document.NewStore(filepath.Join(dir, "docs"), memory.TokenizeWords)
|
||||
if err := docStore.Start(); err != nil {
|
||||
coldcontextStore := coldcontext.NewStore(filepath.Join(dir, "docs"), memory.TokenizeWords)
|
||||
if err := coldcontextStore.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rc := NewRelevanceContext(filepath.Join(dir, "context.json"), emb)
|
||||
@ -296,7 +296,7 @@ func TestPruneMigratesBlocksToDocument(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
if n := rc.Prune("完全不相关的查询", 5, docStore); n == 0 {
|
||||
if n := rc.Prune("完全不相关的查询", 5, coldcontextStore); n == 0 {
|
||||
t.Fatal("应有事件被归档")
|
||||
}
|
||||
|
||||
@ -305,8 +305,8 @@ func TestPruneMigratesBlocksToDocument(t *testing.T) {
|
||||
// ★ 2026-10-22 更新:L2 与 L1 同构后,事件正文也各自成为文本块
|
||||
// (Input 一块、Response 一块),所以这里不能再假设「文档只有 1 个块」。
|
||||
// 要断言的是**媒体块原样迁移**,而不是块总数。
|
||||
var found *document.Doc
|
||||
for _, d := range docStore.RecentDocs(20) {
|
||||
var found *coldcontext.ColdDoc
|
||||
for _, d := range coldcontextStore.RecentColdContexts(20) {
|
||||
for _, b := range d.Blocks {
|
||||
if b.ID == block.ID {
|
||||
found = d
|
||||
|
||||
Reference in New Issue
Block a user