rust-kgdb 0.8.13 → 0.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4958,6 +4958,269 @@ class HyperMindAgent {
4958
4958
  this.intentPatterns = this._buildIntentPatterns()
4959
4959
  }
4960
4960
 
4961
+ /**
4962
+ * 1-LINE SETUP: Create a fully configured HyperMindAgent
4963
+ *
4964
+ * This is the recommended way to create agents - handles all setup automatically:
4965
+ * - Creates GraphDB and loads TTL data
4966
+ * - Auto-detects OWL ontology from data (owl:Class, owl:*Property patterns)
4967
+ * - Optionally trains RDF2Vec embeddings
4968
+ * - Enables prompt optimization with schema context
4969
+ *
4970
+ * @example
4971
+ * // Minimal setup (just data)
4972
+ * const agent = await HyperMindAgent.create({
4973
+ * name: 'my-agent',
4974
+ * data: ttlData
4975
+ * })
4976
+ *
4977
+ * // Full setup with all features
4978
+ * const agent = await HyperMindAgent.create({
4979
+ * name: 'fraud-detector',
4980
+ * data: ttlData,
4981
+ * rdf2vec: true, // Train embeddings automatically
4982
+ * promptOptimize: true, // Enable schema-aware prompts
4983
+ * apiKey: process.env.OPENAI_API_KEY,
4984
+ * model: 'gpt-4o'
4985
+ * })
4986
+ *
4987
+ * // Then just call
4988
+ * const result = await agent.call("Who committed fraud?")
4989
+ *
4990
+ * @param {Object} options - Configuration options
4991
+ * @param {string} options.name - Agent name (required)
4992
+ * @param {string} options.data - TTL/N-Triples data to load (required)
4993
+ * @param {string} [options.baseUri] - Base URI for GraphDB (default: auto-detected)
4994
+ * @param {boolean} [options.rdf2vec=false] - Train RDF2Vec embeddings
4995
+ * @param {boolean} [options.promptOptimize=true] - Enable prompt optimization
4996
+ * @param {string} [options.apiKey] - OpenAI/Anthropic API key
4997
+ * @param {string} [options.model] - LLM model (e.g., 'gpt-4o', 'claude-3-opus')
4998
+ * @param {string} [options.ontology] - Custom ontology TTL (optional, auto-detected if not provided)
4999
+ * @returns {Promise<HyperMindAgent>} Configured agent ready to use
5000
+ */
5001
+ static async create(options) {
5002
+ if (!options.name) {
5003
+ throw new Error('name is required for HyperMindAgent.create()')
5004
+ }
5005
+ if (!options.data) {
5006
+ throw new Error('data (TTL/N-Triples) is required for HyperMindAgent.create()')
5007
+ }
5008
+
5009
+ // 1. Create SchemaAwareGraphDB with auto-detected or provided base URI
5010
+ const baseUri = options.baseUri || HyperMindAgent._detectBaseUri(options.data)
5011
+ const db = new SchemaAwareGraphDB(baseUri, { autoExtract: true })
5012
+
5013
+ // 2. Load TTL data
5014
+ db.loadTtl(options.data, null)
5015
+ const tripleCount = db.countTriples()
5016
+ console.log(`[HyperMindAgent.create] Loaded ${tripleCount} triples`)
5017
+
5018
+ // 3. Auto-detect OWL ontology from data (unless custom ontology provided)
5019
+ let ontology = options.ontology
5020
+ if (!ontology) {
5021
+ ontology = HyperMindAgent._autoDetectOntology(db)
5022
+ if (ontology) {
5023
+ console.log(`[HyperMindAgent.create] Auto-detected OWL ontology from data`)
5024
+ }
5025
+ }
5026
+
5027
+ // 4. Train RDF2Vec embeddings if requested
5028
+ // Uses native Rust loadTtlWithEmbeddings() - all embedding logic in Rust
5029
+ let embeddingsEnabled = false
5030
+ if (options.rdf2vec) {
5031
+ try {
5032
+ // Get RDF2Vec config from options (support both boolean and object)
5033
+ const rdf2vecConfig = typeof options.rdf2vec === 'object' ? options.rdf2vec : {}
5034
+ // Use snake_case for NAPI-RS struct field names
5035
+ const config = {
5036
+ vector_size: rdf2vecConfig.dimensions || options.rdf2vecDimensions || 128,
5037
+ window_size: rdf2vecConfig.window || options.rdf2vecWindowSize || 5,
5038
+ walk_length: rdf2vecConfig.walkLength || options.rdf2vecWalkLength || 5,
5039
+ walks_per_node: rdf2vecConfig.walksPerNode || options.rdf2vecWalksPerEntity || 10
5040
+ }
5041
+
5042
+ // Re-load data with embeddings using native Rust (efficient, parallel)
5043
+ const loadResult = JSON.parse(db._db.loadTtlWithEmbeddings(
5044
+ options.data,
5045
+ null,
5046
+ config
5047
+ ))
5048
+
5049
+ if (loadResult.embeddings?.trained) {
5050
+ embeddingsEnabled = true
5051
+ console.log(`[HyperMindAgent.create] Trained RDF2Vec embeddings:`)
5052
+ console.log(` Entities: ${loadResult.embeddings.entities_embedded}`)
5053
+ console.log(` Dimensions: ${loadResult.embeddings.dimensions}`)
5054
+ console.log(` Walks: ${loadResult.embeddings.walks_generated}`)
5055
+ console.log(` Training time: ${loadResult.embeddings.training_time_secs?.toFixed(2)}s`)
5056
+ }
5057
+ } catch (e) {
5058
+ console.warn(`[HyperMindAgent.create] RDF2Vec training skipped: ${e.message}`)
5059
+ }
5060
+ }
5061
+
5062
+ // Create wrapper for embedding operations if enabled
5063
+ const embeddings = embeddingsEnabled ? {
5064
+ // Delegate to native GraphDB embedding methods
5065
+ getEmbedding: (entity) => db._db.getEmbedding(entity),
5066
+ findSimilar: (entity, k, threshold) => {
5067
+ try {
5068
+ const results = JSON.parse(db._db.findSimilar(entity, k || 10))
5069
+ if (threshold) {
5070
+ return results.filter(r => r.similarity >= threshold)
5071
+ }
5072
+ return results
5073
+ } catch (e) {
5074
+ return []
5075
+ }
5076
+ },
5077
+ search: (text, k, threshold) => {
5078
+ // For text search, find entities that match and return similar
5079
+ // This uses the embedding similarity from native Rust
5080
+ const entities = db.querySelect(`SELECT ?s WHERE { ?s ?p ?o } LIMIT ${k || 10}`)
5081
+ const results = []
5082
+ for (const e of entities) {
5083
+ const entity = e.bindings?.s || e.s
5084
+ if (entity) {
5085
+ const similar = JSON.parse(db._db.findSimilar(entity, 1))
5086
+ if (similar.length > 0 && (!threshold || similar[0].similarity >= threshold)) {
5087
+ results.push({ entity, similarity: similar[0]?.similarity || 0 })
5088
+ }
5089
+ }
5090
+ }
5091
+ return results.slice(0, k || 10)
5092
+ },
5093
+ hasEmbeddings: () => db._db.hasEmbeddings(),
5094
+ getStats: () => JSON.parse(db._db.getEmbeddingStats())
5095
+ } : null
5096
+
5097
+ // 5. Create agent with all components
5098
+ const agent = new HyperMindAgent({
5099
+ name: options.name,
5100
+ kg: db,
5101
+ embeddings: embeddings,
5102
+ apiKey: options.apiKey,
5103
+ model: options.model
5104
+ })
5105
+
5106
+ // 6. Load ontology for reasoning rules
5107
+ if (ontology) {
5108
+ agent.loadOntology(ontology)
5109
+ }
5110
+
5111
+ // 7. Enable prompt optimization (extract schema)
5112
+ if (options.promptOptimize !== false) { // Default to true
5113
+ await agent.extractSchema()
5114
+ console.log(`[HyperMindAgent.create] Schema extracted for prompt optimization`)
5115
+ }
5116
+
5117
+ console.log(`[HyperMindAgent.create] Agent "${options.name}" ready!`)
5118
+ return agent
5119
+ }
5120
+
5121
+ /**
5122
+ * Auto-detect base URI from TTL data
5123
+ * Looks for common patterns like @prefix, @base, or first subject
5124
+ * @private
5125
+ */
5126
+ static _detectBaseUri(data) {
5127
+ // Try to find @base declaration
5128
+ const baseMatch = data.match(/@base\s+<([^>]+)>/)
5129
+ if (baseMatch) return baseMatch[1]
5130
+
5131
+ // Try to find first URI in data
5132
+ const uriMatch = data.match(/<(https?:\/\/[^>#\s]+)/)
5133
+ if (uriMatch) {
5134
+ // Extract base (remove fragment/local part)
5135
+ const uri = uriMatch[1]
5136
+ const lastSlash = uri.lastIndexOf('/')
5137
+ const lastHash = uri.lastIndexOf('#')
5138
+ const cutPoint = Math.max(lastSlash, lastHash)
5139
+ return cutPoint > 0 ? uri.substring(0, cutPoint + 1) : uri
5140
+ }
5141
+
5142
+ return 'http://example.org/'
5143
+ }
5144
+
5145
+ /**
5146
+ * Auto-detect OWL ontology from loaded data
5147
+ * Scans for owl:Class, owl:ObjectProperty, owl:SymmetricProperty, etc.
5148
+ * @private
5149
+ */
5150
+ static _autoDetectOntology(db) {
5151
+ const owlPatterns = []
5152
+
5153
+ // Query for OWL class declarations
5154
+ try {
5155
+ const classes = db.querySelect(`
5156
+ SELECT ?class WHERE {
5157
+ ?class <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .
5158
+ }
5159
+ `)
5160
+ for (const r of classes) {
5161
+ const cls = r.bindings?.class || r.class
5162
+ if (cls) owlPatterns.push(`<${cls}> a <http://www.w3.org/2002/07/owl#Class> .`)
5163
+ }
5164
+ } catch (e) { /* ignore */ }
5165
+
5166
+ // Query for OWL SymmetricProperty
5167
+ try {
5168
+ const symProps = db.querySelect(`
5169
+ SELECT ?prop WHERE {
5170
+ ?prop <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#SymmetricProperty> .
5171
+ }
5172
+ `)
5173
+ for (const r of symProps) {
5174
+ const prop = r.bindings?.prop || r.prop
5175
+ if (prop) owlPatterns.push(`<${prop}> a <http://www.w3.org/2002/07/owl#SymmetricProperty> .`)
5176
+ }
5177
+ } catch (e) { /* ignore */ }
5178
+
5179
+ // Query for OWL TransitiveProperty
5180
+ try {
5181
+ const transProps = db.querySelect(`
5182
+ SELECT ?prop WHERE {
5183
+ ?prop <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#TransitiveProperty> .
5184
+ }
5185
+ `)
5186
+ for (const r of transProps) {
5187
+ const prop = r.bindings?.prop || r.prop
5188
+ if (prop) owlPatterns.push(`<${prop}> a <http://www.w3.org/2002/07/owl#TransitiveProperty> .`)
5189
+ }
5190
+ } catch (e) { /* ignore */ }
5191
+
5192
+ // Query for OWL ObjectProperty
5193
+ try {
5194
+ const objProps = db.querySelect(`
5195
+ SELECT ?prop WHERE {
5196
+ ?prop <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .
5197
+ }
5198
+ `)
5199
+ for (const r of objProps) {
5200
+ const prop = r.bindings?.prop || r.prop
5201
+ if (prop) owlPatterns.push(`<${prop}> a <http://www.w3.org/2002/07/owl#ObjectProperty> .`)
5202
+ }
5203
+ } catch (e) { /* ignore */ }
5204
+
5205
+ // Query for OWL DatatypeProperty
5206
+ try {
5207
+ const dataProps = db.querySelect(`
5208
+ SELECT ?prop WHERE {
5209
+ ?prop <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .
5210
+ }
5211
+ `)
5212
+ for (const r of dataProps) {
5213
+ const prop = r.bindings?.prop || r.prop
5214
+ if (prop) owlPatterns.push(`<${prop}> a <http://www.w3.org/2002/07/owl#DatatypeProperty> .`)
5215
+ }
5216
+ } catch (e) { /* ignore */ }
5217
+
5218
+ if (owlPatterns.length > 0) {
5219
+ return owlPatterns.join('\n')
5220
+ }
5221
+ return null
5222
+ }
5223
+
4961
5224
  /**
4962
5225
  * Extract schema from KG (delegates to planner)
4963
5226
  * @returns {Object} Schema with predicates, classes, examples
package/index.d.ts CHANGED
@@ -779,7 +779,75 @@ export interface TraceEntry {
779
779
  * const trace = agent.getTrace()
780
780
  * ```
781
781
  */
782
+ /**
783
+ * Options for HyperMindAgent.create() - the 1-line setup method
784
+ */
785
+ export interface HyperMindAgentCreateOptions {
786
+ /** Agent name (required) */
787
+ name: string
788
+ /** TTL/N-Triples data to load (required) */
789
+ data: string
790
+ /** Base URI for GraphDB (optional - auto-detected from data) */
791
+ baseUri?: string
792
+ /** Train RDF2Vec embeddings (default: false) */
793
+ rdf2vec?: boolean
794
+ /** RDF2Vec dimensions (default: 128) */
795
+ rdf2vecDimensions?: number
796
+ /** RDF2Vec walk length (default: 10) */
797
+ rdf2vecWalkLength?: number
798
+ /** RDF2Vec walks per entity (default: 10) */
799
+ rdf2vecWalksPerEntity?: number
800
+ /** RDF2Vec window size (default: 5) */
801
+ rdf2vecWindowSize?: number
802
+ /** RDF2Vec training epochs (default: 5) */
803
+ rdf2vecEpochs?: number
804
+ /** Enable prompt optimization with schema context (default: true) */
805
+ promptOptimize?: boolean
806
+ /** OpenAI/Anthropic API key */
807
+ apiKey?: string
808
+ /** LLM model (e.g., 'gpt-4o', 'claude-3-opus') */
809
+ model?: string
810
+ /** Custom ontology TTL (optional - auto-detected if not provided) */
811
+ ontology?: string
812
+ }
813
+
782
814
  export class HyperMindAgent {
815
+ /**
816
+ * 1-LINE SETUP: Create a fully configured HyperMindAgent
817
+ *
818
+ * This is the recommended way to create agents - handles all setup automatically:
819
+ * - Creates GraphDB and loads TTL data
820
+ * - Auto-detects OWL ontology from data (owl:Class, owl:*Property patterns)
821
+ * - Optionally trains RDF2Vec embeddings
822
+ * - Enables prompt optimization with schema context
823
+ *
824
+ * @example
825
+ * ```typescript
826
+ * // Minimal setup (just data)
827
+ * const agent = await HyperMindAgent.create({
828
+ * name: 'my-agent',
829
+ * data: ttlData
830
+ * })
831
+ *
832
+ * // Full setup with all features
833
+ * const agent = await HyperMindAgent.create({
834
+ * name: 'fraud-detector',
835
+ * data: ttlData,
836
+ * rdf2vec: true, // Train embeddings automatically
837
+ * promptOptimize: true, // Enable schema-aware prompts
838
+ * apiKey: process.env.OPENAI_API_KEY,
839
+ * model: 'gpt-4o'
840
+ * })
841
+ *
842
+ * // Then just call
843
+ * const result = await agent.call("Who committed fraud?")
844
+ * ```
845
+ *
846
+ * @param options - Configuration options
847
+ * @returns Promise resolving to a fully configured agent
848
+ */
849
+ static create(options: HyperMindAgentCreateOptions): Promise<HyperMindAgent>
850
+
783
851
  /**
784
852
  * Spawn a new HyperMind agent with the given specification
785
853
  * @param spec - Agent specification
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rust-kgdb",
3
- "version": "0.8.13",
3
+ "version": "0.8.15",
4
4
  "description": "High-performance RDF/SPARQL database with AI agent framework and cross-database federation. GraphDB (449ns lookups, 5-11x faster than RDFox), HyperFederate (KGDB + Snowflake + BigQuery), GraphFrames analytics, Datalog reasoning, HNSW vector embeddings. HyperMindAgent for schema-aware query generation with audit trails. W3C SPARQL 1.1 compliant. Native performance via Rust + NAPI-RS.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",