Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0acbe53fad |
@@ -1 +1 @@
|
||||
{"task_file":"dev/tasks/GEN2-008-promote-episode-and-experience-v2-including-negative-experience.json","task_id":"GEN2-008","task_revision":1}
|
||||
{"task_file":"dev/tasks/GEN2-009-build-memory-retrieval-fabric-as-rebuildable-projections.json","task_id":"GEN2-009","task_revision":1}
|
||||
@@ -0,0 +1,92 @@
|
||||
package retrieval
|
||||
|
||||
import "sort"
|
||||
|
||||
type Lane string
|
||||
|
||||
const (
|
||||
LaneSemantic Lane = "SEMANTIC"
|
||||
LaneEntity Lane = "ENTITY"
|
||||
LaneTemporal Lane = "TEMPORAL"
|
||||
LaneGoal Lane = "GOAL"
|
||||
LanePositiveExperience Lane = "POSITIVE_EXPERIENCE"
|
||||
LaneNegativeExperience Lane = "NEGATIVE_EXPERIENCE"
|
||||
LaneContradiction Lane = "CONTRADICTION"
|
||||
LaneSkill Lane = "SKILL"
|
||||
)
|
||||
|
||||
// RetrievalDocument is disposable read-side projection data. SourceRef and
|
||||
// Owner preserve provenance; this type never becomes canonical meaning.
|
||||
type RetrievalDocument struct {
|
||||
ID string
|
||||
SourceRef string
|
||||
Owner string
|
||||
PrincipalID string
|
||||
ContextScopeRef string
|
||||
VersionRef string
|
||||
Lane Lane
|
||||
Text string
|
||||
Relevance int
|
||||
Freshness int
|
||||
Confidence int
|
||||
Salience int
|
||||
Cost int
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
PrincipalID string
|
||||
ContextScopeRef string
|
||||
VersionRef string
|
||||
Lanes []Lane
|
||||
Limit int
|
||||
}
|
||||
|
||||
func FilterAndRank(documents []RetrievalDocument, query Query) []RetrievalDocument {
|
||||
filtered := make([]RetrievalDocument, 0, len(documents))
|
||||
for _, doc := range documents {
|
||||
if doc.PrincipalID != query.PrincipalID || (query.ContextScopeRef != "" && doc.ContextScopeRef != query.ContextScopeRef) || (query.VersionRef != "" && doc.VersionRef != query.VersionRef) || !containsLane(query.Lanes, doc.Lane) {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, doc)
|
||||
}
|
||||
sort.SliceStable(filtered, func(i, j int) bool {
|
||||
left := filtered[i].Relevance + filtered[i].Freshness + filtered[i].Confidence + filtered[i].Salience - filtered[i].Cost
|
||||
right := filtered[j].Relevance + filtered[j].Freshness + filtered[j].Confidence + filtered[j].Salience - filtered[j].Cost
|
||||
if left != right {
|
||||
return left > right
|
||||
}
|
||||
return filtered[i].ID < filtered[j].ID
|
||||
})
|
||||
if query.Limit > 0 && len(filtered) > query.Limit {
|
||||
filtered = filtered[:query.Limit]
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func containsLane(lanes []Lane, lane Lane) bool {
|
||||
if len(lanes) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, v := range lanes {
|
||||
if v == lane {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ProjectionBuilder interface {
|
||||
Build() ([]RetrievalDocument, error)
|
||||
}
|
||||
|
||||
func Rebuild(builders ...ProjectionBuilder) ([]RetrievalDocument, error) {
|
||||
var result []RetrievalDocument
|
||||
for _, builder := range builders {
|
||||
docs, err := builder.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, docs...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package retrieval_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/runtime/retrieval"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScopeAndVersionFilterBeforeRanking(t *testing.T) {
|
||||
docs := []retrieval.RetrievalDocument{{ID: "wrong-company", PrincipalID: "a", ContextScopeRef: "b", VersionRef: "v", Lane: retrieval.LaneSemantic, Relevance: 100}, {ID: "right", PrincipalID: "a", ContextScopeRef: "a", VersionRef: "v", Lane: retrieval.LaneNegativeExperience, Relevance: 1}, {ID: "wrong-version", PrincipalID: "a", ContextScopeRef: "a", VersionRef: "old", Lane: retrieval.LaneSemantic, Relevance: 100}}
|
||||
got := retrieval.FilterAndRank(docs, retrieval.Query{PrincipalID: "a", ContextScopeRef: "a", VersionRef: "v", Lanes: []retrieval.Lane{retrieval.LaneSemantic, retrieval.LaneNegativeExperience}, Limit: 10})
|
||||
if len(got) != 1 || got[0].ID != "right" {
|
||||
t.Fatalf("got %#v", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user