cuemap 0.2.2__tar.gz → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuemap
3
- Version: 0.2.2
3
+ Version: 0.4.0
4
4
  Summary: Redis for AI Agents - High-performance temporal-associative memory
5
5
  Author-email: CueMap Team <hello@cuemap.dev>
6
6
  License: MIT
@@ -98,6 +98,7 @@ memory_id = client.add(
98
98
  ### Recall Memories
99
99
 
100
100
  ```python
101
+ # OR logic (default): matches any cue
101
102
  results = client.recall(
102
103
  cues=["meeting", "john"],
103
104
  limit=10
@@ -105,6 +106,18 @@ results = client.recall(
105
106
 
106
107
  for result in results:
107
108
  print(f"{result.content} (score: {result.score})")
109
+
110
+ # AND logic: requires all cues to match
111
+ results = client.recall(
112
+ cues=["meeting", "john"],
113
+ min_intersection=2 # Both cues must match
114
+ )
115
+
116
+ # Cross-domain query (multi-tenant mode)
117
+ results = client.recall(
118
+ cues=["urgent"],
119
+ projects=["sales", "support", "engineering"]
120
+ )
108
121
  ```
109
122
 
110
123
  ### Reinforce Memory
@@ -63,6 +63,7 @@ memory_id = client.add(
63
63
  ### Recall Memories
64
64
 
65
65
  ```python
66
+ # OR logic (default): matches any cue
66
67
  results = client.recall(
67
68
  cues=["meeting", "john"],
68
69
  limit=10
@@ -70,6 +71,18 @@ results = client.recall(
70
71
 
71
72
  for result in results:
72
73
  print(f"{result.content} (score: {result.score})")
74
+
75
+ # AND logic: requires all cues to match
76
+ results = client.recall(
77
+ cues=["meeting", "john"],
78
+ min_intersection=2 # Both cues must match
79
+ )
80
+
81
+ # Cross-domain query (multi-tenant mode)
82
+ results = client.recall(
83
+ cues=["urgent"],
84
+ projects=["sales", "support", "engineering"]
85
+ )
73
86
  ```
74
87
 
75
88
  ### Reinforce Memory
@@ -48,14 +48,10 @@ class CueMap:
48
48
  """Get request headers."""
49
49
  headers = {}
50
50
  if self.api_key:
51
- headers["x-api-key"] = self.api_key
52
- return headers
53
-
54
- def _endpoint(self, path: str) -> str:
55
- """Get endpoint with optional project_id."""
51
+ headers["X-API-Key"] = self.api_key
56
52
  if self.project_id:
57
- return f"/v1/{self.project_id}{path}"
58
- return path
53
+ headers["X-Project-ID"] = self.project_id
54
+ return headers
59
55
 
60
56
  def add(
61
57
  self,
@@ -81,7 +77,7 @@ class CueMap:
81
77
  ... )
82
78
  """
83
79
  response = self.client.post(
84
- self._endpoint("/memories"),
80
+ "/memories",
85
81
  json={
86
82
  "content": content,
87
83
  "cues": cues,
@@ -101,7 +97,9 @@ class CueMap:
101
97
  self,
102
98
  cues: List[str],
103
99
  limit: int = 10,
104
- auto_reinforce: bool = False
100
+ auto_reinforce: bool = False,
101
+ min_intersection: Optional[int] = None,
102
+ projects: Optional[List[str]] = None
105
103
  ) -> List[RecallResult]:
106
104
  """
107
105
  Recall memories by cues.
@@ -110,22 +108,37 @@ class CueMap:
110
108
  cues: List of cues to search for
111
109
  limit: Maximum results to return
112
110
  auto_reinforce: Automatically reinforce retrieved memories
111
+ min_intersection: Minimum number of cues that must match (for strict AND logic)
112
+ projects: List of project IDs for cross-domain queries (multi-tenant only)
113
113
 
114
114
  Returns:
115
115
  List of recall results
116
116
 
117
117
  Example:
118
+ >>> # OR logic (default): matches any cue
118
119
  >>> results = client.recall(["meeting", "john"])
119
- >>> for r in results:
120
- ... print(r.content)
120
+
121
+ >>> # AND logic: requires both cues
122
+ >>> results = client.recall(["meeting", "john"], min_intersection=2)
123
+
124
+ >>> # Cross-domain query (multi-tenant)
125
+ >>> results = client.recall(["urgent"], projects=["sales", "support"])
121
126
  """
127
+ payload = {
128
+ "cues": cues,
129
+ "limit": limit,
130
+ "auto_reinforce": auto_reinforce
131
+ }
132
+
133
+ if min_intersection is not None:
134
+ payload["min_intersection"] = min_intersection
135
+
136
+ if projects is not None:
137
+ payload["projects"] = projects
138
+
122
139
  response = self.client.post(
123
- self._endpoint("/recall"),
124
- json={
125
- "cues": cues,
126
- "limit": limit,
127
- "auto_reinforce": auto_reinforce
128
- },
140
+ "/recall",
141
+ json=payload,
129
142
  headers=self._headers()
130
143
  )
131
144
 
@@ -147,7 +160,7 @@ class CueMap:
147
160
  Success status
148
161
  """
149
162
  response = self.client.patch(
150
- self._endpoint(f"/memories/{memory_id}/reinforce"),
163
+ f"/memories/{memory_id}/reinforce",
151
164
  json={"cues": cues},
152
165
  headers=self._headers()
153
166
  )
@@ -157,7 +170,7 @@ class CueMap:
157
170
  def get(self, memory_id: str) -> Memory:
158
171
  """Get a memory by ID."""
159
172
  response = self.client.get(
160
- self._endpoint(f"/memories/{memory_id}"),
173
+ f"/memories/{memory_id}",
161
174
  headers=self._headers()
162
175
  )
163
176
 
@@ -171,7 +184,7 @@ class CueMap:
171
184
  def stats(self) -> Dict[str, Any]:
172
185
  """Get server statistics."""
173
186
  response = self.client.get(
174
- self._endpoint("/stats"),
187
+ "/stats",
175
188
  headers=self._headers()
176
189
  )
177
190
 
@@ -217,13 +230,10 @@ class AsyncCueMap:
217
230
  def _headers(self) -> Dict[str, str]:
218
231
  headers = {}
219
232
  if self.api_key:
220
- headers["x-api-key"] = self.api_key
221
- return headers
222
-
223
- def _endpoint(self, path: str) -> str:
233
+ headers["X-API-Key"] = self.api_key
224
234
  if self.project_id:
225
- return f"/v1/{self.project_id}{path}"
226
- return path
235
+ headers["X-Project-ID"] = self.project_id
236
+ return headers
227
237
 
228
238
  async def add(
229
239
  self,
@@ -233,7 +243,7 @@ class AsyncCueMap:
233
243
  ) -> str:
234
244
  """Add a memory (async)."""
235
245
  response = await self.client.post(
236
- self._endpoint("/memories"),
246
+ "/memories",
237
247
  json={
238
248
  "content": content,
239
249
  "cues": cues,
@@ -253,16 +263,26 @@ class AsyncCueMap:
253
263
  self,
254
264
  cues: List[str],
255
265
  limit: int = 10,
256
- auto_reinforce: bool = False
266
+ auto_reinforce: bool = False,
267
+ min_intersection: Optional[int] = None,
268
+ projects: Optional[List[str]] = None
257
269
  ) -> List[RecallResult]:
258
270
  """Recall memories (async)."""
271
+ payload = {
272
+ "cues": cues,
273
+ "limit": limit,
274
+ "auto_reinforce": auto_reinforce
275
+ }
276
+
277
+ if min_intersection is not None:
278
+ payload["min_intersection"] = min_intersection
279
+
280
+ if projects is not None:
281
+ payload["projects"] = projects
282
+
259
283
  response = await self.client.post(
260
- self._endpoint("/recall"),
261
- json={
262
- "cues": cues,
263
- "limit": limit,
264
- "auto_reinforce": auto_reinforce
265
- },
284
+ "/recall",
285
+ json=payload,
266
286
  headers=self._headers()
267
287
  )
268
288
 
@@ -275,7 +295,7 @@ class AsyncCueMap:
275
295
  async def reinforce(self, memory_id: str, cues: List[str]) -> bool:
276
296
  """Reinforce a memory (async)."""
277
297
  response = await self.client.patch(
278
- self._endpoint(f"/memories/{memory_id}/reinforce"),
298
+ f"/memories/{memory_id}/reinforce",
279
299
  json={"cues": cues},
280
300
  headers=self._headers()
281
301
  )
@@ -285,7 +305,7 @@ class AsyncCueMap:
285
305
  async def get(self, memory_id: str) -> Memory:
286
306
  """Get a memory by ID (async)."""
287
307
  response = await self.client.get(
288
- self._endpoint(f"/memories/{memory_id}"),
308
+ f"/memories/{memory_id}",
289
309
  headers=self._headers()
290
310
  )
291
311
 
@@ -299,7 +319,7 @@ class AsyncCueMap:
299
319
  async def stats(self) -> Dict[str, Any]:
300
320
  """Get server statistics (async)."""
301
321
  response = await self.client.get(
302
- self._endpoint("/stats"),
322
+ "/stats",
303
323
  headers=self._headers()
304
324
  )
305
325
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuemap
3
- Version: 0.2.2
3
+ Version: 0.4.0
4
4
  Summary: Redis for AI Agents - High-performance temporal-associative memory
5
5
  Author-email: CueMap Team <hello@cuemap.dev>
6
6
  License: MIT
@@ -98,6 +98,7 @@ memory_id = client.add(
98
98
  ### Recall Memories
99
99
 
100
100
  ```python
101
+ # OR logic (default): matches any cue
101
102
  results = client.recall(
102
103
  cues=["meeting", "john"],
103
104
  limit=10
@@ -105,6 +106,18 @@ results = client.recall(
105
106
 
106
107
  for result in results:
107
108
  print(f"{result.content} (score: {result.score})")
109
+
110
+ # AND logic: requires all cues to match
111
+ results = client.recall(
112
+ cues=["meeting", "john"],
113
+ min_intersection=2 # Both cues must match
114
+ )
115
+
116
+ # Cross-domain query (multi-tenant mode)
117
+ results = client.recall(
118
+ cues=["urgent"],
119
+ projects=["sales", "support", "engineering"]
120
+ )
108
121
  ```
109
122
 
110
123
  ### Reinforce Memory
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cuemap"
7
- version = "0.2.2"
7
+ version = "0.4.0"
8
8
  description = "Redis for AI Agents - High-performance temporal-associative memory"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes