UNPKG

@ruvector/postgres-cli

Version:

Advanced AI vector database CLI for PostgreSQL - pgvector drop-in replacement with 53+ SQL functions, 39 attention mechanisms, GNN layers, hyperbolic embeddings, and self-learning capabilities

119 lines (118 loc) 5.06 kB
/** * GNN Commands * CLI commands for Graph Neural Network operations */ import chalk from 'chalk'; import ora from 'ora'; import Table from 'cli-table3'; import { readFileSync } from 'fs'; export class GnnCommands { static async create(client, name, options) { const spinner = ora(`Creating GNN layer '${name}'...`).start(); try { await client.connect(); await client.createGnnLayer(name, options.type, parseInt(options.inputDim), parseInt(options.outputDim)); spinner.succeed(chalk.green(`GNN layer '${name}' created successfully`)); console.log(chalk.bold.blue('\nLayer Configuration:')); console.log(chalk.gray('─'.repeat(40))); console.log(` ${chalk.green('Type:')} ${options.type.toUpperCase()}`); console.log(` ${chalk.green('Input Dimensions:')} ${options.inputDim}`); console.log(` ${chalk.green('Output Dimensions:')} ${options.outputDim}`); // Type-specific info const typeInfo = { gcn: 'Graph Convolutional Network - Spectral graph convolutions', graphsage: 'GraphSAGE - Inductive learning with neighborhood sampling', gat: 'Graph Attention Network - Attention-based message passing', gin: 'Graph Isomorphism Network - WL-test expressive power' }; console.log(`\n ${chalk.gray(typeInfo[options.type])}`); } catch (err) { spinner.fail(chalk.red('Failed to create GNN layer')); console.error(chalk.red(err.message)); } finally { await client.disconnect(); } } static async forward(client, layer, options) { const spinner = ora(`Running forward pass through '${layer}'...`).start(); try { await client.connect(); // Load features and edges from files const featuresContent = readFileSync(options.features, 'utf-8'); const edgesContent = readFileSync(options.edges, 'utf-8'); const features = JSON.parse(featuresContent); const edges = JSON.parse(edgesContent); // Extract src and dst from edges const src = edges.map(e => e[0]); const dst = edges.map(e => e[1]); const outDim = features[0]?.length || 64; const result = await client.gnnForward(layer, features, src, dst, outDim); spinner.succeed(chalk.green('Forward pass completed successfully')); console.log(chalk.bold.blue('\nGNN Output:')); console.log(chalk.gray('─'.repeat(40))); console.log(` ${chalk.green('Nodes:')} ${result.length}`); console.log(` ${chalk.green('Embedding Dim:')} ${result[0]?.length || 0}`); // Show sample embeddings console.log(chalk.bold.blue('\nSample Node Embeddings:')); const table = new Table({ head: [ chalk.cyan('Node'), chalk.cyan('Embedding (first 8 dims)') ], colWidths: [8, 60] }); for (let i = 0; i < Math.min(5, result.length); i++) { const emb = result[i]; table.push([ `${i}`, `[${emb.slice(0, 8).map((v) => v.toFixed(4)).join(', ')}${emb.length > 8 ? '...' : ''}]` ]); } console.log(table.toString()); if (result.length > 5) { console.log(chalk.gray(` ... and ${result.length - 5} more nodes`)); } } catch (err) { spinner.fail(chalk.red('Forward pass failed')); console.error(chalk.red(err.message)); } finally { await client.disconnect(); } } static async listTypes() { console.log(chalk.bold.blue('\nAvailable GNN Layer Types:')); console.log(chalk.gray('─'.repeat(50))); const types = [ { name: 'GCN', desc: 'Graph Convolutional Network', details: 'Spectral graph convolutions using Chebyshev polynomials' }, { name: 'GraphSAGE', desc: 'Sample and Aggregate', details: 'Inductive learning with neighborhood sampling and aggregation' }, { name: 'GAT', desc: 'Graph Attention Network', details: 'Attention-weighted message passing between nodes' }, { name: 'GIN', desc: 'Graph Isomorphism Network', details: 'Provably as powerful as WL-test for graph isomorphism' } ]; for (const type of types) { console.log(`\n ${chalk.yellow(type.name)} - ${type.desc}`); console.log(` ${chalk.gray(type.details)}`); } console.log(); } } export default GnnCommands;