enigma-memory 0.1.18 → 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.
- package/README.md +76 -24
- package/apps/cli/bin/enigma-desktop.mjs +140 -0
- package/apps/cli/bin/enigma-terminal.mjs +78 -0
- package/apps/cli/bin/enigma.mjs +1923 -285
- package/apps/desktop/electron-main.cjs +217 -0
- package/apps/desktop/package.json +12 -0
- package/apps/desktop/src/app.js +264 -7
- package/apps/desktop/src/index.html +3514 -1373
- package/apps/desktop/src/launch-electron.mjs +51 -0
- package/apps/desktop/src/server.mjs +2914 -0
- package/apps/desktop/src/styles.css +2972 -260
- package/apps/desktop/src/zk-browser-prove.mjs +53 -0
- package/apps/desktop/src/zk-state.mjs +1789 -0
- package/apps/gateway/bin/enigma-gateway.mjs +102 -5
- package/apps/gateway/src/server.mjs +271 -8
- package/apps/ios/EnigmaCore/Package.swift +12 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
- package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
- package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
- package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
- package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
- package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
- package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
- package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
- package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
- package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
- package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
- package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
- package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
- package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
- package/apps/native-host/README.md +19 -8
- package/apps/native-host/bin/enigma-native-host.mjs +229 -13
- package/apps/relay/bin/enigma-relay.mjs +103 -5
- package/apps/relay/src/federation-runtime.mjs +618 -0
- package/apps/relay/src/server.mjs +310 -9
- package/apps/verifier/bin/enigma-verify.mjs +327 -11
- package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/vk_bytes.json +32 -0
- package/cortex-v3/proving-assets.json +64 -0
- package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
- package/cortex-v3/zk/action-transition-vk.json +119 -0
- package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
- package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
- package/cortex-v3/zk/intent-witness.mjs +365 -0
- package/cortex-v3/zk/intent-witness.test.mjs +485 -0
- package/cortex-v3/zk/proving-assets.mjs +203 -0
- package/cortex-v3/zk/sale-witness.mjs +783 -0
- package/cortex-v3/zk/sale-witness.test.mjs +784 -0
- package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
- package/cortex-v3/zk/settlement-evidence.mjs +722 -0
- package/cortex-v3/zk/setup-intent.mjs +688 -0
- package/cortex-v3/zk/setup-sale.mjs +666 -0
- package/cortex-v3/zk/setup.mjs +594 -0
- package/cortex-v3/zk/witness.mjs +184 -0
- package/cortex-v3/zk/zk-codec.mjs +232 -0
- package/cortex-v3/zk/zk-codec.test.mjs +293 -0
- package/cortex-v3/zk/zk-settle.mjs +370 -0
- package/cortex-v3/zk/zk-tree.mjs +256 -0
- package/cortex-v3/zk/zk-tree.test.mjs +419 -0
- package/deploy/docker-compose.local-production-simulation.yml +36 -0
- package/docs/browser-extension-install.md +8 -6
- package/docs/client-connectors.md +15 -11
- package/docs/developer-ecosystem.md +15 -13
- package/docs/enigma-memory-ready-conformance.md +11 -9
- package/docs/install-anywhere.md +61 -28
- package/docs/installers-and-desktop.md +8 -7
- package/docs/novelty-invention-candidates.md +161 -161
- package/docs/proof-network-claim-boundaries.md +320 -318
- package/examples/01-quickstart-agent/index.mjs +49 -0
- package/examples/01_agent_memory_quickstart.mjs +57 -0
- package/examples/02-multi-agent-swarm/index.mjs +57 -0
- package/examples/02_cross_model_passport.mjs +64 -0
- package/examples/03-langchain-memory/index.mjs +41 -0
- package/examples/03_poseidon_commitment_verification.mjs +71 -0
- package/examples/04-python-trading-agent/trader.py +49 -0
- package/examples/README.md +27 -0
- package/examples/ci/github-actions.yml +7 -2
- package/package.json +142 -11
- package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
- package/packages/connectors/src/index.js +196 -4
- package/packages/connectors/swarm-router.mjs +168 -0
- package/packages/core/src/index.js +248 -1
- package/packages/core/src/version.mjs +7 -0
- package/packages/dev-tools/package.json +19 -0
- package/packages/dev-tools/src/index.js +4 -0
- package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
- package/packages/dev-tools/src/swarm-simulator.js +101 -0
- package/packages/dev-tools/src/vault-inspector.js +114 -0
- package/packages/dev-tools/src/vector-benchmark.js +100 -0
- package/packages/developer-platform/src/access-credentials.js +341 -0
- package/packages/developer-platform/src/http.js +132 -0
- package/packages/developer-platform/src/index.js +4 -0
- package/packages/developer-platform/src/usage-http.js +60 -0
- package/packages/developer-platform/src/usage.js +295 -0
- package/packages/enclave-runtime/attestation.mjs +159 -0
- package/packages/enclave-runtime/index.mjs +47 -0
- package/packages/enclave-runtime/session-manager.mjs +253 -0
- package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
- package/packages/enigma-reflex/package.json +14 -0
- package/packages/enigma-reflex/src/index.js +204 -0
- package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
- package/packages/enigma-reflex/training/requirements.txt +8 -0
- package/packages/enigma-reflex/training/train.py +314 -0
- package/packages/enigma-weave/LICENSE +22 -0
- package/packages/enigma-weave/UPSTREAM.json +21 -0
- package/packages/enigma-weave/package.json +14 -0
- package/packages/enigma-weave/src/index.js +286 -0
- package/packages/hosted-cloud/src/index.js +80 -5
- package/packages/importers/src/index.js +432 -0
- package/packages/inference-runtime/src/browser.js +401 -0
- package/packages/inference-runtime/src/chat.js +265 -0
- package/packages/inference-runtime/src/code.js +407 -0
- package/packages/inference-runtime/src/contracts.js +162 -0
- package/packages/inference-runtime/src/http.js +232 -0
- package/packages/inference-runtime/src/image.js +186 -0
- package/packages/inference-runtime/src/index.js +10 -0
- package/packages/inference-runtime/src/model-router.js +320 -0
- package/packages/inference-runtime/src/platform.js +125 -0
- package/packages/inference-runtime/src/privacy.js +400 -0
- package/packages/inference-runtime/src/video.js +253 -0
- package/packages/mcp-server/README.md +22 -6
- package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
- package/packages/mcp-server/src/index.js +1418 -105
- package/packages/mcp-server/src/oauth.js +561 -0
- package/packages/mcp-server/src/private-handoff.js +84 -0
- package/packages/mcp-server/src/remote-http.js +273 -0
- package/packages/mcp-server/src/remote-policy.js +72 -0
- package/packages/mcp-server/swarm-bridge.mjs +361 -0
- package/packages/mesh/index.d.ts +283 -0
- package/packages/mesh/package.json +23 -0
- package/packages/mesh/src/crypto.js +189 -0
- package/packages/mesh/src/federation-packets.js +353 -0
- package/packages/mesh/src/gossip.js +311 -0
- package/packages/mesh/src/index.js +6 -0
- package/packages/mesh/src/protocol.js +255 -0
- package/packages/mesh/src/router.js +279 -0
- package/packages/mesh/src/transport.js +306 -0
- package/packages/passport/src/index.js +426 -1
- package/packages/private-economy/src/credits-http.js +100 -0
- package/packages/private-economy/src/credits.js +447 -0
- package/packages/private-economy/src/index.js +5 -0
- package/packages/private-economy/src/payments-http.js +120 -0
- package/packages/private-economy/src/payments.js +509 -0
- package/packages/private-economy/src/x402.js +346 -0
- package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
- package/packages/rag/index.d.ts +182 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
- package/packages/rag/package.json +27 -0
- package/packages/rag/src/blinded-search.js +109 -0
- package/packages/rag/src/bm25.js +169 -0
- package/packages/rag/src/embeddings.js +459 -0
- package/packages/rag/src/hybrid.js +76 -0
- package/packages/rag/src/index.js +38 -0
- package/packages/rag/src/reranker.js +61 -0
- package/packages/rag/src/research.js +107 -0
- package/packages/rag/src/vector-store.js +430 -0
- package/packages/rag/src/verify-model-artifacts.mjs +4 -0
- package/packages/sdk/index.d.ts +760 -0
- package/packages/sdk/package.json +33 -0
- package/packages/sdk/python/README.md +24 -0
- package/packages/sdk/python/enigma_sdk.py +250 -0
- package/packages/sdk/python/pyproject.toml +34 -0
- package/packages/sdk/python/requirements.txt +1 -0
- package/packages/sdk/python/setup.py +20 -0
- package/packages/sdk/src/federation/capability-grant.js +389 -0
- package/packages/sdk/src/federation/federation-router.js +360 -0
- package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
- package/packages/sdk/src/federation/index.js +3 -0
- package/packages/sdk/src/index.js +1796 -0
- package/packages/sdk/src/intelligence/contradiction.js +337 -0
- package/packages/sdk/src/intelligence/decision-engine.js +155 -0
- package/packages/sdk/src/intelligence/index.js +4 -0
- package/packages/sdk/src/intelligence/ontology.js +122 -0
- package/packages/sdk/src/intelligence/temporal.js +123 -0
- package/packages/sdk/src/market-client.js +142 -0
- package/packages/sdk/src/mesh-client.js +110 -0
- package/packages/sdk/src/middleware/index.js +3 -0
- package/packages/sdk/src/middleware/langchain.js +159 -0
- package/packages/sdk/src/middleware/llamaindex.js +101 -0
- package/packages/sdk/src/middleware/vercel-ai.js +112 -0
- package/packages/sdk/src/rag-client.js +85 -0
- package/packages/sdk/src/swarm-orchestrator.js +260 -0
- package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
- package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
- package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
- package/packages/snapcompact/index.d.ts +284 -0
- package/packages/snapcompact/package.json +25 -0
- package/packages/snapcompact/src/index.js +716 -0
- package/packages/storage/PACKAGE_CONTRACT.md +1 -1
- package/packages/terminal-console/animations.mjs +240 -0
- package/packages/terminal-console/auto-anchor.mjs +220 -0
- package/packages/terminal-console/banner.mjs +91 -0
- package/packages/terminal-console/commands.mjs +459 -0
- package/packages/terminal-console/delegation.mjs +152 -0
- package/packages/terminal-console/index.mjs +5 -0
- package/packages/terminal-console/outbox.mjs +143 -0
- package/packages/terminal-console/phantom-bridge.mjs +637 -0
- package/packages/terminal-console/repl.mjs +136 -0
- package/packages/terminal-console/signer-store.mjs +130 -0
- package/packages/terminal-console/solana-rpc.mjs +214 -0
- package/packages/terminal-console/solana-transport.mjs +189 -0
- package/packages/terminal-tui/dashboard.mjs +214 -0
- package/packages/terminal-tui/index.mjs +28 -0
- package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
- package/packages/terminal-tui/telemetry-hud.mjs +137 -0
- package/packages/vault/index.d.ts +449 -0
- package/packages/vault/package.json +27 -0
- package/packages/vault/src/e2ee.mjs +393 -0
- package/packages/vault/src/enclave.js +481 -0
- package/packages/vault/src/erasure.js +207 -0
- package/packages/vault/src/index.js +1018 -155
- package/packages/vault/src/persistence.js +307 -0
- package/packages/vault/src/poseidon.js +354 -0
- package/packages/vault/src/receipt.js +459 -0
- package/scripts/benchmark-optical-context.mjs +166 -0
- package/scripts/bootstrap-enigma.mjs +502 -0
- package/scripts/build-edge-backend-workers.mjs +20 -5
- package/scripts/build-goal-completion-audit.mjs +72 -25
- package/scripts/build-hosted-api-key-lifecycle.mjs +26 -8
- package/scripts/build-hosted-customer-lifecycle.mjs +20 -3
- package/scripts/build-hosted-probe-worker.mjs +19 -4
- package/scripts/build-installer-assets.mjs +41 -21
- package/scripts/build-operator-evidence-starter.mjs +59 -1
- package/scripts/build-production-backend-env-kit.mjs +2 -0
- package/scripts/build-production-unblocker.mjs +3 -0
- package/scripts/check.mjs +17 -3
- package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
- package/scripts/install-enigma-local.mjs +18 -5
- package/scripts/release-audit.mjs +65 -109
- package/scripts/release-provenance.mjs +6 -0
- package/scripts/run-backend-readiness-smoke.mjs +112 -10
- package/scripts/scan-secrets.mjs +1 -0
- package/scripts/simulate-production-env.mjs +7 -2
- package/scripts/validate-hosted-backend-live.mjs +112 -1
- package/specs/antibody-pack-v1.schema.json +95 -0
- package/specs/antigen-envelope-v1.schema.json +81 -0
- package/specs/boundary-manifest-v1.schema.json +35 -35
- package/specs/capsule-v1.schema.json +55 -55
- package/specs/claim-boundary-manifest-v1.schema.json +22 -22
- package/specs/claim-ledger-v1.schema.json +291 -0
- package/specs/context-passport-v1.schema.json +59 -0
- package/specs/deletion-tombstone-v1.schema.json +26 -26
- package/specs/evidence-packet-v1.schema.json +177 -0
- package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
- package/specs/immune-scan-report-v1.schema.json +112 -0
- package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
- package/specs/memory-atom-v1.schema.json +59 -0
- package/specs/memory-event-v1.schema.json +42 -42
- package/specs/passport-v1.schema.json +50 -50
- package/specs/proof-of-non-use-v1.schema.json +65 -0
- package/specs/quarantine-record-v1.schema.json +126 -0
- package/specs/receipt-v1.schema.json +61 -61
- package/specs/state-checkpoint-v1.schema.json +37 -37
- package/specs/trust-bundle-v1.schema.json +56 -56
- package/specs/trust-card-v1.schema.json +119 -0
- package/docs/proof-network-launch-plan.md +0 -421
- package/packages/metering/PACKAGE_CONTRACT.md +0 -20
- package/scripts/build-ai-orchestration-plan.mjs +0 -248
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Enigma Memory Intelligence: Temporal Validity & Observation Windows.
|
|
2
|
+
// Handles time-bounded validity, observation provenance, and exponential decay models.
|
|
3
|
+
import { MEMORY_TYPES } from './ontology.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Constructs normalized temporal metadata for a memory atom.
|
|
7
|
+
* @param {Object} [options]
|
|
8
|
+
* @param {number|string|Date} [options.validFrom] - Start of validity window (defaults to now)
|
|
9
|
+
* @param {number|string|Date|null} [options.validUntil] - End of validity (null = indefinitely valid)
|
|
10
|
+
* @param {number|string|Date} [options.observedAt] - Time observation was recorded
|
|
11
|
+
* @param {number} [options.ttlMs] - Time-to-live in milliseconds
|
|
12
|
+
* @returns {{ validFrom: number, validUntil: number|null, observedAt: number, isPermanent: boolean }}
|
|
13
|
+
*/
|
|
14
|
+
export function createTemporalMetadata(options = {}) {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const observedAt = parseRequiredTimestamp(options.observedAt, now, 'observedAt');
|
|
17
|
+
const validFrom = parseRequiredTimestamp(options.validFrom, observedAt, 'validFrom');
|
|
18
|
+
|
|
19
|
+
let validUntil = null;
|
|
20
|
+
if (options.validUntil !== undefined && options.validUntil !== null) {
|
|
21
|
+
validUntil = parseRequiredTimestamp(options.validUntil, null, 'validUntil');
|
|
22
|
+
} else if (options.ttlMs !== undefined) {
|
|
23
|
+
if (typeof options.ttlMs !== 'number' || !Number.isFinite(options.ttlMs) || options.ttlMs < 0) {
|
|
24
|
+
throw new TypeError('ttlMs must be a finite non-negative number');
|
|
25
|
+
}
|
|
26
|
+
validUntil = validFrom + options.ttlMs;
|
|
27
|
+
}
|
|
28
|
+
if (validUntil !== null && validUntil < validFrom) {
|
|
29
|
+
throw new RangeError('validUntil must be greater than or equal to validFrom');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
validFrom,
|
|
34
|
+
validUntil,
|
|
35
|
+
observedAt,
|
|
36
|
+
isPermanent: validUntil === null,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseRequiredTimestamp(value, fallback, fieldName) {
|
|
41
|
+
if (value === null || value === undefined) {
|
|
42
|
+
if (fallback === null) throw new TypeError(`${fieldName} must be a valid timestamp`);
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
const parsed = parseTimestamp(value, null);
|
|
46
|
+
if (parsed === null) throw new TypeError(`${fieldName} must be a valid timestamp`);
|
|
47
|
+
return parsed;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Safely parses timestamps from number, string, or Date.
|
|
52
|
+
* @param {number|string|Date|undefined|null} val
|
|
53
|
+
* @param {number|null} fallback
|
|
54
|
+
* @returns {number|null}
|
|
55
|
+
*/
|
|
56
|
+
export function parseTimestamp(val, fallback = Date.now()) {
|
|
57
|
+
if (val === null || val === undefined) return fallback;
|
|
58
|
+
if (typeof val === 'number') return Number.isFinite(val) ? val : fallback;
|
|
59
|
+
if (val instanceof Date) {
|
|
60
|
+
const parsed = val.getTime();
|
|
61
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
62
|
+
}
|
|
63
|
+
if (typeof val === 'string' && val.trim().length > 0) {
|
|
64
|
+
const parsed = Date.parse(val);
|
|
65
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
66
|
+
}
|
|
67
|
+
return fallback;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Checks whether a memory atom is currently active and valid at a target query timestamp.
|
|
72
|
+
* @param {Object} atom - Memory atom with metadata or temporal fields
|
|
73
|
+
* @param {number|string|Date} [queryTime=Date.now()]
|
|
74
|
+
* @returns {boolean}
|
|
75
|
+
*/
|
|
76
|
+
export function isTemporallyActive(atom, queryTime = Date.now()) {
|
|
77
|
+
if (!atom) return false;
|
|
78
|
+
const targetTime = parseTimestamp(queryTime, null);
|
|
79
|
+
if (targetTime === null) return false;
|
|
80
|
+
const meta = atom.temporal || atom.metadata?.temporal || atom.metadata || {};
|
|
81
|
+
|
|
82
|
+
const validFromSource = meta.validFrom ?? atom.createdAt ?? 0;
|
|
83
|
+
const validFrom = parseTimestamp(validFromSource, null);
|
|
84
|
+
const validUntil = meta.validUntil !== undefined && meta.validUntil !== null
|
|
85
|
+
? parseTimestamp(meta.validUntil, null)
|
|
86
|
+
: null;
|
|
87
|
+
if (validFrom === null) return false;
|
|
88
|
+
if (meta.validUntil !== undefined && meta.validUntil !== null && validUntil === null) return false;
|
|
89
|
+
if (validUntil !== null && validUntil < validFrom) return false;
|
|
90
|
+
if (targetTime < validFrom) return false;
|
|
91
|
+
if (validUntil !== null && targetTime > validUntil) return false;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Computes exponential recency/decay score multiplier (0.0 to 1.0) based on age and memory type.
|
|
97
|
+
* Policy and identity memories do not decay (multiplier = 1.0).
|
|
98
|
+
* Episodic memories decay over a half-life of 30 days.
|
|
99
|
+
* @param {Object} atom
|
|
100
|
+
* @param {number} [queryTime=Date.now()]
|
|
101
|
+
* @param {number} [halfLifeDays=30]
|
|
102
|
+
* @returns {number} Multiplier between 0.1 and 1.0
|
|
103
|
+
*/
|
|
104
|
+
export function computeTemporalDecay(atom, queryTime = Date.now(), halfLifeDays = 30) {
|
|
105
|
+
const type = atom.type || atom.metadata?.type || MEMORY_TYPES.SEMANTIC;
|
|
106
|
+
if (type === MEMORY_TYPES.POLICY || type === MEMORY_TYPES.IDENTITY) {
|
|
107
|
+
return 1.0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const targetTime = parseTimestamp(queryTime, Date.now());
|
|
111
|
+
const observedAt = parseTimestamp(
|
|
112
|
+
atom.observedAt ?? atom.temporal?.observedAt ?? atom.createdAt,
|
|
113
|
+
targetTime
|
|
114
|
+
);
|
|
115
|
+
const ageMs = Math.max(0, targetTime - observedAt);
|
|
116
|
+
const ageDays = ageMs / (1000 * 60 * 60 * 24);
|
|
117
|
+
|
|
118
|
+
const effectiveHalfLife = type === MEMORY_TYPES.EPISODIC ? halfLifeDays : halfLifeDays * 3;
|
|
119
|
+
const decayFactor = Math.pow(0.5, ageDays / effectiveHalfLife);
|
|
120
|
+
|
|
121
|
+
// Floor at 0.2 so historic memories remain recallable
|
|
122
|
+
return Math.max(0.2, Math.min(1.0, decayFactor));
|
|
123
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Enigma SDK: ZKCP Sealed Sale Marketplace Client.
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
|
|
4
|
+
export class EnigmaMarketClient {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Object} [options]
|
|
7
|
+
* @param {string} [options.apiBase] - Local daemon or proxy endpoint
|
|
8
|
+
* @param {string} [options.authToken] - Local IPC auth token
|
|
9
|
+
*/
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.apiBase = options.apiBase || 'http://127.0.0.1:8787';
|
|
12
|
+
this.authToken = options.authToken || null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal authenticated API helper.
|
|
17
|
+
*/
|
|
18
|
+
async _request(path, method = 'GET', body = null) {
|
|
19
|
+
const headers = { 'Accept': 'application/json' };
|
|
20
|
+
if (this.authToken) headers['X-Enigma-Auth-Token'] = this.authToken;
|
|
21
|
+
if (body) headers['Content-Type'] = 'application/json';
|
|
22
|
+
|
|
23
|
+
const res = await fetch(`${this.apiBase}${path}`, {
|
|
24
|
+
method,
|
|
25
|
+
headers,
|
|
26
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
27
|
+
});
|
|
28
|
+
const data = await res.json().catch(() => null);
|
|
29
|
+
if (!res.ok || (data && data.ok === false)) {
|
|
30
|
+
throw new Error(data?.error || `HTTP ${res.status}`);
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Retrieves marketplace circuit parameters and local state status.
|
|
37
|
+
*/
|
|
38
|
+
async getStatus() {
|
|
39
|
+
return await this._request('/api/zk/status');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves or derives the buyer's local BabyJubJub identity and escrow address.
|
|
44
|
+
*/
|
|
45
|
+
async getBuyerIdentity() {
|
|
46
|
+
return await this._request('/api/zk/sale/buyer-identity');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Prepares and proves a sealed sale listing for a confidential memory atom.
|
|
51
|
+
* @param {Object} params
|
|
52
|
+
* @param {number} params.noteIndex - Index of the appended note in the sovereign note tree
|
|
53
|
+
* @param {string|number} params.priceLamports - Price in lamports
|
|
54
|
+
* @param {number} [params.expirySlots=4000] - Expiry slots
|
|
55
|
+
* @param {string} params.buyerPubkeyX - Buyer's BabyJub public key X coordinate
|
|
56
|
+
* @param {string} params.buyerPubkeyY - Buyer's BabyJub public key Y coordinate
|
|
57
|
+
*/
|
|
58
|
+
async prepareListing(params) {
|
|
59
|
+
return await this._request('/api/zk/sale/prepare-listing', 'POST', params);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Submits a prepared Groth16 listing proof to the settlement program.
|
|
63
|
+
* Only the public proof, public inputs, and optional predecessor receipt refs
|
|
64
|
+
* traverse the submission endpoint.
|
|
65
|
+
* @param {Object} prepared
|
|
66
|
+
* @param {Object} prepared.proofBytes
|
|
67
|
+
* @param {string[]} prepared.publicInputs
|
|
68
|
+
* @param {string[]} [prepared.predecessorReceiptRefs]
|
|
69
|
+
*/
|
|
70
|
+
async submitListing(prepared) {
|
|
71
|
+
if (!prepared || typeof prepared !== 'object' || Array.isArray(prepared)) {
|
|
72
|
+
throw new TypeError('prepared listing must be an object');
|
|
73
|
+
}
|
|
74
|
+
return await this._request('/api/zk/sale/submit-listing', 'POST', {
|
|
75
|
+
proofBytes: prepared.proofBytes,
|
|
76
|
+
publicInputs: prepared.publicInputs,
|
|
77
|
+
predecessorReceiptRefs: prepared.predecessorReceiptRefs || [],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Runs the complete seller listing sequence against the real desktop routes:
|
|
83
|
+
* prepare/prove locally, then submit the resulting public proof on-chain.
|
|
84
|
+
* @param {Object} params
|
|
85
|
+
* @param {string[]} [params.predecessorReceiptRefs]
|
|
86
|
+
*/
|
|
87
|
+
async createListing(params) {
|
|
88
|
+
if (!params || typeof params !== 'object' || Array.isArray(params)) {
|
|
89
|
+
throw new TypeError('listing params must be an object');
|
|
90
|
+
}
|
|
91
|
+
const { predecessorReceiptRefs = [], ...prepareParams } = params;
|
|
92
|
+
const prepared = await this.prepareListing(prepareParams);
|
|
93
|
+
const submitted = await this.submitListing({
|
|
94
|
+
proofBytes: prepared.proofBytes,
|
|
95
|
+
publicInputs: prepared.publicInputs,
|
|
96
|
+
predecessorReceiptRefs,
|
|
97
|
+
});
|
|
98
|
+
return {
|
|
99
|
+
ok: true,
|
|
100
|
+
listing: {
|
|
101
|
+
...prepared,
|
|
102
|
+
receiptPda: submitted.receiptPda,
|
|
103
|
+
receiptRef: submitted.receiptRef,
|
|
104
|
+
settlementReceipt: submitted.settlementReceipt,
|
|
105
|
+
},
|
|
106
|
+
submission: submitted,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Performs offline and on-chain verification of a seller's sealed listing.
|
|
112
|
+
* Verifies Poseidon-CTR cipher fold and BabyJub recipient binding before paying.
|
|
113
|
+
* @param {Object} listing
|
|
114
|
+
*/
|
|
115
|
+
async verifyListing(listing) {
|
|
116
|
+
return await this._request('/api/zk/sale/verify', 'POST', listing);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Funds an on-chain escrow account on Solana locked to a verified receipt PDA.
|
|
121
|
+
* @param {Object} listing
|
|
122
|
+
*/
|
|
123
|
+
async fundEscrow(listing) {
|
|
124
|
+
return await this._request('/api/zk/sale/escrow', 'POST', listing);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Seller: Atomically claims a funded escrow, revealing the encrypted key envelope on-chain.
|
|
129
|
+
* @param {Object} params
|
|
130
|
+
*/
|
|
131
|
+
async claim(params) {
|
|
132
|
+
return await this._request('/api/zk/sale/claim', 'POST', params);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Buyer: Reads the revealed envelope on-chain and decrypts the off-chain ciphertext chunks.
|
|
137
|
+
* @param {Object} params
|
|
138
|
+
*/
|
|
139
|
+
async open(params) {
|
|
140
|
+
return await this._request('/api/zk/sale/open', 'POST', params);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Enigma SDK: GhostMesh P2P Swarm Client.
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { MeshGossipNode, generateMeshIdentity, sealPayload, unsealPayload } from '../../mesh/src/index.js';
|
|
4
|
+
|
|
5
|
+
export class EnigmaMeshClient extends EventEmitter {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Object} [options]
|
|
8
|
+
* @param {Object} [options.identity] - Pre-generated mesh identity or auto-generated
|
|
9
|
+
* @param {string} [options.nodeId] - Human-readable agent node ID
|
|
10
|
+
* @param {string} [options.scope='enigma.agents']
|
|
11
|
+
*/
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
super();
|
|
14
|
+
this.scope = options.scope || 'enigma.agents';
|
|
15
|
+
this.identity = options.identity || generateMeshIdentity(this.scope);
|
|
16
|
+
this.nodeId = options.nodeId || `agent_${this.identity.destinationHex.slice(0, 8)}`;
|
|
17
|
+
|
|
18
|
+
this.node = new MeshGossipNode({
|
|
19
|
+
identity: this.identity,
|
|
20
|
+
nodeId: this.nodeId,
|
|
21
|
+
scope: this.scope,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Forward internal events
|
|
25
|
+
this.node.on('capsule', (capsule) => this.emit('capsule', capsule));
|
|
26
|
+
this.node.on('sale:offer', (offer) => this.emit('sale:offer', offer));
|
|
27
|
+
this.node.on('zk:proof', (proof) => this.emit('zk:proof', proof));
|
|
28
|
+
this.node.on('peer:discovered', (peer) => this.emit('peer:discovered', peer));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Starts the mesh node and begins background route discovery.
|
|
33
|
+
*/
|
|
34
|
+
async start() {
|
|
35
|
+
await this.node.start();
|
|
36
|
+
return this.status();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Stops the mesh node and tears down active transports.
|
|
41
|
+
*/
|
|
42
|
+
async stop() {
|
|
43
|
+
await this.node.stop();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Broadcasts an announce beacon with agent metadata across all active transports.
|
|
48
|
+
* @param {Object} [metadata={}]
|
|
49
|
+
*/
|
|
50
|
+
async announce(metadata = {}) {
|
|
51
|
+
const payload = {
|
|
52
|
+
agentName: this.nodeId,
|
|
53
|
+
encryptionPublicKeyHex: this.identity.encryptionPublicKey ? this.identity.encryptionPublicKey.toString('hex') : null,
|
|
54
|
+
...metadata,
|
|
55
|
+
};
|
|
56
|
+
return await this.node.announce(payload);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Sends an end-to-end encrypted memory capsule to a target destination peer.
|
|
61
|
+
* @param {string|Buffer} destination - 32-byte destination hash
|
|
62
|
+
* @param {string|Buffer} recipientX25519Pub - Recipient's 32-byte X25519 public key
|
|
63
|
+
* @param {string|Buffer} payload - Confidential memory string or buffer
|
|
64
|
+
* @param {Object} [options]
|
|
65
|
+
* @returns {Promise<{ packetId: string, routed: boolean, deliveredLocally: boolean }>}
|
|
66
|
+
*/
|
|
67
|
+
async send(destination, recipientX25519Pub, payload, options = {}) {
|
|
68
|
+
const destHex = Buffer.isBuffer(destination) ? destination.toString('hex') : destination;
|
|
69
|
+
const xPubBuf = Buffer.isBuffer(recipientX25519Pub) ? recipientX25519Pub : Buffer.from(recipientX25519Pub, 'hex');
|
|
70
|
+
return await this.node.sendEncryptedCapsule(destHex, xPubBuf, payload, options);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Discovers and returns all active peer agents.
|
|
75
|
+
* @returns {Array<Object>}
|
|
76
|
+
*/
|
|
77
|
+
getPeers() {
|
|
78
|
+
return this.node.getPeers();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Subscribes to incoming decrypted memory capsules.
|
|
83
|
+
* @param {Function} listener
|
|
84
|
+
*/
|
|
85
|
+
onCapsule(listener) {
|
|
86
|
+
this.node.on('capsule', listener);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param {Object} transport
|
|
91
|
+
*/
|
|
92
|
+
addTransport(transport) {
|
|
93
|
+
return this.node.addTransport(transport);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns current node status and public identity hashes.
|
|
98
|
+
* @returns {Object}
|
|
99
|
+
*/
|
|
100
|
+
status() {
|
|
101
|
+
return {
|
|
102
|
+
nodeId: this.nodeId,
|
|
103
|
+
scope: this.scope,
|
|
104
|
+
destinationHex: this.identity.destinationHex,
|
|
105
|
+
publicKeyHex: this.identity.publicKey.toString('hex'),
|
|
106
|
+
encryptionPublicKeyHex: this.identity.encryptionPublicKey ? this.identity.encryptionPublicKey.toString('hex') : null,
|
|
107
|
+
peersCount: this.node.getPeers().length,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Enigma LangChain Memory & Lifecycle Adapter.
|
|
2
|
+
// Connects LangChain agents and chains to Enigma sovereign encrypted memory
|
|
3
|
+
// with automated decision filtering, tool execution tracking, and contradiction handling.
|
|
4
|
+
import { Enigma } from '../index.js';
|
|
5
|
+
|
|
6
|
+
export class EnigmaLangChainMemory {
|
|
7
|
+
/**
|
|
8
|
+
* @param {Object} options
|
|
9
|
+
* @param {Enigma} options.enigma - Connected Enigma instance
|
|
10
|
+
* @param {string} [options.memoryKey='history'] - Output key for formatted context
|
|
11
|
+
* @param {string} [options.inputKey='input']
|
|
12
|
+
* @param {string} [options.outputKey='output']
|
|
13
|
+
* @param {number} [options.maxTokens=2000] - Token budget for context compilation
|
|
14
|
+
* @param {string} [options.scope]
|
|
15
|
+
* @param {boolean} [options.selectiveMemory=true] - Uses DecisionEngine to filter low-signal noise
|
|
16
|
+
*/
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
if (!options.enigma || typeof options.enigma.remember !== 'function') {
|
|
19
|
+
throw new Error('options.enigma must be an initialized Enigma instance');
|
|
20
|
+
}
|
|
21
|
+
this.enigma = options.enigma;
|
|
22
|
+
this.memoryKey = options.memoryKey || 'history';
|
|
23
|
+
this.inputKey = options.inputKey || 'input';
|
|
24
|
+
this.outputKey = options.outputKey || 'output';
|
|
25
|
+
this.maxTokens = options.maxTokens ?? 2000;
|
|
26
|
+
this.scope = options.scope || this.enigma.scope;
|
|
27
|
+
this.selectiveMemory = options.selectiveMemory !== false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get memoryKeys() {
|
|
31
|
+
return [this.memoryKey];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Loads relevant memory context for the incoming prompt values.
|
|
36
|
+
* @param {Record<string, unknown>} [values={}]
|
|
37
|
+
* @returns {Promise<Record<string, string>>}
|
|
38
|
+
*/
|
|
39
|
+
async loadMemoryVariables(values = {}) {
|
|
40
|
+
const query = typeof values[this.inputKey] === 'string'
|
|
41
|
+
? values[this.inputKey]
|
|
42
|
+
: (typeof values.prompt === 'string' ? values.prompt : '');
|
|
43
|
+
|
|
44
|
+
if (!query) {
|
|
45
|
+
return { [this.memoryKey]: '' };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const pack = await this.enigma.getContextPack(query, {
|
|
49
|
+
maxTokens: this.maxTokens,
|
|
50
|
+
scope: this.scope,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
[this.memoryKey]: pack.contextText,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Stores a conversational turn or observation into sovereign encrypted memory.
|
|
60
|
+
* Evaluates novelty and importance if selectiveMemory is enabled.
|
|
61
|
+
* @param {Record<string, unknown>} inputValues
|
|
62
|
+
* @param {Record<string, unknown>} outputValues
|
|
63
|
+
* @returns {Promise<void>}
|
|
64
|
+
*/
|
|
65
|
+
async saveContext(inputValues = {}, outputValues = {}) {
|
|
66
|
+
const input = inputValues[this.inputKey] || inputValues.prompt || '';
|
|
67
|
+
const output = outputValues[this.outputKey] || outputValues.response || outputValues.text || '';
|
|
68
|
+
|
|
69
|
+
if (!input && !output) return;
|
|
70
|
+
|
|
71
|
+
const memoryText = input && output ? `User: ${input}\nAssistant: ${output}` : String(input || output);
|
|
72
|
+
|
|
73
|
+
if (this.selectiveMemory) {
|
|
74
|
+
const evaluation = this.enigma.evaluateObservation(memoryText, { framework: 'langchain' });
|
|
75
|
+
if (!evaluation.shouldRemember) {
|
|
76
|
+
return; // Filtered low-signal chat chatter
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await this.enigma.remember(memoryText, {
|
|
81
|
+
scope: this.scope,
|
|
82
|
+
metadata: { framework: 'langchain', turnType: 'dialogue' },
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Lifecycle Hook: Executed before an LLM invocation to inject sovereign context.
|
|
88
|
+
* @param {Array<Object>|string} promptOrMessages
|
|
89
|
+
* @returns {Promise<{ sovereignContext: string, items: Array }>}
|
|
90
|
+
*/
|
|
91
|
+
async beforeModel(promptOrMessages) {
|
|
92
|
+
const queryText = typeof promptOrMessages === 'string'
|
|
93
|
+
? promptOrMessages
|
|
94
|
+
: Array.isArray(promptOrMessages) && promptOrMessages.length > 0
|
|
95
|
+
? promptOrMessages[promptOrMessages.length - 1].content || promptOrMessages[promptOrMessages.length - 1].text || ''
|
|
96
|
+
: '';
|
|
97
|
+
|
|
98
|
+
const pack = await this.enigma.getContextPack(queryText, {
|
|
99
|
+
maxTokens: this.maxTokens,
|
|
100
|
+
scope: this.scope,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
sovereignContext: pack.contextText,
|
|
105
|
+
items: pack.items,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Lifecycle Hook: Executed after a tool execution to record procedural execution receipts.
|
|
111
|
+
* @param {string} toolName
|
|
112
|
+
* @param {Object} toolInput
|
|
113
|
+
* @param {Object} toolOutput
|
|
114
|
+
*/
|
|
115
|
+
async afterTool(toolName, toolInput, toolOutput) {
|
|
116
|
+
const recordText = `Tool Execution [${toolName}]: Input: ${JSON.stringify(toolInput)} => Output: ${JSON.stringify(toolOutput)}`;
|
|
117
|
+
await this.enigma.remember(recordText, {
|
|
118
|
+
scope: this.scope,
|
|
119
|
+
type: 'procedural',
|
|
120
|
+
importance: 1.2,
|
|
121
|
+
metadata: { toolName, framework: 'langchain' },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Records a user correction and registers supersession in the contradiction DAG.
|
|
127
|
+
* @param {string} priorFact
|
|
128
|
+
* @param {string} updatedFact
|
|
129
|
+
* @param {string} [reason='user_correction']
|
|
130
|
+
*/
|
|
131
|
+
async onCorrection(priorFact, updatedFact, reason = 'user_correction') {
|
|
132
|
+
const candidates = await this.enigma.recall(priorFact, { scope: this.scope, topK: 3 });
|
|
133
|
+
const priorId = candidates.length > 0 ? candidates[0].id : null;
|
|
134
|
+
|
|
135
|
+
const newAtom = await this.enigma.remember(updatedFact, {
|
|
136
|
+
scope: this.scope,
|
|
137
|
+
type: 'semantic',
|
|
138
|
+
importance: 2.0,
|
|
139
|
+
supersedes: priorId ? [priorId] : [],
|
|
140
|
+
metadata: { reason, framework: 'langchain' },
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return newAtom;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Clears all memory atoms recorded under this memory scope.
|
|
148
|
+
* @returns {Promise<number>} Count of forgotten memories
|
|
149
|
+
*/
|
|
150
|
+
async clear() {
|
|
151
|
+
let count = 0;
|
|
152
|
+
const scopedMemories = Array.from(this.enigma._memories.values()).filter(m => m.scope === this.scope);
|
|
153
|
+
for (const mem of scopedMemories) {
|
|
154
|
+
await this.enigma.forget(mem.id);
|
|
155
|
+
count++;
|
|
156
|
+
}
|
|
157
|
+
return count;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Enigma LlamaIndex Retriever Adapter & Node Store.
|
|
2
|
+
// Connects LlamaIndex node indexers, synthesizers, and query engines to sovereign encrypted vector memory.
|
|
3
|
+
import { Enigma } from '../index.js';
|
|
4
|
+
|
|
5
|
+
export class EnigmaLlamaIndexRetriever {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Object} options
|
|
8
|
+
* @param {Enigma} options.enigma - Connected Enigma instance
|
|
9
|
+
* @param {number} [options.similarityTopK=5]
|
|
10
|
+
* @param {string} [options.scope]
|
|
11
|
+
*/
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
if (!options.enigma || typeof options.enigma.recall !== 'function') {
|
|
14
|
+
throw new Error('options.enigma must be an initialized Enigma instance');
|
|
15
|
+
}
|
|
16
|
+
this.enigma = options.enigma;
|
|
17
|
+
this.similarityTopK = options.similarityTopK || 5;
|
|
18
|
+
this.scope = options.scope || this.enigma.scope;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves nodes matching the query string.
|
|
23
|
+
* @param {string} query
|
|
24
|
+
* @returns {Promise<Array<{ node: { id_: string, text: string, metadata: Record<string, unknown> }, score: number }>>}
|
|
25
|
+
*/
|
|
26
|
+
async retrieve(query) {
|
|
27
|
+
if (!query || typeof query !== 'string') return [];
|
|
28
|
+
|
|
29
|
+
const results = await this.enigma.recall(query, {
|
|
30
|
+
topK: this.similarityTopK,
|
|
31
|
+
scope: this.scope,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return results.map((r) => ({
|
|
35
|
+
node: {
|
|
36
|
+
id_: r.id,
|
|
37
|
+
text: r.text,
|
|
38
|
+
metadata: {
|
|
39
|
+
scope: r.scope,
|
|
40
|
+
type: r.type,
|
|
41
|
+
superseded: r.superseded,
|
|
42
|
+
createdAt: r.createdAt,
|
|
43
|
+
...r.metadata,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
score: r.score,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Batch inserts LlamaIndex nodes into sovereign memory.
|
|
52
|
+
* @param {Array<{ id_?: string, text: string, metadata?: Object }>} nodes
|
|
53
|
+
* @returns {Promise<number>}
|
|
54
|
+
*/
|
|
55
|
+
async insertNodes(nodes = []) {
|
|
56
|
+
let count = 0;
|
|
57
|
+
for (const n of nodes) {
|
|
58
|
+
if (n.text) {
|
|
59
|
+
await this.enigma.remember(n.text, {
|
|
60
|
+
id: n.id_,
|
|
61
|
+
scope: this.scope,
|
|
62
|
+
metadata: { framework: 'llamaindex', ...(n.metadata || {}) },
|
|
63
|
+
});
|
|
64
|
+
count++;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return count;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Deletes nodes by ID.
|
|
72
|
+
* @param {string[]} nodeIds
|
|
73
|
+
* @returns {Promise<number>}
|
|
74
|
+
*/
|
|
75
|
+
async deleteNodes(nodeIds = []) {
|
|
76
|
+
let count = 0;
|
|
77
|
+
for (const id of nodeIds) {
|
|
78
|
+
const ok = await this.enigma.forget(id);
|
|
79
|
+
if (ok) count++;
|
|
80
|
+
}
|
|
81
|
+
return count;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Records a factual correction in the knowledge base.
|
|
86
|
+
* @param {string} priorFact
|
|
87
|
+
* @param {string} updatedFact
|
|
88
|
+
*/
|
|
89
|
+
async onCorrection(priorFact, updatedFact) {
|
|
90
|
+
const matches = await this.enigma.recall(priorFact, { scope: this.scope, topK: 3 });
|
|
91
|
+
const priorId = matches.length > 0 ? matches[0].id : null;
|
|
92
|
+
|
|
93
|
+
return await this.enigma.remember(updatedFact, {
|
|
94
|
+
scope: this.scope,
|
|
95
|
+
type: 'semantic',
|
|
96
|
+
importance: 2.0,
|
|
97
|
+
supersedes: priorId ? [priorId] : [],
|
|
98
|
+
metadata: { framework: 'llamaindex', correction: true },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|