fastrmemory 0.5.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/skills/skills.json +1 -1
- package/README.md +40 -30
- package/dist/bin/fastr.js +122 -14
- 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-init.d.ts.map +1 -1
- package/dist/src/installer/mcp-init.js +5 -6
- 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 -0
- package/dist/src/installer/setup.d.ts.map +1 -1
- package/dist/src/installer/setup.js +32 -0
- 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/llms-install.md +3 -3
- package/package.json +5 -1
- package/server.json +1 -1
- package/skills/skills.json +1 -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":"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"}
|
|
@@ -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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"}
|
package/llms-install.md
CHANGED
|
@@ -27,9 +27,9 @@ From the project the developer works in, configure the MCP client with one comma
|
|
|
27
27
|
fastr mcp init --client claude
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Supported project-scoped clients are `claude`, `cursor`, `vscode`, `opencode`, `gemini`, and `copilot`. Use `--client all --scope project` for all six. User-scoped clients are `claude`, `cursor`, `vscode`, `gemini`, `windsurf`, `antigravity`, `claude-desktop`, and `codex`; `codex` prints a TOML snippet for `~/.codex/config.toml` instead of rewriting it. The default writes `fastrmemory@latest`; add `--channel pinned` to write the exact version, `--runner pnpm|yarn|bunx` to change the package runner, and `--dry-run` to inspect without writing. Existing JSON is merged, unrelated keys are preserved, and the first change writes a `.fastr.bak` backup. Pass `--source local` to write the active CLI path plus an absolute `--project`; use the default `--source registry` for portable configs. `--source local` ships in `0.5.0
|
|
30
|
+
Supported project-scoped clients are `claude`, `cursor`, `vscode`, `opencode`, `gemini`, and `copilot`. Use `--client all --scope project` for all six. User-scoped clients are `claude`, `cursor`, `vscode`, `gemini`, `windsurf`, `antigravity`, `claude-desktop`, and `codex`; `codex` prints a TOML snippet for `~/.codex/config.toml` instead of rewriting it. The default writes `fastrmemory@latest`; add `--channel pinned` to write the exact version, `--runner pnpm|yarn|bunx` to change the package runner, and `--dry-run` to inspect without writing. Existing JSON is merged, unrelated keys are preserved, and the first change writes a `.fastr.bak` backup. Pass `--source local` to write the active CLI path plus an absolute `--project`; use the default `--source registry` for portable configs. `--source local` ships in published `0.5.0`; `0.4.0` remains published historical, and on `0.4.0`, `fastr setup` writes an installed-CLI entry.
|
|
31
31
|
|
|
32
|
-
> `mcp init` ships in
|
|
32
|
+
> `mcp init` ships in `0.4.0` and later; `npx fastrmemory@latest mcp init ...` now resolves to published `0.5.0`. If the command is missing, check `fastr --version`, install `npm install -g fastrmemory@0.5.0`, or run `npx -y fastrmemory@0.5.0 mcp init ...`. For the previous release, use `fastr setup` or pin `fastrmemory@0.3.1`.
|
|
33
33
|
|
|
34
34
|
For the full installer (database initialization, `AGENTS.md`, skills, and lifecycle hooks), run:
|
|
35
35
|
|
|
@@ -58,7 +58,7 @@ Any MCP client can launch the stdio server directly:
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
For user-scoped clients (Claude Desktop, Antigravity, Windsurf, and the Claude Code entry in `~/.claude.json`), append `--project /absolute/path/to/project` so the client's launch directory cannot select the wrong database. `fastr mcp init --scope user` adds this automatically. On native Windows, `fastr mcp init` emits `cmd /c npx ...`; a manual entry can use `cmd /c npx -y fastrmemory@latest mcp` if the client cannot launch `npx` directly. `fastr setup` writes the absolute `node` path automatically. On
|
|
61
|
+
For user-scoped clients (Claude Desktop, Antigravity, Windsurf, and the Claude Code entry in `~/.claude.json`), append `--project /absolute/path/to/project` so the client's launch directory cannot select the wrong database. `fastr mcp init --scope user` adds this automatically. On native Windows, `fastr mcp init` emits `cmd /c npx ...`; a manual entry can use `cmd /c npx -y fastrmemory@latest mcp` if the client cannot launch `npx` directly. `fastr setup` writes the absolute `node` path automatically. On published `0.5.0`, `fastr mcp init --source local` writes the same installed-CLI shape. The default core profile exposes 12 tools, including `fastr_tools` and `fastr_call`; add `--profile full` to expose all 43.
|
|
62
62
|
|
|
63
63
|
## 5. Verify
|
|
64
64
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastrmemory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"mcpName": "io.github.atifjubaer/fastrmemory",
|
|
5
5
|
"description": "High-Performance Cognitive Agent Memory Engine with Bi-Temporal SQLite and Official MCP v2",
|
|
6
6
|
"type": "module",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"smoke:gemini": "npm run build:core && node scripts/smoke-gemini.mjs",
|
|
53
53
|
"smoke:copilot": "npm run build:core && node scripts/smoke-copilot.mjs",
|
|
54
54
|
"smoke:opencode": "npm run build:core && node scripts/smoke-opencode.mjs",
|
|
55
|
+
"smoke:hooks": "npm run build:core && node scripts/smoke-hooks.mjs",
|
|
55
56
|
"test:crash": "node scripts/crash-test.mjs",
|
|
56
57
|
"check:skills": "node scripts/check-skills.mjs",
|
|
57
58
|
"check:dist-ui": "node scripts/check-dist-ui.mjs",
|
|
@@ -64,6 +65,9 @@
|
|
|
64
65
|
"bench:legacy": "tsx scripts/capture-bench.ts",
|
|
65
66
|
"bench:public": "tsx scripts/eval-public.ts",
|
|
66
67
|
"bench:external": "tsx scripts/eval-external.ts",
|
|
68
|
+
"bench:vs": "tsx scripts/bench-vs.ts",
|
|
69
|
+
"bench:fetch": "tsx scripts/fetch-bench-data.ts",
|
|
70
|
+
"bench:setup": "tsx scripts/fetch-bench-data.ts --engines",
|
|
67
71
|
"bench:verify": "node scripts/check-bench.mjs",
|
|
68
72
|
"verify:replay": "tsx scripts/verify-replay.ts",
|
|
69
73
|
"check:ci": "npm run test && npm run test:isolation && npm run check:skills && npm run check:dist-ui && npm run check:package && npm run check:query-plans && npm run check:recall-latency && npm run check:install-size && npm run verify:replay && npm run check:hygiene && npm run check:docs && npm run check:crash && npm run bench:verify",
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.atifjubaer/fastrmemory",
|
|
4
4
|
"title": "FastrMemory",
|
|
5
5
|
"description": "Local-first cognitive agent memory with bi-temporal SQLite, replayable history, and triple-stream retrieval.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.6.0",
|
|
7
7
|
"websiteUrl": "https://github.com/atifjubaer/fastrmemory",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/atifjubaer/fastrmemory",
|
package/skills/skills.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://skills.sh/schema/v1.json",
|
|
3
3
|
"name": "fastrmemory-skills",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"description": "Agent Skills that teach coding agents when to recall, log traps, curate, and commit FastrMemory.",
|
|
6
6
|
"author": "Fastrsoft",
|
|
7
7
|
"license": "Apache-2.0",
|