mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-21 14:47:34 +08:00
enforce memory recall hints and long-term memory write gating
This commit is contained in:
@@ -307,6 +307,11 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
|||||||
|
|
||||||
history := al.sessions.GetHistory(msg.SessionKey)
|
history := al.sessions.GetHistory(msg.SessionKey)
|
||||||
summary := al.sessions.GetSummary(msg.SessionKey)
|
summary := al.sessions.GetSummary(msg.SessionKey)
|
||||||
|
if shouldRecallMemory(msg.Content) {
|
||||||
|
if recall, err := al.tools.Execute(ctx, "memory_search", map[string]interface{}{"query": msg.Content, "maxResults": 3}); err == nil && strings.TrimSpace(recall) != "" {
|
||||||
|
summary = strings.TrimSpace(summary + "\n\n[Memory Recall]\n" + recall)
|
||||||
|
}
|
||||||
|
}
|
||||||
if explicitPref := ExtractLanguagePreference(msg.Content); explicitPref != "" {
|
if explicitPref := ExtractLanguagePreference(msg.Content); explicitPref != "" {
|
||||||
al.sessions.SetPreferredLanguage(msg.SessionKey, explicitPref)
|
al.sessions.SetPreferredLanguage(msg.SessionKey, explicitPref)
|
||||||
}
|
}
|
||||||
@@ -828,6 +833,20 @@ func truncateString(s string, maxLen int) string {
|
|||||||
return s[:maxLen-3] + "..."
|
return s[:maxLen-3] + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldRecallMemory(text string) bool {
|
||||||
|
s := strings.ToLower(strings.TrimSpace(text))
|
||||||
|
if s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
keywords := []string{"remember", "记得", "上次", "之前", "偏好", "preference", "todo", "待办", "决定", "decision", "日期", "when did", "what did we"}
|
||||||
|
for _, k := range keywords {
|
||||||
|
if strings.Contains(s, k) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func alSessionListForTool(sm *session.SessionManager, limit int) []tools.SessionInfo {
|
func alSessionListForTool(sm *session.SessionManager, limit int) []tools.SessionInfo {
|
||||||
items := sm.List(limit)
|
items := sm.List(limit)
|
||||||
out := make([]tools.SessionInfo, 0, len(items))
|
out := make([]tools.SessionInfo, 0, len(items))
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ func (t *MemoryWriteTool) Execute(ctx context.Context, args map[string]interface
|
|||||||
|
|
||||||
formatted := formatMemoryLine(content, importance, source, tags)
|
formatted := formatMemoryLine(content, importance, source, tags)
|
||||||
|
|
||||||
|
if (kind == "longterm" || kind == "memory" || kind == "permanent") && !allowLongTermWrite(importance, tags) {
|
||||||
|
kind = "daily"
|
||||||
|
formatted = formatMemoryLine(content, importance, source, append(tags, "downgraded:longterm_gate"))
|
||||||
|
}
|
||||||
|
|
||||||
switch kind {
|
switch kind {
|
||||||
case "longterm", "memory", "permanent":
|
case "longterm", "memory", "permanent":
|
||||||
path := filepath.Join(t.workspace, "MEMORY.md")
|
path := filepath.Join(t.workspace, "MEMORY.md")
|
||||||
@@ -179,3 +184,17 @@ func formatMemoryLine(content, importance, source string, tags []string) string
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("[%s] %s", strings.Join(meta, " | "), content)
|
return fmt.Sprintf("[%s] %s", strings.Join(meta, " | "), content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func allowLongTermWrite(importance string, tags []string) bool {
|
||||||
|
if strings.ToLower(strings.TrimSpace(importance)) == "high" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, t := range tags {
|
||||||
|
s := strings.ToLower(strings.TrimSpace(t))
|
||||||
|
switch s {
|
||||||
|
case "preference", "decision", "rule", "policy", "identity":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user