token-goat 2.9.15 → 2.9.17
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/README.md +2 -5
- package/dist/{token-goat-chunk-IVUQLQWN.mjs → token-goat-chunk-26YUO7MP.mjs} +5 -3
- package/dist/{token-goat-chunk-SZWYESBS.mjs → token-goat-chunk-2M33Q3O4.mjs} +172 -67
- package/dist/{token-goat-chunk-S4XRY446.mjs → token-goat-chunk-2VASS5VR.mjs} +4 -3
- package/dist/{token-goat-chunk-7ZYK25AO.mjs → token-goat-chunk-2XA5ZW4T.mjs} +4 -4
- package/dist/{token-goat-chunk-C5JIO6HK.mjs → token-goat-chunk-5WB7GDH4.mjs} +5 -5
- package/dist/{token-goat-chunk-MZDIJJ3R.mjs → token-goat-chunk-66224KCZ.mjs} +40 -3
- package/dist/{token-goat-chunk-NDRP4KJQ.mjs → token-goat-chunk-73GXYYZR.mjs} +248 -50
- package/dist/{token-goat-chunk-ATIFTMRC.mjs → token-goat-chunk-7EGKXBWT.mjs} +7 -7
- package/dist/{token-goat-chunk-GMQQA7E4.mjs → token-goat-chunk-7VQMOBPQ.mjs} +2453 -722
- package/dist/token-goat-chunk-BGHSSJUA.mjs +102 -0
- package/dist/{token-goat-chunk-2X2EBBC6.mjs → token-goat-chunk-BK3RPPTK.mjs} +2 -2
- package/dist/{token-goat-chunk-YQ7WI2CO.mjs → token-goat-chunk-C26ZBGBC.mjs} +393 -3957
- package/dist/{token-goat-chunk-SFAS46RE.mjs → token-goat-chunk-CICJFVIH.mjs} +2 -2
- package/dist/{token-goat-chunk-6DLVZDB6.mjs → token-goat-chunk-CKIJWTRQ.mjs} +13 -12
- package/dist/{token-goat-chunk-5V7DAC7V.mjs → token-goat-chunk-CPHVXKNU.mjs} +10 -3
- package/dist/{token-goat-chunk-LT7JRU6K.mjs → token-goat-chunk-EKGVCAES.mjs} +4 -4
- package/dist/{token-goat-chunk-Z6UXPYJA.mjs → token-goat-chunk-F2ARFHLJ.mjs} +1 -1
- package/dist/{token-goat-chunk-NDPO7GAH.mjs → token-goat-chunk-G75WIVFM.mjs} +21 -20
- package/dist/{token-goat-chunk-YZX7EFG4.mjs → token-goat-chunk-GLOM5W5C.mjs} +1 -1
- package/dist/{token-goat-chunk-GIIHUSZX.mjs → token-goat-chunk-GPCCYQSS.mjs} +41 -11
- package/dist/{token-goat-chunk-OUGNPMDA.mjs → token-goat-chunk-HRUGS6CO.mjs} +30 -14
- package/dist/{token-goat-chunk-LCZBPOIN.mjs → token-goat-chunk-IDHWKNKZ.mjs} +143 -51
- package/dist/{token-goat-chunk-YKG35VHC.mjs → token-goat-chunk-KZPO4DWC.mjs} +1 -1
- package/dist/{token-goat-chunk-NEI4NC54.mjs → token-goat-chunk-LKSXAMJB.mjs} +7 -2
- package/dist/{token-goat-chunk-K7F2BFIK.mjs → token-goat-chunk-MWSVUKVV.mjs} +1 -1
- package/dist/{token-goat-chunk-BL5LNGBG.mjs → token-goat-chunk-PKNOHVWP.mjs} +2966 -3869
- package/dist/{token-goat-chunk-A4JYKD5H.mjs → token-goat-chunk-RB24DBBS.mjs} +2 -2
- package/dist/{token-goat-chunk-3NSDDTGL.mjs → token-goat-chunk-RFFUCQK7.mjs} +5 -5
- package/dist/token-goat-chunk-RRNZMM3A.mjs +3364 -0
- package/dist/{token-goat-chunk-XEPXYDPI.mjs → token-goat-chunk-SWRKVA3J.mjs} +11 -2
- package/dist/{token-goat-chunk-NU7TLMQK.mjs → token-goat-chunk-THBLW56G.mjs} +10 -7
- package/dist/{token-goat-chunk-PM76YS22.mjs → token-goat-chunk-UBZCON6N.mjs} +1 -1
- package/dist/{token-goat-chunk-ASYEPR3S.mjs → token-goat-chunk-W2GUUQAQ.mjs} +7 -3
- package/dist/{token-goat-chunk-DQ4J5AFF.mjs → token-goat-chunk-YFGEUIEO.mjs} +69 -18
- package/dist/token-goat-hook.mjs +13 -12
- package/dist/token-goat.core.mjs +21 -20
- package/docs/cli.md +1 -0
- package/package.json +1 -1
|
@@ -4,11 +4,7 @@ import {
|
|
|
4
4
|
pathEqClause,
|
|
5
5
|
projectScopeClause,
|
|
6
6
|
querySymbols
|
|
7
|
-
} from "./token-goat-chunk-
|
|
8
|
-
import {
|
|
9
|
-
DocumentRefusedError,
|
|
10
|
-
MAX_DOCUMENT_WORK_MILLIS
|
|
11
|
-
} from "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
7
|
+
} from "./token-goat-chunk-BK3RPPTK.mjs";
|
|
12
8
|
import {
|
|
13
9
|
TREE_SITTER_LANGUAGES,
|
|
14
10
|
_detectOpenQuote,
|
|
@@ -25,11 +21,11 @@ import {
|
|
|
25
21
|
stripJsComments,
|
|
26
22
|
stripStringLiterals,
|
|
27
23
|
stripXmlComments
|
|
28
|
-
} from "./token-goat-chunk-
|
|
24
|
+
} from "./token-goat-chunk-MWSVUKVV.mjs";
|
|
29
25
|
import {
|
|
30
26
|
fingerprintContent,
|
|
31
27
|
loadConfig
|
|
32
|
-
} from "./token-goat-chunk-
|
|
28
|
+
} from "./token-goat-chunk-2VASS5VR.mjs";
|
|
33
29
|
import {
|
|
34
30
|
registerReset
|
|
35
31
|
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
@@ -43,11 +39,15 @@ import {
|
|
|
43
39
|
foldPath,
|
|
44
40
|
globalDbPath,
|
|
45
41
|
isCaseInsensitiveFs
|
|
46
|
-
} from "./token-goat-chunk-
|
|
42
|
+
} from "./token-goat-chunk-UBZCON6N.mjs";
|
|
47
43
|
import {
|
|
48
44
|
displaySafeText,
|
|
49
45
|
normalizePath
|
|
50
46
|
} from "./token-goat-chunk-ERTXEKB6.mjs";
|
|
47
|
+
import {
|
|
48
|
+
DocumentRefusedError,
|
|
49
|
+
MAX_DOCUMENT_WORK_MILLIS
|
|
50
|
+
} from "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
51
51
|
import {
|
|
52
52
|
init_define_import_meta_env
|
|
53
53
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -69,16 +69,16 @@ function isTransientDocumentRefusal(err) {
|
|
|
69
69
|
async function extractEmbeddableDocumentText(filePath) {
|
|
70
70
|
switch (path.extname(filePath).toLowerCase()) {
|
|
71
71
|
case ".pdf": {
|
|
72
|
-
const { extractPdfText, readPdfFileWithinBounds } = await import("./token-goat-chunk-
|
|
72
|
+
const { extractPdfText, readPdfFileWithinBounds } = await import("./token-goat-chunk-F2ARFHLJ.mjs");
|
|
73
73
|
const { text } = await extractPdfText(await readPdfFileWithinBounds(filePath));
|
|
74
74
|
return text;
|
|
75
75
|
}
|
|
76
76
|
case ".docx":
|
|
77
|
-
return await (await import("./token-goat-chunk-
|
|
77
|
+
return await (await import("./token-goat-chunk-EKGVCAES.mjs")).docxText(filePath);
|
|
78
78
|
case ".pptx":
|
|
79
|
-
return await (await import("./token-goat-chunk-
|
|
79
|
+
return await (await import("./token-goat-chunk-2XA5ZW4T.mjs")).pptxAllSlidesText(filePath, true);
|
|
80
80
|
case ".xlsx":
|
|
81
|
-
return await (await import("./token-goat-chunk-
|
|
81
|
+
return await (await import("./token-goat-chunk-RFFUCQK7.mjs")).allSheetsHeadText(filePath, XLSX_SHEET_ROW_CAP);
|
|
82
82
|
default:
|
|
83
83
|
return null;
|
|
84
84
|
}
|
|
@@ -297,6 +297,12 @@ var BertWordPiece = class _BertWordPiece {
|
|
|
297
297
|
ids.push(this.sepId);
|
|
298
298
|
return ids.length > maxLength ? ids.slice(0, maxLength) : ids;
|
|
299
299
|
}
|
|
300
|
+
/** How many wordpieces `text` becomes, markers excluded and nothing cut: what {@link encode} would read before its limit, for a caller sizing text to fit under it. Words never span whitespace, so the count of a newline-joined text is the sum of its lines' counts. */
|
|
301
|
+
countTokens(text) {
|
|
302
|
+
const ids = [];
|
|
303
|
+
for (const word of preTokenize(normalize(text))) this.wordToIds(word, ids);
|
|
304
|
+
return ids.length;
|
|
305
|
+
}
|
|
300
306
|
};
|
|
301
307
|
|
|
302
308
|
// src/embed_model.ts
|
|
@@ -558,6 +564,10 @@ var EmbeddingModel = class _EmbeddingModel {
|
|
|
558
564
|
});
|
|
559
565
|
return new _EmbeddingModel(tokenizer, session, ort.Tensor);
|
|
560
566
|
}
|
|
567
|
+
/** Wordpieces `text` becomes under this model's own tokenizer, markers excluded. */
|
|
568
|
+
countTokens(text) {
|
|
569
|
+
return this.tokenizer.countTokens(text);
|
|
570
|
+
}
|
|
561
571
|
/** Embed one text. Sequences are run singly, so there is no padding and no mask to get wrong. */
|
|
562
572
|
async embed(text) {
|
|
563
573
|
const ids = this.tokenizer.encode(text);
|
|
@@ -687,14 +697,14 @@ init_define_import_meta_env();
|
|
|
687
697
|
|
|
688
698
|
// src/embed_fingerprint.ts
|
|
689
699
|
init_define_import_meta_env();
|
|
690
|
-
var EMBED_FINGERPRINT = "
|
|
700
|
+
var EMBED_FINGERPRINT = "b7b2ff71de288d13";
|
|
691
701
|
|
|
692
702
|
// src/embeddings.ts
|
|
693
703
|
var QUERY_INSTRUCTION_PREFIX = "Represent this sentence for searching relevant passages: ";
|
|
694
704
|
var _extractorCache = /* @__PURE__ */ new Map();
|
|
695
705
|
var inHousePipelineFn = async (_task, modelName) => {
|
|
696
706
|
const model = await EmbeddingModel.load(modelName);
|
|
697
|
-
return async (text) => ({ data: await model.embed(text) });
|
|
707
|
+
return Object.assign(async (text) => ({ data: await model.embed(text) }), { countTokens: (text) => model.countTokens(text) });
|
|
698
708
|
};
|
|
699
709
|
var _pipelineFnOverride = null;
|
|
700
710
|
registerReset(() => {
|
|
@@ -724,6 +734,7 @@ async function buildExtractorWithRetry(pipelineFn, modelName) {
|
|
|
724
734
|
}
|
|
725
735
|
var MIN_CHUNK_CHARS = 50;
|
|
726
736
|
var MAX_CHUNK_CHARS = 8e3;
|
|
737
|
+
var MAX_CHUNK_TOKENS = MAX_SEQUENCE_TOKENS - 2;
|
|
727
738
|
var DEFAULT_DISTANCE_THRESHOLD = 1.2;
|
|
728
739
|
var _GENERATED_PATH_SEGMENTS = /* @__PURE__ */ new Set([
|
|
729
740
|
"node_modules",
|
|
@@ -772,15 +783,7 @@ function isAvailable() {
|
|
|
772
783
|
function embeddingBackendLoadError() {
|
|
773
784
|
return runtimeLoadError();
|
|
774
785
|
}
|
|
775
|
-
|
|
776
|
-
if (!isAvailable()) {
|
|
777
|
-
throw new Error(
|
|
778
|
-
`Embedding backend not available: ${runtimeLoadError()?.message ?? "unknown error"}`
|
|
779
|
-
);
|
|
780
|
-
}
|
|
781
|
-
if (texts.length === 0) {
|
|
782
|
-
return [];
|
|
783
|
-
}
|
|
786
|
+
function getExtractor(modelName) {
|
|
784
787
|
let extractorPromise = _extractorCache.get(modelName);
|
|
785
788
|
if (!extractorPromise) {
|
|
786
789
|
const pipelineFn = _pipelineFnOverride ?? inHousePipelineFn;
|
|
@@ -790,7 +793,18 @@ async function embedTexts(texts, modelName = DEFAULT_MODEL) {
|
|
|
790
793
|
if (_extractorCache.get(modelName) === extractorPromise) _extractorCache.delete(modelName);
|
|
791
794
|
});
|
|
792
795
|
}
|
|
793
|
-
|
|
796
|
+
return extractorPromise;
|
|
797
|
+
}
|
|
798
|
+
async function embedTexts(texts, modelName = DEFAULT_MODEL) {
|
|
799
|
+
if (!isAvailable()) {
|
|
800
|
+
throw new Error(
|
|
801
|
+
`Embedding backend not available: ${runtimeLoadError()?.message ?? "unknown error"}`
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
if (texts.length === 0) {
|
|
805
|
+
return [];
|
|
806
|
+
}
|
|
807
|
+
const extractor = await getExtractor(modelName);
|
|
794
808
|
const vecs = [];
|
|
795
809
|
const expectedDim = DEFAULT_DIM;
|
|
796
810
|
try {
|
|
@@ -840,17 +854,29 @@ function packVec(vec) {
|
|
|
840
854
|
}
|
|
841
855
|
return Buffer.from(view.buffer);
|
|
842
856
|
}
|
|
843
|
-
function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize, overlap, kind) {
|
|
857
|
+
function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize, overlap, kind, countTokens) {
|
|
844
858
|
const chunks = [];
|
|
859
|
+
const lineTokenCache = /* @__PURE__ */ new Map();
|
|
860
|
+
const tokensOf = (lineNo) => {
|
|
861
|
+
if (countTokens === void 0) return 0;
|
|
862
|
+
let n = lineTokenCache.get(lineNo);
|
|
863
|
+
if (n === void 0) {
|
|
864
|
+
n = countTokens(lines2[lineNo - 1] ?? "");
|
|
865
|
+
lineTokenCache.set(lineNo, n);
|
|
866
|
+
}
|
|
867
|
+
return n;
|
|
868
|
+
};
|
|
845
869
|
let currentChunk = "";
|
|
870
|
+
let currentTokens = 0;
|
|
846
871
|
let startLine = rangeStart;
|
|
847
872
|
let currentLine = rangeStart;
|
|
848
873
|
for (let lineNo = rangeStart; lineNo <= rangeEnd; lineNo++) {
|
|
849
874
|
const line = lines2[lineNo - 1] ?? "";
|
|
850
875
|
const lineWithNewline = line + "\n";
|
|
851
|
-
|
|
876
|
+
const lineTokens = tokensOf(lineNo);
|
|
877
|
+
if ((currentChunk.length + lineWithNewline.length > chunkSize || currentTokens + lineTokens > MAX_CHUNK_TOKENS) && currentChunk.length > 0) {
|
|
852
878
|
const trimmedLength = currentChunk.trim().length;
|
|
853
|
-
const currentChunkTooSmall = trimmedLength < MIN_CHUNK_CHARS;
|
|
879
|
+
const currentChunkTooSmall = trimmedLength === 0 || trimmedLength < MIN_CHUNK_CHARS && countTokens === void 0;
|
|
854
880
|
if (!currentChunkTooSmall) {
|
|
855
881
|
chunks.push({
|
|
856
882
|
filePath,
|
|
@@ -861,11 +887,15 @@ function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize,
|
|
|
861
887
|
});
|
|
862
888
|
}
|
|
863
889
|
let overlapChars = 0;
|
|
890
|
+
let overlapTokens = 0;
|
|
864
891
|
let computedOverlapStart = currentLine;
|
|
865
892
|
while (computedOverlapStart > rangeStart) {
|
|
866
893
|
const candidateChars = (lines2[computedOverlapStart - 2] ?? "").length + 1;
|
|
867
894
|
if (overlapChars + candidateChars > overlap) break;
|
|
895
|
+
const candidateTokens = tokensOf(computedOverlapStart - 1);
|
|
896
|
+
if (overlapTokens + candidateTokens + lineTokens > MAX_CHUNK_TOKENS) break;
|
|
868
897
|
overlapChars += candidateChars;
|
|
898
|
+
overlapTokens += candidateTokens;
|
|
869
899
|
computedOverlapStart--;
|
|
870
900
|
}
|
|
871
901
|
const droppedChunkHadContent = currentChunkTooSmall && trimmedLength > 0;
|
|
@@ -873,10 +903,24 @@ function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize,
|
|
|
873
903
|
if (overlapStart !== startLine) {
|
|
874
904
|
const overlapText = lines2.slice(overlapStart - 1, currentLine - 1).join("\n");
|
|
875
905
|
currentChunk = overlapText + "\n";
|
|
906
|
+
currentTokens = overlapTokens;
|
|
876
907
|
startLine = overlapStart;
|
|
877
908
|
}
|
|
878
909
|
}
|
|
910
|
+
if (countTokens !== void 0 && (lineTokens > MAX_CHUNK_TOKENS || lineWithNewline.length > chunkSize)) {
|
|
911
|
+
const pieces = splitToFit(line, (piece) => piece.length + 1 <= chunkSize && countTokens(piece) <= MAX_CHUNK_TOKENS);
|
|
912
|
+
const last = pieces.pop() ?? "";
|
|
913
|
+
for (const piece of pieces) {
|
|
914
|
+
if (piece.trim().length > 0) chunks.push({ filePath, startLine: lineNo, endLine: lineNo, text: piece.trim(), kind });
|
|
915
|
+
}
|
|
916
|
+
currentChunk = last + "\n";
|
|
917
|
+
currentTokens = countTokens(last);
|
|
918
|
+
startLine = lineNo;
|
|
919
|
+
currentLine++;
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
879
922
|
currentChunk += lineWithNewline;
|
|
923
|
+
currentTokens += lineTokens;
|
|
880
924
|
currentLine++;
|
|
881
925
|
}
|
|
882
926
|
if (currentChunk.trim().length >= MIN_CHUNK_CHARS) {
|
|
@@ -889,17 +933,42 @@ function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize,
|
|
|
889
933
|
});
|
|
890
934
|
} else if (currentChunk.length > 0 && chunks.length > 0) {
|
|
891
935
|
const last = chunks[chunks.length - 1];
|
|
892
|
-
|
|
893
|
-
|
|
936
|
+
let mergedTokens = 0;
|
|
937
|
+
for (let lineNo = last.startLine; lineNo <= rangeEnd; lineNo++) mergedTokens += tokensOf(lineNo);
|
|
938
|
+
if (mergedTokens <= MAX_CHUNK_TOKENS) {
|
|
939
|
+
last.endLine = rangeEnd;
|
|
940
|
+
last.text = lines2.slice(last.startLine - 1, rangeEnd).join("\n").trim();
|
|
941
|
+
} else if (currentChunk.trim().length > 0) {
|
|
942
|
+
chunks.push({ filePath, startLine, endLine: rangeEnd, text: currentChunk.trim(), kind });
|
|
943
|
+
}
|
|
894
944
|
}
|
|
895
945
|
return chunks;
|
|
896
946
|
}
|
|
897
|
-
function
|
|
947
|
+
function splitToFit(text, fits) {
|
|
948
|
+
if (text.length < 2 || fits(text)) return [text];
|
|
949
|
+
const mid = Math.floor(text.length / 2);
|
|
950
|
+
let cut = mid;
|
|
951
|
+
for (let d = 0; d <= Math.floor(text.length / 4); d++) {
|
|
952
|
+
if (/\s/.test(text[mid - d] ?? "")) {
|
|
953
|
+
cut = mid - d;
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
if (/\s/.test(text[mid + d] ?? "")) {
|
|
957
|
+
cut = mid + d;
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
const before = text.charCodeAt(cut - 1);
|
|
962
|
+
if (before >= 55296 && before <= 56319) cut++;
|
|
963
|
+
if (cut <= 0 || cut >= text.length) return [text];
|
|
964
|
+
return [...splitToFit(text.slice(0, cut), fits), ...splitToFit(text.slice(cut), fits)];
|
|
965
|
+
}
|
|
966
|
+
function chunkFile(filePath, content, chunkSize = MAX_CHUNK_CHARS, overlap = 200, boundaries = [], countTokens) {
|
|
898
967
|
const lines2 = content.split(/\r?\n/);
|
|
899
968
|
if (lines2.length > 1 && lines2[lines2.length - 1] === "") lines2.pop();
|
|
900
969
|
const totalLines = lines2.length;
|
|
901
970
|
if (boundaries.length === 0) {
|
|
902
|
-
return splitRangeIntoChunks(filePath, lines2, 1, totalLines, chunkSize, overlap, "window");
|
|
971
|
+
return splitRangeIntoChunks(filePath, lines2, 1, totalLines, chunkSize, overlap, "window", countTokens);
|
|
903
972
|
}
|
|
904
973
|
const clipped = boundaries.map((b) => ({
|
|
905
974
|
start: Math.max(1, Math.min(b.start, totalLines)),
|
|
@@ -907,7 +976,7 @@ function chunkFile(filePath, content, chunkSize = MAX_CHUNK_CHARS, overlap = 200
|
|
|
907
976
|
kind: b.kind
|
|
908
977
|
})).filter((b) => b.end >= b.start).sort((a, b) => a.start - b.start || b.end - a.end);
|
|
909
978
|
if (clipped.length === 0) {
|
|
910
|
-
return splitRangeIntoChunks(filePath, lines2, 1, totalLines, chunkSize, overlap, "window");
|
|
979
|
+
return splitRangeIntoChunks(filePath, lines2, 1, totalLines, chunkSize, overlap, "window", countTokens);
|
|
911
980
|
}
|
|
912
981
|
const flattened = [];
|
|
913
982
|
let openEnd = 0;
|
|
@@ -974,7 +1043,7 @@ function chunkFile(filePath, content, chunkSize = MAX_CHUNK_CHARS, overlap = 200
|
|
|
974
1043
|
}
|
|
975
1044
|
const chunks = [];
|
|
976
1045
|
for (const r of ranges) {
|
|
977
|
-
chunks.push(...splitRangeIntoChunks(filePath, lines2, r.start, r.end, chunkSize, overlap, r.kind));
|
|
1046
|
+
chunks.push(...splitRangeIntoChunks(filePath, lines2, r.start, r.end, chunkSize, overlap, r.kind, countTokens));
|
|
978
1047
|
}
|
|
979
1048
|
return chunks;
|
|
980
1049
|
}
|
|
@@ -1225,8 +1294,12 @@ function mergeNearbyHits(hits, proximity = 20) {
|
|
|
1225
1294
|
return merged;
|
|
1226
1295
|
}
|
|
1227
1296
|
async function indexFile(db, filePath, content, boundaries = []) {
|
|
1228
|
-
|
|
1297
|
+
let chunks = chunkFile(filePath, content, void 0, void 0, boundaries);
|
|
1229
1298
|
if (chunks.length > 0) {
|
|
1299
|
+
if (embeddingsDepsAvailable(db)) {
|
|
1300
|
+
const { countTokens } = await getExtractor(DEFAULT_MODEL);
|
|
1301
|
+
if (countTokens !== void 0) chunks = chunkFile(filePath, content, void 0, void 0, boundaries, countTokens);
|
|
1302
|
+
}
|
|
1230
1303
|
return upsertChunks(db, chunks);
|
|
1231
1304
|
}
|
|
1232
1305
|
deleteFileEmbeddings(db, filePath);
|
|
@@ -1260,11 +1333,11 @@ function deleteFileEmbeddings(db, filePath) {
|
|
|
1260
1333
|
}
|
|
1261
1334
|
db.prepare(`DELETE FROM chunks WHERE ${pathEqClause("file_path")}`).run(folded);
|
|
1262
1335
|
}
|
|
1263
|
-
function resetAllEmbeddings(db) {
|
|
1336
|
+
function resetAllEmbeddings(db, keepVectors = false) {
|
|
1264
1337
|
const paths = db.prepare("SELECT DISTINCT file_path FROM chunks").pluck().all();
|
|
1265
1338
|
const clearEmbedSha = db.prepare(`UPDATE files SET embed_sha = NULL WHERE ${pathEqClause("path")}`);
|
|
1266
1339
|
const tx = db.transaction(() => {
|
|
1267
|
-
for (const p of paths) deleteFileEmbeddings(db, p);
|
|
1340
|
+
if (!keepVectors) for (const p of paths) deleteFileEmbeddings(db, p);
|
|
1268
1341
|
for (const p of paths) clearEmbedSha.run(foldPath(p));
|
|
1269
1342
|
});
|
|
1270
1343
|
tx.immediate();
|
|
@@ -1282,17 +1355,22 @@ function majorMinor(version) {
|
|
|
1282
1355
|
return parts.length >= 2 ? `${parts[0]}.${parts[1]}` : version;
|
|
1283
1356
|
}
|
|
1284
1357
|
var _provenanceChecked = /* @__PURE__ */ new WeakSet();
|
|
1358
|
+
function vectorSpaceOf(provenance) {
|
|
1359
|
+
const at = provenance.lastIndexOf("/embed-");
|
|
1360
|
+
return at === -1 ? provenance : provenance.slice(0, at);
|
|
1361
|
+
}
|
|
1285
1362
|
function ensureEmbeddingProvenance(db, modelName = DEFAULT_MODEL) {
|
|
1286
1363
|
if (_provenanceChecked.has(db)) return;
|
|
1287
1364
|
_provenanceChecked.add(db);
|
|
1288
1365
|
const current = embeddingProvenance(modelName);
|
|
1289
1366
|
const stored = db.prepare("SELECT provenance FROM embedding_provenance WHERE id = 1").pluck().get();
|
|
1290
1367
|
if (stored === current) return;
|
|
1291
|
-
const
|
|
1368
|
+
const keepVectors = stored !== void 0 && vectorSpaceOf(stored) === vectorSpaceOf(current);
|
|
1369
|
+
const cleared = resetAllEmbeddings(db, keepVectors);
|
|
1292
1370
|
db.prepare(
|
|
1293
1371
|
"INSERT INTO embedding_provenance (id, provenance) VALUES (1, ?) ON CONFLICT(id) DO UPDATE SET provenance = excluded.provenance"
|
|
1294
1372
|
).run(current);
|
|
1295
|
-
if (cleared > 0) {
|
|
1373
|
+
if (cleared > 0 && !keepVectors) {
|
|
1296
1374
|
console.warn(
|
|
1297
1375
|
`Embedding stack changed (${stored ?? "unrecorded"} -> ${current}); discarded ${cleared} file${cleared === 1 ? "" : "s"} worth of vectors because they no longer reliably describe this file's current chunks. Run \`token-goat index\` to rebuild them.`
|
|
1298
1376
|
);
|
|
@@ -1335,7 +1413,7 @@ function _pathPriorityPenalty(filePath) {
|
|
|
1335
1413
|
|
|
1336
1414
|
// src/parser_fingerprint.ts
|
|
1337
1415
|
init_define_import_meta_env();
|
|
1338
|
-
var PARSER_FINGERPRINT = "
|
|
1416
|
+
var PARSER_FINGERPRINT = "0d80572d3abdfb19";
|
|
1339
1417
|
|
|
1340
1418
|
// src/parser.ts
|
|
1341
1419
|
init_define_import_meta_env();
|
|
@@ -1374,7 +1452,7 @@ function* eachUnfencedLine(lines2) {
|
|
|
1374
1452
|
}
|
|
1375
1453
|
|
|
1376
1454
|
// src/hints/markdown_hints.ts
|
|
1377
|
-
var MARKDOWN_SIZE_THRESHOLD =
|
|
1455
|
+
var MARKDOWN_SIZE_THRESHOLD = 4e3;
|
|
1378
1456
|
var MAX_HEADINGS = 40;
|
|
1379
1457
|
var MAX_OUTPUT_LINES = 60;
|
|
1380
1458
|
function extractMarkdownHeadings(content, limit = MAX_HEADINGS) {
|
|
@@ -1918,6 +1996,28 @@ function extractTsJsSymbols(root, filePath, lines2) {
|
|
|
1918
1996
|
out.push(makeSymbol(filePath, fieldName.text, "method", node, lines2, "c"));
|
|
1919
1997
|
}
|
|
1920
1998
|
}
|
|
1999
|
+
if (node.type === "method_definition" && node.parent?.type === "object") {
|
|
2000
|
+
const name = nodeName(node);
|
|
2001
|
+
if (name !== null && name !== "") {
|
|
2002
|
+
out.push(makeSymbol(filePath, name, "method", node, lines2, "c"));
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (node.type === "pair" && node.parent?.type === "object") {
|
|
2006
|
+
const key = node.childForFieldName("key");
|
|
2007
|
+
const value = node.childForFieldName("value");
|
|
2008
|
+
if (key !== null && value !== null) {
|
|
2009
|
+
const keyName = key.type === "identifier" || key.type === "property_identifier" || key.type === "string" ? key.text.replace(/^['"]|['"]$/g, "") : null;
|
|
2010
|
+
if (keyName !== null && keyName !== "") {
|
|
2011
|
+
const isFn = value.type === "arrow_function" || value.type === "function_expression" || value.type === "function";
|
|
2012
|
+
const isObjectOrArray = value.type === "object" || value.type === "array";
|
|
2013
|
+
if (isFn) {
|
|
2014
|
+
out.push(makeSymbol(filePath, keyName, "method", node, lines2, "c"));
|
|
2015
|
+
} else if (isObjectOrArray && node.endPosition.row - node.startPosition.row >= 1) {
|
|
2016
|
+
out.push(makeSymbol(filePath, keyName, "config", node, lines2, "c"));
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
1921
2021
|
const childInside = insideFunction || TSJS_FN_SCOPE_TYPES.has(node.type);
|
|
1922
2022
|
for (const child of node.namedChildren) {
|
|
1923
2023
|
visit(child, childInside);
|
|
@@ -3594,7 +3694,7 @@ function parseSourceSymbolsTreeSitterOnly(content, filePath, language) {
|
|
|
3594
3694
|
var REGEX_ADAPTERS_SLOT = /* @__PURE__ */ Symbol.for("token-goat.regex-adapters");
|
|
3595
3695
|
var adapterSlot = globalThis;
|
|
3596
3696
|
async function loadRegexExtractors() {
|
|
3597
|
-
adapterSlot[REGEX_ADAPTERS_SLOT] ??= await import("./token-goat-chunk-
|
|
3697
|
+
adapterSlot[REGEX_ADAPTERS_SLOT] ??= await import("./token-goat-chunk-GPCCYQSS.mjs");
|
|
3598
3698
|
}
|
|
3599
3699
|
function regexAdapters() {
|
|
3600
3700
|
const loaded = adapterSlot[REGEX_ADAPTERS_SLOT];
|
|
@@ -4166,7 +4266,7 @@ function tableSectionEndIndex(headers, headerPos, totalLines) {
|
|
|
4166
4266
|
}
|
|
4167
4267
|
return totalLines;
|
|
4168
4268
|
}
|
|
4169
|
-
function resolveHeaderPos(headers, base, ordinal) {
|
|
4269
|
+
function resolveHeaderPos(headers, base, ordinal, allowFuzzy = true) {
|
|
4170
4270
|
const target = base.toLowerCase();
|
|
4171
4271
|
const normalizedTarget = normalizeHeading(base).toLowerCase();
|
|
4172
4272
|
const strippedTarget = normalizeHeadingStrip(base).toLowerCase();
|
|
@@ -4227,10 +4327,106 @@ function resolveHeaderPos(headers, base, ordinal) {
|
|
|
4227
4327
|
const allWordsMatch = queryWords.every((qw) => headingWords.some((hw) => hw.includes(qw)));
|
|
4228
4328
|
if (allWordsMatch) widenedMatches.push(i);
|
|
4229
4329
|
}
|
|
4230
|
-
if (widenedMatches.length
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4330
|
+
if (widenedMatches.length === 1) {
|
|
4331
|
+
const widenedPos = widenedMatches[0];
|
|
4332
|
+
if (widenedPos !== void 0) {
|
|
4333
|
+
return { headerPos: widenedPos, redirectedFrom: base, occurrences: null };
|
|
4334
|
+
}
|
|
4335
|
+
}
|
|
4336
|
+
function sectionLevenshtein(a, b) {
|
|
4337
|
+
if (a === b) return 0;
|
|
4338
|
+
const la = a.length;
|
|
4339
|
+
const lb = b.length;
|
|
4340
|
+
if (la === 0) return lb;
|
|
4341
|
+
if (lb === 0) return la;
|
|
4342
|
+
const v0 = new Array(lb + 1);
|
|
4343
|
+
const v1 = new Array(lb + 1);
|
|
4344
|
+
for (let i = 0; i <= lb; i++) v0[i] = i;
|
|
4345
|
+
for (let i = 0; i < la; i++) {
|
|
4346
|
+
v1[0] = i + 1;
|
|
4347
|
+
for (let j = 0; j < lb; j++) {
|
|
4348
|
+
const cost = a.charCodeAt(i) === b.charCodeAt(j) ? 0 : 1;
|
|
4349
|
+
v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
|
|
4350
|
+
}
|
|
4351
|
+
for (let j = 0; j <= lb; j++) v0[j] = v1[j];
|
|
4352
|
+
}
|
|
4353
|
+
return v0[lb];
|
|
4354
|
+
}
|
|
4355
|
+
const STOP_WORDS = /* @__PURE__ */ new Set(["a", "an", "the", "and", "or", "in", "on", "at", "to", "for", "of", "with", "by", "is", "&"]);
|
|
4356
|
+
const cleanTokens = (str) => str.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 0);
|
|
4357
|
+
const rawQTokens = cleanTokens(base);
|
|
4358
|
+
const qTokens = rawQTokens.filter((t) => !STOP_WORDS.has(t) || rawQTokens.length <= 2);
|
|
4359
|
+
if (allowFuzzy && qTokens.length > 0) {
|
|
4360
|
+
const candidates = [];
|
|
4361
|
+
for (let i = 0; i < headers.length; i++) {
|
|
4362
|
+
const h = headers[i];
|
|
4363
|
+
if (h === void 0) continue;
|
|
4364
|
+
const rawHTokens = cleanTokens(h.heading);
|
|
4365
|
+
const hTokens = rawHTokens.filter((t) => !STOP_WORDS.has(t) || rawHTokens.length <= 2);
|
|
4366
|
+
if (hTokens.length === 0) continue;
|
|
4367
|
+
const normH = normalizeHeading(h.heading).toLowerCase();
|
|
4368
|
+
const maxLen = Math.max(normalizedTarget.length, normH.length);
|
|
4369
|
+
const editDist = sectionLevenshtein(normalizedTarget, normH);
|
|
4370
|
+
const strSim = maxLen > 0 ? 1 - editDist / maxLen : 0;
|
|
4371
|
+
let matchedQ = 0;
|
|
4372
|
+
for (const qw of qTokens) {
|
|
4373
|
+
let best = 0;
|
|
4374
|
+
for (const hw of hTokens) {
|
|
4375
|
+
if (qw === hw) {
|
|
4376
|
+
best = 1;
|
|
4377
|
+
break;
|
|
4378
|
+
}
|
|
4379
|
+
if (qw.length >= 3 && hw.length >= 3) {
|
|
4380
|
+
if (hw.startsWith(qw) || qw.startsWith(hw)) {
|
|
4381
|
+
best = Math.max(best, 0.9);
|
|
4382
|
+
} else if (sectionLevenshtein(qw, hw) <= 1) {
|
|
4383
|
+
best = Math.max(best, 0.85);
|
|
4384
|
+
}
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
matchedQ += best;
|
|
4388
|
+
}
|
|
4389
|
+
let matchedH = 0;
|
|
4390
|
+
for (const hw of hTokens) {
|
|
4391
|
+
let best = 0;
|
|
4392
|
+
for (const qw of qTokens) {
|
|
4393
|
+
if (qw === hw) {
|
|
4394
|
+
best = 1;
|
|
4395
|
+
break;
|
|
4396
|
+
}
|
|
4397
|
+
if (qw.length >= 3 && hw.length >= 3) {
|
|
4398
|
+
if (hw.startsWith(qw) || qw.startsWith(hw)) {
|
|
4399
|
+
best = Math.max(best, 0.9);
|
|
4400
|
+
} else if (sectionLevenshtein(qw, hw) <= 1) {
|
|
4401
|
+
best = Math.max(best, 0.85);
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
matchedH += best;
|
|
4406
|
+
}
|
|
4407
|
+
const wordRecall = matchedQ / qTokens.length;
|
|
4408
|
+
const wordPrecision = matchedH / hTokens.length;
|
|
4409
|
+
const tokenDice = 2 * matchedQ / (qTokens.length + hTokens.length);
|
|
4410
|
+
let score = 0;
|
|
4411
|
+
if (strSim >= 0.8) {
|
|
4412
|
+
score = strSim;
|
|
4413
|
+
} else if (tokenDice >= 0.75 && wordRecall >= 0.7 && wordPrecision >= 0.7) {
|
|
4414
|
+
score = (tokenDice + wordRecall + wordPrecision) / 3;
|
|
4415
|
+
}
|
|
4416
|
+
if (score >= 0.75) {
|
|
4417
|
+
candidates.push({ index: i, score });
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
if (candidates.length > 0) {
|
|
4421
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
4422
|
+
const best = candidates[0];
|
|
4423
|
+
const runnerUp = candidates[1];
|
|
4424
|
+
if (candidates.length === 1 || runnerUp !== void 0 && best.score - runnerUp.score >= 0.08) {
|
|
4425
|
+
return { headerPos: best.index, redirectedFrom: base, occurrences: null };
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
}
|
|
4429
|
+
return null;
|
|
4234
4430
|
}
|
|
4235
4431
|
function buildSectionResult(headers, kind, lines2, headerPos, redirectedFrom) {
|
|
4236
4432
|
const header = headers[headerPos];
|
|
@@ -4249,12 +4445,12 @@ function buildSectionResult(headers, kind, lines2, headerPos, redirectedFrom) {
|
|
|
4249
4445
|
};
|
|
4250
4446
|
return redirectedFrom === null ? result : { ...result, redirectedFrom };
|
|
4251
4447
|
}
|
|
4252
|
-
function resolveSectionFromText(text, headingSpec, language) {
|
|
4448
|
+
function resolveSectionFromText(text, headingSpec, language, allowFuzzy = true) {
|
|
4253
4449
|
const { headers, kind } = findHeaders(text, language);
|
|
4254
4450
|
const { base, ordinal } = parseHeadingSpec(headingSpec, headers);
|
|
4255
4451
|
if (base.length === 0) return null;
|
|
4256
4452
|
const lines2 = text.split("\n");
|
|
4257
|
-
const resolved = resolveHeaderPos(headers, base, ordinal);
|
|
4453
|
+
const resolved = resolveHeaderPos(headers, base, ordinal, allowFuzzy);
|
|
4258
4454
|
if (resolved === null) return null;
|
|
4259
4455
|
const built = buildSectionResult(headers, kind, lines2, resolved.headerPos, resolved.redirectedFrom);
|
|
4260
4456
|
if (built === null || resolved.occurrences === null) return built;
|
|
@@ -4281,10 +4477,10 @@ function readTextForSections(filePath, readFn) {
|
|
|
4281
4477
|
}
|
|
4282
4478
|
return redactIfDotenv(filePath, text);
|
|
4283
4479
|
}
|
|
4284
|
-
function readSection(filePath, headingSpec, readFn) {
|
|
4480
|
+
function readSection(filePath, headingSpec, readFn, allowFuzzy = true) {
|
|
4285
4481
|
const text = readTextForSections(filePath, readFn);
|
|
4286
4482
|
if (text === null) return null;
|
|
4287
|
-
return resolveSectionFromText(text, headingSpec, refineLanguageByContent(filePath, detectLanguage(filePath), text));
|
|
4483
|
+
return resolveSectionFromText(text, headingSpec, refineLanguageByContent(filePath, detectLanguage(filePath), text), allowFuzzy);
|
|
4288
4484
|
}
|
|
4289
4485
|
function findContainingSection(filePath, lineStart, lineEnd, readFn) {
|
|
4290
4486
|
const text = readTextForSections(filePath, readFn);
|
|
@@ -4334,6 +4530,8 @@ export {
|
|
|
4334
4530
|
isEmbeddableDocument,
|
|
4335
4531
|
ipynbToVirtualSource,
|
|
4336
4532
|
eachUnfencedLine,
|
|
4533
|
+
modelFilesPresent,
|
|
4534
|
+
ensureModelFiles,
|
|
4337
4535
|
checkEmbeddingPreflight,
|
|
4338
4536
|
OVER_FETCH_FACTOR,
|
|
4339
4537
|
MAX_OVER_FETCH,
|
|
@@ -3,7 +3,7 @@ const require = __cjsRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
deliveredOutputBytes,
|
|
5
5
|
wrappedShell
|
|
6
|
-
} from "./token-goat-chunk-
|
|
6
|
+
} from "./token-goat-chunk-GLOM5W5C.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ToolFilter,
|
|
9
9
|
capTokens,
|
|
@@ -14,18 +14,18 @@ import {
|
|
|
14
14
|
selectFilter,
|
|
15
15
|
shlexSplit,
|
|
16
16
|
storeBashOutputSync
|
|
17
|
-
} from "./token-goat-chunk-
|
|
18
|
-
import "./token-goat-chunk-2X2EBBC6.mjs";
|
|
17
|
+
} from "./token-goat-chunk-C26ZBGBC.mjs";
|
|
19
18
|
import {
|
|
20
19
|
recordStat
|
|
21
|
-
} from "./token-goat-chunk-
|
|
22
|
-
import "./token-goat-chunk-
|
|
20
|
+
} from "./token-goat-chunk-26YUO7MP.mjs";
|
|
21
|
+
import "./token-goat-chunk-BK3RPPTK.mjs";
|
|
22
|
+
import "./token-goat-chunk-MWSVUKVV.mjs";
|
|
23
23
|
import {
|
|
24
24
|
loadConfig
|
|
25
|
-
} from "./token-goat-chunk-
|
|
25
|
+
} from "./token-goat-chunk-2VASS5VR.mjs";
|
|
26
26
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
27
27
|
import "./token-goat-chunk-OSUFN2FV.mjs";
|
|
28
|
-
import "./token-goat-chunk-
|
|
28
|
+
import "./token-goat-chunk-UBZCON6N.mjs";
|
|
29
29
|
import "./token-goat-chunk-ERTXEKB6.mjs";
|
|
30
30
|
import "./token-goat-chunk-GMOUBOX4.mjs";
|
|
31
31
|
import {
|