fastrmemory 0.4.0 → 0.6.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.cursor/mcp.json +1 -1
- package/.cursor/skills/fastr-setup/SKILL.md +4 -4
- package/.cursor/skills/skills.json +1 -1
- package/README.md +87 -36
- package/dist/bin/fastr.js +131 -17
- package/dist/bin/fastr.js.map +1 -1
- package/dist/src/bench/harness.d.ts.map +1 -1
- package/dist/src/bench/harness.js +4 -0
- package/dist/src/bench/harness.js.map +1 -1
- package/dist/src/bench/marker-corpus.d.ts +98 -0
- package/dist/src/bench/marker-corpus.d.ts.map +1 -0
- package/dist/src/bench/marker-corpus.js +306 -0
- package/dist/src/bench/marker-corpus.js.map +1 -0
- package/dist/src/bench/mcp-stdio.d.ts +55 -0
- package/dist/src/bench/mcp-stdio.d.ts.map +1 -0
- package/dist/src/bench/mcp-stdio.js +146 -0
- package/dist/src/bench/mcp-stdio.js.map +1 -0
- package/dist/src/bench/public-datasets.d.ts +2 -0
- package/dist/src/bench/public-datasets.d.ts.map +1 -1
- package/dist/src/bench/public-datasets.js +2 -1
- package/dist/src/bench/public-datasets.js.map +1 -1
- package/dist/src/bench/public-harness.d.ts +14 -0
- package/dist/src/bench/public-harness.d.ts.map +1 -1
- package/dist/src/bench/public-harness.js +83 -8
- package/dist/src/bench/public-harness.js.map +1 -1
- package/dist/src/bench/public-pins.js +5 -5
- package/dist/src/bench/public-pins.js.map +1 -1
- package/dist/src/bench/split.d.ts +33 -0
- package/dist/src/bench/split.d.ts.map +1 -0
- package/dist/src/bench/split.js +56 -0
- package/dist/src/bench/split.js.map +1 -0
- package/dist/src/bench/stats.d.ts +40 -0
- package/dist/src/bench/stats.d.ts.map +1 -0
- package/dist/src/bench/stats.js +99 -0
- package/dist/src/bench/stats.js.map +1 -0
- package/dist/src/bench/vs-engines.d.ts +51 -0
- package/dist/src/bench/vs-engines.d.ts.map +1 -0
- package/dist/src/bench/vs-engines.js +121 -0
- package/dist/src/bench/vs-engines.js.map +1 -0
- package/dist/src/config.d.ts +33 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +84 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/db/doctor.d.ts +8 -0
- package/dist/src/db/doctor.d.ts.map +1 -1
- package/dist/src/db/doctor.js +65 -1
- package/dist/src/db/doctor.js.map +1 -1
- package/dist/src/db/fts-queue.d.ts +35 -0
- package/dist/src/db/fts-queue.d.ts.map +1 -0
- package/dist/src/db/fts-queue.js +78 -0
- package/dist/src/db/fts-queue.js.map +1 -0
- package/dist/src/db/repository.d.ts +63 -1
- package/dist/src/db/repository.d.ts.map +1 -1
- package/dist/src/db/repository.js +244 -50
- package/dist/src/db/repository.js.map +1 -1
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +63 -2
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/installer/copilot.d.ts +21 -0
- package/dist/src/installer/copilot.d.ts.map +1 -1
- package/dist/src/installer/copilot.js +72 -1
- package/dist/src/installer/copilot.js.map +1 -1
- package/dist/src/installer/gemini.d.ts +13 -0
- package/dist/src/installer/gemini.d.ts.map +1 -1
- package/dist/src/installer/gemini.js +64 -1
- package/dist/src/installer/gemini.js.map +1 -1
- package/dist/src/installer/hooks.d.ts +42 -5
- package/dist/src/installer/hooks.d.ts.map +1 -1
- package/dist/src/installer/hooks.js +270 -62
- package/dist/src/installer/hooks.js.map +1 -1
- package/dist/src/installer/json-config.d.ts +25 -1
- package/dist/src/installer/json-config.d.ts.map +1 -1
- package/dist/src/installer/json-config.js +95 -2
- package/dist/src/installer/json-config.js.map +1 -1
- package/dist/src/installer/mcp-command.d.ts +19 -0
- package/dist/src/installer/mcp-command.d.ts.map +1 -0
- package/dist/src/installer/mcp-command.js +57 -0
- package/dist/src/installer/mcp-command.js.map +1 -0
- package/dist/src/installer/mcp-init.d.ts +16 -0
- package/dist/src/installer/mcp-init.d.ts.map +1 -1
- package/dist/src/installer/mcp-init.js +34 -13
- package/dist/src/installer/mcp-init.js.map +1 -1
- package/dist/src/installer/opencode.d.ts +18 -0
- package/dist/src/installer/opencode.d.ts.map +1 -1
- package/dist/src/installer/opencode.js +81 -1
- package/dist/src/installer/opencode.js.map +1 -1
- package/dist/src/installer/setup.d.ts +7 -11
- package/dist/src/installer/setup.d.ts.map +1 -1
- package/dist/src/installer/setup.js +34 -31
- package/dist/src/installer/setup.js.map +1 -1
- package/dist/src/mcp/profiles.d.ts +9 -6
- package/dist/src/mcp/profiles.d.ts.map +1 -1
- package/dist/src/mcp/profiles.js +12 -9
- package/dist/src/mcp/profiles.js.map +1 -1
- package/dist/src/mcp/server.d.ts +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +80 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/search/aggregate.d.ts +24 -0
- package/dist/src/search/aggregate.d.ts.map +1 -0
- package/dist/src/search/aggregate.js +59 -0
- package/dist/src/search/aggregate.js.map +1 -0
- package/dist/src/search/backfill.d.ts.map +1 -1
- package/dist/src/search/backfill.js +7 -2
- package/dist/src/search/backfill.js.map +1 -1
- package/dist/src/search/budget.d.ts +2 -0
- package/dist/src/search/budget.d.ts.map +1 -1
- package/dist/src/search/budget.js.map +1 -1
- package/dist/src/search/embeddings.d.ts +35 -2
- package/dist/src/search/embeddings.d.ts.map +1 -1
- package/dist/src/search/embeddings.js +128 -5
- package/dist/src/search/embeddings.js.map +1 -1
- package/dist/src/search/hybrid-rrf.d.ts +45 -0
- package/dist/src/search/hybrid-rrf.d.ts.map +1 -1
- package/dist/src/search/hybrid-rrf.js +212 -56
- package/dist/src/search/hybrid-rrf.js.map +1 -1
- package/dist/src/search/static-model-install.d.ts +43 -0
- package/dist/src/search/static-model-install.d.ts.map +1 -0
- package/dist/src/search/static-model-install.js +112 -0
- package/dist/src/search/static-model-install.js.map +1 -0
- package/dist/src/search/static-model.d.ts +63 -0
- package/dist/src/search/static-model.d.ts.map +1 -0
- package/dist/src/search/static-model.js +244 -0
- package/dist/src/search/static-model.js.map +1 -0
- package/dist/src/search/temporal.d.ts +32 -0
- package/dist/src/search/temporal.d.ts.map +1 -0
- package/dist/src/search/temporal.js +164 -0
- package/dist/src/search/temporal.js.map +1 -0
- package/dist/src/ui/server.d.ts.map +1 -1
- package/dist/src/ui/server.js +10 -0
- package/dist/src/ui/server.js.map +1 -1
- package/dist-ui/assets/{ActionsPage-B3quzFNF.js → ActionsPage-CI-IRMeS.js} +1 -1
- package/dist-ui/assets/{GraphPage-DetiATmC.js → GraphPage-BdYMF7yz.js} +1 -1
- package/dist-ui/assets/{ObservatoryPage-QIGMwENf.js → ObservatoryPage-BG_vg8B9.js} +1 -1
- package/dist-ui/assets/{TreemapPage-C7uLZd37.js → TreemapPage-CZreyyLA.js} +1 -1
- package/dist-ui/assets/index-Ca9pma3Q.css +1 -0
- package/dist-ui/assets/{index-DWAH--Fu.js → index-MlNuiu0T.js} +17 -17
- package/dist-ui/assets/{maximize-2-BebkGbZA.js → maximize-2-_nvSvCC7.js} +1 -1
- package/dist-ui/build-manifest.json +11 -11
- package/dist-ui/index.html +2 -2
- package/llms-install.md +3 -3
- package/package.json +5 -1
- package/server.json +1 -1
- package/skills/fastr-setup/SKILL.md +4 -4
- package/skills/skills.json +1 -1
- package/dist-ui/assets/index-BJnPINTu.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-model-install.js","sourceRoot":"","sources":["../../../src/search/static-model-install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-TypeScript static embedding model (model2vec / potion).
|
|
3
|
+
*
|
|
4
|
+
* A model2vec model is a lookup table: one 256-dim vector per WordPiece token, plus the
|
|
5
|
+
* tokenizer. Inference is mean pooling over the token rows followed by L2 normalization,
|
|
6
|
+
* exactly as `model2vec.StaticModel.encode` does it: no special tokens, unknown tokens
|
|
7
|
+
* dropped, no Zipf weighting at inference (that is a training-time re-regularization).
|
|
8
|
+
*
|
|
9
|
+
* This module reads `model.safetensors` and `tokenizer.json` directly, so the semantic tier
|
|
10
|
+
* needs no native binary and no extra runtime dependency.
|
|
11
|
+
*/
|
|
12
|
+
export declare const POTION_BASE_8M: {
|
|
13
|
+
readonly name: "minishlab/potion-base-8M";
|
|
14
|
+
readonly revision: "bf8b056651a2c21b8d2565580b8569da283cab23";
|
|
15
|
+
readonly modelFile: "model.safetensors";
|
|
16
|
+
readonly modelBytes: 30236760;
|
|
17
|
+
readonly modelSha256: "f65d0f325faadc1e121c319e2faa41170d3fa07d8c89abd48ca5358d9a223de2";
|
|
18
|
+
readonly tokenizerFile: "tokenizer.json";
|
|
19
|
+
readonly tokenizerBytes: 683666;
|
|
20
|
+
readonly tokenizerSha256: "e67e803f624fb4d67dea1c730d06e1067e1b14d830e2c2202569e3ef0f70bb50";
|
|
21
|
+
readonly dim: 256;
|
|
22
|
+
readonly vocabSize: 29528;
|
|
23
|
+
};
|
|
24
|
+
export interface StaticModel {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly dim: number;
|
|
27
|
+
readonly vocabSize: number;
|
|
28
|
+
/** WordPiece token ids for a string, with special tokens omitted. */
|
|
29
|
+
tokenize(text: string): number[];
|
|
30
|
+
/** Mean-pooled, L2-normalized embedding. */
|
|
31
|
+
embed(text: string): Float32Array;
|
|
32
|
+
}
|
|
33
|
+
interface WordPieceVocab {
|
|
34
|
+
vocab: Map<string, number>;
|
|
35
|
+
unkId: number;
|
|
36
|
+
continuingPrefix: string;
|
|
37
|
+
maxCharsPerWord: number;
|
|
38
|
+
}
|
|
39
|
+
/** Parses the `model` section of a HuggingFace `tokenizer.json`. */
|
|
40
|
+
export declare function parseWordPieceVocab(tokenizerJson: unknown): WordPieceVocab;
|
|
41
|
+
/**
|
|
42
|
+
* `BertNormalizer` with the flags this model ships: clean_text, handle_chinese_chars,
|
|
43
|
+
* lowercase, and strip_accents (which BERT defaults to the lowercase flag when unset).
|
|
44
|
+
*/
|
|
45
|
+
export declare function normalizeBertText(text: string): string;
|
|
46
|
+
/** `BertPreTokenizer`: whitespace-delimited words with punctuation isolated. */
|
|
47
|
+
export declare function preTokenizeBert(normalized: string): string[];
|
|
48
|
+
/** Greedy longest-match-first WordPiece, with whole-word `[UNK]` on failure. */
|
|
49
|
+
export declare function wordPieceTokenize(word: string, vocab: WordPieceVocab): number[];
|
|
50
|
+
export declare function createBertTokenizer(tokenizerJson: unknown): (text: string) => number[];
|
|
51
|
+
export interface SafetensorsTensor {
|
|
52
|
+
data: Float32Array;
|
|
53
|
+
shape: number[];
|
|
54
|
+
}
|
|
55
|
+
/** Reads a single 2-D float32 tensor from a safetensors file buffer. */
|
|
56
|
+
export declare function readSafetensorsTensor(buffer: Buffer, name?: string): SafetensorsTensor;
|
|
57
|
+
/**
|
|
58
|
+
* Loads a model2vec directory (`model.safetensors` + `tokenizer.json`).
|
|
59
|
+
* Throws when either file is missing or malformed; callers decide whether that is fatal.
|
|
60
|
+
*/
|
|
61
|
+
export declare function loadStaticModel(modelDir: string): StaticModel;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=static-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-model.d.ts","sourceRoot":"","sources":["../../../src/search/static-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,cAAc;;;;;;;;;;;CAWjB,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,4CAA4C;IAC5C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CACnC;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,OAAO,GAAG,cAAc,CA0B1E;AAoCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBtD;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAqB5D;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CAyB/E;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAStF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAyBtF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CA6C7D"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-TypeScript static embedding model (model2vec / potion).
|
|
3
|
+
*
|
|
4
|
+
* A model2vec model is a lookup table: one 256-dim vector per WordPiece token, plus the
|
|
5
|
+
* tokenizer. Inference is mean pooling over the token rows followed by L2 normalization,
|
|
6
|
+
* exactly as `model2vec.StaticModel.encode` does it: no special tokens, unknown tokens
|
|
7
|
+
* dropped, no Zipf weighting at inference (that is a training-time re-regularization).
|
|
8
|
+
*
|
|
9
|
+
* This module reads `model.safetensors` and `tokenizer.json` directly, so the semantic tier
|
|
10
|
+
* needs no native binary and no extra runtime dependency.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
export const POTION_BASE_8M = {
|
|
15
|
+
name: 'minishlab/potion-base-8M',
|
|
16
|
+
revision: 'bf8b056651a2c21b8d2565580b8569da283cab23',
|
|
17
|
+
modelFile: 'model.safetensors',
|
|
18
|
+
modelBytes: 30_236_760,
|
|
19
|
+
modelSha256: 'f65d0f325faadc1e121c319e2faa41170d3fa07d8c89abd48ca5358d9a223de2',
|
|
20
|
+
tokenizerFile: 'tokenizer.json',
|
|
21
|
+
tokenizerBytes: 683_666,
|
|
22
|
+
tokenizerSha256: 'e67e803f624fb4d67dea1c730d06e1067e1b14d830e2c2202569e3ef0f70bb50',
|
|
23
|
+
dim: 256,
|
|
24
|
+
vocabSize: 29_528
|
|
25
|
+
};
|
|
26
|
+
/** Parses the `model` section of a HuggingFace `tokenizer.json`. */
|
|
27
|
+
export function parseWordPieceVocab(tokenizerJson) {
|
|
28
|
+
const model = tokenizerJson?.model;
|
|
29
|
+
if (!model || model.type !== 'WordPiece') {
|
|
30
|
+
throw new Error('tokenizer.json does not contain a WordPiece model');
|
|
31
|
+
}
|
|
32
|
+
const raw = model.vocab;
|
|
33
|
+
if (!raw)
|
|
34
|
+
throw new Error('tokenizer.json is missing the WordPiece vocabulary');
|
|
35
|
+
const vocab = new Map();
|
|
36
|
+
for (const [token, id] of Object.entries(raw)) {
|
|
37
|
+
if (typeof id === 'number')
|
|
38
|
+
vocab.set(token, id);
|
|
39
|
+
}
|
|
40
|
+
const unkId = vocab.get('[UNK]');
|
|
41
|
+
if (unkId === undefined)
|
|
42
|
+
throw new Error('WordPiece vocabulary is missing [UNK]');
|
|
43
|
+
return {
|
|
44
|
+
vocab,
|
|
45
|
+
unkId,
|
|
46
|
+
continuingPrefix: typeof model.continuing_subword_prefix === 'string'
|
|
47
|
+
? model.continuing_subword_prefix
|
|
48
|
+
: '##',
|
|
49
|
+
maxCharsPerWord: typeof model.max_input_chars_per_word === 'number'
|
|
50
|
+
? model.max_input_chars_per_word
|
|
51
|
+
: 100
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** True for the Unicode code points BERT's `handle_chinese_chars` surrounds with spaces. */
|
|
55
|
+
function isChineseChar(code) {
|
|
56
|
+
return ((code >= 0x4e00 && code <= 0x9fff) ||
|
|
57
|
+
(code >= 0x3400 && code <= 0x4dbf) ||
|
|
58
|
+
(code >= 0x20000 && code <= 0x2a6df) ||
|
|
59
|
+
(code >= 0x2a700 && code <= 0x2b73f) ||
|
|
60
|
+
(code >= 0x2b740 && code <= 0x2b81f) ||
|
|
61
|
+
(code >= 0x2b920 && code <= 0x2ceaf) ||
|
|
62
|
+
(code >= 0xf900 && code <= 0xfaff) ||
|
|
63
|
+
(code >= 0x2f800 && code <= 0x2fa1f));
|
|
64
|
+
}
|
|
65
|
+
/** BERT punctuation: ASCII ranges plus every Unicode `P*` code point. */
|
|
66
|
+
function isPunctuation(char) {
|
|
67
|
+
const code = char.codePointAt(0) ?? 0;
|
|
68
|
+
if ((code >= 33 && code <= 47) ||
|
|
69
|
+
(code >= 58 && code <= 64) ||
|
|
70
|
+
(code >= 91 && code <= 96) ||
|
|
71
|
+
(code >= 123 && code <= 126)) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return /\p{P}/u.test(char);
|
|
75
|
+
}
|
|
76
|
+
function isControlOrReplacement(char) {
|
|
77
|
+
const code = char.codePointAt(0) ?? 0;
|
|
78
|
+
if (code === 0 || code === 0xfffd)
|
|
79
|
+
return true;
|
|
80
|
+
return /\p{Cc}|\p{Cf}/u.test(char);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* `BertNormalizer` with the flags this model ships: clean_text, handle_chinese_chars,
|
|
84
|
+
* lowercase, and strip_accents (which BERT defaults to the lowercase flag when unset).
|
|
85
|
+
*/
|
|
86
|
+
export function normalizeBertText(text) {
|
|
87
|
+
let out = '';
|
|
88
|
+
for (const char of text) {
|
|
89
|
+
// Whitespace becomes a single space before the control-character filter: the
|
|
90
|
+
// reference tokenizer treats tabs/newlines as word delimiters, not as noise.
|
|
91
|
+
if (/\s/u.test(char)) {
|
|
92
|
+
out += ' ';
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (isControlOrReplacement(char))
|
|
96
|
+
continue;
|
|
97
|
+
if (isChineseChar(char.codePointAt(0) ?? 0)) {
|
|
98
|
+
out += ` ${char} `;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
out += char;
|
|
102
|
+
}
|
|
103
|
+
return out.toLowerCase().normalize('NFD').replace(/\p{Mn}/gu, '');
|
|
104
|
+
}
|
|
105
|
+
/** `BertPreTokenizer`: whitespace-delimited words with punctuation isolated. */
|
|
106
|
+
export function preTokenizeBert(normalized) {
|
|
107
|
+
const pieces = [];
|
|
108
|
+
let current = '';
|
|
109
|
+
const flush = () => {
|
|
110
|
+
if (current)
|
|
111
|
+
pieces.push(current);
|
|
112
|
+
current = '';
|
|
113
|
+
};
|
|
114
|
+
for (const char of normalized) {
|
|
115
|
+
if (char === ' ') {
|
|
116
|
+
flush();
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (isPunctuation(char)) {
|
|
120
|
+
flush();
|
|
121
|
+
pieces.push(char);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
current += char;
|
|
125
|
+
}
|
|
126
|
+
flush();
|
|
127
|
+
return pieces;
|
|
128
|
+
}
|
|
129
|
+
/** Greedy longest-match-first WordPiece, with whole-word `[UNK]` on failure. */
|
|
130
|
+
export function wordPieceTokenize(word, vocab) {
|
|
131
|
+
if (word.length === 0)
|
|
132
|
+
return [];
|
|
133
|
+
if (word.length > vocab.maxCharsPerWord)
|
|
134
|
+
return [vocab.unkId];
|
|
135
|
+
const ids = [];
|
|
136
|
+
let start = 0;
|
|
137
|
+
while (start < word.length) {
|
|
138
|
+
let end = word.length;
|
|
139
|
+
let match = -1;
|
|
140
|
+
while (start < end) {
|
|
141
|
+
const piece = start > 0
|
|
142
|
+
? `${vocab.continuingPrefix}${word.slice(start, end)}`
|
|
143
|
+
: word.slice(start, end);
|
|
144
|
+
const id = vocab.vocab.get(piece);
|
|
145
|
+
if (id !== undefined) {
|
|
146
|
+
match = id;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
end--;
|
|
150
|
+
}
|
|
151
|
+
if (match < 0)
|
|
152
|
+
return [vocab.unkId];
|
|
153
|
+
ids.push(match);
|
|
154
|
+
start = end;
|
|
155
|
+
}
|
|
156
|
+
return ids;
|
|
157
|
+
}
|
|
158
|
+
export function createBertTokenizer(tokenizerJson) {
|
|
159
|
+
const vocab = parseWordPieceVocab(tokenizerJson);
|
|
160
|
+
return (text) => {
|
|
161
|
+
const ids = [];
|
|
162
|
+
for (const piece of preTokenizeBert(normalizeBertText(text))) {
|
|
163
|
+
for (const id of wordPieceTokenize(piece, vocab))
|
|
164
|
+
ids.push(id);
|
|
165
|
+
}
|
|
166
|
+
return ids;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/** Reads a single 2-D float32 tensor from a safetensors file buffer. */
|
|
170
|
+
export function readSafetensorsTensor(buffer, name) {
|
|
171
|
+
if (buffer.byteLength < 9)
|
|
172
|
+
throw new Error('safetensors file is truncated');
|
|
173
|
+
const headerLength = Number(buffer.readBigUInt64LE(0));
|
|
174
|
+
const headerEnd = 8 + headerLength;
|
|
175
|
+
if (headerEnd > buffer.byteLength)
|
|
176
|
+
throw new Error('safetensors header exceeds file size');
|
|
177
|
+
const header = JSON.parse(buffer.subarray(8, headerEnd).toString('utf8'));
|
|
178
|
+
const key = name ?? Object.keys(header).find((candidate) => candidate !== '__metadata__');
|
|
179
|
+
if (!key)
|
|
180
|
+
throw new Error('safetensors file has no tensors');
|
|
181
|
+
const info = header[key];
|
|
182
|
+
if (!info || info.dtype !== 'F32' || !info.shape || !info.data_offsets) {
|
|
183
|
+
throw new Error(`safetensors tensor ${key} is not a float32 tensor`);
|
|
184
|
+
}
|
|
185
|
+
const [start, end] = info.data_offsets;
|
|
186
|
+
if (headerEnd + end > buffer.byteLength)
|
|
187
|
+
throw new Error('safetensors tensor exceeds file size');
|
|
188
|
+
const length = (end - start) / Float32Array.BYTES_PER_ELEMENT;
|
|
189
|
+
const data = new Float32Array(length);
|
|
190
|
+
new Uint8Array(data.buffer).set(buffer.subarray(headerEnd + start, headerEnd + end));
|
|
191
|
+
return { data, shape: info.shape };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Loads a model2vec directory (`model.safetensors` + `tokenizer.json`).
|
|
195
|
+
* Throws when either file is missing or malformed; callers decide whether that is fatal.
|
|
196
|
+
*/
|
|
197
|
+
export function loadStaticModel(modelDir) {
|
|
198
|
+
const modelPath = path.join(modelDir, POTION_BASE_8M.modelFile);
|
|
199
|
+
const tokenizerPath = path.join(modelDir, POTION_BASE_8M.tokenizerFile);
|
|
200
|
+
const tokenizerJson = JSON.parse(fs.readFileSync(tokenizerPath, 'utf8'));
|
|
201
|
+
const tokenize = createBertTokenizer(tokenizerJson);
|
|
202
|
+
const vocab = parseWordPieceVocab(tokenizerJson);
|
|
203
|
+
const tensor = readSafetensorsTensor(fs.readFileSync(modelPath));
|
|
204
|
+
if (tensor.shape.length !== 2) {
|
|
205
|
+
throw new Error(`expected a 2-D embedding matrix, got shape [${tensor.shape.join(', ')}]`);
|
|
206
|
+
}
|
|
207
|
+
const [vocabSize, dim] = tensor.shape;
|
|
208
|
+
const matrix = tensor.data;
|
|
209
|
+
return {
|
|
210
|
+
name: POTION_BASE_8M.name,
|
|
211
|
+
dim,
|
|
212
|
+
vocabSize,
|
|
213
|
+
tokenize,
|
|
214
|
+
embed(text) {
|
|
215
|
+
const ids = tokenize(text);
|
|
216
|
+
const out = new Float32Array(dim);
|
|
217
|
+
let count = 0;
|
|
218
|
+
for (const id of ids) {
|
|
219
|
+
if (id === vocab.unkId)
|
|
220
|
+
continue;
|
|
221
|
+
if (id < 0 || id >= vocabSize)
|
|
222
|
+
continue;
|
|
223
|
+
const offset = id * dim;
|
|
224
|
+
for (let i = 0; i < dim; i++)
|
|
225
|
+
out[i] += matrix[offset + i];
|
|
226
|
+
count++;
|
|
227
|
+
}
|
|
228
|
+
if (count === 0)
|
|
229
|
+
return out;
|
|
230
|
+
let norm = 0;
|
|
231
|
+
for (let i = 0; i < dim; i++) {
|
|
232
|
+
out[i] /= count;
|
|
233
|
+
norm += out[i] * out[i];
|
|
234
|
+
}
|
|
235
|
+
if (norm > 0) {
|
|
236
|
+
const inv = 1 / Math.sqrt(norm);
|
|
237
|
+
for (let i = 0; i < dim; i++)
|
|
238
|
+
out[i] *= inv;
|
|
239
|
+
}
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=static-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-model.js","sourceRoot":"","sources":["../../../src/search/static-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,0CAA0C;IACpD,SAAS,EAAE,mBAAmB;IAC9B,UAAU,EAAE,UAAU;IACtB,WAAW,EAAE,kEAAkE;IAC/E,aAAa,EAAE,gBAAgB;IAC/B,cAAc,EAAE,OAAO;IACvB,eAAe,EAAE,kEAAkE;IACnF,GAAG,EAAE,GAAG;IACR,SAAS,EAAE,MAAM;CACT,CAAC;AAmBX,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CAAC,aAAsB;IACxD,MAAM,KAAK,GAAI,aAAqD,EAAE,KAAK,CAAC;IAC5E,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,KAA2C,CAAC;IAC9D,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAEhF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAElF,OAAO;QACL,KAAK;QACL,KAAK;QACL,gBAAgB,EAAE,OAAO,KAAK,CAAC,yBAAyB,KAAK,QAAQ;YACnE,CAAC,CAAC,KAAK,CAAC,yBAAyB;YACjC,CAAC,CAAC,IAAI;QACR,eAAe,EAAE,OAAO,KAAK,CAAC,wBAAwB,KAAK,QAAQ;YACjE,CAAC,CAAC,KAAK,CAAC,wBAAwB;YAChC,CAAC,CAAC,GAAG;KACR,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,CACL,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;QACpC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,CACrC,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,IACE,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC;QAC1B,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC;QAC1B,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC;QAC1B,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,EAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,6EAA6E;QAC7E,6EAA6E;QAC7E,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,GAAG,IAAI,GAAG,CAAC;YACX,SAAS;QACX,CAAC;QACD,IAAI,sBAAsB,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC;YACnB,SAAS;QACX,CAAC;QACD,GAAG,IAAI,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC;IACf,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,KAAK,EAAE,CAAC;YACR,SAAS;QACX,CAAC;QACD,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,EAAE,CAAC;YACR,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAqB;IACnE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,eAAe;QAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE9D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACtB,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QACf,OAAO,KAAK,GAAG,GAAG,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;gBACrB,CAAC,CAAC,GAAG,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;gBACtD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;gBACrB,KAAK,GAAG,EAAE,CAAC;gBACX,MAAM;YACR,CAAC;YACD,GAAG,EAAE,CAAC;QACR,CAAC;QACD,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,aAAsB;IACxD,MAAM,KAAK,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IACjD,OAAO,CAAC,IAAY,EAAY,EAAE;QAChC,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC7D,KAAK,MAAM,EAAE,IAAI,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;AACJ,CAAC;AAOD,wEAAwE;AACxE,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,IAAa;IACjE,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC5E,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC;IACnC,IAAI,SAAS,GAAG,MAAM,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAE3F,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAGvE,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC;IAC1F,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,0BAA0B,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,IAAI,SAAS,GAAG,GAAG,GAAG,MAAM,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAEjG,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,YAAY,CAAC,iBAAiB,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC;IACrF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAExE,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,qBAAqB,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;IAE3B,OAAO;QACL,IAAI,EAAE,cAAc,CAAC,IAAI;QACzB,GAAG;QACH,SAAS;QACT,QAAQ;QACR,KAAK,CAAC,IAAY;YAChB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACrB,IAAI,EAAE,KAAK,KAAK,CAAC,KAAK;oBAAE,SAAS;gBACjC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,SAAS;oBAAE,SAAS;gBACxC,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,CAAC;gBACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;oBAAE,GAAG,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC3D,KAAK,EAAE,CAAC;YACV,CAAC;YACD,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,GAAG,CAAC;YAE5B,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;gBAChB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;oBAAE,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAC9C,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporal query windows.
|
|
3
|
+
*
|
|
4
|
+
* "How many times did I bake in the past two weeks?" is not a topical query: it is a
|
|
5
|
+
* date-bounded one. BM25 cannot see the bound, so it ranks sessions by shared words and
|
|
6
|
+
* loses the ones outside the window. This module parses the bound into an absolute
|
|
7
|
+
* interval using the question date, so retrieval can filter on `valid_from` first and
|
|
8
|
+
* rank inside the surviving set.
|
|
9
|
+
*
|
|
10
|
+
* Only explicit, unambiguous ranges are parsed. Anything else returns null and retrieval
|
|
11
|
+
* behaves exactly as before.
|
|
12
|
+
*/
|
|
13
|
+
export interface TemporalWindow {
|
|
14
|
+
/** Inclusive lower bound, ISO-8601 UTC. */
|
|
15
|
+
start: string;
|
|
16
|
+
/** Inclusive upper bound, ISO-8601 UTC. */
|
|
17
|
+
end: string;
|
|
18
|
+
/** Human-readable description of what was parsed, for result annotation. */
|
|
19
|
+
label: string;
|
|
20
|
+
}
|
|
21
|
+
/** Parses `2023/05/30 (Tue) 23:40` and ISO strings. Returns null for unknown formats. */
|
|
22
|
+
export declare function parseQuestionDate(value: string | undefined | null): Date | null;
|
|
23
|
+
/**
|
|
24
|
+
* Extracts an absolute window from a question.
|
|
25
|
+
*
|
|
26
|
+
* `questionDate` anchors relative ranges. Without it, only absolute ranges ("in 2022",
|
|
27
|
+
* "in March 2023") can be resolved.
|
|
28
|
+
*/
|
|
29
|
+
export declare function detectTemporalWindow(query: string, questionDate: Date | null): TemporalWindow | null;
|
|
30
|
+
/** True when a memory's `valid_from` falls inside the window. Unparseable dates never match. */
|
|
31
|
+
export declare function withinWindow(validFrom: string, window: TemporalWindow): boolean;
|
|
32
|
+
//# sourceMappingURL=temporal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../../../src/search/temporal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;CACf;AAoBD,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAiB/E;AAsCD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,GAAG,IAAI,GAAG,cAAc,GAAG,IAAI,CA8FpG;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAI/E"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporal query windows.
|
|
3
|
+
*
|
|
4
|
+
* "How many times did I bake in the past two weeks?" is not a topical query: it is a
|
|
5
|
+
* date-bounded one. BM25 cannot see the bound, so it ranks sessions by shared words and
|
|
6
|
+
* loses the ones outside the window. This module parses the bound into an absolute
|
|
7
|
+
* interval using the question date, so retrieval can filter on `valid_from` first and
|
|
8
|
+
* rank inside the surviving set.
|
|
9
|
+
*
|
|
10
|
+
* Only explicit, unambiguous ranges are parsed. Anything else returns null and retrieval
|
|
11
|
+
* behaves exactly as before.
|
|
12
|
+
*/
|
|
13
|
+
const MONTHS = {
|
|
14
|
+
january: 1, february: 2, march: 3, april: 4, may: 5, june: 6,
|
|
15
|
+
july: 7, august: 8, september: 9, october: 10, november: 11, december: 12,
|
|
16
|
+
jan: 1, feb: 2, mar: 3, apr: 4, jun: 6, jul: 7, aug: 8, sep: 9, sept: 9, oct: 10, nov: 11, dec: 12
|
|
17
|
+
};
|
|
18
|
+
const NUMBER_WORDS = {
|
|
19
|
+
one: 1, two: 2, three: 3, four: 4, five: 5, six: 6, seven: 7, eight: 8, nine: 9, ten: 10,
|
|
20
|
+
eleven: 11, twelve: 12, a: 1, an: 1
|
|
21
|
+
};
|
|
22
|
+
const UNIT_MS = {
|
|
23
|
+
day: 86_400_000,
|
|
24
|
+
week: 7 * 86_400_000,
|
|
25
|
+
month: 30 * 86_400_000,
|
|
26
|
+
year: 365 * 86_400_000
|
|
27
|
+
};
|
|
28
|
+
/** Parses `2023/05/30 (Tue) 23:40` and ISO strings. Returns null for unknown formats. */
|
|
29
|
+
export function parseQuestionDate(value) {
|
|
30
|
+
if (!value)
|
|
31
|
+
return null;
|
|
32
|
+
const match = /^(\d{4})[/-](\d{2})[/-](\d{2})(?:\s*\([A-Za-z]{3}\))?(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?/.exec(value.trim());
|
|
33
|
+
if (match) {
|
|
34
|
+
const [, year, month, day, hour, minute, second] = match;
|
|
35
|
+
const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day), hour ? Number(hour) : 0, minute ? Number(minute) : 0, second ? Number(second) : 0));
|
|
36
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
37
|
+
}
|
|
38
|
+
const parsed = new Date(value);
|
|
39
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
40
|
+
}
|
|
41
|
+
function iso(date) {
|
|
42
|
+
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
43
|
+
}
|
|
44
|
+
function windowFrom(start, end, label) {
|
|
45
|
+
if (start.getTime() > end.getTime())
|
|
46
|
+
return null;
|
|
47
|
+
return { start: iso(start), end: iso(end), label };
|
|
48
|
+
}
|
|
49
|
+
function subtractUnits(date, amount, unit) {
|
|
50
|
+
if (unit === 'month') {
|
|
51
|
+
// Calendar months have different lengths, so the day is clamped to the last day of
|
|
52
|
+
// the target month instead of rolling forward (2023-05-30 minus 3 months is
|
|
53
|
+
// 2023-02-28, not 2023-03-02).
|
|
54
|
+
const year = date.getUTCFullYear();
|
|
55
|
+
const month = date.getUTCMonth() - amount;
|
|
56
|
+
const lastDay = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
57
|
+
const day = Math.min(date.getUTCDate(), lastDay);
|
|
58
|
+
return new Date(Date.UTC(year, month, day, date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds()));
|
|
59
|
+
}
|
|
60
|
+
if (unit === 'year') {
|
|
61
|
+
const copy = new Date(date.getTime());
|
|
62
|
+
copy.setUTCFullYear(copy.getUTCFullYear() - amount);
|
|
63
|
+
return copy;
|
|
64
|
+
}
|
|
65
|
+
return new Date(date.getTime() - amount * UNIT_MS[unit]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extracts an absolute window from a question.
|
|
69
|
+
*
|
|
70
|
+
* `questionDate` anchors relative ranges. Without it, only absolute ranges ("in 2022",
|
|
71
|
+
* "in March 2023") can be resolved.
|
|
72
|
+
*/
|
|
73
|
+
export function detectTemporalWindow(query, questionDate) {
|
|
74
|
+
const text = query.toLowerCase().replace(/\s+/g, ' ').trim();
|
|
75
|
+
const anchor = questionDate ?? null;
|
|
76
|
+
// "past two weeks", "last 3 months", "in the past year"
|
|
77
|
+
const counted = /\b(?:in the )?(?:past|last)\s+(\d+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve)\s+(day|week|month|year)s?\b/.exec(text);
|
|
78
|
+
if (counted && anchor) {
|
|
79
|
+
const amount = /^\d+$/.test(counted[1]) ? Number(counted[1]) : NUMBER_WORDS[counted[1]];
|
|
80
|
+
if (amount > 0) {
|
|
81
|
+
return windowFrom(subtractUnits(anchor, amount, counted[2]), anchor, `past ${counted[1]} ${counted[2]}${amount === 1 ? '' : 's'}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// "past few months", "last couple of weeks"
|
|
85
|
+
const vague = /\b(?:in the )?(?:past|last)\s+(few|couple(?: of)?)\s+(day|week|month|year)s?\b/.exec(text);
|
|
86
|
+
if (vague && anchor) {
|
|
87
|
+
// "a few" is conventionally three; "a couple" is two.
|
|
88
|
+
const amount = vague[1] === 'few' ? 3 : 2;
|
|
89
|
+
return windowFrom(subtractUnits(anchor, amount, vague[2]), anchor, `past ${vague[1]} ${vague[2]}s`);
|
|
90
|
+
}
|
|
91
|
+
if (anchor) {
|
|
92
|
+
// "this week / month / year"
|
|
93
|
+
const current = /\bthis (week|month|year)\b/.exec(text);
|
|
94
|
+
if (current) {
|
|
95
|
+
const unit = current[1];
|
|
96
|
+
let start;
|
|
97
|
+
if (unit === 'week') {
|
|
98
|
+
start = new Date(anchor.getTime());
|
|
99
|
+
const day = start.getUTCDay();
|
|
100
|
+
start.setUTCDate(start.getUTCDate() - ((day + 6) % 7));
|
|
101
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
102
|
+
}
|
|
103
|
+
else if (unit === 'month') {
|
|
104
|
+
start = new Date(Date.UTC(anchor.getUTCFullYear(), anchor.getUTCMonth(), 1));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
start = new Date(Date.UTC(anchor.getUTCFullYear(), 0, 1));
|
|
108
|
+
}
|
|
109
|
+
return windowFrom(start, anchor, `this ${unit}`);
|
|
110
|
+
}
|
|
111
|
+
// "last week / month / year"
|
|
112
|
+
const previous = /\blast (week|month|year)\b/.exec(text);
|
|
113
|
+
if (previous) {
|
|
114
|
+
const unit = previous[1];
|
|
115
|
+
if (unit === 'year') {
|
|
116
|
+
const year = anchor.getUTCFullYear() - 1;
|
|
117
|
+
return windowFrom(new Date(Date.UTC(year, 0, 1)), new Date(Date.UTC(year, 11, 31, 23, 59, 59)), 'last year');
|
|
118
|
+
}
|
|
119
|
+
if (unit === 'month') {
|
|
120
|
+
const start = new Date(Date.UTC(anchor.getUTCFullYear(), anchor.getUTCMonth() - 1, 1));
|
|
121
|
+
const end = new Date(Date.UTC(anchor.getUTCFullYear(), anchor.getUTCMonth(), 0, 23, 59, 59));
|
|
122
|
+
return windowFrom(start, end, 'last month');
|
|
123
|
+
}
|
|
124
|
+
const start = new Date(anchor.getTime());
|
|
125
|
+
const day = start.getUTCDay();
|
|
126
|
+
start.setUTCDate(start.getUTCDate() - ((day + 6) % 7) - 7);
|
|
127
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
128
|
+
return windowFrom(start, new Date(start.getTime() + 7 * UNIT_MS.day - 1000), 'last week');
|
|
129
|
+
}
|
|
130
|
+
// "since the start of the year", "since the beginning of this year", "since this year"
|
|
131
|
+
if (/\bsince (?:the )?(?:start|beginning) of (?:the|this) year\b|\bsince (?:the )?(?:this )?year\b/.test(text)) {
|
|
132
|
+
return windowFrom(new Date(Date.UTC(anchor.getUTCFullYear(), 0, 1)), anchor, 'since the start of the year');
|
|
133
|
+
}
|
|
134
|
+
// "since 2021", "since March 2022"
|
|
135
|
+
const since = /\bsince\s+(?:(january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|jun|jul|aug|sep|sept|oct|nov|dec)\s+)?(\d{4})\b/.exec(text);
|
|
136
|
+
if (since) {
|
|
137
|
+
const month = since[1] ? MONTHS[since[1]] : 1;
|
|
138
|
+
const year = Number(since[2]);
|
|
139
|
+
return windowFrom(new Date(Date.UTC(year, month - 1, 1)), anchor, `since ${since[1] ? `${since[1]} ` : ''}${year}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Absolute year: "in 2022", "during 2021"
|
|
143
|
+
const year = /\b(?:in|during)\s+(\d{4})\b/.exec(text);
|
|
144
|
+
if (year) {
|
|
145
|
+
const value = Number(year[1]);
|
|
146
|
+
return windowFrom(new Date(Date.UTC(value, 0, 1)), new Date(Date.UTC(value, 11, 31, 23, 59, 59)), `in ${value}`);
|
|
147
|
+
}
|
|
148
|
+
// Absolute month + year: "in March 2023"
|
|
149
|
+
const monthYear = /\b(?:in|during)\s+(january|february|march|april|may|june|july|august|september|october|november|december)\s+(\d{4})\b/.exec(text);
|
|
150
|
+
if (monthYear) {
|
|
151
|
+
const month = MONTHS[monthYear[1]];
|
|
152
|
+
const value = Number(monthYear[2]);
|
|
153
|
+
return windowFrom(new Date(Date.UTC(value, month - 1, 1)), new Date(Date.UTC(value, month, 0, 23, 59, 59)), `${monthYear[1]} ${value}`);
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
/** True when a memory's `valid_from` falls inside the window. Unparseable dates never match. */
|
|
158
|
+
export function withinWindow(validFrom, window) {
|
|
159
|
+
const time = Date.parse(validFrom);
|
|
160
|
+
if (Number.isNaN(time))
|
|
161
|
+
return false;
|
|
162
|
+
return time >= Date.parse(window.start) && time <= Date.parse(window.end);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=temporal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal.js","sourceRoot":"","sources":["../../../src/search/temporal.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/ui/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/ui/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAMlC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAoB3C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAmBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAO3E;AAqID,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA2pB7I"}
|
package/dist/src/ui/server.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as http from 'node:http';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
import * as os from 'node:os';
|
|
4
5
|
import { fileURLToPath } from 'node:url';
|
|
5
6
|
import { exec } from 'node:child_process';
|
|
7
|
+
import { PACKAGE_VERSION } from '../version.js';
|
|
8
|
+
import { classifyMcpCommand, resolveMcpCommand, withProjectRoot } from '../installer/mcp-command.js';
|
|
6
9
|
import { initDatabase } from '../db/schema.js';
|
|
7
10
|
import { FastrRepository } from '../db/repository.js';
|
|
8
11
|
import { SpoolManager } from '../db/spool.js';
|
|
@@ -232,11 +235,18 @@ export function startUiServer(config, options = {}) {
|
|
|
232
235
|
const frontier = repo.getFrontier(config.projectId);
|
|
233
236
|
const conflicts = repo.listConflicts(config.projectId, 'open');
|
|
234
237
|
const entities = repo.getEntities(config.projectId);
|
|
238
|
+
const mcpEntry = withProjectRoot(resolveMcpCommand(), config.projectRoot);
|
|
235
239
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
236
240
|
res.end(JSON.stringify({
|
|
237
241
|
projectId: config.projectId,
|
|
238
242
|
projectName: config.projectName,
|
|
243
|
+
projectRoot: config.projectRoot,
|
|
239
244
|
dbPath: config.dbPath,
|
|
245
|
+
version: PACKAGE_VERSION,
|
|
246
|
+
platform: process.platform,
|
|
247
|
+
isHomeProject: path.resolve(config.projectRoot) === path.resolve(os.homedir()),
|
|
248
|
+
mcp: mcpEntry,
|
|
249
|
+
mcpSource: classifyMcpCommand(mcpEntry, config.projectRoot),
|
|
240
250
|
status,
|
|
241
251
|
trapsCount: traps.length,
|
|
242
252
|
activeCount: memories.length,
|