Files
zeekayandHanzo Dev ca8a8eb4b7 The SDKs here are the ones that shipped, under this repo's module path
hanzoai/agents carried the reconciled Go, TypeScript and Python SDKs:
memory in Base with one record schema across all three, scope ids
resolved the way the control plane resolves them, /v1 paths, one address
per vector operation, agents that start under Express 5, and suites that
run (Go green, 92 TypeScript, 527 Python). They come home here.

The Go module is github.com/hanzoai/agent/sdk/go, because the path has to
name the repository it is fetched from. The TypeScript manifest names its
versions directly and keeps npm's lockfile; this repo is not a pnpm
workspace. Versions are 0.2.10.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 12:12:32 -07:00

73 lines
1.6 KiB
Go

package agent
import (
"math"
"sort"
)
// The vector math every memory backend shares.
// cosine is the similarity of two vectors of equal width: 1 for the same
// direction, 0 for perpendicular, -1 for opposite. A zero vector has no
// direction, so it scores 0 rather than dividing by zero.
func cosine(a, b []float64) float64 {
var dot, na, nb float64
for i := range a {
dot += a[i] * b[i]
na += a[i] * a[i]
nb += b[i] * b[i]
}
if na == 0 || nb == 0 {
return 0
}
return dot / (math.Sqrt(na) * math.Sqrt(nb))
}
// matches reports whether metadata satisfies every filter. A missing key fails
// its filter; numbers compare as float64, as JSON decodes them.
func matches(metadata map[string]any, filters map[string]any) bool {
for key, want := range filters {
got, ok := metadata[key]
if !ok || !same(got, want) {
return false
}
}
return true
}
func same(a, b any) bool {
if x, ok := number(a); ok {
if y, ok := number(b); ok {
return x == y
}
return false
}
return a == b
}
func number(v any) (float64, bool) {
switch n := v.(type) {
case float64:
return n, true
case float32:
return float64(n), true
case int:
return float64(n), true
case int64:
return float64(n), true
case int32:
return float64(n), true
default:
return 0, false
}
}
// rank orders results by score, strongest first, and cuts to the limit.
func rank(found []VectorSearchResult, limit int) []VectorSearchResult {
sort.SliceStable(found, func(i, j int) bool { return found[i].Score > found[j].Score })
if limit > 0 && len(found) > limit {
found = found[:limit]
}
return found
}