memside 0.2.0__tar.gz → 0.3.0__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.
memside-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.4
2
+ Name: memside
3
+ Version: 0.3.0
4
+ Summary: Python client for Memside AI continuity, portable context, checkpoints, operating rules, User AI Profile, and AI Skills.
5
+ Author-email: Memside <support@memside.com>
6
+ License-Expression: LicenseRef-Proprietary
7
+ Project-URL: Homepage, https://github.com/memside/memside
8
+ Project-URL: Repository, https://github.com/memside/memside
9
+ Project-URL: Issues, https://github.com/memside/memside/issues
10
+ Keywords: memside,ai,memory,mcp,sdk
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE.md
22
+ Dynamic: license-file
23
+
24
+ # Memside Python SDK
25
+
26
+ Python client for Memside AI continuity, portable context, checkpoints, operating rules, User AI Profile, and AI Skills.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install memside
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```python
37
+ from memside import MemsideClient
38
+
39
+ client = MemsideClient(api_key="mem_sk_your_key_here")
40
+
41
+ startup = client.context_startup()
42
+ print(startup)
43
+ ```
44
+
45
+ Create a memory with the public `type` and `text` fields:
46
+
47
+ ```python
48
+ memory = client.memories_create(
49
+ {
50
+ "type": "note",
51
+ "text": "Packing checklist\nBring a charger and a reusable bottle.",
52
+ "sensitivity": "private",
53
+ }
54
+ )
55
+ ```
56
+
57
+ Use the current version when updating a Memory you previously read:
58
+
59
+ ```python
60
+ updated = client.memories_update(
61
+ memory["id"],
62
+ {
63
+ "text": "Packing checklist\nBring a charger and a reusable bottle.",
64
+ "expected_version": memory["version"],
65
+ },
66
+ )
67
+ ```
68
+
69
+ Create a Subject and link a non-secret memory:
70
+
71
+ ```python
72
+ subject = client.subjects_create(
73
+ {
74
+ "name": "Weekend reading",
75
+ "subject_type": "topic",
76
+ "aliases": ["Reading list"],
77
+ }
78
+ )
79
+
80
+ client.subjects_link_memory(subject["id"], memory["id"])
81
+ context = client.subjects_get_context(subject["id"])
82
+ ```
83
+
84
+ Read eligible Facts and propose a source-backed addition for user review:
85
+
86
+ ```python
87
+ facts = client.subjects_list_facts(subject["id"])
88
+
89
+ suggestion = client.subjects_suggest_fact(
90
+ subject["id"],
91
+ {
92
+ "suggestion_type": "add_fact",
93
+ "proposed_fact_type": "preference",
94
+ "proposed_fact_text": (
95
+ "Prefers printed books for long-form reading."
96
+ ),
97
+ "source_memory_id": memory["id"],
98
+ "idempotency_key": "reading-preference-v1",
99
+ },
100
+ )
101
+ ```
102
+
103
+ Fact Suggestions remain pending until a signed-in user reviews them. The SDK
104
+ does not expose direct Fact mutation or suggestion review.
105
+
106
+ Read a bounded Context Map and pending Memory Insights:
107
+
108
+ ```python
109
+ context_map = client.memories_get_context_map(memory["id"])
110
+ history = client.memories_get_revisions(memory["id"])
111
+ insights = client.subjects_list_memory_insights(
112
+ subject["id"],
113
+ limit=25,
114
+ )
115
+ ```
116
+
117
+ Insight refresh, review, and undo remain signed-in application actions.
118
+
119
+ Prepare Subject deletion without changing data:
120
+
121
+ ```python
122
+ preview = client.subjects_prepare_delete(subject["id"])
123
+ print(preview["required_confirmation"])
124
+ ```
125
+
126
+ The SDK does not generate or submit Subject deletion confirmation
127
+ automatically.
128
+
129
+ Deletion requires the resource-specific confirmation returned by your
130
+ application workflow:
131
+
132
+ ```python
133
+ client.memories_delete(
134
+ memory["id"],
135
+ f"CONFIRM_DELETE_{memory['id']}",
136
+ )
137
+ ```
138
+
139
+ You can also set the API key through the environment:
140
+
141
+ ```bash
142
+ MEMSIDE_API_KEY=mem_sk_your_key_here
143
+ ```
144
+
145
+ ## Supported API Areas
146
+
147
+ This package wraps public Memside API-key routes:
148
+
149
+ - startup context
150
+ - resume context
151
+ - workspace profile
152
+ - memory listing
153
+ - memory search
154
+ - memory fetch
155
+ - memory revision history
156
+ - bounded exact-ID memory batch reads
157
+ - bounded memory Context Maps
158
+ - memory create
159
+ - memory update
160
+ - memory delete, when allowed by the API
161
+ - Subject listing, creation, retrieval, and update
162
+ - Subject-memory listing, linking, and unlinking
163
+ - bounded Subject Context
164
+ - eligible Subject Fact reads
165
+ - source-backed Fact Suggestions for signed-in-user review
166
+ - pending-only Memory Insight reads
167
+ - guarded Subject deletion preparation and confirmation
168
+
169
+ This package does not include private Memside application source, account/session internals, billing internals, admin routes, database details, or MCP server implementation.
170
+
171
+ ## API Reference
172
+
173
+ | Area | Methods |
174
+ | --- | --- |
175
+ | Context | `context_startup`, `context_resume`, `context_workspace_profile` |
176
+ | Memories | `memories_list`, `memories_search`, `memories_get`, `memories_get_batch`, `memories_get_revisions`, `memories_get_context_map`, `memories_list_subjects`, `memories_create`, `memories_update`, `memories_delete` |
177
+ | Subjects | `subjects_list`, `subjects_create`, `subjects_get`, `subjects_update`, `subjects_list_memories`, `subjects_link_memory`, `subjects_unlink_memory`, `subjects_get_context`, `subjects_list_facts`, `subjects_suggest_fact`, `subjects_list_memory_insights`, `subjects_prepare_delete`, `subjects_delete` |
178
+
179
+ See the curated
180
+ [OpenAPI document](https://raw.githubusercontent.com/memside/memside/main/openapi.json)
181
+ for public request and response fields.
182
+
183
+ Public request and response shapes are exported as lightweight `TypedDict`
184
+ definitions for editors and type checkers. Failed requests raise
185
+ `MemsideError`, including `status`, `code`, `retryable`, `retry_after`,
186
+ `request_id`, and safe `details`.
187
+
188
+ For `429` responses, wait for `retry_after` before retrying a read. The SDK
189
+ does not automatically retry writes.
190
+
191
+ Eligible responses contain attachment metadata only. Raw attachment data,
192
+ private storage locations, and signed download URLs are not returned through
193
+ the public API-key contract.
194
+
195
+ ## Compatibility
196
+
197
+ The package uses additive public methods and typed fields where possible.
198
+ Breaking changes require a documented migration path. The client accepts the
199
+ current public error envelope and documented legacy `detail` responses during
200
+ the V2 compatibility period.
201
+
202
+ ## Requirements
203
+
204
+ Python 3.9 or newer.
@@ -0,0 +1,181 @@
1
+ # Memside Python SDK
2
+
3
+ Python client for Memside AI continuity, portable context, checkpoints, operating rules, User AI Profile, and AI Skills.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install memside
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from memside import MemsideClient
15
+
16
+ client = MemsideClient(api_key="mem_sk_your_key_here")
17
+
18
+ startup = client.context_startup()
19
+ print(startup)
20
+ ```
21
+
22
+ Create a memory with the public `type` and `text` fields:
23
+
24
+ ```python
25
+ memory = client.memories_create(
26
+ {
27
+ "type": "note",
28
+ "text": "Packing checklist\nBring a charger and a reusable bottle.",
29
+ "sensitivity": "private",
30
+ }
31
+ )
32
+ ```
33
+
34
+ Use the current version when updating a Memory you previously read:
35
+
36
+ ```python
37
+ updated = client.memories_update(
38
+ memory["id"],
39
+ {
40
+ "text": "Packing checklist\nBring a charger and a reusable bottle.",
41
+ "expected_version": memory["version"],
42
+ },
43
+ )
44
+ ```
45
+
46
+ Create a Subject and link a non-secret memory:
47
+
48
+ ```python
49
+ subject = client.subjects_create(
50
+ {
51
+ "name": "Weekend reading",
52
+ "subject_type": "topic",
53
+ "aliases": ["Reading list"],
54
+ }
55
+ )
56
+
57
+ client.subjects_link_memory(subject["id"], memory["id"])
58
+ context = client.subjects_get_context(subject["id"])
59
+ ```
60
+
61
+ Read eligible Facts and propose a source-backed addition for user review:
62
+
63
+ ```python
64
+ facts = client.subjects_list_facts(subject["id"])
65
+
66
+ suggestion = client.subjects_suggest_fact(
67
+ subject["id"],
68
+ {
69
+ "suggestion_type": "add_fact",
70
+ "proposed_fact_type": "preference",
71
+ "proposed_fact_text": (
72
+ "Prefers printed books for long-form reading."
73
+ ),
74
+ "source_memory_id": memory["id"],
75
+ "idempotency_key": "reading-preference-v1",
76
+ },
77
+ )
78
+ ```
79
+
80
+ Fact Suggestions remain pending until a signed-in user reviews them. The SDK
81
+ does not expose direct Fact mutation or suggestion review.
82
+
83
+ Read a bounded Context Map and pending Memory Insights:
84
+
85
+ ```python
86
+ context_map = client.memories_get_context_map(memory["id"])
87
+ history = client.memories_get_revisions(memory["id"])
88
+ insights = client.subjects_list_memory_insights(
89
+ subject["id"],
90
+ limit=25,
91
+ )
92
+ ```
93
+
94
+ Insight refresh, review, and undo remain signed-in application actions.
95
+
96
+ Prepare Subject deletion without changing data:
97
+
98
+ ```python
99
+ preview = client.subjects_prepare_delete(subject["id"])
100
+ print(preview["required_confirmation"])
101
+ ```
102
+
103
+ The SDK does not generate or submit Subject deletion confirmation
104
+ automatically.
105
+
106
+ Deletion requires the resource-specific confirmation returned by your
107
+ application workflow:
108
+
109
+ ```python
110
+ client.memories_delete(
111
+ memory["id"],
112
+ f"CONFIRM_DELETE_{memory['id']}",
113
+ )
114
+ ```
115
+
116
+ You can also set the API key through the environment:
117
+
118
+ ```bash
119
+ MEMSIDE_API_KEY=mem_sk_your_key_here
120
+ ```
121
+
122
+ ## Supported API Areas
123
+
124
+ This package wraps public Memside API-key routes:
125
+
126
+ - startup context
127
+ - resume context
128
+ - workspace profile
129
+ - memory listing
130
+ - memory search
131
+ - memory fetch
132
+ - memory revision history
133
+ - bounded exact-ID memory batch reads
134
+ - bounded memory Context Maps
135
+ - memory create
136
+ - memory update
137
+ - memory delete, when allowed by the API
138
+ - Subject listing, creation, retrieval, and update
139
+ - Subject-memory listing, linking, and unlinking
140
+ - bounded Subject Context
141
+ - eligible Subject Fact reads
142
+ - source-backed Fact Suggestions for signed-in-user review
143
+ - pending-only Memory Insight reads
144
+ - guarded Subject deletion preparation and confirmation
145
+
146
+ This package does not include private Memside application source, account/session internals, billing internals, admin routes, database details, or MCP server implementation.
147
+
148
+ ## API Reference
149
+
150
+ | Area | Methods |
151
+ | --- | --- |
152
+ | Context | `context_startup`, `context_resume`, `context_workspace_profile` |
153
+ | Memories | `memories_list`, `memories_search`, `memories_get`, `memories_get_batch`, `memories_get_revisions`, `memories_get_context_map`, `memories_list_subjects`, `memories_create`, `memories_update`, `memories_delete` |
154
+ | Subjects | `subjects_list`, `subjects_create`, `subjects_get`, `subjects_update`, `subjects_list_memories`, `subjects_link_memory`, `subjects_unlink_memory`, `subjects_get_context`, `subjects_list_facts`, `subjects_suggest_fact`, `subjects_list_memory_insights`, `subjects_prepare_delete`, `subjects_delete` |
155
+
156
+ See the curated
157
+ [OpenAPI document](https://raw.githubusercontent.com/memside/memside/main/openapi.json)
158
+ for public request and response fields.
159
+
160
+ Public request and response shapes are exported as lightweight `TypedDict`
161
+ definitions for editors and type checkers. Failed requests raise
162
+ `MemsideError`, including `status`, `code`, `retryable`, `retry_after`,
163
+ `request_id`, and safe `details`.
164
+
165
+ For `429` responses, wait for `retry_after` before retrying a read. The SDK
166
+ does not automatically retry writes.
167
+
168
+ Eligible responses contain attachment metadata only. Raw attachment data,
169
+ private storage locations, and signed download URLs are not returned through
170
+ the public API-key contract.
171
+
172
+ ## Compatibility
173
+
174
+ The package uses additive public methods and typed fields where possible.
175
+ Breaking changes require a documented migration path. The client accepts the
176
+ current public error envelope and documented legacy `detail` responses during
177
+ the V2 compatibility period.
178
+
179
+ ## Requirements
180
+
181
+ Python 3.9 or newer.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memside"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Python client for Memside AI continuity, portable context, checkpoints, operating rules, User AI Profile, and AI Skills."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,70 @@
1
+ from .client import MemsideClient, MemsideError
2
+ from .connected_context_types import (
3
+ ContextMap,
4
+ ContextMapMemoryNode,
5
+ MemoryInsight,
6
+ MemoryInsightEvidence,
7
+ MemoryInsightList,
8
+ )
9
+ from .subject_types import (
10
+ FactSuggestion,
11
+ FactSuggestionCreate,
12
+ FactType,
13
+ Subject,
14
+ SubjectContext,
15
+ SubjectCreate,
16
+ SubjectDeleteResult,
17
+ SubjectDeletionPreview,
18
+ SubjectFact,
19
+ SubjectFactList,
20
+ SubjectMemory,
21
+ SubjectMemoryLinkResult,
22
+ SubjectMemoryUnlinkResult,
23
+ SubjectUpdate,
24
+ )
25
+ from .types import (
26
+ Memory,
27
+ MemoryBatchResult,
28
+ MemoryCreate,
29
+ MemoryDeleteResult,
30
+ MemoryRevision,
31
+ MemoryRevisionList,
32
+ MemoryUpdate,
33
+ ResumeContext,
34
+ StartupContext,
35
+ WorkspaceProfile,
36
+ )
37
+
38
+ __all__ = [
39
+ "MemsideClient",
40
+ "MemsideError",
41
+ "ContextMap",
42
+ "ContextMapMemoryNode",
43
+ "FactSuggestion",
44
+ "FactSuggestionCreate",
45
+ "FactType",
46
+ "Subject",
47
+ "SubjectContext",
48
+ "SubjectCreate",
49
+ "SubjectDeleteResult",
50
+ "SubjectDeletionPreview",
51
+ "SubjectFact",
52
+ "SubjectFactList",
53
+ "SubjectMemory",
54
+ "SubjectMemoryLinkResult",
55
+ "SubjectMemoryUnlinkResult",
56
+ "SubjectUpdate",
57
+ "Memory",
58
+ "MemoryBatchResult",
59
+ "MemoryCreate",
60
+ "MemoryDeleteResult",
61
+ "MemoryRevision",
62
+ "MemoryRevisionList",
63
+ "MemoryUpdate",
64
+ "MemoryInsight",
65
+ "MemoryInsightEvidence",
66
+ "MemoryInsightList",
67
+ "ResumeContext",
68
+ "StartupContext",
69
+ "WorkspaceProfile",
70
+ ]
@@ -3,14 +3,30 @@ import os
3
3
  from typing import Iterable, List, Optional
4
4
  from urllib.error import HTTPError
5
5
  from urllib.parse import urlencode
6
- from urllib.request import Request, urlopen
7
-
8
- from .types import (
6
+ from urllib.request import Request, urlopen
7
+
8
+ from .connected_context_types import ContextMap, MemoryInsightList
9
+ from .subject_types import (
10
+ FactSuggestion,
11
+ FactSuggestionCreate,
12
+ Subject,
13
+ SubjectContext,
14
+ SubjectCreate,
15
+ SubjectDeleteResult,
16
+ SubjectDeletionPreview,
17
+ SubjectMemory,
18
+ SubjectMemoryLinkResult,
19
+ SubjectMemoryUnlinkResult,
20
+ SubjectFactList,
21
+ SubjectUpdate,
22
+ )
23
+ from .types import (
9
24
  Memory,
10
25
  MemoryBatchResult,
11
26
  MemoryCreate,
12
- MemoryDeleteResult,
13
- MemoryUpdate,
27
+ MemoryDeleteResult,
28
+ MemoryRevisionList,
29
+ MemoryUpdate,
14
30
  ResumeContext,
15
31
  StartupContext,
16
32
  WorkspaceProfile,
@@ -70,9 +86,18 @@ class MemsideClient:
70
86
  def memories_search(self, **params) -> List[Memory]:
71
87
  return self.request("GET", "/memories/search", params=params)
72
88
 
73
- def memories_get(self, memory_id: str) -> Memory:
74
- return self.request("GET", f"/memories/{memory_id}")
75
-
89
+ def memories_get(self, memory_id: str) -> Memory:
90
+ return self.request("GET", f"/memories/{memory_id}")
91
+
92
+ def memories_get_revisions(self, memory_id: str) -> MemoryRevisionList:
93
+ return self.request("GET", f"/memories/{memory_id}/revisions")
94
+
95
+ def memories_get_context_map(self, memory_id: str) -> ContextMap:
96
+ return self.request("GET", f"/memories/{memory_id}/context-map")
97
+
98
+ def memories_list_subjects(self, memory_id: str) -> List[Subject]:
99
+ return self.request("GET", f"/memories/{memory_id}/subjects")
100
+
76
101
  def memories_get_batch(
77
102
  self,
78
103
  memory_ids: Iterable[str],
@@ -103,12 +128,127 @@ class MemsideClient:
103
128
  if delete_confirmation is not None
104
129
  else None
105
130
  )
106
- return self.request(
107
- "DELETE",
108
- f"/memories/{memory_id}",
109
- json_body=body,
110
- )
111
-
131
+ return self.request(
132
+ "DELETE",
133
+ f"/memories/{memory_id}",
134
+ json_body=body,
135
+ )
136
+
137
+ def subjects_list(self, **params) -> List[Subject]:
138
+ return self.request("GET", "/subjects", params=params)
139
+
140
+ def subjects_create(self, subject: SubjectCreate) -> Subject:
141
+ return self.request("POST", "/subjects", json_body=subject)
142
+
143
+ def subjects_get(self, subject_id: str) -> Subject:
144
+ return self.request("GET", f"/subjects/{subject_id}")
145
+
146
+ def subjects_update(self, subject_id: str, patch: SubjectUpdate) -> Subject:
147
+ return self.request("PATCH", f"/subjects/{subject_id}", json_body=patch)
148
+
149
+ def subjects_list_memories(
150
+ self,
151
+ subject_id: str,
152
+ *,
153
+ include_archived: bool = False,
154
+ limit: int = 20,
155
+ ) -> List[SubjectMemory]:
156
+ return self.request(
157
+ "GET",
158
+ f"/subjects/{subject_id}/memories",
159
+ params={"include_archived": include_archived, "limit": limit},
160
+ )
161
+
162
+ def subjects_link_memory(
163
+ self,
164
+ subject_id: str,
165
+ memory_id: str,
166
+ ) -> SubjectMemoryLinkResult:
167
+ return self.request(
168
+ "POST",
169
+ f"/subjects/{subject_id}/memories",
170
+ json_body={"memory_id": memory_id},
171
+ )
172
+
173
+ def subjects_unlink_memory(
174
+ self,
175
+ subject_id: str,
176
+ memory_id: str,
177
+ ) -> SubjectMemoryUnlinkResult:
178
+ return self.request(
179
+ "DELETE",
180
+ f"/subjects/{subject_id}/memories/{memory_id}",
181
+ )
182
+
183
+ def subjects_get_context(
184
+ self,
185
+ subject_id: str,
186
+ **params,
187
+ ) -> SubjectContext:
188
+ return self.request(
189
+ "GET",
190
+ f"/subjects/{subject_id}/context",
191
+ params=params,
192
+ )
193
+
194
+ def subjects_list_facts(
195
+ self,
196
+ subject_id: str,
197
+ *,
198
+ include_history: bool = False,
199
+ limit: int = 50,
200
+ ) -> SubjectFactList:
201
+ return self.request(
202
+ "GET",
203
+ f"/subjects/{subject_id}/facts",
204
+ params={"include_history": include_history, "limit": limit},
205
+ )
206
+
207
+ def subjects_suggest_fact(
208
+ self,
209
+ subject_id: str,
210
+ suggestion: FactSuggestionCreate,
211
+ ) -> FactSuggestion:
212
+ return self.request(
213
+ "POST",
214
+ f"/subjects/{subject_id}/fact-suggestions",
215
+ json_body=suggestion,
216
+ )
217
+
218
+ def subjects_list_memory_insights(
219
+ self,
220
+ subject_id: str,
221
+ *,
222
+ limit: int = 50,
223
+ ) -> MemoryInsightList:
224
+ return self.request(
225
+ "GET",
226
+ f"/subjects/{subject_id}/memory-insights",
227
+ params={"status": "pending", "limit": limit},
228
+ )
229
+
230
+ def subjects_prepare_delete(self, subject_id: str) -> SubjectDeletionPreview:
231
+ return self.request(
232
+ "POST",
233
+ f"/subjects/{subject_id}/deletion/prepare",
234
+ )
235
+
236
+ def subjects_delete(
237
+ self,
238
+ subject_id: str,
239
+ delete_confirmation: Optional[str] = None,
240
+ ) -> SubjectDeleteResult:
241
+ body = (
242
+ {"delete_confirmation": delete_confirmation}
243
+ if delete_confirmation is not None
244
+ else None
245
+ )
246
+ return self.request(
247
+ "DELETE",
248
+ f"/subjects/{subject_id}",
249
+ json_body=body,
250
+ )
251
+
112
252
  def request(self, method, path, *, params=None, json_body=None, headers=None):
113
253
  url = self._build_url(path, params)
114
254
  request_headers = {