sovant 1.0.5__py3-none-any.whl → 1.0.7__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/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .client import Sovant, SovantError
2
2
  from .models import MemoryCreate, MemoryResult, SearchQuery
3
3
 
4
- __version__ = "0.1.0"
4
+ __version__ = "1.0.7"
@@ -0,0 +1,475 @@
1
+ Metadata-Version: 2.4
2
+ Name: sovant
3
+ Version: 1.0.7
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
+ [![PyPI version](https://img.shields.io/pypi/v/sovant.svg)](https://pypi.org/project/sovant/)
19
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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.
@@ -1,4 +1,4 @@
1
- sovant/__init__.py,sha256=1GYQzmb1Ni5-y874HOs1J-rYrpx-iBzR4_cCEBFIjpk,122
1
+ sovant/__init__.py,sha256=hmpXJBx3oFfXlSlmJrTh79Dy6LwvpI11jdaix-fyt88,122
2
2
  sovant/base_client.py,sha256=Vmn6OGywGwLbH5cEeflSjVOFwn5iX_YdfTdUq9pWWxA,8778
3
3
  sovant/client.py,sha256=B1SlHvUKKRSf1NYOOEkfukBmxhpsop4lHY2X_-EBFek,3372
4
4
  sovant/exceptions.py,sha256=MQMSgk7ckXnAbe7hPPpbKOnRBHSPxuCY7WSjqfJAvd0,1557
@@ -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.5.dist-info/licenses/LICENSE,sha256=rnNP6-elrMIlQ9jf2aqnHZMyyQ_wvF3y1hTpVUusCWU,1062
11
- sovant-1.0.5.dist-info/METADATA,sha256=GmaGl7CztLd-e_iqfvn35tQE3peBCnhEfGzwDARAHV8,3834
12
- sovant-1.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- sovant-1.0.5.dist-info/top_level.txt,sha256=za6eVEsYd_ZQQs8vrmEWNcAR58r1wCDge_jA60e4CvQ,7
14
- sovant-1.0.5.dist-info/RECORD,,
10
+ sovant-1.0.7.dist-info/licenses/LICENSE,sha256=rnNP6-elrMIlQ9jf2aqnHZMyyQ_wvF3y1hTpVUusCWU,1062
11
+ sovant-1.0.7.dist-info/METADATA,sha256=PLokxYhdgIjz8eEFRx3epAIYwIngF-EFUf-Lu6OXzXk,11407
12
+ sovant-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ sovant-1.0.7.dist-info/top_level.txt,sha256=za6eVEsYd_ZQQs8vrmEWNcAR58r1wCDge_jA60e4CvQ,7
14
+ sovant-1.0.7.dist-info/RECORD,,
@@ -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
- [![PyPI version](https://img.shields.io/pypi/v/sovant)](https://pypi.org/project/sovant/)
20
- [![Documentation](https://img.shields.io/badge/docs-sovant.ai-blue)](https://sovant.ai/docs)
21
- [![GitHub](https://img.shields.io/badge/github-sovant-lightgrey)](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