sxng-cli 1.1.7 → 1.1.8
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/commands/graph-add.d.ts.sync-conflict-20260629-232900-2SGIW5T.map +1 -0
- package/dist/commands/graph-add.js.sync-conflict-20260629-232916-2SGIW5T.map +1 -0
- package/dist/commands/graph-add.sync-conflict-20260629-232853-2SGIW5T.js +163 -0
- package/dist/deep/extractor.d.sync-conflict-20260629-232902-2SGIW5T.ts +37 -0
- package/dist/deep/extractor.d.ts.sync-conflict-20260629-232921-2SGIW5T.map +1 -0
- package/dist/deep/extractor.js.sync-conflict-20260629-232921-2SGIW5T.map +1 -0
- package/dist/deep/extractor.sync-conflict-20260629-232903-2SGIW5T.js +203 -0
- package/dist/deep/graph.d.sync-conflict-20260629-232917-2SGIW5T.ts +78 -0
- package/dist/deep/graph.d.ts.sync-conflict-20260629-232911-2SGIW5T.map +1 -0
- package/dist/deep/graph.js.sync-conflict-20260629-232855-2SGIW5T.map +1 -0
- package/dist/deep/graph.sync-conflict-20260629-232907-2SGIW5T.js +194 -0
- package/dist/deep/session.d.sync-conflict-20260629-232917-2SGIW5T.ts +71 -0
- package/dist/deep/session.d.ts.sync-conflict-20260629-232921-2SGIW5T.map +1 -0
- package/dist/deep/session.js.sync-conflict-20260629-232854-2SGIW5T.map +1 -0
- package/dist/runCli.d.ts.sync-conflict-20260629-232854-2SGIW5T.map +1 -0
- package/dist/runCli.js +4 -4
- package/dist/runCli.js.map +1 -1
- package/dist/runCli.js.sync-conflict-20260629-232857-2SGIW5T.map +1 -0
- package/dist/runCli.sync-conflict-20260629-232915-2SGIW5T.js +1109 -0
- package/dist/runCli.sync-conflict-20260629-233530-JAULAPO.d.ts +8 -0
- package/dist/runCli.sync-conflict-20260629-233530-JAULAPO.d.ts.map +1 -0
- package/dist/runCli.sync-conflict-20260629-233530-JAULAPO.js +1111 -0
- package/dist/runCli.sync-conflict-20260629-233530-JAULAPO.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-add.d.ts","sourceRoot":"","sources":["../../src/commands/graph-add.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2BH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB;AA0BD,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA4J3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-add.js","sourceRoot":"","sources":["../../src/commands/graph-add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* graph-add subcommand - Add entities and edges to an entity-centric knowledge graph
|
|
3
|
+
*
|
|
4
|
+
* Agent (LLM) extracts entities from search results and sends them here.
|
|
5
|
+
* Each entity is connected to its source result via "mentions" edges.
|
|
6
|
+
* Result nodes store lightweight metadata (title, url, rank).
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync, statSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
import { deserializeGraph, serializeGraph, graphStats, entityId, resultId } from '../deep/graph.js';
|
|
12
|
+
import { DirectedGraph } from 'graphology';
|
|
13
|
+
import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
|
|
14
|
+
/** Resolve graph file path — if directory (session), use graph.json inside it.
|
|
15
|
+
* Pure name (no separators) is resolved to ~/sxng-cli/sessions/<name>
|
|
16
|
+
*/
|
|
17
|
+
function resolveGraphFile(path) {
|
|
18
|
+
// Pure name without path separators: resolve to default sessions dir
|
|
19
|
+
if (!path.includes('/') && !path.includes('\\')) {
|
|
20
|
+
path = join(homedir(), 'sxng-cli', 'sessions', path);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
if (statSync(path).isDirectory()) {
|
|
24
|
+
return join(path, 'graph.json');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Not a file/dir, return as-is
|
|
29
|
+
}
|
|
30
|
+
return path;
|
|
31
|
+
}
|
|
32
|
+
export async function runGraphAdd(options) {
|
|
33
|
+
const graphFile = resolveGraphFile(options.graphFile);
|
|
34
|
+
if (!graphFile) {
|
|
35
|
+
const envelope = createErrorEnvelope('MISSING_GRAPH_FILE', 'No graph file specified', { hint: 'Use: sxng graph-add graph.json --data \'...\'' });
|
|
36
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
// Parse input data
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(options.data);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
const envelope = createErrorEnvelope('INVALID_JSON', 'Failed to parse --data JSON', { hint: 'Ensure --data contains valid JSON with "entities", "results", and/or "edges" arrays' });
|
|
46
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
// Load or create graph
|
|
50
|
+
let graph;
|
|
51
|
+
if (existsSync(graphFile)) {
|
|
52
|
+
try {
|
|
53
|
+
const raw = readFileSync(graphFile, 'utf-8');
|
|
54
|
+
const fileParsed = JSON.parse(raw);
|
|
55
|
+
const graphData = fileParsed.status === 'ok' && fileParsed.data?.graph
|
|
56
|
+
? fileParsed.data.graph
|
|
57
|
+
: (fileParsed.nodes && fileParsed.edges ? fileParsed : null);
|
|
58
|
+
graph = graphData
|
|
59
|
+
? deserializeGraph(graphData)
|
|
60
|
+
: new DirectedGraph();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
const envelope = createErrorEnvelope('GRAPH_LOAD_FAILED', `Failed to load graph from: ${graphFile}`, { hint: 'Ensure the file contains a valid graphology graph' });
|
|
64
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
graph = new DirectedGraph();
|
|
70
|
+
}
|
|
71
|
+
let entitiesAdded = 0;
|
|
72
|
+
let resultsAdded = 0;
|
|
73
|
+
let edgesAdded = 0;
|
|
74
|
+
// Add entity nodes
|
|
75
|
+
for (const entity of parsed.entities || []) {
|
|
76
|
+
const id = entity.id || entityId(entity.label);
|
|
77
|
+
if (!graph.hasNode(id)) {
|
|
78
|
+
graph.mergeNode(id, {
|
|
79
|
+
type: 'entity',
|
|
80
|
+
label: entity.label,
|
|
81
|
+
entityType: entity.entityType,
|
|
82
|
+
score: entity.score,
|
|
83
|
+
obfuscatedLabel: entity.obfuscatedLabel,
|
|
84
|
+
sourceRounds: entity.sourceRounds,
|
|
85
|
+
frequency: entity.frequency,
|
|
86
|
+
reasoningPaths: entity.reasoningPaths,
|
|
87
|
+
});
|
|
88
|
+
entitiesAdded++;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Update existing entity — merge new fields
|
|
92
|
+
const existing = graph.getNodeAttributes(id);
|
|
93
|
+
graph.mergeNode(id, {
|
|
94
|
+
...existing,
|
|
95
|
+
label: entity.label,
|
|
96
|
+
entityType: entity.entityType ?? existing.entityType,
|
|
97
|
+
score: entity.score ?? existing.score,
|
|
98
|
+
obfuscatedLabel: entity.obfuscatedLabel ?? existing.obfuscatedLabel,
|
|
99
|
+
sourceRounds: entity.sourceRounds ?? existing.sourceRounds,
|
|
100
|
+
frequency: entity.frequency ?? existing.frequency,
|
|
101
|
+
reasoningPaths: entity.reasoningPaths ?? existing.reasoningPaths,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Add result metadata nodes
|
|
106
|
+
for (const result of parsed.results || []) {
|
|
107
|
+
const id = resultId(result.url);
|
|
108
|
+
if (!graph.hasNode(id)) {
|
|
109
|
+
graph.mergeNode(id, {
|
|
110
|
+
type: 'result',
|
|
111
|
+
label: result.title,
|
|
112
|
+
url: result.url,
|
|
113
|
+
title: result.title,
|
|
114
|
+
rank: result.rank,
|
|
115
|
+
});
|
|
116
|
+
resultsAdded++;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Update rank if better
|
|
120
|
+
const existing = graph.getNodeAttributes(id);
|
|
121
|
+
if (result.rank !== undefined) {
|
|
122
|
+
graph.mergeNode(id, {
|
|
123
|
+
...existing,
|
|
124
|
+
rank: result.rank < (existing.rank ?? Infinity) ? result.rank : existing.rank,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Add edges (entity-entity and entity-result relationships)
|
|
130
|
+
const skippedEdges = [];
|
|
131
|
+
for (const edge of parsed.edges || []) {
|
|
132
|
+
if (!graph.hasNode(edge.source) || !graph.hasNode(edge.target)) {
|
|
133
|
+
skippedEdges.push({ source: edge.source, target: edge.target, relation: edge.relation });
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
graph.mergeEdge(edge.source, edge.target, {
|
|
137
|
+
relation: edge.relation,
|
|
138
|
+
weight: edge.weight ?? 1,
|
|
139
|
+
});
|
|
140
|
+
edgesAdded++;
|
|
141
|
+
}
|
|
142
|
+
// Save graph
|
|
143
|
+
const serialized = serializeGraph(graph);
|
|
144
|
+
const stats = graphStats(graph);
|
|
145
|
+
try {
|
|
146
|
+
writeFileSync(graphFile, JSON.stringify({ status: 'ok', data: { graph: serialized, stats } }, null, 2), 'utf-8');
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
const envelope = createErrorEnvelope('GRAPH_WRITE_FAILED', `Failed to write graph to: ${graphFile}`, { hint: 'Check directory permissions and disk space', details: { error: e instanceof Error ? e.message : String(e) } });
|
|
150
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
const envelope = createSuccessEnvelope({
|
|
154
|
+
entitiesAdded,
|
|
155
|
+
resultsAdded,
|
|
156
|
+
edgesAdded,
|
|
157
|
+
skippedEdges,
|
|
158
|
+
stats,
|
|
159
|
+
});
|
|
160
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=graph-add.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content extraction: Defuddle (linkedom) → Obscura fallback
|
|
3
|
+
*/
|
|
4
|
+
export interface ExtractorOptions {
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
maxResponseBytes?: number;
|
|
8
|
+
obscura?: boolean;
|
|
9
|
+
obscuraPath?: string;
|
|
10
|
+
obscuraDumpFormat?: 'html' | 'markdown';
|
|
11
|
+
}
|
|
12
|
+
export interface ExtractedContent {
|
|
13
|
+
title: string;
|
|
14
|
+
content: string;
|
|
15
|
+
excerpt: string;
|
|
16
|
+
url: string;
|
|
17
|
+
byline?: string;
|
|
18
|
+
siteName?: string;
|
|
19
|
+
length: number;
|
|
20
|
+
extractedAt: number;
|
|
21
|
+
error?: string;
|
|
22
|
+
method?: 'defuddle' | 'obscura';
|
|
23
|
+
}
|
|
24
|
+
export declare class ContentExtractor {
|
|
25
|
+
private timeoutMs;
|
|
26
|
+
private concurrency;
|
|
27
|
+
private maxResponseBytes;
|
|
28
|
+
private useObscura;
|
|
29
|
+
private obscuraPath?;
|
|
30
|
+
private obscuraDumpFormat;
|
|
31
|
+
constructor(options?: ExtractorOptions);
|
|
32
|
+
extract(url: string): Promise<ExtractedContent>;
|
|
33
|
+
private fetchHtml;
|
|
34
|
+
extractFromHtml(html: string, url: string): Promise<ExtractedContent>;
|
|
35
|
+
extractBatch(urls: string[]): Promise<ExtractedContent[]>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/deep/extractor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,MAAM,WAAW,gBAAgB;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACnC;AA8GD,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,iBAAiB,CAAsB;gBAEnC,OAAO,CAAC,EAAE,gBAAgB;IAShC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAkCvC,SAAS;IAyBjB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIrE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CASlE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/deep/extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content extraction: Defuddle (linkedom) → Obscura fallback
|
|
3
|
+
*/
|
|
4
|
+
import { parseHTML } from 'linkedom';
|
|
5
|
+
import { Defuddle } from 'defuddle/node';
|
|
6
|
+
import { execFile } from 'child_process';
|
|
7
|
+
import { promisify } from 'util';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
12
|
+
const DEFAULT_CONCURRENCY = 3;
|
|
13
|
+
const MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
14
|
+
const MIN_CONTENT_LENGTH = 100;
|
|
15
|
+
const OBSCURA_THRESHOLD = 50;
|
|
16
|
+
const OBSCURA_SEARCH_PATHS = [
|
|
17
|
+
'obscura',
|
|
18
|
+
join(homedir(), '.local/bin/obscura'),
|
|
19
|
+
'/usr/local/bin/obscura',
|
|
20
|
+
];
|
|
21
|
+
let _obscuraAvailable = null;
|
|
22
|
+
async function findObscura(path) {
|
|
23
|
+
const candidates = path ? [path] : OBSCURA_SEARCH_PATHS;
|
|
24
|
+
for (const candidate of candidates) {
|
|
25
|
+
try {
|
|
26
|
+
await execFileAsync(candidate, ['--version'], { timeout: 5_000 });
|
|
27
|
+
return candidate;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
async function isObscuraAvailable(path) {
|
|
36
|
+
if (_obscuraAvailable !== null && !path)
|
|
37
|
+
return _obscuraAvailable;
|
|
38
|
+
const found = await findObscura(path);
|
|
39
|
+
const available = found !== null;
|
|
40
|
+
if (!path)
|
|
41
|
+
_obscuraAvailable = available;
|
|
42
|
+
return available;
|
|
43
|
+
}
|
|
44
|
+
async function defuddleExtract(html, url) {
|
|
45
|
+
try {
|
|
46
|
+
const { document } = parseHTML(html);
|
|
47
|
+
const result = await Defuddle(document, url, {
|
|
48
|
+
markdown: true,
|
|
49
|
+
useAsync: false,
|
|
50
|
+
});
|
|
51
|
+
const content = (result.content || '').trim();
|
|
52
|
+
if (!content) {
|
|
53
|
+
return {
|
|
54
|
+
title: result.title || '',
|
|
55
|
+
content: '',
|
|
56
|
+
excerpt: result.description || '',
|
|
57
|
+
url,
|
|
58
|
+
byline: result.author || undefined,
|
|
59
|
+
siteName: result.site || undefined,
|
|
60
|
+
length: 0,
|
|
61
|
+
extractedAt: Date.now(),
|
|
62
|
+
method: 'defuddle',
|
|
63
|
+
error: 'Defuddle could not extract content',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
title: result.title || '',
|
|
68
|
+
content,
|
|
69
|
+
excerpt: result.description || '',
|
|
70
|
+
url,
|
|
71
|
+
byline: result.author || undefined,
|
|
72
|
+
siteName: result.site || undefined,
|
|
73
|
+
length: result.wordCount || content.length,
|
|
74
|
+
extractedAt: Date.now(),
|
|
75
|
+
method: 'defuddle',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
title: '',
|
|
81
|
+
content: '',
|
|
82
|
+
excerpt: '',
|
|
83
|
+
url,
|
|
84
|
+
length: 0,
|
|
85
|
+
extractedAt: Date.now(),
|
|
86
|
+
method: 'defuddle',
|
|
87
|
+
error: error instanceof Error ? error.message : 'Defuddle parsing failed',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function obscuraExtract(url, options) {
|
|
92
|
+
const obscuraBin = await findObscura(options.obscuraPath);
|
|
93
|
+
if (!obscuraBin)
|
|
94
|
+
return null;
|
|
95
|
+
try {
|
|
96
|
+
const dumpFormat = options.dumpFormat ?? 'html';
|
|
97
|
+
const timeoutSec = Math.ceil(options.timeoutMs / 1000);
|
|
98
|
+
const { stdout } = await execFileAsync(obscuraBin, ['fetch', url, '--dump', dumpFormat, '--timeout', String(timeoutSec)], { timeout: options.timeoutMs + 5_000, maxBuffer: 10 * 1024 * 1024 });
|
|
99
|
+
if (!stdout || !stdout.trim())
|
|
100
|
+
return null;
|
|
101
|
+
if (dumpFormat === 'markdown') {
|
|
102
|
+
return {
|
|
103
|
+
title: '',
|
|
104
|
+
content: stdout.trim(),
|
|
105
|
+
excerpt: '',
|
|
106
|
+
url,
|
|
107
|
+
length: stdout.trim().length,
|
|
108
|
+
extractedAt: Date.now(),
|
|
109
|
+
method: 'obscura',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const html = stdout.trim();
|
|
113
|
+
const result = await defuddleExtract(html, url);
|
|
114
|
+
result.method = 'obscura';
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export class ContentExtractor {
|
|
122
|
+
timeoutMs;
|
|
123
|
+
concurrency;
|
|
124
|
+
maxResponseBytes;
|
|
125
|
+
useObscura;
|
|
126
|
+
obscuraPath;
|
|
127
|
+
obscuraDumpFormat;
|
|
128
|
+
constructor(options) {
|
|
129
|
+
this.timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
130
|
+
this.concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;
|
|
131
|
+
this.maxResponseBytes = options?.maxResponseBytes ?? MAX_RESPONSE_BYTES;
|
|
132
|
+
this.useObscura = options?.obscura ?? false;
|
|
133
|
+
this.obscuraPath = options?.obscuraPath;
|
|
134
|
+
this.obscuraDumpFormat = options?.obscuraDumpFormat ?? 'html';
|
|
135
|
+
}
|
|
136
|
+
async extract(url) {
|
|
137
|
+
try {
|
|
138
|
+
const html = await this.fetchHtml(url);
|
|
139
|
+
const result = await defuddleExtract(html, url);
|
|
140
|
+
if (result.content.length >= MIN_CONTENT_LENGTH)
|
|
141
|
+
return result;
|
|
142
|
+
// Defuddle insufficient → Obscura fallback
|
|
143
|
+
if (this.useObscura && result.content.length < OBSCURA_THRESHOLD) {
|
|
144
|
+
const obsResult = await obscuraExtract(url, {
|
|
145
|
+
timeoutMs: this.timeoutMs,
|
|
146
|
+
obscuraPath: this.obscuraPath,
|
|
147
|
+
dumpFormat: this.obscuraDumpFormat,
|
|
148
|
+
});
|
|
149
|
+
if (obsResult && obsResult.content.length > result.content.length)
|
|
150
|
+
return obsResult;
|
|
151
|
+
}
|
|
152
|
+
if (result.content.length < MIN_CONTENT_LENGTH && !result.error) {
|
|
153
|
+
result.error = 'Extracted content too short';
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
return {
|
|
159
|
+
title: '',
|
|
160
|
+
content: '',
|
|
161
|
+
excerpt: '',
|
|
162
|
+
url,
|
|
163
|
+
length: 0,
|
|
164
|
+
extractedAt: Date.now(),
|
|
165
|
+
error: error instanceof Error ? error.message : String(error),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async fetchHtml(url) {
|
|
170
|
+
const response = await fetch(url, {
|
|
171
|
+
headers: {
|
|
172
|
+
'User-Agent': 'Mozilla/5.0 (compatible; SxngDeepSearch/1.0)',
|
|
173
|
+
'Accept': 'text/html,application/xhtml+xml',
|
|
174
|
+
},
|
|
175
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
176
|
+
});
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
179
|
+
}
|
|
180
|
+
const contentLength = response.headers.get('content-length');
|
|
181
|
+
if (contentLength && parseInt(contentLength, 10) > this.maxResponseBytes) {
|
|
182
|
+
throw new Error(`Response too large: ${contentLength} bytes (max ${this.maxResponseBytes})`);
|
|
183
|
+
}
|
|
184
|
+
const html = await response.text();
|
|
185
|
+
if (html.length > this.maxResponseBytes) {
|
|
186
|
+
throw new Error(`Response too large: ${html.length} bytes (max ${this.maxResponseBytes})`);
|
|
187
|
+
}
|
|
188
|
+
return html;
|
|
189
|
+
}
|
|
190
|
+
async extractFromHtml(html, url) {
|
|
191
|
+
return defuddleExtract(html, url);
|
|
192
|
+
}
|
|
193
|
+
async extractBatch(urls) {
|
|
194
|
+
const results = [];
|
|
195
|
+
for (let i = 0; i < urls.length; i += this.concurrency) {
|
|
196
|
+
const batch = urls.slice(i, i + this.concurrency);
|
|
197
|
+
const batchResults = await Promise.all(batch.map(u => this.extract(u)));
|
|
198
|
+
results.push(...batchResults);
|
|
199
|
+
}
|
|
200
|
+
return results;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity-centric knowledge graph using graphology
|
|
3
|
+
*
|
|
4
|
+
* The graph stores entities and their relationships.
|
|
5
|
+
* Search results are stored as lightweight metadata nodes (title, url, rank)
|
|
6
|
+
* connected to entities via "mentions" edges.
|
|
7
|
+
*
|
|
8
|
+
* Entity extraction is done by the Agent (LLM), not by the CLI.
|
|
9
|
+
* The CLI only stores what the Agent sends via graph-add.
|
|
10
|
+
*/
|
|
11
|
+
import { DirectedGraph } from 'graphology';
|
|
12
|
+
/** Semantic edge relation types */
|
|
13
|
+
export declare const EDGE_RELATIONS: {
|
|
14
|
+
readonly yields: "yields";
|
|
15
|
+
readonly belongs_to: "belongs_to";
|
|
16
|
+
readonly mentions: "mentions";
|
|
17
|
+
readonly alternative_to: "alternative_to";
|
|
18
|
+
readonly depends_on: "depends_on";
|
|
19
|
+
readonly co_occurs_with: "co_occurs_with";
|
|
20
|
+
readonly mentioned_in: "mentioned_in";
|
|
21
|
+
readonly includes: "includes";
|
|
22
|
+
};
|
|
23
|
+
export type PathType = 'composition_chain' | 'conjunction' | 'augmented_chain' | 'community_core_path' | 'dual_core_bridge';
|
|
24
|
+
export interface GraphNodeAttrs {
|
|
25
|
+
type: 'entity' | 'result' | 'query' | 'domain' | 'path';
|
|
26
|
+
label: string;
|
|
27
|
+
entityType?: string;
|
|
28
|
+
score?: number;
|
|
29
|
+
reasoningPaths?: string[];
|
|
30
|
+
sourceRounds?: number[];
|
|
31
|
+
frequency?: number;
|
|
32
|
+
obfuscatedLabel?: string;
|
|
33
|
+
url?: string;
|
|
34
|
+
rank?: number;
|
|
35
|
+
title?: string;
|
|
36
|
+
query?: string;
|
|
37
|
+
round?: number;
|
|
38
|
+
domain?: string;
|
|
39
|
+
pathType?: PathType;
|
|
40
|
+
hops?: number;
|
|
41
|
+
entities?: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface GraphEdgeAttrs {
|
|
44
|
+
relation: string;
|
|
45
|
+
weight: number;
|
|
46
|
+
}
|
|
47
|
+
/** Create an empty entity-centric knowledge graph */
|
|
48
|
+
export declare function createGraph(): DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>;
|
|
49
|
+
/** Generate a node ID for an entity */
|
|
50
|
+
export declare function entityId(label: string): string;
|
|
51
|
+
/** Generate a node ID for a result */
|
|
52
|
+
export declare function resultId(url: string): string;
|
|
53
|
+
/** Generate a node ID for a query */
|
|
54
|
+
export declare function queryId(query: string): string;
|
|
55
|
+
/** Generate a node ID for a domain */
|
|
56
|
+
export declare function domainId(domain: string): string;
|
|
57
|
+
/** Generate the next path node ID for a given path type.
|
|
58
|
+
* Scans existing graph nodes to find the current max counter. */
|
|
59
|
+
export declare function nextPathId(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, pathType: PathType): string;
|
|
60
|
+
/** Auto-build structural edges: query→result→domain */
|
|
61
|
+
export declare function buildStructuralEdges(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, query: string, results: Array<{
|
|
62
|
+
url: string;
|
|
63
|
+
title: string;
|
|
64
|
+
rank?: number;
|
|
65
|
+
}>, round?: number): void;
|
|
66
|
+
export declare function bfsSubgraph(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>, seeds: string[], depth?: number): DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>;
|
|
67
|
+
export declare function serializeGraph(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>): object;
|
|
68
|
+
export declare function deserializeGraph(data: any): DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>;
|
|
69
|
+
export declare function graphStats(graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>): {
|
|
70
|
+
nodes: number;
|
|
71
|
+
edges: number;
|
|
72
|
+
entities: number;
|
|
73
|
+
results: number;
|
|
74
|
+
queries: number;
|
|
75
|
+
domains: number;
|
|
76
|
+
paths: number;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/deep/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/deep/graph.ts"],"names":[],"mappings":"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"}
|