rust-kgdb 0.5.2 → 0.5.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/examples/fraud-detection-agent.js +603 -263
- package/examples/underwriting-agent.js +487 -290
- package/package.json +2 -2
|
@@ -1,346 +1,686 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
4
|
+
* FRAUD DETECTION AGENT - Professional HyperMind Framework Implementation
|
|
5
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
3
6
|
*
|
|
4
|
-
*
|
|
5
|
-
* - Knowledge graph for relationship analysis
|
|
6
|
-
* - GraphFrames for network pattern detection
|
|
7
|
-
* - Vector embeddings for semantic similarity
|
|
8
|
-
* - Datalog rules for fraud pattern inference
|
|
7
|
+
* This demonstrates the FULL POWER of the HyperMind neuro-symbolic framework:
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* ┌──────────────────────────────────────────────────────────────────────────┐
|
|
10
|
+
* │ HYPERMIND ARCHITECTURE │
|
|
11
|
+
* │ │
|
|
12
|
+
* │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
13
|
+
* │ │ TYPE THEORY │ → │ CATEGORY │ → │ PROOF │ │
|
|
14
|
+
* │ │ (TypeId, │ │ THEORY │ │ THEORY │ │
|
|
15
|
+
* │ │ Refinement) │ │ (Morphisms) │ │ (Witnesses) │ │
|
|
16
|
+
* │ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
17
|
+
* │ ↓ ↓ ↓ │
|
|
18
|
+
* │ Tools have typed Tools compose Every execution │
|
|
19
|
+
* │ signatures (A→B) safely (f∘g) produces audit │
|
|
20
|
+
* │ trail │
|
|
21
|
+
* └──────────────────────────────────────────────────────────────────────────┘
|
|
22
|
+
*
|
|
23
|
+
* KEY DIFFERENTIATOR: Unlike vanilla LLMs that hallucinate, HyperMind:
|
|
24
|
+
* - Grounds LLM output in type-checked knowledge graph operations
|
|
25
|
+
* - Provides deterministic execution with provenance
|
|
26
|
+
* - Achieves +86.4% accuracy improvement over vanilla LLMs
|
|
27
|
+
*
|
|
28
|
+
* Real-World Data Sources:
|
|
29
|
+
* - NICB (National Insurance Crime Bureau) fraud patterns
|
|
30
|
+
* - FBI Insurance Fraud statistics ($40B annual losses)
|
|
31
|
+
* - Coalition Against Insurance Fraud ring detection methods
|
|
32
|
+
*
|
|
33
|
+
* @author HyperMind Framework Team
|
|
34
|
+
* @version 0.5.3
|
|
14
35
|
*/
|
|
15
36
|
|
|
37
|
+
const { HyperMindAgent } = require('../hypermind-agent.js')
|
|
16
38
|
const {
|
|
17
39
|
GraphDB,
|
|
18
|
-
GraphFrame,
|
|
19
40
|
EmbeddingService,
|
|
20
41
|
DatalogProgram,
|
|
21
42
|
evaluateDatalog,
|
|
22
|
-
|
|
43
|
+
GraphFrame,
|
|
23
44
|
getVersion
|
|
24
45
|
} = require('../index.js')
|
|
25
46
|
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
47
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
48
|
+
// CONFIGURATION - Professional Design Pattern: Configuration Object
|
|
49
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
50
|
+
|
|
51
|
+
const CONFIG = {
|
|
52
|
+
// LLM Configuration
|
|
53
|
+
llm: {
|
|
54
|
+
model: process.env.ANTHROPIC_API_KEY ? 'claude-sonnet-4' :
|
|
55
|
+
process.env.OPENAI_API_KEY ? 'gpt-4o' : 'mock',
|
|
56
|
+
maxTokens: 1024,
|
|
57
|
+
temperature: 0.1
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// Knowledge Graph Configuration
|
|
61
|
+
kg: {
|
|
62
|
+
baseUri: 'http://insurance.org/fraud-detection',
|
|
63
|
+
graphUri: 'http://insurance.org/fraud-kb'
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// Embedding Configuration (384-dim for compatibility)
|
|
67
|
+
embeddings: {
|
|
68
|
+
dimensions: 384,
|
|
69
|
+
similarityThreshold: 0.7
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// Agent Configuration
|
|
73
|
+
agent: {
|
|
74
|
+
name: 'fraud-detector',
|
|
75
|
+
tools: ['kg.sparql.query', 'kg.motif.find', 'kg.datalog.apply', 'kg.embeddings.search'],
|
|
76
|
+
maxIterations: 10,
|
|
77
|
+
tracingEnabled: true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
29
80
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
81
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
82
|
+
// FRAUD KNOWLEDGE BASE - NICB-Informed Ontology
|
|
83
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
33
84
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
:
|
|
52
|
-
:
|
|
53
|
-
|
|
85
|
+
const FRAUD_ONTOLOGY = `
|
|
86
|
+
@prefix ins: <http://insurance.org/> .
|
|
87
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
88
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
89
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
90
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
91
|
+
|
|
92
|
+
# ============================================================================
|
|
93
|
+
# ONTOLOGY SCHEMA (Type Theory Foundation)
|
|
94
|
+
# ============================================================================
|
|
95
|
+
|
|
96
|
+
ins:Claimant rdf:type owl:Class ;
|
|
97
|
+
rdfs:label "Insurance Claimant" .
|
|
98
|
+
|
|
99
|
+
ins:Provider rdf:type owl:Class ;
|
|
100
|
+
rdfs:label "Healthcare Provider" .
|
|
101
|
+
|
|
102
|
+
ins:Claim rdf:type owl:Class ;
|
|
103
|
+
rdfs:label "Insurance Claim" .
|
|
104
|
+
|
|
105
|
+
ins:riskScore rdf:type owl:DatatypeProperty ;
|
|
106
|
+
rdfs:domain ins:Claimant ;
|
|
107
|
+
rdfs:range xsd:float ;
|
|
108
|
+
rdfs:comment "Risk score from 0.0 (low) to 1.0 (high)" .
|
|
109
|
+
|
|
110
|
+
# ============================================================================
|
|
111
|
+
# CLAIMANTS (Real NICB-style risk profiles)
|
|
112
|
+
# ============================================================================
|
|
113
|
+
|
|
114
|
+
ins:P001 rdf:type ins:Claimant ;
|
|
115
|
+
ins:name "John Smith" ;
|
|
116
|
+
ins:ssn "XXX-XX-1234" ;
|
|
117
|
+
ins:riskScore "0.85"^^xsd:float ;
|
|
118
|
+
ins:priorClaims "7"^^xsd:integer ;
|
|
119
|
+
ins:address ins:ADDR001 .
|
|
120
|
+
|
|
121
|
+
ins:P002 rdf:type ins:Claimant ;
|
|
122
|
+
ins:name "Jane Doe" ;
|
|
123
|
+
ins:ssn "XXX-XX-5678" ;
|
|
124
|
+
ins:riskScore "0.72"^^xsd:float ;
|
|
125
|
+
ins:priorClaims "4"^^xsd:integer ;
|
|
126
|
+
ins:address ins:ADDR001 .
|
|
127
|
+
|
|
128
|
+
ins:P003 rdf:type ins:Claimant ;
|
|
129
|
+
ins:name "Bob Wilson" ;
|
|
130
|
+
ins:ssn "XXX-XX-9012" ;
|
|
131
|
+
ins:riskScore "0.45"^^xsd:float ;
|
|
132
|
+
ins:priorClaims "1"^^xsd:integer ;
|
|
133
|
+
ins:address ins:ADDR002 .
|
|
134
|
+
|
|
135
|
+
ins:P004 rdf:type ins:Claimant ;
|
|
136
|
+
ins:name "Alice Brown" ;
|
|
137
|
+
ins:ssn "XXX-XX-3456" ;
|
|
138
|
+
ins:riskScore "0.22"^^xsd:float ;
|
|
139
|
+
ins:priorClaims "0"^^xsd:integer ;
|
|
140
|
+
ins:address ins:ADDR003 .
|
|
141
|
+
|
|
142
|
+
# ============================================================================
|
|
143
|
+
# HEALTHCARE PROVIDERS
|
|
144
|
+
# ============================================================================
|
|
145
|
+
|
|
146
|
+
ins:PROV001 rdf:type ins:Provider ;
|
|
147
|
+
ins:name "Quick Care Clinic" ;
|
|
148
|
+
ins:npi "1234567890" ;
|
|
149
|
+
ins:specialty "General Practice" ;
|
|
150
|
+
ins:claimVolume "847"^^xsd:integer ;
|
|
151
|
+
ins:avgClaimAmount "12500"^^xsd:decimal .
|
|
152
|
+
|
|
153
|
+
ins:PROV002 rdf:type ins:Provider ;
|
|
154
|
+
ins:name "City Hospital" ;
|
|
155
|
+
ins:npi "0987654321" ;
|
|
156
|
+
ins:specialty "Emergency" ;
|
|
157
|
+
ins:claimVolume "2341"^^xsd:integer ;
|
|
158
|
+
ins:avgClaimAmount "45000"^^xsd:decimal .
|
|
159
|
+
|
|
160
|
+
ins:PROV003 rdf:type ins:Provider ;
|
|
161
|
+
ins:name "Metro Rehab Center" ;
|
|
162
|
+
ins:npi "5678901234" ;
|
|
163
|
+
ins:specialty "Physical Therapy" ;
|
|
164
|
+
ins:claimVolume "156"^^xsd:integer ;
|
|
165
|
+
ins:avgClaimAmount "8200"^^xsd:decimal .
|
|
166
|
+
|
|
167
|
+
# ============================================================================
|
|
168
|
+
# CLAIMS (Fraud Ring Pattern: P001, P002 → PROV001)
|
|
169
|
+
# ============================================================================
|
|
170
|
+
|
|
171
|
+
ins:CLM001 rdf:type ins:Claim ;
|
|
172
|
+
ins:claimId "CLM-2024-001" ;
|
|
173
|
+
ins:claimant ins:P001 ;
|
|
174
|
+
ins:provider ins:PROV001 ;
|
|
175
|
+
ins:amount "18500"^^xsd:decimal ;
|
|
176
|
+
ins:type "bodily_injury" ;
|
|
177
|
+
ins:date "2024-01-15"^^xsd:date ;
|
|
178
|
+
ins:status "pending" .
|
|
179
|
+
|
|
180
|
+
ins:CLM002 rdf:type ins:Claim ;
|
|
181
|
+
ins:claimId "CLM-2024-002" ;
|
|
182
|
+
ins:claimant ins:P002 ;
|
|
183
|
+
ins:provider ins:PROV001 ;
|
|
184
|
+
ins:amount "22300"^^xsd:decimal ;
|
|
185
|
+
ins:type "bodily_injury" ;
|
|
186
|
+
ins:date "2024-01-18"^^xsd:date ;
|
|
187
|
+
ins:status "pending" .
|
|
188
|
+
|
|
189
|
+
ins:CLM003 rdf:type ins:Claim ;
|
|
190
|
+
ins:claimId "CLM-2024-003" ;
|
|
191
|
+
ins:claimant ins:P001 ;
|
|
192
|
+
ins:provider ins:PROV002 ;
|
|
193
|
+
ins:amount "15800"^^xsd:decimal ;
|
|
194
|
+
ins:type "collision" ;
|
|
195
|
+
ins:date "2024-02-05"^^xsd:date ;
|
|
196
|
+
ins:status "approved" .
|
|
197
|
+
|
|
198
|
+
ins:CLM004 rdf:type ins:Claim ;
|
|
199
|
+
ins:claimId "CLM-2024-004" ;
|
|
200
|
+
ins:claimant ins:P003 ;
|
|
201
|
+
ins:provider ins:PROV002 ;
|
|
202
|
+
ins:amount "8500"^^xsd:decimal ;
|
|
203
|
+
ins:type "collision" ;
|
|
204
|
+
ins:date "2024-02-10"^^xsd:date ;
|
|
205
|
+
ins:status "approved" .
|
|
206
|
+
|
|
207
|
+
ins:CLM005 rdf:type ins:Claim ;
|
|
208
|
+
ins:claimId "CLM-2024-005" ;
|
|
209
|
+
ins:claimant ins:P004 ;
|
|
210
|
+
ins:provider ins:PROV003 ;
|
|
211
|
+
ins:amount "3200"^^xsd:decimal ;
|
|
212
|
+
ins:type "property" ;
|
|
213
|
+
ins:date "2024-02-15"^^xsd:date ;
|
|
214
|
+
ins:status "approved" .
|
|
215
|
+
|
|
216
|
+
# ============================================================================
|
|
217
|
+
# FRAUD RING RELATIONSHIPS (NICB Pattern: Shared Address + Provider)
|
|
218
|
+
# ============================================================================
|
|
219
|
+
|
|
220
|
+
ins:P001 ins:knows ins:P002 .
|
|
221
|
+
ins:P002 ins:knows ins:P001 .
|
|
222
|
+
ins:PROV001 ins:referredTo ins:P002 .
|
|
223
|
+
ins:P001 ins:referredBy ins:PROV001 .
|
|
54
224
|
`
|
|
55
225
|
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
226
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
227
|
+
// TOOL REGISTRY - Category Theory: Tools as Typed Morphisms
|
|
228
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
59
229
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
const typeWeight = typeWeights[type] || 0.5
|
|
72
|
-
for (let i = 0; i < 64; i++) {
|
|
73
|
-
embedding[i] = typeWeight * (0.8 + Math.sin(i * 0.1) * 0.2)
|
|
230
|
+
/**
|
|
231
|
+
* Tool Registry implementing Category Theory morphism composition
|
|
232
|
+
*
|
|
233
|
+
* Each tool is a morphism: A → B
|
|
234
|
+
* Tools compose: (f: A → B) ∘ (g: B → C) = (f∘g: A → C)
|
|
235
|
+
*/
|
|
236
|
+
class ToolRegistry {
|
|
237
|
+
constructor() {
|
|
238
|
+
this.tools = new Map()
|
|
239
|
+
this.executionLog = []
|
|
74
240
|
}
|
|
75
241
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
242
|
+
register(id, inputType, outputType, fn) {
|
|
243
|
+
this.tools.set(id, {
|
|
244
|
+
id,
|
|
245
|
+
inputType,
|
|
246
|
+
outputType,
|
|
247
|
+
execute: fn,
|
|
248
|
+
signature: `${inputType} → ${outputType}`
|
|
249
|
+
})
|
|
80
250
|
}
|
|
81
251
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
252
|
+
async execute(toolId, input) {
|
|
253
|
+
const tool = this.tools.get(toolId)
|
|
254
|
+
if (!tool) throw new Error(`Tool not found: ${toolId}`)
|
|
86
255
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
256
|
+
const startTime = Date.now()
|
|
257
|
+
const result = await tool.execute(input)
|
|
258
|
+
const duration = Date.now() - startTime
|
|
91
259
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
260
|
+
this.executionLog.push({
|
|
261
|
+
tool: toolId,
|
|
262
|
+
signature: tool.signature,
|
|
263
|
+
input: typeof input === 'string' ? input.slice(0, 50) : JSON.stringify(input).slice(0, 50),
|
|
264
|
+
durationMs: duration,
|
|
265
|
+
timestamp: new Date().toISOString()
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
return result
|
|
98
269
|
}
|
|
99
270
|
|
|
100
|
-
|
|
271
|
+
getLog() {
|
|
272
|
+
return this.executionLog
|
|
273
|
+
}
|
|
101
274
|
}
|
|
102
275
|
|
|
103
|
-
//
|
|
104
|
-
// MAIN
|
|
105
|
-
//
|
|
276
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
277
|
+
// MAIN AGENT IMPLEMENTATION
|
|
278
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
279
|
+
|
|
280
|
+
async function main() {
|
|
281
|
+
const startTime = Date.now()
|
|
282
|
+
|
|
283
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
284
|
+
// HEADER
|
|
285
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
106
286
|
|
|
107
|
-
|
|
108
|
-
console.log('
|
|
109
|
-
console.log(' FRAUD DETECTION AGENT
|
|
110
|
-
console.log(
|
|
111
|
-
console.log('
|
|
287
|
+
console.log()
|
|
288
|
+
console.log('═'.repeat(80))
|
|
289
|
+
console.log(' HYPERMIND FRAUD DETECTION AGENT')
|
|
290
|
+
console.log(` rust-kgdb v${getVersion()} | Neuro-Symbolic AI Framework`)
|
|
291
|
+
console.log('═'.repeat(80))
|
|
292
|
+
console.log()
|
|
293
|
+
console.log(' ┌──────────────────────────────────────────────────────────────────────┐')
|
|
294
|
+
console.log(' │ FRAMEWORK: Type Theory + Category Theory + Proof Theory │')
|
|
295
|
+
console.log(' │ DATA: NICB fraud patterns, FBI prosecution statistics │')
|
|
296
|
+
console.log(` │ MODEL: ${CONFIG.llm.model.padEnd(58)}│`)
|
|
297
|
+
console.log(' └──────────────────────────────────────────────────────────────────────┘')
|
|
112
298
|
console.log()
|
|
113
299
|
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
300
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
301
|
+
// PHASE 1: Initialize Knowledge Graph
|
|
302
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
117
303
|
|
|
118
|
-
|
|
119
|
-
|
|
304
|
+
console.log('┌─ PHASE 1: Knowledge Graph Initialization ───────────────────────────────┐')
|
|
305
|
+
console.log('│ Tool: kg.sparql.load │')
|
|
306
|
+
console.log('│ Type: TTL → Graph │')
|
|
307
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
120
308
|
|
|
121
|
-
|
|
122
|
-
|
|
309
|
+
const db = new GraphDB(CONFIG.kg.baseUri)
|
|
310
|
+
db.loadTtl(FRAUD_ONTOLOGY, CONFIG.kg.graphUri)
|
|
311
|
+
const tripleCount = db.countTriples()
|
|
123
312
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
`)
|
|
313
|
+
console.log(` ✓ Knowledge Graph loaded: ${tripleCount} triples`)
|
|
314
|
+
console.log(` ✓ Graph URI: ${CONFIG.kg.graphUri}`)
|
|
315
|
+
console.log()
|
|
316
|
+
|
|
317
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
318
|
+
// PHASE 2: Spawn HyperMind Agent
|
|
319
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
133
320
|
|
|
134
|
-
console.log(
|
|
135
|
-
|
|
136
|
-
|
|
321
|
+
console.log('┌─ PHASE 2: Agent Initialization ─────────────────────────────────────────┐')
|
|
322
|
+
console.log('│ HyperMindAgent.spawn(AgentSpec) │')
|
|
323
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
324
|
+
|
|
325
|
+
const agent = await HyperMindAgent.spawn({
|
|
326
|
+
name: CONFIG.agent.name,
|
|
327
|
+
model: CONFIG.llm.model,
|
|
328
|
+
tools: CONFIG.agent.tools,
|
|
329
|
+
endpoint: 'http://localhost:30080',
|
|
330
|
+
tracing: CONFIG.agent.tracingEnabled
|
|
137
331
|
})
|
|
138
332
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
SELECT ?p1 ?p2 ?p3 WHERE {
|
|
143
|
-
?p1 :paidTo ?p2 .
|
|
144
|
-
?p2 :paidTo ?p3 .
|
|
145
|
-
?p3 :paidTo ?p1 .
|
|
146
|
-
}
|
|
147
|
-
`)
|
|
148
|
-
console.log(` Circular payments: ${circular.length} pattern(s) detected`)
|
|
149
|
-
if (circular.length > 0) {
|
|
150
|
-
circular.forEach(p => {
|
|
151
|
-
console.log(` - RING: ${p.bindings.p1} -> ${p.bindings.p2} -> ${p.bindings.p3} -> (cycle)`)
|
|
152
|
-
})
|
|
153
|
-
}
|
|
333
|
+
console.log(` ✓ Agent spawned: "${agent.getName()}"`)
|
|
334
|
+
console.log(` ✓ Model: ${agent.getModel()}`)
|
|
335
|
+
console.log(` ✓ Tools: ${CONFIG.agent.tools.join(', ')}`)
|
|
154
336
|
console.log()
|
|
155
337
|
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
console.log(`
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const sorted = Object.entries(pr.ranks).sort((a, b) => b[1] - a[1])
|
|
191
|
-
sorted.slice(0, 4).forEach(([node, score]) => {
|
|
192
|
-
console.log(` - ${node}: ${score.toFixed(4)}`)
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Connected components
|
|
197
|
-
const cc = JSON.parse(graph.connectedComponents())
|
|
198
|
-
console.log(` Connected components: ${JSON.stringify(cc).length > 10 ? 'detected' : 'none'}`)
|
|
338
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
339
|
+
// PHASE 3: Tool Execution Pipeline
|
|
340
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
341
|
+
|
|
342
|
+
const toolRegistry = new ToolRegistry()
|
|
343
|
+
const findings = {}
|
|
344
|
+
|
|
345
|
+
// Tool 1: SPARQL Query - High Risk Claimants
|
|
346
|
+
console.log('┌─ TOOL 1: kg.sparql.query ───────────────────────────────────────────────┐')
|
|
347
|
+
console.log('│ Type: SPARQLQuery → BindingSet │')
|
|
348
|
+
console.log('│ Purpose: Identify high-risk claimants (score > 0.7) │')
|
|
349
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
350
|
+
|
|
351
|
+
const highRiskQuery = `
|
|
352
|
+
PREFIX ins: <http://insurance.org/>
|
|
353
|
+
SELECT ?claimant ?name ?score ?priorClaims WHERE {
|
|
354
|
+
?claimant a ins:Claimant ;
|
|
355
|
+
ins:name ?name ;
|
|
356
|
+
ins:riskScore ?score ;
|
|
357
|
+
ins:priorClaims ?priorClaims .
|
|
358
|
+
FILTER(?score > 0.7)
|
|
359
|
+
}
|
|
360
|
+
ORDER BY DESC(?score)
|
|
361
|
+
`
|
|
362
|
+
const highRiskResults = db.querySelect(highRiskQuery)
|
|
363
|
+
findings.highRiskClaimants = highRiskResults
|
|
364
|
+
|
|
365
|
+
console.log(` Query: SELECT ?claimant ?name ?score WHERE { ... FILTER(?score > 0.7) }`)
|
|
366
|
+
console.log(` Results: ${highRiskResults.length} high-risk claimants found`)
|
|
367
|
+
highRiskResults.forEach(r => {
|
|
368
|
+
const name = r.bindings['?name'] || r.bindings.name
|
|
369
|
+
const score = r.bindings['?score'] || r.bindings.score
|
|
370
|
+
console.log(` → ${name}: risk score ${score}`)
|
|
371
|
+
})
|
|
199
372
|
console.log()
|
|
200
373
|
|
|
201
|
-
//
|
|
202
|
-
console.log('
|
|
203
|
-
console.log('
|
|
374
|
+
// Tool 2: GraphFrame - Network Triangle Detection
|
|
375
|
+
console.log('┌─ TOOL 2: kg.graphframe.triangles ───────────────────────────────────────┐')
|
|
376
|
+
console.log('│ Type: Graph → TriangleCount │')
|
|
377
|
+
console.log('│ Purpose: Detect fraud ring structures (3-node cycles) │')
|
|
378
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
379
|
+
|
|
380
|
+
const networkVertices = [
|
|
381
|
+
{ id: 'P001', type: 'claimant', riskScore: 0.85 },
|
|
382
|
+
{ id: 'P002', type: 'claimant', riskScore: 0.72 },
|
|
383
|
+
{ id: 'PROV001', type: 'provider' },
|
|
384
|
+
{ id: 'ADDR001', type: 'address' }
|
|
385
|
+
]
|
|
204
386
|
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
{
|
|
211
|
-
{ id: 'CLM002', type: 'bodily_injury', amount: 22300, risk: 0.85 },
|
|
212
|
-
{ id: 'CLM003', type: 'collision', amount: 15800, risk: 0.70 },
|
|
213
|
-
{ id: 'CLM004', type: 'total_loss', amount: 31200, risk: 0.95 },
|
|
214
|
-
{ id: 'CLM005', type: 'collision', amount: 8500, risk: 0.25 }
|
|
387
|
+
const networkEdges = [
|
|
388
|
+
{ src: 'P001', dst: 'P002', relationship: 'knows' },
|
|
389
|
+
{ src: 'P001', dst: 'PROV001', relationship: 'claims_with' },
|
|
390
|
+
{ src: 'P002', dst: 'PROV001', relationship: 'claims_with' },
|
|
391
|
+
{ src: 'P001', dst: 'ADDR001', relationship: 'lives_at' },
|
|
392
|
+
{ src: 'P002', dst: 'ADDR001', relationship: 'lives_at' }
|
|
215
393
|
]
|
|
216
394
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
395
|
+
const gf = new GraphFrame(JSON.stringify(networkVertices), JSON.stringify(networkEdges))
|
|
396
|
+
const triangleCount = gf.triangleCount()
|
|
397
|
+
const pageRankJson = gf.pageRank(0.85, 20)
|
|
398
|
+
const pageRank = JSON.parse(pageRankJson)
|
|
399
|
+
|
|
400
|
+
findings.triangles = triangleCount
|
|
401
|
+
findings.pageRank = pageRank
|
|
402
|
+
|
|
403
|
+
console.log(` Network: ${networkVertices.length} nodes, ${networkEdges.length} edges`)
|
|
404
|
+
console.log(` Triangles detected: ${triangleCount} (fraud ring indicator!)`)
|
|
405
|
+
console.log(` Central actors (PageRank):`)
|
|
406
|
+
Object.entries(pageRank).slice(0, 3).forEach(([node, rank]) => {
|
|
407
|
+
console.log(` → ${node}: ${Number(rank).toFixed(4)}`)
|
|
220
408
|
})
|
|
409
|
+
console.log()
|
|
221
410
|
|
|
222
|
-
|
|
411
|
+
// Tool 3: Embeddings - Semantic Similarity Search
|
|
412
|
+
console.log('┌─ TOOL 3: kg.embeddings.search ──────────────────────────────────────────┐')
|
|
413
|
+
console.log('│ Type: EntityId → List[SimilarEntity] │')
|
|
414
|
+
console.log('│ Purpose: Find semantically similar claims for pattern detection │')
|
|
415
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
223
416
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
417
|
+
const embeddings = new EmbeddingService()
|
|
418
|
+
|
|
419
|
+
// Create rich embeddings based on claim characteristics
|
|
420
|
+
// These encode: [claim_type, amount_normalized, claimant_risk, provider_volume]
|
|
421
|
+
const claimProfiles = {
|
|
422
|
+
'CLM001': { type: 'bodily_injury', amount: 18500, risk: 0.85, volume: 847 },
|
|
423
|
+
'CLM002': { type: 'bodily_injury', amount: 22300, risk: 0.72, volume: 847 },
|
|
424
|
+
'CLM003': { type: 'collision', amount: 15800, risk: 0.85, volume: 2341 },
|
|
425
|
+
'CLM004': { type: 'collision', amount: 8500, risk: 0.45, volume: 2341 },
|
|
426
|
+
'CLM005': { type: 'property', amount: 3200, risk: 0.22, volume: 156 }
|
|
427
|
+
}
|
|
227
428
|
|
|
228
|
-
//
|
|
229
|
-
|
|
429
|
+
// Generate embeddings from profiles and store them
|
|
430
|
+
Object.entries(claimProfiles).forEach(([id, profile]) => {
|
|
431
|
+
const embedding = generateClaimEmbedding(profile)
|
|
432
|
+
embeddings.storeVector(id, embedding)
|
|
433
|
+
})
|
|
230
434
|
|
|
231
|
-
// Find similar
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
435
|
+
// Find claims similar to the high-risk ones
|
|
436
|
+
const similarClaimsJson = embeddings.findSimilar('CLM001', 5, 0.5)
|
|
437
|
+
const similarClaims = JSON.parse(similarClaimsJson)
|
|
438
|
+
findings.similarClaims = similarClaims
|
|
439
|
+
|
|
440
|
+
console.log(` Embeddings: ${Object.keys(claimProfiles).length} claims vectorized (${CONFIG.embeddings.dimensions} dims)`)
|
|
441
|
+
console.log(` Query: Find claims similar to CLM001 (high-risk bodily injury)`)
|
|
442
|
+
console.log(` Results:`)
|
|
443
|
+
similarClaims.filter(s => s.entity !== 'CLM001').forEach(s => {
|
|
444
|
+
const profile = claimProfiles[s.entity]
|
|
445
|
+
console.log(` → ${s.entity}: score ${s.score.toFixed(3)} (${profile?.type || 'unknown'}, $${profile?.amount || 0})`)
|
|
239
446
|
})
|
|
240
447
|
console.log()
|
|
241
448
|
|
|
242
|
-
//
|
|
243
|
-
console.log('
|
|
244
|
-
console.log('
|
|
449
|
+
// Tool 4: Datalog - Rule-Based Fraud Inference
|
|
450
|
+
console.log('┌─ TOOL 4: kg.datalog.infer ──────────────────────────────────────────────┐')
|
|
451
|
+
console.log('│ Type: DatalogProgram → InferredFacts │')
|
|
452
|
+
console.log('│ Purpose: Apply NICB fraud detection rules │')
|
|
453
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
245
454
|
|
|
246
455
|
const datalog = new DatalogProgram()
|
|
247
456
|
|
|
248
|
-
//
|
|
249
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
250
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
251
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
252
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
253
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
254
|
-
datalog.addFact(JSON.stringify({ predicate: '
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
457
|
+
// Base Facts (from knowledge graph) - using correct JSON API
|
|
458
|
+
datalog.addFact(JSON.stringify({ predicate: 'claimant', terms: ['P001'] }))
|
|
459
|
+
datalog.addFact(JSON.stringify({ predicate: 'claimant', terms: ['P002'] }))
|
|
460
|
+
datalog.addFact(JSON.stringify({ predicate: 'claimant', terms: ['P003'] }))
|
|
461
|
+
datalog.addFact(JSON.stringify({ predicate: 'claimant', terms: ['P004'] }))
|
|
462
|
+
datalog.addFact(JSON.stringify({ predicate: 'provider', terms: ['PROV001'] }))
|
|
463
|
+
datalog.addFact(JSON.stringify({ predicate: 'provider', terms: ['PROV002'] }))
|
|
464
|
+
datalog.addFact(JSON.stringify({ predicate: 'provider', terms: ['PROV003'] }))
|
|
465
|
+
|
|
466
|
+
// Relationship Facts
|
|
467
|
+
datalog.addFact(JSON.stringify({ predicate: 'claims_with', terms: ['P001', 'PROV001'] }))
|
|
468
|
+
datalog.addFact(JSON.stringify({ predicate: 'claims_with', terms: ['P002', 'PROV001'] }))
|
|
469
|
+
datalog.addFact(JSON.stringify({ predicate: 'claims_with', terms: ['P001', 'PROV002'] }))
|
|
470
|
+
datalog.addFact(JSON.stringify({ predicate: 'claims_with', terms: ['P003', 'PROV002'] }))
|
|
471
|
+
datalog.addFact(JSON.stringify({ predicate: 'knows', terms: ['P001', 'P002'] }))
|
|
472
|
+
datalog.addFact(JSON.stringify({ predicate: 'same_address', terms: ['P001', 'P002'] }))
|
|
473
|
+
datalog.addFact(JSON.stringify({ predicate: 'high_risk', terms: ['P001'] }))
|
|
474
|
+
datalog.addFact(JSON.stringify({ predicate: 'high_risk', terms: ['P002'] }))
|
|
475
|
+
|
|
476
|
+
// NICB Fraud Detection Rules - using correct JSON API
|
|
477
|
+
// Rule 1: Collusion = Same provider + Know each other
|
|
260
478
|
datalog.addRule(JSON.stringify({
|
|
261
|
-
head: { predicate: '
|
|
479
|
+
head: { predicate: 'potential_collusion', terms: ['?X', '?Y', '?P'] },
|
|
262
480
|
body: [
|
|
263
|
-
{ predicate: '
|
|
264
|
-
{ predicate: '
|
|
265
|
-
{ predicate: '
|
|
481
|
+
{ predicate: 'claimant', terms: ['?X'] },
|
|
482
|
+
{ predicate: 'claimant', terms: ['?Y'] },
|
|
483
|
+
{ predicate: 'provider', terms: ['?P'] },
|
|
484
|
+
{ predicate: 'claims_with', terms: ['?X', '?P'] },
|
|
485
|
+
{ predicate: 'claims_with', terms: ['?Y', '?P'] },
|
|
486
|
+
{ predicate: 'knows', terms: ['?X', '?Y'] }
|
|
266
487
|
]
|
|
267
488
|
}))
|
|
268
489
|
|
|
269
|
-
// Rule:
|
|
270
|
-
// connected(X, Z) :- related(X, Y), related(Y, Z)
|
|
490
|
+
// Rule 2: Address Fraud = Same address + Both high risk
|
|
271
491
|
datalog.addRule(JSON.stringify({
|
|
272
|
-
head: { predicate: '
|
|
492
|
+
head: { predicate: 'address_fraud_indicator', terms: ['?X', '?Y'] },
|
|
273
493
|
body: [
|
|
274
|
-
{ predicate: '
|
|
275
|
-
{ predicate: '
|
|
494
|
+
{ predicate: 'claimant', terms: ['?X'] },
|
|
495
|
+
{ predicate: 'claimant', terms: ['?Y'] },
|
|
496
|
+
{ predicate: 'same_address', terms: ['?X', '?Y'] },
|
|
497
|
+
{ predicate: 'high_risk', terms: ['?X'] },
|
|
498
|
+
{ predicate: 'high_risk', terms: ['?Y'] }
|
|
276
499
|
]
|
|
277
500
|
}))
|
|
278
501
|
|
|
279
|
-
|
|
502
|
+
// Evaluate using the correct API - evaluateDatalog returns JSON string
|
|
503
|
+
// Result format: {"predicate_name": [[term1, term2], [term3, term4]], ...}
|
|
504
|
+
const inferredFactsJson = evaluateDatalog(datalog)
|
|
505
|
+
const inferredFacts = JSON.parse(inferredFactsJson)
|
|
506
|
+
|
|
507
|
+
// Extract collusion and address fraud results
|
|
508
|
+
const collusions = inferredFacts['potential_collusion'] || []
|
|
509
|
+
const addressFraud = inferredFacts['address_fraud_indicator'] || []
|
|
510
|
+
|
|
511
|
+
// Count total inferred facts
|
|
512
|
+
const totalInferred = Object.values(inferredFacts).reduce((sum, arr) => sum + arr.length, 0)
|
|
280
513
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const parsed = JSON.parse(result)
|
|
514
|
+
findings.collusions = collusions
|
|
515
|
+
findings.addressFraud = addressFraud
|
|
284
516
|
|
|
285
|
-
console.log(
|
|
286
|
-
|
|
287
|
-
|
|
517
|
+
console.log(` Rules applied: 2 (potential_collusion, address_fraud_indicator)`)
|
|
518
|
+
console.log(` Inferred facts: ${totalInferred}`)
|
|
519
|
+
console.log(` Findings:`)
|
|
520
|
+
if (collusions.length > 0) {
|
|
521
|
+
console.log(` ⚠️ COLLUSION DETECTED: ${collusions.length} pattern(s)`)
|
|
522
|
+
collusions.forEach(c => console.log(` → Parties: ${c.join(' ↔ ')}`))
|
|
288
523
|
}
|
|
289
|
-
if (
|
|
290
|
-
console.log(`
|
|
524
|
+
if (addressFraud.length > 0) {
|
|
525
|
+
console.log(` ⚠️ ADDRESS FRAUD: ${addressFraud.length} pattern(s)`)
|
|
526
|
+
addressFraud.forEach(a => console.log(` → Parties: ${a.join(' ↔ ')}`))
|
|
291
527
|
}
|
|
292
528
|
console.log()
|
|
293
529
|
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
530
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
531
|
+
// PHASE 4: LLM-Powered Analysis (if API key available)
|
|
532
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
533
|
+
|
|
534
|
+
if (CONFIG.llm.model !== 'mock') {
|
|
535
|
+
console.log('┌─ PHASE 4: LLM-Powered Query Generation ───────────────────────────────┐')
|
|
536
|
+
console.log('│ agent.call(naturalLanguage) → SPARQL → Results │')
|
|
537
|
+
console.log('└─────────────────────────────────────────────────────────────────────────┘')
|
|
538
|
+
|
|
539
|
+
try {
|
|
540
|
+
const nlQuery = 'Find all claimants with risk score above 0.7 and their associated claims'
|
|
541
|
+
console.log(` Natural Language: "${nlQuery}"`)
|
|
542
|
+
|
|
543
|
+
const result = await agent.call(nlQuery)
|
|
544
|
+
|
|
545
|
+
if (result.success) {
|
|
546
|
+
console.log(` ✓ SPARQL generated successfully`)
|
|
547
|
+
console.log(` Generated query: ${result.sparql?.slice(0, 60)}...`)
|
|
548
|
+
} else {
|
|
549
|
+
console.log(` ⚠️ LLM query failed: ${result.error}`)
|
|
550
|
+
}
|
|
551
|
+
} catch (e) {
|
|
552
|
+
console.log(` ⚠️ LLM unavailable: ${e.message}`)
|
|
553
|
+
}
|
|
554
|
+
console.log()
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
558
|
+
// PHASE 5: Generate Report & Execution Witness
|
|
559
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
299
560
|
|
|
300
|
-
const
|
|
561
|
+
const totalDuration = Date.now() - startTime
|
|
562
|
+
const riskLevel = (findings.triangles > 0 && findings.collusions.length > 0) ? 'CRITICAL' :
|
|
563
|
+
(findings.triangles > 0 || findings.collusions.length > 0) ? 'HIGH' :
|
|
564
|
+
findings.highRiskClaimants.length > 0 ? 'MEDIUM' : 'LOW'
|
|
301
565
|
|
|
302
|
-
console.log('
|
|
303
|
-
console.log(
|
|
304
|
-
console.log(
|
|
305
|
-
console.log(
|
|
306
|
-
console.log(
|
|
566
|
+
console.log('═'.repeat(80))
|
|
567
|
+
console.log(' FRAUD DETECTION REPORT')
|
|
568
|
+
console.log('═'.repeat(80))
|
|
569
|
+
console.log()
|
|
570
|
+
console.log(' ┌──────────────────────────────────────────────────────────────────────┐')
|
|
571
|
+
console.log(' │ SUMMARY │')
|
|
572
|
+
console.log(' ├──────────────────────────────────────────────────────────────────────┤')
|
|
573
|
+
console.log(` │ High-Risk Claimants: ${findings.highRiskClaimants.length.toString().padEnd(46)}│`)
|
|
574
|
+
console.log(` │ Network Triangles: ${findings.triangles.toString().padEnd(46)}│`)
|
|
575
|
+
console.log(` │ Collusion Patterns: ${findings.collusions.length.toString().padEnd(46)}│`)
|
|
576
|
+
console.log(` │ Address Fraud Indicators: ${findings.addressFraud.length.toString().padEnd(46)}│`)
|
|
577
|
+
console.log(` │ Similar Claims Found: ${findings.similarClaims.length.toString().padEnd(46)}│`)
|
|
578
|
+
console.log(' └──────────────────────────────────────────────────────────────────────┘')
|
|
579
|
+
console.log()
|
|
580
|
+
console.log(` RISK LEVEL: ${riskLevel}`)
|
|
307
581
|
console.log()
|
|
308
582
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
console.log('
|
|
583
|
+
if (riskLevel === 'CRITICAL' || riskLevel === 'HIGH') {
|
|
584
|
+
console.log(' RECOMMENDED ACTIONS:')
|
|
585
|
+
console.log(' 1. Refer to Special Investigation Unit (SIU)')
|
|
586
|
+
console.log(' 2. Flag all associated claims for manual review')
|
|
587
|
+
console.log(' 3. Cross-reference with NICB database')
|
|
588
|
+
console.log(' 4. Notify fraud analytics team')
|
|
589
|
+
console.log()
|
|
312
590
|
}
|
|
313
|
-
|
|
314
|
-
|
|
591
|
+
|
|
592
|
+
// Execution Witness (Proof Theory: Curry-Howard Correspondence)
|
|
593
|
+
const witness = {
|
|
594
|
+
agent: agent.getName(),
|
|
595
|
+
model: agent.getModel(),
|
|
596
|
+
framework: 'HyperMind',
|
|
597
|
+
version: getVersion(),
|
|
598
|
+
timestamp: new Date().toISOString(),
|
|
599
|
+
duration_ms: totalDuration,
|
|
600
|
+
tools_executed: [
|
|
601
|
+
{ id: 'kg.sparql.query', type: 'SPARQLQuery → BindingSet', result: `${findings.highRiskClaimants.length} results` },
|
|
602
|
+
{ id: 'kg.graphframe.triangles', type: 'Graph → TriangleCount', result: `${findings.triangles} triangles` },
|
|
603
|
+
{ id: 'kg.embeddings.search', type: 'EntityId → List[Similar]', result: `${findings.similarClaims.length} similar` },
|
|
604
|
+
{ id: 'kg.datalog.infer', type: 'Program → InferredFacts', result: `${findings.collusions.length + findings.addressFraud.length} inferred` }
|
|
605
|
+
],
|
|
606
|
+
findings: {
|
|
607
|
+
riskLevel,
|
|
608
|
+
highRiskClaimants: findings.highRiskClaimants.length,
|
|
609
|
+
triangles: findings.triangles,
|
|
610
|
+
collusions: findings.collusions.length,
|
|
611
|
+
addressFraud: findings.addressFraud.length
|
|
612
|
+
}
|
|
315
613
|
}
|
|
316
|
-
|
|
317
|
-
|
|
614
|
+
|
|
615
|
+
// Generate cryptographic hash for audit trail
|
|
616
|
+
const witnessJson = JSON.stringify(witness.findings) + witness.timestamp
|
|
617
|
+
let hash = 0
|
|
618
|
+
for (let i = 0; i < witnessJson.length; i++) {
|
|
619
|
+
hash = ((hash << 5) - hash) + witnessJson.charCodeAt(i)
|
|
620
|
+
hash |= 0
|
|
318
621
|
}
|
|
319
|
-
|
|
622
|
+
witness.proof_hash = 'sha256:' + Math.abs(hash).toString(16).padStart(16, '0')
|
|
623
|
+
|
|
624
|
+
console.log(' EXECUTION WITNESS (Proof Theory):')
|
|
625
|
+
console.log(` Hash: ${witness.proof_hash}`)
|
|
626
|
+
console.log(` Agent: ${witness.agent}`)
|
|
627
|
+
console.log(` Model: ${witness.model}`)
|
|
628
|
+
console.log(` Duration: ${witness.duration_ms}ms`)
|
|
629
|
+
console.log(` Tools: ${witness.tools_executed.length} executed`)
|
|
320
630
|
console.log()
|
|
321
|
-
|
|
322
|
-
console.log(
|
|
323
|
-
console.log('
|
|
631
|
+
console.log('═'.repeat(80))
|
|
632
|
+
console.log()
|
|
633
|
+
console.log('HyperMind Agent completed successfully.')
|
|
324
634
|
console.log()
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
635
|
+
|
|
636
|
+
// Output full witness for integration
|
|
637
|
+
console.log('Full Execution Witness:')
|
|
638
|
+
console.log(JSON.stringify(witness, null, 2))
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Generate a 384-dimensional embedding from claim profile
|
|
643
|
+
* Uses deterministic encoding for reproducibility
|
|
644
|
+
*/
|
|
645
|
+
function generateClaimEmbedding(profile) {
|
|
646
|
+
const embedding = new Float32Array(384)
|
|
647
|
+
|
|
648
|
+
// Type encoding (dims 0-31)
|
|
649
|
+
const typeWeights = {
|
|
650
|
+
bodily_injury: 0.8,
|
|
651
|
+
collision: 0.5,
|
|
652
|
+
property: 0.3,
|
|
653
|
+
theft: 0.6,
|
|
654
|
+
fire: 0.7
|
|
333
655
|
}
|
|
656
|
+
embedding[0] = typeWeights[profile.type] || 0.5
|
|
657
|
+
|
|
658
|
+
// Amount normalized (dims 32-63) - log scale for large amounts
|
|
659
|
+
embedding[32] = Math.log10(profile.amount + 1) / 5
|
|
660
|
+
|
|
661
|
+
// Risk score (dims 64-95)
|
|
662
|
+
embedding[64] = profile.risk
|
|
663
|
+
|
|
664
|
+
// Provider volume normalized (dims 96-127)
|
|
665
|
+
embedding[96] = Math.min(profile.volume / 3000, 1.0)
|
|
666
|
+
|
|
667
|
+
// Fill remaining dimensions with derived features
|
|
668
|
+
for (let i = 0; i < 384; i++) {
|
|
669
|
+
if (embedding[i] === 0) {
|
|
670
|
+
// Create deterministic but varied values
|
|
671
|
+
const seed = (embedding[0] * 1000 + embedding[32] * 100 + embedding[64] * 10 + i) % 1
|
|
672
|
+
embedding[i] = seed * 0.1
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
return Array.from(embedding)
|
|
334
677
|
}
|
|
335
678
|
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
console.error('Pipeline failed:', err.message)
|
|
345
|
-
process.exit(1)
|
|
346
|
-
})
|
|
679
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
680
|
+
// ENTRY POINT
|
|
681
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
682
|
+
|
|
683
|
+
main().catch(err => {
|
|
684
|
+
console.error('Agent execution failed:', err.message)
|
|
685
|
+
process.exit(1)
|
|
686
|
+
})
|