MCPcopy
hub / github.com/colbymchenry/codegraph / computeGraphRelevance

Method computeGraphRelevance

src/mcp/tools.ts:2394–2447  ·  view source on GitHub ↗

* Graph-connectivity relevance via Random-Walk-with-Restart (personalized * PageRank) from the query's matched SEED nodes over the call/reference graph. * * This is the ranking signal text search (FTS/bm25) CANNOT provide, and it's * codegraph's home turf: relevance by STRUCTURE, not wor

(
    nodeIds: string[],
    edges: Edge[],
    seedIds: Set<string>,
  )

Source from the content-addressed store, hash-verified

2392 * it's a few hundred nodes × ~25 iterations — negligible cost.
2393 */
2394 private computeGraphRelevance(
2395 nodeIds: string[],
2396 edges: Edge[],
2397 seedIds: Set<string>,
2398 ): Map<string, number> {
2399 const out = new Map<string, number>();
2400 const n = nodeIds.length;
2401 if (n === 0) return out;
2402 const idx = new Map<string, number>();
2403 for (let i = 0; i < n; i++) idx.set(nodeIds[i]!, i);
2404
2405 const RANK_EDGES = new Set<string>([
2406 'calls', 'references', 'extends', 'implements', 'overrides',
2407 'instantiates', 'returns', 'type_of', 'imports',
2408 ]);
2409 const adj: number[][] = Array.from({ length: n }, () => []);
2410 for (const e of edges) {
2411 if (!RANK_EDGES.has(e.kind)) continue;
2412 const i = idx.get(e.source);
2413 const j = idx.get(e.target);
2414 if (i === undefined || j === undefined || i === j) continue;
2415 adj[i]!.push(j);
2416 adj[j]!.push(i); // undirected — reachable either direction
2417 }
2418
2419 // Restart vector: uniform over seeds present in the candidate set. (Falls
2420 // back to uniform-over-all if no seed landed in the set, so we never return
2421 // all-zero.)
2422 const r = new Array<number>(n).fill(0);
2423 let rsum = 0;
2424 for (const id of seedIds) {
2425 const i = idx.get(id);
2426 if (i !== undefined) { r[i] = 1; rsum += 1; }
2427 }
2428 if (rsum === 0) { for (let i = 0; i < n; i++) r[i] = 1; rsum = n; }
2429 for (let i = 0; i < n; i++) r[i]! /= rsum;
2430
2431 const alpha = 0.25;
2432 let s = r.slice();
2433 for (let iter = 0; iter < 25; iter++) {
2434 const next = new Array<number>(n).fill(0);
2435 for (let i = 0; i < n; i++) {
2436 const si = s[i]!;
2437 if (si === 0) continue;
2438 const d = adj[i]!.length;
2439 if (d === 0) { next[i]! += si; continue; } // dangling: keep its mass
2440 const share = si / d;
2441 for (const j of adj[i]!) next[j]! += share;
2442 }
2443 for (let i = 0; i < n; i++) s[i] = (1 - alpha) * next[i]! + alpha * r[i]!;
2444 }
2445 for (let i = 0; i < n; i++) out.set(nodeIds[i]!, s[i]!);
2446 return out;
2447 }
2448
2449 /**
2450 * Handle codegraph_explore — deep exploration in a single call

Callers 1

handleExploreMethod · 0.95

Calls 3

setMethod · 0.80
hasMethod · 0.80
getMethod · 0.65

Tested by

no test coverage detected