-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcontext_string.go
More file actions
148 lines (127 loc) · 4.09 KB
/
Copy pathcontext_string.go
File metadata and controls
148 lines (127 loc) · 4.09 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package zep
import (
"fmt"
"strings"
"time"
)
// dateFormat defines the format for date strings
const dateFormat = "2006-01-02 15:04:05"
// templateString defines the template for context information
const templateString = `
FACTS and ENTITIES%s represent relevant context to the current conversation.
# These are the most relevant facts and their valid date ranges
# format: FACT (Date range: from - to)
<FACTS>
%s
</FACTS>
# These are the most relevant entities
# Name: ENTITY_NAME
# Label: entity_label (if present)
# Attributes: (if present)
# attr_name: attr_value
# Summary: entity summary
<ENTITIES>
%s
</ENTITIES>
%s
`
// formatEdgeDateRange formats the date range of an entity edge.
func formatEdgeDateRange(edge *EntityEdge) string {
validAt := "date unknown"
invalidAt := "present"
if edge.ValidAt != nil && *edge.ValidAt != "" {
if t, err := time.Parse(time.RFC3339, *edge.ValidAt); err == nil {
validAt = t.Format(dateFormat)
}
}
if edge.InvalidAt != nil && *edge.InvalidAt != "" {
if t, err := time.Parse(time.RFC3339, *edge.InvalidAt); err == nil {
invalidAt = t.Format(dateFormat)
}
}
return fmt.Sprintf("%s - %s", validAt, invalidAt)
}
// ComposeContextString composes a search context from entity edges, nodes, and episodes.
func ComposeContextString(edges []*EntityEdge, nodes []*EntityNode, episodes []*Episode) string {
var facts []string
for _, edge := range edges {
fact := fmt.Sprintf(" - %s (%s)", edge.Fact, formatEdgeDateRange(edge))
facts = append(facts, fact)
}
var entities []string
for _, node := range nodes {
var entityParts []string
entityParts = append(entityParts, fmt.Sprintf("Name: %s", node.Name))
// Add label if present (excluding 'Entity' from labels)
if node.Labels != nil && len(node.Labels) > 0 {
labels := make([]string, 0, len(node.Labels))
for _, label := range node.Labels {
if label != "Entity" {
labels = append(labels, label)
}
}
if len(labels) > 0 {
entityParts = append(entityParts, fmt.Sprintf("Label: %s", labels[0]))
}
}
// Add attributes if present (excluding 'labels' attribute)
if node.Attributes != nil && len(node.Attributes) > 0 {
hasNonLabelAttributes := false
for key := range node.Attributes {
if key != "labels" {
hasNonLabelAttributes = true
break
}
}
if hasNonLabelAttributes {
entityParts = append(entityParts, "Attributes:")
for key, value := range node.Attributes {
if key != "labels" {
entityParts = append(entityParts, fmt.Sprintf(" %s: %v", key, value))
}
}
}
}
// Add summary if present
if node.Summary != "" {
entityParts = append(entityParts, fmt.Sprintf("Summary: %s", node.Summary))
}
entity := strings.Join(entityParts, "\n")
entities = append(entities, entity)
}
// Format episodes
var episodesList []string
if episodes != nil {
for _, episode := range episodes {
var rolePrefix string
if episode.Role != nil && *episode.Role != "" {
if episode.RoleType != nil && *episode.RoleType != "" {
rolePrefix = fmt.Sprintf("%s (%s): ", *episode.Role, *episode.RoleType)
} else {
rolePrefix = fmt.Sprintf("%s: ", *episode.Role)
}
} else if episode.RoleType != nil && *episode.RoleType != "" {
rolePrefix = fmt.Sprintf("(%s): ", *episode.RoleType)
}
timestamp := "date unknown"
if episode.CreatedAt != "" {
if t, err := time.Parse(time.RFC3339, episode.CreatedAt); err == nil {
timestamp = t.Format(dateFormat)
}
}
episodeStr := fmt.Sprintf(" - %s%s (%s)", rolePrefix, episode.Content, timestamp)
episodesList = append(episodesList, episodeStr)
}
}
factsStr := strings.Join(facts, "\n")
entitiesStr := strings.Join(entities, "\n")
episodesStr := strings.Join(episodesList, "\n")
// Determine if episodes section should be included
episodesHeader := ""
episodesSection := ""
if len(episodesList) > 0 {
episodesHeader = ", and EPISODES"
episodesSection = fmt.Sprintf("\n# These are the most relevant episodes\n<EPISODES>\n%s\n</EPISODES>", episodesStr)
}
return fmt.Sprintf(templateString, episodesHeader, factsStr, entitiesStr, episodesSection)
}