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,187 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public enum PrivacyMode: String, Codable, Sendable, CaseIterable {
|
|
4
|
+
case off, smart, full
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
public enum PrivacyCategory: String, Codable, Sendable, CaseIterable {
|
|
8
|
+
case email, phone, ipv4, paymentCard, apiKey, privateKey, evmWallet, solanaWallet
|
|
9
|
+
case person, location, address, organization, medical, legalMatter, account
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public struct SemanticPrivacyFinding: Hashable, Sendable {
|
|
13
|
+
public let range: Range<String.Index>
|
|
14
|
+
public let category: PrivacyCategory
|
|
15
|
+
|
|
16
|
+
public init(range: Range<String.Index>, category: PrivacyCategory) {
|
|
17
|
+
self.range = range
|
|
18
|
+
self.category = category
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public protocol SemanticPrivacyTagging: Sendable {
|
|
23
|
+
func findings(in text: String) -> [SemanticPrivacyFinding]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public struct HeuristicSemanticPrivacyTagger: SemanticPrivacyTagging {
|
|
27
|
+
public init() {}
|
|
28
|
+
|
|
29
|
+
public func findings(in text: String) -> [SemanticPrivacyFinding] {
|
|
30
|
+
let rules: [(String, PrivacyCategory)] = [
|
|
31
|
+
(#"(?i)\b(?:my name is|i am|i'm)\s+([A-Z][\p{L}'-]+(?:\s+[A-Z][\p{L}'-]+){0,2})"#, .person),
|
|
32
|
+
(#"(?i)\b(?:i live in|i am based in|my address is)\s+([^,.!?\n]{2,80})"#, .location),
|
|
33
|
+
(#"(?i)\b(?:my employer is|i work (?:at|for))\s+([^,.!?\n]{2,80})"#, .organization),
|
|
34
|
+
(#"(?i)\b(?:my diagnosis is|i was diagnosed with)\s+([^,.!?\n]{2,80})"#, .medical),
|
|
35
|
+
(#"(?i)\b(?:my case number is|my lawyer is)\s+([^,.!?\n]{2,80})"#, .legalMatter),
|
|
36
|
+
(#"(?i)\b(?:my account number is|account id is)\s+([A-Za-z0-9_-]{4,80})"#, .account),
|
|
37
|
+
]
|
|
38
|
+
var output: [SemanticPrivacyFinding] = []
|
|
39
|
+
let full = NSRange(text.startIndex..<text.endIndex, in: text)
|
|
40
|
+
for (pattern, category) in rules {
|
|
41
|
+
guard let regex = try? NSRegularExpression(pattern: pattern) else { continue }
|
|
42
|
+
for match in regex.matches(in: text, range: full) {
|
|
43
|
+
let target = match.numberOfRanges > 1 ? match.range(at: 1) : match.range
|
|
44
|
+
if let range = Range(target, in: text) { output.append(.init(range: range, category: category)) }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return output
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public struct PrivacyReceipt: Codable, Sendable {
|
|
52
|
+
public struct Summary: Codable, Hashable, Sendable {
|
|
53
|
+
public let category: PrivacyCategory
|
|
54
|
+
public let action: String
|
|
55
|
+
public let count: Int
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public let schema: String
|
|
59
|
+
public let mode: PrivacyMode
|
|
60
|
+
public let safeForExternal: Bool
|
|
61
|
+
public let inputCharacters: Int
|
|
62
|
+
public let outputCharacters: Int
|
|
63
|
+
public let summary: [Summary]
|
|
64
|
+
public let receiptReference: UUID
|
|
65
|
+
|
|
66
|
+
public init(mode: PrivacyMode, safeForExternal: Bool, inputCharacters: Int, outputCharacters: Int, summary: [Summary], receiptReference: UUID = UUID()) {
|
|
67
|
+
self.schema = "enigma.ios_privacy_receipt.v1"
|
|
68
|
+
self.mode = mode
|
|
69
|
+
self.safeForExternal = safeForExternal
|
|
70
|
+
self.inputCharacters = inputCharacters
|
|
71
|
+
self.outputCharacters = outputCharacters
|
|
72
|
+
self.summary = summary
|
|
73
|
+
self.receiptReference = receiptReference
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public final class PrivacySession: @unchecked Sendable {
|
|
78
|
+
public let messages: [EnigmaMessage]
|
|
79
|
+
public let receipt: PrivacyReceipt
|
|
80
|
+
private let lock = NSLock()
|
|
81
|
+
private var replacements: [String: String]
|
|
82
|
+
|
|
83
|
+
init(messages: [EnigmaMessage], receipt: PrivacyReceipt, replacements: [String: String]) {
|
|
84
|
+
self.messages = messages
|
|
85
|
+
self.receipt = receipt
|
|
86
|
+
self.replacements = replacements
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public func restore(_ value: String) -> String {
|
|
90
|
+
lock.lock()
|
|
91
|
+
let current = replacements
|
|
92
|
+
lock.unlock()
|
|
93
|
+
return current.reduce(value) { output, replacement in output.replacingOccurrences(of: replacement.key, with: replacement.value) }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public func dispose() {
|
|
97
|
+
lock.lock()
|
|
98
|
+
replacements.removeAll(keepingCapacity: false)
|
|
99
|
+
lock.unlock()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
deinit { dispose() }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public struct PrivacyMinimizer: Sendable {
|
|
106
|
+
private struct Rule: Sendable {
|
|
107
|
+
let pattern: String
|
|
108
|
+
let category: PrivacyCategory
|
|
109
|
+
let validator: @Sendable (String) -> Bool
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private let rules: [Rule] = [
|
|
113
|
+
.init(pattern: #"(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b"#, category: .email, validator: { _ in true }),
|
|
114
|
+
.init(pattern: #"\b(?:\+?\d[\d .()-]{7,}\d)\b"#, category: .phone, validator: { value in value.filter(\.isNumber).count >= 8 }),
|
|
115
|
+
.init(pattern: #"\b(?:\d{1,3}\.){3}\d{1,3}\b"#, category: .ipv4, validator: { value in value.split(separator: ".").allSatisfy { (0...255).contains(Int($0) ?? -1) } }),
|
|
116
|
+
.init(pattern: #"\b(?:\d[ -]*?){13,19}\b"#, category: .paymentCard, validator: Self.luhn),
|
|
117
|
+
.init(pattern: #"(?i)\b(?:sk|pk|api|token|key)[_-](?:live|test)?[_-]?[A-Za-z0-9]{16,}\b"#, category: .apiKey, validator: { _ in true }),
|
|
118
|
+
.init(pattern: #"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"#, category: .privateKey, validator: { _ in true }),
|
|
119
|
+
.init(pattern: #"\b0x[a-fA-F0-9]{40}\b"#, category: .evmWallet, validator: { _ in true }),
|
|
120
|
+
.init(pattern: #"\b[1-9A-HJ-NP-Za-km-z]{32,44}\b"#, category: .solanaWallet, validator: { _ in true }),
|
|
121
|
+
]
|
|
122
|
+
private let semanticTagger: any SemanticPrivacyTagging
|
|
123
|
+
|
|
124
|
+
public init(semanticTagger: any SemanticPrivacyTagging = HeuristicSemanticPrivacyTagger()) {
|
|
125
|
+
self.semanticTagger = semanticTagger
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public func minimize(_ messages: [EnigmaMessage], mode: PrivacyMode) -> PrivacySession {
|
|
129
|
+
guard mode != .off else {
|
|
130
|
+
let count = messages.reduce(0) { $0 + $1.content.count }
|
|
131
|
+
return PrivacySession(messages: messages, receipt: .init(mode: mode, safeForExternal: true, inputCharacters: count, outputCharacters: count, summary: []), replacements: [:])
|
|
132
|
+
}
|
|
133
|
+
var replacements: [String: String] = [:]
|
|
134
|
+
var counts: [PrivacyCategory: Int] = [:]
|
|
135
|
+
let inputCharacters = messages.reduce(0) { $0 + $1.content.count }
|
|
136
|
+
let minimized = messages.map { message -> EnigmaMessage in
|
|
137
|
+
guard message.role == .user || message.role == .system else { return message }
|
|
138
|
+
if mode == .full {
|
|
139
|
+
counts[.account, default: 0] += 1
|
|
140
|
+
return EnigmaMessage(id: message.id, role: message.role, content: "[PRIVATE_INPUT_WITHHELD]", createdAt: message.createdAt)
|
|
141
|
+
}
|
|
142
|
+
var text = message.content
|
|
143
|
+
var candidates: [(Range<String.Index>, PrivacyCategory)] = []
|
|
144
|
+
for rule in rules {
|
|
145
|
+
guard let regex = try? NSRegularExpression(pattern: rule.pattern) else { continue }
|
|
146
|
+
let full = NSRange(text.startIndex..<text.endIndex, in: text)
|
|
147
|
+
for match in regex.matches(in: text, range: full) {
|
|
148
|
+
guard let range = Range(match.range, in: text), rule.validator(String(text[range])) else { continue }
|
|
149
|
+
candidates.append((range, rule.category))
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
candidates.append(contentsOf: semanticTagger.findings(in: text).map { ($0.range, $0.category) })
|
|
153
|
+
let nonOverlapping = candidates.sorted { $0.0.lowerBound > $1.0.lowerBound }.reduce(into: [(Range<String.Index>, PrivacyCategory)]()) { accepted, candidate in
|
|
154
|
+
if !accepted.contains(where: { $0.0.overlaps(candidate.0) }) { accepted.append(candidate) }
|
|
155
|
+
}
|
|
156
|
+
for (range, category) in nonOverlapping {
|
|
157
|
+
let raw = String(text[range])
|
|
158
|
+
let token = "⟪ENIGMA_\(category.rawValue.uppercased())_\(UUID().uuidString)⟫"
|
|
159
|
+
text.replaceSubrange(range, with: token)
|
|
160
|
+
replacements[token] = raw
|
|
161
|
+
counts[category, default: 0] += 1
|
|
162
|
+
}
|
|
163
|
+
return EnigmaMessage(id: message.id, role: message.role, content: text, createdAt: message.createdAt)
|
|
164
|
+
}
|
|
165
|
+
let outputCharacters = minimized.reduce(0) { $0 + $1.content.count }
|
|
166
|
+
let summary = counts.keys.sorted { $0.rawValue < $1.rawValue }.map {
|
|
167
|
+
PrivacyReceipt.Summary(category: $0, action: mode == .full ? "withheld" : "masked", count: counts[$0] ?? 0)
|
|
168
|
+
}
|
|
169
|
+
return PrivacySession(
|
|
170
|
+
messages: minimized,
|
|
171
|
+
receipt: .init(mode: mode, safeForExternal: mode == .full || !summary.isEmpty, inputCharacters: inputCharacters, outputCharacters: outputCharacters, summary: summary),
|
|
172
|
+
replacements: replacements
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private static func luhn(_ value: String) -> Bool {
|
|
177
|
+
let digits = value.compactMap(\.wholeNumberValue)
|
|
178
|
+
guard (13...19).contains(digits.count) else { return false }
|
|
179
|
+
let sum = digits.reversed().enumerated().reduce(0) { partial, element in
|
|
180
|
+
let (index, digit) = element
|
|
181
|
+
if index.isMultiple(of: 2) { return partial + digit }
|
|
182
|
+
let doubled = digit * 2
|
|
183
|
+
return partial + (doubled > 9 ? doubled - 9 : doubled)
|
|
184
|
+
}
|
|
185
|
+
return sum.isMultiple(of: 10)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public struct VideoQueueRequest: Codable, Sendable {
|
|
4
|
+
public let prompt: String
|
|
5
|
+
public let model: String
|
|
6
|
+
public let duration: Int
|
|
7
|
+
public let resolution: String
|
|
8
|
+
public let aspectRatio: String
|
|
9
|
+
|
|
10
|
+
public init(prompt: String, model: String, duration: Int = 5, resolution: String = "720p", aspectRatio: String = "16:9") {
|
|
11
|
+
self.prompt = prompt
|
|
12
|
+
self.model = model
|
|
13
|
+
self.duration = duration
|
|
14
|
+
self.resolution = resolution
|
|
15
|
+
self.aspectRatio = aspectRatio
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
enum CodingKeys: String, CodingKey {
|
|
19
|
+
case prompt, model, duration, resolution
|
|
20
|
+
case aspectRatio = "aspect_ratio"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public struct VideoJob: Codable, Sendable {
|
|
25
|
+
public let id: String
|
|
26
|
+
public let model: String
|
|
27
|
+
public let provider: String
|
|
28
|
+
public let status: String
|
|
29
|
+
public let progress: Double
|
|
30
|
+
public let error: String?
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public struct VideoAsset: Codable, Sendable {
|
|
34
|
+
public let url: String?
|
|
35
|
+
public let base64: String?
|
|
36
|
+
public let mimeType: String?
|
|
37
|
+
|
|
38
|
+
enum CodingKeys: String, CodingKey {
|
|
39
|
+
case url, base64
|
|
40
|
+
case mimeType = "mimeType"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public struct VideoRetrieveResponse: Decodable, Sendable {
|
|
45
|
+
public let job: VideoJob
|
|
46
|
+
public let asset: VideoAsset?
|
|
47
|
+
|
|
48
|
+
public init(from decoder: Decoder) throws {
|
|
49
|
+
let container = try decoder.container(keyedBy: DynamicCodingKey.self)
|
|
50
|
+
if container.contains(DynamicCodingKey("job")) {
|
|
51
|
+
job = try container.decode(VideoJob.self, forKey: DynamicCodingKey("job"))
|
|
52
|
+
asset = try container.decodeIfPresent(VideoAsset.self, forKey: DynamicCodingKey("asset"))
|
|
53
|
+
} else {
|
|
54
|
+
job = try VideoJob(from: decoder)
|
|
55
|
+
asset = nil
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public struct CodeSession: Codable, Sendable {
|
|
61
|
+
public let id: String
|
|
62
|
+
public let provider: String
|
|
63
|
+
public let status: String
|
|
64
|
+
public let language: String
|
|
65
|
+
public let network: String
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public struct CodeSessionEnvelope: Codable, Sendable { public let session: CodeSession }
|
|
69
|
+
public struct CodeUploadRequest: Codable, Sendable {
|
|
70
|
+
public let path: String
|
|
71
|
+
public let data: String
|
|
72
|
+
public let encoding: String
|
|
73
|
+
public init(path: String = "main.js", data: String, encoding: String = "utf8") {
|
|
74
|
+
self.path = path; self.data = data; self.encoding = encoding
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
public struct CodeExecuteRequest: Codable, Sendable {
|
|
78
|
+
public let entry: String
|
|
79
|
+
public init(entry: String = "main.js") { self.entry = entry }
|
|
80
|
+
}
|
|
81
|
+
public struct CodeExecutionResponse: Codable, Sendable {
|
|
82
|
+
public let ok: Bool
|
|
83
|
+
public let code: Int?
|
|
84
|
+
public let signal: String?
|
|
85
|
+
public let timedOut: Bool?
|
|
86
|
+
public let session: CodeSession
|
|
87
|
+
}
|
|
88
|
+
public struct CodeEventData: Codable, Sendable {
|
|
89
|
+
public let stream: String?
|
|
90
|
+
public let data: String?
|
|
91
|
+
public let message: String?
|
|
92
|
+
}
|
|
93
|
+
public struct CodeEvent: Codable, Identifiable, Sendable {
|
|
94
|
+
public var id: Int { cursor }
|
|
95
|
+
public let cursor: Int
|
|
96
|
+
public let type: String
|
|
97
|
+
public let data: CodeEventData?
|
|
98
|
+
}
|
|
99
|
+
public struct CodeEventsResponse: Codable, Sendable {
|
|
100
|
+
public let session: CodeSession
|
|
101
|
+
public let events: [CodeEvent]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public struct BrowserPrivacy: Codable, Sendable {
|
|
105
|
+
public let ephemeralProfile: Bool
|
|
106
|
+
public let privateNetworkBlocked: Bool
|
|
107
|
+
public let egressLayer: String?
|
|
108
|
+
public let egressPolicyHash: String?
|
|
109
|
+
}
|
|
110
|
+
public struct BrowserSession: Codable, Sendable {
|
|
111
|
+
public let id: String
|
|
112
|
+
public let provider: String
|
|
113
|
+
public let state: String
|
|
114
|
+
public let streamUrl: String?
|
|
115
|
+
public let privacy: BrowserPrivacy
|
|
116
|
+
}
|
|
117
|
+
public struct BrowserSessionEnvelope: Codable, Sendable { public let session: BrowserSession }
|
|
118
|
+
public struct BrowserNavigateRequest: Codable, Sendable {
|
|
119
|
+
public let url: String
|
|
120
|
+
public init(url: String) { self.url = url }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private struct DynamicCodingKey: CodingKey {
|
|
124
|
+
let stringValue: String
|
|
125
|
+
let intValue: Int? = nil
|
|
126
|
+
init(_ value: String) { stringValue = value }
|
|
127
|
+
init?(stringValue: String) { self.stringValue = stringValue }
|
|
128
|
+
init?(intValue: Int) { return nil }
|
|
129
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Testing
|
|
3
|
+
@testable import EnigmaCore
|
|
4
|
+
|
|
5
|
+
@Test func pkceMatchesRFC7636Vector() {
|
|
6
|
+
let verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
|
7
|
+
#expect(PKCE.challenge(for: verifier) == "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM")
|
|
8
|
+
}
|
|
9
|
+
@Test func iosOAuthScopeContractCoversEveryMobileSurface() {
|
|
10
|
+
#expect(Set(EnigmaOAuthScopes.iOSPlatform) == Set([
|
|
11
|
+
"models:invoke",
|
|
12
|
+
"images:generate",
|
|
13
|
+
"video:generate",
|
|
14
|
+
"code:execute",
|
|
15
|
+
"browser:control",
|
|
16
|
+
"usage:read",
|
|
17
|
+
"credits:create",
|
|
18
|
+
"offline_access",
|
|
19
|
+
]))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@Test func smartPrivacyMasksRestoresAndKeepsReceiptContentFree() throws {
|
|
24
|
+
let canary = "Alice Smith"
|
|
25
|
+
let messages = [EnigmaMessage(role: .user, content: "My name is \(canary), email alice@example.com, and I live in Paris.")]
|
|
26
|
+
let session = PrivacyMinimizer().minimize(messages, mode: .smart)
|
|
27
|
+
#expect(!session.messages[0].content.contains(canary))
|
|
28
|
+
#expect(!session.messages[0].content.contains("alice@example.com"))
|
|
29
|
+
#expect(session.restore(session.messages[0].content).contains(canary))
|
|
30
|
+
let receipt = try JSONEncoder().encode(session.receipt)
|
|
31
|
+
let serialized = String(decoding: receipt, as: UTF8.self)
|
|
32
|
+
#expect(!serialized.contains(canary))
|
|
33
|
+
#expect(!serialized.contains("alice@example.com"))
|
|
34
|
+
session.dispose()
|
|
35
|
+
#expect(!session.restore(session.messages[0].content).contains(canary))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Test func fullPrivacyWithholdsUserInput() {
|
|
39
|
+
let session = PrivacyMinimizer().minimize([EnigmaMessage(role: .user, content: "private prose")], mode: .full)
|
|
40
|
+
#expect(session.messages[0].content == "[PRIVATE_INPUT_WITHHELD]")
|
|
41
|
+
#expect(session.receipt.mode == .full)
|
|
42
|
+
}
|