memoryintelligence 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,153 @@
1
+ """
2
+ Memory Intelligence SDK
3
+ =======================
4
+
5
+ The official Python SDK for Memory Intelligence.
6
+
7
+ Quick Start:
8
+ from memoryintelligence import MemoryClient
9
+
10
+ mi = MemoryClient(api_key="mi_sk_...")
11
+
12
+ # Process content → meaning (raw content discarded)
13
+ umo = mi.process("Important meeting notes", user_ulid="01ABC...")
14
+
15
+ # Search with explanation
16
+ results = mi.search("What did we discuss?", user_ulid="01ABC...", explain=True)
17
+
18
+ # Match for recommendations
19
+ match = mi.match(user_ulid, candidate_ulid, explain=True)
20
+
21
+ # Delete for GDPR
22
+ mi.delete(user_ulid="01ABC...")
23
+
24
+ For regulated industries (HIPAA, legal, finance):
25
+ from memoryintelligence import EdgeClient
26
+
27
+ mi = EdgeClient(
28
+ endpoint="https://mi.internal.yourcompany.com",
29
+ api_key="mi_sk_...",
30
+ hipaa_mode=True
31
+ )
32
+
33
+ # Process locally—data never leaves your infrastructure
34
+ umo = mi.process(clinical_note, patient_ulid="01ABC...")
35
+
36
+ Core Operations:
37
+ - process() → Convert raw content to meaning
38
+ - search() → Find relevant memories
39
+ - match() → Compare memories for relevance
40
+ - explain() → Get explanation for any UMO
41
+ - delete() → Remove all user data
42
+ - verify_provenance() → Verify authorship/timestamp
43
+
44
+ Version: 1.0.0
45
+ Author: Memory Intelligence Team
46
+ """
47
+
48
+ __version__ = "1.0.0"
49
+ __author__ = "Memory Intelligence Team"
50
+
51
+ # ============================================================================
52
+ # Public API
53
+ # ============================================================================
54
+
55
+ # Main clients
56
+ from .memory_client import MemoryClient
57
+ from .edge_client import EdgeClient, connect_edge
58
+
59
+ # Enums
60
+ from .mi_types import (
61
+ Scope,
62
+ RetentionPolicy,
63
+ PIIHandling,
64
+ ProvenanceMode,
65
+ ExplainLevel,
66
+ )
67
+
68
+ # Response types
69
+ from .mi_types import (
70
+ MeaningObject,
71
+ SearchResponse,
72
+ SearchResult,
73
+ MatchResult,
74
+ DeleteResult,
75
+ VerifyResult,
76
+ Explanation,
77
+ ExplainHuman,
78
+ ExplainAudit,
79
+ Entity,
80
+ Topic,
81
+ SVOTriple,
82
+ Provenance,
83
+ PIIDetection,
84
+ )
85
+
86
+ # Config types
87
+ from .mi_types import (
88
+ ProcessConfig,
89
+ SearchConfig,
90
+ MatchConfig,
91
+ )
92
+
93
+ # Exceptions
94
+ from .mi_types import (
95
+ MIError,
96
+ AuthenticationError,
97
+ RateLimitError,
98
+ ScopeViolationError,
99
+ PIIViolationError,
100
+ GovernanceError,
101
+ ProvenenaceError,
102
+ )
103
+
104
+ # ============================================================================
105
+ # Convenience exports
106
+ # ============================================================================
107
+
108
+ __all__ = [
109
+ # Version
110
+ "__version__",
111
+
112
+ # Clients
113
+ "MemoryClient",
114
+ "EdgeClient",
115
+ "connect_edge",
116
+
117
+ # Enums
118
+ "Scope",
119
+ "RetentionPolicy",
120
+ "PIIHandling",
121
+ "ProvenanceMode",
122
+ "ExplainLevel",
123
+
124
+ # Response types
125
+ "MeaningObject",
126
+ "SearchResponse",
127
+ "SearchResult",
128
+ "MatchResult",
129
+ "DeleteResult",
130
+ "VerifyResult",
131
+ "Explanation",
132
+ "ExplainHuman",
133
+ "ExplainAudit",
134
+ "Entity",
135
+ "Topic",
136
+ "SVOTriple",
137
+ "Provenance",
138
+ "PIIDetection",
139
+
140
+ # Config types
141
+ "ProcessConfig",
142
+ "SearchConfig",
143
+ "MatchConfig",
144
+
145
+ # Exceptions
146
+ "MIError",
147
+ "AuthenticationError",
148
+ "RateLimitError",
149
+ "ScopeViolationError",
150
+ "PIIViolationError",
151
+ "GovernanceError",
152
+ "ProvenenaceError",
153
+ ]
@@ -0,0 +1,384 @@
1
+ """
2
+ Memory Intelligence SDK - Edge Client
3
+ =====================================
4
+
5
+ On-premises / VPC deployment for regulated industries.
6
+ Data never leaves your infrastructure—only metering crosses the network.
7
+
8
+ Problem Solved: Proprietary Data Paralysis
9
+ - HIPAA: Clinical notes processed locally
10
+ - Legal: Attorney-client privileged documents
11
+ - Finance: Trading data, internal communications
12
+ - Competitive: Trade secrets, internal strategy
13
+
14
+ Architecture:
15
+ ┌─────────────────────────────────────────────────────────┐
16
+ │ YOUR INFRASTRUCTURE │
17
+ │ │
18
+ │ ┌──────────────┐ ┌──────────────────────────┐ │
19
+ │ │ Your App │ │ MI Edge Container │ │
20
+ │ │ │ ──────> │ - 12-phase pipeline │ │
21
+ │ │ EdgeClient │ │ - NER engine │ │
22
+ │ │ │ <────── │ - Embedding engine │ │
23
+ │ └──────────────┘ │ - Provenance ledger │ │
24
+ │ └──────────────────────────┘ │
25
+ │ │ │
26
+ └──────────────────────────────────────│───────────────────┘
27
+ │ Metering only
28
+
29
+ ┌───────────────────────┐
30
+ │ MI Cloud (optional) │
31
+ │ - Usage tracking │
32
+ │ - License validation │
33
+ └───────────────────────┘
34
+
35
+ Usage:
36
+ from memoryintelligence import EdgeClient
37
+
38
+ # Connect to your on-prem MI container
39
+ mi = EdgeClient(
40
+ endpoint="https://mi.internal.yourcompany.com",
41
+ api_key="mi_sk_...", # For metering only
42
+ hipaa_mode=True
43
+ )
44
+
45
+ # Process locally—data never leaves
46
+ umo = mi.process(clinical_note, patient_ulid="01ABC...")
47
+
48
+ Author: Memory Intelligence Team
49
+ Version: 1.0.0
50
+ """
51
+
52
+ import httpx
53
+ import logging
54
+ from datetime import datetime
55
+ from typing import Any, Dict, List, Optional, Union
56
+
57
+ from .mi_types import (
58
+ Scope,
59
+ RetentionPolicy,
60
+ PIIHandling,
61
+ ProvenanceMode,
62
+ ExplainLevel,
63
+ MeaningObject,
64
+ SearchResponse,
65
+ MatchResult,
66
+ DeleteResult,
67
+ Explanation,
68
+ MIError,
69
+ AuthenticationError,
70
+ )
71
+ from .memory_client import MemoryClient
72
+
73
+ logger = logging.getLogger(__name__)
74
+
75
+
76
+ class EdgeClient(MemoryClient):
77
+ """
78
+ Edge deployment client for regulated industries.
79
+
80
+ All processing happens in your infrastructure.
81
+ Only metering/licensing data crosses the network (optional).
82
+
83
+ Key Features:
84
+ - HIPAA mode: Enhanced PHI detection, audit logging
85
+ - Air-gapped mode: No network calls at all
86
+ - Federated aggregation: Query across deployments without sharing data
87
+
88
+ Args:
89
+ endpoint: Your internal MI container endpoint
90
+ api_key: MI API key (for metering, can be disabled)
91
+ hipaa_mode: Enable HIPAA-compliant processing
92
+ air_gapped: Disable all external network calls
93
+ metering_enabled: Whether to report usage to MI cloud
94
+
95
+ Example:
96
+ # Standard edge deployment
97
+ mi = EdgeClient(
98
+ endpoint="https://mi.internal.yourcompany.com",
99
+ api_key="mi_sk_...",
100
+ hipaa_mode=True
101
+ )
102
+
103
+ # Air-gapped (no external calls)
104
+ mi = EdgeClient(
105
+ endpoint="https://mi.internal.yourcompany.com",
106
+ air_gapped=True
107
+ )
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ endpoint: str,
113
+ api_key: Optional[str] = None,
114
+ hipaa_mode: bool = False,
115
+ air_gapped: bool = False,
116
+ metering_enabled: bool = True,
117
+ timeout: float = 30.0,
118
+ ):
119
+ self.endpoint = endpoint.rstrip("/")
120
+ self.hipaa_mode = hipaa_mode
121
+ self.air_gapped = air_gapped
122
+ self.metering_enabled = metering_enabled and not air_gapped
123
+
124
+ # For air-gapped mode, API key is optional
125
+ if not air_gapped and not api_key:
126
+ raise AuthenticationError(
127
+ "API key required for metered edge deployment. "
128
+ "Use air_gapped=True for offline mode."
129
+ )
130
+
131
+ self.api_key = api_key
132
+ self.timeout = timeout
133
+
134
+ # Edge client connects to internal endpoint
135
+ self._client = httpx.Client(
136
+ base_url=self.endpoint,
137
+ timeout=self.timeout,
138
+ headers={
139
+ "X-MI-Edge-Mode": "true",
140
+ "X-MI-HIPAA-Mode": str(hipaa_mode).lower(),
141
+ "Content-Type": "application/json",
142
+ }
143
+ )
144
+
145
+ # Separate client for metering (if enabled)
146
+ if self.metering_enabled and api_key:
147
+ self._metering_client = httpx.Client(
148
+ base_url="https://api.memoryintelligence.dev",
149
+ timeout=5.0, # Fast timeout for metering
150
+ headers={
151
+ "Authorization": f"Bearer {api_key}",
152
+ "X-MI-Edge-Metering": "true",
153
+ }
154
+ )
155
+ else:
156
+ self._metering_client = None
157
+
158
+ logger.info(
159
+ f"EdgeClient initialized (endpoint={endpoint}, "
160
+ f"hipaa={hipaa_mode}, air_gapped={air_gapped})"
161
+ )
162
+
163
+ def process(
164
+ self,
165
+ content: str,
166
+ user_ulid: str,
167
+ *,
168
+ retention_policy: RetentionPolicy = RetentionPolicy.MEANING_ONLY,
169
+ pii_handling: PIIHandling = PIIHandling.EXTRACT_AND_REDACT,
170
+ provenance_mode: ProvenanceMode = ProvenanceMode.STANDARD,
171
+ scope: Scope = Scope.USER,
172
+ scope_id: Optional[str] = None,
173
+ source: str = "edge",
174
+ metadata: Optional[Dict[str, Any]] = None,
175
+ ) -> MeaningObject:
176
+ """
177
+ Process content locally in your infrastructure.
178
+
179
+ In HIPAA mode:
180
+ - Enhanced PHI detection (ICD-10, medical terms)
181
+ - All PHI hashed, never stored
182
+ - Audit log proves data never left
183
+
184
+ Args:
185
+ content: Raw content (processed locally, never transmitted)
186
+ user_ulid: Owner ULID (can be patient ULID in HIPAA mode)
187
+ retention_policy: What to retain (meaning_only recommended)
188
+ pii_handling: PHI/PII handling (hash recommended for HIPAA)
189
+ ... (same as MemoryClient.process)
190
+
191
+ Returns:
192
+ MeaningObject with entities, embedding, provenance
193
+
194
+ Note:
195
+ In HIPAA mode, the response includes phi_status showing
196
+ what PHI was detected and how it was handled.
197
+ """
198
+ # Override PII handling in HIPAA mode
199
+ if self.hipaa_mode:
200
+ pii_handling = PIIHandling.HASH
201
+ provenance_mode = ProvenanceMode.AUDIT
202
+
203
+ payload = {
204
+ "content": content,
205
+ "user_ulid": user_ulid,
206
+ "retention_policy": retention_policy.value,
207
+ "pii_handling": pii_handling.value,
208
+ "provenance_mode": provenance_mode.value,
209
+ "scope": scope.value,
210
+ "scope_id": scope_id,
211
+ "source": source,
212
+ "metadata": metadata or {},
213
+ "hipaa_mode": self.hipaa_mode,
214
+ }
215
+
216
+ # Process locally
217
+ response = self._request("POST", "/v1/process", json=payload)
218
+ result = self._parse_meaning_object(response)
219
+
220
+ # Report usage (async, non-blocking, fails silently)
221
+ if self.metering_enabled:
222
+ self._report_usage("process", user_ulid)
223
+
224
+ return result
225
+
226
+ def aggregate(
227
+ self,
228
+ query: str,
229
+ scope: Scope = Scope.ORGANIZATION,
230
+ return_format: str = "statistics_only",
231
+ minimum_cohort_size: int = 50,
232
+ ) -> Dict[str, Any]:
233
+ """
234
+ Aggregate insights across records without exposing individual data.
235
+
236
+ Federated querying with differential privacy for regulated data.
237
+
238
+ Args:
239
+ query: Natural language query for aggregation
240
+ scope: Aggregation scope (typically ORGANIZATION)
241
+ return_format: "statistics_only" (no individual records)
242
+ minimum_cohort_size: K-anonymity threshold
243
+
244
+ Returns:
245
+ Aggregated statistics with privacy guarantees
246
+
247
+ Example:
248
+ insights = mi.aggregate(
249
+ "Patients with chest pain who responded to nitroglycerin",
250
+ scope=Scope.ORGANIZATION,
251
+ minimum_cohort_size=50
252
+ )
253
+
254
+ # Returns:
255
+ # {
256
+ # "count": 1247,
257
+ # "avg_response_time": "4.2 minutes",
258
+ # "audit_proof": {"no_phi_returned": True, ...}
259
+ # }
260
+ """
261
+ payload = {
262
+ "query": query,
263
+ "scope": scope.value,
264
+ "return_format": return_format,
265
+ "minimum_cohort_size": minimum_cohort_size,
266
+ "hipaa_mode": self.hipaa_mode,
267
+ }
268
+
269
+ response = self._request("POST", "/v1/aggregate", json=payload)
270
+
271
+ # Report usage
272
+ if self.metering_enabled:
273
+ self._report_usage("aggregate", "aggregate")
274
+
275
+ return response
276
+
277
+ def verify_phi_handling(self, umo_id: str) -> Dict[str, Any]:
278
+ """
279
+ Verify how PHI was handled for a specific UMO.
280
+
281
+ Returns audit proof showing:
282
+ - What PHI types were detected
283
+ - How each was handled (hashed, redacted)
284
+ - Proof that raw PHI was never stored/transmitted
285
+
286
+ Args:
287
+ umo_id: ULID of the processed memory
288
+
289
+ Returns:
290
+ PHI handling audit proof
291
+
292
+ Example:
293
+ proof = mi.verify_phi_handling(umo_id)
294
+
295
+ # Returns:
296
+ # {
297
+ # "phi_detected": ["PERSON", "DATE", "MRN"],
298
+ # "handling_method": "hash",
299
+ # "raw_phi_stored": False,
300
+ # "raw_phi_transmitted": False,
301
+ # "audit_hash": "sha256:...",
302
+ # "timestamp": "2025-12-26T..."
303
+ # }
304
+ """
305
+ response = self._request("GET", f"/v1/phi/verify/{umo_id}")
306
+ return response
307
+
308
+ def export_audit_log(
309
+ self,
310
+ start_date: datetime,
311
+ end_date: datetime,
312
+ format: str = "json",
313
+ ) -> Dict[str, Any]:
314
+ """
315
+ Export audit log for compliance review.
316
+
317
+ Returns complete processing audit trail for the date range.
318
+
319
+ Args:
320
+ start_date: Audit period start
321
+ end_date: Audit period end
322
+ format: Export format ("json", "csv")
323
+
324
+ Returns:
325
+ Audit log with all processing events
326
+ """
327
+ payload = {
328
+ "start_date": start_date.isoformat(),
329
+ "end_date": end_date.isoformat(),
330
+ "format": format,
331
+ }
332
+
333
+ response = self._request("POST", "/v1/audit/export", json=payload)
334
+ return response
335
+
336
+ def _report_usage(self, operation: str, user_ulid: str):
337
+ """Report usage to MI cloud for metering (non-blocking)."""
338
+ if not self._metering_client:
339
+ return
340
+
341
+ try:
342
+ self._metering_client.post(
343
+ "/v1/metering/report",
344
+ json={
345
+ "operation": operation,
346
+ "user_ulid": user_ulid,
347
+ "timestamp": datetime.utcnow().isoformat(),
348
+ "hipaa_mode": self.hipaa_mode,
349
+ }
350
+ )
351
+ except Exception as e:
352
+ # Metering failures should never block processing
353
+ logger.debug(f"Metering report failed (non-blocking): {e}")
354
+
355
+ def close(self):
356
+ """Close HTTP clients."""
357
+ self._client.close()
358
+ if self._metering_client:
359
+ self._metering_client.close()
360
+
361
+
362
+ # ============================================================================
363
+ # Convenience function for quick edge setup
364
+ # ============================================================================
365
+
366
+ def connect_edge(
367
+ endpoint: str,
368
+ api_key: Optional[str] = None,
369
+ hipaa_mode: bool = False,
370
+ ) -> EdgeClient:
371
+ """
372
+ Quick helper to connect to an edge deployment.
373
+
374
+ Example:
375
+ from memoryintelligence import connect_edge
376
+
377
+ mi = connect_edge("https://mi.internal.hospital.com", hipaa_mode=True)
378
+ umo = mi.process(clinical_note, patient_ulid="01ABC...")
379
+ """
380
+ return EdgeClient(
381
+ endpoint=endpoint,
382
+ api_key=api_key,
383
+ hipaa_mode=hipaa_mode,
384
+ )