aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-neural-vfs.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-07-09 06:00:32 +0200
committerAgando <roduccomm@gmail.com>2026-07-09 06:00:32 +0200
commit2538c91876455fe96febf441fc8dde20f2606023 (patch)
treeb74c949cdf4296d10103dd57ef8178ba427a5b39 /modules/core/module-neural-vfs.js
parentea4d09fb5ccba12ed774fcf7c913edfa1e6a851a (diff)
auto: 2026-07-09_06:00 changes
Diffstat (limited to 'modules/core/module-neural-vfs.js')
-rw-r--r--modules/core/module-neural-vfs.js58
1 files changed, 57 insertions, 1 deletions
diff --git a/modules/core/module-neural-vfs.js b/modules/core/module-neural-vfs.js
index 32fb0eb..1019299 100644
--- a/modules/core/module-neural-vfs.js
+++ b/modules/core/module-neural-vfs.js
@@ -33,7 +33,7 @@ class NeuralVFSModule {
this._loadAliases();
// Deep Indexing toggle
this._deepIndexEnabled = localStorage.getItem('webx11_nvfs_deep') === 'true';
- this._deepModel = localStorage.getItem('webx11_nvfs_deep_model') || 'ministral-3:3b-cloud';
+ this._deepModel = localStorage.getItem('webx11_nvfs_deep_model') || 'gemma4:31b-cloud';
this._deepIndexing = false;
this._deepQueue = [];
this._deepProcessed = 0;
@@ -80,6 +80,7 @@ class NeuralVFSModule {
this.commands['nvfs-sync'] = async (args) => this.nvfsSync(args);
this.commands['nvfs-save'] = async (args) => this.nvfsSave();
this.commands['nvfs-cancel'] = (args) => this.cancelIndex();
+ this.commands['nvfs-index-graph'] = () => this.indexGraphFacts();
}
// ── Core Index Builder (async, chunked) ──
@@ -1044,6 +1045,61 @@ Concepts:`;
}
}
}
+
+ // v4.5.89: Semantic bridge — mirror graph facts into VFS for unified search
+ indexGraphFacts() {
+ const mg = this.terminal.moduleManager.modules['MemoryGraphModule'];
+ if (!mg) return this.terminal.print('❌ Memory Graph module not loaded', 'error');
+ const fs = this.terminal.fs;
+ if (!fs) return this.terminal.print('❌ VFS not available', 'error');
+
+ const factNodes = Object.values(mg._nodes).filter(function(n) {
+ return n.type === 'concept' || n.type === 'fact' || n.type === 'entity' || n.type === 'task';
+ });
+
+ if (factNodes.length === 0) {
+ return this.terminal.print('No graph fact nodes to index. Use memgraph-learn first.', 'info');
+ }
+
+ if (!fs.readDir('/_graph_facts')) fs.mkdir('_graph_facts');
+
+ // v4.5.89b fix: Clean stale files for deleted nodes (P2 from review)
+ const validKeys = new Set(factNodes.map(function(n) { return n.id.replace(/[^a-zA-Z0-9_-]/g, '_') + '.txt'; }));
+ try {
+ const existing = fs.readDir('/_graph_facts') || [];
+ for (const f of existing) {
+ if (!validKeys.has(f)) fs.deleteFile('/_graph_facts/' + f);
+ }
+ } catch (_) {}
+
+ let indexed = 0;
+ for (const node of factNodes) {
+ let content = node.label + '\n';
+ if (node.metadata) {
+ if (node.metadata.full) content += node.metadata.full + '\n';
+ if (node.metadata.result) content += 'Result: ' + node.metadata.result + '\n';
+ }
+ content += 'Type: ' + node.type + '\n';
+ content += 'Namespace: ' + (node.namespace || 'global') + '\n';
+ if (node.source_session) content += 'Session: ' + node.source_session + '\n';
+ const safeName = node.id.replace(/[^a-zA-Z0-9_-]/g, '_');
+ fs.writeFile('/_graph_facts/' + safeName + '.txt', content);
+ indexed++;
+ }
+
+ this.terminal.print('🔗 Indexed ' + indexed + ' graph facts into /_graph_facts/', 'success');
+ this.terminal.print(' Run nvfs-index to include them in semantic search', 'info');
+ }
+
+ // v4.5.89b: Index a single fact — O(1) instead of O(n) re-index (P2 from review)
+ indexSingleFact(factKey, entity, fact) {
+ const fs = this.terminal.fs;
+ if (!fs) return;
+ if (!fs.readDir('/_graph_facts')) fs.mkdir('_graph_facts');
+ const safeName = factKey.replace(/[^a-zA-Z0-9_-]/g, '_');
+ const content = entity + '\n' + fact + '\nType: fact\nNamespace: global\n';
+ fs.writeFile('/_graph_facts/' + safeName + '.txt', content);
+ }
}
// Required for module system