ai-agent/internal/ice/automemory.go
admin 8dc496b626
Some checks failed
CI / test (push) Has been cancelled
Release / release (push) Failing after 4m36s
first commit
2026-03-08 15:40:34 +07:00

77 lines
2.2 KiB
Go

package ice
import (
"context"
"fmt"
"strings"
"ai-agent/internal/llm"
"ai-agent/internal/memory"
)
var autoMemorySystemPrompt = "Extract any important facts, user preferences, decisions, or action items from this exchange.\n" +
"Output one item per line in the format: TYPE: content\n" +
"Where TYPE is one of: FACT, DECISION, PREFERENCE, TODO\n" +
"If there is nothing worth remembering, output exactly: NONE"
var autoMemoryUserTemplate = "User: %s\nAssistant: %s"
type AutoMemory struct {
client llm.Client
memStore *memory.Store
}
func (am *AutoMemory) Detect(ctx context.Context, userMsg, assistantMsg string) error {
if am.memStore == nil {
return nil
}
if len(userMsg) < 20 && len(assistantMsg) < 50 {
return nil
}
prompt := fmt.Sprintf(autoMemoryUserTemplate, userMsg, assistantMsg)
var response strings.Builder
err := am.client.ChatStream(ctx, llm.ChatOptions{
System: autoMemorySystemPrompt,
Messages: []llm.Message{
{Role: "user", Content: prompt},
},
}, func(chunk llm.StreamChunk) error {
response.WriteString(chunk.Text)
return nil
})
if err != nil {
return fmt.Errorf("auto-memory LLM call: %w", err)
}
return am.parseAndSave(response.String())
}
func (am *AutoMemory) parseAndSave(response string) error {
lines := strings.Split(strings.TrimSpace(response), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.EqualFold(line, "NONE") {
continue
}
parts := strings.SplitN(line, ": ", 2)
if len(parts) != 2 {
continue
}
typeName := strings.TrimSpace(parts[0])
content := strings.TrimSpace(parts[1])
if content == "" {
continue
}
tag := strings.ToLower(typeName)
switch tag {
case "fact", "decision", "preference", "todo":
// Valid type.
default:
continue
}
if _, err := am.memStore.Save(content, []string{tag, "auto"}); err != nil {
return fmt.Errorf("save auto-memory: %w", err)
}
}
return nil
}