Files
AskaEth 0ce498754a fix(memory,loop): 记忆作用域读写成对 + source_conversation 结构化(裁决 1.9/04.4.2/04.4.3)
- 04.4.2/1.9 读侧:Retrieve 候选集并集 = 本人 persona 域 ∪ user 共享域 ∪ project 共享域(他角色 persona 域仍排除),群聊/陌生人取受限收窄
- 写侧:群聊/陌生人整段跳过记忆提取(可查不可写),persona 域仅属主可写
- 04.4.3:source_conversation 不再由 LLM 自由生成(prompt 不索要、候选结构不含该键),落库时无条件盖真实 {session_id,message_id},编解码集中在 memory/source.go
- 新增跨角色种子用例(原用例即使关掉并集也会通过)+ 成对用例「同群聊上下文:读得到共享域、写不进 store」
- 同步 store.go/retrieve.go 文档注释,与 design/03 §3/§4 口径一致
2026-10-04 12:07:44 +08:00

57 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package memory
import "testing"
// TestSourceConversation_Roundtrip 证明溯源编码是机器可回溯的:
// Format 后 Parse 得回同一对真实 id(裁决 04.4.3,design/03 §2)。
func TestSourceConversation_Roundtrip(t *testing.T) {
t.Parallel()
raw := FormatSourceConversation("web:abc", "turn-1")
ref, ok := ParseSourceConversation(raw)
if !ok {
t.Fatalf("ParseSourceConversation(%q) ok = false, want structured", raw)
}
if ref.SessionID != "web:abc" || ref.MessageID != "turn-1" {
t.Fatalf("parsed ref = %+v, want session web:abc / message turn-1", ref)
}
}
// TestSourceConversation_BothBlank 证明两个 id 都缺时不落伪溯源
// (空串而不是空 JSON 对象)。
func TestSourceConversation_BothBlank(t *testing.T) {
t.Parallel()
if got := FormatSourceConversation("", " "); got != "" {
t.Fatalf("FormatSourceConversation(blank) = %q, want empty", got)
}
if _, ok := ParseSourceConversation(""); ok {
t.Fatal("ParseSourceConversation(\"\") ok = true, want false")
}
}
// TestSourceConversation_SessionOnly 证明只知会话粒度时溯源降级为
// 仅 session_id(渠道路径未挂 turn id 时的真实形态)。
func TestSourceConversation_SessionOnly(t *testing.T) {
t.Parallel()
raw := FormatSourceConversation("qq-obv11:group:123", "")
ref, ok := ParseSourceConversation(raw)
if !ok {
t.Fatalf("ParseSourceConversation(%q) ok = false, want structured", raw)
}
if ref.SessionID != "qq-obv11:group:123" || ref.MessageID != "" {
t.Fatalf("parsed ref = %+v, want session-only provenance", ref)
}
}
// TestSourceConversation_LegacyFreeTextNotStructured 证明裁决前的
// LLM 自由文本来源解不回结构化形状 —— 调用方靠 ok=false 区分
// 遗留行与真实溯源,而不是把自由文本误当 id。
func TestSourceConversation_LegacyFreeTextNotStructured(t *testing.T) {
t.Parallel()
for _, legacy := range []string{"conv.1", "昨天聊咖啡时提到的", `["session"]`, `{"other":1}`} {
if _, ok := ParseSourceConversation(legacy); ok {
t.Fatalf("ParseSourceConversation(%q) ok = true, want false for legacy free text", legacy)
}
}
}