@graphmemory/server 1.3.0 → 1.3.1
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/dist/api/index.js +4 -4
- package/dist/api/rest/code.js +2 -1
- package/dist/api/rest/docs.js +2 -1
- package/dist/api/rest/embed.js +8 -1
- package/dist/api/rest/index.js +4 -3
- package/dist/api/rest/knowledge.js +4 -2
- package/dist/api/rest/skills.js +2 -1
- package/dist/api/rest/tasks.js +2 -1
- package/dist/api/rest/validation.js +41 -40
- package/dist/api/rest/websocket.js +24 -7
- package/dist/api/tools/knowledge/add-attachment.js +2 -1
- package/dist/api/tools/skills/add-attachment.js +2 -1
- package/dist/api/tools/tasks/add-attachment.js +2 -1
- package/dist/cli/index.js +5 -4
- package/dist/cli/indexer.js +2 -1
- package/dist/graphs/attachment-types.js +5 -0
- package/dist/graphs/code.js +34 -8
- package/dist/graphs/docs.js +5 -3
- package/dist/graphs/file-index.js +5 -3
- package/dist/graphs/knowledge.js +11 -4
- package/dist/graphs/skill.js +12 -5
- package/dist/graphs/task.js +12 -5
- package/dist/lib/defaults.js +78 -0
- package/dist/lib/embedder.js +11 -12
- package/dist/lib/embedding-codec.js +3 -5
- package/dist/lib/graph-persistence.js +68 -0
- package/dist/lib/mirror-watcher.js +4 -3
- package/dist/lib/parsers/docs.js +2 -1
- package/dist/lib/parsers/languages/typescript.js +34 -17
- package/dist/lib/project-manager.js +7 -1
- package/dist/lib/search/bm25.js +5 -4
- package/dist/lib/search/code.js +2 -1
- package/dist/lib/search/docs.js +2 -1
- package/dist/lib/search/file-index.js +2 -1
- package/dist/lib/search/files.js +3 -2
- package/dist/lib/search/knowledge.js +2 -1
- package/dist/lib/search/skills.js +2 -1
- package/dist/lib/search/tasks.js +2 -1
- package/package.json +5 -2
package/dist/lib/search/bm25.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.BM25Index = void 0;
|
|
8
8
|
exports.tokenize = tokenize;
|
|
9
9
|
exports.rrfFuse = rrfFuse;
|
|
10
|
+
const defaults_1 = require("../../lib/defaults");
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
11
12
|
// Tokenizer
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
@@ -56,8 +57,8 @@ class BM25Index {
|
|
|
56
57
|
textExtractor;
|
|
57
58
|
constructor(textExtractor, opts) {
|
|
58
59
|
this.textExtractor = textExtractor;
|
|
59
|
-
this.k1 = opts?.k1 ??
|
|
60
|
-
this.b = opts?.b ??
|
|
60
|
+
this.k1 = opts?.k1 ?? defaults_1.BM25_K1;
|
|
61
|
+
this.b = opts?.b ?? defaults_1.BM25_B;
|
|
61
62
|
}
|
|
62
63
|
get size() {
|
|
63
64
|
return this.docs.size;
|
|
@@ -129,7 +130,7 @@ class BM25Index {
|
|
|
129
130
|
continue;
|
|
130
131
|
const docFreq = this.df.get(term) ?? 0;
|
|
131
132
|
// IDF: log((N - df + 0.5) / (df + 0.5) + 1)
|
|
132
|
-
const idf = Math.log((N - docFreq +
|
|
133
|
+
const idf = Math.log((N - docFreq + defaults_1.BM25_IDF_OFFSET) / (docFreq + defaults_1.BM25_IDF_OFFSET) + 1);
|
|
133
134
|
// TF saturation: (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * dl/avgdl))
|
|
134
135
|
const tfNorm = (tf * (this.k1 + 1)) / (tf + this.k1 * (1 - this.b + this.b * doc.length / avgDl));
|
|
135
136
|
docScore += idf * tfNorm;
|
|
@@ -151,7 +152,7 @@ exports.BM25Index = BM25Index;
|
|
|
151
152
|
*
|
|
152
153
|
* Nodes appearing in only one list get rank = Infinity for the other → only 1/(k+rank) from one source.
|
|
153
154
|
*/
|
|
154
|
-
function rrfFuse(vectorScores, bm25Scores, k =
|
|
155
|
+
function rrfFuse(vectorScores, bm25Scores, k = defaults_1.RRF_K) {
|
|
155
156
|
// Build ranked lists (sorted desc by score, rank starts at 1)
|
|
156
157
|
const vectorRank = buildRankMap(vectorScores);
|
|
157
158
|
const bm25Rank = buildRankMap(bm25Scores);
|
package/dist/lib/search/code.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchCode = searchCode;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
5
|
const bm25_1 = require("../../lib/search/bm25");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
/**
|
|
7
8
|
* Semantic search over the code graph.
|
|
8
9
|
*
|
|
@@ -12,7 +13,7 @@ const bm25_1 = require("../../lib/search/bm25");
|
|
|
12
13
|
* 4. De-duplicate, re-filter, sort, cap at `maxResults`.
|
|
13
14
|
*/
|
|
14
15
|
function searchCode(graph, queryEmbedding, options = {}) {
|
|
15
|
-
const { topK =
|
|
16
|
+
const { topK = defaults_1.SEARCH_TOP_K, bfsDepth = defaults_1.SEARCH_BFS_DEPTH, maxResults = defaults_1.SEARCH_MAX_RESULTS, minScore = defaults_1.SEARCH_MIN_SCORE_CODE, bfsDecay = defaults_1.SEARCH_BFS_DECAY, includeBody = false, queryText, bm25Index, searchMode = 'hybrid', rrfK = defaults_1.RRF_K } = options;
|
|
16
17
|
const useVector = searchMode !== 'keyword';
|
|
17
18
|
const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
|
|
18
19
|
// --- 1. Score all nodes ---
|
package/dist/lib/search/docs.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.search = search;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
5
|
const bm25_1 = require("../../lib/search/bm25");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
/**
|
|
7
8
|
* Semantic search over the graph.
|
|
8
9
|
*
|
|
@@ -15,7 +16,7 @@ const bm25_1 = require("../../lib/search/bm25");
|
|
|
15
16
|
* 5. De-duplicate and return results sorted by score, capped at `maxResults`.
|
|
16
17
|
*/
|
|
17
18
|
function search(graph, queryEmbedding, options = {}) {
|
|
18
|
-
const { topK =
|
|
19
|
+
const { topK = defaults_1.SEARCH_TOP_K, bfsDepth = defaults_1.SEARCH_BFS_DEPTH, maxResults = defaults_1.SEARCH_MAX_RESULTS, minScore = defaults_1.SEARCH_MIN_SCORE, bfsDecay = defaults_1.SEARCH_BFS_DECAY, queryText, bm25Index, searchMode = 'hybrid', rrfK = defaults_1.RRF_K } = options;
|
|
19
20
|
const useVector = searchMode !== 'keyword';
|
|
20
21
|
const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
|
|
21
22
|
// --- 1. Score all nodes ---
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.searchFileIndex = searchFileIndex;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
|
+
const defaults_1 = require("../../lib/defaults");
|
|
5
6
|
/**
|
|
6
7
|
* Semantic search over file nodes by path embedding.
|
|
7
8
|
* Only searches file nodes (directories have empty embeddings).
|
|
8
9
|
* Pure cosine similarity, no BFS expansion.
|
|
9
10
|
*/
|
|
10
11
|
function searchFileIndex(graph, queryEmbedding, options = {}) {
|
|
11
|
-
const { topK =
|
|
12
|
+
const { topK = defaults_1.FILE_SEARCH_TOP_K, minScore = defaults_1.SEARCH_MIN_SCORE_FILES } = options;
|
|
12
13
|
const scored = [];
|
|
13
14
|
graph.forEachNode((_, attrs) => {
|
|
14
15
|
if (attrs.kind !== 'file' || attrs.embedding.length === 0)
|
package/dist/lib/search/files.js
CHANGED
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchDocFiles = searchDocFiles;
|
|
4
4
|
exports.searchCodeFiles = searchCodeFiles;
|
|
5
5
|
const embedder_1 = require("../../lib/embedder");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
function searchDocFiles(graph, queryEmbedding, options = {}) {
|
|
7
|
-
const { topK =
|
|
8
|
+
const { topK = defaults_1.FILE_SEARCH_TOP_K, minScore = defaults_1.SEARCH_MIN_SCORE_FILES } = options;
|
|
8
9
|
// Collect root chunks (level=1) that have a fileEmbedding
|
|
9
10
|
const scored = [];
|
|
10
11
|
graph.forEachNode((_, attrs) => {
|
|
@@ -33,7 +34,7 @@ function searchDocFiles(graph, queryEmbedding, options = {}) {
|
|
|
33
34
|
}));
|
|
34
35
|
}
|
|
35
36
|
function searchCodeFiles(graph, queryEmbedding, options = {}) {
|
|
36
|
-
const { topK =
|
|
37
|
+
const { topK = defaults_1.FILE_SEARCH_TOP_K, minScore = defaults_1.SEARCH_MIN_SCORE_FILES } = options;
|
|
37
38
|
// Collect file nodes that have a fileEmbedding
|
|
38
39
|
const scored = [];
|
|
39
40
|
graph.forEachNode((_, attrs) => {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchKnowledge = searchKnowledge;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
5
|
const bm25_1 = require("../../lib/search/bm25");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
/**
|
|
7
8
|
* Semantic search over the knowledge graph.
|
|
8
9
|
*
|
|
@@ -12,7 +13,7 @@ const bm25_1 = require("../../lib/search/bm25");
|
|
|
12
13
|
* 4. De-duplicate, re-filter, sort, cap at `maxResults`.
|
|
13
14
|
*/
|
|
14
15
|
function searchKnowledge(graph, queryEmbedding, options = {}) {
|
|
15
|
-
const { topK =
|
|
16
|
+
const { topK = defaults_1.SEARCH_TOP_K, bfsDepth = defaults_1.SEARCH_BFS_DEPTH, maxResults = defaults_1.SEARCH_MAX_RESULTS, minScore = defaults_1.SEARCH_MIN_SCORE, bfsDecay = defaults_1.SEARCH_BFS_DECAY, queryText, bm25Index, searchMode = 'hybrid', rrfK = defaults_1.RRF_K } = options;
|
|
16
17
|
const useVector = searchMode !== 'keyword';
|
|
17
18
|
const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
|
|
18
19
|
// --- 1. Score all nodes (skip proxy nodes) ---
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchSkills = searchSkills;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
5
|
const bm25_1 = require("../../lib/search/bm25");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
/**
|
|
7
8
|
* Semantic search over the skill graph.
|
|
8
9
|
*
|
|
@@ -12,7 +13,7 @@ const bm25_1 = require("../../lib/search/bm25");
|
|
|
12
13
|
* 4. De-duplicate, re-filter, sort, cap at `maxResults`.
|
|
13
14
|
*/
|
|
14
15
|
function searchSkills(graph, queryEmbedding, options = {}) {
|
|
15
|
-
const { topK =
|
|
16
|
+
const { topK = defaults_1.SEARCH_TOP_K, bfsDepth = defaults_1.SEARCH_BFS_DEPTH, maxResults = defaults_1.SEARCH_MAX_RESULTS, minScore = defaults_1.SEARCH_MIN_SCORE, bfsDecay = defaults_1.SEARCH_BFS_DECAY, queryText, bm25Index, searchMode = 'hybrid', rrfK = defaults_1.RRF_K } = options;
|
|
16
17
|
const useVector = searchMode !== 'keyword';
|
|
17
18
|
const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
|
|
18
19
|
// --- 1. Score all nodes (skip proxy nodes) ---
|
package/dist/lib/search/tasks.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchTasks = searchTasks;
|
|
4
4
|
const embedder_1 = require("../../lib/embedder");
|
|
5
5
|
const bm25_1 = require("../../lib/search/bm25");
|
|
6
|
+
const defaults_1 = require("../../lib/defaults");
|
|
6
7
|
/**
|
|
7
8
|
* Semantic search over the task graph.
|
|
8
9
|
*
|
|
@@ -12,7 +13,7 @@ const bm25_1 = require("../../lib/search/bm25");
|
|
|
12
13
|
* 4. De-duplicate, re-filter, sort, cap at `maxResults`.
|
|
13
14
|
*/
|
|
14
15
|
function searchTasks(graph, queryEmbedding, options = {}) {
|
|
15
|
-
const { topK =
|
|
16
|
+
const { topK = defaults_1.SEARCH_TOP_K, bfsDepth = defaults_1.SEARCH_BFS_DEPTH, maxResults = defaults_1.SEARCH_MAX_RESULTS, minScore = defaults_1.SEARCH_MIN_SCORE, bfsDecay = defaults_1.SEARCH_BFS_DECAY, queryText, bm25Index, searchMode = 'hybrid', rrfK = defaults_1.RRF_K } = options;
|
|
16
17
|
const useVector = searchMode !== 'keyword';
|
|
17
18
|
const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
|
|
18
19
|
// --- 1. Score all nodes (skip proxy nodes) ---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphmemory/server",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "MCP server for semantic graph memory from markdown files",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"cli": "node dist/cli/index.js",
|
|
16
16
|
"cli:dev": "tsx src/cli/index.ts",
|
|
17
17
|
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
|
|
18
|
-
"test:watch": "NODE_OPTIONS='--experimental-vm-modules' jest --watch"
|
|
18
|
+
"test:watch": "NODE_OPTIONS='--experimental-vm-modules' jest --watch",
|
|
19
|
+
"site:dev": "cd site && npm start",
|
|
20
|
+
"site:build": "cd site && npm run build",
|
|
21
|
+
"site:serve": "cd site && npm run serve"
|
|
19
22
|
},
|
|
20
23
|
"repository": {
|
|
21
24
|
"type": "git",
|