-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvector.go
More file actions
114 lines (94 loc) · 2.71 KB
/
Copy pathvector.go
File metadata and controls
114 lines (94 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/philippgille/chromem-go"
)
var memoryCollection *chromem.Collection
func getDb() (*chromem.Collection, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("error while fetching the home directory of the user: %w", err)
}
joinedPaths := filepath.Join(homeDir, "db")
db, err := chromem.NewPersistentDB(joinedPaths, false)
if err != nil {
return nil, fmt.Errorf("an error occured while trying to connect to vector database: %w", err)
}
c, err := db.GetOrCreateCollection("user-memory", nil, chromemCustomGenerator)
if err != nil {
return nil, fmt.Errorf("an error occured while trying to initialize the vector database: %w", err)
}
return c, nil
}
// Store documents in the vector database.
func storeDocuments(ctx context.Context, collection *chromem.Collection, messages []chromem.Document) error {
if collection == nil {
return fmt.Errorf("vector collection is nil")
}
if len(messages) == 0 {
return nil
}
if err := collection.AddDocuments(ctx, messages, runtime.NumCPU()); err != nil {
return fmt.Errorf("an error occured while trying to store memories: %w", err)
}
return nil
}
// Get documents from the vector database.
func queryDocuments(ctx context.Context, collection *chromem.Collection, query string, limit int) ([]chromem.Result, error) {
if collection == nil {
return nil, fmt.Errorf("vector collection is nil")
}
if strings.TrimSpace(query) == "" {
return nil, nil
}
if limit <= 0 {
limit = 3
}
res, err := collection.Query(ctx, query, limit, nil, nil)
if err != nil {
return nil, fmt.Errorf("an error occured while trying to query the vector database: %w", err)
}
return res, nil
}
func recallMemories(ctx context.Context, query string, limit int) ([]string, error) {
if memoryCollection == nil {
return nil, nil
}
results, err := queryDocuments(ctx, memoryCollection, query, limit)
if err != nil {
return nil, err
}
memories := make([]string, 0, len(results))
seen := map[string]struct{}{}
for _, result := range results {
text := strings.TrimSpace(result.Content)
if text == "" {
continue
}
if _, ok := seen[text]; ok {
continue
}
seen[text] = struct{}{}
memories = append(memories, text)
}
return memories, nil
}
func injectMemoryContext(ctx context.Context, query string) string {
memories, err := recallMemories(ctx, query, 5)
if err != nil || len(memories) == 0 {
return query
}
var b strings.Builder
b.WriteString("Use these long-term memories only if relevant:\n")
for i, m := range memories {
fmt.Fprintf(&b, "%d. %s\n", i+1, m)
}
b.WriteString("\nUser query:\n")
b.WriteString(query)
return b.String()
}