enigma-memory 0.1.17 → 0.1.22

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.
Files changed (290) hide show
  1. package/README.md +85 -27
  2. package/apps/cli/bin/enigma-desktop.mjs +140 -0
  3. package/apps/cli/bin/enigma-terminal.mjs +78 -0
  4. package/apps/cli/bin/enigma.mjs +4979 -3263
  5. package/apps/desktop/electron-main.cjs +217 -0
  6. package/apps/desktop/package.json +12 -0
  7. package/apps/desktop/src/app.js +264 -7
  8. package/apps/desktop/src/index.html +3514 -1373
  9. package/apps/desktop/src/launch-electron.mjs +51 -0
  10. package/apps/desktop/src/server.mjs +2914 -0
  11. package/apps/desktop/src/styles.css +2972 -260
  12. package/apps/desktop/src/zk-browser-prove.mjs +53 -0
  13. package/apps/desktop/src/zk-state.mjs +1789 -0
  14. package/apps/gateway/bin/enigma-gateway.mjs +102 -5
  15. package/apps/gateway/src/server.mjs +271 -8
  16. package/apps/ios/EnigmaCore/Package.swift +12 -0
  17. package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
  18. package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
  19. package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
  20. package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
  21. package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
  22. package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
  23. package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
  24. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
  25. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
  26. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
  27. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
  28. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
  29. package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
  30. package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
  31. package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
  32. package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
  33. package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
  34. package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
  35. package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
  36. package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
  37. package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
  38. package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
  39. package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
  40. package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
  41. package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
  42. package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
  43. package/apps/native-host/README.md +19 -8
  44. package/apps/native-host/bin/enigma-native-host.mjs +229 -13
  45. package/apps/relay/bin/enigma-relay.mjs +103 -5
  46. package/apps/relay/src/federation-runtime.mjs +618 -0
  47. package/apps/relay/src/server.mjs +310 -9
  48. package/apps/verifier/bin/enigma-verify.mjs +327 -11
  49. package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
  50. package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
  51. package/cortex-v3/circuits/build/vk_bytes.json +32 -0
  52. package/cortex-v3/proving-assets.json +64 -0
  53. package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
  54. package/cortex-v3/zk/action-transition-vk.json +119 -0
  55. package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
  56. package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
  57. package/cortex-v3/zk/intent-witness.mjs +365 -0
  58. package/cortex-v3/zk/intent-witness.test.mjs +485 -0
  59. package/cortex-v3/zk/proving-assets.mjs +203 -0
  60. package/cortex-v3/zk/sale-witness.mjs +783 -0
  61. package/cortex-v3/zk/sale-witness.test.mjs +784 -0
  62. package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
  63. package/cortex-v3/zk/settlement-evidence.mjs +722 -0
  64. package/cortex-v3/zk/setup-intent.mjs +688 -0
  65. package/cortex-v3/zk/setup-sale.mjs +666 -0
  66. package/cortex-v3/zk/setup.mjs +594 -0
  67. package/cortex-v3/zk/witness.mjs +184 -0
  68. package/cortex-v3/zk/zk-codec.mjs +232 -0
  69. package/cortex-v3/zk/zk-codec.test.mjs +293 -0
  70. package/cortex-v3/zk/zk-settle.mjs +370 -0
  71. package/cortex-v3/zk/zk-tree.mjs +256 -0
  72. package/cortex-v3/zk/zk-tree.test.mjs +419 -0
  73. package/deploy/SIMULATION.md +14 -9
  74. package/deploy/docker-compose.local-production-simulation.yml +54 -12
  75. package/docs/benchmark-attestation-network.md +487 -487
  76. package/docs/benchmark-reproducibility.md +289 -289
  77. package/docs/blockchain-only-mechanisms.md +400 -400
  78. package/docs/browser-extension-install.md +8 -6
  79. package/docs/client-connectors.md +16 -12
  80. package/docs/demo-proof-network.md +275 -275
  81. package/docs/developer-ecosystem.md +15 -13
  82. package/docs/developer-proof-quickstart.md +325 -325
  83. package/docs/enigma-memory-ready-conformance.md +378 -376
  84. package/docs/install-anywhere.md +64 -30
  85. package/docs/installers-and-desktop.md +8 -7
  86. package/docs/memory-benchmarks.md +1 -1
  87. package/docs/memory-drive-health-model.md +690 -690
  88. package/docs/novelty-invention-candidates.md +161 -161
  89. package/docs/proof-network-build-notes.md +240 -240
  90. package/docs/proof-network-claim-boundaries.md +320 -318
  91. package/docs/proof-network.md +339 -339
  92. package/docs/sdk-api.md +324 -324
  93. package/docs/solana-proof-rail.md +453 -453
  94. package/examples/01-quickstart-agent/index.mjs +49 -0
  95. package/examples/01_agent_memory_quickstart.mjs +57 -0
  96. package/examples/02-multi-agent-swarm/index.mjs +57 -0
  97. package/examples/02_cross_model_passport.mjs +64 -0
  98. package/examples/03-langchain-memory/index.mjs +41 -0
  99. package/examples/03_poseidon_commitment_verification.mjs +71 -0
  100. package/examples/04-python-trading-agent/trader.py +49 -0
  101. package/examples/README.md +27 -0
  102. package/examples/ci/github-actions.yml +7 -2
  103. package/package.json +410 -278
  104. package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
  105. package/packages/connectors/src/index.js +196 -4
  106. package/packages/connectors/swarm-router.mjs +168 -0
  107. package/packages/core/src/index.js +249 -2
  108. package/packages/core/src/version.mjs +7 -0
  109. package/packages/dev-tools/package.json +19 -0
  110. package/packages/dev-tools/src/index.js +4 -0
  111. package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
  112. package/packages/dev-tools/src/swarm-simulator.js +101 -0
  113. package/packages/dev-tools/src/vault-inspector.js +114 -0
  114. package/packages/dev-tools/src/vector-benchmark.js +100 -0
  115. package/packages/developer-platform/src/access-credentials.js +341 -0
  116. package/packages/developer-platform/src/http.js +132 -0
  117. package/packages/developer-platform/src/index.js +4 -0
  118. package/packages/developer-platform/src/usage-http.js +60 -0
  119. package/packages/developer-platform/src/usage.js +295 -0
  120. package/packages/enclave-runtime/attestation.mjs +159 -0
  121. package/packages/enclave-runtime/index.mjs +47 -0
  122. package/packages/enclave-runtime/session-manager.mjs +253 -0
  123. package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
  124. package/packages/enigma-reflex/package.json +14 -0
  125. package/packages/enigma-reflex/src/index.js +204 -0
  126. package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
  127. package/packages/enigma-reflex/training/requirements.txt +8 -0
  128. package/packages/enigma-reflex/training/train.py +314 -0
  129. package/packages/enigma-weave/LICENSE +22 -0
  130. package/packages/enigma-weave/UPSTREAM.json +21 -0
  131. package/packages/enigma-weave/package.json +14 -0
  132. package/packages/enigma-weave/src/index.js +286 -0
  133. package/packages/hosted-cloud/src/index.js +80 -5
  134. package/packages/importers/src/index.js +432 -0
  135. package/packages/inference-runtime/src/browser.js +401 -0
  136. package/packages/inference-runtime/src/chat.js +265 -0
  137. package/packages/inference-runtime/src/code.js +407 -0
  138. package/packages/inference-runtime/src/contracts.js +162 -0
  139. package/packages/inference-runtime/src/http.js +232 -0
  140. package/packages/inference-runtime/src/image.js +186 -0
  141. package/packages/inference-runtime/src/index.js +10 -0
  142. package/packages/inference-runtime/src/model-router.js +320 -0
  143. package/packages/inference-runtime/src/platform.js +125 -0
  144. package/packages/inference-runtime/src/privacy.js +400 -0
  145. package/packages/inference-runtime/src/video.js +253 -0
  146. package/packages/mcp-server/README.md +22 -6
  147. package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
  148. package/packages/mcp-server/src/index.js +2498 -1185
  149. package/packages/mcp-server/src/oauth.js +561 -0
  150. package/packages/mcp-server/src/private-handoff.js +84 -0
  151. package/packages/mcp-server/src/remote-http.js +273 -0
  152. package/packages/mcp-server/src/remote-policy.js +72 -0
  153. package/packages/mcp-server/swarm-bridge.mjs +361 -0
  154. package/packages/mesh/index.d.ts +283 -0
  155. package/packages/mesh/package.json +23 -0
  156. package/packages/mesh/src/crypto.js +189 -0
  157. package/packages/mesh/src/federation-packets.js +353 -0
  158. package/packages/mesh/src/gossip.js +311 -0
  159. package/packages/mesh/src/index.js +6 -0
  160. package/packages/mesh/src/protocol.js +255 -0
  161. package/packages/mesh/src/router.js +279 -0
  162. package/packages/mesh/src/transport.js +306 -0
  163. package/packages/passport/src/index.js +436 -7
  164. package/packages/private-economy/src/credits-http.js +100 -0
  165. package/packages/private-economy/src/credits.js +447 -0
  166. package/packages/private-economy/src/index.js +5 -0
  167. package/packages/private-economy/src/payments-http.js +120 -0
  168. package/packages/private-economy/src/payments.js +509 -0
  169. package/packages/private-economy/src/x402.js +346 -0
  170. package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
  171. package/packages/rag/index.d.ts +182 -0
  172. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
  173. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
  174. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
  175. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
  176. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
  177. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
  178. package/packages/rag/package.json +27 -0
  179. package/packages/rag/src/blinded-search.js +109 -0
  180. package/packages/rag/src/bm25.js +169 -0
  181. package/packages/rag/src/embeddings.js +459 -0
  182. package/packages/rag/src/hybrid.js +76 -0
  183. package/packages/rag/src/index.js +38 -0
  184. package/packages/rag/src/reranker.js +61 -0
  185. package/packages/rag/src/research.js +107 -0
  186. package/packages/rag/src/vector-store.js +430 -0
  187. package/packages/rag/src/verify-model-artifacts.mjs +4 -0
  188. package/packages/sdk/index.d.ts +760 -0
  189. package/packages/sdk/package.json +33 -0
  190. package/packages/sdk/python/README.md +24 -0
  191. package/packages/sdk/python/enigma_sdk.py +250 -0
  192. package/packages/sdk/python/pyproject.toml +34 -0
  193. package/packages/sdk/python/requirements.txt +1 -0
  194. package/packages/sdk/python/setup.py +20 -0
  195. package/packages/sdk/src/federation/capability-grant.js +389 -0
  196. package/packages/sdk/src/federation/federation-router.js +360 -0
  197. package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
  198. package/packages/sdk/src/federation/index.js +3 -0
  199. package/packages/sdk/src/index.js +1796 -0
  200. package/packages/sdk/src/intelligence/contradiction.js +337 -0
  201. package/packages/sdk/src/intelligence/decision-engine.js +155 -0
  202. package/packages/sdk/src/intelligence/index.js +4 -0
  203. package/packages/sdk/src/intelligence/ontology.js +122 -0
  204. package/packages/sdk/src/intelligence/temporal.js +123 -0
  205. package/packages/sdk/src/market-client.js +142 -0
  206. package/packages/sdk/src/mesh-client.js +110 -0
  207. package/packages/sdk/src/middleware/index.js +3 -0
  208. package/packages/sdk/src/middleware/langchain.js +159 -0
  209. package/packages/sdk/src/middleware/llamaindex.js +101 -0
  210. package/packages/sdk/src/middleware/vercel-ai.js +112 -0
  211. package/packages/sdk/src/rag-client.js +85 -0
  212. package/packages/sdk/src/swarm-orchestrator.js +260 -0
  213. package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
  214. package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
  215. package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
  216. package/packages/snapcompact/index.d.ts +284 -0
  217. package/packages/snapcompact/package.json +25 -0
  218. package/packages/snapcompact/src/index.js +716 -0
  219. package/packages/storage/PACKAGE_CONTRACT.md +1 -1
  220. package/packages/terminal-console/animations.mjs +240 -0
  221. package/packages/terminal-console/auto-anchor.mjs +220 -0
  222. package/packages/terminal-console/banner.mjs +91 -0
  223. package/packages/terminal-console/commands.mjs +459 -0
  224. package/packages/terminal-console/delegation.mjs +152 -0
  225. package/packages/terminal-console/index.mjs +5 -0
  226. package/packages/terminal-console/outbox.mjs +143 -0
  227. package/packages/terminal-console/phantom-bridge.mjs +637 -0
  228. package/packages/terminal-console/repl.mjs +136 -0
  229. package/packages/terminal-console/signer-store.mjs +130 -0
  230. package/packages/terminal-console/solana-rpc.mjs +214 -0
  231. package/packages/terminal-console/solana-transport.mjs +189 -0
  232. package/packages/terminal-tui/dashboard.mjs +214 -0
  233. package/packages/terminal-tui/index.mjs +28 -0
  234. package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
  235. package/packages/terminal-tui/telemetry-hud.mjs +137 -0
  236. package/packages/vault/index.d.ts +449 -0
  237. package/packages/vault/package.json +27 -0
  238. package/packages/vault/src/e2ee.mjs +393 -0
  239. package/packages/vault/src/enclave.js +481 -0
  240. package/packages/vault/src/erasure.js +207 -0
  241. package/packages/vault/src/index.js +1150 -125
  242. package/packages/vault/src/persistence.js +307 -0
  243. package/packages/vault/src/poseidon.js +354 -0
  244. package/packages/vault/src/receipt.js +459 -0
  245. package/scripts/benchmark-optical-context.mjs +166 -0
  246. package/scripts/bootstrap-enigma.mjs +502 -0
  247. package/scripts/build-edge-backend-workers.mjs +20 -5
  248. package/scripts/build-goal-completion-audit.mjs +72 -25
  249. package/scripts/build-hosted-api-key-lifecycle.mjs +292 -274
  250. package/scripts/build-hosted-customer-lifecycle.mjs +493 -476
  251. package/scripts/build-hosted-probe-worker.mjs +19 -4
  252. package/scripts/build-installer-assets.mjs +409 -389
  253. package/scripts/build-operator-evidence-starter.mjs +59 -1
  254. package/scripts/build-production-backend-env-kit.mjs +2 -0
  255. package/scripts/build-production-unblocker.mjs +4 -1
  256. package/scripts/build-proof-network-packet.mjs +213 -213
  257. package/scripts/check.mjs +25 -4
  258. package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
  259. package/scripts/install-enigma-local.mjs +18 -5
  260. package/scripts/release-audit.mjs +74 -115
  261. package/scripts/release-provenance.mjs +12 -2
  262. package/scripts/run-backend-readiness-smoke.mjs +112 -10
  263. package/scripts/run-standard-memory-benchmarks.mjs +1354 -1352
  264. package/scripts/scan-secrets.mjs +178 -0
  265. package/scripts/simulate-production-env.mjs +71 -10
  266. package/scripts/validate-hosted-backend-live.mjs +112 -1
  267. package/specs/antibody-pack-v1.schema.json +95 -0
  268. package/specs/antigen-envelope-v1.schema.json +81 -0
  269. package/specs/boundary-manifest-v1.schema.json +35 -35
  270. package/specs/capsule-v1.schema.json +55 -55
  271. package/specs/claim-boundary-manifest-v1.schema.json +22 -22
  272. package/specs/claim-ledger-v1.schema.json +291 -0
  273. package/specs/context-passport-v1.schema.json +59 -0
  274. package/specs/deletion-tombstone-v1.schema.json +26 -26
  275. package/specs/evidence-packet-v1.schema.json +177 -0
  276. package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
  277. package/specs/immune-scan-report-v1.schema.json +112 -0
  278. package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
  279. package/specs/memory-atom-v1.schema.json +59 -0
  280. package/specs/memory-event-v1.schema.json +42 -42
  281. package/specs/passport-v1.schema.json +50 -50
  282. package/specs/proof-of-non-use-v1.schema.json +65 -0
  283. package/specs/quarantine-record-v1.schema.json +126 -0
  284. package/specs/receipt-v1.schema.json +61 -61
  285. package/specs/state-checkpoint-v1.schema.json +37 -37
  286. package/specs/trust-bundle-v1.schema.json +56 -56
  287. package/specs/trust-card-v1.schema.json +119 -0
  288. package/docs/proof-network-launch-plan.md +0 -421
  289. package/packages/metering/PACKAGE_CONTRACT.md +0 -20
  290. package/scripts/build-ai-orchestration-plan.mjs +0 -248
