sovant 1.0.5__py3-none-any.whl → 1.0.6__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.
Potentially problematic release.
This version of sovant might be problematic. Click here for more details.
- sovant-1.0.6.dist-info/METADATA +475 -0
- {sovant-1.0.5.dist-info → sovant-1.0.6.dist-info}/RECORD +5 -5
- sovant-1.0.5.dist-info/METADATA +0 -118
- {sovant-1.0.5.dist-info → sovant-1.0.6.dist-info}/WHEEL +0 -0
- {sovant-1.0.5.dist-info → sovant-1.0.6.dist-info}/licenses/LICENSE +0 -0
- {sovant-1.0.5.dist-info → sovant-1.0.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sovant
|
|
3
|
+
Version: 1.0.6
|
|
4
|
+
Summary: Sovant Memory-as-a-Service Python SDK
|
|
5
|
+
Author: Sovant
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: httpx>=0.27.0
|
|
11
|
+
Requires-Dist: pydantic>=2.8.2
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# Sovant Python SDK
|
|
15
|
+
|
|
16
|
+
Sovant is Memory-as-a-Service: a durable, queryable memory layer for AI apps with cross-model recall, hybrid (semantic + deterministic) retrieval, and simple SDKs.
|
|
17
|
+
|
|
18
|
+
[](https://pypi.org/project/sovant/)
|
|
19
|
+
[](https://opensource.org/licenses/MIT)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install sovant
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from sovant import Sovant
|
|
31
|
+
|
|
32
|
+
# Initialize the client
|
|
33
|
+
client = Sovant(api_key="sk_live_your_api_key_here", base_url="https://sovant.ai")
|
|
34
|
+
|
|
35
|
+
# Create a memory
|
|
36
|
+
mem = client.memory.create({
|
|
37
|
+
"content": "User prefers dark mode",
|
|
38
|
+
"type": "preference",
|
|
39
|
+
"tags": ["ui", "settings"]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
# Search memories
|
|
43
|
+
results = client.memory.search({
|
|
44
|
+
"query": "user preferences",
|
|
45
|
+
"limit": 10
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
# Update a memory
|
|
49
|
+
updated = client.memory.update(mem["id"], {
|
|
50
|
+
"tags": ["ui", "settings", "theme"]
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
# Delete a memory
|
|
54
|
+
client.memory.delete(mem["id"])
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Chat in 60 Seconds
|
|
58
|
+
|
|
59
|
+
Stream real-time chat responses with memory context:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from sovant import Sovant
|
|
63
|
+
import sys
|
|
64
|
+
|
|
65
|
+
client = Sovant(api_key="sk_live_your_api_key_here", base_url="https://sovant.ai")
|
|
66
|
+
|
|
67
|
+
# Create a chat session
|
|
68
|
+
session = client.chat.create_session({"title": "Demo"})
|
|
69
|
+
|
|
70
|
+
# Stream a response
|
|
71
|
+
stream = client.chat.send_message(
|
|
72
|
+
session["id"],
|
|
73
|
+
"hello",
|
|
74
|
+
{
|
|
75
|
+
"provider": "openai",
|
|
76
|
+
"model": "gpt-4o-mini",
|
|
77
|
+
"use_memory": True
|
|
78
|
+
},
|
|
79
|
+
stream=True
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
for ev in stream:
|
|
83
|
+
if ev["type"] == "delta":
|
|
84
|
+
sys.stdout.write(ev.get("data", ""))
|
|
85
|
+
elif ev["type"] == "done":
|
|
86
|
+
print("\n[done]")
|
|
87
|
+
|
|
88
|
+
# Get chat history
|
|
89
|
+
messages = client.chat.get_messages(session["id"])
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Profile Recall Helpers
|
|
93
|
+
|
|
94
|
+
Save and recall user profile facts with canonical patterns:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
# Extract profile entity from text
|
|
98
|
+
fact = client.recall.extract_profile("i'm from kuching")
|
|
99
|
+
# -> {"entity": "location", "value": "kuching"} | None
|
|
100
|
+
|
|
101
|
+
if fact:
|
|
102
|
+
client.recall.save_profile_fact(fact) # canonicalizes and persists
|
|
103
|
+
|
|
104
|
+
# Get all profile facts
|
|
105
|
+
profile = client.recall.get_profile_facts()
|
|
106
|
+
# -> {"name": "...", "age": "...", "location": "...", "preferences": [...]}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Configuration
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from sovant import Sovant
|
|
113
|
+
|
|
114
|
+
client = Sovant(
|
|
115
|
+
api_key="sk_live_your_api_key_here", # Required
|
|
116
|
+
base_url="https://sovant.ai", # Optional, API endpoint
|
|
117
|
+
timeout=30.0, # Optional, request timeout in seconds (default: 30.0)
|
|
118
|
+
max_retries=3, # Optional, max retry attempts (default: 3)
|
|
119
|
+
debug=False, # Optional, enable debug logging (default: False)
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The SDK handles dual authentication automatically, preferring the `x-sovant-api-key` header over `Authorization: Bearer`.
|
|
124
|
+
|
|
125
|
+
## API Reference
|
|
126
|
+
|
|
127
|
+
### Memory Operations
|
|
128
|
+
|
|
129
|
+
#### Create Memory
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
memory = client.memory.create({
|
|
133
|
+
"content": "Customer contacted support about billing",
|
|
134
|
+
"type": "observation", # 'journal' | 'insight' | 'observation' | 'task' | 'preference'
|
|
135
|
+
"tags": ["support", "billing"],
|
|
136
|
+
"metadata": {"ticket_id": "12345"},
|
|
137
|
+
"thread_id": "thread_abc123", # Optional thread association
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### List Memories
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
memories = client.memory.list({
|
|
145
|
+
"limit": 20, # Max items per page (default: 20)
|
|
146
|
+
"offset": 0, # Pagination offset
|
|
147
|
+
"tags": ["billing"], # Filter by tags
|
|
148
|
+
"type": "observation", # Filter by type
|
|
149
|
+
"is_archived": False, # Filter archived status
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
print(memories["memories"]) # Array of memories
|
|
153
|
+
print(memories["total"]) # Total count
|
|
154
|
+
print(memories["has_more"]) # More pages available
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Get Memory by ID
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
memory = client.memory.get("mem_123abc")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Update Memory (Partial)
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
updated = client.memory.update("mem_123abc", {
|
|
167
|
+
"tags": ["support", "billing", "resolved"],
|
|
168
|
+
"metadata": {
|
|
169
|
+
**memory.get("metadata", {}),
|
|
170
|
+
"resolved": True,
|
|
171
|
+
},
|
|
172
|
+
"is_archived": True,
|
|
173
|
+
})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### Replace Memory (Full)
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
replaced = client.memory.put("mem_123abc", {
|
|
180
|
+
"content": "Updated content here", # Required for PUT
|
|
181
|
+
"type": "observation",
|
|
182
|
+
"tags": ["updated"],
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Delete Memory
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
client.memory.delete("mem_123abc")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Search Memories
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# Semantic search
|
|
196
|
+
semantic_results = client.memory.search({
|
|
197
|
+
"query": "customer preferences about notifications",
|
|
198
|
+
"limit": 10,
|
|
199
|
+
"type": "preference",
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
# Filter-based search
|
|
203
|
+
filter_results = client.memory.search({
|
|
204
|
+
"tags": ["settings", "notifications"],
|
|
205
|
+
"from_date": "2024-01-01",
|
|
206
|
+
"to_date": "2024-12-31",
|
|
207
|
+
"limit": 20,
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Batch Operations
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
batch = client.memory.batch({
|
|
215
|
+
"operations": [
|
|
216
|
+
{
|
|
217
|
+
"op": "create",
|
|
218
|
+
"data": {
|
|
219
|
+
"content": "First memory",
|
|
220
|
+
"type": "journal",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"op": "update",
|
|
225
|
+
"id": "mem_123abc",
|
|
226
|
+
"data": {
|
|
227
|
+
"tags": ["updated"],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"op": "delete",
|
|
232
|
+
"id": "mem_456def",
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
print(batch["results"]) # Individual operation results
|
|
238
|
+
print(batch["summary"]) # Summary statistics
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Thread Management
|
|
242
|
+
|
|
243
|
+
Associate memories with conversation threads:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
# Create a thread
|
|
247
|
+
thread = client.threads.create({
|
|
248
|
+
"title": "Customer Support Session",
|
|
249
|
+
"metadata": {"user_id": "user_123"}
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
# List threads
|
|
253
|
+
threads = client.threads.list({
|
|
254
|
+
"limit": 10,
|
|
255
|
+
"offset": 0
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
# Get thread by ID
|
|
259
|
+
thread = client.threads.get("thread_abc123")
|
|
260
|
+
|
|
261
|
+
# Update thread
|
|
262
|
+
updated_thread = client.threads.update("thread_abc123", {
|
|
263
|
+
"title": "Resolved: Billing Issue",
|
|
264
|
+
"metadata": {"status": "resolved"}
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
# Delete thread
|
|
268
|
+
client.threads.delete("thread_abc123")
|
|
269
|
+
|
|
270
|
+
# Link memory to thread
|
|
271
|
+
client.threads.link_memory("thread_abc123", "mem_123abc")
|
|
272
|
+
|
|
273
|
+
# Create memories within a thread
|
|
274
|
+
memory1 = client.memory.create({
|
|
275
|
+
"content": "User asked about pricing",
|
|
276
|
+
"type": "observation",
|
|
277
|
+
"thread_id": "thread_abc123",
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
memory2 = client.memory.create({
|
|
281
|
+
"content": "User selected enterprise plan",
|
|
282
|
+
"type": "observation",
|
|
283
|
+
"thread_id": "thread_abc123",
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
# List memories in a thread
|
|
287
|
+
thread_memories = client.memory.list({
|
|
288
|
+
"thread_id": "thread_abc123",
|
|
289
|
+
})
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### API Key Management
|
|
293
|
+
|
|
294
|
+
Manage API keys programmatically:
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
# List all API keys
|
|
298
|
+
keys = client.keys.list()
|
|
299
|
+
print(keys) # Array of key objects
|
|
300
|
+
|
|
301
|
+
# Create a new API key
|
|
302
|
+
new_key = client.keys.create({"name": "CI key"})
|
|
303
|
+
print(new_key["key"]) # The actual secret key (only shown once!)
|
|
304
|
+
|
|
305
|
+
# Update key metadata
|
|
306
|
+
client.keys.update(new_key["id"], {"name": "Production key"})
|
|
307
|
+
|
|
308
|
+
# Revoke a key
|
|
309
|
+
client.keys.revoke(new_key["id"])
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Memory Types
|
|
313
|
+
|
|
314
|
+
- **journal** - Chronological entries and logs
|
|
315
|
+
- **insight** - Derived patterns and conclusions
|
|
316
|
+
- **observation** - Factual, observed information
|
|
317
|
+
- **task** - Action items and todos
|
|
318
|
+
- **preference** - User preferences and settings
|
|
319
|
+
|
|
320
|
+
## Error Handling
|
|
321
|
+
|
|
322
|
+
The SDK provides typed errors for better error handling:
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
from sovant import Sovant, SovantError, AuthError, RateLimitError, NetworkError, TimeoutError
|
|
326
|
+
|
|
327
|
+
try:
|
|
328
|
+
memory = client.memory.get("invalid_id")
|
|
329
|
+
except AuthError as e:
|
|
330
|
+
print(f"Authentication failed: {e}")
|
|
331
|
+
# Handle authentication error
|
|
332
|
+
except RateLimitError as e:
|
|
333
|
+
print(f"Rate limit exceeded: {e}")
|
|
334
|
+
print(f"Retry after: {e.retry_after}")
|
|
335
|
+
# Handle rate limiting
|
|
336
|
+
except NetworkError as e:
|
|
337
|
+
print(f"Network error: {e}")
|
|
338
|
+
# Handle network issues
|
|
339
|
+
except TimeoutError as e:
|
|
340
|
+
print(f"Request timed out: {e}")
|
|
341
|
+
# Handle timeout
|
|
342
|
+
except SovantError as e:
|
|
343
|
+
print(f"API Error: {e}")
|
|
344
|
+
print(f"Status: {e.status}")
|
|
345
|
+
print(f"Request ID: {e.request_id}")
|
|
346
|
+
|
|
347
|
+
if e.status == 404:
|
|
348
|
+
# Handle not found
|
|
349
|
+
pass
|
|
350
|
+
elif e.status == 400:
|
|
351
|
+
# Handle bad request
|
|
352
|
+
pass
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Advanced Features
|
|
356
|
+
|
|
357
|
+
### Retry Configuration
|
|
358
|
+
|
|
359
|
+
The SDK automatically retries failed requests with exponential backoff:
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
client = Sovant(
|
|
363
|
+
api_key="sk_live_...",
|
|
364
|
+
max_retries=5, # Increase retry attempts
|
|
365
|
+
timeout=60.0, # Increase timeout for slow connections
|
|
366
|
+
)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Debug Mode
|
|
370
|
+
|
|
371
|
+
Enable debug logging to see detailed request/response information:
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
client = Sovant(
|
|
375
|
+
api_key="sk_live_...",
|
|
376
|
+
debug=True, # Enable debug output
|
|
377
|
+
)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Custom Base URL
|
|
381
|
+
|
|
382
|
+
Connect to different environments:
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
client = Sovant(
|
|
386
|
+
api_key="sk_live_...",
|
|
387
|
+
base_url="https://staging.sovant.ai",
|
|
388
|
+
)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Best Practices
|
|
392
|
+
|
|
393
|
+
1. **Use appropriate memory types** - Choose the correct type for your use case
|
|
394
|
+
2. **Add meaningful tags** - Tags improve searchability and organization
|
|
395
|
+
3. **Use threads** - Group related memories together
|
|
396
|
+
4. **Handle errors gracefully** - Implement proper error handling
|
|
397
|
+
5. **Batch operations** - Use batch API for multiple operations
|
|
398
|
+
6. **Archive don't delete** - Consider archiving instead of deleting
|
|
399
|
+
|
|
400
|
+
## Examples
|
|
401
|
+
|
|
402
|
+
### Customer Support Integration
|
|
403
|
+
|
|
404
|
+
```python
|
|
405
|
+
# Track customer interaction
|
|
406
|
+
interaction = client.memory.create({
|
|
407
|
+
"content": "Customer reported slow dashboard loading",
|
|
408
|
+
"type": "observation",
|
|
409
|
+
"thread_id": f"ticket_{ticket_id}",
|
|
410
|
+
"tags": ["support", "performance", "dashboard"],
|
|
411
|
+
"metadata": {
|
|
412
|
+
"ticket_id": ticket_id,
|
|
413
|
+
"customer_id": customer_id,
|
|
414
|
+
"priority": "high",
|
|
415
|
+
},
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
# Record resolution
|
|
419
|
+
resolution = client.memory.create({
|
|
420
|
+
"content": "Resolved by clearing cache and upgrading plan",
|
|
421
|
+
"type": "insight",
|
|
422
|
+
"thread_id": f"ticket_{ticket_id}",
|
|
423
|
+
"tags": ["support", "resolved"],
|
|
424
|
+
"metadata": {
|
|
425
|
+
"ticket_id": ticket_id,
|
|
426
|
+
"resolution_time": "2h",
|
|
427
|
+
},
|
|
428
|
+
})
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### User Preference Tracking
|
|
432
|
+
|
|
433
|
+
```python
|
|
434
|
+
# Store preference
|
|
435
|
+
preference = client.memory.create({
|
|
436
|
+
"content": "User prefers email notifications over SMS",
|
|
437
|
+
"type": "preference",
|
|
438
|
+
"tags": ["notifications", "email", "settings"],
|
|
439
|
+
"metadata": {
|
|
440
|
+
"user_id": user_id,
|
|
441
|
+
"setting": "notification_channel",
|
|
442
|
+
"value": "email",
|
|
443
|
+
},
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
# Query preferences
|
|
447
|
+
preferences = client.memory.search({
|
|
448
|
+
"query": "notification preferences",
|
|
449
|
+
"type": "preference",
|
|
450
|
+
"tags": ["notifications"],
|
|
451
|
+
})
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Rate Limiting
|
|
455
|
+
|
|
456
|
+
The API implements rate limiting. The SDK automatically handles rate limit responses with retries. Rate limit headers are included in responses:
|
|
457
|
+
|
|
458
|
+
- `X-RateLimit-Limit` - Request limit per window
|
|
459
|
+
- `X-RateLimit-Remaining` - Remaining requests
|
|
460
|
+
- `X-RateLimit-Reset` - Reset timestamp
|
|
461
|
+
|
|
462
|
+
## Support
|
|
463
|
+
|
|
464
|
+
- Documentation: [https://sovant.ai/docs](https://sovant.ai/docs)
|
|
465
|
+
- API/Auth docs: [https://sovant.ai/docs/security/auth](https://sovant.ai/docs/security/auth)
|
|
466
|
+
- Issues: [GitHub Issues](https://github.com/sovant-ai/python-sdk/issues)
|
|
467
|
+
- Support: support@sovant.ai
|
|
468
|
+
|
|
469
|
+
## Changelog
|
|
470
|
+
|
|
471
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a detailed history of changes.
|
|
472
|
+
|
|
473
|
+
## License
|
|
474
|
+
|
|
475
|
+
MIT - See [LICENSE](LICENSE) file for details.
|
|
@@ -7,8 +7,8 @@ sovant/types.py,sha256=gnvdXksJt8LObti7nc6eHSBCB7Pz7SNpS5o_HRTq_kA,6098
|
|
|
7
7
|
sovant/resources/__init__.py,sha256=cPFIM7h8duviDdeHudnVEAmv3F89RHQxdH5BCRWFteQ,193
|
|
8
8
|
sovant/resources/memories.py,sha256=bKKE0uWqFkPa1OEvbK1LrdSD7v6N04RhJ_2VDoPPQBA,11379
|
|
9
9
|
sovant/resources/threads.py,sha256=mN29xP0JODmZBKyfhpeqJyViUWNVMAx3TlYAW-1ruTs,12558
|
|
10
|
-
sovant-1.0.
|
|
11
|
-
sovant-1.0.
|
|
12
|
-
sovant-1.0.
|
|
13
|
-
sovant-1.0.
|
|
14
|
-
sovant-1.0.
|
|
10
|
+
sovant-1.0.6.dist-info/licenses/LICENSE,sha256=rnNP6-elrMIlQ9jf2aqnHZMyyQ_wvF3y1hTpVUusCWU,1062
|
|
11
|
+
sovant-1.0.6.dist-info/METADATA,sha256=SmjSY0YBdERNPVumlKvcLvOMZGBMr1j7aV4qUOHJ0oc,11407
|
|
12
|
+
sovant-1.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
+
sovant-1.0.6.dist-info/top_level.txt,sha256=za6eVEsYd_ZQQs8vrmEWNcAR58r1wCDge_jA60e4CvQ,7
|
|
14
|
+
sovant-1.0.6.dist-info/RECORD,,
|
sovant-1.0.5.dist-info/METADATA
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: sovant
|
|
3
|
-
Version: 1.0.5
|
|
4
|
-
Summary: Sovant Memory-as-a-Service Python SDK
|
|
5
|
-
Author: Sovant
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.10
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Requires-Dist: httpx>=0.27.0
|
|
11
|
-
Requires-Dist: pydantic>=2.8.2
|
|
12
|
-
Dynamic: license-file
|
|
13
|
-
|
|
14
|
-
# Sovant Python SDK
|
|
15
|
-
|
|
16
|
-
**AI Infrastructure: Memory-as-a-Service for AI systems.**
|
|
17
|
-
The official Python client for the Sovant Memory API.
|
|
18
|
-
|
|
19
|
-
[](https://pypi.org/project/sovant/)
|
|
20
|
-
[](https://sovant.ai/docs)
|
|
21
|
-
[](https://github.com/sovant-ai/sovant)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## What is Sovant?
|
|
26
|
-
|
|
27
|
-
Sovant is an **AI infrastructure company** providing the **memory layer for AI systems**.
|
|
28
|
-
Our platform makes it simple to persist, search, and manage conversational/context data securely across sessions, channels, and applications.
|
|
29
|
-
|
|
30
|
-
- **Problem:** Most AI systems forget once a session ends → compliance risk, knowledge loss, poor UX.
|
|
31
|
-
- **Solution:** Sovant provides a **Memory-as-a-Service API** — store, retrieve, and search memories with audit-ready controls.
|
|
32
|
-
- **Built for:** Developers & enterprises building AI agents, copilots, or compliance-driven apps that need persistent context.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Installation
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
pip install sovant
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## 60-Second Quickstart
|
|
43
|
-
|
|
44
|
-
```python
|
|
45
|
-
from sovant import Sovant, MemoryCreate, SearchQuery
|
|
46
|
-
|
|
47
|
-
client = Sovant(api_key="YOUR_API_KEY")
|
|
48
|
-
|
|
49
|
-
# Create a memory (SDK uses 'data' field, automatically converts to 'content' for API)
|
|
50
|
-
created = client.memory_create(MemoryCreate(
|
|
51
|
-
data="User prefers morning meetings", # Note: 'data' field (not 'content')
|
|
52
|
-
type="preference",
|
|
53
|
-
tags=["customer:123"],
|
|
54
|
-
# metadata={"source": "crm"},
|
|
55
|
-
# thread_id="00000000-0000-0000-0000-000000000000",
|
|
56
|
-
))
|
|
57
|
-
print(created)
|
|
58
|
-
|
|
59
|
-
# Search memories
|
|
60
|
-
results = client.memory_search(SearchQuery(
|
|
61
|
-
query="meeting preferences",
|
|
62
|
-
topK=3,
|
|
63
|
-
# tags=["customer:123"],
|
|
64
|
-
# thread_id="...",
|
|
65
|
-
))
|
|
66
|
-
print(results)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Features
|
|
70
|
-
|
|
71
|
-
- **Memory CRUD** — create, retrieve, update (PATCH/PUT), delete
|
|
72
|
-
- **Semantic Search** — full-text/semantic with topK and filters
|
|
73
|
-
- **Threads** — group related memories via thread_id (REST API)
|
|
74
|
-
- **Batch Operations (Beta)** — atomic multi-operation requests
|
|
75
|
-
- **Compliance-ready** — audit trails, PDPA/GDPR-friendly design
|
|
76
|
-
- **SDKs** — official Python & TypeScript clients + REST reference
|
|
77
|
-
|
|
78
|
-
## SDKs & Documentation
|
|
79
|
-
|
|
80
|
-
- **Python** (this package) on PyPI: https://pypi.org/project/sovant/
|
|
81
|
-
- **TypeScript** on npm: https://www.npmjs.com/package/@sovant/sdk
|
|
82
|
-
- **REST API Reference**: https://sovant.ai/docs/api
|
|
83
|
-
- **Full Documentation**: https://sovant.ai/docs
|
|
84
|
-
|
|
85
|
-
## API Overview
|
|
86
|
-
|
|
87
|
-
### Endpoints Summary
|
|
88
|
-
|
|
89
|
-
- `POST /api/v1/memory` — Create memory
|
|
90
|
-
- `GET /api/v1/memory` — List memories
|
|
91
|
-
- `GET /api/v1/memories/{id}` — Get by ID
|
|
92
|
-
- `PATCH | PUT /api/v1/memories/{id}` — Update
|
|
93
|
-
- `DELETE /api/v1/memories/{id}` — Delete
|
|
94
|
-
- `GET /api/v1/memory/search` — Search
|
|
95
|
-
- `POST /api/v1/memory/batch` — Batch (Beta)
|
|
96
|
-
|
|
97
|
-
**Auth:** Bearer token in the `Authorization` header.
|
|
98
|
-
|
|
99
|
-
## Field Mapping Note
|
|
100
|
-
|
|
101
|
-
- **SDK uses:** `data` field in MemoryCreate (more intuitive for developers)
|
|
102
|
-
- **API expects:** `content` field (SDK automatically converts `data` → `content`)
|
|
103
|
-
- **Deprecated:** `subject` is ignored by the API. Use `thread_id`, `tags`, or `metadata` for grouping.
|
|
104
|
-
|
|
105
|
-
## Status of Advanced Features
|
|
106
|
-
|
|
107
|
-
- **Batch API:** Available, marked Beta (contract may evolve).
|
|
108
|
-
- **Threads:** Fully supported via REST API.
|
|
109
|
-
- **Webhooks / Personalization / Multi-Channel Sync:** Coming soon.
|
|
110
|
-
|
|
111
|
-
## Versioning & Changelog
|
|
112
|
-
|
|
113
|
-
- **Stable release:** 1.0.5
|
|
114
|
-
- See [CHANGELOG.md](https://github.com/sovant-ai/sovant) in the repo for details.
|
|
115
|
-
|
|
116
|
-
## License
|
|
117
|
-
|
|
118
|
-
MIT © Sovant AI
|
|
File without changes
|
|
File without changes
|
|
File without changes
|