Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
63
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.d.ts
vendored
Normal file
63
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.d.ts
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Cypher statement generator for Neo4j
|
||||
*/
|
||||
import { GraphData, CypherStatement, CypherBatch } from './types.js';
|
||||
export declare class CypherGenerator {
|
||||
/**
|
||||
* Generate Cypher statements from graph data
|
||||
*/
|
||||
generate(data: GraphData): CypherBatch;
|
||||
/**
|
||||
* Generate CREATE statement for a node
|
||||
*/
|
||||
private generateNodeStatement;
|
||||
/**
|
||||
* Generate CREATE statement for an edge
|
||||
*/
|
||||
private generateEdgeStatement;
|
||||
/**
|
||||
* Generate MERGE statements (upsert)
|
||||
*/
|
||||
generateMergeStatements(data: GraphData): CypherBatch;
|
||||
/**
|
||||
* Generate MERGE statement for a node
|
||||
*/
|
||||
private generateNodeMergeStatement;
|
||||
/**
|
||||
* Generate MERGE statement for an edge
|
||||
*/
|
||||
private generateEdgeMergeStatement;
|
||||
/**
|
||||
* Generate index creation statements
|
||||
*/
|
||||
generateIndexStatements(data: GraphData): CypherStatement[];
|
||||
/**
|
||||
* Generate constraint creation statements
|
||||
*/
|
||||
generateConstraintStatements(data: GraphData): CypherStatement[];
|
||||
/**
|
||||
* Generate complete setup script
|
||||
*/
|
||||
generateSetupScript(data: GraphData, options?: {
|
||||
useConstraints?: boolean;
|
||||
useIndexes?: boolean;
|
||||
useMerge?: boolean;
|
||||
}): string;
|
||||
/**
|
||||
* Format a statement for output
|
||||
*/
|
||||
private formatStatement;
|
||||
/**
|
||||
* Escape label names for Cypher
|
||||
*/
|
||||
private escapeLabel;
|
||||
/**
|
||||
* Generate batch insert with transactions
|
||||
*/
|
||||
generateBatchInsert(data: GraphData, batchSize?: number): CypherStatement[];
|
||||
}
|
||||
/**
|
||||
* Create a Cypher generator
|
||||
*/
|
||||
export declare function createCypherGenerator(): CypherGenerator;
|
||||
//# sourceMappingURL=cypher-generator.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cypher-generator.d.ts","sourceRoot":"","sources":["cypher-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,SAAS,EAGT,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAe;IAC1B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW;IA+BtC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,uBAAuB,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW;IA8BrD;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAuBlC;;OAEG;IACH,uBAAuB,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,EAAE;IAoC3D;;OAEG;IACH,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,EAAE;IAgBhE;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;QAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,GAAG,MAAM;IAkCV;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,GAAE,MAAa,GAAG,eAAe,EAAE;CAkDlF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD"}
|
||||
312
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.js
vendored
Normal file
312
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.js
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Cypher statement generator for Neo4j
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CypherGenerator = void 0;
|
||||
exports.createCypherGenerator = createCypherGenerator;
|
||||
class CypherGenerator {
|
||||
/**
|
||||
* Generate Cypher statements from graph data
|
||||
*/
|
||||
generate(data) {
|
||||
const statements = [];
|
||||
// Generate node creation statements
|
||||
for (const node of data.nodes) {
|
||||
statements.push(this.generateNodeStatement(node));
|
||||
}
|
||||
// Generate relationship creation statements
|
||||
for (const edge of data.edges) {
|
||||
statements.push(this.generateEdgeStatement(edge));
|
||||
}
|
||||
// Collect metadata
|
||||
const labels = new Set();
|
||||
const relationshipTypes = new Set();
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
data.edges.forEach(edge => relationshipTypes.add(edge.type));
|
||||
return {
|
||||
statements,
|
||||
metadata: {
|
||||
total_nodes: data.nodes.length,
|
||||
total_relationships: data.edges.length,
|
||||
labels: Array.from(labels),
|
||||
relationship_types: Array.from(relationshipTypes)
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate CREATE statement for a node
|
||||
*/
|
||||
generateNodeStatement(node) {
|
||||
const labels = node.labels.map(l => `:${this.escapeLabel(l)}`).join('');
|
||||
const propsVar = 'props';
|
||||
return {
|
||||
query: `CREATE (n${labels} $${propsVar})`,
|
||||
parameters: {
|
||||
[propsVar]: {
|
||||
id: node.id,
|
||||
...node.properties,
|
||||
...(node.embedding ? { embedding: node.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate CREATE statement for an edge
|
||||
*/
|
||||
generateEdgeStatement(edge) {
|
||||
const type = this.escapeLabel(edge.type);
|
||||
const propsVar = 'props';
|
||||
return {
|
||||
query: `
|
||||
MATCH (source { id: $sourceId })
|
||||
MATCH (target { id: $targetId })
|
||||
CREATE (source)-[r:${type} $${propsVar}]->(target)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
sourceId: edge.source,
|
||||
targetId: edge.target,
|
||||
[propsVar]: {
|
||||
id: edge.id,
|
||||
...edge.properties,
|
||||
...(edge.embedding ? { embedding: edge.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate MERGE statements (upsert)
|
||||
*/
|
||||
generateMergeStatements(data) {
|
||||
const statements = [];
|
||||
// Generate node merge statements
|
||||
for (const node of data.nodes) {
|
||||
statements.push(this.generateNodeMergeStatement(node));
|
||||
}
|
||||
// Generate relationship merge statements
|
||||
for (const edge of data.edges) {
|
||||
statements.push(this.generateEdgeMergeStatement(edge));
|
||||
}
|
||||
const labels = new Set();
|
||||
const relationshipTypes = new Set();
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
data.edges.forEach(edge => relationshipTypes.add(edge.type));
|
||||
return {
|
||||
statements,
|
||||
metadata: {
|
||||
total_nodes: data.nodes.length,
|
||||
total_relationships: data.edges.length,
|
||||
labels: Array.from(labels),
|
||||
relationship_types: Array.from(relationshipTypes)
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate MERGE statement for a node
|
||||
*/
|
||||
generateNodeMergeStatement(node) {
|
||||
const primaryLabel = node.labels[0];
|
||||
const additionalLabels = node.labels.slice(1).map(l => `:${this.escapeLabel(l)}`).join('');
|
||||
const propsVar = 'props';
|
||||
return {
|
||||
query: `
|
||||
MERGE (n:${this.escapeLabel(primaryLabel)} { id: $id })
|
||||
SET n${additionalLabels}
|
||||
SET n += $${propsVar}
|
||||
`.trim(),
|
||||
parameters: {
|
||||
id: node.id,
|
||||
[propsVar]: {
|
||||
...node.properties,
|
||||
...(node.embedding ? { embedding: node.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate MERGE statement for an edge
|
||||
*/
|
||||
generateEdgeMergeStatement(edge) {
|
||||
const type = this.escapeLabel(edge.type);
|
||||
const propsVar = 'props';
|
||||
return {
|
||||
query: `
|
||||
MATCH (source { id: $sourceId })
|
||||
MATCH (target { id: $targetId })
|
||||
MERGE (source)-[r:${type} { id: $id }]->(target)
|
||||
SET r += $${propsVar}
|
||||
`.trim(),
|
||||
parameters: {
|
||||
sourceId: edge.source,
|
||||
targetId: edge.target,
|
||||
id: edge.id,
|
||||
[propsVar]: {
|
||||
...edge.properties,
|
||||
...(edge.embedding ? { embedding: edge.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate index creation statements
|
||||
*/
|
||||
generateIndexStatements(data) {
|
||||
const statements = [];
|
||||
const labels = new Set();
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
// Create index on id for each label
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `CREATE INDEX IF NOT EXISTS FOR (n:${this.escapeLabel(label)}) ON (n.id)`
|
||||
});
|
||||
}
|
||||
// Create vector indexes if embeddings are present
|
||||
const hasEmbeddings = data.nodes.some(node => node.embedding);
|
||||
if (hasEmbeddings) {
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `
|
||||
CREATE VECTOR INDEX IF NOT EXISTS ${this.escapeLabel(label)}_embedding
|
||||
FOR (n:${this.escapeLabel(label)})
|
||||
ON (n.embedding)
|
||||
OPTIONS {
|
||||
indexConfig: {
|
||||
\`vector.dimensions\`: ${data.nodes.find(n => n.embedding)?.embedding?.length || 1536},
|
||||
\`vector.similarity_function\`: 'cosine'
|
||||
}
|
||||
}
|
||||
`.trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
/**
|
||||
* Generate constraint creation statements
|
||||
*/
|
||||
generateConstraintStatements(data) {
|
||||
const statements = [];
|
||||
const labels = new Set();
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
// Create unique constraint on id for each label
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `CREATE CONSTRAINT IF NOT EXISTS FOR (n:${this.escapeLabel(label)}) REQUIRE n.id IS UNIQUE`
|
||||
});
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
/**
|
||||
* Generate complete setup script
|
||||
*/
|
||||
generateSetupScript(data, options) {
|
||||
const statements = [];
|
||||
// Add constraints
|
||||
if (options?.useConstraints !== false) {
|
||||
statements.push('// Create constraints');
|
||||
this.generateConstraintStatements(data).forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
statements.push('');
|
||||
}
|
||||
// Add indexes
|
||||
if (options?.useIndexes !== false) {
|
||||
statements.push('// Create indexes');
|
||||
this.generateIndexStatements(data).forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
statements.push('');
|
||||
}
|
||||
// Add data
|
||||
statements.push('// Create data');
|
||||
const batch = options?.useMerge
|
||||
? this.generateMergeStatements(data)
|
||||
: this.generate(data);
|
||||
batch.statements.forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
return statements.join('\n');
|
||||
}
|
||||
/**
|
||||
* Format a statement for output
|
||||
*/
|
||||
formatStatement(stmt) {
|
||||
if (!stmt.parameters || Object.keys(stmt.parameters).length === 0) {
|
||||
return stmt.query;
|
||||
}
|
||||
let formatted = stmt.query;
|
||||
for (const [key, value] of Object.entries(stmt.parameters)) {
|
||||
const jsonValue = JSON.stringify(value);
|
||||
formatted = formatted.replace(new RegExp(`\\$${key}\\b`, 'g'), jsonValue);
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
/**
|
||||
* Escape label names for Cypher
|
||||
*/
|
||||
escapeLabel(label) {
|
||||
// Remove special characters and use backticks if needed
|
||||
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(label)) {
|
||||
return label;
|
||||
}
|
||||
return `\`${label.replace(/`/g, '``')}\``;
|
||||
}
|
||||
/**
|
||||
* Generate batch insert with transactions
|
||||
*/
|
||||
generateBatchInsert(data, batchSize = 1000) {
|
||||
const statements = [];
|
||||
// Batch nodes
|
||||
for (let i = 0; i < data.nodes.length; i += batchSize) {
|
||||
const batch = data.nodes.slice(i, i + batchSize);
|
||||
statements.push({
|
||||
query: `
|
||||
UNWIND $nodes AS node
|
||||
CREATE (n)
|
||||
SET n = node.properties
|
||||
SET n.id = node.id
|
||||
WITH n, node.labels AS labels
|
||||
CALL apoc.create.addLabels(n, labels) YIELD node AS labeled
|
||||
RETURN count(labeled)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
nodes: batch.map(node => ({
|
||||
id: node.id,
|
||||
labels: node.labels,
|
||||
properties: node.properties
|
||||
}))
|
||||
}
|
||||
});
|
||||
}
|
||||
// Batch edges
|
||||
for (let i = 0; i < data.edges.length; i += batchSize) {
|
||||
const batch = data.edges.slice(i, i + batchSize);
|
||||
statements.push({
|
||||
query: `
|
||||
UNWIND $edges AS edge
|
||||
MATCH (source { id: edge.source })
|
||||
MATCH (target { id: edge.target })
|
||||
CALL apoc.create.relationship(source, edge.type, edge.properties, target) YIELD rel
|
||||
RETURN count(rel)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
edges: batch.map(edge => ({
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
type: edge.type,
|
||||
properties: edge.properties
|
||||
}))
|
||||
}
|
||||
});
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
exports.CypherGenerator = CypherGenerator;
|
||||
/**
|
||||
* Create a Cypher generator
|
||||
*/
|
||||
function createCypherGenerator() {
|
||||
return new CypherGenerator();
|
||||
}
|
||||
//# sourceMappingURL=cypher-generator.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
362
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.ts
vendored
Normal file
362
vendor/ruvector/npm/packages/graph-data-generator/src/cypher-generator.ts
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* Cypher statement generator for Neo4j
|
||||
*/
|
||||
|
||||
import {
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
CypherStatement,
|
||||
CypherBatch
|
||||
} from './types.js';
|
||||
|
||||
export class CypherGenerator {
|
||||
/**
|
||||
* Generate Cypher statements from graph data
|
||||
*/
|
||||
generate(data: GraphData): CypherBatch {
|
||||
const statements: CypherStatement[] = [];
|
||||
|
||||
// Generate node creation statements
|
||||
for (const node of data.nodes) {
|
||||
statements.push(this.generateNodeStatement(node));
|
||||
}
|
||||
|
||||
// Generate relationship creation statements
|
||||
for (const edge of data.edges) {
|
||||
statements.push(this.generateEdgeStatement(edge));
|
||||
}
|
||||
|
||||
// Collect metadata
|
||||
const labels = new Set<string>();
|
||||
const relationshipTypes = new Set<string>();
|
||||
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
data.edges.forEach(edge => relationshipTypes.add(edge.type));
|
||||
|
||||
return {
|
||||
statements,
|
||||
metadata: {
|
||||
total_nodes: data.nodes.length,
|
||||
total_relationships: data.edges.length,
|
||||
labels: Array.from(labels),
|
||||
relationship_types: Array.from(relationshipTypes)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CREATE statement for a node
|
||||
*/
|
||||
private generateNodeStatement(node: GraphNode): CypherStatement {
|
||||
const labels = node.labels.map(l => `:${this.escapeLabel(l)}`).join('');
|
||||
const propsVar = 'props';
|
||||
|
||||
return {
|
||||
query: `CREATE (n${labels} $${propsVar})`,
|
||||
parameters: {
|
||||
[propsVar]: {
|
||||
id: node.id,
|
||||
...node.properties,
|
||||
...(node.embedding ? { embedding: node.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CREATE statement for an edge
|
||||
*/
|
||||
private generateEdgeStatement(edge: GraphEdge): CypherStatement {
|
||||
const type = this.escapeLabel(edge.type);
|
||||
const propsVar = 'props';
|
||||
|
||||
return {
|
||||
query: `
|
||||
MATCH (source { id: $sourceId })
|
||||
MATCH (target { id: $targetId })
|
||||
CREATE (source)-[r:${type} $${propsVar}]->(target)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
sourceId: edge.source,
|
||||
targetId: edge.target,
|
||||
[propsVar]: {
|
||||
id: edge.id,
|
||||
...edge.properties,
|
||||
...(edge.embedding ? { embedding: edge.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate MERGE statements (upsert)
|
||||
*/
|
||||
generateMergeStatements(data: GraphData): CypherBatch {
|
||||
const statements: CypherStatement[] = [];
|
||||
|
||||
// Generate node merge statements
|
||||
for (const node of data.nodes) {
|
||||
statements.push(this.generateNodeMergeStatement(node));
|
||||
}
|
||||
|
||||
// Generate relationship merge statements
|
||||
for (const edge of data.edges) {
|
||||
statements.push(this.generateEdgeMergeStatement(edge));
|
||||
}
|
||||
|
||||
const labels = new Set<string>();
|
||||
const relationshipTypes = new Set<string>();
|
||||
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
data.edges.forEach(edge => relationshipTypes.add(edge.type));
|
||||
|
||||
return {
|
||||
statements,
|
||||
metadata: {
|
||||
total_nodes: data.nodes.length,
|
||||
total_relationships: data.edges.length,
|
||||
labels: Array.from(labels),
|
||||
relationship_types: Array.from(relationshipTypes)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate MERGE statement for a node
|
||||
*/
|
||||
private generateNodeMergeStatement(node: GraphNode): CypherStatement {
|
||||
const primaryLabel = node.labels[0];
|
||||
const additionalLabels = node.labels.slice(1).map(l => `:${this.escapeLabel(l)}`).join('');
|
||||
const propsVar = 'props';
|
||||
|
||||
return {
|
||||
query: `
|
||||
MERGE (n:${this.escapeLabel(primaryLabel)} { id: $id })
|
||||
SET n${additionalLabels}
|
||||
SET n += $${propsVar}
|
||||
`.trim(),
|
||||
parameters: {
|
||||
id: node.id,
|
||||
[propsVar]: {
|
||||
...node.properties,
|
||||
...(node.embedding ? { embedding: node.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate MERGE statement for an edge
|
||||
*/
|
||||
private generateEdgeMergeStatement(edge: GraphEdge): CypherStatement {
|
||||
const type = this.escapeLabel(edge.type);
|
||||
const propsVar = 'props';
|
||||
|
||||
return {
|
||||
query: `
|
||||
MATCH (source { id: $sourceId })
|
||||
MATCH (target { id: $targetId })
|
||||
MERGE (source)-[r:${type} { id: $id }]->(target)
|
||||
SET r += $${propsVar}
|
||||
`.trim(),
|
||||
parameters: {
|
||||
sourceId: edge.source,
|
||||
targetId: edge.target,
|
||||
id: edge.id,
|
||||
[propsVar]: {
|
||||
...edge.properties,
|
||||
...(edge.embedding ? { embedding: edge.embedding } : {})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate index creation statements
|
||||
*/
|
||||
generateIndexStatements(data: GraphData): CypherStatement[] {
|
||||
const statements: CypherStatement[] = [];
|
||||
const labels = new Set<string>();
|
||||
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
|
||||
// Create index on id for each label
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `CREATE INDEX IF NOT EXISTS FOR (n:${this.escapeLabel(label)}) ON (n.id)`
|
||||
});
|
||||
}
|
||||
|
||||
// Create vector indexes if embeddings are present
|
||||
const hasEmbeddings = data.nodes.some(node => node.embedding);
|
||||
if (hasEmbeddings) {
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `
|
||||
CREATE VECTOR INDEX IF NOT EXISTS ${this.escapeLabel(label)}_embedding
|
||||
FOR (n:${this.escapeLabel(label)})
|
||||
ON (n.embedding)
|
||||
OPTIONS {
|
||||
indexConfig: {
|
||||
\`vector.dimensions\`: ${data.nodes.find(n => n.embedding)?.embedding?.length || 1536},
|
||||
\`vector.similarity_function\`: 'cosine'
|
||||
}
|
||||
}
|
||||
`.trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate constraint creation statements
|
||||
*/
|
||||
generateConstraintStatements(data: GraphData): CypherStatement[] {
|
||||
const statements: CypherStatement[] = [];
|
||||
const labels = new Set<string>();
|
||||
|
||||
data.nodes.forEach(node => node.labels.forEach(label => labels.add(label)));
|
||||
|
||||
// Create unique constraint on id for each label
|
||||
for (const label of labels) {
|
||||
statements.push({
|
||||
query: `CREATE CONSTRAINT IF NOT EXISTS FOR (n:${this.escapeLabel(label)}) REQUIRE n.id IS UNIQUE`
|
||||
});
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate complete setup script
|
||||
*/
|
||||
generateSetupScript(data: GraphData, options?: {
|
||||
useConstraints?: boolean;
|
||||
useIndexes?: boolean;
|
||||
useMerge?: boolean;
|
||||
}): string {
|
||||
const statements: string[] = [];
|
||||
|
||||
// Add constraints
|
||||
if (options?.useConstraints !== false) {
|
||||
statements.push('// Create constraints');
|
||||
this.generateConstraintStatements(data).forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
statements.push('');
|
||||
}
|
||||
|
||||
// Add indexes
|
||||
if (options?.useIndexes !== false) {
|
||||
statements.push('// Create indexes');
|
||||
this.generateIndexStatements(data).forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
statements.push('');
|
||||
}
|
||||
|
||||
// Add data
|
||||
statements.push('// Create data');
|
||||
const batch = options?.useMerge
|
||||
? this.generateMergeStatements(data)
|
||||
: this.generate(data);
|
||||
|
||||
batch.statements.forEach(stmt => {
|
||||
statements.push(this.formatStatement(stmt) + ';');
|
||||
});
|
||||
|
||||
return statements.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a statement for output
|
||||
*/
|
||||
private formatStatement(stmt: CypherStatement): string {
|
||||
if (!stmt.parameters || Object.keys(stmt.parameters).length === 0) {
|
||||
return stmt.query;
|
||||
}
|
||||
|
||||
let formatted = stmt.query;
|
||||
for (const [key, value] of Object.entries(stmt.parameters)) {
|
||||
const jsonValue = JSON.stringify(value);
|
||||
formatted = formatted.replace(new RegExp(`\\$${key}\\b`, 'g'), jsonValue);
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape label names for Cypher
|
||||
*/
|
||||
private escapeLabel(label: string): string {
|
||||
// Remove special characters and use backticks if needed
|
||||
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(label)) {
|
||||
return label;
|
||||
}
|
||||
return `\`${label.replace(/`/g, '``')}\``;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate batch insert with transactions
|
||||
*/
|
||||
generateBatchInsert(data: GraphData, batchSize: number = 1000): CypherStatement[] {
|
||||
const statements: CypherStatement[] = [];
|
||||
|
||||
// Batch nodes
|
||||
for (let i = 0; i < data.nodes.length; i += batchSize) {
|
||||
const batch = data.nodes.slice(i, i + batchSize);
|
||||
statements.push({
|
||||
query: `
|
||||
UNWIND $nodes AS node
|
||||
CREATE (n)
|
||||
SET n = node.properties
|
||||
SET n.id = node.id
|
||||
WITH n, node.labels AS labels
|
||||
CALL apoc.create.addLabels(n, labels) YIELD node AS labeled
|
||||
RETURN count(labeled)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
nodes: batch.map(node => ({
|
||||
id: node.id,
|
||||
labels: node.labels,
|
||||
properties: node.properties
|
||||
}))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Batch edges
|
||||
for (let i = 0; i < data.edges.length; i += batchSize) {
|
||||
const batch = data.edges.slice(i, i + batchSize);
|
||||
statements.push({
|
||||
query: `
|
||||
UNWIND $edges AS edge
|
||||
MATCH (source { id: edge.source })
|
||||
MATCH (target { id: edge.target })
|
||||
CALL apoc.create.relationship(source, edge.type, edge.properties, target) YIELD rel
|
||||
RETURN count(rel)
|
||||
`.trim(),
|
||||
parameters: {
|
||||
edges: batch.map(edge => ({
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
type: edge.type,
|
||||
properties: edge.properties
|
||||
}))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Cypher generator
|
||||
*/
|
||||
export function createCypherGenerator(): CypherGenerator {
|
||||
return new CypherGenerator();
|
||||
}
|
||||
82
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.d.ts
vendored
Normal file
82
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.d.ts
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Vector embedding enrichment for graph nodes and edges
|
||||
*/
|
||||
import { OpenRouterClient } from './openrouter-client.js';
|
||||
import { GraphData, GraphNode, EmbeddingConfig } from './types.js';
|
||||
export declare class EmbeddingEnrichment {
|
||||
private client;
|
||||
private config;
|
||||
constructor(client: OpenRouterClient, config?: Partial<EmbeddingConfig>);
|
||||
/**
|
||||
* Enrich graph data with vector embeddings
|
||||
*/
|
||||
enrichGraphData(data: GraphData): Promise<GraphData>;
|
||||
/**
|
||||
* Enrich nodes with embeddings
|
||||
*/
|
||||
private enrichNodes;
|
||||
/**
|
||||
* Enrich edges with embeddings
|
||||
*/
|
||||
private enrichEdges;
|
||||
/**
|
||||
* Generate embedding for a node
|
||||
*/
|
||||
private generateNodeEmbedding;
|
||||
/**
|
||||
* Generate embedding for an edge
|
||||
*/
|
||||
private generateEdgeEmbedding;
|
||||
/**
|
||||
* Convert node to text for embedding
|
||||
*/
|
||||
private nodeToText;
|
||||
/**
|
||||
* Convert edge to text for embedding
|
||||
*/
|
||||
private edgeToText;
|
||||
/**
|
||||
* Generate embedding using OpenRouter or local model
|
||||
*/
|
||||
private generateEmbedding;
|
||||
/**
|
||||
* Generate semantic embedding using chat model
|
||||
*/
|
||||
private generateSemanticEmbedding;
|
||||
/**
|
||||
* Generate local embedding (placeholder)
|
||||
*/
|
||||
private generateLocalEmbedding;
|
||||
/**
|
||||
* Generate random embedding (fallback)
|
||||
*/
|
||||
private generateRandomEmbedding;
|
||||
/**
|
||||
* Calculate similarity between embeddings
|
||||
*/
|
||||
calculateSimilarity(embedding1: number[], embedding2: number[], metric?: 'cosine' | 'euclidean' | 'dot'): number;
|
||||
/**
|
||||
* Calculate cosine similarity
|
||||
*/
|
||||
private cosineSimilarity;
|
||||
/**
|
||||
* Calculate Euclidean distance
|
||||
*/
|
||||
private euclideanDistance;
|
||||
/**
|
||||
* Calculate dot product
|
||||
*/
|
||||
private dotProduct;
|
||||
/**
|
||||
* Find similar nodes using embeddings
|
||||
*/
|
||||
findSimilarNodes(node: GraphNode, allNodes: GraphNode[], topK?: number, metric?: 'cosine' | 'euclidean' | 'dot'): Array<{
|
||||
node: GraphNode;
|
||||
similarity: number;
|
||||
}>;
|
||||
}
|
||||
/**
|
||||
* Create an embedding enrichment instance
|
||||
*/
|
||||
export declare function createEmbeddingEnrichment(client: OpenRouterClient, config?: Partial<EmbeddingConfig>): EmbeddingEnrichment;
|
||||
//# sourceMappingURL=embedding-enrichment.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"embedding-enrichment.d.ts","sourceRoot":"","sources":["embedding-enrichment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,SAAS,EAET,eAAe,EAEhB,MAAM,YAAY,CAAC;AAEpB,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,MAAM;IAHhB,OAAO,CAAC,MAAM,CAAkB;gBAGtB,MAAM,EAAE,gBAAgB,EAChC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAUvC;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAc1D;;OAEG;YACW,WAAW;IAgBzB;;OAEG;YACW,WAAW;IAgBzB;;OAEG;YACW,qBAAqB;IAanC;;OAEG;YACW,qBAAqB;IAanC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgBlB;;OAEG;IACH,OAAO,CAAC,UAAU;IAgBlB;;OAEG;YACW,iBAAiB;IAiB/B;;OAEG;YACW,yBAAyB;IA6CvC;;OAEG;YACW,sBAAsB;IAUpC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAW/B;;OAEG;IACH,mBAAmB,CACjB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,GAAE,QAAQ,GAAG,WAAW,GAAG,KAAgB,GAChD,MAAM;IAiBT;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,gBAAgB,CACd,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EAAE,EACrB,IAAI,GAAE,MAAW,EACjB,MAAM,GAAE,QAAQ,GAAG,WAAW,GAAG,KAAgB,GAChD,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAgBlD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,EACxB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,mBAAmB,CAErB"}
|
||||
257
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.js
vendored
Normal file
257
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.js
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Vector embedding enrichment for graph nodes and edges
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EmbeddingEnrichment = void 0;
|
||||
exports.createEmbeddingEnrichment = createEmbeddingEnrichment;
|
||||
class EmbeddingEnrichment {
|
||||
constructor(client, config = {}) {
|
||||
this.client = client;
|
||||
this.config = {
|
||||
provider: 'openrouter',
|
||||
dimensions: 1536,
|
||||
batchSize: 100,
|
||||
...config
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Enrich graph data with vector embeddings
|
||||
*/
|
||||
async enrichGraphData(data) {
|
||||
// Generate embeddings for nodes
|
||||
const enrichedNodes = await this.enrichNodes(data.nodes);
|
||||
// Generate embeddings for edges (optional)
|
||||
const enrichedEdges = await this.enrichEdges(data.edges);
|
||||
return {
|
||||
...data,
|
||||
nodes: enrichedNodes,
|
||||
edges: enrichedEdges
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Enrich nodes with embeddings
|
||||
*/
|
||||
async enrichNodes(nodes) {
|
||||
const enriched = [];
|
||||
// Process in batches
|
||||
for (let i = 0; i < nodes.length; i += this.config.batchSize) {
|
||||
const batch = nodes.slice(i, i + this.config.batchSize);
|
||||
const batchResults = await Promise.all(batch.map(node => this.generateNodeEmbedding(node)));
|
||||
enriched.push(...batchResults);
|
||||
}
|
||||
return enriched;
|
||||
}
|
||||
/**
|
||||
* Enrich edges with embeddings
|
||||
*/
|
||||
async enrichEdges(edges) {
|
||||
const enriched = [];
|
||||
// Process in batches
|
||||
for (let i = 0; i < edges.length; i += this.config.batchSize) {
|
||||
const batch = edges.slice(i, i + this.config.batchSize);
|
||||
const batchResults = await Promise.all(batch.map(edge => this.generateEdgeEmbedding(edge)));
|
||||
enriched.push(...batchResults);
|
||||
}
|
||||
return enriched;
|
||||
}
|
||||
/**
|
||||
* Generate embedding for a node
|
||||
*/
|
||||
async generateNodeEmbedding(node) {
|
||||
// Create text representation of node
|
||||
const text = this.nodeToText(node);
|
||||
// Generate embedding
|
||||
const embedding = await this.generateEmbedding(text);
|
||||
return {
|
||||
...node,
|
||||
embedding: embedding.embedding
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate embedding for an edge
|
||||
*/
|
||||
async generateEdgeEmbedding(edge) {
|
||||
// Create text representation of edge
|
||||
const text = this.edgeToText(edge);
|
||||
// Generate embedding
|
||||
const embedding = await this.generateEmbedding(text);
|
||||
return {
|
||||
...edge,
|
||||
embedding: embedding.embedding
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert node to text for embedding
|
||||
*/
|
||||
nodeToText(node) {
|
||||
const parts = [];
|
||||
// Add labels
|
||||
parts.push(`Type: ${node.labels.join(', ')}`);
|
||||
// Add properties
|
||||
for (const [key, value] of Object.entries(node.properties)) {
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
parts.push(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
return parts.join('. ');
|
||||
}
|
||||
/**
|
||||
* Convert edge to text for embedding
|
||||
*/
|
||||
edgeToText(edge) {
|
||||
const parts = [];
|
||||
// Add relationship type
|
||||
parts.push(`Relationship: ${edge.type}`);
|
||||
// Add properties
|
||||
for (const [key, value] of Object.entries(edge.properties)) {
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
parts.push(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
return parts.join('. ');
|
||||
}
|
||||
/**
|
||||
* Generate embedding using OpenRouter or local model
|
||||
*/
|
||||
async generateEmbedding(text) {
|
||||
if (this.config.provider === 'local') {
|
||||
return this.generateLocalEmbedding(text);
|
||||
}
|
||||
// Use OpenRouter with embedding-capable model
|
||||
// Note: Kimi K2 may not support embeddings, so we use a workaround
|
||||
// by generating semantic vectors through the chat API
|
||||
const embedding = await this.generateSemanticEmbedding(text);
|
||||
return {
|
||||
embedding,
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
dimensions: embedding.length
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate semantic embedding using chat model
|
||||
*/
|
||||
async generateSemanticEmbedding(text) {
|
||||
// Use the chat API to generate a semantic representation
|
||||
// This is a workaround for models without native embedding support
|
||||
const systemPrompt = `You are a semantic encoder. Convert the input text into a semantic representation by analyzing its key concepts, entities, and relationships. Output ONLY a JSON array of ${this.config.dimensions} floating point numbers between -1 and 1 representing the semantic vector.`;
|
||||
const userPrompt = `Encode this text into a ${this.config.dimensions}-dimensional semantic vector:\n\n${text}`;
|
||||
try {
|
||||
const response = await this.client.createCompletion([
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
], {
|
||||
temperature: 0.3,
|
||||
max_tokens: this.config.dimensions * 10
|
||||
});
|
||||
const content = response.choices[0]?.message?.content;
|
||||
if (!content) {
|
||||
throw new Error('No content in embedding response');
|
||||
}
|
||||
// Extract JSON array
|
||||
const match = content.match(/\[([\s\S]*?)\]/);
|
||||
if (match) {
|
||||
const embedding = JSON.parse(`[${match[1]}]`);
|
||||
// Ensure correct dimensions
|
||||
if (embedding.length !== this.config.dimensions) {
|
||||
return this.generateRandomEmbedding();
|
||||
}
|
||||
return embedding;
|
||||
}
|
||||
// Fallback to random embedding
|
||||
return this.generateRandomEmbedding();
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('Failed to generate semantic embedding, using random:', error);
|
||||
return this.generateRandomEmbedding();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generate local embedding (placeholder)
|
||||
*/
|
||||
async generateLocalEmbedding(_text) {
|
||||
// This would use a local embedding model
|
||||
// For now, return a random embedding
|
||||
return {
|
||||
embedding: this.generateRandomEmbedding(),
|
||||
model: 'local',
|
||||
dimensions: this.config.dimensions
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate random embedding (fallback)
|
||||
*/
|
||||
generateRandomEmbedding() {
|
||||
const embedding = [];
|
||||
for (let i = 0; i < this.config.dimensions; i++) {
|
||||
embedding.push((Math.random() * 2) - 1); // Random value between -1 and 1
|
||||
}
|
||||
// Normalize to unit length
|
||||
const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
||||
return embedding.map(val => val / magnitude);
|
||||
}
|
||||
/**
|
||||
* Calculate similarity between embeddings
|
||||
*/
|
||||
calculateSimilarity(embedding1, embedding2, metric = 'cosine') {
|
||||
if (embedding1.length !== embedding2.length) {
|
||||
throw new Error('Embeddings must have the same dimensions');
|
||||
}
|
||||
switch (metric) {
|
||||
case 'cosine':
|
||||
return this.cosineSimilarity(embedding1, embedding2);
|
||||
case 'euclidean':
|
||||
return this.euclideanDistance(embedding1, embedding2);
|
||||
case 'dot':
|
||||
return this.dotProduct(embedding1, embedding2);
|
||||
default:
|
||||
return this.cosineSimilarity(embedding1, embedding2);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Calculate cosine similarity
|
||||
*/
|
||||
cosineSimilarity(a, b) {
|
||||
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
|
||||
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
|
||||
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
|
||||
return dotProduct / (magnitudeA * magnitudeB);
|
||||
}
|
||||
/**
|
||||
* Calculate Euclidean distance
|
||||
*/
|
||||
euclideanDistance(a, b) {
|
||||
return Math.sqrt(a.reduce((sum, val, i) => sum + Math.pow(val - b[i], 2), 0));
|
||||
}
|
||||
/**
|
||||
* Calculate dot product
|
||||
*/
|
||||
dotProduct(a, b) {
|
||||
return a.reduce((sum, val, i) => sum + val * b[i], 0);
|
||||
}
|
||||
/**
|
||||
* Find similar nodes using embeddings
|
||||
*/
|
||||
findSimilarNodes(node, allNodes, topK = 10, metric = 'cosine') {
|
||||
if (!node.embedding) {
|
||||
throw new Error('Node does not have an embedding');
|
||||
}
|
||||
const similarities = allNodes
|
||||
.filter(n => n.id !== node.id && n.embedding)
|
||||
.map(n => ({
|
||||
node: n,
|
||||
similarity: this.calculateSimilarity(node.embedding, n.embedding, metric)
|
||||
}))
|
||||
.sort((a, b) => b.similarity - a.similarity)
|
||||
.slice(0, topK);
|
||||
return similarities;
|
||||
}
|
||||
}
|
||||
exports.EmbeddingEnrichment = EmbeddingEnrichment;
|
||||
/**
|
||||
* Create an embedding enrichment instance
|
||||
*/
|
||||
function createEmbeddingEnrichment(client, config) {
|
||||
return new EmbeddingEnrichment(client, config);
|
||||
}
|
||||
//# sourceMappingURL=embedding-enrichment.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
331
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.ts
vendored
Normal file
331
vendor/ruvector/npm/packages/graph-data-generator/src/embedding-enrichment.ts
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
* Vector embedding enrichment for graph nodes and edges
|
||||
*/
|
||||
|
||||
import { OpenRouterClient } from './openrouter-client.js';
|
||||
import {
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
EmbeddingConfig,
|
||||
EmbeddingResult
|
||||
} from './types.js';
|
||||
|
||||
export class EmbeddingEnrichment {
|
||||
private config: EmbeddingConfig;
|
||||
|
||||
constructor(
|
||||
private client: OpenRouterClient,
|
||||
config: Partial<EmbeddingConfig> = {}
|
||||
) {
|
||||
this.config = {
|
||||
provider: 'openrouter',
|
||||
dimensions: 1536,
|
||||
batchSize: 100,
|
||||
...config
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich graph data with vector embeddings
|
||||
*/
|
||||
async enrichGraphData(data: GraphData): Promise<GraphData> {
|
||||
// Generate embeddings for nodes
|
||||
const enrichedNodes = await this.enrichNodes(data.nodes);
|
||||
|
||||
// Generate embeddings for edges (optional)
|
||||
const enrichedEdges = await this.enrichEdges(data.edges);
|
||||
|
||||
return {
|
||||
...data,
|
||||
nodes: enrichedNodes,
|
||||
edges: enrichedEdges
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich nodes with embeddings
|
||||
*/
|
||||
private async enrichNodes(nodes: GraphNode[]): Promise<GraphNode[]> {
|
||||
const enriched: GraphNode[] = [];
|
||||
|
||||
// Process in batches
|
||||
for (let i = 0; i < nodes.length; i += this.config.batchSize!) {
|
||||
const batch = nodes.slice(i, i + this.config.batchSize!);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(node => this.generateNodeEmbedding(node))
|
||||
);
|
||||
|
||||
enriched.push(...batchResults);
|
||||
}
|
||||
|
||||
return enriched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich edges with embeddings
|
||||
*/
|
||||
private async enrichEdges(edges: GraphEdge[]): Promise<GraphEdge[]> {
|
||||
const enriched: GraphEdge[] = [];
|
||||
|
||||
// Process in batches
|
||||
for (let i = 0; i < edges.length; i += this.config.batchSize!) {
|
||||
const batch = edges.slice(i, i + this.config.batchSize!);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(edge => this.generateEdgeEmbedding(edge))
|
||||
);
|
||||
|
||||
enriched.push(...batchResults);
|
||||
}
|
||||
|
||||
return enriched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate embedding for a node
|
||||
*/
|
||||
private async generateNodeEmbedding(node: GraphNode): Promise<GraphNode> {
|
||||
// Create text representation of node
|
||||
const text = this.nodeToText(node);
|
||||
|
||||
// Generate embedding
|
||||
const embedding = await this.generateEmbedding(text);
|
||||
|
||||
return {
|
||||
...node,
|
||||
embedding: embedding.embedding
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate embedding for an edge
|
||||
*/
|
||||
private async generateEdgeEmbedding(edge: GraphEdge): Promise<GraphEdge> {
|
||||
// Create text representation of edge
|
||||
const text = this.edgeToText(edge);
|
||||
|
||||
// Generate embedding
|
||||
const embedding = await this.generateEmbedding(text);
|
||||
|
||||
return {
|
||||
...edge,
|
||||
embedding: embedding.embedding
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert node to text for embedding
|
||||
*/
|
||||
private nodeToText(node: GraphNode): string {
|
||||
const parts: string[] = [];
|
||||
|
||||
// Add labels
|
||||
parts.push(`Type: ${node.labels.join(', ')}`);
|
||||
|
||||
// Add properties
|
||||
for (const [key, value] of Object.entries(node.properties)) {
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
parts.push(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join('. ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert edge to text for embedding
|
||||
*/
|
||||
private edgeToText(edge: GraphEdge): string {
|
||||
const parts: string[] = [];
|
||||
|
||||
// Add relationship type
|
||||
parts.push(`Relationship: ${edge.type}`);
|
||||
|
||||
// Add properties
|
||||
for (const [key, value] of Object.entries(edge.properties)) {
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
parts.push(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join('. ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate embedding using OpenRouter or local model
|
||||
*/
|
||||
private async generateEmbedding(text: string): Promise<EmbeddingResult> {
|
||||
if (this.config.provider === 'local') {
|
||||
return this.generateLocalEmbedding(text);
|
||||
}
|
||||
|
||||
// Use OpenRouter with embedding-capable model
|
||||
// Note: Kimi K2 may not support embeddings, so we use a workaround
|
||||
// by generating semantic vectors through the chat API
|
||||
const embedding = await this.generateSemanticEmbedding(text);
|
||||
|
||||
return {
|
||||
embedding,
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
dimensions: embedding.length
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate semantic embedding using chat model
|
||||
*/
|
||||
private async generateSemanticEmbedding(text: string): Promise<number[]> {
|
||||
// Use the chat API to generate a semantic representation
|
||||
// This is a workaround for models without native embedding support
|
||||
const systemPrompt = `You are a semantic encoder. Convert the input text into a semantic representation by analyzing its key concepts, entities, and relationships. Output ONLY a JSON array of ${this.config.dimensions} floating point numbers between -1 and 1 representing the semantic vector.`;
|
||||
|
||||
const userPrompt = `Encode this text into a ${this.config.dimensions}-dimensional semantic vector:\n\n${text}`;
|
||||
|
||||
try {
|
||||
const response = await this.client.createCompletion(
|
||||
[
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
],
|
||||
{
|
||||
temperature: 0.3,
|
||||
max_tokens: this.config.dimensions! * 10
|
||||
}
|
||||
);
|
||||
|
||||
const content = response.choices[0]?.message?.content;
|
||||
if (!content) {
|
||||
throw new Error('No content in embedding response');
|
||||
}
|
||||
|
||||
// Extract JSON array
|
||||
const match = content.match(/\[([\s\S]*?)\]/);
|
||||
if (match) {
|
||||
const embedding = JSON.parse(`[${match[1]}]`) as number[];
|
||||
|
||||
// Ensure correct dimensions
|
||||
if (embedding.length !== this.config.dimensions) {
|
||||
return this.generateRandomEmbedding();
|
||||
}
|
||||
|
||||
return embedding;
|
||||
}
|
||||
|
||||
// Fallback to random embedding
|
||||
return this.generateRandomEmbedding();
|
||||
} catch (error) {
|
||||
console.warn('Failed to generate semantic embedding, using random:', error);
|
||||
return this.generateRandomEmbedding();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate local embedding (placeholder)
|
||||
*/
|
||||
private async generateLocalEmbedding(_text: string): Promise<EmbeddingResult> {
|
||||
// This would use a local embedding model
|
||||
// For now, return a random embedding
|
||||
return {
|
||||
embedding: this.generateRandomEmbedding(),
|
||||
model: 'local',
|
||||
dimensions: this.config.dimensions!
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate random embedding (fallback)
|
||||
*/
|
||||
private generateRandomEmbedding(): number[] {
|
||||
const embedding: number[] = [];
|
||||
for (let i = 0; i < this.config.dimensions!; i++) {
|
||||
embedding.push((Math.random() * 2) - 1); // Random value between -1 and 1
|
||||
}
|
||||
|
||||
// Normalize to unit length
|
||||
const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
||||
return embedding.map(val => val / magnitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate similarity between embeddings
|
||||
*/
|
||||
calculateSimilarity(
|
||||
embedding1: number[],
|
||||
embedding2: number[],
|
||||
metric: 'cosine' | 'euclidean' | 'dot' = 'cosine'
|
||||
): number {
|
||||
if (embedding1.length !== embedding2.length) {
|
||||
throw new Error('Embeddings must have the same dimensions');
|
||||
}
|
||||
|
||||
switch (metric) {
|
||||
case 'cosine':
|
||||
return this.cosineSimilarity(embedding1, embedding2);
|
||||
case 'euclidean':
|
||||
return this.euclideanDistance(embedding1, embedding2);
|
||||
case 'dot':
|
||||
return this.dotProduct(embedding1, embedding2);
|
||||
default:
|
||||
return this.cosineSimilarity(embedding1, embedding2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cosine similarity
|
||||
*/
|
||||
private cosineSimilarity(a: number[], b: number[]): number {
|
||||
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
|
||||
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
|
||||
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
|
||||
return dotProduct / (magnitudeA * magnitudeB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Euclidean distance
|
||||
*/
|
||||
private euclideanDistance(a: number[], b: number[]): number {
|
||||
return Math.sqrt(a.reduce((sum, val, i) => sum + Math.pow(val - b[i], 2), 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dot product
|
||||
*/
|
||||
private dotProduct(a: number[], b: number[]): number {
|
||||
return a.reduce((sum, val, i) => sum + val * b[i], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find similar nodes using embeddings
|
||||
*/
|
||||
findSimilarNodes(
|
||||
node: GraphNode,
|
||||
allNodes: GraphNode[],
|
||||
topK: number = 10,
|
||||
metric: 'cosine' | 'euclidean' | 'dot' = 'cosine'
|
||||
): Array<{ node: GraphNode; similarity: number }> {
|
||||
if (!node.embedding) {
|
||||
throw new Error('Node does not have an embedding');
|
||||
}
|
||||
|
||||
const similarities = allNodes
|
||||
.filter(n => n.id !== node.id && n.embedding)
|
||||
.map(n => ({
|
||||
node: n,
|
||||
similarity: this.calculateSimilarity(node.embedding!, n.embedding!, metric)
|
||||
}))
|
||||
.sort((a, b) => b.similarity - a.similarity)
|
||||
.slice(0, topK);
|
||||
|
||||
return similarities;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an embedding enrichment instance
|
||||
*/
|
||||
export function createEmbeddingEnrichment(
|
||||
client: OpenRouterClient,
|
||||
config?: Partial<EmbeddingConfig>
|
||||
): EmbeddingEnrichment {
|
||||
return new EmbeddingEnrichment(client, config);
|
||||
}
|
||||
49
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.d.ts
vendored
Normal file
49
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.d.ts
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Entity relationship generator for domain-specific graphs
|
||||
*/
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import { EntityRelationshipOptions, GraphData, GraphGenerationResult } from '../types.js';
|
||||
export declare class EntityRelationshipGenerator {
|
||||
private client;
|
||||
constructor(client: OpenRouterClient);
|
||||
/**
|
||||
* Generate entity-relationship graph
|
||||
*/
|
||||
generate(options: EntityRelationshipOptions): Promise<GraphGenerationResult<GraphData>>;
|
||||
/**
|
||||
* Generate domain-specific entities
|
||||
*/
|
||||
private generateEntities;
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
private generateRelationships;
|
||||
/**
|
||||
* Generate schema-aware entities and relationships
|
||||
*/
|
||||
generateWithSchema(schema: {
|
||||
entities: Record<string, {
|
||||
properties: Record<string, string>;
|
||||
relationships?: string[];
|
||||
}>;
|
||||
relationships: Record<string, {
|
||||
from: string;
|
||||
to: string;
|
||||
properties?: Record<string, string>;
|
||||
}>;
|
||||
}, count: number): Promise<GraphData>;
|
||||
/**
|
||||
* Analyze entity-relationship patterns
|
||||
*/
|
||||
analyzeERPatterns(data: GraphData): Promise<{
|
||||
entityTypeDistribution: Record<string, number>;
|
||||
relationshipTypeDistribution: Record<string, number>;
|
||||
avgRelationshipsPerEntity: number;
|
||||
densityScore: number;
|
||||
}>;
|
||||
}
|
||||
/**
|
||||
* Create an entity relationship generator
|
||||
*/
|
||||
export declare function createEntityRelationshipGenerator(client: OpenRouterClient): EntityRelationshipGenerator;
|
||||
//# sourceMappingURL=entity-relationships.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"entity-relationships.d.ts","sourceRoot":"","sources":["entity-relationships.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,yBAAyB,EACzB,SAAS,EAGT,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAerB,qBAAa,2BAA2B;IAC1B,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAE5C;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IA6C7F;;OAEG;YACW,gBAAgB;IA2C9B;;OAEG;YACW,qBAAqB;IA6DnC;;OAEG;IACG,kBAAkB,CACtB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;YACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;SAC1B,CAAC,CAAC;QACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACrC,CAAC,CAAC;KACJ,EACD,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,CAAC;IA+BrB;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAChD,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/C,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrD,yBAAyB,EAAE,MAAM,CAAC;QAClC,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CAoCH;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,gBAAgB,GAAG,2BAA2B,CAEvG"}
|
||||
217
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.js
vendored
Normal file
217
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.js
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Entity relationship generator for domain-specific graphs
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EntityRelationshipGenerator = void 0;
|
||||
exports.createEntityRelationshipGenerator = createEntityRelationshipGenerator;
|
||||
class EntityRelationshipGenerator {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
/**
|
||||
* Generate entity-relationship graph
|
||||
*/
|
||||
async generate(options) {
|
||||
const startTime = Date.now();
|
||||
// Generate entities
|
||||
const entities = await this.generateEntities(options);
|
||||
// Generate relationships
|
||||
const relationships = await this.generateRelationships(entities, options);
|
||||
// Convert to graph structure
|
||||
const nodes = entities.map(entity => ({
|
||||
id: entity.id,
|
||||
labels: entity.labels || ['Entity'],
|
||||
properties: entity.properties
|
||||
}));
|
||||
const edges = relationships.map((rel, idx) => ({
|
||||
id: `rel_${idx}`,
|
||||
type: rel.type,
|
||||
source: rel.source,
|
||||
target: rel.target,
|
||||
properties: rel.properties || {}
|
||||
}));
|
||||
const data = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: options.domain,
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate domain-specific entities
|
||||
*/
|
||||
async generateEntities(options) {
|
||||
const systemPrompt = `You are an expert in ${options.domain} domain modeling. Generate realistic entities following best practices for ${options.domain} data models.`;
|
||||
const schemaInfo = options.entitySchema
|
||||
? `\n\nEntity schema to follow:\n${JSON.stringify(options.entitySchema, null, 2)}`
|
||||
: '';
|
||||
const userPrompt = `Generate ${options.entityCount} diverse entities for a ${options.domain} domain model.${schemaInfo}
|
||||
|
||||
Each entity should have:
|
||||
- id: unique identifier (use snake_case)
|
||||
- labels: array of entity type labels (e.g., ["Product", "Digital"])
|
||||
- properties: object with entity properties (at least 3-5 meaningful properties)
|
||||
|
||||
Make entities realistic and relevant to ${options.domain}. Include variety in types and attributes.
|
||||
|
||||
Return a JSON array of entities.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "product_laptop_001",
|
||||
"labels": ["Product", "Electronics", "Computer"],
|
||||
"properties": {
|
||||
"name": "UltraBook Pro 15",
|
||||
"category": "Laptops",
|
||||
"price": 1299.99,
|
||||
"brand": "TechCorp",
|
||||
"release_date": "2024-01-15",
|
||||
"stock": 45,
|
||||
"rating": 4.7
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, options.entityCount * 150)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
async generateRelationships(entities, options) {
|
||||
// Calculate target relationship count based on density
|
||||
const maxPossibleRelationships = entities.length * (entities.length - 1);
|
||||
const targetRelationships = Math.floor(maxPossibleRelationships * options.relationshipDensity);
|
||||
const relationshipTypes = options.relationshipTypes || [
|
||||
'RELATES_TO',
|
||||
'PART_OF',
|
||||
'DEPENDS_ON',
|
||||
'SIMILAR_TO',
|
||||
'CONTAINS'
|
||||
];
|
||||
const systemPrompt = `You are an expert in ${options.domain} domain modeling. Create meaningful, realistic relationships between entities.`;
|
||||
const entityList = entities.slice(0, 100).map(e => `- ${e.id} (${e.labels.join(', ')}): ${JSON.stringify(e.properties).substring(0, 100)}`).join('\n');
|
||||
const userPrompt = `Given these entities from a ${options.domain} domain:
|
||||
|
||||
${entityList}
|
||||
|
||||
Generate ${targetRelationships} meaningful relationships between them.
|
||||
|
||||
Relationship types to use: ${relationshipTypes.join(', ')}
|
||||
|
||||
Each relationship should have:
|
||||
- source: source entity id
|
||||
- target: target entity id
|
||||
- type: relationship type (use UPPER_SNAKE_CASE)
|
||||
- properties: optional properties describing the relationship
|
||||
|
||||
Make relationships logical and realistic for ${options.domain}. Avoid creating too many relationships from/to the same entity.
|
||||
|
||||
Return a JSON array of relationships.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "product_laptop_001",
|
||||
"target": "category_electronics",
|
||||
"type": "BELONGS_TO",
|
||||
"properties": {
|
||||
"primary": true,
|
||||
"added_date": "2024-01-15"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, targetRelationships * 80)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate schema-aware entities and relationships
|
||||
*/
|
||||
async generateWithSchema(schema, count) {
|
||||
const systemPrompt = 'You are an expert at generating synthetic data that conforms to strict schemas.';
|
||||
const userPrompt = `Generate ${count} instances of entities and relationships following this exact schema:
|
||||
|
||||
${JSON.stringify(schema, null, 2)}
|
||||
|
||||
Return a JSON object with:
|
||||
- nodes: array of entities matching the entity types in the schema
|
||||
- edges: array of relationships matching the relationship types in the schema
|
||||
|
||||
Ensure all properties match their specified types and all relationships connect valid entity types.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
{
|
||||
"nodes": [...],
|
||||
"edges": [...]
|
||||
}
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, count * 200)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Analyze entity-relationship patterns
|
||||
*/
|
||||
async analyzeERPatterns(data) {
|
||||
const entityTypeDistribution = {};
|
||||
const relationshipTypeDistribution = {};
|
||||
const entityDegrees = new Map();
|
||||
// Count entity types
|
||||
for (const node of data.nodes) {
|
||||
for (const label of node.labels) {
|
||||
entityTypeDistribution[label] = (entityTypeDistribution[label] || 0) + 1;
|
||||
}
|
||||
}
|
||||
// Count relationship types and degrees
|
||||
for (const edge of data.edges) {
|
||||
relationshipTypeDistribution[edge.type] = (relationshipTypeDistribution[edge.type] || 0) + 1;
|
||||
entityDegrees.set(edge.source, (entityDegrees.get(edge.source) || 0) + 1);
|
||||
entityDegrees.set(edge.target, (entityDegrees.get(edge.target) || 0) + 1);
|
||||
}
|
||||
const degrees = Array.from(entityDegrees.values());
|
||||
const avgRelationshipsPerEntity = degrees.length > 0
|
||||
? degrees.reduce((a, b) => a + b, 0) / degrees.length
|
||||
: 0;
|
||||
const maxPossibleEdges = data.nodes.length * (data.nodes.length - 1);
|
||||
const densityScore = maxPossibleEdges > 0
|
||||
? data.edges.length / maxPossibleEdges
|
||||
: 0;
|
||||
return {
|
||||
entityTypeDistribution,
|
||||
relationshipTypeDistribution,
|
||||
avgRelationshipsPerEntity,
|
||||
densityScore
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.EntityRelationshipGenerator = EntityRelationshipGenerator;
|
||||
/**
|
||||
* Create an entity relationship generator
|
||||
*/
|
||||
function createEntityRelationshipGenerator(client) {
|
||||
return new EntityRelationshipGenerator(client);
|
||||
}
|
||||
//# sourceMappingURL=entity-relationships.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"entity-relationships.js","sourceRoot":"","sources":["entity-relationships.ts"],"names":[],"mappings":"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"}
|
||||
286
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.ts
vendored
Normal file
286
vendor/ruvector/npm/packages/graph-data-generator/src/generators/entity-relationships.ts
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* Entity relationship generator for domain-specific graphs
|
||||
*/
|
||||
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import {
|
||||
EntityRelationshipOptions,
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
GraphGenerationResult
|
||||
} from '../types.js';
|
||||
|
||||
interface EntityData {
|
||||
id: string;
|
||||
labels: string[];
|
||||
properties: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface RelationshipData {
|
||||
source: string;
|
||||
target: string;
|
||||
type: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export class EntityRelationshipGenerator {
|
||||
constructor(private client: OpenRouterClient) {}
|
||||
|
||||
/**
|
||||
* Generate entity-relationship graph
|
||||
*/
|
||||
async generate(options: EntityRelationshipOptions): Promise<GraphGenerationResult<GraphData>> {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Generate entities
|
||||
const entities = await this.generateEntities(options);
|
||||
|
||||
// Generate relationships
|
||||
const relationships = await this.generateRelationships(entities, options);
|
||||
|
||||
// Convert to graph structure
|
||||
const nodes: GraphNode[] = entities.map(entity => ({
|
||||
id: entity.id,
|
||||
labels: entity.labels || ['Entity'],
|
||||
properties: entity.properties
|
||||
}));
|
||||
|
||||
const edges: GraphEdge[] = relationships.map((rel, idx) => ({
|
||||
id: `rel_${idx}`,
|
||||
type: rel.type,
|
||||
source: rel.source,
|
||||
target: rel.target,
|
||||
properties: rel.properties || {}
|
||||
}));
|
||||
|
||||
const data: GraphData = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: options.domain,
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate domain-specific entities
|
||||
*/
|
||||
private async generateEntities(options: EntityRelationshipOptions): Promise<EntityData[]> {
|
||||
const systemPrompt = `You are an expert in ${options.domain} domain modeling. Generate realistic entities following best practices for ${options.domain} data models.`;
|
||||
|
||||
const schemaInfo = options.entitySchema
|
||||
? `\n\nEntity schema to follow:\n${JSON.stringify(options.entitySchema, null, 2)}`
|
||||
: '';
|
||||
|
||||
const userPrompt = `Generate ${options.entityCount} diverse entities for a ${options.domain} domain model.${schemaInfo}
|
||||
|
||||
Each entity should have:
|
||||
- id: unique identifier (use snake_case)
|
||||
- labels: array of entity type labels (e.g., ["Product", "Digital"])
|
||||
- properties: object with entity properties (at least 3-5 meaningful properties)
|
||||
|
||||
Make entities realistic and relevant to ${options.domain}. Include variety in types and attributes.
|
||||
|
||||
Return a JSON array of entities.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "product_laptop_001",
|
||||
"labels": ["Product", "Electronics", "Computer"],
|
||||
"properties": {
|
||||
"name": "UltraBook Pro 15",
|
||||
"category": "Laptops",
|
||||
"price": 1299.99,
|
||||
"brand": "TechCorp",
|
||||
"release_date": "2024-01-15",
|
||||
"stock": 45,
|
||||
"rating": 4.7
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<EntityData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, options.entityCount * 150)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
private async generateRelationships(
|
||||
entities: EntityData[],
|
||||
options: EntityRelationshipOptions
|
||||
): Promise<RelationshipData[]> {
|
||||
// Calculate target relationship count based on density
|
||||
const maxPossibleRelationships = entities.length * (entities.length - 1);
|
||||
const targetRelationships = Math.floor(maxPossibleRelationships * options.relationshipDensity);
|
||||
|
||||
const relationshipTypes = options.relationshipTypes || [
|
||||
'RELATES_TO',
|
||||
'PART_OF',
|
||||
'DEPENDS_ON',
|
||||
'SIMILAR_TO',
|
||||
'CONTAINS'
|
||||
];
|
||||
|
||||
const systemPrompt = `You are an expert in ${options.domain} domain modeling. Create meaningful, realistic relationships between entities.`;
|
||||
|
||||
const entityList = entities.slice(0, 100).map(e =>
|
||||
`- ${e.id} (${e.labels.join(', ')}): ${JSON.stringify(e.properties).substring(0, 100)}`
|
||||
).join('\n');
|
||||
|
||||
const userPrompt = `Given these entities from a ${options.domain} domain:
|
||||
|
||||
${entityList}
|
||||
|
||||
Generate ${targetRelationships} meaningful relationships between them.
|
||||
|
||||
Relationship types to use: ${relationshipTypes.join(', ')}
|
||||
|
||||
Each relationship should have:
|
||||
- source: source entity id
|
||||
- target: target entity id
|
||||
- type: relationship type (use UPPER_SNAKE_CASE)
|
||||
- properties: optional properties describing the relationship
|
||||
|
||||
Make relationships logical and realistic for ${options.domain}. Avoid creating too many relationships from/to the same entity.
|
||||
|
||||
Return a JSON array of relationships.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "product_laptop_001",
|
||||
"target": "category_electronics",
|
||||
"type": "BELONGS_TO",
|
||||
"properties": {
|
||||
"primary": true,
|
||||
"added_date": "2024-01-15"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<RelationshipData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, targetRelationships * 80)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate schema-aware entities and relationships
|
||||
*/
|
||||
async generateWithSchema(
|
||||
schema: {
|
||||
entities: Record<string, {
|
||||
properties: Record<string, string>;
|
||||
relationships?: string[];
|
||||
}>;
|
||||
relationships: Record<string, {
|
||||
from: string;
|
||||
to: string;
|
||||
properties?: Record<string, string>;
|
||||
}>;
|
||||
},
|
||||
count: number
|
||||
): Promise<GraphData> {
|
||||
const systemPrompt = 'You are an expert at generating synthetic data that conforms to strict schemas.';
|
||||
|
||||
const userPrompt = `Generate ${count} instances of entities and relationships following this exact schema:
|
||||
|
||||
${JSON.stringify(schema, null, 2)}
|
||||
|
||||
Return a JSON object with:
|
||||
- nodes: array of entities matching the entity types in the schema
|
||||
- edges: array of relationships matching the relationship types in the schema
|
||||
|
||||
Ensure all properties match their specified types and all relationships connect valid entity types.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
{
|
||||
"nodes": [...],
|
||||
"edges": [...]
|
||||
}
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<GraphData>(
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
{
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, count * 200)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze entity-relationship patterns
|
||||
*/
|
||||
async analyzeERPatterns(data: GraphData): Promise<{
|
||||
entityTypeDistribution: Record<string, number>;
|
||||
relationshipTypeDistribution: Record<string, number>;
|
||||
avgRelationshipsPerEntity: number;
|
||||
densityScore: number;
|
||||
}> {
|
||||
const entityTypeDistribution: Record<string, number> = {};
|
||||
const relationshipTypeDistribution: Record<string, number> = {};
|
||||
const entityDegrees = new Map<string, number>();
|
||||
|
||||
// Count entity types
|
||||
for (const node of data.nodes) {
|
||||
for (const label of node.labels) {
|
||||
entityTypeDistribution[label] = (entityTypeDistribution[label] || 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Count relationship types and degrees
|
||||
for (const edge of data.edges) {
|
||||
relationshipTypeDistribution[edge.type] = (relationshipTypeDistribution[edge.type] || 0) + 1;
|
||||
entityDegrees.set(edge.source, (entityDegrees.get(edge.source) || 0) + 1);
|
||||
entityDegrees.set(edge.target, (entityDegrees.get(edge.target) || 0) + 1);
|
||||
}
|
||||
|
||||
const degrees = Array.from(entityDegrees.values());
|
||||
const avgRelationshipsPerEntity = degrees.length > 0
|
||||
? degrees.reduce((a, b) => a + b, 0) / degrees.length
|
||||
: 0;
|
||||
|
||||
const maxPossibleEdges = data.nodes.length * (data.nodes.length - 1);
|
||||
const densityScore = maxPossibleEdges > 0
|
||||
? data.edges.length / maxPossibleEdges
|
||||
: 0;
|
||||
|
||||
return {
|
||||
entityTypeDistribution,
|
||||
relationshipTypeDistribution,
|
||||
avgRelationshipsPerEntity,
|
||||
densityScore
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an entity relationship generator
|
||||
*/
|
||||
export function createEntityRelationshipGenerator(client: OpenRouterClient): EntityRelationshipGenerator {
|
||||
return new EntityRelationshipGenerator(client);
|
||||
}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,uDAAqC;AACrC,sDAAoC;AACpC,uDAAqC;AACrC,4DAA0C"}
|
||||
8
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.ts
vendored
Normal file
8
vendor/ruvector/npm/packages/graph-data-generator/src/generators/index.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Graph data generators exports
|
||||
*/
|
||||
|
||||
export * from './knowledge-graph.js';
|
||||
export * from './social-network.js';
|
||||
export * from './temporal-events.js';
|
||||
export * from './entity-relationships.js';
|
||||
30
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.d.ts
vendored
Normal file
30
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Knowledge graph generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import { KnowledgeGraphOptions, GraphData, GraphGenerationResult, KnowledgeTriple } from '../types.js';
|
||||
export declare class KnowledgeGraphGenerator {
|
||||
private client;
|
||||
constructor(client: OpenRouterClient);
|
||||
/**
|
||||
* Generate a knowledge graph
|
||||
*/
|
||||
generate(options: KnowledgeGraphOptions): Promise<GraphGenerationResult<GraphData>>;
|
||||
/**
|
||||
* Generate entities for the knowledge graph
|
||||
*/
|
||||
private generateEntities;
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
private generateRelationships;
|
||||
/**
|
||||
* Generate knowledge triples (subject-predicate-object)
|
||||
*/
|
||||
generateTriples(domain: string, count: number): Promise<KnowledgeTriple[]>;
|
||||
}
|
||||
/**
|
||||
* Create a knowledge graph generator
|
||||
*/
|
||||
export declare function createKnowledgeGraphGenerator(client: OpenRouterClient): KnowledgeGraphGenerator;
|
||||
//# sourceMappingURL=knowledge-graph.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"knowledge-graph.d.ts","sourceRoot":"","sources":["knowledge-graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,qBAAqB,EACrB,SAAS,EAGT,qBAAqB,EACrB,eAAe,EAChB,MAAM,aAAa,CAAC;AAoCrB,qBAAa,uBAAuB;IACtB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAE5C;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAgDzF;;OAEG;YACW,gBAAgB;IA8C9B;;OAEG;YACW,qBAAqB;IAiDnC;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,EAAE,CAAC;CA+B9B;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,gBAAgB,GAAG,uBAAuB,CAE/F"}
|
||||
192
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.js
vendored
Normal file
192
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.js
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Knowledge graph generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.KnowledgeGraphGenerator = void 0;
|
||||
exports.createKnowledgeGraphGenerator = createKnowledgeGraphGenerator;
|
||||
const DEFAULT_ENTITY_TYPES = [
|
||||
'Person',
|
||||
'Organization',
|
||||
'Location',
|
||||
'Event',
|
||||
'Concept',
|
||||
'Technology',
|
||||
'Product'
|
||||
];
|
||||
const DEFAULT_RELATIONSHIP_TYPES = [
|
||||
'WORKS_FOR',
|
||||
'LOCATED_IN',
|
||||
'CREATED_BY',
|
||||
'PART_OF',
|
||||
'RELATED_TO',
|
||||
'INFLUENCES',
|
||||
'DEPENDS_ON'
|
||||
];
|
||||
class KnowledgeGraphGenerator {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
/**
|
||||
* Generate a knowledge graph
|
||||
*/
|
||||
async generate(options) {
|
||||
const startTime = Date.now();
|
||||
// Generate entities first
|
||||
const entities = await this.generateEntities(options);
|
||||
// Generate relationships between entities
|
||||
const relationships = await this.generateRelationships(entities, options);
|
||||
// Convert to graph structure
|
||||
const nodes = entities.map((entity, idx) => ({
|
||||
id: entity.id || `entity_${idx}`,
|
||||
labels: [entity.type || 'Entity'],
|
||||
properties: {
|
||||
name: entity.name,
|
||||
...entity.properties
|
||||
}
|
||||
}));
|
||||
const edges = relationships.map((rel, idx) => ({
|
||||
id: `rel_${idx}`,
|
||||
type: rel.type,
|
||||
source: rel.source,
|
||||
target: rel.target,
|
||||
properties: rel.properties || {}
|
||||
}));
|
||||
const data = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: options.domain,
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate entities for the knowledge graph
|
||||
*/
|
||||
async generateEntities(options) {
|
||||
const entityTypes = options.entityTypes || DEFAULT_ENTITY_TYPES;
|
||||
const systemPrompt = `You are an expert knowledge graph architect. Generate realistic entities for a knowledge graph about ${options.domain}.`;
|
||||
const userPrompt = `Generate ${options.entities} diverse entities for a knowledge graph about ${options.domain}.
|
||||
|
||||
Entity types to include: ${entityTypes.join(', ')}
|
||||
|
||||
For each entity, provide:
|
||||
- id: unique identifier (use snake_case)
|
||||
- name: entity name
|
||||
- type: one of the specified entity types
|
||||
- properties: relevant properties (at least 2-3 properties per entity)
|
||||
|
||||
Return a JSON array of entities. Make them realistic and relevant to ${options.domain}.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "john_doe",
|
||||
"name": "John Doe",
|
||||
"type": "Person",
|
||||
"properties": {
|
||||
"role": "Software Engineer",
|
||||
"expertise": "AI/ML",
|
||||
"years_experience": 5
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
const entities = await this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, options.entities * 100)
|
||||
});
|
||||
return entities;
|
||||
}
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
async generateRelationships(entities, options) {
|
||||
const relationshipTypes = options.relationshipTypes || DEFAULT_RELATIONSHIP_TYPES;
|
||||
const systemPrompt = `You are an expert at creating meaningful relationships in knowledge graphs. Create realistic relationships that make sense for ${options.domain}.`;
|
||||
const entityList = entities.slice(0, 50).map(e => `- ${e.id}: ${e.name} (${e.type})`).join('\n');
|
||||
const userPrompt = `Given these entities from a ${options.domain} knowledge graph:
|
||||
|
||||
${entityList}
|
||||
|
||||
Generate ${options.relationships} meaningful relationships between them.
|
||||
|
||||
Relationship types to use: ${relationshipTypes.join(', ')}
|
||||
|
||||
For each relationship, provide:
|
||||
- source: source entity id
|
||||
- target: target entity id
|
||||
- type: relationship type (use one of the specified types)
|
||||
- properties: optional properties describing the relationship
|
||||
|
||||
Return a JSON array of relationships. Make them logical and realistic.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "john_doe",
|
||||
"target": "acme_corp",
|
||||
"type": "WORKS_FOR",
|
||||
"properties": {
|
||||
"since": "2020",
|
||||
"position": "Senior Engineer"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
const relationships = await this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, options.relationships * 80)
|
||||
});
|
||||
return relationships;
|
||||
}
|
||||
/**
|
||||
* Generate knowledge triples (subject-predicate-object)
|
||||
*/
|
||||
async generateTriples(domain, count) {
|
||||
const systemPrompt = `You are an expert at extracting knowledge triples from domains. Generate meaningful subject-predicate-object triples about ${domain}.`;
|
||||
const userPrompt = `Generate ${count} knowledge triples about ${domain}.
|
||||
|
||||
Each triple should have:
|
||||
- subject: the entity or concept
|
||||
- predicate: the relationship or property
|
||||
- object: the related entity, value, or concept
|
||||
- confidence: confidence score (0-1)
|
||||
|
||||
Return a JSON array of triples.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"subject": "Einstein",
|
||||
"predicate": "developed",
|
||||
"object": "Theory of Relativity",
|
||||
"confidence": 1.0
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, { temperature: 0.7, maxTokens: count * 100 });
|
||||
}
|
||||
}
|
||||
exports.KnowledgeGraphGenerator = KnowledgeGraphGenerator;
|
||||
/**
|
||||
* Create a knowledge graph generator
|
||||
*/
|
||||
function createKnowledgeGraphGenerator(client) {
|
||||
return new KnowledgeGraphGenerator(client);
|
||||
}
|
||||
//# sourceMappingURL=knowledge-graph.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"knowledge-graph.js","sourceRoot":"","sources":["knowledge-graph.ts"],"names":[],"mappings":"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"}
|
||||
248
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.ts
vendored
Normal file
248
vendor/ruvector/npm/packages/graph-data-generator/src/generators/knowledge-graph.ts
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Knowledge graph generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import {
|
||||
KnowledgeGraphOptions,
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
GraphGenerationResult,
|
||||
KnowledgeTriple
|
||||
} from '../types.js';
|
||||
|
||||
interface EntityData {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
properties: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface RelationshipData {
|
||||
source: string;
|
||||
target: string;
|
||||
type: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
const DEFAULT_ENTITY_TYPES = [
|
||||
'Person',
|
||||
'Organization',
|
||||
'Location',
|
||||
'Event',
|
||||
'Concept',
|
||||
'Technology',
|
||||
'Product'
|
||||
];
|
||||
|
||||
const DEFAULT_RELATIONSHIP_TYPES = [
|
||||
'WORKS_FOR',
|
||||
'LOCATED_IN',
|
||||
'CREATED_BY',
|
||||
'PART_OF',
|
||||
'RELATED_TO',
|
||||
'INFLUENCES',
|
||||
'DEPENDS_ON'
|
||||
];
|
||||
|
||||
export class KnowledgeGraphGenerator {
|
||||
constructor(private client: OpenRouterClient) {}
|
||||
|
||||
/**
|
||||
* Generate a knowledge graph
|
||||
*/
|
||||
async generate(options: KnowledgeGraphOptions): Promise<GraphGenerationResult<GraphData>> {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Generate entities first
|
||||
const entities = await this.generateEntities(options);
|
||||
|
||||
// Generate relationships between entities
|
||||
const relationships = await this.generateRelationships(entities, options);
|
||||
|
||||
// Convert to graph structure
|
||||
const nodes: GraphNode[] = entities.map((entity, idx) => ({
|
||||
id: entity.id || `entity_${idx}`,
|
||||
labels: [entity.type || 'Entity'],
|
||||
properties: {
|
||||
name: entity.name,
|
||||
...entity.properties
|
||||
}
|
||||
}));
|
||||
|
||||
const edges: GraphEdge[] = relationships.map((rel, idx) => ({
|
||||
id: `rel_${idx}`,
|
||||
type: rel.type,
|
||||
source: rel.source,
|
||||
target: rel.target,
|
||||
properties: rel.properties || {}
|
||||
}));
|
||||
|
||||
const data: GraphData = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: options.domain,
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate entities for the knowledge graph
|
||||
*/
|
||||
private async generateEntities(options: KnowledgeGraphOptions): Promise<Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
properties: Record<string, unknown>;
|
||||
}>> {
|
||||
const entityTypes = options.entityTypes || DEFAULT_ENTITY_TYPES;
|
||||
|
||||
const systemPrompt = `You are an expert knowledge graph architect. Generate realistic entities for a knowledge graph about ${options.domain}.`;
|
||||
|
||||
const userPrompt = `Generate ${options.entities} diverse entities for a knowledge graph about ${options.domain}.
|
||||
|
||||
Entity types to include: ${entityTypes.join(', ')}
|
||||
|
||||
For each entity, provide:
|
||||
- id: unique identifier (use snake_case)
|
||||
- name: entity name
|
||||
- type: one of the specified entity types
|
||||
- properties: relevant properties (at least 2-3 properties per entity)
|
||||
|
||||
Return a JSON array of entities. Make them realistic and relevant to ${options.domain}.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "john_doe",
|
||||
"name": "John Doe",
|
||||
"type": "Person",
|
||||
"properties": {
|
||||
"role": "Software Engineer",
|
||||
"expertise": "AI/ML",
|
||||
"years_experience": 5
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
const entities = await this.client.generateStructured<EntityData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, options.entities * 100)
|
||||
});
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate relationships between entities
|
||||
*/
|
||||
private async generateRelationships(
|
||||
entities: EntityData[],
|
||||
options: KnowledgeGraphOptions
|
||||
): Promise<RelationshipData[]> {
|
||||
const relationshipTypes = options.relationshipTypes || DEFAULT_RELATIONSHIP_TYPES;
|
||||
|
||||
const systemPrompt = `You are an expert at creating meaningful relationships in knowledge graphs. Create realistic relationships that make sense for ${options.domain}.`;
|
||||
|
||||
const entityList = entities.slice(0, 50).map(e => `- ${e.id}: ${e.name} (${e.type})`).join('\n');
|
||||
|
||||
const userPrompt = `Given these entities from a ${options.domain} knowledge graph:
|
||||
|
||||
${entityList}
|
||||
|
||||
Generate ${options.relationships} meaningful relationships between them.
|
||||
|
||||
Relationship types to use: ${relationshipTypes.join(', ')}
|
||||
|
||||
For each relationship, provide:
|
||||
- source: source entity id
|
||||
- target: target entity id
|
||||
- type: relationship type (use one of the specified types)
|
||||
- properties: optional properties describing the relationship
|
||||
|
||||
Return a JSON array of relationships. Make them logical and realistic.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "john_doe",
|
||||
"target": "acme_corp",
|
||||
"type": "WORKS_FOR",
|
||||
"properties": {
|
||||
"since": "2020",
|
||||
"position": "Senior Engineer"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
const relationships = await this.client.generateStructured<RelationshipData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, options.relationships * 80)
|
||||
});
|
||||
|
||||
return relationships;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate knowledge triples (subject-predicate-object)
|
||||
*/
|
||||
async generateTriples(
|
||||
domain: string,
|
||||
count: number
|
||||
): Promise<KnowledgeTriple[]> {
|
||||
const systemPrompt = `You are an expert at extracting knowledge triples from domains. Generate meaningful subject-predicate-object triples about ${domain}.`;
|
||||
|
||||
const userPrompt = `Generate ${count} knowledge triples about ${domain}.
|
||||
|
||||
Each triple should have:
|
||||
- subject: the entity or concept
|
||||
- predicate: the relationship or property
|
||||
- object: the related entity, value, or concept
|
||||
- confidence: confidence score (0-1)
|
||||
|
||||
Return a JSON array of triples.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"subject": "Einstein",
|
||||
"predicate": "developed",
|
||||
"object": "Theory of Relativity",
|
||||
"confidence": 1.0
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<KnowledgeTriple[]>(
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
{ temperature: 0.7, maxTokens: count * 100 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a knowledge graph generator
|
||||
*/
|
||||
export function createKnowledgeGraphGenerator(client: OpenRouterClient): KnowledgeGraphGenerator {
|
||||
return new KnowledgeGraphGenerator(client);
|
||||
}
|
||||
39
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.d.ts
vendored
Normal file
39
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Social network generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import { SocialNetworkOptions, GraphData, GraphGenerationResult } from '../types.js';
|
||||
export declare class SocialNetworkGenerator {
|
||||
private client;
|
||||
constructor(client: OpenRouterClient);
|
||||
/**
|
||||
* Generate a social network graph
|
||||
*/
|
||||
generate(options: SocialNetworkOptions): Promise<GraphGenerationResult<GraphData>>;
|
||||
/**
|
||||
* Generate realistic social network users
|
||||
*/
|
||||
private generateUsers;
|
||||
/**
|
||||
* Generate connections between users
|
||||
*/
|
||||
private generateConnections;
|
||||
/**
|
||||
* Get guidance for network type
|
||||
*/
|
||||
private getNetworkTypeGuidance;
|
||||
/**
|
||||
* Analyze network properties
|
||||
*/
|
||||
analyzeNetwork(data: GraphData): Promise<{
|
||||
avgDegree: number;
|
||||
maxDegree: number;
|
||||
communities?: number;
|
||||
clustering?: number;
|
||||
}>;
|
||||
}
|
||||
/**
|
||||
* Create a social network generator
|
||||
*/
|
||||
export declare function createSocialNetworkGenerator(client: OpenRouterClient): SocialNetworkGenerator;
|
||||
//# sourceMappingURL=social-network.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"social-network.d.ts","sourceRoot":"","sources":["social-network.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EAEpB,SAAS,EAGT,qBAAqB,EACtB,MAAM,aAAa,CAAC;AASrB,qBAAa,sBAAsB;IACrB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAE5C;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAiDxF;;OAEG;YACW,aAAa;IA6C3B;;OAEG;YACW,mBAAmB;IA+CjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAa9B;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAC7C,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CAiBH;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,CAE7F"}
|
||||
180
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.js
vendored
Normal file
180
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.js
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Social network generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SocialNetworkGenerator = void 0;
|
||||
exports.createSocialNetworkGenerator = createSocialNetworkGenerator;
|
||||
class SocialNetworkGenerator {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
/**
|
||||
* Generate a social network graph
|
||||
*/
|
||||
async generate(options) {
|
||||
const startTime = Date.now();
|
||||
// Generate users
|
||||
const users = await this.generateUsers(options);
|
||||
// Generate connections based on network type
|
||||
const connections = await this.generateConnections(users, options);
|
||||
// Convert to graph structure
|
||||
const nodes = users.map(user => ({
|
||||
id: user.id,
|
||||
labels: ['User'],
|
||||
properties: {
|
||||
username: user.username,
|
||||
...user.profile,
|
||||
...(user.metadata || {})
|
||||
}
|
||||
}));
|
||||
const edges = connections.map((conn, idx) => ({
|
||||
id: `connection_${idx}`,
|
||||
type: conn.type || 'FOLLOWS',
|
||||
source: conn.source,
|
||||
target: conn.target,
|
||||
properties: conn.properties || {}
|
||||
}));
|
||||
const data = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: 'social-network',
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate realistic social network users
|
||||
*/
|
||||
async generateUsers(options) {
|
||||
const systemPrompt = 'You are an expert at creating realistic social network user profiles. Generate diverse, believable users.';
|
||||
const userPrompt = `Generate ${options.users} realistic social network user profiles.
|
||||
|
||||
Each user should have:
|
||||
- id: unique user ID (format: user_XXXXX)
|
||||
- username: unique username
|
||||
- profile: object with name, bio, joined (ISO date), followers (number), following (number)
|
||||
${options.includeMetadata ? '- metadata: additional information like interests, location, verified status' : ''}
|
||||
|
||||
Make the profiles diverse and realistic. Return a JSON array.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "user_12345",
|
||||
"username": "tech_enthusiast_42",
|
||||
"profile": {
|
||||
"name": "Alex Johnson",
|
||||
"bio": "Software developer passionate about AI and open source",
|
||||
"joined": "2020-03-15T00:00:00Z",
|
||||
"followers": 1250,
|
||||
"following": 430
|
||||
}${options.includeMetadata ? `,
|
||||
"metadata": {
|
||||
"interests": ["technology", "AI", "coding"],
|
||||
"location": "San Francisco, CA",
|
||||
"verified": false
|
||||
}` : ''}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.9,
|
||||
maxTokens: Math.min(8000, options.users * 150)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate connections between users
|
||||
*/
|
||||
async generateConnections(users, options) {
|
||||
const totalConnections = Math.floor(options.users * options.avgConnections / 2);
|
||||
const systemPrompt = `You are an expert at modeling social network connections. Create realistic ${options.networkType || 'random'} network patterns.`;
|
||||
const userList = users.slice(0, 100).map(u => `- ${u.id}: @${u.username}`).join('\n');
|
||||
const userPrompt = `Given these social network users:
|
||||
|
||||
${userList}
|
||||
|
||||
Generate ${totalConnections} connections creating a ${options.networkType || 'random'} network structure.
|
||||
|
||||
${this.getNetworkTypeGuidance(options.networkType)}
|
||||
|
||||
Each connection should have:
|
||||
- source: user id who initiates the connection
|
||||
- target: user id being connected to
|
||||
- type: connection type (FOLLOWS, FRIEND, BLOCKS, MUTES)
|
||||
- properties: optional properties like since (ISO date), strength (0-1)
|
||||
|
||||
Return a JSON array of connections.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "user_12345",
|
||||
"target": "user_67890",
|
||||
"type": "FOLLOWS",
|
||||
"properties": {
|
||||
"since": "2021-06-15T00:00:00Z",
|
||||
"strength": 0.8
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, totalConnections * 80)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get guidance for network type
|
||||
*/
|
||||
getNetworkTypeGuidance(networkType) {
|
||||
switch (networkType) {
|
||||
case 'small-world':
|
||||
return 'Create clusters of highly connected users with occasional bridges between clusters (small-world property).';
|
||||
case 'scale-free':
|
||||
return 'Create a power-law distribution where a few users have many connections (influencers) and most have few connections.';
|
||||
case 'clustered':
|
||||
return 'Create distinct communities/clusters with high internal connectivity and sparse connections between clusters.';
|
||||
default:
|
||||
return 'Create random connections with varying connection strengths.';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Analyze network properties
|
||||
*/
|
||||
async analyzeNetwork(data) {
|
||||
const degrees = new Map();
|
||||
for (const edge of data.edges) {
|
||||
degrees.set(edge.source, (degrees.get(edge.source) || 0) + 1);
|
||||
degrees.set(edge.target, (degrees.get(edge.target) || 0) + 1);
|
||||
}
|
||||
const degreeValues = Array.from(degrees.values());
|
||||
const avgDegree = degreeValues.reduce((a, b) => a + b, 0) / degreeValues.length;
|
||||
const maxDegree = Math.max(...degreeValues);
|
||||
return {
|
||||
avgDegree,
|
||||
maxDegree
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.SocialNetworkGenerator = SocialNetworkGenerator;
|
||||
/**
|
||||
* Create a social network generator
|
||||
*/
|
||||
function createSocialNetworkGenerator(client) {
|
||||
return new SocialNetworkGenerator(client);
|
||||
}
|
||||
//# sourceMappingURL=social-network.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"social-network.js","sourceRoot":"","sources":["social-network.ts"],"names":[],"mappings":"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"}
|
||||
223
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.ts
vendored
Normal file
223
vendor/ruvector/npm/packages/graph-data-generator/src/generators/social-network.ts
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* Social network generator using OpenRouter/Kimi K2
|
||||
*/
|
||||
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import {
|
||||
SocialNetworkOptions,
|
||||
SocialNode,
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
GraphGenerationResult
|
||||
} from '../types.js';
|
||||
|
||||
interface ConnectionData {
|
||||
source: string;
|
||||
target: string;
|
||||
type: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export class SocialNetworkGenerator {
|
||||
constructor(private client: OpenRouterClient) {}
|
||||
|
||||
/**
|
||||
* Generate a social network graph
|
||||
*/
|
||||
async generate(options: SocialNetworkOptions): Promise<GraphGenerationResult<GraphData>> {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Generate users
|
||||
const users = await this.generateUsers(options);
|
||||
|
||||
// Generate connections based on network type
|
||||
const connections = await this.generateConnections(users, options);
|
||||
|
||||
// Convert to graph structure
|
||||
const nodes: GraphNode[] = users.map(user => ({
|
||||
id: user.id,
|
||||
labels: ['User'],
|
||||
properties: {
|
||||
username: user.username,
|
||||
...user.profile,
|
||||
...(user.metadata || {})
|
||||
}
|
||||
}));
|
||||
|
||||
const edges: GraphEdge[] = connections.map((conn, idx) => ({
|
||||
id: `connection_${idx}`,
|
||||
type: conn.type || 'FOLLOWS',
|
||||
source: conn.source,
|
||||
target: conn.target,
|
||||
properties: conn.properties || {}
|
||||
}));
|
||||
|
||||
const data: GraphData = {
|
||||
nodes,
|
||||
edges,
|
||||
metadata: {
|
||||
domain: 'social-network',
|
||||
generated_at: new Date(),
|
||||
total_nodes: nodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate realistic social network users
|
||||
*/
|
||||
private async generateUsers(options: SocialNetworkOptions): Promise<SocialNode[]> {
|
||||
const systemPrompt = 'You are an expert at creating realistic social network user profiles. Generate diverse, believable users.';
|
||||
|
||||
const userPrompt = `Generate ${options.users} realistic social network user profiles.
|
||||
|
||||
Each user should have:
|
||||
- id: unique user ID (format: user_XXXXX)
|
||||
- username: unique username
|
||||
- profile: object with name, bio, joined (ISO date), followers (number), following (number)
|
||||
${options.includeMetadata ? '- metadata: additional information like interests, location, verified status' : ''}
|
||||
|
||||
Make the profiles diverse and realistic. Return a JSON array.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "user_12345",
|
||||
"username": "tech_enthusiast_42",
|
||||
"profile": {
|
||||
"name": "Alex Johnson",
|
||||
"bio": "Software developer passionate about AI and open source",
|
||||
"joined": "2020-03-15T00:00:00Z",
|
||||
"followers": 1250,
|
||||
"following": 430
|
||||
}${options.includeMetadata ? `,
|
||||
"metadata": {
|
||||
"interests": ["technology", "AI", "coding"],
|
||||
"location": "San Francisco, CA",
|
||||
"verified": false
|
||||
}` : ''}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<SocialNode[]>(
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
{
|
||||
temperature: 0.9,
|
||||
maxTokens: Math.min(8000, options.users * 150)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate connections between users
|
||||
*/
|
||||
private async generateConnections(
|
||||
users: SocialNode[],
|
||||
options: SocialNetworkOptions
|
||||
): Promise<ConnectionData[]> {
|
||||
const totalConnections = Math.floor(options.users * options.avgConnections / 2);
|
||||
|
||||
const systemPrompt = `You are an expert at modeling social network connections. Create realistic ${options.networkType || 'random'} network patterns.`;
|
||||
|
||||
const userList = users.slice(0, 100).map(u => `- ${u.id}: @${u.username}`).join('\n');
|
||||
|
||||
const userPrompt = `Given these social network users:
|
||||
|
||||
${userList}
|
||||
|
||||
Generate ${totalConnections} connections creating a ${options.networkType || 'random'} network structure.
|
||||
|
||||
${this.getNetworkTypeGuidance(options.networkType)}
|
||||
|
||||
Each connection should have:
|
||||
- source: user id who initiates the connection
|
||||
- target: user id being connected to
|
||||
- type: connection type (FOLLOWS, FRIEND, BLOCKS, MUTES)
|
||||
- properties: optional properties like since (ISO date), strength (0-1)
|
||||
|
||||
Return a JSON array of connections.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"source": "user_12345",
|
||||
"target": "user_67890",
|
||||
"type": "FOLLOWS",
|
||||
"properties": {
|
||||
"since": "2021-06-15T00:00:00Z",
|
||||
"strength": 0.8
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<ConnectionData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, totalConnections * 80)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get guidance for network type
|
||||
*/
|
||||
private getNetworkTypeGuidance(networkType?: string): string {
|
||||
switch (networkType) {
|
||||
case 'small-world':
|
||||
return 'Create clusters of highly connected users with occasional bridges between clusters (small-world property).';
|
||||
case 'scale-free':
|
||||
return 'Create a power-law distribution where a few users have many connections (influencers) and most have few connections.';
|
||||
case 'clustered':
|
||||
return 'Create distinct communities/clusters with high internal connectivity and sparse connections between clusters.';
|
||||
default:
|
||||
return 'Create random connections with varying connection strengths.';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze network properties
|
||||
*/
|
||||
async analyzeNetwork(data: GraphData): Promise<{
|
||||
avgDegree: number;
|
||||
maxDegree: number;
|
||||
communities?: number;
|
||||
clustering?: number;
|
||||
}> {
|
||||
const degrees = new Map<string, number>();
|
||||
|
||||
for (const edge of data.edges) {
|
||||
degrees.set(edge.source, (degrees.get(edge.source) || 0) + 1);
|
||||
degrees.set(edge.target, (degrees.get(edge.target) || 0) + 1);
|
||||
}
|
||||
|
||||
const degreeValues = Array.from(degrees.values());
|
||||
const avgDegree = degreeValues.reduce((a, b) => a + b, 0) / degreeValues.length;
|
||||
const maxDegree = Math.max(...degreeValues);
|
||||
|
||||
return {
|
||||
avgDegree,
|
||||
maxDegree
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a social network generator
|
||||
*/
|
||||
export function createSocialNetworkGenerator(client: OpenRouterClient): SocialNetworkGenerator {
|
||||
return new SocialNetworkGenerator(client);
|
||||
}
|
||||
34
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.d.ts
vendored
Normal file
34
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.d.ts
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Temporal events generator for time-series graph data
|
||||
*/
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import { TemporalEventOptions, TemporalEvent, GraphData, GraphGenerationResult } from '../types.js';
|
||||
export declare class TemporalEventsGenerator {
|
||||
private client;
|
||||
constructor(client: OpenRouterClient);
|
||||
/**
|
||||
* Generate temporal event graph data
|
||||
*/
|
||||
generate(options: TemporalEventOptions): Promise<GraphGenerationResult<GraphData>>;
|
||||
/**
|
||||
* Generate temporal events
|
||||
*/
|
||||
private generateEvents;
|
||||
/**
|
||||
* Generate entities from events
|
||||
*/
|
||||
private generateEntities;
|
||||
/**
|
||||
* Analyze temporal patterns
|
||||
*/
|
||||
analyzeTemporalPatterns(events: TemporalEvent[]): Promise<{
|
||||
eventsPerHour: Record<string, number>;
|
||||
eventTypeDistribution: Record<string, number>;
|
||||
avgTimeBetweenEvents: number;
|
||||
}>;
|
||||
}
|
||||
/**
|
||||
* Create a temporal events generator
|
||||
*/
|
||||
export declare function createTemporalEventsGenerator(client: OpenRouterClient): TemporalEventsGenerator;
|
||||
//# sourceMappingURL=temporal-events.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"temporal-events.d.ts","sourceRoot":"","sources":["temporal-events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,SAAS,EAGT,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAQrB,qBAAa,uBAAuB;IACtB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAE5C;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAiGxF;;OAEG;YACW,cAAc;IA+D5B;;OAEG;YACW,gBAAgB;IAiD9B;;OAEG;IACG,uBAAuB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAC9D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9C,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CAgCH;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,gBAAgB,GAAG,uBAAuB,CAE/F"}
|
||||
232
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.js
vendored
Normal file
232
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.js
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Temporal events generator for time-series graph data
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TemporalEventsGenerator = void 0;
|
||||
exports.createTemporalEventsGenerator = createTemporalEventsGenerator;
|
||||
class TemporalEventsGenerator {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
/**
|
||||
* Generate temporal event graph data
|
||||
*/
|
||||
async generate(options) {
|
||||
const startTime = Date.now();
|
||||
// Generate events
|
||||
const events = await this.generateEvents(options);
|
||||
// Generate entities involved in events
|
||||
const entities = await this.generateEntities(events, options);
|
||||
// Convert to graph structure
|
||||
const eventNodes = events.map(event => ({
|
||||
id: event.id,
|
||||
labels: ['Event', event.type],
|
||||
properties: {
|
||||
type: event.type,
|
||||
timestamp: event.timestamp.toISOString(),
|
||||
...event.properties
|
||||
}
|
||||
}));
|
||||
const entityNodes = entities.map(entity => ({
|
||||
id: entity.id,
|
||||
labels: ['Entity', entity.type],
|
||||
properties: entity.properties
|
||||
}));
|
||||
const edges = [];
|
||||
let edgeId = 0;
|
||||
// Create edges between events and entities
|
||||
for (const event of events) {
|
||||
for (const entityId of event.entities) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: 'INVOLVES',
|
||||
source: event.id,
|
||||
target: entityId,
|
||||
properties: {
|
||||
timestamp: event.timestamp.toISOString()
|
||||
}
|
||||
});
|
||||
}
|
||||
// Create edges for relationships
|
||||
if (event.relationships) {
|
||||
for (const rel of event.relationships) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: rel.type,
|
||||
source: event.id,
|
||||
target: rel.target,
|
||||
properties: {
|
||||
timestamp: event.timestamp.toISOString()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create temporal sequences (NEXT relationships)
|
||||
const sortedEvents = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
||||
for (let i = 0; i < sortedEvents.length - 1; i++) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: 'NEXT',
|
||||
source: sortedEvents[i].id,
|
||||
target: sortedEvents[i + 1].id,
|
||||
properties: {
|
||||
time_diff_ms: sortedEvents[i + 1].timestamp.getTime() - sortedEvents[i].timestamp.getTime()
|
||||
}
|
||||
});
|
||||
}
|
||||
const data = {
|
||||
nodes: [...eventNodes, ...entityNodes],
|
||||
edges,
|
||||
metadata: {
|
||||
domain: 'temporal-events',
|
||||
generated_at: new Date(),
|
||||
total_nodes: eventNodes.length + entityNodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate temporal events
|
||||
*/
|
||||
async generateEvents(options) {
|
||||
const startDate = new Date(options.startDate);
|
||||
const endDate = new Date(options.endDate);
|
||||
const daysDiff = Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
|
||||
const totalEvents = (options.eventsPerDay || 10) * daysDiff;
|
||||
const systemPrompt = 'You are an expert at generating realistic temporal event sequences. Create events that follow logical patterns and causality.';
|
||||
const userPrompt = `Generate ${totalEvents} temporal events between ${startDate.toISOString()} and ${endDate.toISOString()}.
|
||||
|
||||
Event types to include: ${options.eventTypes.join(', ')}
|
||||
|
||||
Each event should have:
|
||||
- id: unique event ID (format: event_XXXXX)
|
||||
- type: one of the specified event types
|
||||
- timestamp: ISO 8601 timestamp within the date range
|
||||
- entities: array of entity IDs involved (format: entity_XXXXX)
|
||||
- properties: relevant properties for the event
|
||||
- relationships: (optional) array of relationships to other events/entities
|
||||
|
||||
Create realistic temporal patterns (e.g., business hours for work events, clustering of related events).
|
||||
|
||||
Return a JSON array sorted by timestamp.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "event_00001",
|
||||
"type": "login",
|
||||
"timestamp": "2024-01-15T09:23:15Z",
|
||||
"entities": ["entity_user_001"],
|
||||
"properties": {
|
||||
"ip_address": "192.168.1.100",
|
||||
"device": "desktop",
|
||||
"success": true
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"type": "TRIGGERED_BY",
|
||||
"target": "entity_user_001"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
const events = await this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, totalEvents * 150)
|
||||
});
|
||||
// Convert timestamp strings to Date objects
|
||||
return events.map(event => ({
|
||||
...event,
|
||||
timestamp: new Date(event.timestamp)
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Generate entities from events
|
||||
*/
|
||||
async generateEntities(events, options) {
|
||||
const uniqueEntityIds = new Set();
|
||||
events.forEach(event => {
|
||||
event.entities.forEach(entityId => uniqueEntityIds.add(entityId));
|
||||
});
|
||||
const entityIds = Array.from(uniqueEntityIds);
|
||||
const entityCount = options.entities || entityIds.length;
|
||||
const systemPrompt = 'You are an expert at creating entity profiles for event-driven systems.';
|
||||
const sampleIds = entityIds.slice(0, 50).join(', ');
|
||||
const userPrompt = `Generate ${entityCount} entity profiles for entities involved in temporal events.
|
||||
|
||||
Sample entity IDs that must be included: ${sampleIds}
|
||||
|
||||
Each entity should have:
|
||||
- id: the entity ID
|
||||
- type: entity type (User, System, Device, Service, etc.)
|
||||
- properties: relevant properties for the entity
|
||||
|
||||
Return a JSON array of entities.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "entity_user_001",
|
||||
"type": "User",
|
||||
"properties": {
|
||||
"name": "Alice Smith",
|
||||
"email": "alice@example.com",
|
||||
"role": "developer",
|
||||
"created_at": "2023-01-15T00:00:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
return this.client.generateStructured(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, entityCount * 100)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Analyze temporal patterns
|
||||
*/
|
||||
async analyzeTemporalPatterns(events) {
|
||||
const eventsPerHour = {};
|
||||
const eventTypeDistribution = {};
|
||||
const timeDiffs = [];
|
||||
const sortedEvents = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
||||
for (let i = 0; i < sortedEvents.length; i++) {
|
||||
const event = sortedEvents[i];
|
||||
const hour = event.timestamp.toISOString().substring(0, 13);
|
||||
eventsPerHour[hour] = (eventsPerHour[hour] || 0) + 1;
|
||||
eventTypeDistribution[event.type] = (eventTypeDistribution[event.type] || 0) + 1;
|
||||
if (i > 0) {
|
||||
timeDiffs.push(event.timestamp.getTime() - sortedEvents[i - 1].timestamp.getTime());
|
||||
}
|
||||
}
|
||||
const avgTimeBetweenEvents = timeDiffs.length > 0
|
||||
? timeDiffs.reduce((a, b) => a + b, 0) / timeDiffs.length
|
||||
: 0;
|
||||
return {
|
||||
eventsPerHour,
|
||||
eventTypeDistribution,
|
||||
avgTimeBetweenEvents
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.TemporalEventsGenerator = TemporalEventsGenerator;
|
||||
/**
|
||||
* Create a temporal events generator
|
||||
*/
|
||||
function createTemporalEventsGenerator(client) {
|
||||
return new TemporalEventsGenerator(client);
|
||||
}
|
||||
//# sourceMappingURL=temporal-events.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
288
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.ts
vendored
Normal file
288
vendor/ruvector/npm/packages/graph-data-generator/src/generators/temporal-events.ts
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* Temporal events generator for time-series graph data
|
||||
*/
|
||||
|
||||
import { OpenRouterClient } from '../openrouter-client.js';
|
||||
import {
|
||||
TemporalEventOptions,
|
||||
TemporalEvent,
|
||||
GraphData,
|
||||
GraphNode,
|
||||
GraphEdge,
|
||||
GraphGenerationResult
|
||||
} from '../types.js';
|
||||
|
||||
interface EntityData {
|
||||
id: string;
|
||||
type: string;
|
||||
properties: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export class TemporalEventsGenerator {
|
||||
constructor(private client: OpenRouterClient) {}
|
||||
|
||||
/**
|
||||
* Generate temporal event graph data
|
||||
*/
|
||||
async generate(options: TemporalEventOptions): Promise<GraphGenerationResult<GraphData>> {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Generate events
|
||||
const events = await this.generateEvents(options);
|
||||
|
||||
// Generate entities involved in events
|
||||
const entities = await this.generateEntities(events, options);
|
||||
|
||||
// Convert to graph structure
|
||||
const eventNodes: GraphNode[] = events.map(event => ({
|
||||
id: event.id,
|
||||
labels: ['Event', event.type],
|
||||
properties: {
|
||||
type: event.type,
|
||||
timestamp: event.timestamp.toISOString(),
|
||||
...event.properties
|
||||
}
|
||||
}));
|
||||
|
||||
const entityNodes: GraphNode[] = entities.map(entity => ({
|
||||
id: entity.id,
|
||||
labels: ['Entity', entity.type],
|
||||
properties: entity.properties
|
||||
}));
|
||||
|
||||
const edges: GraphEdge[] = [];
|
||||
let edgeId = 0;
|
||||
|
||||
// Create edges between events and entities
|
||||
for (const event of events) {
|
||||
for (const entityId of event.entities) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: 'INVOLVES',
|
||||
source: event.id,
|
||||
target: entityId,
|
||||
properties: {
|
||||
timestamp: event.timestamp.toISOString()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Create edges for relationships
|
||||
if (event.relationships) {
|
||||
for (const rel of event.relationships) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: rel.type,
|
||||
source: event.id,
|
||||
target: rel.target,
|
||||
properties: {
|
||||
timestamp: event.timestamp.toISOString()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create temporal sequences (NEXT relationships)
|
||||
const sortedEvents = [...events].sort((a, b) =>
|
||||
a.timestamp.getTime() - b.timestamp.getTime()
|
||||
);
|
||||
|
||||
for (let i = 0; i < sortedEvents.length - 1; i++) {
|
||||
edges.push({
|
||||
id: `edge_${edgeId++}`,
|
||||
type: 'NEXT',
|
||||
source: sortedEvents[i].id,
|
||||
target: sortedEvents[i + 1].id,
|
||||
properties: {
|
||||
time_diff_ms: sortedEvents[i + 1].timestamp.getTime() - sortedEvents[i].timestamp.getTime()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const data: GraphData = {
|
||||
nodes: [...eventNodes, ...entityNodes],
|
||||
edges,
|
||||
metadata: {
|
||||
domain: 'temporal-events',
|
||||
generated_at: new Date(),
|
||||
total_nodes: eventNodes.length + entityNodes.length,
|
||||
total_edges: edges.length
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
metadata: {
|
||||
generated_at: new Date(),
|
||||
model: this.client.getConfig().model || 'moonshot/kimi-k2-instruct',
|
||||
duration: Date.now() - startTime
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate temporal events
|
||||
*/
|
||||
private async generateEvents(options: TemporalEventOptions): Promise<TemporalEvent[]> {
|
||||
const startDate = new Date(options.startDate);
|
||||
const endDate = new Date(options.endDate);
|
||||
const daysDiff = Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
|
||||
const totalEvents = (options.eventsPerDay || 10) * daysDiff;
|
||||
|
||||
const systemPrompt = 'You are an expert at generating realistic temporal event sequences. Create events that follow logical patterns and causality.';
|
||||
|
||||
const userPrompt = `Generate ${totalEvents} temporal events between ${startDate.toISOString()} and ${endDate.toISOString()}.
|
||||
|
||||
Event types to include: ${options.eventTypes.join(', ')}
|
||||
|
||||
Each event should have:
|
||||
- id: unique event ID (format: event_XXXXX)
|
||||
- type: one of the specified event types
|
||||
- timestamp: ISO 8601 timestamp within the date range
|
||||
- entities: array of entity IDs involved (format: entity_XXXXX)
|
||||
- properties: relevant properties for the event
|
||||
- relationships: (optional) array of relationships to other events/entities
|
||||
|
||||
Create realistic temporal patterns (e.g., business hours for work events, clustering of related events).
|
||||
|
||||
Return a JSON array sorted by timestamp.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "event_00001",
|
||||
"type": "login",
|
||||
"timestamp": "2024-01-15T09:23:15Z",
|
||||
"entities": ["entity_user_001"],
|
||||
"properties": {
|
||||
"ip_address": "192.168.1.100",
|
||||
"device": "desktop",
|
||||
"success": true
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"type": "TRIGGERED_BY",
|
||||
"target": "entity_user_001"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
const events = await this.client.generateStructured<TemporalEvent[]>(
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
{
|
||||
temperature: 0.8,
|
||||
maxTokens: Math.min(8000, totalEvents * 150)
|
||||
}
|
||||
);
|
||||
|
||||
// Convert timestamp strings to Date objects
|
||||
return events.map(event => ({
|
||||
...event,
|
||||
timestamp: new Date(event.timestamp)
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate entities from events
|
||||
*/
|
||||
private async generateEntities(
|
||||
events: TemporalEvent[],
|
||||
options: TemporalEventOptions
|
||||
): Promise<EntityData[]> {
|
||||
const uniqueEntityIds = new Set<string>();
|
||||
events.forEach(event => {
|
||||
event.entities.forEach(entityId => uniqueEntityIds.add(entityId));
|
||||
});
|
||||
|
||||
const entityIds = Array.from(uniqueEntityIds);
|
||||
const entityCount = options.entities || entityIds.length;
|
||||
|
||||
const systemPrompt = 'You are an expert at creating entity profiles for event-driven systems.';
|
||||
|
||||
const sampleIds = entityIds.slice(0, 50).join(', ');
|
||||
|
||||
const userPrompt = `Generate ${entityCount} entity profiles for entities involved in temporal events.
|
||||
|
||||
Sample entity IDs that must be included: ${sampleIds}
|
||||
|
||||
Each entity should have:
|
||||
- id: the entity ID
|
||||
- type: entity type (User, System, Device, Service, etc.)
|
||||
- properties: relevant properties for the entity
|
||||
|
||||
Return a JSON array of entities.
|
||||
|
||||
Example format:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"id": "entity_user_001",
|
||||
"type": "User",
|
||||
"properties": {
|
||||
"name": "Alice Smith",
|
||||
"email": "alice@example.com",
|
||||
"role": "developer",
|
||||
"created_at": "2023-01-15T00:00:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
\`\`\``;
|
||||
|
||||
return this.client.generateStructured<EntityData[]>(systemPrompt, userPrompt, {
|
||||
temperature: 0.7,
|
||||
maxTokens: Math.min(8000, entityCount * 100)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze temporal patterns
|
||||
*/
|
||||
async analyzeTemporalPatterns(events: TemporalEvent[]): Promise<{
|
||||
eventsPerHour: Record<string, number>;
|
||||
eventTypeDistribution: Record<string, number>;
|
||||
avgTimeBetweenEvents: number;
|
||||
}> {
|
||||
const eventsPerHour: Record<string, number> = {};
|
||||
const eventTypeDistribution: Record<string, number> = {};
|
||||
const timeDiffs: number[] = [];
|
||||
|
||||
const sortedEvents = [...events].sort((a, b) =>
|
||||
a.timestamp.getTime() - b.timestamp.getTime()
|
||||
);
|
||||
|
||||
for (let i = 0; i < sortedEvents.length; i++) {
|
||||
const event = sortedEvents[i];
|
||||
const hour = event.timestamp.toISOString().substring(0, 13);
|
||||
eventsPerHour[hour] = (eventsPerHour[hour] || 0) + 1;
|
||||
eventTypeDistribution[event.type] = (eventTypeDistribution[event.type] || 0) + 1;
|
||||
|
||||
if (i > 0) {
|
||||
timeDiffs.push(
|
||||
event.timestamp.getTime() - sortedEvents[i - 1].timestamp.getTime()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const avgTimeBetweenEvents = timeDiffs.length > 0
|
||||
? timeDiffs.reduce((a, b) => a + b, 0) / timeDiffs.length
|
||||
: 0;
|
||||
|
||||
return {
|
||||
eventsPerHour,
|
||||
eventTypeDistribution,
|
||||
avgTimeBetweenEvents
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporal events generator
|
||||
*/
|
||||
export function createTemporalEventsGenerator(client: OpenRouterClient): TemporalEventsGenerator {
|
||||
return new TemporalEventsGenerator(client);
|
||||
}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/index.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAA0B,MAAM,wBAAwB,CAAC;AAiBlF,OAAO,EAAE,eAAe,EAAyB,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAA6B,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,SAAS,EACT,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,qBAAqB,CAA8B;IAC3D,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,mBAAmB,CAAC,CAAsB;gBAEtC,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IASlD;;OAEG;IACG,sBAAsB,CAC1B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAgB5C;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAc5C;;OAEG;IACG,sBAAsB,CAC1B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAc5C;;OAEG;IACG,2BAA2B,CAC/B,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAc5C;;OAEG;IACG,oBAAoB,CACxB,IAAI,EAAE,SAAS,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,SAAS,CAAC;IAQrB;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;QACxC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,GAAG,MAAM;IAIV;;OAEG;IACH,SAAS,IAAI,gBAAgB;IAI7B;;OAEG;IACH,kBAAkB,IAAI,eAAe;IAIrC;;OAEG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;CAG1D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACjC,kBAAkB,CAEpB;AAGD,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AAGnC,eAAe,kBAAkB,CAAC"}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/index.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
||||
202
vendor/ruvector/npm/packages/graph-data-generator/src/index.ts
vendored
Normal file
202
vendor/ruvector/npm/packages/graph-data-generator/src/index.ts
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @ruvector/graph-data-generator - AI-powered synthetic graph data generation
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import 'dotenv/config';
|
||||
import { OpenRouterClient, createOpenRouterClient } from './openrouter-client.js';
|
||||
import {
|
||||
KnowledgeGraphGenerator,
|
||||
createKnowledgeGraphGenerator
|
||||
} from './generators/knowledge-graph.js';
|
||||
import {
|
||||
SocialNetworkGenerator,
|
||||
createSocialNetworkGenerator
|
||||
} from './generators/social-network.js';
|
||||
import {
|
||||
TemporalEventsGenerator,
|
||||
createTemporalEventsGenerator
|
||||
} from './generators/temporal-events.js';
|
||||
import {
|
||||
EntityRelationshipGenerator,
|
||||
createEntityRelationshipGenerator
|
||||
} from './generators/entity-relationships.js';
|
||||
import { CypherGenerator, createCypherGenerator } from './cypher-generator.js';
|
||||
import { EmbeddingEnrichment, createEmbeddingEnrichment } from './embedding-enrichment.js';
|
||||
import {
|
||||
OpenRouterConfig,
|
||||
KnowledgeGraphOptions,
|
||||
SocialNetworkOptions,
|
||||
TemporalEventOptions,
|
||||
EntityRelationshipOptions,
|
||||
GraphGenerationResult,
|
||||
GraphData,
|
||||
EmbeddingConfig
|
||||
} from './types.js';
|
||||
|
||||
/**
|
||||
* Main GraphDataGenerator class
|
||||
*/
|
||||
export class GraphDataGenerator {
|
||||
private client: OpenRouterClient;
|
||||
private knowledgeGraphGen: KnowledgeGraphGenerator;
|
||||
private socialNetworkGen: SocialNetworkGenerator;
|
||||
private temporalEventsGen: TemporalEventsGenerator;
|
||||
private entityRelationshipGen: EntityRelationshipGenerator;
|
||||
private cypherGen: CypherGenerator;
|
||||
private embeddingEnrichment?: EmbeddingEnrichment;
|
||||
|
||||
constructor(config: Partial<OpenRouterConfig> = {}) {
|
||||
this.client = createOpenRouterClient(config);
|
||||
this.knowledgeGraphGen = createKnowledgeGraphGenerator(this.client);
|
||||
this.socialNetworkGen = createSocialNetworkGenerator(this.client);
|
||||
this.temporalEventsGen = createTemporalEventsGenerator(this.client);
|
||||
this.entityRelationshipGen = createEntityRelationshipGenerator(this.client);
|
||||
this.cypherGen = createCypherGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a knowledge graph
|
||||
*/
|
||||
async generateKnowledgeGraph(
|
||||
options: KnowledgeGraphOptions
|
||||
): Promise<GraphGenerationResult<GraphData>> {
|
||||
const result = await this.knowledgeGraphGen.generate(options);
|
||||
|
||||
// Add embeddings if requested
|
||||
if (options.includeEmbeddings) {
|
||||
result.data = await this.enrichWithEmbeddings(result.data, {
|
||||
dimensions: options.embeddingDimension
|
||||
});
|
||||
}
|
||||
|
||||
// Generate Cypher statements
|
||||
result.cypher = this.cypherGen.generate(result.data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a social network
|
||||
*/
|
||||
async generateSocialNetwork(
|
||||
options: SocialNetworkOptions
|
||||
): Promise<GraphGenerationResult<GraphData>> {
|
||||
const result = await this.socialNetworkGen.generate(options);
|
||||
|
||||
// Add embeddings if requested
|
||||
if (options.includeEmbeddings) {
|
||||
result.data = await this.enrichWithEmbeddings(result.data);
|
||||
}
|
||||
|
||||
// Generate Cypher statements
|
||||
result.cypher = this.cypherGen.generate(result.data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate temporal events
|
||||
*/
|
||||
async generateTemporalEvents(
|
||||
options: TemporalEventOptions
|
||||
): Promise<GraphGenerationResult<GraphData>> {
|
||||
const result = await this.temporalEventsGen.generate(options);
|
||||
|
||||
// Add embeddings if requested
|
||||
if (options.includeEmbeddings) {
|
||||
result.data = await this.enrichWithEmbeddings(result.data);
|
||||
}
|
||||
|
||||
// Generate Cypher statements
|
||||
result.cypher = this.cypherGen.generate(result.data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate entity relationships
|
||||
*/
|
||||
async generateEntityRelationships(
|
||||
options: EntityRelationshipOptions
|
||||
): Promise<GraphGenerationResult<GraphData>> {
|
||||
const result = await this.entityRelationshipGen.generate(options);
|
||||
|
||||
// Add embeddings if requested
|
||||
if (options.includeEmbeddings) {
|
||||
result.data = await this.enrichWithEmbeddings(result.data);
|
||||
}
|
||||
|
||||
// Generate Cypher statements
|
||||
result.cypher = this.cypherGen.generate(result.data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich graph data with embeddings
|
||||
*/
|
||||
async enrichWithEmbeddings(
|
||||
data: GraphData,
|
||||
config?: Partial<EmbeddingConfig>
|
||||
): Promise<GraphData> {
|
||||
if (!this.embeddingEnrichment) {
|
||||
this.embeddingEnrichment = createEmbeddingEnrichment(this.client, config);
|
||||
}
|
||||
|
||||
return this.embeddingEnrichment.enrichGraphData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Cypher statements from graph data
|
||||
*/
|
||||
generateCypher(data: GraphData, options?: {
|
||||
useConstraints?: boolean;
|
||||
useIndexes?: boolean;
|
||||
useMerge?: boolean;
|
||||
}): string {
|
||||
return this.cypherGen.generateSetupScript(data, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OpenRouter client
|
||||
*/
|
||||
getClient(): OpenRouterClient {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cypher generator
|
||||
*/
|
||||
getCypherGenerator(): CypherGenerator {
|
||||
return this.cypherGen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embedding enrichment
|
||||
*/
|
||||
getEmbeddingEnrichment(): EmbeddingEnrichment | undefined {
|
||||
return this.embeddingEnrichment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GraphDataGenerator instance
|
||||
*/
|
||||
export function createGraphDataGenerator(
|
||||
config?: Partial<OpenRouterConfig>
|
||||
): GraphDataGenerator {
|
||||
return new GraphDataGenerator(config);
|
||||
}
|
||||
|
||||
// Export all types and utilities
|
||||
export * from './types.js';
|
||||
export * from './openrouter-client.js';
|
||||
export * from './generators/index.js';
|
||||
export * from './cypher-generator.js';
|
||||
export * from './embedding-enrichment.js';
|
||||
export * from './schemas/index.js';
|
||||
|
||||
// Default export
|
||||
export default GraphDataGenerator;
|
||||
41
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.d.ts
vendored
Normal file
41
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.d.ts
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* OpenRouter API client with Kimi K2 support
|
||||
*/
|
||||
import { OpenRouterConfig, OpenRouterRequest, OpenRouterResponse, OpenRouterMessage } from './types.js';
|
||||
export declare class OpenRouterClient {
|
||||
private config;
|
||||
private throttledFetch;
|
||||
constructor(config?: Partial<OpenRouterConfig>);
|
||||
/**
|
||||
* Create a chat completion
|
||||
*/
|
||||
createCompletion(messages: OpenRouterMessage[], options?: Partial<Omit<OpenRouterRequest, 'messages' | 'model'>>): Promise<OpenRouterResponse>;
|
||||
/**
|
||||
* Create a streaming chat completion
|
||||
*/
|
||||
createStreamingCompletion(messages: OpenRouterMessage[], options?: Partial<Omit<OpenRouterRequest, 'messages' | 'model'>>): AsyncGenerator<string, void, unknown>;
|
||||
/**
|
||||
* Generate structured data using prompt engineering
|
||||
*/
|
||||
generateStructured<T = unknown>(systemPrompt: string, userPrompt: string, options?: {
|
||||
temperature?: number;
|
||||
maxTokens?: number;
|
||||
}): Promise<T>;
|
||||
/**
|
||||
* Generate embeddings (if the model supports it)
|
||||
*/
|
||||
generateEmbedding(_text: string): Promise<number[]>;
|
||||
/**
|
||||
* Update configuration
|
||||
*/
|
||||
configure(config: Partial<OpenRouterConfig>): void;
|
||||
/**
|
||||
* Get current configuration
|
||||
*/
|
||||
getConfig(): OpenRouterConfig;
|
||||
}
|
||||
/**
|
||||
* Create a new OpenRouter client
|
||||
*/
|
||||
export declare function createOpenRouterClient(config?: Partial<OpenRouterConfig>): OpenRouterClient;
|
||||
//# sourceMappingURL=openrouter-client.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"openrouter-client.d.ts","sourceRoot":"","sources":["openrouter-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EACL,gBAAgB,EAEhB,iBAAiB,EACjB,kBAAkB,EAElB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,cAAc,CAA2D;gBAErE,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IAmBlD;;OAEG;IACG,gBAAgB,CACpB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,GAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,OAAO,CAAC,CAAM,GACnE,OAAO,CAAC,kBAAkB,CAAC;IAgD9B;;OAEG;IACI,yBAAyB,CAC9B,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,GAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,OAAO,CAAC,CAAM,GACnE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IA2ExC;;OAEG;IACG,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,CAAC,CAAC;IA+Bb;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMzD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,IAAI,gBAAgB;CAG9B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAE3F"}
|
||||
194
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.js
vendored
Normal file
194
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.js
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
"use strict";
|
||||
/**
|
||||
* OpenRouter API client with Kimi K2 support
|
||||
*/
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.OpenRouterClient = void 0;
|
||||
exports.createOpenRouterClient = createOpenRouterClient;
|
||||
const p_retry_1 = __importDefault(require("p-retry"));
|
||||
const p_throttle_1 = __importDefault(require("p-throttle"));
|
||||
const types_js_1 = require("./types.js");
|
||||
class OpenRouterClient {
|
||||
constructor(config = {}) {
|
||||
const apiKey = config.apiKey || process.env.OPENROUTER_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new Error('OpenRouter API key is required. Set OPENROUTER_API_KEY environment variable or pass apiKey in config.');
|
||||
}
|
||||
this.config = types_js_1.OpenRouterConfigSchema.parse({ ...config, apiKey });
|
||||
// Setup rate limiting if configured
|
||||
if (this.config.rateLimit) {
|
||||
this.throttledFetch = (0, p_throttle_1.default)({
|
||||
limit: this.config.rateLimit.requests,
|
||||
interval: this.config.rateLimit.interval
|
||||
})(fetch.bind(globalThis));
|
||||
}
|
||||
else {
|
||||
this.throttledFetch = fetch.bind(globalThis);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create a chat completion
|
||||
*/
|
||||
async createCompletion(messages, options = {}) {
|
||||
const request = {
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
messages,
|
||||
temperature: options.temperature ?? 0.7,
|
||||
max_tokens: options.max_tokens ?? 4096,
|
||||
top_p: options.top_p ?? 1,
|
||||
stream: false,
|
||||
...options
|
||||
};
|
||||
return (0, p_retry_1.default)(async () => {
|
||||
const response = await this.throttledFetch(`${this.config.baseURL}/chat/completions`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.config.apiKey}`,
|
||||
'HTTP-Referer': 'https://github.com/ruvnet/ruvector',
|
||||
'X-Title': 'RuVector Graph Data Generator'
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
signal: AbortSignal.timeout(this.config.timeout || 60000)
|
||||
});
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new types_js_1.OpenRouterError(`OpenRouter API error: ${response.status} ${response.statusText}`, { status: response.status, error });
|
||||
}
|
||||
const data = await response.json();
|
||||
return data;
|
||||
}, {
|
||||
retries: this.config.maxRetries || 3,
|
||||
onFailedAttempt: (error) => {
|
||||
console.warn(`Attempt ${error.attemptNumber} failed. ${error.retriesLeft} retries left.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create a streaming chat completion
|
||||
*/
|
||||
async *createStreamingCompletion(messages, options = {}) {
|
||||
const request = {
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
messages,
|
||||
temperature: options.temperature ?? 0.7,
|
||||
max_tokens: options.max_tokens ?? 4096,
|
||||
top_p: options.top_p ?? 1,
|
||||
stream: true,
|
||||
...options
|
||||
};
|
||||
const response = await this.throttledFetch(`${this.config.baseURL}/chat/completions`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.config.apiKey}`,
|
||||
'HTTP-Referer': 'https://github.com/ruvnet/ruvector',
|
||||
'X-Title': 'RuVector Graph Data Generator'
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
signal: AbortSignal.timeout(this.config.timeout || 60000)
|
||||
});
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new types_js_1.OpenRouterError(`OpenRouter API error: ${response.status} ${response.statusText}`, { status: response.status, error });
|
||||
}
|
||||
if (!response.body) {
|
||||
throw new types_js_1.OpenRouterError('No response body received');
|
||||
}
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done)
|
||||
break;
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const lines = buffer.split('\n');
|
||||
buffer = lines.pop() || '';
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.slice(6).trim();
|
||||
if (data === '[DONE]') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
const content = parsed.choices?.[0]?.delta?.content;
|
||||
if (content) {
|
||||
yield content;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.warn('Failed to parse SSE data:', data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generate structured data using prompt engineering
|
||||
*/
|
||||
async generateStructured(systemPrompt, userPrompt, options) {
|
||||
const messages = [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
];
|
||||
const response = await this.createCompletion(messages, {
|
||||
temperature: options?.temperature ?? 0.7,
|
||||
max_tokens: options?.maxTokens ?? 4096
|
||||
});
|
||||
const content = response.choices[0]?.message?.content;
|
||||
if (!content) {
|
||||
throw new types_js_1.OpenRouterError('No content in response');
|
||||
}
|
||||
// Try to extract JSON from response
|
||||
try {
|
||||
// Look for JSON in code blocks
|
||||
const jsonMatch = content.match(/```(?:json)?\s*(\{[\s\S]*?\}|\[[\s\S]*?\])\s*```/);
|
||||
if (jsonMatch) {
|
||||
return JSON.parse(jsonMatch[1]);
|
||||
}
|
||||
// Try to parse the entire response as JSON
|
||||
return JSON.parse(content);
|
||||
}
|
||||
catch (e) {
|
||||
throw new types_js_1.OpenRouterError('Failed to parse JSON from response', { content, error: e });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generate embeddings (if the model supports it)
|
||||
*/
|
||||
async generateEmbedding(_text) {
|
||||
// Note: Kimi K2 may not support embeddings directly
|
||||
// This is a placeholder for potential future support
|
||||
throw new Error('Embedding generation not yet implemented for Kimi K2');
|
||||
}
|
||||
/**
|
||||
* Update configuration
|
||||
*/
|
||||
configure(config) {
|
||||
this.config = types_js_1.OpenRouterConfigSchema.parse({ ...this.config, ...config });
|
||||
}
|
||||
/**
|
||||
* Get current configuration
|
||||
*/
|
||||
getConfig() {
|
||||
return { ...this.config };
|
||||
}
|
||||
}
|
||||
exports.OpenRouterClient = OpenRouterClient;
|
||||
/**
|
||||
* Create a new OpenRouter client
|
||||
*/
|
||||
function createOpenRouterClient(config) {
|
||||
return new OpenRouterClient(config);
|
||||
}
|
||||
//# sourceMappingURL=openrouter-client.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
244
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.ts
vendored
Normal file
244
vendor/ruvector/npm/packages/graph-data-generator/src/openrouter-client.ts
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* OpenRouter API client with Kimi K2 support
|
||||
*/
|
||||
|
||||
import pRetry from 'p-retry';
|
||||
import pThrottle from 'p-throttle';
|
||||
import {
|
||||
OpenRouterConfig,
|
||||
OpenRouterConfigSchema,
|
||||
OpenRouterRequest,
|
||||
OpenRouterResponse,
|
||||
OpenRouterError,
|
||||
OpenRouterMessage
|
||||
} from './types.js';
|
||||
|
||||
export class OpenRouterClient {
|
||||
private config: OpenRouterConfig;
|
||||
private throttledFetch: (url: string, options: RequestInit) => Promise<Response>;
|
||||
|
||||
constructor(config: Partial<OpenRouterConfig> = {}) {
|
||||
const apiKey = config.apiKey || process.env.OPENROUTER_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new Error('OpenRouter API key is required. Set OPENROUTER_API_KEY environment variable or pass apiKey in config.');
|
||||
}
|
||||
|
||||
this.config = OpenRouterConfigSchema.parse({ ...config, apiKey });
|
||||
|
||||
// Setup rate limiting if configured
|
||||
if (this.config.rateLimit) {
|
||||
this.throttledFetch = pThrottle({
|
||||
limit: this.config.rateLimit.requests,
|
||||
interval: this.config.rateLimit.interval
|
||||
})(fetch.bind(globalThis)) as (url: string, options: RequestInit) => Promise<Response>;
|
||||
} else {
|
||||
this.throttledFetch = fetch.bind(globalThis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a chat completion
|
||||
*/
|
||||
async createCompletion(
|
||||
messages: OpenRouterMessage[],
|
||||
options: Partial<Omit<OpenRouterRequest, 'messages' | 'model'>> = {}
|
||||
): Promise<OpenRouterResponse> {
|
||||
const request: OpenRouterRequest = {
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
messages,
|
||||
temperature: options.temperature ?? 0.7,
|
||||
max_tokens: options.max_tokens ?? 4096,
|
||||
top_p: options.top_p ?? 1,
|
||||
stream: false,
|
||||
...options
|
||||
};
|
||||
|
||||
return pRetry(
|
||||
async () => {
|
||||
const response = await this.throttledFetch(
|
||||
`${this.config.baseURL}/chat/completions`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.config.apiKey}`,
|
||||
'HTTP-Referer': 'https://github.com/ruvnet/ruvector',
|
||||
'X-Title': 'RuVector Graph Data Generator'
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
signal: AbortSignal.timeout(this.config.timeout || 60000)
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new OpenRouterError(
|
||||
`OpenRouter API error: ${response.status} ${response.statusText}`,
|
||||
{ status: response.status, error }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json() as OpenRouterResponse;
|
||||
return data;
|
||||
},
|
||||
{
|
||||
retries: this.config.maxRetries || 3,
|
||||
onFailedAttempt: (error) => {
|
||||
console.warn(`Attempt ${error.attemptNumber} failed. ${error.retriesLeft} retries left.`);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a streaming chat completion
|
||||
*/
|
||||
async *createStreamingCompletion(
|
||||
messages: OpenRouterMessage[],
|
||||
options: Partial<Omit<OpenRouterRequest, 'messages' | 'model'>> = {}
|
||||
): AsyncGenerator<string, void, unknown> {
|
||||
const request: OpenRouterRequest = {
|
||||
model: this.config.model || 'moonshot/kimi-k2-instruct',
|
||||
messages,
|
||||
temperature: options.temperature ?? 0.7,
|
||||
max_tokens: options.max_tokens ?? 4096,
|
||||
top_p: options.top_p ?? 1,
|
||||
stream: true,
|
||||
...options
|
||||
};
|
||||
|
||||
const response = await this.throttledFetch(
|
||||
`${this.config.baseURL}/chat/completions`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.config.apiKey}`,
|
||||
'HTTP-Referer': 'https://github.com/ruvnet/ruvector',
|
||||
'X-Title': 'RuVector Graph Data Generator'
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
signal: AbortSignal.timeout(this.config.timeout || 60000)
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new OpenRouterError(
|
||||
`OpenRouter API error: ${response.status} ${response.statusText}`,
|
||||
{ status: response.status, error }
|
||||
);
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
throw new OpenRouterError('No response body received');
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const lines = buffer.split('\n');
|
||||
buffer = lines.pop() || '';
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.slice(6).trim();
|
||||
if (data === '[DONE]') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
const content = parsed.choices?.[0]?.delta?.content;
|
||||
if (content) {
|
||||
yield content;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse SSE data:', data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate structured data using prompt engineering
|
||||
*/
|
||||
async generateStructured<T = unknown>(
|
||||
systemPrompt: string,
|
||||
userPrompt: string,
|
||||
options?: {
|
||||
temperature?: number;
|
||||
maxTokens?: number;
|
||||
}
|
||||
): Promise<T> {
|
||||
const messages: OpenRouterMessage[] = [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
];
|
||||
|
||||
const response = await this.createCompletion(messages, {
|
||||
temperature: options?.temperature ?? 0.7,
|
||||
max_tokens: options?.maxTokens ?? 4096
|
||||
});
|
||||
|
||||
const content = response.choices[0]?.message?.content;
|
||||
if (!content) {
|
||||
throw new OpenRouterError('No content in response');
|
||||
}
|
||||
|
||||
// Try to extract JSON from response
|
||||
try {
|
||||
// Look for JSON in code blocks
|
||||
const jsonMatch = content.match(/```(?:json)?\s*(\{[\s\S]*?\}|\[[\s\S]*?\])\s*```/);
|
||||
if (jsonMatch) {
|
||||
return JSON.parse(jsonMatch[1]) as T;
|
||||
}
|
||||
|
||||
// Try to parse the entire response as JSON
|
||||
return JSON.parse(content) as T;
|
||||
} catch (e) {
|
||||
throw new OpenRouterError('Failed to parse JSON from response', { content, error: e });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate embeddings (if the model supports it)
|
||||
*/
|
||||
async generateEmbedding(_text: string): Promise<number[]> {
|
||||
// Note: Kimi K2 may not support embeddings directly
|
||||
// This is a placeholder for potential future support
|
||||
throw new Error('Embedding generation not yet implemented for Kimi K2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration
|
||||
*/
|
||||
configure(config: Partial<OpenRouterConfig>): void {
|
||||
this.config = OpenRouterConfigSchema.parse({ ...this.config, ...config });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current configuration
|
||||
*/
|
||||
getConfig(): OpenRouterConfig {
|
||||
return { ...this.config };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OpenRouter client
|
||||
*/
|
||||
export function createOpenRouterClient(config?: Partial<OpenRouterConfig>): OpenRouterClient {
|
||||
return new OpenRouterClient(config);
|
||||
}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;EAK1B,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;EAO1B,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU1B,CAAC;AAGH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAQtC,CAAC;AAGH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;EAOrC,CAAC;AAGH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;EAOrC,CAAC;AAGH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;EAO1C,CAAC;AAGH,eAAO,MAAM,qBAAqB;;;;;;;;;EAGhC,CAAC;AAGH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ5B,CAAC;AAGH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAatC,CAAC;AAGH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;EAE9C;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO;;;;;;;;EAE7D;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO;;;;;;;EAE5D;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO;;;;;;;EAE5D;AAED,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,OAAO;;;;;;;EAEjE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO;;;;;;;;;;;EAEjD;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE5D"}
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
139
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.ts
vendored
Normal file
139
vendor/ruvector/npm/packages/graph-data-generator/src/schemas/index.ts
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Zod schemas for graph data validation
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
// Graph node schema
|
||||
export const GraphNodeSchema = z.object({
|
||||
id: z.string(),
|
||||
labels: z.array(z.string()),
|
||||
properties: z.record(z.string(), z.unknown()),
|
||||
embedding: z.array(z.number()).optional()
|
||||
});
|
||||
|
||||
// Graph edge schema
|
||||
export const GraphEdgeSchema = z.object({
|
||||
id: z.string(),
|
||||
type: z.string(),
|
||||
source: z.string(),
|
||||
target: z.string(),
|
||||
properties: z.record(z.string(), z.unknown()),
|
||||
embedding: z.array(z.number()).optional()
|
||||
});
|
||||
|
||||
// Graph data schema
|
||||
export const GraphDataSchema = z.object({
|
||||
nodes: z.array(GraphNodeSchema),
|
||||
edges: z.array(GraphEdgeSchema),
|
||||
metadata: z.object({
|
||||
domain: z.string().optional(),
|
||||
generated_at: z.date().optional(),
|
||||
model: z.string().optional(),
|
||||
total_nodes: z.number().optional(),
|
||||
total_edges: z.number().optional()
|
||||
}).optional()
|
||||
});
|
||||
|
||||
// Knowledge graph options schema
|
||||
export const KnowledgeGraphOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
entities: z.number().positive(),
|
||||
relationships: z.number().positive(),
|
||||
entityTypes: z.array(z.string()).optional(),
|
||||
relationshipTypes: z.array(z.string()).optional(),
|
||||
includeEmbeddings: z.boolean().optional(),
|
||||
embeddingDimension: z.number().positive().optional()
|
||||
});
|
||||
|
||||
// Social network options schema
|
||||
export const SocialNetworkOptionsSchema = z.object({
|
||||
users: z.number().positive(),
|
||||
avgConnections: z.number().positive(),
|
||||
networkType: z.enum(['random', 'small-world', 'scale-free', 'clustered']).optional(),
|
||||
communities: z.number().positive().optional(),
|
||||
includeMetadata: z.boolean().optional(),
|
||||
includeEmbeddings: z.boolean().optional()
|
||||
});
|
||||
|
||||
// Temporal event options schema
|
||||
export const TemporalEventOptionsSchema = z.object({
|
||||
startDate: z.union([z.date(), z.string()]),
|
||||
endDate: z.union([z.date(), z.string()]),
|
||||
eventTypes: z.array(z.string()),
|
||||
eventsPerDay: z.number().positive().optional(),
|
||||
entities: z.number().positive().optional(),
|
||||
includeEmbeddings: z.boolean().optional()
|
||||
});
|
||||
|
||||
// Entity relationship options schema
|
||||
export const EntityRelationshipOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
entityCount: z.number().positive(),
|
||||
relationshipDensity: z.number().min(0).max(1),
|
||||
entitySchema: z.record(z.string(), z.unknown()).optional(),
|
||||
relationshipTypes: z.array(z.string()).optional(),
|
||||
includeEmbeddings: z.boolean().optional()
|
||||
});
|
||||
|
||||
// Cypher statement schema
|
||||
export const CypherStatementSchema = z.object({
|
||||
query: z.string(),
|
||||
parameters: z.record(z.string(), z.unknown()).optional()
|
||||
});
|
||||
|
||||
// Cypher batch schema
|
||||
export const CypherBatchSchema = z.object({
|
||||
statements: z.array(CypherStatementSchema),
|
||||
metadata: z.object({
|
||||
total_nodes: z.number().optional(),
|
||||
total_relationships: z.number().optional(),
|
||||
labels: z.array(z.string()).optional(),
|
||||
relationship_types: z.array(z.string()).optional()
|
||||
}).optional()
|
||||
});
|
||||
|
||||
// Graph generation result schema
|
||||
export const GraphGenerationResultSchema = z.object({
|
||||
data: GraphDataSchema,
|
||||
metadata: z.object({
|
||||
generated_at: z.date(),
|
||||
model: z.string(),
|
||||
duration: z.number(),
|
||||
token_usage: z.object({
|
||||
prompt_tokens: z.number(),
|
||||
completion_tokens: z.number(),
|
||||
total_tokens: z.number()
|
||||
}).optional()
|
||||
}),
|
||||
cypher: CypherBatchSchema.optional()
|
||||
});
|
||||
|
||||
// Validation helpers
|
||||
export function validateGraphData(data: unknown) {
|
||||
return GraphDataSchema.parse(data);
|
||||
}
|
||||
|
||||
export function validateKnowledgeGraphOptions(options: unknown) {
|
||||
return KnowledgeGraphOptionsSchema.parse(options);
|
||||
}
|
||||
|
||||
export function validateSocialNetworkOptions(options: unknown) {
|
||||
return SocialNetworkOptionsSchema.parse(options);
|
||||
}
|
||||
|
||||
export function validateTemporalEventOptions(options: unknown) {
|
||||
return TemporalEventOptionsSchema.parse(options);
|
||||
}
|
||||
|
||||
export function validateEntityRelationshipOptions(options: unknown) {
|
||||
return EntityRelationshipOptionsSchema.parse(options);
|
||||
}
|
||||
|
||||
export function validateCypherBatch(batch: unknown) {
|
||||
return CypherBatchSchema.parse(batch);
|
||||
}
|
||||
|
||||
export function validateGraphGenerationResult(result: unknown) {
|
||||
return GraphGenerationResultSchema.parse(result);
|
||||
}
|
||||
218
vendor/ruvector/npm/packages/graph-data-generator/src/types.d.ts
vendored
Normal file
218
vendor/ruvector/npm/packages/graph-data-generator/src/types.d.ts
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* Core types and interfaces for graph-data-generator
|
||||
*/
|
||||
import { z } from 'zod';
|
||||
export interface GraphNode {
|
||||
id: string;
|
||||
labels: string[];
|
||||
properties: Record<string, unknown>;
|
||||
embedding?: number[];
|
||||
}
|
||||
export interface GraphEdge {
|
||||
id: string;
|
||||
type: string;
|
||||
source: string;
|
||||
target: string;
|
||||
properties: Record<string, unknown>;
|
||||
embedding?: number[];
|
||||
}
|
||||
export interface GraphData {
|
||||
nodes: GraphNode[];
|
||||
edges: GraphEdge[];
|
||||
metadata?: {
|
||||
domain?: string;
|
||||
generated_at?: Date;
|
||||
model?: string;
|
||||
total_nodes?: number;
|
||||
total_edges?: number;
|
||||
};
|
||||
}
|
||||
export interface KnowledgeTriple {
|
||||
subject: string;
|
||||
predicate: string;
|
||||
object: string;
|
||||
confidence?: number;
|
||||
source?: string;
|
||||
}
|
||||
export interface KnowledgeGraphOptions {
|
||||
domain: string;
|
||||
entities: number;
|
||||
relationships: number;
|
||||
entityTypes?: string[];
|
||||
relationshipTypes?: string[];
|
||||
includeEmbeddings?: boolean;
|
||||
embeddingDimension?: number;
|
||||
}
|
||||
export interface SocialNetworkOptions {
|
||||
users: number;
|
||||
avgConnections: number;
|
||||
networkType?: 'random' | 'small-world' | 'scale-free' | 'clustered';
|
||||
communities?: number;
|
||||
includeMetadata?: boolean;
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
export interface SocialNode {
|
||||
id: string;
|
||||
username: string;
|
||||
profile: {
|
||||
name?: string;
|
||||
bio?: string;
|
||||
joined?: Date;
|
||||
followers?: number;
|
||||
following?: number;
|
||||
};
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
export interface TemporalEventOptions {
|
||||
startDate: Date | string;
|
||||
endDate: Date | string;
|
||||
eventTypes: string[];
|
||||
eventsPerDay?: number;
|
||||
entities?: number;
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
export interface TemporalEvent {
|
||||
id: string;
|
||||
type: string;
|
||||
timestamp: Date;
|
||||
entities: string[];
|
||||
properties: Record<string, unknown>;
|
||||
relationships?: Array<{
|
||||
type: string;
|
||||
target: string;
|
||||
}>;
|
||||
}
|
||||
export interface EntityRelationshipOptions {
|
||||
domain: string;
|
||||
entityCount: number;
|
||||
relationshipDensity: number;
|
||||
entitySchema?: Record<string, unknown>;
|
||||
relationshipTypes?: string[];
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
export interface OpenRouterConfig {
|
||||
apiKey: string;
|
||||
model?: string;
|
||||
baseURL?: string;
|
||||
timeout?: number;
|
||||
maxRetries?: number;
|
||||
rateLimit?: {
|
||||
requests: number;
|
||||
interval: number;
|
||||
};
|
||||
}
|
||||
export declare const OpenRouterConfigSchema: z.ZodObject<{
|
||||
apiKey: z.ZodString;
|
||||
model: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
||||
baseURL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
||||
timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
||||
maxRetries: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
||||
rateLimit: z.ZodOptional<z.ZodObject<{
|
||||
requests: z.ZodNumber;
|
||||
interval: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
interval: number;
|
||||
requests: number;
|
||||
}, {
|
||||
interval: number;
|
||||
requests: number;
|
||||
}>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
maxRetries: number;
|
||||
apiKey: string;
|
||||
model: string;
|
||||
timeout: number;
|
||||
baseURL: string;
|
||||
rateLimit?: {
|
||||
interval: number;
|
||||
requests: number;
|
||||
} | undefined;
|
||||
}, {
|
||||
apiKey: string;
|
||||
maxRetries?: number | undefined;
|
||||
model?: string | undefined;
|
||||
timeout?: number | undefined;
|
||||
baseURL?: string | undefined;
|
||||
rateLimit?: {
|
||||
interval: number;
|
||||
requests: number;
|
||||
} | undefined;
|
||||
}>;
|
||||
export interface OpenRouterMessage {
|
||||
role: 'system' | 'user' | 'assistant';
|
||||
content: string;
|
||||
}
|
||||
export interface OpenRouterRequest {
|
||||
model: string;
|
||||
messages: OpenRouterMessage[];
|
||||
temperature?: number;
|
||||
max_tokens?: number;
|
||||
top_p?: number;
|
||||
stream?: boolean;
|
||||
}
|
||||
export interface OpenRouterResponse {
|
||||
id: string;
|
||||
model: string;
|
||||
choices: Array<{
|
||||
message: {
|
||||
role: string;
|
||||
content: string;
|
||||
};
|
||||
finish_reason: string;
|
||||
}>;
|
||||
usage: {
|
||||
prompt_tokens: number;
|
||||
completion_tokens: number;
|
||||
total_tokens: number;
|
||||
};
|
||||
}
|
||||
export interface CypherStatement {
|
||||
query: string;
|
||||
parameters?: Record<string, unknown>;
|
||||
}
|
||||
export interface CypherBatch {
|
||||
statements: CypherStatement[];
|
||||
metadata?: {
|
||||
total_nodes?: number;
|
||||
total_relationships?: number;
|
||||
labels?: string[];
|
||||
relationship_types?: string[];
|
||||
};
|
||||
}
|
||||
export interface EmbeddingConfig {
|
||||
provider: 'openrouter' | 'local';
|
||||
model?: string;
|
||||
dimensions?: number;
|
||||
batchSize?: number;
|
||||
}
|
||||
export interface EmbeddingResult {
|
||||
embedding: number[];
|
||||
model: string;
|
||||
dimensions: number;
|
||||
}
|
||||
export interface GraphGenerationResult<T = GraphData> {
|
||||
data: T;
|
||||
metadata: {
|
||||
generated_at: Date;
|
||||
model: string;
|
||||
duration: number;
|
||||
token_usage?: {
|
||||
prompt_tokens: number;
|
||||
completion_tokens: number;
|
||||
total_tokens: number;
|
||||
};
|
||||
};
|
||||
cypher?: CypherBatch;
|
||||
}
|
||||
export declare class GraphGenerationError extends Error {
|
||||
code: string;
|
||||
details?: unknown | undefined;
|
||||
constructor(message: string, code: string, details?: unknown | undefined);
|
||||
}
|
||||
export declare class OpenRouterError extends GraphGenerationError {
|
||||
constructor(message: string, details?: unknown);
|
||||
}
|
||||
export declare class ValidationError extends GraphGenerationError {
|
||||
constructor(message: string, details?: unknown);
|
||||
}
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/types.d.ts.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/types.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
|
||||
43
vendor/ruvector/npm/packages/graph-data-generator/src/types.js
vendored
Normal file
43
vendor/ruvector/npm/packages/graph-data-generator/src/types.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Core types and interfaces for graph-data-generator
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ValidationError = exports.OpenRouterError = exports.GraphGenerationError = exports.OpenRouterConfigSchema = void 0;
|
||||
const zod_1 = require("zod");
|
||||
exports.OpenRouterConfigSchema = zod_1.z.object({
|
||||
apiKey: zod_1.z.string(),
|
||||
model: zod_1.z.string().optional().default('moonshot/kimi-k2-instruct'),
|
||||
baseURL: zod_1.z.string().optional().default('https://openrouter.ai/api/v1'),
|
||||
timeout: zod_1.z.number().optional().default(60000),
|
||||
maxRetries: zod_1.z.number().optional().default(3),
|
||||
rateLimit: zod_1.z.object({
|
||||
requests: zod_1.z.number(),
|
||||
interval: zod_1.z.number()
|
||||
}).optional()
|
||||
});
|
||||
// Error types
|
||||
class GraphGenerationError extends Error {
|
||||
constructor(message, code, details) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
this.name = 'GraphGenerationError';
|
||||
}
|
||||
}
|
||||
exports.GraphGenerationError = GraphGenerationError;
|
||||
class OpenRouterError extends GraphGenerationError {
|
||||
constructor(message, details) {
|
||||
super(message, 'OPENROUTER_ERROR', details);
|
||||
this.name = 'OpenRouterError';
|
||||
}
|
||||
}
|
||||
exports.OpenRouterError = OpenRouterError;
|
||||
class ValidationError extends GraphGenerationError {
|
||||
constructor(message, details) {
|
||||
super(message, 'VALIDATION_ERROR', details);
|
||||
this.name = 'ValidationError';
|
||||
}
|
||||
}
|
||||
exports.ValidationError = ValidationError;
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
vendor/ruvector/npm/packages/graph-data-generator/src/types.js.map
vendored
Normal file
1
vendor/ruvector/npm/packages/graph-data-generator/src/types.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,6BAAwB;AAsHX,QAAA,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;IAClB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC;IACjE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,8BAA8B,CAAC;IACtE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC7C,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,SAAS,EAAE,OAAC,CAAC,MAAM,CAAC;QAClB,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;KACrB,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AA+EH,cAAc;AACd,MAAa,oBAAqB,SAAQ,KAAK;IAC7C,YACE,OAAe,EACR,IAAY,EACZ,OAAiB;QAExB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAU;QAGxB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AATD,oDASC;AAED,MAAa,eAAgB,SAAQ,oBAAoB;IACvD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED,MAAa,eAAgB,SAAQ,oBAAoB;IACvD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC"}
|
||||
236
vendor/ruvector/npm/packages/graph-data-generator/src/types.ts
vendored
Normal file
236
vendor/ruvector/npm/packages/graph-data-generator/src/types.ts
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Core types and interfaces for graph-data-generator
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
// Graph data types
|
||||
export interface GraphNode {
|
||||
id: string;
|
||||
labels: string[];
|
||||
properties: Record<string, unknown>;
|
||||
embedding?: number[];
|
||||
}
|
||||
|
||||
export interface GraphEdge {
|
||||
id: string;
|
||||
type: string;
|
||||
source: string;
|
||||
target: string;
|
||||
properties: Record<string, unknown>;
|
||||
embedding?: number[];
|
||||
}
|
||||
|
||||
export interface GraphData {
|
||||
nodes: GraphNode[];
|
||||
edges: GraphEdge[];
|
||||
metadata?: {
|
||||
domain?: string;
|
||||
generated_at?: Date;
|
||||
model?: string;
|
||||
total_nodes?: number;
|
||||
total_edges?: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Knowledge graph types
|
||||
export interface KnowledgeTriple {
|
||||
subject: string;
|
||||
predicate: string;
|
||||
object: string;
|
||||
confidence?: number;
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export interface KnowledgeGraphOptions {
|
||||
domain: string;
|
||||
entities: number;
|
||||
relationships: number;
|
||||
entityTypes?: string[];
|
||||
relationshipTypes?: string[];
|
||||
includeEmbeddings?: boolean;
|
||||
embeddingDimension?: number;
|
||||
}
|
||||
|
||||
// Social network types
|
||||
export interface SocialNetworkOptions {
|
||||
users: number;
|
||||
avgConnections: number;
|
||||
networkType?: 'random' | 'small-world' | 'scale-free' | 'clustered';
|
||||
communities?: number;
|
||||
includeMetadata?: boolean;
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
|
||||
export interface SocialNode {
|
||||
id: string;
|
||||
username: string;
|
||||
profile: {
|
||||
name?: string;
|
||||
bio?: string;
|
||||
joined?: Date;
|
||||
followers?: number;
|
||||
following?: number;
|
||||
};
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
// Temporal event types
|
||||
export interface TemporalEventOptions {
|
||||
startDate: Date | string;
|
||||
endDate: Date | string;
|
||||
eventTypes: string[];
|
||||
eventsPerDay?: number;
|
||||
entities?: number;
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
|
||||
export interface TemporalEvent {
|
||||
id: string;
|
||||
type: string;
|
||||
timestamp: Date;
|
||||
entities: string[];
|
||||
properties: Record<string, unknown>;
|
||||
relationships?: Array<{
|
||||
type: string;
|
||||
target: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// Entity relationship types
|
||||
export interface EntityRelationshipOptions {
|
||||
domain: string;
|
||||
entityCount: number;
|
||||
relationshipDensity: number; // 0-1
|
||||
entitySchema?: Record<string, unknown>;
|
||||
relationshipTypes?: string[];
|
||||
includeEmbeddings?: boolean;
|
||||
}
|
||||
|
||||
// OpenRouter client types
|
||||
export interface OpenRouterConfig {
|
||||
apiKey: string;
|
||||
model?: string;
|
||||
baseURL?: string;
|
||||
timeout?: number;
|
||||
maxRetries?: number;
|
||||
rateLimit?: {
|
||||
requests: number;
|
||||
interval: number; // milliseconds
|
||||
};
|
||||
}
|
||||
|
||||
export const OpenRouterConfigSchema = z.object({
|
||||
apiKey: z.string(),
|
||||
model: z.string().optional().default('moonshot/kimi-k2-instruct'),
|
||||
baseURL: z.string().optional().default('https://openrouter.ai/api/v1'),
|
||||
timeout: z.number().optional().default(60000),
|
||||
maxRetries: z.number().optional().default(3),
|
||||
rateLimit: z.object({
|
||||
requests: z.number(),
|
||||
interval: z.number()
|
||||
}).optional()
|
||||
});
|
||||
|
||||
export interface OpenRouterMessage {
|
||||
role: 'system' | 'user' | 'assistant';
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface OpenRouterRequest {
|
||||
model: string;
|
||||
messages: OpenRouterMessage[];
|
||||
temperature?: number;
|
||||
max_tokens?: number;
|
||||
top_p?: number;
|
||||
stream?: boolean;
|
||||
}
|
||||
|
||||
export interface OpenRouterResponse {
|
||||
id: string;
|
||||
model: string;
|
||||
choices: Array<{
|
||||
message: {
|
||||
role: string;
|
||||
content: string;
|
||||
};
|
||||
finish_reason: string;
|
||||
}>;
|
||||
usage: {
|
||||
prompt_tokens: number;
|
||||
completion_tokens: number;
|
||||
total_tokens: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Cypher types
|
||||
export interface CypherStatement {
|
||||
query: string;
|
||||
parameters?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface CypherBatch {
|
||||
statements: CypherStatement[];
|
||||
metadata?: {
|
||||
total_nodes?: number;
|
||||
total_relationships?: number;
|
||||
labels?: string[];
|
||||
relationship_types?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
// Embedding types
|
||||
export interface EmbeddingConfig {
|
||||
provider: 'openrouter' | 'local';
|
||||
model?: string;
|
||||
dimensions?: number;
|
||||
batchSize?: number;
|
||||
}
|
||||
|
||||
export interface EmbeddingResult {
|
||||
embedding: number[];
|
||||
model: string;
|
||||
dimensions: number;
|
||||
}
|
||||
|
||||
// Generation result types
|
||||
export interface GraphGenerationResult<T = GraphData> {
|
||||
data: T;
|
||||
metadata: {
|
||||
generated_at: Date;
|
||||
model: string;
|
||||
duration: number;
|
||||
token_usage?: {
|
||||
prompt_tokens: number;
|
||||
completion_tokens: number;
|
||||
total_tokens: number;
|
||||
};
|
||||
};
|
||||
cypher?: CypherBatch;
|
||||
}
|
||||
|
||||
// Error types
|
||||
export class GraphGenerationError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public code: string,
|
||||
public details?: unknown
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'GraphGenerationError';
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenRouterError extends GraphGenerationError {
|
||||
constructor(message: string, details?: unknown) {
|
||||
super(message, 'OPENROUTER_ERROR', details);
|
||||
this.name = 'OpenRouterError';
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidationError extends GraphGenerationError {
|
||||
constructor(message: string, details?: unknown) {
|
||||
super(message, 'VALIDATION_ERROR', details);
|
||||
this.name = 'ValidationError';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user