sxng-cli 1.0.8 → 1.1.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 +10 -2
- package/dist/commands/graph-add.d.ts.map +1 -1
- package/dist/commands/graph-add.js +11 -3
- package/dist/commands/graph-add.js.map +1 -1
- package/dist/commands/graph-drill.d.ts +11 -0
- package/dist/commands/graph-drill.d.ts.map +1 -0
- package/dist/commands/graph-drill.js +26 -0
- package/dist/commands/graph-drill.js.map +1 -0
- package/dist/commands/graph-explore.d.ts +10 -0
- package/dist/commands/graph-explore.d.ts.map +1 -0
- package/dist/commands/graph-explore.js +32 -0
- package/dist/commands/graph-explore.js.map +1 -0
- package/dist/commands/graph-obfuscate.d.ts +17 -0
- package/dist/commands/graph-obfuscate.d.ts.map +1 -0
- package/dist/commands/graph-obfuscate.js +110 -0
- package/dist/commands/graph-obfuscate.js.map +1 -0
- package/dist/commands/graph-search.d.ts +11 -0
- package/dist/commands/graph-search.d.ts.map +1 -0
- package/dist/commands/graph-search.js +19 -0
- package/dist/commands/graph-search.js.map +1 -0
- package/dist/commands/graph-traverse.d.ts +10 -0
- package/dist/commands/graph-traverse.d.ts.map +1 -0
- package/dist/commands/graph-traverse.js +39 -0
- package/dist/commands/graph-traverse.js.map +1 -0
- package/dist/commands/query-graph.d.ts +2 -0
- package/dist/commands/query-graph.d.ts.map +1 -1
- package/dist/commands/query-graph.js +68 -2
- package/dist/commands/query-graph.js.map +1 -1
- package/dist/commands/session.js +1 -1
- package/dist/commands/session.js.map +1 -1
- package/dist/deep/co-occurrence.d.ts +50 -0
- package/dist/deep/co-occurrence.d.ts.map +1 -0
- package/dist/deep/co-occurrence.js +95 -0
- package/dist/deep/co-occurrence.js.map +1 -0
- package/dist/deep/degree-utils.d.ts +39 -0
- package/dist/deep/degree-utils.d.ts.map +1 -0
- package/dist/deep/degree-utils.js +42 -0
- package/dist/deep/degree-utils.js.map +1 -0
- package/dist/deep/extractor.d.ts +7 -2
- package/dist/deep/extractor.d.ts.map +1 -1
- package/dist/deep/extractor.js +143 -78
- package/dist/deep/extractor.js.map +1 -1
- package/dist/deep/graph-explore.d.ts +115 -0
- package/dist/deep/graph-explore.d.ts.map +1 -0
- package/dist/deep/graph-explore.js +586 -0
- package/dist/deep/graph-explore.js.map +1 -0
- package/dist/deep/graph-obfuscate.d.ts +51 -0
- package/dist/deep/graph-obfuscate.d.ts.map +1 -0
- package/dist/deep/graph-obfuscate.js +226 -0
- package/dist/deep/graph-obfuscate.js.map +1 -0
- package/dist/deep/graph-preprocess.d.ts +41 -0
- package/dist/deep/graph-preprocess.d.ts.map +1 -0
- package/dist/deep/graph-preprocess.js +32 -0
- package/dist/deep/graph-preprocess.js.map +1 -0
- package/dist/deep/graph-sampling.d.ts +51 -0
- package/dist/deep/graph-sampling.d.ts.map +1 -0
- package/dist/deep/graph-sampling.js +409 -0
- package/dist/deep/graph-sampling.js.map +1 -0
- package/dist/deep/graph.d.ts +24 -1
- package/dist/deep/graph.d.ts.map +1 -1
- package/dist/deep/graph.js +42 -1
- package/dist/deep/graph.js.map +1 -1
- package/dist/deep/iteration-data.d.ts +38 -0
- package/dist/deep/iteration-data.d.ts.map +1 -0
- package/dist/deep/iteration-data.js +48 -0
- package/dist/deep/iteration-data.js.map +1 -0
- package/dist/deep/path-extraction.d.ts +53 -0
- package/dist/deep/path-extraction.d.ts.map +1 -0
- package/dist/deep/path-extraction.js +229 -0
- package/dist/deep/path-extraction.js.map +1 -0
- package/dist/deep/quality-assess.d.ts +45 -0
- package/dist/deep/quality-assess.d.ts.map +1 -0
- package/dist/deep/quality-assess.js +125 -0
- package/dist/deep/quality-assess.js.map +1 -0
- package/dist/deep/query-redundancy.d.ts +39 -0
- package/dist/deep/query-redundancy.d.ts.map +1 -0
- package/dist/deep/query-redundancy.js +109 -0
- package/dist/deep/query-redundancy.js.map +1 -0
- package/dist/deep/query-suggest.d.ts +35 -0
- package/dist/deep/query-suggest.d.ts.map +1 -0
- package/dist/deep/query-suggest.js +98 -0
- package/dist/deep/query-suggest.js.map +1 -0
- package/dist/deep/recovery-analysis.d.ts +61 -0
- package/dist/deep/recovery-analysis.d.ts.map +1 -0
- package/dist/deep/recovery-analysis.js +188 -0
- package/dist/deep/recovery-analysis.js.map +1 -0
- package/dist/deep/search-strategy.d.ts +37 -0
- package/dist/deep/search-strategy.d.ts.map +1 -0
- package/dist/deep/search-strategy.js +99 -0
- package/dist/deep/search-strategy.js.map +1 -0
- package/dist/deep/session.d.ts +3 -1
- package/dist/deep/session.d.ts.map +1 -1
- package/dist/deep/session.js +4 -4
- package/dist/deep/session.js.map +1 -1
- package/dist/deep/simhash.d.ts +5 -0
- package/dist/deep/simhash.d.ts.map +1 -1
- package/dist/deep/simhash.js +16 -0
- package/dist/deep/simhash.js.map +1 -1
- package/dist/deep/tfidf.d.ts +38 -0
- package/dist/deep/tfidf.d.ts.map +1 -0
- package/dist/deep/tfidf.js +103 -0
- package/dist/deep/tfidf.js.map +1 -0
- package/dist/runCli.d.ts +3 -1
- package/dist/runCli.d.ts.map +1 -1
- package/dist/runCli.js +762 -307
- package/dist/runCli.js.map +1 -1
- package/package.json +17 -4
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-style knowledge graph exploration.
|
|
3
|
+
*
|
|
4
|
+
* Two-step interaction model:
|
|
5
|
+
* graph-explore: inspect all relations around a seed entity (summary view)
|
|
6
|
+
* graph-drill: follow specific relations from an entity (targeted retrieval)
|
|
7
|
+
*
|
|
8
|
+
* Also includes dead-end detection and alternative path suggestion.
|
|
9
|
+
*/
|
|
10
|
+
import { getEntityDegree } from './degree-utils.js';
|
|
11
|
+
import { distance as levenshteinDistance } from 'fastest-levenshtein';
|
|
12
|
+
// ── Explore ───────────────────────────────────────────────────────
|
|
13
|
+
/** Explore all relations around a seed entity. */
|
|
14
|
+
export function exploreSeedEntity(graph, seedLabel) {
|
|
15
|
+
const eId = findEntityByLabel(graph, seedLabel);
|
|
16
|
+
if (!eId) {
|
|
17
|
+
const suggestions = suggestSimilarEntities(graph, seedLabel);
|
|
18
|
+
return {
|
|
19
|
+
error: `Entity "${seedLabel}" not found`,
|
|
20
|
+
suggestions,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const attrs = graph.getNodeAttributes(eId);
|
|
24
|
+
const degree = getEntityDegree(graph, eId);
|
|
25
|
+
// Collect outgoing relations
|
|
26
|
+
const outEdges = graph.outEdges(eId);
|
|
27
|
+
const outByRelation = new Map();
|
|
28
|
+
for (const edge of outEdges) {
|
|
29
|
+
const target = graph.target(edge);
|
|
30
|
+
const edgeAttrs = graph.getEdgeAttributes(edge);
|
|
31
|
+
const targetAttrs = graph.getNodeAttributes(target);
|
|
32
|
+
const group = outByRelation.get(edgeAttrs.relation) || [];
|
|
33
|
+
group.push({
|
|
34
|
+
nodeId: target,
|
|
35
|
+
label: targetAttrs.label,
|
|
36
|
+
type: targetAttrs.type,
|
|
37
|
+
weight: edgeAttrs.weight,
|
|
38
|
+
});
|
|
39
|
+
outByRelation.set(edgeAttrs.relation, group);
|
|
40
|
+
}
|
|
41
|
+
// Collect incoming relations
|
|
42
|
+
const inEdges = graph.inEdges(eId);
|
|
43
|
+
const inByRelation = new Map();
|
|
44
|
+
for (const edge of inEdges) {
|
|
45
|
+
const source = graph.source(edge);
|
|
46
|
+
const edgeAttrs = graph.getEdgeAttributes(edge);
|
|
47
|
+
const sourceAttrs = graph.getNodeAttributes(source);
|
|
48
|
+
const group = inByRelation.get(edgeAttrs.relation) || [];
|
|
49
|
+
group.push({
|
|
50
|
+
nodeId: source,
|
|
51
|
+
label: sourceAttrs.label,
|
|
52
|
+
type: sourceAttrs.type,
|
|
53
|
+
weight: edgeAttrs.weight,
|
|
54
|
+
});
|
|
55
|
+
inByRelation.set(edgeAttrs.relation, group);
|
|
56
|
+
}
|
|
57
|
+
const outgoingRelations = [...outByRelation.entries()]
|
|
58
|
+
.map(([relation, targets]) => ({ relation, targets }))
|
|
59
|
+
.sort((a, b) => b.targets.length - a.targets.length);
|
|
60
|
+
const incomingRelations = [...inByRelation.entries()]
|
|
61
|
+
.map(([relation, targets]) => ({ relation, targets }))
|
|
62
|
+
.sort((a, b) => b.targets.length - a.targets.length);
|
|
63
|
+
// Generate suggested next steps
|
|
64
|
+
const suggestedNextSteps = generateExploreNextSteps(eId, attrs.label, outgoingRelations, incomingRelations);
|
|
65
|
+
return {
|
|
66
|
+
entity: {
|
|
67
|
+
id: eId,
|
|
68
|
+
label: attrs.label,
|
|
69
|
+
type: attrs.entityType || attrs.type,
|
|
70
|
+
score: attrs.score,
|
|
71
|
+
degree,
|
|
72
|
+
},
|
|
73
|
+
outgoingRelations,
|
|
74
|
+
incomingRelations,
|
|
75
|
+
suggestedNextSteps,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ── Drill ─────────────────────────────────────────────────────────
|
|
79
|
+
/** Follow specific relations from a seed entity. */
|
|
80
|
+
export function drillByRelations(graph, seedLabel, relations) {
|
|
81
|
+
const eId = findEntityByLabel(graph, seedLabel);
|
|
82
|
+
if (!eId) {
|
|
83
|
+
const suggestions = suggestSimilarEntities(graph, seedLabel);
|
|
84
|
+
return {
|
|
85
|
+
error: `Entity "${seedLabel}" not found`,
|
|
86
|
+
suggestions,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const attrs = graph.getNodeAttributes(eId);
|
|
90
|
+
const relationSet = new Set(relations);
|
|
91
|
+
const triples = [];
|
|
92
|
+
const seen = new Set();
|
|
93
|
+
// Outgoing edges
|
|
94
|
+
const outEdges = graph.outEdges(eId);
|
|
95
|
+
for (const edge of outEdges) {
|
|
96
|
+
const target = graph.target(edge);
|
|
97
|
+
const edgeAttrs = graph.getEdgeAttributes(edge);
|
|
98
|
+
if (!relationSet.has(edgeAttrs.relation))
|
|
99
|
+
continue;
|
|
100
|
+
const targetAttrs = graph.getNodeAttributes(target);
|
|
101
|
+
const key = `${eId}|${edgeAttrs.relation}|${target}`;
|
|
102
|
+
if (seen.has(key))
|
|
103
|
+
continue;
|
|
104
|
+
seen.add(key);
|
|
105
|
+
triples.push({
|
|
106
|
+
source: eId,
|
|
107
|
+
sourceLabel: attrs.label,
|
|
108
|
+
relation: edgeAttrs.relation,
|
|
109
|
+
target,
|
|
110
|
+
targetLabel: targetAttrs.label,
|
|
111
|
+
weight: edgeAttrs.weight,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// Incoming edges
|
|
115
|
+
const inEdges = graph.inEdges(eId);
|
|
116
|
+
for (const edge of inEdges) {
|
|
117
|
+
const source = graph.source(edge);
|
|
118
|
+
const edgeAttrs = graph.getEdgeAttributes(edge);
|
|
119
|
+
if (!relationSet.has(edgeAttrs.relation))
|
|
120
|
+
continue;
|
|
121
|
+
const sourceAttrs = graph.getNodeAttributes(source);
|
|
122
|
+
const key = `${source}|${edgeAttrs.relation}|${eId}`;
|
|
123
|
+
if (seen.has(key))
|
|
124
|
+
continue;
|
|
125
|
+
seen.add(key);
|
|
126
|
+
triples.push({
|
|
127
|
+
source,
|
|
128
|
+
sourceLabel: sourceAttrs.label,
|
|
129
|
+
relation: edgeAttrs.relation,
|
|
130
|
+
target: eId,
|
|
131
|
+
targetLabel: attrs.label,
|
|
132
|
+
weight: edgeAttrs.weight,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Next steps: suggest drilling into discovered targets
|
|
136
|
+
const nextSteps = [];
|
|
137
|
+
const discoveredEntities = new Set();
|
|
138
|
+
for (const t of triples) {
|
|
139
|
+
const tAttrs = graph.getNodeAttributes(t.target);
|
|
140
|
+
if (tAttrs.type === 'entity' && t.target !== eId && !discoveredEntities.has(t.target)) {
|
|
141
|
+
discoveredEntities.add(t.target);
|
|
142
|
+
nextSteps.push(`graph-explore --seed "${t.targetLabel}"`);
|
|
143
|
+
}
|
|
144
|
+
const sAttrs = graph.getNodeAttributes(t.source);
|
|
145
|
+
if (sAttrs.type === 'entity' && t.source !== eId && !discoveredEntities.has(t.source)) {
|
|
146
|
+
discoveredEntities.add(t.source);
|
|
147
|
+
nextSteps.push(`graph-explore --seed "${t.sourceLabel}"`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Also suggest following other relations from this entity
|
|
151
|
+
const allRelations = new Set();
|
|
152
|
+
graph.forEachOutEdge(eId, (_edge, attrs) => {
|
|
153
|
+
allRelations.add(attrs.relation);
|
|
154
|
+
});
|
|
155
|
+
graph.forEachInEdge(eId, (_edge, attrs) => {
|
|
156
|
+
allRelations.add(attrs.relation);
|
|
157
|
+
});
|
|
158
|
+
const unexplored = [...allRelations].filter(r => !relationSet.has(r));
|
|
159
|
+
if (unexplored.length > 0) {
|
|
160
|
+
nextSteps.push(`graph-drill --seed "${attrs.label}" --relations "${unexplored.slice(0, 3).join(',')}"`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
seed: eId,
|
|
164
|
+
relations,
|
|
165
|
+
triples,
|
|
166
|
+
nextSteps,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ── Dead End Detection ────────────────────────────────────────────
|
|
170
|
+
/** Detect if an entity is a dead end and suggest alternatives. */
|
|
171
|
+
export function detectDeadEnd(graph, entityId, visited) {
|
|
172
|
+
if (!graph.hasNode(entityId))
|
|
173
|
+
return null;
|
|
174
|
+
const degree = getEntityDegree(graph, entityId);
|
|
175
|
+
const visitedSet = visited || new Set();
|
|
176
|
+
// Already visited
|
|
177
|
+
if (visitedSet.has(entityId)) {
|
|
178
|
+
const alternatives = rankAlternativePaths(graph, entityId, visitedSet);
|
|
179
|
+
return {
|
|
180
|
+
entityId,
|
|
181
|
+
reason: 'already_visited',
|
|
182
|
+
alternativePaths: alternatives,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// Only mentioned_in edges (leaf entity — no semantic relationships)
|
|
186
|
+
// Check this before low_degree because a degree-1 entity with only
|
|
187
|
+
// mentioned_in is more precisely described as "only_mentioned_in"
|
|
188
|
+
const outEdges = graph.outEdges(entityId);
|
|
189
|
+
const inEdges = graph.inEdges(entityId);
|
|
190
|
+
const allRelations = [];
|
|
191
|
+
for (const edge of outEdges) {
|
|
192
|
+
allRelations.push(graph.getEdgeAttributes(edge).relation);
|
|
193
|
+
}
|
|
194
|
+
for (const edge of inEdges) {
|
|
195
|
+
allRelations.push(graph.getEdgeAttributes(edge).relation);
|
|
196
|
+
}
|
|
197
|
+
const uniqueRelations = new Set(allRelations);
|
|
198
|
+
if (uniqueRelations.size === 1 && uniqueRelations.has('mentioned_in')) {
|
|
199
|
+
const alternatives = rankAlternativePaths(graph, entityId, visitedSet);
|
|
200
|
+
return {
|
|
201
|
+
entityId,
|
|
202
|
+
reason: 'only_mentioned_in',
|
|
203
|
+
alternativePaths: alternatives,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// Low degree (≤ 1) — but not only mentioned_in (already handled above)
|
|
207
|
+
if (degree <= 1) {
|
|
208
|
+
const alternatives = rankAlternativePaths(graph, entityId, visitedSet);
|
|
209
|
+
return {
|
|
210
|
+
entityId,
|
|
211
|
+
reason: 'low_degree',
|
|
212
|
+
alternativePaths: alternatives,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
/** Rank alternative paths from visited nodes with unexplored relations. */
|
|
218
|
+
function rankAlternativePaths(graph, _deadEndId, visited) {
|
|
219
|
+
const candidates = [];
|
|
220
|
+
for (const vId of visited) {
|
|
221
|
+
if (!graph.hasNode(vId))
|
|
222
|
+
continue;
|
|
223
|
+
const vAttrs = graph.getNodeAttributes(vId);
|
|
224
|
+
const vDegree = getEntityDegree(graph, vId);
|
|
225
|
+
// Count visited neighbors
|
|
226
|
+
let visitedCount = 0;
|
|
227
|
+
let totalCount = 0;
|
|
228
|
+
graph.forEachNeighbor(vId, (neighbor) => {
|
|
229
|
+
totalCount++;
|
|
230
|
+
if (visited.has(neighbor))
|
|
231
|
+
visitedCount++;
|
|
232
|
+
});
|
|
233
|
+
const visitedRatio = totalCount > 0 ? visitedCount / totalCount : 1;
|
|
234
|
+
// Find unexplored outgoing edges from visited nodes
|
|
235
|
+
const outEdges = graph.outEdges(vId);
|
|
236
|
+
for (const edge of outEdges) {
|
|
237
|
+
const target = graph.target(edge);
|
|
238
|
+
if (visited.has(target))
|
|
239
|
+
continue;
|
|
240
|
+
const edgeAttrs = graph.getEdgeAttributes(edge);
|
|
241
|
+
const targetAttrs = graph.getNodeAttributes(target);
|
|
242
|
+
const targetScore = targetAttrs.score ?? 1;
|
|
243
|
+
const score = edgeAttrs.weight * targetScore * (1 - visitedRatio);
|
|
244
|
+
candidates.push({
|
|
245
|
+
fromEntity: vId,
|
|
246
|
+
fromLabel: vAttrs.label,
|
|
247
|
+
relation: edgeAttrs.relation,
|
|
248
|
+
toEntity: target,
|
|
249
|
+
toLabel: targetAttrs.label,
|
|
250
|
+
score,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Sort by score descending, return top 3
|
|
255
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
256
|
+
return candidates.slice(0, 3);
|
|
257
|
+
}
|
|
258
|
+
/** Traverse a path: node and return the ordered reasoning chain. */
|
|
259
|
+
export function traversePath(graph, pathId) {
|
|
260
|
+
if (!graph.hasNode(pathId)) {
|
|
261
|
+
const availablePaths = findAvailablePaths(graph);
|
|
262
|
+
return {
|
|
263
|
+
error: `Path "${pathId}" not found`,
|
|
264
|
+
availablePaths,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const pathAttrs = graph.getNodeAttributes(pathId);
|
|
268
|
+
if (pathAttrs.type !== 'path') {
|
|
269
|
+
const availablePaths = findAvailablePaths(graph);
|
|
270
|
+
return {
|
|
271
|
+
error: `Node "${pathId}" is not a path node`,
|
|
272
|
+
availablePaths,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
const entityIds = pathAttrs.entities || [];
|
|
276
|
+
const hops = [];
|
|
277
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
278
|
+
const eId = entityIds[i];
|
|
279
|
+
const eAttrs = graph.hasNode(eId) ? graph.getNodeAttributes(eId) : null;
|
|
280
|
+
// Find the relation between consecutive entities
|
|
281
|
+
let relation;
|
|
282
|
+
if (i > 0) {
|
|
283
|
+
const prevId = entityIds[i - 1];
|
|
284
|
+
if (graph.hasEdge(prevId, eId)) {
|
|
285
|
+
relation = graph.getEdgeAttributes(prevId, eId).relation;
|
|
286
|
+
}
|
|
287
|
+
else if (graph.hasEdge(eId, prevId)) {
|
|
288
|
+
relation = graph.getEdgeAttributes(eId, prevId).relation;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
hops.push({
|
|
292
|
+
index: i + 1,
|
|
293
|
+
entityId: eId,
|
|
294
|
+
entityLabel: eAttrs?.label || eId,
|
|
295
|
+
entityType: eAttrs?.entityType || eAttrs?.type || 'unknown',
|
|
296
|
+
relation,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
// Collect source info: results that mention entities in this path
|
|
300
|
+
const domainSet = new Set();
|
|
301
|
+
const roundSet = new Set();
|
|
302
|
+
let resultCount = 0;
|
|
303
|
+
for (const eId of entityIds) {
|
|
304
|
+
if (!graph.hasNode(eId))
|
|
305
|
+
continue;
|
|
306
|
+
// Check incoming edges for "mentions" (result → entity)
|
|
307
|
+
const inEdges = graph.inEdges(eId);
|
|
308
|
+
for (const edge of inEdges) {
|
|
309
|
+
const source = graph.source(edge);
|
|
310
|
+
const sourceAttrs = graph.getNodeAttributes(source);
|
|
311
|
+
if (sourceAttrs.type === 'result') {
|
|
312
|
+
resultCount++;
|
|
313
|
+
if (sourceAttrs.url) {
|
|
314
|
+
try {
|
|
315
|
+
const domain = new URL(sourceAttrs.url).hostname;
|
|
316
|
+
domainSet.add(domain);
|
|
317
|
+
}
|
|
318
|
+
catch { /* skip */ }
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Collect rounds from entity sourceRounds
|
|
323
|
+
if (graph.getNodeAttributes(eId).sourceRounds) {
|
|
324
|
+
for (const r of graph.getNodeAttributes(eId).sourceRounds) {
|
|
325
|
+
roundSet.add(r);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
pathId,
|
|
331
|
+
pathType: pathAttrs.pathType || 'unknown',
|
|
332
|
+
label: pathAttrs.label,
|
|
333
|
+
hops,
|
|
334
|
+
sources: {
|
|
335
|
+
resultCount,
|
|
336
|
+
domains: [...domainSet],
|
|
337
|
+
rounds: [...roundSet].sort((a, b) => a - b),
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function findAvailablePaths(graph) {
|
|
342
|
+
const paths = [];
|
|
343
|
+
graph.forEachNode((node, attrs) => {
|
|
344
|
+
if (attrs.type === 'path')
|
|
345
|
+
paths.push(node);
|
|
346
|
+
});
|
|
347
|
+
return paths;
|
|
348
|
+
}
|
|
349
|
+
/** Keyword search across entity labels. Returns entity IDs ranked by score × degree. */
|
|
350
|
+
export function searchEntities(graph, keyword, limit = 10) {
|
|
351
|
+
const lowerKeyword = keyword.toLowerCase();
|
|
352
|
+
const results = [];
|
|
353
|
+
graph.forEachNode((node, attrs) => {
|
|
354
|
+
if (attrs.type !== 'entity')
|
|
355
|
+
return;
|
|
356
|
+
const label = attrs.label.toLowerCase();
|
|
357
|
+
// Match if keyword is contained in label or label contains keyword
|
|
358
|
+
if (!label.includes(lowerKeyword))
|
|
359
|
+
return;
|
|
360
|
+
const degree = getEntityDegree(graph, node);
|
|
361
|
+
const entityScore = attrs.score ?? 1;
|
|
362
|
+
const score = entityScore * degree;
|
|
363
|
+
results.push({
|
|
364
|
+
id: node,
|
|
365
|
+
label: attrs.label,
|
|
366
|
+
score,
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
// Sort by score descending
|
|
370
|
+
results.sort((a, b) => b.score - a.score);
|
|
371
|
+
return results.slice(0, limit);
|
|
372
|
+
}
|
|
373
|
+
// ── Helpers ───────────────────────────────────────────────────────
|
|
374
|
+
/** Find entity node by label (case-insensitive). */
|
|
375
|
+
function findEntityByLabel(graph, label) {
|
|
376
|
+
const lowerLabel = label.toLowerCase();
|
|
377
|
+
let found = null;
|
|
378
|
+
graph.forEachNode((node, attrs) => {
|
|
379
|
+
if (attrs.type === 'entity' && attrs.label.toLowerCase() === lowerLabel) {
|
|
380
|
+
found = node;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
return found;
|
|
384
|
+
}
|
|
385
|
+
/** Suggest similar entities using Levenshtein distance. */
|
|
386
|
+
function suggestSimilarEntities(graph, label) {
|
|
387
|
+
const entityLabels = [];
|
|
388
|
+
const labelToId = new Map();
|
|
389
|
+
graph.forEachNode((node, attrs) => {
|
|
390
|
+
if (attrs.type === 'entity') {
|
|
391
|
+
entityLabels.push(attrs.label);
|
|
392
|
+
labelToId.set(attrs.label, node);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
if (entityLabels.length === 0)
|
|
396
|
+
return [];
|
|
397
|
+
const suggestions = [];
|
|
398
|
+
const scored = entityLabels
|
|
399
|
+
.map(l => ({ label: l, distance: levenshteinDistance(label, l) }))
|
|
400
|
+
.sort((a, b) => a.distance - b.distance)
|
|
401
|
+
.slice(0, 5);
|
|
402
|
+
for (const s of scored) {
|
|
403
|
+
const id = labelToId.get(s.label);
|
|
404
|
+
if (id) {
|
|
405
|
+
suggestions.push({ id, label: s.label, distance: s.distance });
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return suggestions;
|
|
409
|
+
}
|
|
410
|
+
/** Generate suggested next steps for explore result. */
|
|
411
|
+
function generateExploreNextSteps(entityId, entityLabel, outgoing, incoming) {
|
|
412
|
+
const steps = [];
|
|
413
|
+
// Suggest drilling into top relation groups
|
|
414
|
+
for (const group of outgoing.slice(0, 2)) {
|
|
415
|
+
steps.push(`graph-drill --seed "${entityLabel}" --relations "${group.relation}"`);
|
|
416
|
+
}
|
|
417
|
+
// Suggest exploring connected entity targets
|
|
418
|
+
const entityTargets = new Set();
|
|
419
|
+
for (const group of outgoing) {
|
|
420
|
+
for (const t of group.targets) {
|
|
421
|
+
if (t.type === 'entity' && t.nodeId !== entityId && !entityTargets.has(t.label)) {
|
|
422
|
+
entityTargets.add(t.label);
|
|
423
|
+
steps.push(`graph-explore --seed "${t.label}"`);
|
|
424
|
+
if (entityTargets.size >= 3)
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (entityTargets.size >= 3)
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
// Suggest exploring from incoming entity sources
|
|
432
|
+
for (const group of incoming) {
|
|
433
|
+
for (const t of group.targets) {
|
|
434
|
+
if (t.type === 'entity' && t.nodeId !== entityId && !entityTargets.has(t.label)) {
|
|
435
|
+
entityTargets.add(t.label);
|
|
436
|
+
steps.push(`graph-explore --seed "${t.label}"`);
|
|
437
|
+
if (entityTargets.size >= 5)
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (entityTargets.size >= 5)
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
return steps.slice(0, 5);
|
|
445
|
+
}
|
|
446
|
+
// ── Formatting ────────────────────────────────────────────────────
|
|
447
|
+
/** Format explore result as Markdown. */
|
|
448
|
+
export function formatExploreAsMarkdown(result) {
|
|
449
|
+
const lines = [];
|
|
450
|
+
lines.push(`## Entity: ${result.entity.label} (${result.entity.type}, degree: ${result.entity.degree})`);
|
|
451
|
+
lines.push('');
|
|
452
|
+
if (result.outgoingRelations.length > 0) {
|
|
453
|
+
const totalOut = result.outgoingRelations.reduce((sum, g) => sum + g.targets.length, 0);
|
|
454
|
+
lines.push(`### Outgoing Relations (${totalOut})`);
|
|
455
|
+
lines.push('');
|
|
456
|
+
lines.push('| # | Relation | Target | Target Type | Weight |');
|
|
457
|
+
lines.push('|---|----------|--------|-------------|--------|');
|
|
458
|
+
let idx = 1;
|
|
459
|
+
for (const group of result.outgoingRelations) {
|
|
460
|
+
for (const t of group.targets) {
|
|
461
|
+
lines.push(`| ${idx++} | ${group.relation} | ${t.label} | ${t.type} | ${t.weight.toFixed(2)} |`);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
lines.push('');
|
|
465
|
+
}
|
|
466
|
+
if (result.incomingRelations.length > 0) {
|
|
467
|
+
const totalIn = result.incomingRelations.reduce((sum, g) => sum + g.targets.length, 0);
|
|
468
|
+
lines.push(`### Incoming Relations (${totalIn})`);
|
|
469
|
+
lines.push('');
|
|
470
|
+
lines.push('| # | Relation | Source | Source Type | Weight |');
|
|
471
|
+
lines.push('|---|----------|--------|-------------|--------|');
|
|
472
|
+
let idx = 1;
|
|
473
|
+
for (const group of result.incomingRelations) {
|
|
474
|
+
for (const t of group.targets) {
|
|
475
|
+
lines.push(`| ${idx++} | ${group.relation} | ${t.label} | ${t.type} | ${t.weight.toFixed(2)} |`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
lines.push('');
|
|
479
|
+
}
|
|
480
|
+
if (result.suggestedNextSteps.length > 0) {
|
|
481
|
+
lines.push('### Next Steps');
|
|
482
|
+
lines.push('');
|
|
483
|
+
for (const step of result.suggestedNextSteps) {
|
|
484
|
+
lines.push(`- \`${step}\``);
|
|
485
|
+
}
|
|
486
|
+
lines.push('');
|
|
487
|
+
}
|
|
488
|
+
return lines.join('\n');
|
|
489
|
+
}
|
|
490
|
+
/** Format drill result as Markdown. */
|
|
491
|
+
export function formatDrillAsMarkdown(result) {
|
|
492
|
+
const lines = [];
|
|
493
|
+
const seedAttrs = result.seed;
|
|
494
|
+
lines.push(`## Drill: ${seedAttrs} → [${result.relations.join(', ')}]`);
|
|
495
|
+
lines.push('');
|
|
496
|
+
// Group triples by relation
|
|
497
|
+
const byRelation = new Map();
|
|
498
|
+
for (const t of result.triples) {
|
|
499
|
+
const group = byRelation.get(t.relation) || [];
|
|
500
|
+
group.push(t);
|
|
501
|
+
byRelation.set(t.relation, group);
|
|
502
|
+
}
|
|
503
|
+
for (const [relation, triples] of byRelation) {
|
|
504
|
+
lines.push(`### ${relation}`);
|
|
505
|
+
lines.push('');
|
|
506
|
+
lines.push('| Source | Target | Weight |');
|
|
507
|
+
lines.push('|--------|--------|--------|');
|
|
508
|
+
for (const t of triples) {
|
|
509
|
+
lines.push(`| ${t.sourceLabel} | ${t.targetLabel} | ${t.weight.toFixed(2)} |`);
|
|
510
|
+
}
|
|
511
|
+
lines.push('');
|
|
512
|
+
}
|
|
513
|
+
if (result.nextSteps.length > 0) {
|
|
514
|
+
lines.push('### Next Steps');
|
|
515
|
+
lines.push('');
|
|
516
|
+
for (const step of result.nextSteps) {
|
|
517
|
+
lines.push(`- \`${step}\``);
|
|
518
|
+
}
|
|
519
|
+
lines.push('');
|
|
520
|
+
}
|
|
521
|
+
return lines.join('\n');
|
|
522
|
+
}
|
|
523
|
+
/** Format dead-end info as Markdown. */
|
|
524
|
+
export function formatDeadEndAsMarkdown(info) {
|
|
525
|
+
const lines = [];
|
|
526
|
+
const reasonLabels = {
|
|
527
|
+
low_degree: 'Low degree (leaf node)',
|
|
528
|
+
only_mentioned_in: 'Only has "mentioned_in" edges',
|
|
529
|
+
already_visited: 'Already visited',
|
|
530
|
+
};
|
|
531
|
+
lines.push(`### Dead End: ${info.entityId}`);
|
|
532
|
+
lines.push(`**Reason:** ${reasonLabels[info.reason] || info.reason}`);
|
|
533
|
+
lines.push('');
|
|
534
|
+
if (info.alternativePaths.length > 0) {
|
|
535
|
+
lines.push('**Alternative Paths:**');
|
|
536
|
+
lines.push('');
|
|
537
|
+
lines.push('| From | Relation | To | Score |');
|
|
538
|
+
lines.push('|------|----------|----|-------|');
|
|
539
|
+
for (const p of info.alternativePaths) {
|
|
540
|
+
lines.push(`| ${p.fromLabel} | ${p.relation} | ${p.toLabel} | ${p.score.toFixed(3)} |`);
|
|
541
|
+
}
|
|
542
|
+
lines.push('');
|
|
543
|
+
}
|
|
544
|
+
return lines.join('\n');
|
|
545
|
+
}
|
|
546
|
+
/** Format traverse result as Markdown. */
|
|
547
|
+
export function formatTraverseAsMarkdown(result) {
|
|
548
|
+
const lines = [];
|
|
549
|
+
lines.push(`## Path: ${result.label}`);
|
|
550
|
+
lines.push('');
|
|
551
|
+
lines.push('| Hop | Entity | Relation | Type |');
|
|
552
|
+
lines.push('|-----|--------|----------|------|');
|
|
553
|
+
for (const hop of result.hops) {
|
|
554
|
+
lines.push(`| ${hop.index} | ${hop.entityLabel} | ${hop.relation || '-'} | ${hop.entityType} |`);
|
|
555
|
+
}
|
|
556
|
+
lines.push('');
|
|
557
|
+
if (result.sources.resultCount > 0 || result.sources.domains.length > 0) {
|
|
558
|
+
lines.push('### Sources');
|
|
559
|
+
lines.push('');
|
|
560
|
+
lines.push(`- Mentioned in ${result.sources.resultCount} results`);
|
|
561
|
+
if (result.sources.rounds.length > 0) {
|
|
562
|
+
lines.push(`- Rounds: ${result.sources.rounds.join(', ')}`);
|
|
563
|
+
}
|
|
564
|
+
if (result.sources.domains.length > 0) {
|
|
565
|
+
lines.push(`- Domains: ${result.sources.domains.slice(0, 5).join(', ')}`);
|
|
566
|
+
}
|
|
567
|
+
lines.push('');
|
|
568
|
+
}
|
|
569
|
+
return lines.join('\n');
|
|
570
|
+
}
|
|
571
|
+
/** Format search results as Markdown. */
|
|
572
|
+
export function formatSearchAsMarkdown(results, keyword) {
|
|
573
|
+
const lines = [];
|
|
574
|
+
lines.push(`## Search: "${keyword}"`);
|
|
575
|
+
lines.push('');
|
|
576
|
+
lines.push(`**${results.length} entities found**`);
|
|
577
|
+
lines.push('');
|
|
578
|
+
lines.push('| # | Entity | Score |');
|
|
579
|
+
lines.push('|---|--------|-------|');
|
|
580
|
+
for (let i = 0; i < results.length; i++) {
|
|
581
|
+
lines.push(`| ${i + 1} | ${results[i].label} | ${results[i].score.toFixed(2)} |`);
|
|
582
|
+
}
|
|
583
|
+
lines.push('');
|
|
584
|
+
return lines.join('\n');
|
|
585
|
+
}
|
|
586
|
+
//# sourceMappingURL=graph-explore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-explore.js","sourceRoot":"","sources":["../../src/deep/graph-explore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity obfuscation (MTG-inspired) for knowledge graph.
|
|
3
|
+
*
|
|
4
|
+
* Primary flow: Agent (LLM) generates obfuscated labels.
|
|
5
|
+
* Fallback flow: simple rule-based obfuscation (experimental).
|
|
6
|
+
*
|
|
7
|
+
* The `graph-obfuscate` command outputs candidate entities for obfuscation,
|
|
8
|
+
* then the Agent uses LLM to produce obfuscated labels and writes them
|
|
9
|
+
* back via `graph-add`.
|
|
10
|
+
*
|
|
11
|
+
* Fallback rules are intentionally weak — they preserve too many
|
|
12
|
+
* identifying cues. Marked as experimental, not for production use.
|
|
13
|
+
*/
|
|
14
|
+
import { DirectedGraph } from 'graphology';
|
|
15
|
+
import { GraphNodeAttrs, GraphEdgeAttrs } from './graph.js';
|
|
16
|
+
export interface ObfuscationCandidate {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
entityType?: string;
|
|
20
|
+
score?: number;
|
|
21
|
+
hasObfuscatedLabel: boolean;
|
|
22
|
+
obfuscatedLabel?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface FallbackRuleResult {
|
|
25
|
+
original: string;
|
|
26
|
+
obfuscated: string;
|
|
27
|
+
rule: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ObfuscationResult {
|
|
30
|
+
mode: 'list' | 'fallback_rules';
|
|
31
|
+
candidates: ObfuscationCandidate[];
|
|
32
|
+
fallbackResults?: FallbackRuleResult[];
|
|
33
|
+
stats: {
|
|
34
|
+
totalEntities: number;
|
|
35
|
+
alreadyObfuscated: number;
|
|
36
|
+
needObfuscation: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface ObfuscationConfig {
|
|
40
|
+
mode: 'list' | 'fallback_rules';
|
|
41
|
+
/** Entity types to skip during obfuscation (e.g. "concept" may be too vague) */
|
|
42
|
+
skipEntityTypes?: string[];
|
|
43
|
+
}
|
|
44
|
+
/** List entities that are candidates for obfuscation (those without obfuscatedLabel). */
|
|
45
|
+
export declare function listObfuscationCandidates(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, config?: ObfuscationConfig): ObfuscationResult;
|
|
46
|
+
/** Apply fallback rules to all entities without obfuscatedLabel and write results to graph.
|
|
47
|
+
* Returns the list of applied rules. */
|
|
48
|
+
export declare function applyFallbackRules(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, config?: ObfuscationConfig): ObfuscationResult;
|
|
49
|
+
/** Run entity obfuscation on a graph. */
|
|
50
|
+
export declare function runGraphObfuscate(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, config: ObfuscationConfig): ObfuscationResult;
|
|
51
|
+
//# sourceMappingURL=graph-obfuscate.d.ts.map
|