sxng-cli 1.1.7 → 1.1.9
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 +2 -2
- package/dist/commands/graph-add.d.ts.sync-conflict-20260629-232900-2SGIW5T.map +1 -0
- package/dist/commands/graph-add.js +3 -3
- package/dist/commands/graph-add.js.map +1 -1
- 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/commands/graph-obfuscate.js +2 -2
- package/dist/commands/graph-obfuscate.js.map +1 -1
- package/dist/commands/query-graph.d.ts.map +1 -1
- package/dist/commands/query-graph.js +3 -3
- package/dist/commands/query-graph.js.map +1 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +2 -3
- package/dist/commands/session.js.map +1 -1
- 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 +1 -1
- package/dist/deep/session.d.ts.map +1 -1
- package/dist/deep/session.d.ts.sync-conflict-20260629-232921-2SGIW5T.map +1 -0
- package/dist/deep/session.js +4 -5
- package/dist/deep/session.js.map +1 -1
- 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,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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"}
|
|
@@ -0,0 +1,194 @@
|
|
|
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 const EDGE_RELATIONS = {
|
|
14
|
+
yields: 'yields', // query → result
|
|
15
|
+
belongs_to: 'belongs_to', // result → domain
|
|
16
|
+
mentions: 'mentions', // result → entity
|
|
17
|
+
alternative_to: 'alternative_to', // entity ↔ entity
|
|
18
|
+
depends_on: 'depends_on', // entity → entity
|
|
19
|
+
co_occurs_with: 'co_occurs_with', // entity ↔ entity
|
|
20
|
+
mentioned_in: 'mentioned_in', // entity → result
|
|
21
|
+
includes: 'includes', // path → entity
|
|
22
|
+
};
|
|
23
|
+
function generateId(prefix, value) {
|
|
24
|
+
return `${prefix}:${value.toLowerCase().replace(/[^\w]+/g, '_').slice(0, 60)}`;
|
|
25
|
+
}
|
|
26
|
+
/** Create an empty entity-centric knowledge graph */
|
|
27
|
+
export function createGraph() {
|
|
28
|
+
return new DirectedGraph();
|
|
29
|
+
}
|
|
30
|
+
/** Generate a node ID for an entity */
|
|
31
|
+
export function entityId(label) {
|
|
32
|
+
return generateId('e', label);
|
|
33
|
+
}
|
|
34
|
+
/** Generate a node ID for a result */
|
|
35
|
+
export function resultId(url) {
|
|
36
|
+
return generateId('r', url);
|
|
37
|
+
}
|
|
38
|
+
/** Generate a node ID for a query */
|
|
39
|
+
export function queryId(query) {
|
|
40
|
+
return generateId('q', query);
|
|
41
|
+
}
|
|
42
|
+
/** Generate a node ID for a domain */
|
|
43
|
+
export function domainId(domain) {
|
|
44
|
+
return generateId('d', domain);
|
|
45
|
+
}
|
|
46
|
+
/** Map from PathType to ID prefix */
|
|
47
|
+
const PATH_TYPE_PREFIX = {
|
|
48
|
+
composition_chain: 'chain',
|
|
49
|
+
conjunction: 'conj',
|
|
50
|
+
augmented_chain: 'aug',
|
|
51
|
+
community_core_path: 'core',
|
|
52
|
+
dual_core_bridge: 'bridge',
|
|
53
|
+
};
|
|
54
|
+
/** Generate the next path node ID for a given path type.
|
|
55
|
+
* Scans existing graph nodes to find the current max counter. */
|
|
56
|
+
export function nextPathId(graph, pathType) {
|
|
57
|
+
const prefix = PATH_TYPE_PREFIX[pathType];
|
|
58
|
+
let maxCounter = 0;
|
|
59
|
+
graph.forEachNode((node, attrs) => {
|
|
60
|
+
if (attrs.type === 'path' && attrs.pathType === pathType) {
|
|
61
|
+
// Extract counter from node ID: p:<prefix>_NNN
|
|
62
|
+
const match = node.match(new RegExp(`^p:${prefix}_(\\d+)$`));
|
|
63
|
+
if (match) {
|
|
64
|
+
const counter = parseInt(match[1], 10);
|
|
65
|
+
if (counter > maxCounter)
|
|
66
|
+
maxCounter = counter;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const next = maxCounter + 1;
|
|
71
|
+
return `p:${prefix}_${String(next).padStart(3, '0')}`;
|
|
72
|
+
}
|
|
73
|
+
/** Extract domain from URL */
|
|
74
|
+
function extractDomain(url) {
|
|
75
|
+
try {
|
|
76
|
+
return new URL(url).hostname;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return url;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Auto-build structural edges: query→result→domain */
|
|
83
|
+
export function buildStructuralEdges(graph, query, results, round) {
|
|
84
|
+
const qId = queryId(query);
|
|
85
|
+
// Ensure query node exists
|
|
86
|
+
if (!graph.hasNode(qId)) {
|
|
87
|
+
graph.mergeNode(qId, {
|
|
88
|
+
type: 'query',
|
|
89
|
+
label: query,
|
|
90
|
+
query,
|
|
91
|
+
round,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
for (let i = 0; i < results.length; i++) {
|
|
95
|
+
const r = results[i];
|
|
96
|
+
const rId = resultId(r.url);
|
|
97
|
+
// Ensure result node exists
|
|
98
|
+
if (!graph.hasNode(rId)) {
|
|
99
|
+
graph.mergeNode(rId, {
|
|
100
|
+
type: 'result',
|
|
101
|
+
label: r.title,
|
|
102
|
+
url: r.url,
|
|
103
|
+
title: r.title,
|
|
104
|
+
rank: r.rank ?? i + 1,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// query→result edge
|
|
108
|
+
if (!graph.hasEdge(qId, rId)) {
|
|
109
|
+
graph.addEdge(qId, rId, {
|
|
110
|
+
relation: 'yields',
|
|
111
|
+
weight: 1 / (i + 1),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// domain node and result→domain edge
|
|
115
|
+
const domain = extractDomain(r.url);
|
|
116
|
+
if (domain) {
|
|
117
|
+
const dId = domainId(domain);
|
|
118
|
+
if (!graph.hasNode(dId)) {
|
|
119
|
+
graph.mergeNode(dId, {
|
|
120
|
+
type: 'domain',
|
|
121
|
+
label: domain,
|
|
122
|
+
domain,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (!graph.hasEdge(rId, dId)) {
|
|
126
|
+
graph.addEdge(rId, dId, {
|
|
127
|
+
relation: 'belongs_to',
|
|
128
|
+
weight: 1,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export function bfsSubgraph(graph, seeds, depth = 2) {
|
|
135
|
+
const visited = new Set();
|
|
136
|
+
const queue = seeds
|
|
137
|
+
.filter(id => graph.hasNode(id))
|
|
138
|
+
.map(id => ({ id, depth: 0 }));
|
|
139
|
+
while (queue.length > 0) {
|
|
140
|
+
const { id, depth: d } = queue.shift();
|
|
141
|
+
if (d > depth || visited.has(id))
|
|
142
|
+
continue;
|
|
143
|
+
visited.add(id);
|
|
144
|
+
graph.forEachNeighbor(id, (neighbor) => {
|
|
145
|
+
if (!visited.has(neighbor)) {
|
|
146
|
+
queue.push({ id: neighbor, depth: d + 1 });
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const subgraph = new DirectedGraph();
|
|
151
|
+
for (const nodeId of visited) {
|
|
152
|
+
const attrs = graph.getNodeAttributes(nodeId);
|
|
153
|
+
subgraph.mergeNode(nodeId, attrs);
|
|
154
|
+
}
|
|
155
|
+
graph.forEachEdge((edge, attrs, source, target) => {
|
|
156
|
+
if (visited.has(source) && visited.has(target)) {
|
|
157
|
+
subgraph.mergeEdge(source, target, attrs);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return subgraph;
|
|
161
|
+
}
|
|
162
|
+
export function serializeGraph(graph) {
|
|
163
|
+
return graph.export();
|
|
164
|
+
}
|
|
165
|
+
export function deserializeGraph(data) {
|
|
166
|
+
const graph = new DirectedGraph();
|
|
167
|
+
graph.import(data);
|
|
168
|
+
return graph;
|
|
169
|
+
}
|
|
170
|
+
export function graphStats(graph) {
|
|
171
|
+
let entities = 0, results = 0, queries = 0, domains = 0, paths = 0;
|
|
172
|
+
graph.forEachNode((node, attrs) => {
|
|
173
|
+
if (attrs.type === 'entity')
|
|
174
|
+
entities++;
|
|
175
|
+
else if (attrs.type === 'result')
|
|
176
|
+
results++;
|
|
177
|
+
else if (attrs.type === 'query')
|
|
178
|
+
queries++;
|
|
179
|
+
else if (attrs.type === 'domain')
|
|
180
|
+
domains++;
|
|
181
|
+
else if (attrs.type === 'path')
|
|
182
|
+
paths++;
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
nodes: graph.order,
|
|
186
|
+
edges: graph.size,
|
|
187
|
+
entities,
|
|
188
|
+
results,
|
|
189
|
+
queries,
|
|
190
|
+
domains,
|
|
191
|
+
paths,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session management for multi-round search accumulation
|
|
3
|
+
*
|
|
4
|
+
* A session directory contains:
|
|
5
|
+
* - results.json: Accumulated search result pool (deduped by URL)
|
|
6
|
+
* - graph.json: graphology knowledge graph (structural + semantic layers)
|
|
7
|
+
*/
|
|
8
|
+
import { DirectedGraph } from 'graphology';
|
|
9
|
+
import { GraphNodeAttrs, GraphEdgeAttrs } from './graph.js';
|
|
10
|
+
export interface SessionResult {
|
|
11
|
+
url: string;
|
|
12
|
+
title: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
engine?: string;
|
|
15
|
+
category?: string;
|
|
16
|
+
score?: number;
|
|
17
|
+
publishedDate?: string;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface SessionResultsFile {
|
|
21
|
+
status: 'ok';
|
|
22
|
+
data: {
|
|
23
|
+
results: SessionResult[];
|
|
24
|
+
rounds: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Resolve session path. Supports:
|
|
28
|
+
* - "new": auto-create under default root with unique name
|
|
29
|
+
* - pure name (no separators): resolve to ~/sxng-cli/sessions/<name>
|
|
30
|
+
* - full path: return as-is
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveSessionPath(sessionValue: string): string;
|
|
33
|
+
/** Ensure session directory exists and write initial meta */
|
|
34
|
+
export declare function initSessionDir(sessionDir: string, owner?: string, description?: string, query?: string): void;
|
|
35
|
+
/** Load accumulated results from session, or return empty */
|
|
36
|
+
export declare function loadSessionResults(sessionDir: string): SessionResult[];
|
|
37
|
+
/** Append new results to session results (dedup by URL) */
|
|
38
|
+
export declare function appendSessionResults(sessionDir: string, newResults: SessionResult[]): {
|
|
39
|
+
added: number;
|
|
40
|
+
total: number;
|
|
41
|
+
};
|
|
42
|
+
/** Load graph from session, or create empty */
|
|
43
|
+
export declare function loadSessionGraph(sessionDir: string): DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>;
|
|
44
|
+
/** Save graph to session */
|
|
45
|
+
export declare function saveSessionGraph(sessionDir: string, graph: DirectedGraph<GraphNodeAttrs, GraphEdgeAttrs>): void;
|
|
46
|
+
/** Update session graph with new search results (structural layer) */
|
|
47
|
+
export declare function updateSessionGraph(sessionDir: string, query: string, results: Array<{
|
|
48
|
+
url: string;
|
|
49
|
+
title: string;
|
|
50
|
+
rank?: number;
|
|
51
|
+
}>, round?: number): {
|
|
52
|
+
nodesAdded: number;
|
|
53
|
+
edgesAdded: number;
|
|
54
|
+
};
|
|
55
|
+
/** Merge extracted content into session results (update content field by URL match) */
|
|
56
|
+
export declare function mergeExtractedContent(sessionDir: string, extracted: Array<{
|
|
57
|
+
url: string;
|
|
58
|
+
content: string;
|
|
59
|
+
title?: string;
|
|
60
|
+
excerpt?: string;
|
|
61
|
+
byline?: string;
|
|
62
|
+
siteName?: string;
|
|
63
|
+
length?: number;
|
|
64
|
+
error?: string;
|
|
65
|
+
}>): {
|
|
66
|
+
updated: number;
|
|
67
|
+
total: number;
|
|
68
|
+
};
|
|
69
|
+
/** Get current round number from results file */
|
|
70
|
+
export declare function loadSessionRounds(sessionDir: string): number;
|
|
71
|
+
//# sourceMappingURL=session.d.ts.map
|
package/dist/deep/session.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface SessionResultsFile {
|
|
|
27
27
|
}
|
|
28
28
|
/** Resolve session path. Supports:
|
|
29
29
|
* - "new": auto-create under default root with unique name
|
|
30
|
-
* - pure name (no separators): resolve to
|
|
30
|
+
* - pure name (no separators): resolve to default session root
|
|
31
31
|
* - full path: return as-is
|
|
32
32
|
*/
|
|
33
33
|
export declare function resolveSessionPath(sessionValue: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/deep/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/deep/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAsE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIhI,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE;QACF,OAAO,EAAE,aAAa,EAAE,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;CACL;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAe/D;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAqB7G;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE,CActE;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiCtH;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAiBlG;AAED,4BAA4B;AAC5B,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,IAAI,CAY/G;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9E,KAAK,CAAC,EAAE,MAAM,GACf;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAY5C;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAmCvP;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAW5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/deep/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAsE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIhI,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE;QACF,OAAO,EAAE,aAAa,EAAE,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;CACL;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAe/D;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAqB7G;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE,CActE;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiCtH;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAiBlG;AAED,4BAA4B;AAC5B,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,IAAI,CAY/G;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7D,KAAK,CAAC,EAAE,MAAM,GACf;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAY5C;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAmCvP;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAW5D"}
|
package/dist/deep/session.js
CHANGED
|
@@ -7,19 +7,18 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
9
9
|
import { join } from 'path';
|
|
10
|
-
import { homedir } from 'os';
|
|
11
10
|
import { DirectedGraph } from 'graphology';
|
|
12
11
|
import { deserializeGraph, serializeGraph, graphStats, buildStructuralEdges } from './graph.js';
|
|
13
12
|
import { normalizeUrl } from './dedupe.js';
|
|
14
|
-
import { loadSessionMeta } from '../commands/session.js';
|
|
13
|
+
import { getDefaultSessionRoot, loadSessionMeta } from '../commands/session.js';
|
|
15
14
|
/** Resolve session path. Supports:
|
|
16
15
|
* - "new": auto-create under default root with unique name
|
|
17
|
-
* - pure name (no separators): resolve to
|
|
16
|
+
* - pure name (no separators): resolve to default session root
|
|
18
17
|
* - full path: return as-is
|
|
19
18
|
*/
|
|
20
19
|
export function resolveSessionPath(sessionValue) {
|
|
21
20
|
if (sessionValue === 'new') {
|
|
22
|
-
const root =
|
|
21
|
+
const root = getDefaultSessionRoot();
|
|
23
22
|
if (!existsSync(root)) {
|
|
24
23
|
mkdirSync(root, { recursive: true });
|
|
25
24
|
}
|
|
@@ -28,7 +27,7 @@ export function resolveSessionPath(sessionValue) {
|
|
|
28
27
|
}
|
|
29
28
|
// Pure name without path separators: resolve to default sessions dir
|
|
30
29
|
if (!sessionValue.includes('/') && !sessionValue.includes('\\')) {
|
|
31
|
-
const root =
|
|
30
|
+
const root = getDefaultSessionRoot();
|
|
32
31
|
return join(root, sessionValue);
|
|
33
32
|
}
|
|
34
33
|
return sessionValue;
|
package/dist/deep/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/deep/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/deep/session.ts"],"names":[],"mappings":"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"}
|