@openweave/weave-graph 0.2.0 → 0.2.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/cjs/compression.d.ts +94 -0
- package/dist/cjs/compression.d.ts.map +1 -0
- package/dist/cjs/compression.js +215 -0
- package/dist/cjs/compression.js.map +1 -0
- package/dist/cjs/edge.d.ts +43 -0
- package/dist/cjs/edge.d.ts.map +1 -0
- package/dist/cjs/edge.js +83 -0
- package/dist/cjs/edge.js.map +1 -0
- package/dist/cjs/hebbian-weights.d.ts +100 -0
- package/dist/cjs/hebbian-weights.d.ts.map +1 -0
- package/dist/cjs/hebbian-weights.js +152 -0
- package/dist/cjs/hebbian-weights.js.map +1 -0
- package/dist/cjs/index.d.ts +193 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +417 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/node.d.ts +43 -0
- package/dist/cjs/node.d.ts.map +1 -0
- package/dist/cjs/node.js +83 -0
- package/dist/cjs/node.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/persistence.d.ts +86 -0
- package/dist/cjs/persistence.d.ts.map +1 -0
- package/dist/cjs/persistence.js +215 -0
- package/dist/cjs/persistence.js.map +1 -0
- package/dist/cjs/synaptic-engine.d.ts +126 -0
- package/dist/cjs/synaptic-engine.d.ts.map +1 -0
- package/dist/cjs/synaptic-engine.js +243 -0
- package/dist/cjs/synaptic-engine.js.map +1 -0
- package/dist/cjs/types.d.ts +74 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +30 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/hebbian-weights.d.ts +100 -0
- package/dist/hebbian-weights.d.ts.map +1 -0
- package/dist/hebbian-weights.js +148 -0
- package/dist/hebbian-weights.js.map +1 -0
- package/dist/index.d.ts +36 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -3
- package/dist/index.js.map +1 -1
- package/dist/persistence.d.ts +43 -15
- package/dist/persistence.d.ts.map +1 -1
- package/dist/persistence.js +109 -119
- package/dist/persistence.js.map +1 -1
- package/dist/synaptic-engine.d.ts +126 -0
- package/dist/synaptic-engine.d.ts.map +1 -0
- package/dist/synaptic-engine.js +236 -0
- package/dist/synaptic-engine.js.map +1 -0
- package/package.json +6 -4
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PersistenceManager = void 0;
|
|
37
|
+
const weave_provider_1 = require("@openweave/weave-provider");
|
|
38
|
+
const index_1 = require("./index");
|
|
39
|
+
/**
|
|
40
|
+
* PersistenceManager
|
|
41
|
+
*
|
|
42
|
+
* Handles saving and loading graph snapshots through a pluggable
|
|
43
|
+
* IWeaveProvider. If no provider is injected, it falls back to the
|
|
44
|
+
* built-in JsonProvider (same behaviour as before, backward-compatible).
|
|
45
|
+
*
|
|
46
|
+
* Key convention: `graph:<chatId>` — namespaced so multiple subsystems can
|
|
47
|
+
* share a single provider without key collisions.
|
|
48
|
+
*/
|
|
49
|
+
class PersistenceManager {
|
|
50
|
+
/** Kept for backward-compat (`getDataDir` / `setDataDir` / constructor). */
|
|
51
|
+
dataDir;
|
|
52
|
+
provider;
|
|
53
|
+
/**
|
|
54
|
+
* @param dataDir Root directory used by the default JsonProvider.
|
|
55
|
+
* Ignored when an explicit `provider` is supplied.
|
|
56
|
+
* @param provider Optional storage provider. Defaults to `JsonProvider(dataDir)`.
|
|
57
|
+
*/
|
|
58
|
+
constructor(dataDir = "./weave-data", provider) {
|
|
59
|
+
this.dataDir = dataDir;
|
|
60
|
+
this.provider = provider ?? new weave_provider_1.JsonProvider(dataDir);
|
|
61
|
+
}
|
|
62
|
+
// ── Key helpers ───────────────────────────────────────────────────────────
|
|
63
|
+
graphKey(chatId) {
|
|
64
|
+
return `graph:${chatId}`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Serialize a GraphSnapshot to a plain object (dates → ISO strings).
|
|
68
|
+
*/
|
|
69
|
+
serialize(snapshot) {
|
|
70
|
+
return {
|
|
71
|
+
...snapshot,
|
|
72
|
+
metadata: {
|
|
73
|
+
...snapshot.metadata,
|
|
74
|
+
createdAt: snapshot.metadata.createdAt.toISOString(),
|
|
75
|
+
updatedAt: snapshot.metadata.updatedAt.toISOString(),
|
|
76
|
+
},
|
|
77
|
+
nodes: Object.fromEntries(Object.entries(snapshot.nodes).map(([id, node]) => [
|
|
78
|
+
id,
|
|
79
|
+
{
|
|
80
|
+
...node,
|
|
81
|
+
createdAt: node.createdAt.toISOString(),
|
|
82
|
+
updatedAt: node.updatedAt.toISOString(),
|
|
83
|
+
},
|
|
84
|
+
])),
|
|
85
|
+
edges: Object.fromEntries(Object.entries(snapshot.edges).map(([id, edge]) => [
|
|
86
|
+
id,
|
|
87
|
+
{
|
|
88
|
+
...edge,
|
|
89
|
+
createdAt: edge.createdAt.toISOString(),
|
|
90
|
+
updatedAt: edge.updatedAt.toISOString(),
|
|
91
|
+
},
|
|
92
|
+
])),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Deserialize a plain object back to a GraphSnapshot (ISO strings → dates).
|
|
97
|
+
*/
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
|
+
deserialize(parsed) {
|
|
100
|
+
return {
|
|
101
|
+
...parsed,
|
|
102
|
+
metadata: {
|
|
103
|
+
...parsed.metadata,
|
|
104
|
+
createdAt: new Date(parsed.metadata.createdAt),
|
|
105
|
+
updatedAt: new Date(parsed.metadata.updatedAt),
|
|
106
|
+
},
|
|
107
|
+
nodes: Object.fromEntries(
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
Object.entries(parsed.nodes).map(([id, node]) => [
|
|
110
|
+
id,
|
|
111
|
+
{ ...node, createdAt: new Date(node.createdAt), updatedAt: new Date(node.updatedAt) },
|
|
112
|
+
])),
|
|
113
|
+
edges: Object.fromEntries(
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
Object.entries(parsed.edges).map(([id, edge]) => [
|
|
116
|
+
id,
|
|
117
|
+
{ ...edge, createdAt: new Date(edge.createdAt), updatedAt: new Date(edge.updatedAt) },
|
|
118
|
+
])),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// ── Public API ────────────────────────────────────────────────────────────
|
|
122
|
+
/**
|
|
123
|
+
* Ensure the data directory exists.
|
|
124
|
+
* Delegates to the OS mkdir so callers that relied on the old
|
|
125
|
+
* PersistenceManager behaviour continue to work unchanged.
|
|
126
|
+
*/
|
|
127
|
+
async ensureDataDir() {
|
|
128
|
+
const { promises: fsp } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
129
|
+
await fsp.mkdir(this.dataDir, { recursive: true });
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Save a graph snapshot via the configured provider.
|
|
133
|
+
*/
|
|
134
|
+
async saveGraph(snapshot) {
|
|
135
|
+
await this.provider.set(this.graphKey(snapshot.metadata.chatId), this.serialize(snapshot));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load a graph snapshot from the configured provider.
|
|
139
|
+
* Returns `null` if the snapshot does not exist.
|
|
140
|
+
*/
|
|
141
|
+
async loadGraph(chatId) {
|
|
142
|
+
const raw = await this.provider.get(this.graphKey(chatId));
|
|
143
|
+
if (raw === null)
|
|
144
|
+
return null;
|
|
145
|
+
return this.deserialize(raw);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Load or create a graph manager for a chat session.
|
|
149
|
+
*/
|
|
150
|
+
async loadOrCreateGraph(chatId, compressionThreshold) {
|
|
151
|
+
const snapshot = await this.loadGraph(chatId);
|
|
152
|
+
if (snapshot)
|
|
153
|
+
return index_1.ContextGraphManager.fromSnapshot(snapshot);
|
|
154
|
+
return new index_1.ContextGraphManager(chatId, compressionThreshold);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check whether a graph exists in the provider.
|
|
158
|
+
*/
|
|
159
|
+
async graphExists(chatId) {
|
|
160
|
+
return (await this.provider.get(this.graphKey(chatId))) !== null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Delete a graph from the provider. No-op if it does not exist.
|
|
164
|
+
*/
|
|
165
|
+
async deleteGraph(chatId) {
|
|
166
|
+
await this.provider.delete(this.graphKey(chatId));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* List all saved chat sessions by querying the `graph:` namespace.
|
|
170
|
+
*/
|
|
171
|
+
async listSessions() {
|
|
172
|
+
const keys = await this.provider.list("graph:");
|
|
173
|
+
const sessions = await Promise.all(keys.map(async (key) => {
|
|
174
|
+
const chatId = key.replace(/^graph:/, "");
|
|
175
|
+
const snapshot = await this.loadGraph(chatId);
|
|
176
|
+
if (!snapshot)
|
|
177
|
+
return null;
|
|
178
|
+
return {
|
|
179
|
+
chatId,
|
|
180
|
+
createdAt: snapshot.metadata.createdAt,
|
|
181
|
+
updatedAt: snapshot.metadata.updatedAt,
|
|
182
|
+
nodeCount: Object.keys(snapshot.nodes).length,
|
|
183
|
+
edgeCount: Object.keys(snapshot.edges).length,
|
|
184
|
+
};
|
|
185
|
+
}));
|
|
186
|
+
return sessions.filter((s) => s !== null);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Swap in a different provider at runtime (e.g. after migration).
|
|
190
|
+
*/
|
|
191
|
+
setProvider(provider) {
|
|
192
|
+
this.provider = provider;
|
|
193
|
+
}
|
|
194
|
+
/** Returns the active provider (useful for tests / diagnostics). */
|
|
195
|
+
getProvider() {
|
|
196
|
+
return this.provider;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Change the data directory used by the default JsonProvider.
|
|
200
|
+
* Has no effect when an external provider was injected.
|
|
201
|
+
*/
|
|
202
|
+
setDataDir(newDataDir) {
|
|
203
|
+
this.dataDir = newDataDir;
|
|
204
|
+
// Re-create the default provider so the new path takes effect
|
|
205
|
+
if (!(this.provider instanceof weave_provider_1.JsonProvider))
|
|
206
|
+
return;
|
|
207
|
+
this.provider = new weave_provider_1.JsonProvider(newDataDir);
|
|
208
|
+
}
|
|
209
|
+
/** Returns the configured data directory. */
|
|
210
|
+
getDataDir() {
|
|
211
|
+
return this.dataDir;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.PersistenceManager = PersistenceManager;
|
|
215
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/persistence.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAAyE;AACzE,mCAA8C;AAM9C;;;;;;;;;GASG;AACH,MAAa,kBAAkB;IAC7B,4EAA4E;IACpE,OAAO,CAAS;IAChB,QAAQ,CAAqC;IAErD;;;;OAIG;IACH,YACE,UAAkB,cAAc,EAChC,QAA6C;QAE7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,6BAAY,CAAqB,OAAO,CAAC,CAAC;IAC5E,CAAC;IAED,6EAA6E;IAErE,QAAQ,CAAC,MAAc;QAC7B,OAAO,SAAS,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,QAAuB;QACvC,OAAO;YACL,GAAG,QAAQ;YACX,QAAQ,EAAE;gBACR,GAAG,QAAQ,CAAC,QAAQ;gBACpB,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE;gBACpD,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE;aACrD;YACD,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;gBACjD,EAAE;gBACF;oBACE,GAAG,IAAI;oBACP,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;oBACvC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;iBACxC;aACF,CAAC,CACH;YACD,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;gBACjD,EAAE;gBACF;oBACE,GAAG,IAAI;oBACP,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;oBACvC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;iBACxC;aACF,CAAC,CACH;SACoB,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,8DAA8D;IACtD,WAAW,CAAC,MAAW;QAC7B,OAAO;YACL,GAAG,MAAM;YACT,QAAQ,EAAE;gBACR,GAAG,MAAM,CAAC,QAAQ;gBAClB,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAC9C,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;aAC/C;YACD,KAAK,EAAE,MAAM,CAAC,WAAW;YACvB,8DAA8D;YAC9D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAgB,EAAE,EAAE,CAAC;gBAC9D,EAAE;gBACF,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;aACtF,CAAC,CACH;YACD,KAAK,EAAE,MAAM,CAAC,WAAW;YACvB,8DAA8D;YAC9D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAgB,EAAE,EAAE,CAAC;gBAC9D,EAAE;gBACF,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;aACtF,CAAC,CACH;SACF,CAAC;IACJ,CAAC;IAED,6EAA6E;IAE7E;;;;OAIG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,wDAAa,IAAI,GAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,QAAuB;QACrC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,MAAc,EACd,oBAA6B;QAE7B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,QAAQ;YAAE,OAAO,2BAAmB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChE,OAAO,IAAI,2BAAmB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAShB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC3B,OAAO;gBACL,MAAM;gBACN,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;gBACtC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;gBACtC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM;gBAC7C,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM;aAC9C,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QACF,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACxE,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,QAA4C;QACtD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,oEAAoE;IACpE,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,UAAkB;QAC3B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;QAC1B,8DAA8D;QAC9D,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,YAAY,6BAAY,CAAC;YAAE,OAAO;QACrD,IAAI,CAAC,QAAQ,GAAG,IAAI,6BAAY,CAAqB,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,6CAA6C;IAC7C,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF;AAvMD,gDAuMC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Edge, Node } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal duck-typed interface for an embedding service.
|
|
4
|
+
* `EmbeddingService` from `@openweave/weave-embed` satisfies this interface
|
|
5
|
+
* directly — no import required, keeping weave-graph free of extra deps.
|
|
6
|
+
*/
|
|
7
|
+
export interface SynapticEmbeddingService {
|
|
8
|
+
/** Embed a single text string. Returns an object with an `embedding` vector. */
|
|
9
|
+
embed(text: string): Promise<{
|
|
10
|
+
embedding: number[];
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export interface SynapticOptions {
|
|
14
|
+
/** Minimum similarity required to create a retroactive edge. Default: 0.72 */
|
|
15
|
+
threshold?: number;
|
|
16
|
+
/** Maximum number of retroactive edges created per new node. Default: 20 */
|
|
17
|
+
maxConnections?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Optional embedding service for semantic (cosine) retroactive linking.
|
|
20
|
+
* When provided, `linkRetroactivelyEmbedding()` uses cosine similarity
|
|
21
|
+
* instead of Jaccard keyword overlap — enabling cross-vocabulary matching.
|
|
22
|
+
*/
|
|
23
|
+
embeddingService?: SynapticEmbeddingService;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Minimal structural interface that ContextGraphManager satisfies.
|
|
27
|
+
* SynapticEngine only needs these two methods — no import of the full class.
|
|
28
|
+
*/
|
|
29
|
+
export interface SynapticGraph {
|
|
30
|
+
getAllNodes(): Node[];
|
|
31
|
+
addEdge(edge: Edge): Edge;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Tokenize a text string into a normalised set of meaningful tokens.
|
|
35
|
+
*
|
|
36
|
+
* - Splits camelCase / PascalCase boundaries before lowercasing
|
|
37
|
+
* - Splits on whitespace and common punctuation
|
|
38
|
+
* - Filters tokens shorter than 2 chars
|
|
39
|
+
* - Removes stop-words
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* tokenize("TypeScript generics") → Set { "typescript", "generics" }
|
|
43
|
+
* tokenize("useContextManager") → Set { "context", "manager" }
|
|
44
|
+
*/
|
|
45
|
+
export declare function tokenize(text: string): Set<string>;
|
|
46
|
+
/**
|
|
47
|
+
* Jaccard similarity coefficient between two token sets.
|
|
48
|
+
* Returns 0 when both sets are empty.
|
|
49
|
+
*
|
|
50
|
+
* J(A,B) = |A ∩ B| / |A ∪ B|
|
|
51
|
+
*/
|
|
52
|
+
export declare function jaccardSimilarity(a: Set<string>, b: Set<string>): number;
|
|
53
|
+
/**
|
|
54
|
+
* Cosine similarity between two dense embedding vectors.
|
|
55
|
+
* Returns a value in [−1, 1]. Returns 0 when either vector has zero magnitude.
|
|
56
|
+
*
|
|
57
|
+
* cos(θ) = (A · B) / (|A| × |B|)
|
|
58
|
+
*/
|
|
59
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
60
|
+
/**
|
|
61
|
+
* SynapticEngine — retroactive keyword-based linking between nodes.
|
|
62
|
+
*
|
|
63
|
+
* When a new node enters the graph, `linkRetroactively()` scans **all**
|
|
64
|
+
* existing nodes — regardless of when they were created — and creates
|
|
65
|
+
* RELATES edges wherever the Jaccard similarity between tokenised
|
|
66
|
+
* labels/descriptions meets the configured threshold.
|
|
67
|
+
*
|
|
68
|
+
* This gives WeaveGraph its neuronal behaviour: new concepts automatically
|
|
69
|
+
* form connections with historically relevant knowledge.
|
|
70
|
+
*
|
|
71
|
+
* Produced edges carry `metadata.synapse = true` so callers can distinguish
|
|
72
|
+
* auto-generated synaptic edges from manually created ones.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const engine = new SynapticEngine({ threshold: 0.72, maxConnections: 20 });
|
|
77
|
+
*
|
|
78
|
+
* // Inject into ContextGraphManager
|
|
79
|
+
* graph.setSynapticEngine(engine);
|
|
80
|
+
*
|
|
81
|
+
* // From now on, every addNode() triggers retroactive linking automatically
|
|
82
|
+
* graph.addNode(NodeBuilder.concept("TypeScript generics"));
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare class SynapticEngine {
|
|
86
|
+
private readonly threshold;
|
|
87
|
+
private readonly maxConnections;
|
|
88
|
+
private readonly embeddingService?;
|
|
89
|
+
constructor(options?: SynapticOptions);
|
|
90
|
+
/** Read-only view of the resolved configuration. */
|
|
91
|
+
get config(): Required<Omit<SynapticOptions, "embeddingService">> & {
|
|
92
|
+
hasEmbeddings: boolean;
|
|
93
|
+
};
|
|
94
|
+
/** Whether an embedding service is configured. */
|
|
95
|
+
get hasEmbeddingService(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Scan all existing nodes in `graph` and create RELATES edges to `newNode`
|
|
98
|
+
* wherever the Jaccard similarity between their tokenised text meets the
|
|
99
|
+
* threshold. At most `maxConnections` edges are created, selecting the
|
|
100
|
+
* highest-similarity candidates first.
|
|
101
|
+
*
|
|
102
|
+
* The new node itself **must already exist** in the graph before calling
|
|
103
|
+
* this method (so that `addEdge` can reference a valid node id).
|
|
104
|
+
*
|
|
105
|
+
* @returns The list of synaptic edges created and added to the graph.
|
|
106
|
+
*/
|
|
107
|
+
linkRetroactively(newNode: Node, graph: SynapticGraph): Edge[];
|
|
108
|
+
/**
|
|
109
|
+
* Embedding-based retroactive linking (async).
|
|
110
|
+
*
|
|
111
|
+
* Requires an `embeddingService` to have been provided at construction time.
|
|
112
|
+
* If none is configured, falls back to keyword-based Jaccard similarity
|
|
113
|
+
* (identical to `linkRetroactively()`).
|
|
114
|
+
*
|
|
115
|
+
* Produced edges carry:
|
|
116
|
+
* - `metadata.synapse: true`
|
|
117
|
+
* - `metadata.similarity: number` — cosine similarity score
|
|
118
|
+
* - `metadata.mode: "embedding"` (or `"keyword"` on fallback)
|
|
119
|
+
*
|
|
120
|
+
* @returns The list of synaptic edges created and added to the graph.
|
|
121
|
+
*/
|
|
122
|
+
linkRetroactivelyEmbedding(newNode: Node, graph: SynapticGraph): Promise<Edge[]>;
|
|
123
|
+
/** Combine label + description into a single text fingerprint for a node. */
|
|
124
|
+
private _nodeText;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=synaptic-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synaptic-engine.d.ts","sourceRoot":"","sources":["../../src/synaptic-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOxC;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,gFAAgF;IAChF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;CAC7C;AAuBD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,IAAI,IAAI,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlD;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAQxE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAYjE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAA2B;gBAEjD,OAAO,GAAE,eAAoB;IAMzC,oDAAoD;IACpD,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,GAAG;QAAE,aAAa,EAAE,OAAO,CAAA;KAAE,CAM7F;IAED,kDAAkD;IAClD,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,EAAE;IAoC9D;;;;;;;;;;;;;OAaG;IACG,0BAA0B,CAC9B,OAAO,EAAE,IAAI,EACb,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,EAAE,CAAC;IAkDlB,6EAA6E;IAC7E,OAAO,CAAC,SAAS;CAGlB"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SynapticEngine = void 0;
|
|
4
|
+
exports.tokenize = tokenize;
|
|
5
|
+
exports.jaccardSimilarity = jaccardSimilarity;
|
|
6
|
+
exports.cosineSimilarity = cosineSimilarity;
|
|
7
|
+
const edge_js_1 = require("./edge.js");
|
|
8
|
+
const DEFAULT_THRESHOLD = 0.72;
|
|
9
|
+
const DEFAULT_MAX_CONNECTIONS = 20;
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Stop-words (excluded from tokenization)
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const STOP_WORDS = new Set([
|
|
14
|
+
"a", "an", "the", "is", "are", "was", "were", "be", "been", "being",
|
|
15
|
+
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
|
16
|
+
"should", "may", "might", "shall", "can", "need", "dare", "ought",
|
|
17
|
+
"for", "and", "nor", "but", "or", "yet", "so", "in", "on", "at",
|
|
18
|
+
"to", "of", "by", "up", "as", "if", "it", "its", "with", "this",
|
|
19
|
+
"that", "from", "not", "no", "vs", "via", "than", "then", "use",
|
|
20
|
+
"using", "used",
|
|
21
|
+
]);
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Tokenizer
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Tokenize a text string into a normalised set of meaningful tokens.
|
|
27
|
+
*
|
|
28
|
+
* - Splits camelCase / PascalCase boundaries before lowercasing
|
|
29
|
+
* - Splits on whitespace and common punctuation
|
|
30
|
+
* - Filters tokens shorter than 2 chars
|
|
31
|
+
* - Removes stop-words
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* tokenize("TypeScript generics") → Set { "typescript", "generics" }
|
|
35
|
+
* tokenize("useContextManager") → Set { "context", "manager" }
|
|
36
|
+
*/
|
|
37
|
+
function tokenize(text) {
|
|
38
|
+
// Split camelCase: "useContext" → "use Context"
|
|
39
|
+
const expanded = text
|
|
40
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
41
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
42
|
+
const tokens = expanded
|
|
43
|
+
.toLowerCase()
|
|
44
|
+
.split(/[\s\-_/\\.,;:()[\]{}'"!?@#$%^&*+=<>|~`]+/)
|
|
45
|
+
.filter((t) => t.length >= 2 && !STOP_WORDS.has(t));
|
|
46
|
+
return new Set(tokens);
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Similarity
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
/**
|
|
52
|
+
* Jaccard similarity coefficient between two token sets.
|
|
53
|
+
* Returns 0 when both sets are empty.
|
|
54
|
+
*
|
|
55
|
+
* J(A,B) = |A ∩ B| / |A ∪ B|
|
|
56
|
+
*/
|
|
57
|
+
function jaccardSimilarity(a, b) {
|
|
58
|
+
if (a.size === 0 && b.size === 0)
|
|
59
|
+
return 0;
|
|
60
|
+
let intersectionSize = 0;
|
|
61
|
+
for (const token of a) {
|
|
62
|
+
if (b.has(token))
|
|
63
|
+
intersectionSize++;
|
|
64
|
+
}
|
|
65
|
+
const unionSize = a.size + b.size - intersectionSize;
|
|
66
|
+
return intersectionSize / unionSize;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Cosine similarity between two dense embedding vectors.
|
|
70
|
+
* Returns a value in [−1, 1]. Returns 0 when either vector has zero magnitude.
|
|
71
|
+
*
|
|
72
|
+
* cos(θ) = (A · B) / (|A| × |B|)
|
|
73
|
+
*/
|
|
74
|
+
function cosineSimilarity(a, b) {
|
|
75
|
+
if (a.length === 0 || b.length === 0)
|
|
76
|
+
return 0;
|
|
77
|
+
let dot = 0;
|
|
78
|
+
let magA = 0;
|
|
79
|
+
let magB = 0;
|
|
80
|
+
for (let i = 0; i < a.length; i++) {
|
|
81
|
+
dot += a[i] * b[i];
|
|
82
|
+
magA += a[i] * a[i];
|
|
83
|
+
magB += b[i] * b[i];
|
|
84
|
+
}
|
|
85
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
86
|
+
return denom === 0 ? 0 : dot / denom;
|
|
87
|
+
}
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// SynapticEngine
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
/**
|
|
92
|
+
* SynapticEngine — retroactive keyword-based linking between nodes.
|
|
93
|
+
*
|
|
94
|
+
* When a new node enters the graph, `linkRetroactively()` scans **all**
|
|
95
|
+
* existing nodes — regardless of when they were created — and creates
|
|
96
|
+
* RELATES edges wherever the Jaccard similarity between tokenised
|
|
97
|
+
* labels/descriptions meets the configured threshold.
|
|
98
|
+
*
|
|
99
|
+
* This gives WeaveGraph its neuronal behaviour: new concepts automatically
|
|
100
|
+
* form connections with historically relevant knowledge.
|
|
101
|
+
*
|
|
102
|
+
* Produced edges carry `metadata.synapse = true` so callers can distinguish
|
|
103
|
+
* auto-generated synaptic edges from manually created ones.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* const engine = new SynapticEngine({ threshold: 0.72, maxConnections: 20 });
|
|
108
|
+
*
|
|
109
|
+
* // Inject into ContextGraphManager
|
|
110
|
+
* graph.setSynapticEngine(engine);
|
|
111
|
+
*
|
|
112
|
+
* // From now on, every addNode() triggers retroactive linking automatically
|
|
113
|
+
* graph.addNode(NodeBuilder.concept("TypeScript generics"));
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
class SynapticEngine {
|
|
117
|
+
threshold;
|
|
118
|
+
maxConnections;
|
|
119
|
+
embeddingService;
|
|
120
|
+
constructor(options = {}) {
|
|
121
|
+
this.threshold = options.threshold ?? DEFAULT_THRESHOLD;
|
|
122
|
+
this.maxConnections = options.maxConnections ?? DEFAULT_MAX_CONNECTIONS;
|
|
123
|
+
this.embeddingService = options.embeddingService;
|
|
124
|
+
}
|
|
125
|
+
/** Read-only view of the resolved configuration. */
|
|
126
|
+
get config() {
|
|
127
|
+
return {
|
|
128
|
+
threshold: this.threshold,
|
|
129
|
+
maxConnections: this.maxConnections,
|
|
130
|
+
hasEmbeddings: this.embeddingService !== undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** Whether an embedding service is configured. */
|
|
134
|
+
get hasEmbeddingService() {
|
|
135
|
+
return this.embeddingService !== undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Scan all existing nodes in `graph` and create RELATES edges to `newNode`
|
|
139
|
+
* wherever the Jaccard similarity between their tokenised text meets the
|
|
140
|
+
* threshold. At most `maxConnections` edges are created, selecting the
|
|
141
|
+
* highest-similarity candidates first.
|
|
142
|
+
*
|
|
143
|
+
* The new node itself **must already exist** in the graph before calling
|
|
144
|
+
* this method (so that `addEdge` can reference a valid node id).
|
|
145
|
+
*
|
|
146
|
+
* @returns The list of synaptic edges created and added to the graph.
|
|
147
|
+
*/
|
|
148
|
+
linkRetroactively(newNode, graph) {
|
|
149
|
+
const existing = graph.getAllNodes().filter((n) => n.id !== newNode.id);
|
|
150
|
+
if (existing.length === 0)
|
|
151
|
+
return [];
|
|
152
|
+
const newTokens = tokenize(this._nodeText(newNode));
|
|
153
|
+
if (newTokens.size === 0)
|
|
154
|
+
return [];
|
|
155
|
+
// Score every existing node
|
|
156
|
+
const candidates = [];
|
|
157
|
+
for (const node of existing) {
|
|
158
|
+
const tokens = tokenize(this._nodeText(node));
|
|
159
|
+
const score = jaccardSimilarity(newTokens, tokens);
|
|
160
|
+
if (score >= this.threshold) {
|
|
161
|
+
candidates.push({ node, score });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Select top-maxConnections by descending similarity
|
|
165
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
166
|
+
const selected = candidates.slice(0, this.maxConnections);
|
|
167
|
+
const created = [];
|
|
168
|
+
for (const { node, score } of selected) {
|
|
169
|
+
const base = edge_js_1.EdgeBuilder.relates(newNode.id, node.id, score);
|
|
170
|
+
const synapticEdge = {
|
|
171
|
+
...base,
|
|
172
|
+
weight: score,
|
|
173
|
+
metadata: { synapse: true, similarity: score, mode: "keyword" },
|
|
174
|
+
};
|
|
175
|
+
graph.addEdge(synapticEdge);
|
|
176
|
+
created.push(synapticEdge);
|
|
177
|
+
}
|
|
178
|
+
return created;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Embedding-based retroactive linking (async).
|
|
182
|
+
*
|
|
183
|
+
* Requires an `embeddingService` to have been provided at construction time.
|
|
184
|
+
* If none is configured, falls back to keyword-based Jaccard similarity
|
|
185
|
+
* (identical to `linkRetroactively()`).
|
|
186
|
+
*
|
|
187
|
+
* Produced edges carry:
|
|
188
|
+
* - `metadata.synapse: true`
|
|
189
|
+
* - `metadata.similarity: number` — cosine similarity score
|
|
190
|
+
* - `metadata.mode: "embedding"` (or `"keyword"` on fallback)
|
|
191
|
+
*
|
|
192
|
+
* @returns The list of synaptic edges created and added to the graph.
|
|
193
|
+
*/
|
|
194
|
+
async linkRetroactivelyEmbedding(newNode, graph) {
|
|
195
|
+
// No embedding service — fall back to keyword path
|
|
196
|
+
if (!this.embeddingService) {
|
|
197
|
+
return this.linkRetroactively(newNode, graph);
|
|
198
|
+
}
|
|
199
|
+
const existing = graph.getAllNodes().filter((n) => n.id !== newNode.id);
|
|
200
|
+
if (existing.length === 0)
|
|
201
|
+
return [];
|
|
202
|
+
const newText = this._nodeText(newNode);
|
|
203
|
+
if (newText.trim().length === 0)
|
|
204
|
+
return [];
|
|
205
|
+
// Embed new node + all existing nodes concurrently
|
|
206
|
+
const [newEmbed, ...existingEmbeds] = await Promise.all([
|
|
207
|
+
this.embeddingService.embed(newText),
|
|
208
|
+
...existing.map((n) => this.embeddingService.embed(this._nodeText(n))),
|
|
209
|
+
]);
|
|
210
|
+
// Score every existing node via cosine similarity
|
|
211
|
+
const candidates = [];
|
|
212
|
+
for (let i = 0; i < existing.length; i++) {
|
|
213
|
+
const score = cosineSimilarity(newEmbed.embedding, existingEmbeds[i].embedding);
|
|
214
|
+
if (score >= this.threshold) {
|
|
215
|
+
candidates.push({ node: existing[i], score });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Select top-maxConnections by descending similarity
|
|
219
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
220
|
+
const selected = candidates.slice(0, this.maxConnections);
|
|
221
|
+
const created = [];
|
|
222
|
+
for (const { node, score } of selected) {
|
|
223
|
+
const base = edge_js_1.EdgeBuilder.relates(newNode.id, node.id, score);
|
|
224
|
+
const synapticEdge = {
|
|
225
|
+
...base,
|
|
226
|
+
weight: score,
|
|
227
|
+
metadata: { synapse: true, similarity: score, mode: "embedding" },
|
|
228
|
+
};
|
|
229
|
+
graph.addEdge(synapticEdge);
|
|
230
|
+
created.push(synapticEdge);
|
|
231
|
+
}
|
|
232
|
+
return created;
|
|
233
|
+
}
|
|
234
|
+
// ------------------------------------------------------------------
|
|
235
|
+
// Private helpers
|
|
236
|
+
// ------------------------------------------------------------------
|
|
237
|
+
/** Combine label + description into a single text fingerprint for a node. */
|
|
238
|
+
_nodeText(node) {
|
|
239
|
+
return [node.label, node.description ?? ""].join(" ").trim();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
exports.SynapticEngine = SynapticEngine;
|
|
243
|
+
//# sourceMappingURL=synaptic-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synaptic-engine.js","sourceRoot":"","sources":["../../src/synaptic-engine.ts"],"names":[],"mappings":"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"}
|