Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

151 lines
3.9 KiB
Go

package rerank
import "github.com/zzet/gortex/internal/graph"
// FanInSignal scores by log-normalised in-edge count. Symbols with
// many callers / references are more likely to be load-bearing and
// thus more likely to be what an agent is actually after.
type FanInSignal struct{}
func (FanInSignal) Name() string { return SignalFanIn }
func (FanInSignal) Contribute(_ string, c *Candidate, ctx *Context) float64 {
if ctx.Graph == nil {
return 0
}
count := len(ctx.inEdges(c.Node.ID))
return normLog(count, ctx.fanInMax)
}
// FanOutSignal scores by log-normalised out-edge count. Pure utility
// functions tend to have low fan-out; coordinator / dispatcher code
// has high fan-out. A weak signal, but discriminating for navigation
// queries that target orchestration code.
type FanOutSignal struct{}
func (FanOutSignal) Name() string { return SignalFanOut }
func (FanOutSignal) Contribute(_ string, c *Candidate, ctx *Context) float64 {
if ctx.Graph == nil {
return 0
}
count := len(ctx.outEdges(c.Node.ID))
return normLog(count, ctx.fanOutMax)
}
// MinHashSignal scores by similarity-cluster cohesion: how many other
// candidates in the same result batch this candidate is MinHash-near
// to. Higher = the candidate sits at the center of a cluster of
// similar code, lower = isolated. Depends on the F9 clone-detection
// pass having stamped EdgeSimilarTo edges.
type MinHashSignal struct{}
func (MinHashSignal) Name() string { return SignalMinHash }
func (MinHashSignal) Contribute(_ string, c *Candidate, ctx *Context) float64 {
if ctx.Graph == nil || len(ctx.candidateIDs) <= 1 {
return 0
}
var total, n float64
for _, e := range ctx.outEdges(c.Node.ID) {
if e.Kind != graph.EdgeSimilarTo {
continue
}
if _, ok := ctx.candidateIDs[e.To]; !ok {
continue
}
sim := similarityFromEdge(e)
if sim <= 0 {
continue
}
total += sim
n++
}
// Symmetric edge — also walk incoming (snapshots that omit
// outgoing copies of similar_to don't lose recall).
for _, e := range ctx.inEdges(c.Node.ID) {
if e.Kind != graph.EdgeSimilarTo {
continue
}
if _, ok := ctx.candidateIDs[e.From]; !ok {
continue
}
sim := similarityFromEdge(e)
if sim <= 0 {
continue
}
total += sim
n++
}
if n == 0 {
return 0
}
avg := total / n
// Normalise by the cap of EdgeSimilarTo similarity (Jaccard ≤ 1).
if avg > 1 {
avg = 1
}
return avg
}
// similarityFromEdge mirrors the lookup used by tools_clones — prefer
// Meta["similarity"], fall back to Confidence so edges restored from
// older snapshots still contribute.
func similarityFromEdge(e *graph.Edge) float64 {
if e == nil {
return 0
}
if e.Meta != nil {
if v, ok := e.Meta["similarity"].(float64); ok {
return v
}
}
return e.Confidence
}
// CommunitySignal scores by topic-cluster cohesion plus session
// locality. The contribution is the max of:
//
// - same graph community as other top candidates (cluster cohesion)
// - same repo as the session's home repo
// - same project as the session's home project
//
// All three saturate at 1.0; the max collapses them so a candidate
// that's both same-repo and same-cluster doesn't double-count.
type CommunitySignal struct{}
func (CommunitySignal) Name() string { return SignalCommunity }
func (CommunitySignal) Contribute(_ string, c *Candidate, ctx *Context) float64 {
var best float64
if ctx.CommunityOf != nil && ctx.maxCommunityCount > 1 {
com := ctx.CommunityOf(c.Node.ID)
if com != "" {
cnt := ctx.communityCount[com]
if cnt > 1 {
score := float64(cnt) / float64(ctx.maxCommunityCount)
if score > best {
best = score
}
}
}
}
if ctx.RepoPrefix != "" && c.Node.RepoPrefix == ctx.RepoPrefix {
if 1.0 > best {
best = 1.0
}
} else if ctx.ProjectID != "" {
proj := c.Node.ProjectID
if proj == "" {
proj = c.Node.RepoPrefix
}
if proj == ctx.ProjectID && 0.7 > best {
best = 0.7
}
}
return best
}