sovant 1.3.0__tar.gz → 1.3.2__tar.gz

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.
sovant-1.3.2/PKG-INFO ADDED
@@ -0,0 +1,417 @@
1
+ Metadata-Version: 2.4
2
+ Name: sovant
3
+ Version: 1.3.2
4
+ Summary: Sovant Python SDK — governed AI memory layer for AI agents and applications
5
+ Author: Sovant
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://sovant.ai/docs
8
+ Project-URL: Source, https://github.com/hechin91/sovant-ai
9
+ Project-URL: Tracker, https://github.com/hechin91/sovant-ai/issues
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: httpx>=0.27.0
14
+ Requires-Dist: pydantic>=2.8.2
15
+ Dynamic: license-file
16
+
17
+ # Sovant Python SDK
18
+
19
+ **Sovant is a governed AI memory layer for AI agents and applications.**
20
+ Use it to store, search, and recall memories with profile awareness and enterprise-grade control over how memory is captured and used.
21
+
22
+ [![PyPI version](https://img.shields.io/pypi/v/sovant.svg)](https://pypi.org/project/sovant/)
23
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install sovant
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```python
34
+ import os
35
+ from sovant import Sovant, MemoryCreate, SearchQuery
36
+
37
+ client = Sovant(api_key=os.environ["SOVANT_API_KEY"])
38
+
39
+ # Create a memory
40
+ mem = client.memory_create(MemoryCreate(
41
+ data="User prefers dark mode",
42
+ type="preference",
43
+ tags=["ui", "settings"],
44
+ ))
45
+
46
+ # Search memories
47
+ results = client.memory_search(SearchQuery(
48
+ query="user preferences",
49
+ limit=10,
50
+ ))
51
+
52
+ # Update a memory
53
+ updated = client.memory_update(mem["id"], {
54
+ "tags": ["ui", "settings", "theme"],
55
+ })
56
+
57
+ # Delete a memory
58
+ client.memory_delete(mem["id"])
59
+ ```
60
+
61
+ ## Recall vs Search
62
+
63
+ Sovant provides two ways to query memories:
64
+
65
+ - **`memory_recall()`** -- Hybrid recall, profile-aware.
66
+ Use for conversational queries: "What do you know about me?", "What happened on Project X?".
67
+ Uses Sovant's hybrid pipeline (profile fast-path + thread-scoped lexical + vector semantic search) and prioritizes profile facts (name/age/location) when available.
68
+
69
+ - **`memory_search()`** -- Semantic search.
70
+ Use for topic lookup and discovery. Pure vector similarity search without profile logic.
71
+
72
+ ```python
73
+ # Recall for conversational queries (returns { "results": [...], "total": N })
74
+ recall = client.memory_recall(
75
+ query="what do you know about me?",
76
+ limit=10,
77
+ )
78
+ for mem in recall.get("results", []):
79
+ print(mem["content"])
80
+
81
+ # Search for topic discovery
82
+ topics = client.memory_search(SearchQuery(
83
+ query="project updates",
84
+ limit=5,
85
+ ))
86
+ ```
87
+
88
+ ## Working with Threads
89
+
90
+ Threads let you organize related memories into conversations or sessions. Each thread has a `title` and can contain multiple memories.
91
+
92
+ ```python
93
+ import os
94
+ from sovant import Sovant, MemoryCreate
95
+
96
+ client = Sovant(api_key=os.environ["SOVANT_API_KEY"])
97
+
98
+ # Create a new thread
99
+ thread = client.threads_create(
100
+ title="Project Alpha Discussion",
101
+ description="Q1 planning meeting notes",
102
+ metadata={"project": "alpha", "quarter": "Q1"},
103
+ )
104
+
105
+ # Store memories in the thread
106
+ mem1 = client.memory_create(MemoryCreate(
107
+ data="Decided to launch in March",
108
+ type="journal",
109
+ thread_id=thread["id"],
110
+ ))
111
+
112
+ mem2 = client.memory_create(MemoryCreate(
113
+ data="Budget approved: $50k",
114
+ type="insight",
115
+ thread_id=thread["id"],
116
+ ))
117
+
118
+ # Recall memories from this specific thread
119
+ thread_recall = client.memory_recall(
120
+ query="launch date",
121
+ thread_id=thread["id"],
122
+ limit=10,
123
+ )
124
+ # thread_recall["results"] contains the matching memories
125
+
126
+ # Get thread with all its memories
127
+ thread_with_memories = client.threads_get(
128
+ thread["id"],
129
+ include_memories=True,
130
+ limit=50,
131
+ )
132
+
133
+ # List all threads
134
+ threads = client.threads_list(limit=20, offset=0)
135
+
136
+ # Update thread
137
+ updated = client.threads_update(
138
+ thread["id"],
139
+ title="Project Alpha - Q1 Launch",
140
+ status="completed",
141
+ )
142
+
143
+ # Delete thread (keeps memories by default)
144
+ client.threads_delete(thread["id"])
145
+
146
+ # Delete thread AND all its memories
147
+ client.threads_delete(thread["id"], delete_memories=True)
148
+ ```
149
+
150
+ ## Configuration
151
+
152
+ ```python
153
+ from sovant import Sovant
154
+
155
+ client = Sovant(
156
+ api_key="sk_live_...", # Required (or set SOVANT_API_KEY env var)
157
+ base_url="https://sovant.ai", # Optional, defaults to https://sovant.ai
158
+ timeout=30.0, # Optional, request timeout in seconds (default: 30.0)
159
+ max_retries=3, # Optional, max retry attempts (default: 3)
160
+ )
161
+ ```
162
+
163
+ The SDK handles authentication via the `Authorization: Bearer` header.
164
+
165
+ ## API Reference
166
+
167
+ ### Memory Operations
168
+
169
+ #### Create Memory
170
+
171
+ ```python
172
+ from sovant import MemoryCreate
173
+
174
+ memory = client.memory_create(MemoryCreate(
175
+ data="Customer contacted support about billing",
176
+ type="observation", # 'journal' | 'insight' | 'observation' | 'task' | 'preference'
177
+ tags=["support", "billing"],
178
+ metadata={"ticket_id": "12345"},
179
+ thread_id="thread_abc123", # Optional thread association
180
+ ))
181
+ ```
182
+
183
+ #### Get Memory by ID
184
+
185
+ ```python
186
+ memory = client.memory_get("mem_123abc")
187
+ ```
188
+
189
+ #### Update Memory
190
+
191
+ ```python
192
+ updated = client.memory_update("mem_123abc", {
193
+ "tags": ["support", "billing", "resolved"],
194
+ })
195
+ ```
196
+
197
+ #### Delete Memory
198
+
199
+ ```python
200
+ client.memory_delete("mem_123abc")
201
+ ```
202
+
203
+ #### Search Memories
204
+
205
+ ```python
206
+ from sovant import SearchQuery
207
+
208
+ # Semantic search
209
+ results = client.memory_search(SearchQuery(
210
+ query="customer preferences about notifications",
211
+ limit=10,
212
+ type="preference",
213
+ ))
214
+
215
+ # Filter-based search
216
+ results = client.memory_search(SearchQuery(
217
+ tags=["settings", "notifications"],
218
+ from_date="2024-01-01",
219
+ to_date="2024-12-31",
220
+ limit=20,
221
+ ))
222
+ ```
223
+
224
+ #### Recall Memories
225
+
226
+ Recall returns `{ "results": [...], "total": N, "query_type": "hybrid" }`.
227
+
228
+ ```python
229
+ # Hybrid recall with profile awareness
230
+ recall = client.memory_recall(
231
+ query="what do you know about me?",
232
+ limit=10,
233
+ )
234
+ for mem in recall.get("results", []):
235
+ print(mem["content"], mem.get("relevance"))
236
+
237
+ # Thread-scoped recall
238
+ recall = client.memory_recall(
239
+ query="launch timeline",
240
+ thread_id="thread_abc123",
241
+ limit=5,
242
+ )
243
+ ```
244
+
245
+ #### Batch Create
246
+
247
+ ```python
248
+ results = client.memory_create_batch([
249
+ {"data": "First memory", "type": "journal"},
250
+ {"data": "Second memory", "type": "insight", "tags": ["important"]},
251
+ ])
252
+ ```
253
+
254
+ #### List Memories
255
+
256
+ Fetch memories with filtering and pagination. Use `memory_list()` to retrieve recent memories or filter by criteria — it's more efficient than `memory_search()` when you don't need vector similarity.
257
+
258
+ ```python
259
+ # List recent memories
260
+ result = client.memory_list(limit=20, offset=0)
261
+ for mem in result["memories"]:
262
+ print(mem["content"])
263
+
264
+ # Filter by thread
265
+ thread_mems = client.memory_list(thread_id="thread-uuid", limit=50)
266
+
267
+ # Filter by type and tags
268
+ prefs = client.memory_list(
269
+ type="preference",
270
+ tags=["settings"],
271
+ sort_by="updated_at",
272
+ sort_order="desc",
273
+ )
274
+
275
+ # Pinned memories only
276
+ pinned = client.memory_list(is_pinned=True)
277
+ ```
278
+
279
+ **Available parameters:**
280
+ - `limit` — max results (default: 20, max: 100)
281
+ - `offset` — pagination offset
282
+ - `thread_id` — filter by thread
283
+ - `type` — filter by memory type
284
+ - `tags` — filter by tags (must have all)
285
+ - `is_pinned` — filter by pinned status
286
+ - `is_archived` — filter by archived status
287
+ - `sort_by` — `created_at`, `updated_at`, `importance`, or `type`
288
+ - `sort_order` — `asc` or `desc`
289
+
290
+ ### Thread Management
291
+
292
+ ```python
293
+ # Create a thread
294
+ thread = client.threads_create(
295
+ title="Customer Support Session",
296
+ metadata={"user_id": "user_123"},
297
+ )
298
+
299
+ # List threads
300
+ threads = client.threads_list(limit=10, offset=0)
301
+
302
+ # Get thread by ID (with memories)
303
+ thread = client.threads_get("thread_abc123", include_memories=True)
304
+
305
+ # Update thread
306
+ updated = client.threads_update(
307
+ "thread_abc123",
308
+ title="Resolved: Billing Issue",
309
+ status="completed",
310
+ )
311
+
312
+ # Delete thread
313
+ client.threads_delete("thread_abc123")
314
+ ```
315
+
316
+ ## Memory Types
317
+
318
+ - **journal** -- Chronological entries and logs
319
+ - **insight** -- Derived patterns and conclusions
320
+ - **observation** -- Factual, observed information
321
+ - **task** -- Action items and todos
322
+ - **preference** -- User preferences and settings
323
+
324
+ ## Error Handling
325
+
326
+ The SDK raises `SovantError` for all API errors:
327
+
328
+ ```python
329
+ from sovant import Sovant, SovantError
330
+
331
+ try:
332
+ memory = client.memory_get("invalid_id")
333
+ except SovantError as e:
334
+ print(f"Error: {e}")
335
+ print(f"Code: {e.code}") # e.g. "NOT_FOUND", "HTTP_401"
336
+ print(f"Status: {e.status}") # e.g. 404, 401
337
+
338
+ if e.status == 404:
339
+ print("Memory not found")
340
+ elif e.status == 401:
341
+ print("Invalid API key")
342
+ elif e.status == 429:
343
+ print("Rate limited -- SDK retries automatically")
344
+ ```
345
+
346
+ The SDK automatically retries on rate limit (429) and server errors (5xx) with exponential backoff.
347
+
348
+ ## Examples
349
+
350
+ ### Customer Support Integration
351
+
352
+ ```python
353
+ from sovant import MemoryCreate
354
+
355
+ # Track customer interaction
356
+ interaction = client.memory_create(MemoryCreate(
357
+ data="Customer reported slow dashboard loading",
358
+ type="observation",
359
+ thread_id=f"ticket_{ticket_id}",
360
+ tags=["support", "performance", "dashboard"],
361
+ metadata={
362
+ "ticket_id": ticket_id,
363
+ "priority": "high",
364
+ },
365
+ ))
366
+
367
+ # Record resolution
368
+ resolution = client.memory_create(MemoryCreate(
369
+ data="Resolved by clearing cache and upgrading plan",
370
+ type="insight",
371
+ thread_id=f"ticket_{ticket_id}",
372
+ tags=["support", "resolved"],
373
+ ))
374
+ ```
375
+
376
+ ### User Preference Tracking
377
+
378
+ ```python
379
+ from sovant import MemoryCreate, SearchQuery
380
+
381
+ # Store preference
382
+ client.memory_create(MemoryCreate(
383
+ data="User prefers email notifications over SMS",
384
+ type="preference",
385
+ tags=["notifications", "email"],
386
+ ))
387
+
388
+ # Query preferences
389
+ preferences = client.memory_search(SearchQuery(
390
+ query="notification preferences",
391
+ type="preference",
392
+ ))
393
+ ```
394
+
395
+ ## Rate Limiting
396
+
397
+ The API enforces 60 requests per minute. The SDK automatically retries rate-limited requests with exponential backoff. Rate limit headers are included in responses:
398
+
399
+ - `X-RateLimit-Limit` -- Request limit per window
400
+ - `X-RateLimit-Remaining` -- Remaining requests
401
+ - `X-RateLimit-Reset` -- Reset timestamp
402
+
403
+ ## Support
404
+
405
+ - Documentation: [https://sovant.ai/docs](https://sovant.ai/docs)
406
+ - Issues: [GitHub Issues](https://github.com/hechin91/sovant-ai/issues)
407
+
408
+ ## License & Use
409
+
410
+ - This SDK is MIT-licensed for integration convenience.
411
+ - The Sovant API and platform are proprietary to Sovant Technologies Sdn. Bhd.
412
+ - You may use this SDK to integrate with Sovant's hosted API.
413
+ - Hosting/redistributing the Sovant backend or any proprietary components is not permitted.
414
+
415
+ ## License
416
+
417
+ MIT -- See [LICENSE](LICENSE) file for details.