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.
- memoryintelligence/__init__.py +153 -0
- memoryintelligence/edge_client.py +384 -0
- memoryintelligence/memory_client.py +688 -0
- memoryintelligence/mi_types.py +364 -0
- memoryintelligence-1.0.0.dist-info/METADATA +428 -0
- memoryintelligence-1.0.0.dist-info/RECORD +9 -0
- memoryintelligence-1.0.0.dist-info/WHEEL +5 -0
- memoryintelligence-1.0.0.dist-info/licenses/LICENSE +31 -0
- memoryintelligence-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory Intelligence SDK - Types
|
|
3
|
+
===============================
|
|
4
|
+
|
|
5
|
+
Core types, enums, and response models for the SDK.
|
|
6
|
+
These define the contract between developers and the MI API.
|
|
7
|
+
|
|
8
|
+
Design Principles:
|
|
9
|
+
1. Meaning-Only by Default: Raw content discarded unless explicitly overridden
|
|
10
|
+
2. Provenance-First: Every operation produces verifiable audit trail
|
|
11
|
+
3. Scope Isolation: Cryptographic boundaries, not just policies
|
|
12
|
+
4. Explainability: Human + audit explanations on every operation
|
|
13
|
+
5. Edge-Ready: Same types work cloud and on-prem
|
|
14
|
+
|
|
15
|
+
Author: Memory Intelligence Team
|
|
16
|
+
Version: 1.0.0
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
from enum import Enum
|
|
22
|
+
from typing import Any, Dict, List, Optional, Union
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ============================================================================
|
|
26
|
+
# ENUMS - SDK Controlled Vocabularies
|
|
27
|
+
# ============================================================================
|
|
28
|
+
|
|
29
|
+
class Scope(str, Enum):
|
|
30
|
+
"""
|
|
31
|
+
Governance scope for memory isolation.
|
|
32
|
+
|
|
33
|
+
Scopes are cryptographic boundaries—data in one scope is
|
|
34
|
+
technically inaccessible from another, not just policy-restricted.
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
mi.process(content, scope=Scope.CLIENT, client_ulid="01ABC...")
|
|
38
|
+
mi.search(query, scope=Scope.CLIENT, client_ulid="01ABC...")
|
|
39
|
+
"""
|
|
40
|
+
USER = "user" # Personal user memories
|
|
41
|
+
CLIENT = "client" # Per-client isolation (consulting, legal)
|
|
42
|
+
PROJECT = "project" # Per-project isolation
|
|
43
|
+
TEAM = "team" # Team-shared memories
|
|
44
|
+
ORGANIZATION = "org" # Organization-wide
|
|
45
|
+
ALL = "all" # All accessible scopes (for deletion)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class RetentionPolicy(str, Enum):
|
|
49
|
+
"""
|
|
50
|
+
What to retain after processing.
|
|
51
|
+
|
|
52
|
+
Privacy by design: meaning_only is the default, discards raw content.
|
|
53
|
+
|
|
54
|
+
Usage:
|
|
55
|
+
mi.process(content, retention_policy=RetentionPolicy.MEANING_ONLY)
|
|
56
|
+
"""
|
|
57
|
+
MEANING_ONLY = "meaning_only" # Extract meaning, discard raw (DEFAULT)
|
|
58
|
+
FULL = "full" # Store raw + meaning (requires governance override)
|
|
59
|
+
SUMMARY_ONLY = "summary_only" # Store summary + meaning, discard raw
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class PIIHandling(str, Enum):
|
|
63
|
+
"""
|
|
64
|
+
How to handle detected PII.
|
|
65
|
+
|
|
66
|
+
Usage:
|
|
67
|
+
mi.process(content, pii_handling=PIIHandling.EXTRACT_AND_REDACT)
|
|
68
|
+
"""
|
|
69
|
+
DETECT_ONLY = "detect_only" # Flag PII, don't modify
|
|
70
|
+
EXTRACT_AND_REDACT = "extract_and_redact" # Extract to meaning, redact in output
|
|
71
|
+
HASH = "hash" # Replace PII with deterministic hash
|
|
72
|
+
REJECT = "reject" # Reject content containing PII
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ProvenanceMode(str, Enum):
|
|
76
|
+
"""
|
|
77
|
+
Provenance tracking level.
|
|
78
|
+
|
|
79
|
+
Usage:
|
|
80
|
+
mi.process(content, provenance_mode=ProvenanceMode.AUTHORSHIP)
|
|
81
|
+
"""
|
|
82
|
+
STANDARD = "standard" # Hash chain, timestamp (DEFAULT)
|
|
83
|
+
AUTHORSHIP = "authorship" # + semantic fingerprint, lineage tracking
|
|
84
|
+
AUDIT = "audit" # + full transformation log
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ExplainLevel(str, Enum):
|
|
88
|
+
"""
|
|
89
|
+
Level of explanation to include in responses.
|
|
90
|
+
|
|
91
|
+
Usage:
|
|
92
|
+
mi.search(query, explain=ExplainLevel.FULL)
|
|
93
|
+
"""
|
|
94
|
+
NONE = "none" # No explanation (fastest)
|
|
95
|
+
HUMAN = "human" # Human-readable only
|
|
96
|
+
AUDIT = "audit" # Machine-verifiable only
|
|
97
|
+
FULL = "full" # Both human + audit (DEFAULT when explain=True)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# ============================================================================
|
|
101
|
+
# RESPONSE TYPES - What the SDK Returns
|
|
102
|
+
# ============================================================================
|
|
103
|
+
|
|
104
|
+
@dataclass
|
|
105
|
+
class Entity:
|
|
106
|
+
"""An extracted entity from content."""
|
|
107
|
+
text: str
|
|
108
|
+
type: str # PERSON, ORG, LOCATION, CONCEPT, etc.
|
|
109
|
+
confidence: float # 0.0 to 1.0
|
|
110
|
+
first_seen: Optional[datetime] = None
|
|
111
|
+
resolved_ulid: Optional[str] = None # Canonical entity ID
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@dataclass
|
|
115
|
+
class Topic:
|
|
116
|
+
"""An extracted topic from content."""
|
|
117
|
+
name: str
|
|
118
|
+
confidence: float
|
|
119
|
+
parent: Optional[str] = None
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass
|
|
123
|
+
class SVOTriple:
|
|
124
|
+
"""Subject-Verb-Object extraction."""
|
|
125
|
+
subject: str
|
|
126
|
+
verb: str
|
|
127
|
+
object: str
|
|
128
|
+
confidence: float = 1.0
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@dataclass
|
|
132
|
+
class Provenance:
|
|
133
|
+
"""Cryptographic provenance record."""
|
|
134
|
+
semantic_hash: str # Hash of meaning content
|
|
135
|
+
timestamp_anchor: datetime # When processed
|
|
136
|
+
hash_chain: str # Link to previous hash
|
|
137
|
+
lineage: List[str] = field(default_factory=list) # Parent UMO IDs
|
|
138
|
+
model_version: str = "" # Processing model version
|
|
139
|
+
|
|
140
|
+
def verify(self) -> bool:
|
|
141
|
+
"""Verify hash chain integrity."""
|
|
142
|
+
# Implementation would verify cryptographic chain
|
|
143
|
+
return True
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@dataclass
|
|
147
|
+
class ExplainHuman:
|
|
148
|
+
"""Human-readable explanation."""
|
|
149
|
+
summary: str
|
|
150
|
+
key_reasons: List[str] = field(default_factory=list)
|
|
151
|
+
what_changed: Optional[str] = None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass
|
|
155
|
+
class ExplainAudit:
|
|
156
|
+
"""Machine-verifiable audit explanation."""
|
|
157
|
+
semantic_score: float
|
|
158
|
+
temporal_score: float
|
|
159
|
+
entity_score: float
|
|
160
|
+
graph_score: float
|
|
161
|
+
topic_match: List[str] = field(default_factory=list)
|
|
162
|
+
model_version: str = ""
|
|
163
|
+
hash_chain: str = ""
|
|
164
|
+
reproducible: bool = True
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@dataclass
|
|
168
|
+
class Explanation:
|
|
169
|
+
"""Combined explanation for auditable AI."""
|
|
170
|
+
human: ExplainHuman
|
|
171
|
+
audit: ExplainAudit
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass
|
|
175
|
+
class PIIDetection:
|
|
176
|
+
"""PII detection result."""
|
|
177
|
+
detected: bool
|
|
178
|
+
types: List[str] = field(default_factory=list) # PERSON, EMAIL, PHONE, SSN, etc.
|
|
179
|
+
count: int = 0
|
|
180
|
+
handling_applied: PIIHandling = PIIHandling.DETECT_ONLY
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@dataclass
|
|
184
|
+
class MeaningObject:
|
|
185
|
+
"""
|
|
186
|
+
The core output of MI processing.
|
|
187
|
+
|
|
188
|
+
This is what developers work with—structured meaning, not raw content.
|
|
189
|
+
"""
|
|
190
|
+
umo_id: str # ULID identifier
|
|
191
|
+
user_ulid: str # Owner
|
|
192
|
+
|
|
193
|
+
# Meaning extraction
|
|
194
|
+
entities: List[Entity] = field(default_factory=list)
|
|
195
|
+
topics: List[Topic] = field(default_factory=list)
|
|
196
|
+
svo_triples: List[SVOTriple] = field(default_factory=list)
|
|
197
|
+
key_phrases: List[str] = field(default_factory=list)
|
|
198
|
+
summary: Optional[str] = None
|
|
199
|
+
|
|
200
|
+
# Embeddings
|
|
201
|
+
embedding: Optional[List[float]] = None # 384D or 768D vector
|
|
202
|
+
embedding_model: str = ""
|
|
203
|
+
|
|
204
|
+
# Sentiment
|
|
205
|
+
sentiment_label: Optional[str] = None # positive, negative, neutral
|
|
206
|
+
sentiment_score: float = 0.0
|
|
207
|
+
|
|
208
|
+
# Temporal
|
|
209
|
+
timestamp: Optional[datetime] = None
|
|
210
|
+
ingested_at: datetime = field(default_factory=lambda: datetime.utcnow())
|
|
211
|
+
recency_score: float = 1.0
|
|
212
|
+
|
|
213
|
+
# Quality
|
|
214
|
+
quality_score: float = 0.0 # 0.0 to 1.0
|
|
215
|
+
validation_status: str = "pending"
|
|
216
|
+
|
|
217
|
+
# Provenance
|
|
218
|
+
provenance: Optional[Provenance] = None
|
|
219
|
+
|
|
220
|
+
# PII
|
|
221
|
+
pii: Optional[PIIDetection] = None
|
|
222
|
+
|
|
223
|
+
# Scope
|
|
224
|
+
scope: Scope = Scope.USER
|
|
225
|
+
scope_id: Optional[str] = None # client_ulid, project_ulid, etc.
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@dataclass
|
|
229
|
+
class SearchResult:
|
|
230
|
+
"""A single search result with explanation."""
|
|
231
|
+
umo: MeaningObject
|
|
232
|
+
score: float
|
|
233
|
+
explain: Optional[Explanation] = None
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass
|
|
237
|
+
class SearchResponse:
|
|
238
|
+
"""Response from mi.search()."""
|
|
239
|
+
results: List[SearchResult]
|
|
240
|
+
query: str
|
|
241
|
+
scope: Scope
|
|
242
|
+
total_count: int
|
|
243
|
+
|
|
244
|
+
# Audit
|
|
245
|
+
audit_proof: Optional[Dict[str, Any]] = None
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@dataclass
|
|
249
|
+
class MatchResult:
|
|
250
|
+
"""Response from mi.match()."""
|
|
251
|
+
score: float # 0.0 to 1.0
|
|
252
|
+
match: bool # Above threshold?
|
|
253
|
+
source_ulid: str
|
|
254
|
+
candidate_ulid: str
|
|
255
|
+
explain: Optional[Explanation] = None
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@dataclass
|
|
259
|
+
class DeleteResult:
|
|
260
|
+
"""Response from mi.delete()."""
|
|
261
|
+
deleted_count: int
|
|
262
|
+
user_ulid: str
|
|
263
|
+
scope: Scope
|
|
264
|
+
scope_id: Optional[str] = None
|
|
265
|
+
audit_proof: Dict[str, Any] = field(default_factory=dict)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@dataclass
|
|
269
|
+
class VerifyResult:
|
|
270
|
+
"""Response from mi.verify_provenance()."""
|
|
271
|
+
valid: bool
|
|
272
|
+
semantic_hash: str
|
|
273
|
+
timestamp_anchor: datetime
|
|
274
|
+
original_author_ulid: Optional[str] = None
|
|
275
|
+
first_published: Optional[datetime] = None
|
|
276
|
+
hash_chain_valid: bool = True
|
|
277
|
+
audit_proof: Dict[str, Any] = field(default_factory=dict)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
# ============================================================================
|
|
281
|
+
# CONFIGURATION TYPES
|
|
282
|
+
# ============================================================================
|
|
283
|
+
|
|
284
|
+
@dataclass
|
|
285
|
+
class ProcessConfig:
|
|
286
|
+
"""Configuration for mi.process()."""
|
|
287
|
+
retention_policy: RetentionPolicy = RetentionPolicy.MEANING_ONLY
|
|
288
|
+
pii_handling: PIIHandling = PIIHandling.EXTRACT_AND_REDACT
|
|
289
|
+
provenance_mode: ProvenanceMode = ProvenanceMode.STANDARD
|
|
290
|
+
scope: Scope = Scope.USER
|
|
291
|
+
scope_id: Optional[str] = None
|
|
292
|
+
|
|
293
|
+
# Edge processing
|
|
294
|
+
edge_mode: bool = False
|
|
295
|
+
hipaa_mode: bool = False
|
|
296
|
+
|
|
297
|
+
# Optional metadata
|
|
298
|
+
source: str = "api"
|
|
299
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@dataclass
|
|
303
|
+
class SearchConfig:
|
|
304
|
+
"""Configuration for mi.search()."""
|
|
305
|
+
scope: Scope = Scope.USER
|
|
306
|
+
scope_id: Optional[str] = None
|
|
307
|
+
explain: Union[bool, ExplainLevel] = False
|
|
308
|
+
limit: int = 10
|
|
309
|
+
offset: int = 0
|
|
310
|
+
|
|
311
|
+
# Filtering
|
|
312
|
+
date_from: Optional[datetime] = None
|
|
313
|
+
date_to: Optional[datetime] = None
|
|
314
|
+
topics: Optional[List[str]] = None
|
|
315
|
+
entities: Optional[List[str]] = None
|
|
316
|
+
|
|
317
|
+
# Budget
|
|
318
|
+
budget_tokens: Optional[int] = None # Max tokens in response
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@dataclass
|
|
322
|
+
class MatchConfig:
|
|
323
|
+
"""Configuration for mi.match()."""
|
|
324
|
+
explain: Union[bool, ExplainLevel] = False
|
|
325
|
+
threshold: float = 0.7
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
# ============================================================================
|
|
329
|
+
# ERROR TYPES
|
|
330
|
+
# ============================================================================
|
|
331
|
+
|
|
332
|
+
class MIError(Exception):
|
|
333
|
+
"""Base exception for Memory Intelligence SDK."""
|
|
334
|
+
pass
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class AuthenticationError(MIError):
|
|
338
|
+
"""Invalid or expired API key."""
|
|
339
|
+
pass
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class RateLimitError(MIError):
|
|
343
|
+
"""Rate limit exceeded."""
|
|
344
|
+
retry_after: int = 60
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
class ScopeViolationError(MIError):
|
|
348
|
+
"""Attempted cross-scope access."""
|
|
349
|
+
pass
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
class PIIViolationError(MIError):
|
|
353
|
+
"""Content contains PII and policy is REJECT."""
|
|
354
|
+
detected_types: List[str] = field(default_factory=list)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
class GovernanceError(MIError):
|
|
358
|
+
"""Operation violates governance policy."""
|
|
359
|
+
pass
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class ProvenenaceError(MIError):
|
|
363
|
+
"""Provenance verification failed."""
|
|
364
|
+
pass
|