@@ -0,0 +1,459 @@
1
+ // Enigma Sovereign Embedding & Lexical-Vector Provider.
2
+ // Neural inference is local-only and pinned to the bundled, hash-verified model.
3
+ import { createHash } from 'node:crypto';
4
+ import { readFile } from 'node:fs/promises';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ export const EMBEDDING_DIM = 384;
8
+
9
+ export const LEXICAL_HASH_DESCRIPTOR = Object.freeze({
10
+ provider: 'enigma_lexical_hash',
11
+ version: '1.0.0',
12
+ dimension: EMBEDDING_DIM,
13
+ architecture: 'DeterministicLexicalHash/NgramProjection',
14
+ description: 'Explicit deterministic subword n-gram fallback with position-weighted pooling and L2 unit-sphere normalization.',
15
+ });
16
+
17
+ export const LOCAL_MINILM_DESCRIPTOR = Object.freeze({
18
+ provider: 'huggingface_transformers_local',
19
+ package: '@huggingface/transformers',
20
+ packageVersion: '4.2.0',
21
+ modelId: 'Xenova/all-MiniLM-L6-v2',
22
+ immutableCommit: '751bff37182d3f1213fa05d7196b954e230abad9',
23
+ dimension: EMBEDDING_DIM,
24
+ maxSequenceLength: 512,
25
+ dtype: 'q8',
26
+ device: 'cpu',
27
+ pooling: 'mean',
28
+ normalization: 'l2_unit_sphere',
29
+ manifest: 'sha256-manifest.json',
30
+ manifestSha256: 'c1d03ad7b6e33e74fdbb862bda766cffb6c2bc6674f9628172d98c8f58b8b103',
31
+ artifacts: Object.freeze([
32
+ Object.freeze({ path: 'config.json', size: 650, sha256: '7135149f7cffa1a573466c6e4d8423ed73b62fd2332c575bf738a0d033f70df7' }),
33
+ Object.freeze({ path: 'tokenizer.json', size: 711661, sha256: 'da0e79933b9ed51798a3ae27893d3c5fa4a201126cef75586296df9b4d2c62a0' }),
34
+ Object.freeze({ path: 'tokenizer_config.json', size: 366, sha256: '9261e7d79b44c8195c1cada2b453e55b00aeb81e907a6664974b4d7776172ab3' }),
35
+ Object.freeze({ path: 'onnx/model_quantized.onnx', size: 22972370, sha256: 'afdb6f1a0e45b715d0bb9b11772f032c399babd23bfc31fed1c170afc848bdb1' }),
36
+ ]),
37
+ });
38
+
39
+ // Retained name for callers that inspected the earlier integration descriptor.
40
+ export const ONNX_INTEGRATION_SPEC = LOCAL_MINILM_DESCRIPTOR;
41
+
42
+ /**
43
+ * Word and subword tokenizer.
44
+ * Segments strings into lowercase words and subword fragments.
45
+ * @param {string} text
46
+ * @returns {Array<{ token: string, isSubword: boolean, pos: number }>}
47
+ */
48
+ export function tokenizeSubwords(text) {
49
+ if (!text || typeof text !== 'string') return [];
50
+ const normalized = text.toLowerCase().replace(/[^\w\s]/g, ' ');
51
+ const words = normalized.split(/\s+/).filter(w => w.length > 0);
52
+ const tokens = [];
53
+
54
+ let pos = 0;
55
+ for (const word of words) {
56
+ tokens.push({ token: word, isSubword: false, pos: pos++ });
57
+ if (word.length > 4) {
58
+ const mid = Math.floor(word.length / 2);
59
+ tokens.push({ token: word.slice(0, mid), isSubword: false, pos });
60
+ tokens.push({ token: `##${word.slice(mid)}`, isSubword: true, pos });
61
+ pos++;
62
+ }
63
+ }
64
+ return tokens;
65
+ }
66
+
67
+ /**
68
+ * Deterministic Murmur-style hash for feature projection.
69
+ */
70
+ function hashFeature(str, seed = 0) {
71
+ let h = seed ^ str.length;
72
+ for (let i = 0; i < str.length; i++) {
73
+ const c = str.charCodeAt(i);
74
+ h = Math.imul(h ^ c, 0x5bd1e995);
75
+ h ^= h >>> 15;
76
+ }
77
+ return (h >>> 0);
78
+ }
79
+
80
+ /**
81
+ * Computes 384-dimensional dense vector via deterministic subword feature hashing,
82
+ * position-weighted pooling, and L2 unit-sphere normalization.
83
+ * Note: This is an offline lexical-hash fallback, not neural transformer inference.
84
+ * @param {string} text
85
+ * @param {number} [dim=384]
86
+ * @returns {Float32Array} L2-normalized 384-D vector
87
+ */
88
+ export function computeLexicalEmbedding(text, dim = EMBEDDING_DIM) {
89
+ const tokens = tokenizeSubwords(text);
90
+ const vector = new Float32Array(dim);
91
+
92
+ if (tokens.length === 0) {
93
+ return vector;
94
+ }
95
+
96
+ const HEAD_SEEDS = [0x9747b28c, 0xcafebabe, 0x85ebca6b, 0x5bd1e995, 0x12b9b0a1, 0x43f119e2];
97
+ let totalWeight = 0;
98
+
99
+ for (const item of tokens) {
100
+ const weight = (item.isSubword ? 0.65 : 1.25) / Math.sqrt(1 + item.pos * 0.05);
101
+ totalWeight += weight;
102
+
103
+ for (let h = 0; h < HEAD_SEEDS.length; h++) {
104
+ const h1 = hashFeature(item.token, HEAD_SEEDS[h]);
105
+ const idx = h1 % dim;
106
+ const sign = (hashFeature(item.token, h1) & 1) === 0 ? 1.0 : -1.0;
107
+ vector[idx] += sign * weight;
108
+ }
109
+ }
110
+
111
+ if (totalWeight > 1e-12) {
112
+ const invWeight = 1.0 / totalWeight;
113
+ for (let i = 0; i < dim; i++) {
114
+ vector[i] *= invWeight;
115
+ }
116
+ }
117
+
118
+ const mixed = new Float32Array(dim);
119
+ for (let i = 0; i < dim; i++) {
120
+ const prev = vector[(i - 1 + dim) % dim];
121
+ const curr = vector[i];
122
+ const next = vector[(i + 1) % dim];
123
+ mixed[i] = curr * 0.70 + (prev + next) * 0.15;
124
+ }
125
+
126
+ let normSq = 0;
127
+ for (let i = 0; i < dim; i++) {
128
+ normSq += mixed[i] * mixed[i];
129
+ }
130
+ const norm = Math.sqrt(normSq);
131
+ if (norm > 1e-12) {
132
+ const invNorm = 1.0 / norm;
133
+ for (let i = 0; i < dim; i++) {
134
+ mixed[i] *= invNorm;
135
+ }
136
+ }
137
+
138
+ return mixed;
139
+ }
140
+
141
+ const BUNDLED_MODELS_URL = new URL('../models/', import.meta.url);
142
+ const BUNDLED_MODEL_URL = new URL(`${LOCAL_MINILM_DESCRIPTOR.modelId}/`, BUNDLED_MODELS_URL);
143
+
144
+ let sharedExtractorPromise = null;
145
+ let sharedExtractorLeases = 0;
146
+ let sharedExtractorDisposal = null;
147
+
148
+ export async function verifyBundledModel() {
149
+ const manifestUrl = new URL(LOCAL_MINILM_DESCRIPTOR.manifest, BUNDLED_MODEL_URL);
150
+ let manifestBytes;
151
+ try {
152
+ manifestBytes = await readFile(manifestUrl);
153
+ } catch (error) {
154
+ throw new Error('Bundled embedding model SHA-256 manifest is unavailable', { cause: error });
155
+ }
156
+
157
+ const manifestHash = createHash('sha256').update(manifestBytes).digest('hex');
158
+ if (manifestHash !== LOCAL_MINILM_DESCRIPTOR.manifestSha256) {
159
+ throw new Error(
160
+ `Bundled embedding model SHA-256 manifest hash mismatch: expected ${LOCAL_MINILM_DESCRIPTOR.manifestSha256}, received ${manifestHash}`
161
+ );
162
+ }
163
+
164
+ let manifest;
165
+ try {
166
+ manifest = JSON.parse(manifestBytes.toString('utf8'));
167
+ } catch (error) {
168
+ throw new Error('Bundled embedding model SHA-256 manifest is invalid JSON', { cause: error });
169
+ }
170
+ if (
171
+ manifest.schemaVersion !== 1
172
+ || manifest.algorithm !== 'sha256'
173
+ || manifest.modelId !== LOCAL_MINILM_DESCRIPTOR.modelId
174
+ || manifest.revision !== LOCAL_MINILM_DESCRIPTOR.immutableCommit
175
+ || !Array.isArray(manifest.artifacts)
176
+ || manifest.artifacts.length !== LOCAL_MINILM_DESCRIPTOR.artifacts.length
177
+ ) {
178
+ throw new Error('Bundled embedding model SHA-256 manifest does not match the pinned runtime descriptor');
179
+ }
180
+
181
+ for (let index = 0; index < LOCAL_MINILM_DESCRIPTOR.artifacts.length; index += 1) {
182
+ const artifact = LOCAL_MINILM_DESCRIPTOR.artifacts[index];
183
+ const manifestArtifact = manifest.artifacts[index];
184
+ if (
185
+ manifestArtifact?.path !== artifact.path
186
+ || manifestArtifact?.size !== artifact.size
187
+ || manifestArtifact?.sha256 !== artifact.sha256
188
+ ) {
189
+ throw new Error(`Bundled embedding model SHA-256 manifest entry mismatch for ${artifact.path}`);
190
+ }
191
+
192
+ const artifactUrl = new URL(artifact.path, BUNDLED_MODEL_URL);
193
+ let bytes;
194
+ try {
195
+ bytes = await readFile(artifactUrl);
196
+ } catch (error) {
197
+ throw new Error(`Bundled embedding model artifact is unavailable: ${artifact.path}`, { cause: error });
198
+ }
199
+
200
+ if (bytes.byteLength !== artifact.size) {
201
+ throw new Error(
202
+ `Bundled embedding model artifact size mismatch for ${artifact.path}: expected ${artifact.size}, received ${bytes.byteLength}`
203
+ );
204
+ }
205
+ const actualHash = createHash('sha256').update(bytes).digest('hex');
206
+ if (actualHash !== artifact.sha256) {
207
+ throw new Error(
208
+ `Bundled embedding model artifact hash mismatch for ${artifact.path}: expected ${artifact.sha256}, received ${actualHash}`
209
+ );
210
+ }
211
+ }
212
+ }
213
+
214
+ async function loadSharedExtractor() {
215
+ if (sharedExtractorDisposal) await sharedExtractorDisposal;
216
+ if (!sharedExtractorPromise) {
217
+ sharedExtractorPromise = (async () => {
218
+ await verifyBundledModel();
219
+ const { env, pipeline } = await import('@huggingface/transformers');
220
+ env.localModelPath = fileURLToPath(BUNDLED_MODELS_URL);
221
+ env.allowLocalModels = true;
222
+ env.allowRemoteModels = false;
223
+ env.useFS = true;
224
+ env.useBrowserCache = false;
225
+ env.useFSCache = false;
226
+ env.cacheDir = null;
227
+ env.useCustomCache = false;
228
+ env.customCache = null;
229
+ env.useWasmCache = false;
230
+ const extractor = await pipeline(
231
+ 'feature-extraction',
232
+ LOCAL_MINILM_DESCRIPTOR.modelId,
233
+ {
234
+ revision: LOCAL_MINILM_DESCRIPTOR.immutableCommit,
235
+ local_files_only: true,
236
+ device: LOCAL_MINILM_DESCRIPTOR.device,
237
+ dtype: LOCAL_MINILM_DESCRIPTOR.dtype,
238
+ }
239
+ );
240
+ return extractor;
241
+ })().catch((error) => {
242
+ sharedExtractorPromise = null;
243
+ throw error;
244
+ });
245
+ }
246
+ return await sharedExtractorPromise;
247
+ }
248
+
249
+ async function releaseSharedExtractor() {
250
+ sharedExtractorLeases -= 1;
251
+ if (sharedExtractorLeases !== 0 || !sharedExtractorPromise) return;
252
+
253
+ const extractorPromise = sharedExtractorPromise;
254
+ sharedExtractorPromise = null;
255
+ sharedExtractorDisposal = (async () => {
256
+ const extractor = await extractorPromise;
257
+ await extractor.dispose();
258
+ })().finally(() => {
259
+ sharedExtractorDisposal = null;
260
+ });
261
+ await sharedExtractorDisposal;
262
+ }
263
+
264
+ function coerceAdapterVector(output, dimension) {
265
+ const candidate = Array.isArray(output) && output.length === 1
266
+ && (Array.isArray(output[0]) || ArrayBuffer.isView(output[0]))
267
+ ? output[0]
268
+ : output;
269
+ const vector = candidate instanceof Float32Array
270
+ ? new Float32Array(candidate)
271
+ : Array.isArray(candidate)
272
+ ? new Float32Array(candidate)
273
+ : null;
274
+ if (!vector) {
275
+ throw new TypeError('ONNX runner must return a Float32Array, number array, or one-element batch');
276
+ }
277
+ if (vector.length !== dimension) {
278
+ throw new Error(`ONNX runner returned ${vector.length} values; expected ${dimension}`);
279
+ }
280
+ return vector;
281
+ }
282
+
283
+ function createAdapterProvider(onnxRunner, dimension) {
284
+ const invoke = typeof onnxRunner === 'function'
285
+ ? (text) => onnxRunner(text)
286
+ : onnxRunner && typeof onnxRunner.run === 'function'
287
+ ? async (text) => {
288
+ const result = await onnxRunner.run([text]);
289
+ return result;
290
+ }
291
+ : null;
292
+ if (!invoke) throw new TypeError('onnxRunner must be a function or an object with run(texts)');
293
+
294
+ return {
295
+ providerType: 'onnx_runtime_adapter',
296
+ descriptor: LOCAL_MINILM_DESCRIPTOR,
297
+ dimension,
298
+ async embed(text) {
299
+ return coerceAdapterVector(await invoke(text), dimension);
300
+ },
301
+ async embedBatch(texts) {
302
+ return await Promise.all(texts.map((text) => this.embed(text)));
303
+ },
304
+ embedSync() {
305
+ throw new Error('embedSync() is unsupported by an async ONNX runner; use await embed() instead');
306
+ },
307
+ async dispose() {
308
+ await onnxRunner.dispose?.();
309
+ },
310
+ };
311
+ }
312
+
313
+ function createLocalNeuralProvider(dimension) {
314
+ if (dimension !== EMBEDDING_DIM) {
315
+ throw new Error(`The bundled MiniLM model requires dimension ${EMBEDDING_DIM}, received ${dimension}`);
316
+ }
317
+
318
+ let extractorLeasePromise = null;
319
+ let disposed = false;
320
+ const acquire = async () => {
321
+ if (disposed) throw new Error('Embedding provider has been disposed');
322
+ if (!extractorLeasePromise) {
323
+ extractorLeasePromise = loadSharedExtractor().then((extractor) => {
324
+ sharedExtractorLeases += 1;
325
+ return extractor;
326
+ });
327
+ }
328
+ return await extractorLeasePromise;
329
+ };
330
+
331
+ return {
332
+ providerType: 'local_minilm',
333
+ descriptor: LOCAL_MINILM_DESCRIPTOR,
334
+ dimension,
335
+ async embed(text) {
336
+ if (typeof text !== 'string') throw new TypeError('Embedding text must be a string');
337
+ const extractor = await acquire();
338
+ let output;
339
+ try {
340
+ output = await extractor(text, { pooling: 'mean', normalize: true });
341
+ if (
342
+ !(output.data instanceof Float32Array)
343
+ || output.dims?.length !== 2
344
+ || output.dims[0] !== 1
345
+ || output.dims[1] !== EMBEDDING_DIM
346
+ ) {
347
+ throw new Error(
348
+ `Local MiniLM returned invalid tensor shape or dtype: expected Float32[1,${EMBEDDING_DIM}]`
349
+ );
350
+ }
351
+ return new Float32Array(output.data);
352
+ } finally {
353
+ output?.dispose();
354
+ }
355
+ },
356
+ async embedBatch(texts) {
357
+ const results = [];
358
+ for (const text of texts) results.push(await this.embed(text));
359
+ return results;
360
+ },
361
+ embedSync() {
362
+ throw new Error('embedSync() is unsupported by the local neural provider; use await embed() instead');
363
+ },
364
+ async dispose() {
365
+ if (disposed) return;
366
+ disposed = true;
367
+ if (extractorLeasePromise) {
368
+ await extractorLeasePromise;
369
+ extractorLeasePromise = null;
370
+ await releaseSharedExtractor();
371
+ }
372
+ },
373
+ };
374
+ }
375
+
376
+ /**
377
+ * Creates an embedding provider. Local MiniLM is the fail-closed default; the
378
+ * deterministic lexical provider is available only through modelType: 'lexical'.
379
+ * @param {Object} [options]
380
+ * @param {'neural'|'lexical'|'onnx'} [options.modelType='neural']
381
+ * @param {Function|{run: Function, dispose?: Function}} [options.onnxRunner]
382
+ * @param {number} [options.dimension=384]
383
+ * @returns {Object}
384
+ */
385
+ export function createEmbeddingProvider(options = {}) {
386
+ const dimension = options.dimension || EMBEDDING_DIM;
387
+ if (options.onnxRunner) return createAdapterProvider(options.onnxRunner, dimension);
388
+
389
+ const modelType = options.modelType || 'neural';
390
+ if (modelType === 'lexical') {
391
+ return {
392
+ providerType: 'lexical_hash',
393
+ descriptor: LEXICAL_HASH_DESCRIPTOR,
394
+ dimension,
395
+ async embed(text) {
396
+ return computeLexicalEmbedding(text, dimension);
397
+ },
398
+ async embedBatch(texts) {
399
+ return texts.map((text) => computeLexicalEmbedding(text, dimension));
400
+ },
401
+ embedSync(text) {
402
+ return computeLexicalEmbedding(text, dimension);
403
+ },
404
+ async dispose() {},
405
+ };
406
+ }
407
+ if (modelType === 'onnx') {
408
+ throw new Error('modelType "onnx" requires an explicit onnxRunner');
409
+ }
410
+ if (modelType !== 'neural') throw new Error(`Unsupported embedding modelType: ${modelType}`);
411
+ return createLocalNeuralProvider(dimension);
412
+ }
413
+
414
+ /**
415
+ * Cosine similarity between two float vectors.
416
+ * @param {Float32Array} a
417
+ * @param {Float32Array} b
418
+ * @returns {number}
419
+ */
420
+ export function cosineSimilarity(a, b) {
421
+ if (a.length !== b.length) throw new Error(`Vector length mismatch: ${a.length} !== ${b.length}`);
422
+ let dot = 0;
423
+ for (let i = 0; i < a.length; i++) dot += a[i] * b[i];
424
+ return Math.max(-1.0, Math.min(1.0, dot));
425
+ }
426
+
427
+ /**
428
+ * Quantizes Float32Array to Int8Array [-127, 127] for 75% memory reduction.
429
+ * @param {Float32Array} floatVec
430
+ * @returns {Int8Array}
431
+ */
432
+ export function quantizeVector(floatVec) {
433
+ const int8 = new Int8Array(floatVec.length);
434
+ for (let i = 0; i < floatVec.length; i++) {
435
+ int8[i] = Math.round(Math.max(-1.0, Math.min(1.0, floatVec[i])) * 127);
436
+ }
437
+ return int8;
438
+ }
439
+
440
+ /**
441
+ * Dequantizes Int8Array back to L2-normalized Float32Array.
442
+ * @param {Int8Array} int8Vec
443
+ * @returns {Float32Array}
444
+ */
445
+ export function dequantizeVector(int8Vec) {
446
+ const floatVec = new Float32Array(int8Vec.length);
447
+ let sumSq = 0;
448
+ for (let i = 0; i < int8Vec.length; i++) {
449
+ const v = int8Vec[i] / 127.0;
450
+ floatVec[i] = v;
451
+ sumSq += v * v;
452
+ }
453
+ const norm = Math.sqrt(sumSq);
454
+ if (norm > 1e-12) {
455
+ const inv = 1.0 / norm;
456
+ for (let i = 0; i < floatVec.length; i++) floatVec[i] *= inv;
457
+ }
458
+ return floatVec;
459
+ }
@@ -0,0 +1,76 @@
1
+ // Enigma Hybrid RAG: Reciprocal Rank Fusion (RRF).
2
+ // Blends dense vector semantic retrieval with BM25 exact lexical term matching.
3
+
4
+ /**
5
+ * Combines dense vector search results and BM25 lexical results using Reciprocal Rank Fusion.
6
+ * @param {Array<{ id: string, text: string, score: number, scope: string, metadata?: Object }>} denseResults
7
+ * @param {Array<{ id: string, text: string, score: number, scope: string }>} bm25Results
8
+ * @param {Object} [options]
9
+ * @param {number} [options.k=60] - RRF smoothing parameter
10
+ * @param {number} [options.denseWeight=1.0] - Weight multiplier for dense semantic search
11
+ * @param {number} [options.bm25Weight=1.0] - Weight multiplier for BM25 keyword search
12
+ * @param {number} [options.topK=10]
13
+ * @returns {Array<{ id: string, text: string, score: number, denseScore: number, bm25Score: number, scope: string, metadata?: Object }>}
14
+ */
15
+ export function reciprocalRankFusion(denseResults = [], bm25Results = [], options = {}) {
16
+ const k = options.k || 60;
17
+ const denseWeight = typeof options.denseWeight === 'number' ? options.denseWeight : 1.0;
18
+ const bm25Weight = typeof options.bm25Weight === 'number' ? options.bm25Weight : 1.0;
19
+ const topK = options.topK || 10;
20
+
21
+ const fusedMap = new Map();
22
+
23
+ // 1. Process Dense Vector Ranks
24
+ for (let rank = 0; rank < denseResults.length; rank++) {
25
+ const item = denseResults[rank];
26
+ const rrfScore = denseWeight / (k + rank + 1);
27
+
28
+ fusedMap.set(item.id, {
29
+ id: item.id,
30
+ text: item.text,
31
+ scope: item.scope,
32
+ metadata: item.metadata,
33
+ denseScore: item.score,
34
+ bm25Score: 0,
35
+ rrfScore,
36
+ });
37
+ }
38
+
39
+ // 2. Process BM25 Ranks
40
+ for (let rank = 0; rank < bm25Results.length; rank++) {
41
+ const item = bm25Results[rank];
42
+ const rrfScore = bm25Weight / (k + rank + 1);
43
+
44
+ if (fusedMap.has(item.id)) {
45
+ const entry = fusedMap.get(item.id);
46
+ entry.bm25Score = item.score;
47
+ entry.rrfScore += rrfScore;
48
+ } else {
49
+ fusedMap.set(item.id, {
50
+ id: item.id,
51
+ text: item.text,
52
+ scope: item.scope,
53
+ metadata: item.metadata,
54
+ denseScore: 0,
55
+ bm25Score: item.score,
56
+ rrfScore,
57
+ });
58
+ }
59
+ }
60
+
61
+ const fusedList = Array.from(fusedMap.values());
62
+ fusedList.sort((a, b) => b.rrfScore - a.rrfScore);
63
+
64
+ // Normalize final score relative to top match
65
+ const maxRrf = fusedList.length > 0 && fusedList[0].rrfScore > 0 ? fusedList[0].rrfScore : 1.0;
66
+
67
+ return fusedList.slice(0, topK).map((item) => ({
68
+ id: item.id,
69
+ text: item.text,
70
+ score: Math.round((item.rrfScore / maxRrf) * 1000) / 1000,
71
+ denseScore: Math.round(item.denseScore * 1000) / 1000,
72
+ bm25Score: Math.round(item.bm25Score * 1000) / 1000,
73
+ scope: item.scope,
74
+ metadata: item.metadata,
75
+ }));
76
+ }
@@ -0,0 +1,38 @@
1
+ // Enigma Semantic Vector Search & Hybrid RAG Engine.
2
+ export {
3
+ LEXICAL_HASH_DESCRIPTOR,
4
+ LOCAL_MINILM_DESCRIPTOR,
5
+ ONNX_INTEGRATION_SPEC,
6
+ EMBEDDING_DIM,
7
+ tokenizeSubwords,
8
+ computeLexicalEmbedding,
9
+ createEmbeddingProvider,
10
+ verifyBundledModel,
11
+ cosineSimilarity,
12
+ quantizeVector,
13
+ dequantizeVector,
14
+ } from './embeddings.js';
15
+
16
+ export {
17
+ BM25Index,
18
+ } from './bm25.js';
19
+
20
+ export {
21
+ reciprocalRankFusion,
22
+ } from './hybrid.js';
23
+
24
+ export {
25
+ semanticReranker,
26
+ } from './reranker.js';
27
+
28
+ export {
29
+ EncryptedVectorStore,
30
+ } from './vector-store.js';
31
+
32
+ export {
33
+ RESEARCH_DISCLAIMER,
34
+ generateResearchOrthogonalBasis,
35
+ applyResearchBasisTransform,
36
+ createResearchBlindedQuery,
37
+ evaluateResearchBlindedRanking,
38
+ } from './research.js';
@@ -0,0 +1,61 @@
1
+ // Enigma Hybrid RAG: Semantic Candidate Reranker.
2
+ // Calibrates retrieval scores by evaluating exact phrase matches,
3
+ // token coverage density, and metadata importance boosts.
4
+
5
+ /**
6
+ * Reranks candidate memories against the query for precision.
7
+ * @param {string} queryText
8
+ * @param {Array<{ id: string, text: string, score: number, scope: string, metadata?: Object }>} candidates
9
+ * @param {Object} [options]
10
+ * @param {number} [options.topK=5]
11
+ * @param {number} [options.phraseBonus=0.3]
12
+ * @param {number} [options.coverageWeight=0.25]
13
+ * @returns {Array<{ id: string, text: string, score: number, originalScore: number, scope: string, metadata?: Object }>}
14
+ */
15
+ export function semanticReranker(queryText, candidates = [], options = {}) {
16
+ if (!queryText || typeof queryText !== 'string' || candidates.length === 0) {
17
+ return candidates.slice(0, options.topK || 5);
18
+ }
19
+
20
+ const topK = options.topK || 5;
21
+ const phraseBonus = typeof options.phraseBonus === 'number' ? options.phraseBonus : 0.3;
22
+ const coverageWeight = typeof options.coverageWeight === 'number' ? options.coverageWeight : 0.25;
23
+
24
+ const cleanQuery = queryText.toLowerCase().trim();
25
+ const queryTerms = cleanQuery.split(/[^a-zA-Z0-9_\-]/).filter(t => t.length >= 2);
26
+ const queryTermSet = new Set(queryTerms);
27
+
28
+ const reranked = candidates.map((cand) => {
29
+ const textLower = cand.text.toLowerCase();
30
+ let score = cand.score;
31
+
32
+ // 1. Exact phrase match boost
33
+ if (cleanQuery.length > 3 && textLower.includes(cleanQuery)) {
34
+ score += phraseBonus;
35
+ }
36
+
37
+ // 2. Token coverage calculation
38
+ if (queryTermSet.size > 0) {
39
+ const docTerms = new Set(textLower.split(/[^a-zA-Z0-9_\-]/).filter(t => t.length >= 2));
40
+ let matches = 0;
41
+ for (const t of queryTermSet) {
42
+ if (docTerms.has(t)) matches++;
43
+ }
44
+ const coverage = matches / queryTermSet.size;
45
+ score += coverage * coverageWeight;
46
+ }
47
+
48
+ // 3. Metadata importance multiplier
49
+ const importance = cand.metadata?.importance || cand.importance || 1.0;
50
+ score = score * Math.min(2.0, Math.max(0.5, importance));
51
+
52
+ return {
53
+ ...cand,
54
+ originalScore: cand.score,
55
+ score: Math.round(score * 1000) / 1000,
56
+ };
57
+ });
58
+
59
+ reranked.sort((a, b) => b.score - a.score);
60
+ return reranked.slice(0, topK);
61
+ }