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

88 lines
3.0 KiB
Go

package mcp
import (
"time"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/search/rerank"
)
// applyRerankBoostsTimed is the I13 entry point that runs the full
// 11-signal rerank.Pipeline over the candidate set with the session-
// aware Context wired in (locality, combo, frecency, feedback, churn,
// community). Structural signals (BM25 rank, fan-in / fan-out,
// MinHash similarity, signature match, recency) are computed off the
// graph + the candidate's current index.
//
// rerankCtx is the per-request Context built by the server; pass nil
// and the pipeline falls back to a structural-only rerank using just
// the graph data on the nodes. lastResults is the optional rich
// candidate slice — when non-nil it carries per-signal contributions
// out to the caller for debug / winnow surfacing; pass nil if the
// caller only wants the sorted nodes.
//
// Returns the rerank's prepare and signals phase durations separately
// so the search_symbols handler's per-phase Debug log can attribute
// time honestly between the batched edge fetch (prepare) and the
// in-process scoring loop (signals). Zero durations when there's no
// work to do.
func applyRerankBoostsTimed(s *Server, nodes []*graph.Node, query string, rerankCtx *rerank.Context, lastResults *[]*rerank.Candidate) (result []*graph.Node, prepare time.Duration, signals time.Duration) {
if len(nodes) < 2 || s == nil || s.engine == nil {
return nodes, 0, 0
}
pipeline := s.engine.Rerank()
if pipeline == nil {
return nodes, 0, 0
}
cands := make([]*rerank.Candidate, 0, len(nodes))
for i, n := range nodes {
cands = append(cands, &rerank.Candidate{
Node: n, TextRank: i, VectorRank: -1,
})
}
if rerankCtx == nil {
rerankCtx = &rerank.Context{}
}
if rerankCtx.Graph == nil {
rerankCtx.Graph = s.graph
}
// Phase 1: prepare — the batched in/out edge fetch + scratch fields.
// Exposed via the explicit Prepare call; Pipeline.Rerank detects the
// already-prepared slice and skips the duplicate work.
prepStart := time.Now()
rerankCtx.Prepare(cands)
prepare = time.Since(prepStart)
// Phase 2: signals — the in-process scoring loop + final sort.
sigStart := time.Now()
pipeline.Rerank(query, cands, rerankCtx)
signals = time.Since(sigStart)
result = make([]*graph.Node, 0, len(cands))
for _, c := range cands {
result = append(result, c.Node)
}
if lastResults != nil {
*lastResults = cands
}
return result, prepare, signals
}
// recordLastSearchFromNodes stores the query + top-limit IDs on the session
// so a subsequent get_symbol_source / get_editing_context can credit this
// search. Capped at limit to avoid crediting results the agent never saw.
func recordLastSearchFromNodes(sess *sessionState, query string, nodes []*graph.Node, limit int) {
if sess == nil || len(nodes) == 0 {
return
}
if limit <= 0 || limit > len(nodes) {
limit = len(nodes)
}
ids := make([]string, 0, limit)
for i := 0; i < limit; i++ {
ids = append(ids, nodes[i].ID)
}
sess.recordLastSearch(query, ids)
}