@henrychong-ai/mcp-neo4j-knowledge-graph 2.7.0 → 2.8.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/README.md +86 -0
- package/dist/KnowledgeGraphManager.d.ts +54 -7
- package/dist/KnowledgeGraphManager.js +130 -27
- package/dist/KnowledgeGraphManager.js.map +1 -1
- package/dist/cli/report-oversized.d.ts +20 -0
- package/dist/cli/report-oversized.js +158 -0
- package/dist/cli/report-oversized.js.map +1 -0
- package/dist/config/entitySize.d.ts +44 -0
- package/dist/config/entitySize.js +77 -0
- package/dist/config/entitySize.js.map +1 -0
- package/dist/maintenance/EntitySizeService.d.ts +103 -0
- package/dist/maintenance/EntitySizeService.js +143 -0
- package/dist/maintenance/EntitySizeService.js.map +1 -0
- package/dist/schemas/index.d.ts +11 -3
- package/dist/schemas/index.js +12 -3
- package/dist/schemas/index.js.map +1 -1
- package/dist/server/handlers/callToolHandler.js +22 -1
- package/dist/server/handlers/callToolHandler.js.map +1 -1
- package/dist/server/handlers/listToolsHandler.js +21 -0
- package/dist/server/handlers/listToolsHandler.js.map +1 -1
- package/dist/server/handlers/toolHandlers/addObservationsBatch.js +5 -1
- package/dist/server/handlers/toolHandlers/addObservationsBatch.js.map +1 -1
- package/dist/server/handlers/toolHandlers/createEntitiesBatch.js +5 -1
- package/dist/server/handlers/toolHandlers/createEntitiesBatch.js.map +1 -1
- package/dist/server/handlers/toolHandlers/updateEntitiesBatch.js +5 -1
- package/dist/server/handlers/toolHandlers/updateEntitiesBatch.js.map +1 -1
- package/dist/server/handlers/toolHandlers/writeSizeWarnings.d.ts +45 -0
- package/dist/server/handlers/toolHandlers/writeSizeWarnings.js +106 -0
- package/dist/server/handlers/toolHandlers/writeSizeWarnings.js.map +1 -0
- package/dist/storage/StorageProvider.d.ts +27 -0
- package/dist/storage/StorageProvider.js.map +1 -1
- package/dist/storage/neo4j/Neo4jStorageProvider.d.ts +14 -1
- package/dist/storage/neo4j/Neo4jStorageProvider.js +75 -2
- package/dist/storage/neo4j/Neo4jStorageProvider.js.map +1 -1
- package/example.env +14 -1
- package/package.json +9 -5
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI tool: report knowledge-graph entities that are at risk of exceeding the
|
|
3
|
+
* MCP `open_nodes` output cap, so they can be restructured before they become
|
|
4
|
+
* unretrievable.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npm run kg:oversized # table of WARN/CRITICAL entities
|
|
8
|
+
* npm run kg:oversized -- --include-ok # include OK entities too
|
|
9
|
+
* npm run kg:oversized -- --json # machine-readable JSON
|
|
10
|
+
* npm run kg:oversized -- --limit 100 # scan the 100 largest
|
|
11
|
+
*
|
|
12
|
+
* Exit code is 1 when any CRITICAL entity exists (so a cron/CI job can alert),
|
|
13
|
+
* 0 otherwise. This is the "ongoing basis" mechanism: schedule it on a recurring
|
|
14
|
+
* cron alongside the embedding backfill.
|
|
15
|
+
*
|
|
16
|
+
* Requirements:
|
|
17
|
+
* - Neo4j connection configured (NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD)
|
|
18
|
+
* - No embedding provider needed — sizing is pure Cypher.
|
|
19
|
+
*/
|
|
20
|
+
import dotenv from 'dotenv';
|
|
21
|
+
import { getEntitySizeConfig } from '../config/entitySize.js';
|
|
22
|
+
import { estimateEntitySize, estimateFromCharCount, RESTRUCTURE_HINT, } from '../maintenance/EntitySizeService.js';
|
|
23
|
+
import { Neo4jStorageProvider } from '../storage/neo4j/Neo4jStorageProvider.js';
|
|
24
|
+
dotenv.config();
|
|
25
|
+
function parseArgs() {
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
const options = { includeOk: false, json: false };
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
switch (args[i]) {
|
|
30
|
+
case '--limit': {
|
|
31
|
+
options.limit = Number.parseInt(args[++i], 10);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case '--warn-ratio': {
|
|
35
|
+
options.warnRatio = Number.parseFloat(args[++i]);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case '--include-ok': {
|
|
39
|
+
options.includeOk = true;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case '--json': {
|
|
43
|
+
options.json = true;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case '--help': {
|
|
47
|
+
printHelp();
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return options;
|
|
53
|
+
}
|
|
54
|
+
function printHelp() {
|
|
55
|
+
console.log(`
|
|
56
|
+
Report Oversized Entities CLI
|
|
57
|
+
|
|
58
|
+
Usage:
|
|
59
|
+
npm run kg:oversized [options]
|
|
60
|
+
|
|
61
|
+
Options:
|
|
62
|
+
--limit <n> Scan and rank the N largest entities (default: 50)
|
|
63
|
+
--warn-ratio <r> Fraction of the cap (0.0-1.0) for the WARN threshold (default: 0.8)
|
|
64
|
+
--include-ok Include entities below the warn threshold
|
|
65
|
+
--json Output machine-readable JSON instead of a table
|
|
66
|
+
--help Show this help message
|
|
67
|
+
|
|
68
|
+
Environment Variables:
|
|
69
|
+
MAX_MCP_OUTPUT_TOKENS Assumed open_nodes cap in tokens (default: 25000)
|
|
70
|
+
ENTITY_SIZE_WARN_RATIO WARN threshold ratio (default: 0.8)
|
|
71
|
+
ENTITY_SIZE_CRITICAL_RATIO CRITICAL threshold ratio (default: 1.0)
|
|
72
|
+
ENTITY_SIZE_SCAN_LIMIT Default scan size (default: 50)
|
|
73
|
+
NEO4J_URI / NEO4J_USERNAME / NEO4J_PASSWORD / NEO4J_DATABASE
|
|
74
|
+
|
|
75
|
+
Exit code: 1 if any CRITICAL entity exists, else 0.
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
function pad(value, width) {
|
|
79
|
+
return value.length >= width ? value : value + ' '.repeat(width - value.length);
|
|
80
|
+
}
|
|
81
|
+
function printTable(reports, cap) {
|
|
82
|
+
if (reports.length === 0) {
|
|
83
|
+
console.log('✅ No entities at or near the open_nodes cap.\n');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.log(`\nAssumed open_nodes cap: ~${cap} tokens\n`);
|
|
87
|
+
console.log(`${pad('STATE', 9)}${pad('~TOKENS', 10)}${pad('%CAP', 7)}${pad('OBS', 6)}${pad('TYPE', 18)}NAME`);
|
|
88
|
+
console.log('-'.repeat(90));
|
|
89
|
+
for (const r of reports) {
|
|
90
|
+
const icon = r.state === 'CRITICAL' ? '🔴' : r.state === 'WARN' ? '🟡' : '🟢';
|
|
91
|
+
console.log(`${pad(`${icon} ${r.state}`, 9)}${pad(String(r.estTokens), 10)}${pad(`${Math.round(r.ratio * 100)}%`, 7)}${pad(String(r.obsCount), 6)}${pad((r.entityType || '-').slice(0, 16), 18)}${r.name}`);
|
|
92
|
+
}
|
|
93
|
+
console.log('');
|
|
94
|
+
}
|
|
95
|
+
async function run() {
|
|
96
|
+
const options = parseArgs();
|
|
97
|
+
const cfg = getEntitySizeConfig({
|
|
98
|
+
scanLimit: options.limit,
|
|
99
|
+
warnRatio: options.warnRatio,
|
|
100
|
+
});
|
|
101
|
+
const storageProvider = new Neo4jStorageProvider({
|
|
102
|
+
config: {
|
|
103
|
+
uri: process.env.NEO4J_URI || 'bolt://localhost:7687',
|
|
104
|
+
username: process.env.NEO4J_USERNAME || 'neo4j',
|
|
105
|
+
password: process.env.NEO4J_PASSWORD || '',
|
|
106
|
+
database: process.env.NEO4J_DATABASE || 'neo4j',
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
try {
|
|
110
|
+
const rows = await storageProvider.scanEntitySizes(cfg.scanLimit);
|
|
111
|
+
const names = rows.map(r => r.name);
|
|
112
|
+
const entityByName = new Map();
|
|
113
|
+
if (names.length > 0) {
|
|
114
|
+
const graph = await storageProvider.openNodes(names);
|
|
115
|
+
for (const e of graph.entities) {
|
|
116
|
+
entityByName.set(e.name, e);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
let reports = rows.map(row => {
|
|
120
|
+
const entity = entityByName.get(row.name);
|
|
121
|
+
return entity ? estimateEntitySize(entity, cfg) : estimateFromCharCount(row, cfg);
|
|
122
|
+
});
|
|
123
|
+
reports.sort((a, b) => b.estTokens - a.estTokens);
|
|
124
|
+
if (!options.includeOk) {
|
|
125
|
+
reports = reports.filter(r => r.state !== 'OK');
|
|
126
|
+
}
|
|
127
|
+
const criticalCount = reports.filter(r => r.state === 'CRITICAL').length;
|
|
128
|
+
if (options.json) {
|
|
129
|
+
console.log(JSON.stringify({
|
|
130
|
+
assumedCap: cfg.maxTokens,
|
|
131
|
+
warnRatio: cfg.warnRatio,
|
|
132
|
+
criticalRatio: cfg.criticalRatio,
|
|
133
|
+
scanned: rows.length,
|
|
134
|
+
flaggedCount: reports.filter(r => r.state !== 'OK').length,
|
|
135
|
+
criticalCount,
|
|
136
|
+
entities: reports,
|
|
137
|
+
restructureHint: RESTRUCTURE_HINT,
|
|
138
|
+
}, null, 2));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
printTable(reports, cfg.maxTokens);
|
|
142
|
+
if (criticalCount > 0) {
|
|
143
|
+
console.log(`⚠️ ${criticalCount} CRITICAL entity(ies) — ${RESTRUCTURE_HINT}\n`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return criticalCount > 0 ? 1 : 0;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
await storageProvider.close();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
run()
|
|
153
|
+
.then(code => process.exit(code))
|
|
154
|
+
.catch(error => {
|
|
155
|
+
console.error('❌ report-oversized failed:', error instanceof Error ? error.message : error);
|
|
156
|
+
process.exit(2);
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=report-oversized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-oversized.js","sourceRoot":"","sources":["../../src/cli/report-oversized.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for entity-size flagging.
|
|
3
|
+
*
|
|
4
|
+
* The MCP `open_nodes` response is bounded by the client/harness output cap
|
|
5
|
+
* (default 25,000 tokens). An entity whose own serialized form approaches that
|
|
6
|
+
* cap risks becoming unretrievable via `open_nodes(["Name"])`. These settings
|
|
7
|
+
* drive the early-warning thresholds used by `flag_oversized_entities`, the
|
|
8
|
+
* on-write warnings, and the `report-oversized` CLI.
|
|
9
|
+
*
|
|
10
|
+
* All values are advisory: the estimate is a conservative chars-per-token
|
|
11
|
+
* heuristic (see EntitySizeService), not a reproduction of the harness tokenizer.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Resolved entity-size configuration (frozen).
|
|
15
|
+
*/
|
|
16
|
+
export interface EntitySizeConfig {
|
|
17
|
+
/** Assumed MCP output cap in tokens (MAX_MCP_OUTPUT_TOKENS). */
|
|
18
|
+
maxTokens: number;
|
|
19
|
+
/** Ratio of the cap at/above which an entity is flagged WARN (0-1). */
|
|
20
|
+
warnRatio: number;
|
|
21
|
+
/** Ratio of the cap at/above which an entity is flagged CRITICAL (>= warnRatio). */
|
|
22
|
+
criticalRatio: number;
|
|
23
|
+
/** When true, write tools append non-fatal size warnings for touched entities. */
|
|
24
|
+
warnOnWrite: boolean;
|
|
25
|
+
/** Number of largest entities to scan/rank per pass. */
|
|
26
|
+
scanLimit: number;
|
|
27
|
+
}
|
|
28
|
+
/** Per-call overrides accepted by tools/CLI (all optional). */
|
|
29
|
+
export interface EntitySizeConfigOverrides {
|
|
30
|
+
maxTokens?: number;
|
|
31
|
+
warnRatio?: number;
|
|
32
|
+
criticalRatio?: number;
|
|
33
|
+
warnOnWrite?: boolean;
|
|
34
|
+
scanLimit?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the entity-size configuration from environment variables, applying
|
|
38
|
+
* optional per-call overrides on top. Values are validated and clamped so a bad
|
|
39
|
+
* input never produces nonsensical thresholds.
|
|
40
|
+
*
|
|
41
|
+
* @param overrides Optional per-call overrides (e.g. tool arguments)
|
|
42
|
+
* @returns A frozen, validated EntitySizeConfig
|
|
43
|
+
*/
|
|
44
|
+
export declare function getEntitySizeConfig(overrides?: EntitySizeConfigOverrides): EntitySizeConfig;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for entity-size flagging.
|
|
3
|
+
*
|
|
4
|
+
* The MCP `open_nodes` response is bounded by the client/harness output cap
|
|
5
|
+
* (default 25,000 tokens). An entity whose own serialized form approaches that
|
|
6
|
+
* cap risks becoming unretrievable via `open_nodes(["Name"])`. These settings
|
|
7
|
+
* drive the early-warning thresholds used by `flag_oversized_entities`, the
|
|
8
|
+
* on-write warnings, and the `report-oversized` CLI.
|
|
9
|
+
*
|
|
10
|
+
* All values are advisory: the estimate is a conservative chars-per-token
|
|
11
|
+
* heuristic (see EntitySizeService), not a reproduction of the harness tokenizer.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULTS = {
|
|
14
|
+
maxTokens: 25_000,
|
|
15
|
+
warnRatio: 0.8,
|
|
16
|
+
criticalRatio: 1.0,
|
|
17
|
+
warnOnWrite: true,
|
|
18
|
+
scanLimit: 50,
|
|
19
|
+
};
|
|
20
|
+
function intEnv(name, fallback) {
|
|
21
|
+
const raw = process.env[name];
|
|
22
|
+
if (raw === undefined || raw === '') {
|
|
23
|
+
return fallback;
|
|
24
|
+
}
|
|
25
|
+
const parsed = Number.parseInt(raw, 10);
|
|
26
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
27
|
+
}
|
|
28
|
+
function floatEnv(name, fallback) {
|
|
29
|
+
const raw = process.env[name];
|
|
30
|
+
if (raw === undefined || raw === '') {
|
|
31
|
+
return fallback;
|
|
32
|
+
}
|
|
33
|
+
const parsed = Number.parseFloat(raw);
|
|
34
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
35
|
+
}
|
|
36
|
+
function boolEnv(name, fallback) {
|
|
37
|
+
const raw = process.env[name];
|
|
38
|
+
if (raw === undefined || raw === '') {
|
|
39
|
+
return fallback;
|
|
40
|
+
}
|
|
41
|
+
return raw.toLowerCase() === 'true' || raw === '1';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the entity-size configuration from environment variables, applying
|
|
45
|
+
* optional per-call overrides on top. Values are validated and clamped so a bad
|
|
46
|
+
* input never produces nonsensical thresholds.
|
|
47
|
+
*
|
|
48
|
+
* @param overrides Optional per-call overrides (e.g. tool arguments)
|
|
49
|
+
* @returns A frozen, validated EntitySizeConfig
|
|
50
|
+
*/
|
|
51
|
+
export function getEntitySizeConfig(overrides) {
|
|
52
|
+
const maxTokens = overrides?.maxTokens ?? intEnv('MAX_MCP_OUTPUT_TOKENS', DEFAULTS.maxTokens);
|
|
53
|
+
let warnRatio = overrides?.warnRatio ?? floatEnv('ENTITY_SIZE_WARN_RATIO', DEFAULTS.warnRatio);
|
|
54
|
+
let criticalRatio = overrides?.criticalRatio ?? floatEnv('ENTITY_SIZE_CRITICAL_RATIO', DEFAULTS.criticalRatio);
|
|
55
|
+
const warnOnWrite = overrides?.warnOnWrite ?? boolEnv('ENTITY_SIZE_WARN_ON_WRITE', DEFAULTS.warnOnWrite);
|
|
56
|
+
const scanLimit = overrides?.scanLimit ?? intEnv('ENTITY_SIZE_SCAN_LIMIT', DEFAULTS.scanLimit);
|
|
57
|
+
// Clamp ratios into a sane range and keep critical >= warn.
|
|
58
|
+
warnRatio = Math.min(Math.max(warnRatio, 0.01), 2);
|
|
59
|
+
criticalRatio = Math.min(Math.max(criticalRatio, 0.01), 4);
|
|
60
|
+
if (criticalRatio < warnRatio) {
|
|
61
|
+
criticalRatio = warnRatio;
|
|
62
|
+
}
|
|
63
|
+
// Upper-clamp scanLimit: it bounds both how many entities the refine step
|
|
64
|
+
// hydrates AND how many size rows the tool returns. Too large a value would
|
|
65
|
+
// let flag_oversized_entities' own response approach the very cap it polices
|
|
66
|
+
// (especially with include_ok). SCAN_LIMIT_MAX rows stay well under it.
|
|
67
|
+
const SCAN_LIMIT_MAX = 200;
|
|
68
|
+
const boundedScanLimit = scanLimit > 0 ? Math.min(scanLimit, SCAN_LIMIT_MAX) : DEFAULTS.scanLimit;
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
maxTokens: maxTokens > 0 ? maxTokens : DEFAULTS.maxTokens,
|
|
71
|
+
warnRatio,
|
|
72
|
+
criticalRatio,
|
|
73
|
+
warnOnWrite,
|
|
74
|
+
scanLimit: boundedScanLimit,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=entitySize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entitySize.js","sourceRoot":"","sources":["../../src/config/entitySize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EntitySizeService — the single primitive for estimating how much of the MCP
|
|
3
|
+
* `open_nodes` output cap a knowledge-graph entity consumes.
|
|
4
|
+
*
|
|
5
|
+
* The cap (default MAX_MCP_OUTPUT_TOKENS = 25,000) is enforced by the MCP
|
|
6
|
+
* client/harness on the serialized tool RESPONSE, not by the server. An entity
|
|
7
|
+
* whose own serialized form approaches the cap risks becoming unretrievable via
|
|
8
|
+
* `open_nodes(["Name"])`, because that call fails closed above the cap.
|
|
9
|
+
*
|
|
10
|
+
* The estimate is deliberately dependency-free and conservative: it counts the
|
|
11
|
+
* characters of the entity as `open_nodes` serializes it (JSON, 2-space
|
|
12
|
+
* indented) and approximates tokens at chars / 4. Combined with a sub-1.0 warn
|
|
13
|
+
* ratio, this gives margin against the harness's real (unseen) tokenizer rather
|
|
14
|
+
* than false precision.
|
|
15
|
+
*/
|
|
16
|
+
import type { EntitySizeConfig } from '../config/entitySize.js';
|
|
17
|
+
/** Three-state classification for an entity's size relative to the cap. */
|
|
18
|
+
export type EntitySizeState = 'OK' | 'WARN' | 'CRITICAL';
|
|
19
|
+
/** Minimal entity shape needed to estimate size (matches what open_nodes returns). */
|
|
20
|
+
export interface SizeableEntity {
|
|
21
|
+
name: string;
|
|
22
|
+
entityType?: string;
|
|
23
|
+
domain?: string | null;
|
|
24
|
+
observations?: string[];
|
|
25
|
+
}
|
|
26
|
+
/** Per-entity size report. */
|
|
27
|
+
export interface EntitySizeReport {
|
|
28
|
+
name: string;
|
|
29
|
+
entityType: string;
|
|
30
|
+
/** Characters of the entity as open_nodes serializes it (incl. wrapper overhead). */
|
|
31
|
+
charCount: number;
|
|
32
|
+
/** Estimated tokens (charCount / 4, rounded up). */
|
|
33
|
+
estTokens: number;
|
|
34
|
+
/** estTokens / cap. */
|
|
35
|
+
ratio: number;
|
|
36
|
+
state: EntitySizeState;
|
|
37
|
+
obsCount: number;
|
|
38
|
+
/** Size in characters of the single largest observation (the first thing to peel off). */
|
|
39
|
+
largestObservationChars: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Average characters per token. Dense technical / JSON content — paths, IPs,
|
|
43
|
+
* hex, code, plus the heavy punctuation and 2-space indentation of an
|
|
44
|
+
* `open_nodes` response — tokenizes at FEWER chars per token (more tokens per
|
|
45
|
+
* char) than the ~4 chars/token prose rule. Using too large a divisor
|
|
46
|
+
* UNDER-estimates tokens, which is the unsafe direction for an early warning.
|
|
47
|
+
*
|
|
48
|
+
* Calibration anchor: the documented `sgo-mac-studio` failure was ~73k
|
|
49
|
+
* serialized chars and EXCEEDED the 25,000-token cap (it failed `open_nodes`
|
|
50
|
+
* closed) ⇒ real density was < 2.93 chars/token for this KG's content. We pick
|
|
51
|
+
* 2.8 so that incident lands CRITICAL with margin (≈ WARN at ~56k chars,
|
|
52
|
+
* CRITICAL at ~70k chars), deliberately erring toward over-estimating tokens:
|
|
53
|
+
* a false WARN is cheap (you look and decide not to split) while a false OK is
|
|
54
|
+
* the missed-unretrievability catastrophe the feature exists to prevent.
|
|
55
|
+
* Exported so tests assert behaviour relative to it rather than a magic number.
|
|
56
|
+
*/
|
|
57
|
+
export declare const CHARS_PER_TOKEN = 2.8;
|
|
58
|
+
/** Convert a character count to an estimated token count. */
|
|
59
|
+
export declare function estimateTokensFromChars(charCount: number): number;
|
|
60
|
+
/** Classify a token estimate against the configured thresholds. */
|
|
61
|
+
export declare function classifySize(estTokens: number, cfg: EntitySizeConfig): EntitySizeState;
|
|
62
|
+
/**
|
|
63
|
+
* Character length of a single entity as `open_nodes` ACTUALLY serializes it:
|
|
64
|
+
* the entity nested inside the `{ entities: [ … ], relations: [], total, timeTaken }`
|
|
65
|
+
* response envelope, 2-space indented. Nesting matters — each observation sits
|
|
66
|
+
* at 8-space indentation in the real response (array-in-entity-in-array), which
|
|
67
|
+
* a top-level slice would undercount by ~4 chars per observation.
|
|
68
|
+
*
|
|
69
|
+
* open_nodes' nodeToEntity does NOT include the embedding vector, but it DOES
|
|
70
|
+
* include the temporal/identity fields (id, version, timestamps, changedBy);
|
|
71
|
+
* representative placeholder values are included so the char count matches a
|
|
72
|
+
* real response without needing the live values. A single-name open_nodes
|
|
73
|
+
* attaches only self-loop relations, so relations are omitted (empty), making
|
|
74
|
+
* this the per-entity retrievability cost. Observations dominate.
|
|
75
|
+
*/
|
|
76
|
+
export declare function serializedEntityChars(entity: SizeableEntity): number;
|
|
77
|
+
/**
|
|
78
|
+
* Build a precise size report for a single entity.
|
|
79
|
+
*
|
|
80
|
+
* @param entity The entity (as open_nodes would return it)
|
|
81
|
+
* @param cfg Resolved entity-size configuration
|
|
82
|
+
* @returns The entity's size report
|
|
83
|
+
*/
|
|
84
|
+
export declare function estimateEntitySize(entity: SizeableEntity, cfg: EntitySizeConfig): EntitySizeReport;
|
|
85
|
+
/**
|
|
86
|
+
* Build an approximate size report from a raw character count (the storage-layer
|
|
87
|
+
* scan path, where full observation text was deliberately not materialized).
|
|
88
|
+
*
|
|
89
|
+
* @param row Compact ranking row from the storage scan
|
|
90
|
+
* @param cfg Resolved entity-size configuration
|
|
91
|
+
* @returns An approximate size report (precise fields refined elsewhere)
|
|
92
|
+
*/
|
|
93
|
+
export declare function estimateFromCharCount(row: {
|
|
94
|
+
name: string;
|
|
95
|
+
entityType?: string;
|
|
96
|
+
approxChars: number;
|
|
97
|
+
obsCount?: number;
|
|
98
|
+
}, cfg: EntitySizeConfig): EntitySizeReport;
|
|
99
|
+
/**
|
|
100
|
+
* Human-readable guidance for restructuring an oversized entity, included in
|
|
101
|
+
* tool/CLI output. Restructuring stays a manual/agent judgement call.
|
|
102
|
+
*/
|
|
103
|
+
export declare const RESTRUCTURE_HINT: string;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EntitySizeService — the single primitive for estimating how much of the MCP
|
|
3
|
+
* `open_nodes` output cap a knowledge-graph entity consumes.
|
|
4
|
+
*
|
|
5
|
+
* The cap (default MAX_MCP_OUTPUT_TOKENS = 25,000) is enforced by the MCP
|
|
6
|
+
* client/harness on the serialized tool RESPONSE, not by the server. An entity
|
|
7
|
+
* whose own serialized form approaches the cap risks becoming unretrievable via
|
|
8
|
+
* `open_nodes(["Name"])`, because that call fails closed above the cap.
|
|
9
|
+
*
|
|
10
|
+
* The estimate is deliberately dependency-free and conservative: it counts the
|
|
11
|
+
* characters of the entity as `open_nodes` serializes it (JSON, 2-space
|
|
12
|
+
* indented) and approximates tokens at chars / 4. Combined with a sub-1.0 warn
|
|
13
|
+
* ratio, this gives margin against the harness's real (unseen) tokenizer rather
|
|
14
|
+
* than false precision.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Average characters per token. Dense technical / JSON content — paths, IPs,
|
|
18
|
+
* hex, code, plus the heavy punctuation and 2-space indentation of an
|
|
19
|
+
* `open_nodes` response — tokenizes at FEWER chars per token (more tokens per
|
|
20
|
+
* char) than the ~4 chars/token prose rule. Using too large a divisor
|
|
21
|
+
* UNDER-estimates tokens, which is the unsafe direction for an early warning.
|
|
22
|
+
*
|
|
23
|
+
* Calibration anchor: the documented `sgo-mac-studio` failure was ~73k
|
|
24
|
+
* serialized chars and EXCEEDED the 25,000-token cap (it failed `open_nodes`
|
|
25
|
+
* closed) ⇒ real density was < 2.93 chars/token for this KG's content. We pick
|
|
26
|
+
* 2.8 so that incident lands CRITICAL with margin (≈ WARN at ~56k chars,
|
|
27
|
+
* CRITICAL at ~70k chars), deliberately erring toward over-estimating tokens:
|
|
28
|
+
* a false WARN is cheap (you look and decide not to split) while a false OK is
|
|
29
|
+
* the missed-unretrievability catastrophe the feature exists to prevent.
|
|
30
|
+
* Exported so tests assert behaviour relative to it rather than a magic number.
|
|
31
|
+
*/
|
|
32
|
+
export const CHARS_PER_TOKEN = 2.8;
|
|
33
|
+
/**
|
|
34
|
+
* Fixed envelope overhead (chars) added to the storage-scan APPROXIMATE path,
|
|
35
|
+
* which has only the observation-char total — not the full serialized entity.
|
|
36
|
+
* Covers the `{ entities: [ { name, type, domain, temporal fields… } ], ... }`
|
|
37
|
+
* structure around the observations. The precise path serializes the real
|
|
38
|
+
* shape directly (see serializedEntityChars) and does not use this.
|
|
39
|
+
*/
|
|
40
|
+
const APPROX_ENVELOPE_CHARS = 320;
|
|
41
|
+
/** Convert a character count to an estimated token count. */
|
|
42
|
+
export function estimateTokensFromChars(charCount) {
|
|
43
|
+
return Math.ceil(Math.max(charCount, 0) / CHARS_PER_TOKEN);
|
|
44
|
+
}
|
|
45
|
+
/** Classify a token estimate against the configured thresholds. */
|
|
46
|
+
export function classifySize(estTokens, cfg) {
|
|
47
|
+
const ratio = estTokens / cfg.maxTokens;
|
|
48
|
+
if (ratio >= cfg.criticalRatio) {
|
|
49
|
+
return 'CRITICAL';
|
|
50
|
+
}
|
|
51
|
+
if (ratio >= cfg.warnRatio) {
|
|
52
|
+
return 'WARN';
|
|
53
|
+
}
|
|
54
|
+
return 'OK';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Character length of a single entity as `open_nodes` ACTUALLY serializes it:
|
|
58
|
+
* the entity nested inside the `{ entities: [ … ], relations: [], total, timeTaken }`
|
|
59
|
+
* response envelope, 2-space indented. Nesting matters — each observation sits
|
|
60
|
+
* at 8-space indentation in the real response (array-in-entity-in-array), which
|
|
61
|
+
* a top-level slice would undercount by ~4 chars per observation.
|
|
62
|
+
*
|
|
63
|
+
* open_nodes' nodeToEntity does NOT include the embedding vector, but it DOES
|
|
64
|
+
* include the temporal/identity fields (id, version, timestamps, changedBy);
|
|
65
|
+
* representative placeholder values are included so the char count matches a
|
|
66
|
+
* real response without needing the live values. A single-name open_nodes
|
|
67
|
+
* attaches only self-loop relations, so relations are omitted (empty), making
|
|
68
|
+
* this the per-entity retrievability cost. Observations dominate.
|
|
69
|
+
*/
|
|
70
|
+
export function serializedEntityChars(entity) {
|
|
71
|
+
const slice = {
|
|
72
|
+
name: entity.name,
|
|
73
|
+
entityType: entity.entityType ?? '',
|
|
74
|
+
domain: entity.domain ?? null,
|
|
75
|
+
observations: entity.observations ?? [],
|
|
76
|
+
// Representative placeholders for the temporal/identity fields nodeToEntity
|
|
77
|
+
// returns — present so indentation + field overhead match a real response.
|
|
78
|
+
id: '00000000-0000-0000-0000-000000000000',
|
|
79
|
+
version: 1,
|
|
80
|
+
createdAt: 1700000000000,
|
|
81
|
+
updatedAt: 1700000000000,
|
|
82
|
+
validFrom: 1700000000000,
|
|
83
|
+
validTo: null,
|
|
84
|
+
changedBy: null,
|
|
85
|
+
};
|
|
86
|
+
const response = { entities: [slice], relations: [], total: 1, timeTaken: 0 };
|
|
87
|
+
return JSON.stringify(response, null, 2).length;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build a precise size report for a single entity.
|
|
91
|
+
*
|
|
92
|
+
* @param entity The entity (as open_nodes would return it)
|
|
93
|
+
* @param cfg Resolved entity-size configuration
|
|
94
|
+
* @returns The entity's size report
|
|
95
|
+
*/
|
|
96
|
+
export function estimateEntitySize(entity, cfg) {
|
|
97
|
+
const observations = entity.observations ?? [];
|
|
98
|
+
const charCount = serializedEntityChars(entity);
|
|
99
|
+
const estTokens = estimateTokensFromChars(charCount);
|
|
100
|
+
const largestObservationChars = observations.reduce((max, obs) => Math.max(max, (obs ?? '').length), 0);
|
|
101
|
+
return {
|
|
102
|
+
name: entity.name,
|
|
103
|
+
entityType: entity.entityType ?? '',
|
|
104
|
+
charCount,
|
|
105
|
+
estTokens,
|
|
106
|
+
ratio: estTokens / cfg.maxTokens,
|
|
107
|
+
state: classifySize(estTokens, cfg),
|
|
108
|
+
obsCount: observations.length,
|
|
109
|
+
largestObservationChars,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Build an approximate size report from a raw character count (the storage-layer
|
|
114
|
+
* scan path, where full observation text was deliberately not materialized).
|
|
115
|
+
*
|
|
116
|
+
* @param row Compact ranking row from the storage scan
|
|
117
|
+
* @param cfg Resolved entity-size configuration
|
|
118
|
+
* @returns An approximate size report (precise fields refined elsewhere)
|
|
119
|
+
*/
|
|
120
|
+
export function estimateFromCharCount(row, cfg) {
|
|
121
|
+
const charCount = Math.max(row.approxChars, 0) + APPROX_ENVELOPE_CHARS;
|
|
122
|
+
const estTokens = estimateTokensFromChars(charCount);
|
|
123
|
+
return {
|
|
124
|
+
name: row.name,
|
|
125
|
+
entityType: row.entityType ?? '',
|
|
126
|
+
charCount,
|
|
127
|
+
estTokens,
|
|
128
|
+
ratio: estTokens / cfg.maxTokens,
|
|
129
|
+
state: classifySize(estTokens, cfg),
|
|
130
|
+
obsCount: row.obsCount ?? 0,
|
|
131
|
+
largestObservationChars: 0,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Human-readable guidance for restructuring an oversized entity, included in
|
|
136
|
+
* tool/CLI output. Restructuring stays a manual/agent judgement call.
|
|
137
|
+
*/
|
|
138
|
+
export const RESTRUCTURE_HINT = 'Split oversized entities into themed sibling entities linked by relations: ' +
|
|
139
|
+
'group related observations under new, more specific entity names, then connect ' +
|
|
140
|
+
'them with create_relations (e.g. part-of / relates-to). Dedup with open_nodes ' +
|
|
141
|
+
'before creating. CRITICAL entities already exceed the cap and cannot be fetched ' +
|
|
142
|
+
'whole via open_nodes — split them first.';
|
|
143
|
+
//# sourceMappingURL=EntitySizeService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntitySizeService.js","sourceRoot":"","sources":["../../src/maintenance/EntitySizeService.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -97,12 +97,20 @@ export declare const SearchNodesInputSchema: z.ZodObject<{
|
|
|
97
97
|
}, z.core.$strip>;
|
|
98
98
|
export type SearchNodesInput = z.infer<typeof SearchNodesInputSchema>;
|
|
99
99
|
/**
|
|
100
|
-
* Schema for semantic_search tool input
|
|
100
|
+
* Schema for semantic_search tool input.
|
|
101
|
+
*
|
|
102
|
+
* v2.7.1: aligned with the reranker-aware default semantics — `limit` and
|
|
103
|
+
* `minSimilarity` carry NO schema defaults so an absent value stays undefined
|
|
104
|
+
* through the handler and the manager resolves it reranker-aware (limit:
|
|
105
|
+
* 10 plain / RERANK_TOP_K reranked; minSimilarity: 0). A schema `.default()`
|
|
106
|
+
* here would silently resurrect pre-2.7.0 behaviour if this schema is ever
|
|
107
|
+
* wired into the handler path. `limit` accepts 0 (explicit empty result) and
|
|
108
|
+
* non-negative values; the manager floors/clamps at runtime.
|
|
101
109
|
*/
|
|
102
110
|
export declare const SemanticSearchInputSchema: z.ZodObject<{
|
|
103
111
|
query: z.ZodString;
|
|
104
|
-
limit: z.
|
|
105
|
-
minSimilarity: z.
|
|
112
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
113
|
+
minSimilarity: z.ZodOptional<z.ZodNumber>;
|
|
106
114
|
domain: z.ZodOptional<z.ZodString>;
|
|
107
115
|
}, z.core.$strip>;
|
|
108
116
|
export type SemanticSearchInput = z.infer<typeof SemanticSearchInputSchema>;
|
package/dist/schemas/index.js
CHANGED
|
@@ -91,12 +91,21 @@ export const SearchNodesInputSchema = z.object({
|
|
|
91
91
|
domain: z.string().optional(),
|
|
92
92
|
});
|
|
93
93
|
/**
|
|
94
|
-
* Schema for semantic_search tool input
|
|
94
|
+
* Schema for semantic_search tool input.
|
|
95
|
+
*
|
|
96
|
+
* v2.7.1: aligned with the reranker-aware default semantics — `limit` and
|
|
97
|
+
* `minSimilarity` carry NO schema defaults so an absent value stays undefined
|
|
98
|
+
* through the handler and the manager resolves it reranker-aware (limit:
|
|
99
|
+
* 10 plain / RERANK_TOP_K reranked; minSimilarity: 0). A schema `.default()`
|
|
100
|
+
* here would silently resurrect pre-2.7.0 behaviour if this schema is ever
|
|
101
|
+
* wired into the handler path. `limit` accepts 0 (explicit empty result) and
|
|
102
|
+
* non-negative values; the manager floors/clamps at runtime.
|
|
95
103
|
*/
|
|
96
104
|
export const SemanticSearchInputSchema = z.object({
|
|
97
105
|
query: z.string().min(1, 'Search query is required'),
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
// No max: the live tool contract honours any explicit limit exactly.
|
|
107
|
+
limit: z.number().min(0).optional(),
|
|
108
|
+
minSimilarity: z.number().min(0).max(1).optional(),
|
|
100
109
|
domain: z.string().optional(),
|
|
101
110
|
});
|
|
102
111
|
// =============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"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"}
|