@comfanion/usethis_search 3.0.0-dev.14 → 3.0.0-dev.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/vectorizer/index.ts +39 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comfanion/usethis_search",
|
|
3
|
-
"version": "3.0.0-dev.
|
|
3
|
+
"version": "3.0.0-dev.15",
|
|
4
4
|
"description": "OpenCode plugin: semantic search with graph-based context (v3: graph relations, 1-hop context, LSP + regex analyzers)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
package/vectorizer/index.ts
CHANGED
|
@@ -28,8 +28,8 @@ if (!DEBUG) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
* Default index presets (can be overridden by config).
|
|
32
|
+
*/
|
|
33
33
|
const DEFAULT_PRESETS = {
|
|
34
34
|
code: {
|
|
35
35
|
pattern: "**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj}",
|
|
@@ -44,22 +44,30 @@ const DEFAULT_PRESETS = {
|
|
|
44
44
|
"**/__pycache__/**",
|
|
45
45
|
],
|
|
46
46
|
description: "Source code files (excludes docs, vendor, node_modules)",
|
|
47
|
+
hybrid: true,
|
|
48
|
+
bm25_weight: 0.3,
|
|
47
49
|
},
|
|
48
50
|
docs: {
|
|
49
51
|
pattern: "docs/**/*.{md,mdx,txt,rst,adoc}",
|
|
50
52
|
ignore: [],
|
|
51
53
|
description: "Documentation in docs/ folder",
|
|
54
|
+
hybrid: false,
|
|
55
|
+
bm25_weight: 0.2,
|
|
52
56
|
},
|
|
53
57
|
config: {
|
|
54
58
|
pattern: "**/*.{yaml,yml,json,toml,ini,env,xml}",
|
|
55
59
|
ignore: ["**/node_modules/**", "**/.git/**", "**/.opencode/**"],
|
|
56
60
|
description: "Configuration files",
|
|
61
|
+
hybrid: false,
|
|
62
|
+
bm25_weight: 0.3,
|
|
57
63
|
},
|
|
58
64
|
all: {
|
|
59
65
|
pattern:
|
|
60
66
|
"**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj,md,mdx,txt,rst,adoc,yaml,yml,json,toml}",
|
|
61
67
|
ignore: ["**/node_modules/**", "**/.git/**", "**/.opencode/**"],
|
|
62
68
|
description: "All supported files",
|
|
69
|
+
hybrid: false,
|
|
70
|
+
bm25_weight: 0.3,
|
|
63
71
|
},
|
|
64
72
|
};
|
|
65
73
|
|
|
@@ -124,15 +132,21 @@ function defaultVectorizerYaml() {
|
|
|
124
132
|
` pattern: \"${DEFAULT_PRESETS.code.pattern}\"\n` +
|
|
125
133
|
` ignore:\n` +
|
|
126
134
|
DEFAULT_PRESETS.code.ignore.map((p) => ` - \"${p}\"\n`).join("") +
|
|
135
|
+
` hybrid: true\n` +
|
|
136
|
+
` bm25_weight: 0.3\n` +
|
|
127
137
|
` docs:\n` +
|
|
128
138
|
` enabled: true\n` +
|
|
129
139
|
` pattern: \"${DEFAULT_PRESETS.docs.pattern}\"\n` +
|
|
130
140
|
` ignore: []\n` +
|
|
141
|
+
` hybrid: false\n` +
|
|
142
|
+
` bm25_weight: 0.2\n` +
|
|
131
143
|
` config:\n` +
|
|
132
144
|
` enabled: false\n` +
|
|
133
145
|
` pattern: \"${DEFAULT_PRESETS.config.pattern}\"\n` +
|
|
134
146
|
` ignore:\n` +
|
|
135
147
|
DEFAULT_PRESETS.config.ignore.map((p) => ` - \"${p}\"\n`).join("") +
|
|
148
|
+
` hybrid: false\n` +
|
|
149
|
+
` bm25_weight: 0.3\n` +
|
|
136
150
|
` exclude:\n` +
|
|
137
151
|
` - node_modules\n` +
|
|
138
152
|
` - vendor\n` +
|
|
@@ -294,15 +308,15 @@ async function loadConfig(projectRoot) {
|
|
|
294
308
|
if (!indexMatch) continue;
|
|
295
309
|
|
|
296
310
|
const indexSection = indexMatch[1];
|
|
297
|
-
|
|
311
|
+
|
|
298
312
|
// Parse enabled
|
|
299
313
|
const enabledMatch = indexSection.match(/^\s+enabled:\s*(true|false)/m);
|
|
300
314
|
const enabled = enabledMatch ? enabledMatch[1] === "true" : true;
|
|
301
|
-
|
|
315
|
+
|
|
302
316
|
// Parse pattern
|
|
303
317
|
const patternMatch = indexSection.match(/^\s+pattern:\s*["']?([^"'\n]+)["']?/m);
|
|
304
318
|
const pattern = patternMatch ? patternMatch[1].trim() : DEFAULT_PRESETS[indexName]?.pattern;
|
|
305
|
-
|
|
319
|
+
|
|
306
320
|
// Parse ignore array
|
|
307
321
|
const ignoreMatch = indexSection.match(/^\s+ignore:\s*\n((?:\s+-\s+.+\n?)*)/m);
|
|
308
322
|
let ignore = [];
|
|
@@ -312,12 +326,22 @@ async function loadConfig(projectRoot) {
|
|
|
312
326
|
.map((line) => line.replace(/^\s*-\s*/, "").replace(/["']/g, "").trim())
|
|
313
327
|
.filter(Boolean);
|
|
314
328
|
}
|
|
315
|
-
|
|
329
|
+
|
|
330
|
+
// Parse hybrid (per-index)
|
|
331
|
+
const hybridMatch = indexSection.match(/^\s+hybrid:\s*(true|false)/m);
|
|
332
|
+
const hybrid = hybridMatch ? hybridMatch[1] === "true" : DEFAULT_PRESETS[indexName]?.hybrid;
|
|
333
|
+
|
|
334
|
+
// Parse bm25_weight (per-index)
|
|
335
|
+
const bm25WeightMatch = indexSection.match(/^\s+bm25_weight:\s*([\d.]+)/m);
|
|
336
|
+
const bm25Weight = bm25WeightMatch ? parseFloat(bm25WeightMatch[1]) : DEFAULT_PRESETS[indexName]?.bm25_weight;
|
|
337
|
+
|
|
316
338
|
if (enabled && pattern) {
|
|
317
339
|
INDEX_PRESETS[indexName] = {
|
|
318
340
|
pattern,
|
|
319
341
|
ignore,
|
|
320
342
|
description: `${indexName} files from config`,
|
|
343
|
+
hybrid,
|
|
344
|
+
bm25_weight: bm25Weight,
|
|
321
345
|
};
|
|
322
346
|
}
|
|
323
347
|
}
|
|
@@ -647,8 +671,11 @@ class CodebaseIndexer {
|
|
|
647
671
|
const hasFilters = !includeArchived || options.fileType || options.language ||
|
|
648
672
|
options.modifiedAfter || options.modifiedBefore ||
|
|
649
673
|
(options.tags && options.tags.length > 0);
|
|
650
|
-
const
|
|
651
|
-
const
|
|
674
|
+
const indexConfig = INDEX_PRESETS[this.indexName];
|
|
675
|
+
const indexHybridEnabled = indexConfig?.hybrid ?? false;
|
|
676
|
+
const indexBM25Weight = indexConfig?.bm25_weight ?? HYBRID_CONFIG.bm25_weight;
|
|
677
|
+
const isHybrid = indexHybridEnabled || options.hybrid;
|
|
678
|
+
const fetchLimit = (hasFilters || isHybrid) ? Math.max(limit *3, 50) : limit;
|
|
652
679
|
let results;
|
|
653
680
|
try {
|
|
654
681
|
results = await table.search(queryEmbedding).limit(fetchLimit).execute();
|
|
@@ -659,7 +686,7 @@ class CodebaseIndexer {
|
|
|
659
686
|
}
|
|
660
687
|
|
|
661
688
|
// ── Hybrid search ───────────────────────────────────────────────────────
|
|
662
|
-
if (
|
|
689
|
+
if (isHybrid) {
|
|
663
690
|
try {
|
|
664
691
|
const bm25 = await this.ensureBM25();
|
|
665
692
|
if (bm25 && this._bm25Rows) {
|
|
@@ -706,7 +733,7 @@ class CodebaseIndexer {
|
|
|
706
733
|
if (v.bm25Score > maxBM25) maxBM25 = v.bm25Score;
|
|
707
734
|
}
|
|
708
735
|
|
|
709
|
-
const bw = (options.bm25_weight ??
|
|
736
|
+
const bw = (options.bm25_weight ?? indexBM25Weight) || 0.3;
|
|
710
737
|
const vw = 1 - bw;
|
|
711
738
|
|
|
712
739
|
const merged = [];
|
|
@@ -1035,7 +1062,8 @@ class CodebaseIndexer {
|
|
|
1035
1062
|
chunkCount,
|
|
1036
1063
|
features: {
|
|
1037
1064
|
chunking: CHUNKING_CONFIG.strategy,
|
|
1038
|
-
hybrid:
|
|
1065
|
+
hybrid: preset?.hybrid ?? false,
|
|
1066
|
+
bm25_weight: preset?.bm25_weight ?? HYBRID_CONFIG.bm25_weight,
|
|
1039
1067
|
metrics: METRICS_ENABLED,
|
|
1040
1068
|
cache: CACHE_ENABLED,
|
|
1041
1069
|
},
|