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
+39 -3
View File
@@ -79,9 +79,45 @@ export function scorePathRelevance(filePath: string, query: string): number {
else if (pathLower.includes(term)) score += 3;
}
// Deprioritize test files unless the query is explicitly about tests
const queryLower = query.toLowerCase();
const isTestQuery = queryLower.includes('test') || queryLower.includes('spec');
if (!isTestQuery && isTestFile(filePath)) {
score -= 15;
}
return score;
}
/**
* Check if a file path looks like a test file
*/
export function isTestFile(filePath: string): boolean {
const lower = filePath.toLowerCase();
const fileName = path.basename(lower);
// Common test file patterns
return (
fileName.startsWith('test_') ||
fileName.startsWith('test.') ||
fileName.endsWith('.test.ts') ||
fileName.endsWith('.test.js') ||
fileName.endsWith('.test.tsx') ||
fileName.endsWith('.test.jsx') ||
fileName.endsWith('.spec.ts') ||
fileName.endsWith('.spec.js') ||
fileName.endsWith('_test.go') ||
fileName.endsWith('_test.py') ||
fileName.endsWith('_test.rs') ||
fileName.endsWith('Tests.java') ||
fileName.endsWith('Test.java') ||
lower.includes('/tests/') ||
lower.includes('/test/') ||
lower.includes('/__tests__/') ||
lower.includes('/spec/')
);
}
/**
* Kind-based bonus for search ranking
* Functions and classes are typically more relevant than variables/imports
@@ -91,10 +127,10 @@ export function kindBonus(kind: Node['kind']): number {
function: 10,
method: 10,
class: 8,
interface: 7,
interface: 9,
type_alias: 6,
struct: 6,
trait: 6,
trait: 9,
enum: 5,
component: 8,
route: 9,
@@ -108,7 +144,7 @@ export function kindBonus(kind: Node['kind']): number {
parameter: 0,
namespace: 4,
file: 0,
protocol: 6,
protocol: 9,
enum_member: 3,
};
return bonuses[kind] ?? 0;