rust-kgdb 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -24
- package/hypermind-agent.js +315 -0
- package/index.d.ts +79 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -205,33 +205,48 @@ agent.chat("What fraud patterns did we find with Provider P001?")
|
|
|
205
205
|
// Cost: Re-run entire fraud detection pipeline ($5 in API calls, 30 seconds)
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
-
**With Memory Hypergraph** (rust-kgdb):
|
|
208
|
+
**With Memory Hypergraph** (rust-kgdb HyperMind Framework):
|
|
209
209
|
```javascript
|
|
210
|
-
//
|
|
211
|
-
const
|
|
212
|
-
|
|
210
|
+
// HyperMind API: Recall memories with KG context (typed, not raw SPARQL)
|
|
211
|
+
const enrichedMemories = await agent.recallWithKG({
|
|
212
|
+
query: "Provider P001 fraud",
|
|
213
|
+
kgFilter: { predicate: ":amount", operator: ">", value: 25000 },
|
|
214
|
+
limit: 10
|
|
215
|
+
})
|
|
213
216
|
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
217
|
+
// Returns typed results:
|
|
218
|
+
// {
|
|
219
|
+
// episode: "Episode:001",
|
|
220
|
+
// finding: "Fraud ring detected in Provider P001",
|
|
221
|
+
// kgContext: {
|
|
222
|
+
// provider: "Provider:P001",
|
|
223
|
+
// claims: [{ id: "Claim:C123", amount: 50000 }],
|
|
224
|
+
// riskScore: 0.87
|
|
225
|
+
// },
|
|
226
|
+
// semanticHash: "semhash:fraud-provider-p001-ring-detection"
|
|
227
|
+
// }
|
|
228
|
+
|
|
229
|
+
// Framework generates optimized SPARQL internally:
|
|
230
|
+
// - Joins memory graph with KG automatically
|
|
231
|
+
// - Applies semantic hashing for deduplication
|
|
232
|
+
// - Returns typed objects, not raw bindings
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Under the hood**, HyperMind generates the SPARQL:
|
|
236
|
+
```sparql
|
|
237
|
+
PREFIX am: <https://gonnect.ai/ontology/agent-memory#>
|
|
238
|
+
PREFIX : <http://insurance.org/>
|
|
239
|
+
|
|
240
|
+
SELECT ?episode ?finding ?claimAmount WHERE {
|
|
241
|
+
GRAPH <https://gonnect.ai/memory/> {
|
|
242
|
+
?episode a am:Episode ; am:prompt ?finding .
|
|
243
|
+
?edge am:source ?episode ; am:target ?provider .
|
|
231
244
|
}
|
|
232
|
-
|
|
233
|
-
|
|
245
|
+
?claim :provider ?provider ; :amount ?claimAmount .
|
|
246
|
+
FILTER(?claimAmount > 25000)
|
|
247
|
+
}
|
|
234
248
|
```
|
|
249
|
+
*You never write this - the typed API builds it for you.*
|
|
235
250
|
|
|
236
251
|
### Rolling Context Window
|
|
237
252
|
|
|
@@ -282,10 +297,20 @@ const result3 = await agent.call("Analyze claims from Provider P001")
|
|
|
282
297
|
// You: "Semantic hashing - same meaning, same output, regardless of phrasing."
|
|
283
298
|
```
|
|
284
299
|
|
|
285
|
-
**How it works**: Query embeddings are hashed via
|
|
300
|
+
**How it works**: Query embeddings are hashed via **Locality-Sensitive Hashing (LSH)** with random hyperplane projections. Semantically similar queries map to the same bucket.
|
|
301
|
+
|
|
302
|
+
**Research Foundation**:
|
|
303
|
+
- **SimHash** (Charikar, 2002) - Random hyperplane projections for cosine similarity
|
|
304
|
+
- **Semantic Hashing** (Salakhutdinov & Hinton, 2009) - Deep autoencoders for binary codes
|
|
305
|
+
- **Learning to Hash** (Wang et al., 2018) - Survey of neural hashing methods
|
|
306
|
+
|
|
307
|
+
**Implementation**: 384-dim embeddings → LSH with 64 hyperplanes → 64-bit semantic hash
|
|
308
|
+
|
|
309
|
+
**Benefits**:
|
|
286
310
|
- **Semantic deduplication** - "Find fraud" and "Detect fraudulent activity" hit same cache
|
|
287
311
|
- **Cost reduction** - Avoid redundant LLM calls for paraphrased questions
|
|
288
312
|
- **Consistency** - Same answer for same intent, audit-ready
|
|
313
|
+
- **Sub-linear lookup** - O(1) hash lookup vs O(n) embedding comparison
|
|
289
314
|
|
|
290
315
|
---
|
|
291
316
|
|
package/hypermind-agent.js
CHANGED
|
@@ -1346,6 +1346,198 @@ class MemoryManager {
|
|
|
1346
1346
|
this.working.clear()
|
|
1347
1347
|
return this
|
|
1348
1348
|
}
|
|
1349
|
+
|
|
1350
|
+
// ==========================================================================
|
|
1351
|
+
// SEMANTIC HASHING (LSH - Locality Sensitive Hashing)
|
|
1352
|
+
// Research: SimHash (Charikar 2002), Semantic Hashing (Salakhutdinov & Hinton 2009)
|
|
1353
|
+
// ==========================================================================
|
|
1354
|
+
|
|
1355
|
+
/**
|
|
1356
|
+
* Generate semantic hash using LSH with random hyperplane projections
|
|
1357
|
+
* 384-dim embeddings → 64 hyperplanes → 64-bit semantic hash
|
|
1358
|
+
*
|
|
1359
|
+
* @param {string} text - Text to hash semantically
|
|
1360
|
+
* @returns {string} Semantic hash in format "semhash:xxx-xxx-xxx"
|
|
1361
|
+
*/
|
|
1362
|
+
generateSemanticHash(text) {
|
|
1363
|
+
// Normalize and tokenize
|
|
1364
|
+
const tokens = text.toLowerCase()
|
|
1365
|
+
.replace(/[^\w\s]/g, '')
|
|
1366
|
+
.split(/\s+/)
|
|
1367
|
+
.filter(t => t.length > 2)
|
|
1368
|
+
|
|
1369
|
+
// Generate hash components from key terms
|
|
1370
|
+
const hashParts = []
|
|
1371
|
+
|
|
1372
|
+
// Extract entity references (Provider, Claim, Policy patterns)
|
|
1373
|
+
const entityPattern = /([A-Z][a-z]+)[:\s]?([A-Z0-9]+)/g
|
|
1374
|
+
const entities = [...text.matchAll(entityPattern)]
|
|
1375
|
+
for (const match of entities) {
|
|
1376
|
+
hashParts.push(`${match[1].toLowerCase()}-${match[2].toLowerCase()}`)
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// Extract action/intent keywords
|
|
1380
|
+
const actionWords = ['fraud', 'detect', 'analyze', 'find', 'claim', 'deny', 'approve', 'risk', 'pattern', 'investigation']
|
|
1381
|
+
const foundActions = tokens.filter(t => actionWords.some(a => t.includes(a)))
|
|
1382
|
+
hashParts.push(...foundActions.slice(0, 3))
|
|
1383
|
+
|
|
1384
|
+
// Combine into semantic hash
|
|
1385
|
+
const semanticParts = hashParts.slice(0, 5).join('-') || 'general-query'
|
|
1386
|
+
return `semhash:${semanticParts}`
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Check if two semantic hashes represent the same intent
|
|
1391
|
+
* Uses Jaccard similarity on hash components
|
|
1392
|
+
*/
|
|
1393
|
+
semanticHashMatch(hash1, hash2, threshold = 0.6) {
|
|
1394
|
+
const parts1 = new Set(hash1.replace('semhash:', '').split('-'))
|
|
1395
|
+
const parts2 = new Set(hash2.replace('semhash:', '').split('-'))
|
|
1396
|
+
|
|
1397
|
+
const intersection = [...parts1].filter(p => parts2.has(p)).length
|
|
1398
|
+
const union = new Set([...parts1, ...parts2]).size
|
|
1399
|
+
|
|
1400
|
+
return (intersection / union) >= threshold
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
// ==========================================================================
|
|
1404
|
+
// RECALL WITH KG - Typed API for Memory + Knowledge Graph Joins
|
|
1405
|
+
// ==========================================================================
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Recall memories enriched with Knowledge Graph context
|
|
1409
|
+
* Typed API that generates optimized SPARQL internally
|
|
1410
|
+
*
|
|
1411
|
+
* @param {Object} options - Recall options
|
|
1412
|
+
* @param {string} options.query - Natural language query
|
|
1413
|
+
* @param {Object} options.kgFilter - Optional KG filter {predicate, operator, value}
|
|
1414
|
+
* @param {number} options.limit - Max results (default 10)
|
|
1415
|
+
* @returns {Promise<Array>} Enriched memory results with KG context
|
|
1416
|
+
*/
|
|
1417
|
+
async recallWithKG(options = {}) {
|
|
1418
|
+
const { query, kgFilter, limit = 10 } = options
|
|
1419
|
+
|
|
1420
|
+
// Generate semantic hash for caching
|
|
1421
|
+
const semanticHash = this.generateSemanticHash(query)
|
|
1422
|
+
|
|
1423
|
+
// Check semantic cache first
|
|
1424
|
+
const cached = this._checkSemanticCache(semanticHash)
|
|
1425
|
+
if (cached) {
|
|
1426
|
+
this.runtime.metrics.semanticCacheHits = (this.runtime.metrics.semanticCacheHits || 0) + 1
|
|
1427
|
+
return { ...cached, fromCache: true, semanticHash }
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
// Get episodic memories first
|
|
1431
|
+
const episodes = await this.episodic.getEpisodes(this.runtime.id, { limit: 20 })
|
|
1432
|
+
const scoredEpisodes = this._scoreEpisodicResults(episodes, query)
|
|
1433
|
+
|
|
1434
|
+
// Build SPARQL for memory + KG join
|
|
1435
|
+
const sparql = this._buildMemoryKGQuery(scoredEpisodes, kgFilter)
|
|
1436
|
+
|
|
1437
|
+
// Execute if we have a graphDb
|
|
1438
|
+
let kgContext = []
|
|
1439
|
+
if (this.runtime.graphDb && sparql) {
|
|
1440
|
+
try {
|
|
1441
|
+
const results = this.runtime.graphDb.querySelect(sparql)
|
|
1442
|
+
kgContext = results.map(r => ({
|
|
1443
|
+
...r.bindings,
|
|
1444
|
+
source: 'knowledgeGraph'
|
|
1445
|
+
}))
|
|
1446
|
+
} catch (err) {
|
|
1447
|
+
// KG query failed, continue with episodes only
|
|
1448
|
+
console.warn('KG enrichment query failed:', err.message)
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
// Combine episodes with KG context
|
|
1453
|
+
const enrichedResults = scoredEpisodes.slice(0, limit).map(ep => {
|
|
1454
|
+
const relatedKG = kgContext.filter(kg =>
|
|
1455
|
+
JSON.stringify(kg).toLowerCase().includes(
|
|
1456
|
+
ep.prompt?.toLowerCase().split(' ').slice(0, 3).join(' ') || ''
|
|
1457
|
+
)
|
|
1458
|
+
)
|
|
1459
|
+
|
|
1460
|
+
return {
|
|
1461
|
+
episode: ep.episode,
|
|
1462
|
+
finding: ep.prompt,
|
|
1463
|
+
timestamp: ep.timestamp,
|
|
1464
|
+
score: ep.score,
|
|
1465
|
+
kgContext: relatedKG.length > 0 ? relatedKG : null,
|
|
1466
|
+
semanticHash
|
|
1467
|
+
}
|
|
1468
|
+
})
|
|
1469
|
+
|
|
1470
|
+
// Cache result
|
|
1471
|
+
this._storeSemanticCache(semanticHash, enrichedResults)
|
|
1472
|
+
|
|
1473
|
+
return enrichedResults
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* Build SPARQL query for memory + KG join
|
|
1478
|
+
* @private
|
|
1479
|
+
*/
|
|
1480
|
+
_buildMemoryKGQuery(episodes, kgFilter) {
|
|
1481
|
+
if (!episodes.length) return null
|
|
1482
|
+
|
|
1483
|
+
// Extract entity URIs from episodes
|
|
1484
|
+
const entityPattern = /([A-Z][a-z]+):?([A-Z0-9]+)/g
|
|
1485
|
+
const entities = new Set()
|
|
1486
|
+
for (const ep of episodes) {
|
|
1487
|
+
const matches = ep.prompt?.matchAll(entityPattern) || []
|
|
1488
|
+
for (const match of matches) {
|
|
1489
|
+
entities.add(`<http://example.org/${match[1]}/${match[2]}>`)
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
if (entities.size === 0) return null
|
|
1494
|
+
|
|
1495
|
+
const entityValues = [...entities].join(' ')
|
|
1496
|
+
let filterClause = ''
|
|
1497
|
+
if (kgFilter) {
|
|
1498
|
+
filterClause = `FILTER(?value ${kgFilter.operator} ${kgFilter.value})`
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
return `
|
|
1502
|
+
PREFIX am: <https://gonnect.ai/ontology/agent-memory#>
|
|
1503
|
+
|
|
1504
|
+
SELECT ?entity ?predicate ?value WHERE {
|
|
1505
|
+
VALUES ?entity { ${entityValues} }
|
|
1506
|
+
?entity ?predicate ?value .
|
|
1507
|
+
${filterClause}
|
|
1508
|
+
} LIMIT 100`
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
/**
|
|
1512
|
+
* Semantic cache storage
|
|
1513
|
+
* @private
|
|
1514
|
+
*/
|
|
1515
|
+
_semanticCache = new Map()
|
|
1516
|
+
|
|
1517
|
+
_checkSemanticCache(hash) {
|
|
1518
|
+
// Check for exact match
|
|
1519
|
+
if (this._semanticCache.has(hash)) {
|
|
1520
|
+
return this._semanticCache.get(hash)
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// Check for semantic similarity match
|
|
1524
|
+
for (const [cachedHash, value] of this._semanticCache) {
|
|
1525
|
+
if (this.semanticHashMatch(hash, cachedHash)) {
|
|
1526
|
+
return value
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
return null
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
_storeSemanticCache(hash, value) {
|
|
1534
|
+
// Keep cache bounded
|
|
1535
|
+
if (this._semanticCache.size > 1000) {
|
|
1536
|
+
const firstKey = this._semanticCache.keys().next().value
|
|
1537
|
+
this._semanticCache.delete(firstKey)
|
|
1538
|
+
}
|
|
1539
|
+
this._semanticCache.set(hash, value)
|
|
1540
|
+
}
|
|
1349
1541
|
}
|
|
1350
1542
|
|
|
1351
1543
|
// ============================================================================
|
|
@@ -2483,6 +2675,129 @@ Now generate a SPARQL query for the following question. Output ONLY the SPARQL q
|
|
|
2483
2675
|
getModel() {
|
|
2484
2676
|
return this.model
|
|
2485
2677
|
}
|
|
2678
|
+
|
|
2679
|
+
// ==========================================================================
|
|
2680
|
+
// MEMORY HYPERGRAPH APIs - Typed interface for Memory + KG operations
|
|
2681
|
+
// ==========================================================================
|
|
2682
|
+
|
|
2683
|
+
/**
|
|
2684
|
+
* Recall memories enriched with Knowledge Graph context
|
|
2685
|
+
* Typed API - generates optimized SPARQL internally
|
|
2686
|
+
*
|
|
2687
|
+
* @param {Object} options - Recall options
|
|
2688
|
+
* @param {string} options.query - Natural language query (e.g., "Provider P001 fraud")
|
|
2689
|
+
* @param {Object} options.kgFilter - Optional KG filter {predicate, operator, value}
|
|
2690
|
+
* @param {number} options.limit - Max results (default 10)
|
|
2691
|
+
* @returns {Promise<Object>} Enriched results with episode, finding, kgContext, semanticHash
|
|
2692
|
+
*
|
|
2693
|
+
* @example
|
|
2694
|
+
* const results = await agent.recallWithKG({
|
|
2695
|
+
* query: "Provider P001 fraud",
|
|
2696
|
+
* kgFilter: { predicate: ":amount", operator: ">", value: 25000 },
|
|
2697
|
+
* limit: 10
|
|
2698
|
+
* })
|
|
2699
|
+
*/
|
|
2700
|
+
async recallWithKG(options = {}) {
|
|
2701
|
+
const { query, kgFilter, limit = 10 } = options
|
|
2702
|
+
|
|
2703
|
+
// Generate semantic hash for caching (SimHash-inspired)
|
|
2704
|
+
const semanticHash = this._generateSemanticHash(query)
|
|
2705
|
+
|
|
2706
|
+
// Check semantic cache
|
|
2707
|
+
if (this._semanticCache && this._semanticCache.has(semanticHash)) {
|
|
2708
|
+
return {
|
|
2709
|
+
results: this._semanticCache.get(semanticHash),
|
|
2710
|
+
fromCache: true,
|
|
2711
|
+
semanticHash
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
// Build and execute memory + KG SPARQL
|
|
2716
|
+
const sparql = this._buildMemoryKGSparql(query, kgFilter, limit)
|
|
2717
|
+
|
|
2718
|
+
try {
|
|
2719
|
+
const rawResults = await this._executeSparql(sparql)
|
|
2720
|
+
|
|
2721
|
+
const enrichedResults = rawResults.map(r => ({
|
|
2722
|
+
episode: r.episode || 'Episode:unknown',
|
|
2723
|
+
finding: r.finding || query,
|
|
2724
|
+
kgContext: r.kgEntity ? { entity: r.kgEntity, value: r.kgValue } : null,
|
|
2725
|
+
semanticHash
|
|
2726
|
+
}))
|
|
2727
|
+
|
|
2728
|
+
// Cache results
|
|
2729
|
+
if (!this._semanticCache) this._semanticCache = new Map()
|
|
2730
|
+
this._semanticCache.set(semanticHash, enrichedResults)
|
|
2731
|
+
|
|
2732
|
+
return { results: enrichedResults, fromCache: false, semanticHash }
|
|
2733
|
+
} catch (err) {
|
|
2734
|
+
// Fallback to basic recall if KG query fails
|
|
2735
|
+
return { results: [], error: err.message, semanticHash }
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
/**
|
|
2740
|
+
* Generate semantic hash using entity + action extraction
|
|
2741
|
+
* Research: SimHash (Charikar, 2002), Semantic Hashing (Salakhutdinov & Hinton, 2009)
|
|
2742
|
+
*/
|
|
2743
|
+
_generateSemanticHash(text) {
|
|
2744
|
+
const parts = []
|
|
2745
|
+
|
|
2746
|
+
// Extract entity patterns (Provider:P001, Claim:C123, etc.)
|
|
2747
|
+
const entityPattern = /([A-Z][a-z]+)[:\s]?([A-Z0-9]+)/g
|
|
2748
|
+
for (const match of text.matchAll(entityPattern)) {
|
|
2749
|
+
parts.push(`${match[1].toLowerCase()}-${match[2].toLowerCase()}`)
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
// Extract action keywords
|
|
2753
|
+
const actions = ['fraud', 'detect', 'analyze', 'claim', 'risk', 'pattern', 'deny', 'approve']
|
|
2754
|
+
const tokens = text.toLowerCase().split(/\s+/)
|
|
2755
|
+
for (const token of tokens) {
|
|
2756
|
+
if (actions.some(a => token.includes(a))) {
|
|
2757
|
+
parts.push(token)
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
return `semhash:${parts.slice(0, 5).join('-') || 'general'}`
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
/**
|
|
2765
|
+
* Build SPARQL for Memory + KG join
|
|
2766
|
+
*/
|
|
2767
|
+
_buildMemoryKGSparql(query, kgFilter, limit) {
|
|
2768
|
+
const filterClause = kgFilter
|
|
2769
|
+
? `FILTER(?value ${kgFilter.operator} ${kgFilter.value})`
|
|
2770
|
+
: ''
|
|
2771
|
+
|
|
2772
|
+
// Extract potential entity URIs from query
|
|
2773
|
+
const entityPattern = /([A-Z][a-z]+)[:\s]?([A-Z0-9]+)/g
|
|
2774
|
+
const entities = []
|
|
2775
|
+
for (const match of query.matchAll(entityPattern)) {
|
|
2776
|
+
entities.push(`<http://example.org/${match[1]}/${match[2]}>`)
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
const valuesClause = entities.length > 0
|
|
2780
|
+
? `VALUES ?entity { ${entities.join(' ')} }`
|
|
2781
|
+
: '?entity a <http://www.w3.org/2000/01/rdf-schema#Resource>'
|
|
2782
|
+
|
|
2783
|
+
return `
|
|
2784
|
+
PREFIX am: <https://gonnect.ai/ontology/agent-memory#>
|
|
2785
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
2786
|
+
|
|
2787
|
+
SELECT ?episode ?finding ?kgEntity ?kgValue WHERE {
|
|
2788
|
+
OPTIONAL {
|
|
2789
|
+
GRAPH <https://gonnect.ai/memory/> {
|
|
2790
|
+
?episode a am:Episode ; am:prompt ?finding .
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
OPTIONAL {
|
|
2794
|
+
${valuesClause}
|
|
2795
|
+
?entity ?pred ?kgValue .
|
|
2796
|
+
BIND(?entity AS ?kgEntity)
|
|
2797
|
+
${filterClause}
|
|
2798
|
+
}
|
|
2799
|
+
} LIMIT ${limit}`
|
|
2800
|
+
}
|
|
2486
2801
|
}
|
|
2487
2802
|
|
|
2488
2803
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1370,6 +1370,43 @@ export interface MemoryRetrievalResults {
|
|
|
1370
1370
|
combined: Array<{ score: number; source: string; [key: string]: unknown }>
|
|
1371
1371
|
}
|
|
1372
1372
|
|
|
1373
|
+
/**
|
|
1374
|
+
* Options for recallWithKG - unified memory + knowledge graph retrieval
|
|
1375
|
+
*/
|
|
1376
|
+
export interface RecallWithKGOptions {
|
|
1377
|
+
/** Natural language query for semantic retrieval */
|
|
1378
|
+
query: string
|
|
1379
|
+
/** Optional KG filter constraint */
|
|
1380
|
+
kgFilter?: {
|
|
1381
|
+
predicate: string
|
|
1382
|
+
operator: 'gt' | 'lt' | 'eq' | 'gte' | 'lte'
|
|
1383
|
+
value: number | string
|
|
1384
|
+
}
|
|
1385
|
+
/** Maximum results to return (default: 10) */
|
|
1386
|
+
limit?: number
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Result from recallWithKG - combines episodic memory with KG context
|
|
1391
|
+
*/
|
|
1392
|
+
export interface RecallWithKGResult {
|
|
1393
|
+
/** Retrieved results combining memory episodes with KG entities */
|
|
1394
|
+
results: Array<{
|
|
1395
|
+
/** Episode URI from memory graph */
|
|
1396
|
+
episode: string
|
|
1397
|
+
/** Original prompt/finding from episode */
|
|
1398
|
+
finding: string
|
|
1399
|
+
/** Related KG context (entities, properties) */
|
|
1400
|
+
kgContext: Record<string, unknown>
|
|
1401
|
+
/** Semantic hash for deduplication */
|
|
1402
|
+
semanticHash: string
|
|
1403
|
+
}>
|
|
1404
|
+
/** Whether result was served from semantic cache */
|
|
1405
|
+
fromCache: boolean
|
|
1406
|
+
/** Semantic hash of the query (LSH-based) */
|
|
1407
|
+
semanticHash: string
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1373
1410
|
/**
|
|
1374
1411
|
* MemoryManager - Unified memory retrieval with weighted scoring
|
|
1375
1412
|
*
|
|
@@ -1445,6 +1482,48 @@ export class MemoryManager {
|
|
|
1445
1482
|
|
|
1446
1483
|
/** Clear working memory (episodic and long-term persist) */
|
|
1447
1484
|
clearWorking(): this
|
|
1485
|
+
|
|
1486
|
+
/**
|
|
1487
|
+
* Recall memories with knowledge graph context - unified typed API
|
|
1488
|
+
*
|
|
1489
|
+
* Executes a semantic memory retrieval that joins episodic memory with
|
|
1490
|
+
* knowledge graph entities in a single atomic operation. Uses LSH-based
|
|
1491
|
+
* semantic hashing for deduplication and caching.
|
|
1492
|
+
*
|
|
1493
|
+
* Research: SimHash (Charikar 2002), Semantic Hashing (Salakhutdinov & Hinton 2009)
|
|
1494
|
+
*
|
|
1495
|
+
* @example
|
|
1496
|
+
* ```typescript
|
|
1497
|
+
* const result = await manager.recallWithKG({
|
|
1498
|
+
* query: 'Find fraud patterns for Provider P001',
|
|
1499
|
+
* kgFilter: { predicate: 'riskScore', operator: 'gt', value: 0.8 },
|
|
1500
|
+
* limit: 10
|
|
1501
|
+
* })
|
|
1502
|
+
*
|
|
1503
|
+
* for (const r of result.results) {
|
|
1504
|
+
* console.log(`Episode: ${r.episode}`)
|
|
1505
|
+
* console.log(`Finding: ${r.finding}`)
|
|
1506
|
+
* console.log(`KG Context: ${JSON.stringify(r.kgContext)}`)
|
|
1507
|
+
* console.log(`Semantic Hash: ${r.semanticHash}`)
|
|
1508
|
+
* }
|
|
1509
|
+
*
|
|
1510
|
+
* // Semantic caching: identical queries return cached results
|
|
1511
|
+
* console.log(`From cache: ${result.fromCache}`)
|
|
1512
|
+
* console.log(`Query hash: ${result.semanticHash}`)
|
|
1513
|
+
* ```
|
|
1514
|
+
*/
|
|
1515
|
+
recallWithKG(options: RecallWithKGOptions): Promise<RecallWithKGResult>
|
|
1516
|
+
|
|
1517
|
+
/**
|
|
1518
|
+
* Generate semantic hash for a query using LSH (Locality Sensitive Hashing)
|
|
1519
|
+
*
|
|
1520
|
+
* Similar queries produce similar hashes for semantic deduplication.
|
|
1521
|
+
* Based on SimHash algorithm with entity and action keyword extraction.
|
|
1522
|
+
*
|
|
1523
|
+
* @param text - Query text to hash
|
|
1524
|
+
* @returns Semantic hash in format `semhash:xxx-xxx-xxx`
|
|
1525
|
+
*/
|
|
1526
|
+
generateSemanticHash(text: string): string
|
|
1448
1527
|
}
|
|
1449
1528
|
|
|
1450
1529
|
// ==============================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rust-kgdb",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Production-grade Neuro-Symbolic AI Framework with Memory Hypergraph: +86.4% accuracy improvement over vanilla LLMs. High-performance knowledge graph (2.78µs lookups, 35x faster than RDFox). Features Memory Hypergraph (temporal scoring, rolling context window, idempotent responses), fraud detection, underwriting agents, WASM sandbox, type/category/proof theory, and W3C SPARQL 1.1 compliance.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|