fix: Improve Python resolution accuracy and context relevance

Eliminate cross-language false positives in name resolution and deprioritize
test files in context building. Benchmarked on a Python+Rust codebase where
37% of edges were false positives from Python built-in methods resolving to
Rust functions (e.g., list.extend → Rust extend).

Resolution fixes (index-time):
- Filter Python built-in type method calls (list.extend, dict.update, etc.)
- Filter bare Python built-in method names (append, extend, pop, keys, etc.)
- Add language boundary checks to matchMethodCall strategies 1, 2, and 3
- Penalize cross-language matches: -80 points in findBestMatch (was 0)
- Reduce confidence for single cross-language exact matches (0.5 vs 0.9)
- Prefer same-language candidates in matchFuzzy

Context relevance fixes (query-time):
- Add isTestFile() utility detecting test files across Python/JS/TS/Go/Rust/Java
- Deprioritize test files in scorePathRelevance (-15 penalty)
- Reduce test file scores to 30% in context builder result merging
- Both skip deprioritization when query mentions "test" or "spec"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby McHenry
2026-04-03 12:29:21 -05:00
co-authored by Claude Opus 4.6
parent 5d5e715dec
commit 8b541be894
4 changed files with 204 additions and 11 deletions
+12
View File
@@ -25,6 +25,7 @@ import { VectorManager } from '../vectors';
import { formatContextAsMarkdown, formatContextAsJson } from './formatter';
import { logDebug, logWarn } from '../errors';
import { validatePathWithinRoot } from '../utils';
import { isTestFile } from '../search/query-utils';
/**
* Extract likely symbol names from a natural language query
@@ -334,6 +335,17 @@ export class ContextBuilder {
// Limit total results
searchResults = searchResults.slice(0, opts.searchLimit * 2);
// Deprioritize test files unless the query is about tests
const queryLower = query.toLowerCase();
const isTestQuery = queryLower.includes('test') || queryLower.includes('spec');
if (!isTestQuery) {
searchResults = searchResults.map(r => ({
...r,
score: isTestFile(r.node.filePath) ? r.score * 0.3 : r.score,
}));
searchResults.sort((a, b) => b.score - a.score);
}
// Filter by minimum score
let filteredResults = searchResults.filter((r) => r.score >= opts.minScore);