@hiperplano/aluy-cli 1.0.0-rc.156 → 1.0.0-rc.161

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.
@@ -115,6 +115,49 @@ def _untrack_user(users: dict[str, dict[str, Any]], user_id: str) -> None:
115
115
 
116
116
 
117
117
  # ── Handler HTTP ──────────────────────────────────────────────────────────
118
+
119
+ # ── COMPATIBILIDADE DE API DO mem0ai ──────────────────────────────────────────
120
+ #
121
+ # O mem0ai TROCOU a assinatura de leitura entre as linhas 0.1.x e 2.x, e este script
122
+ # tinha sido escrito só para a 2.x:
123
+ #
124
+ # 0.1.x search(query, user_id=..., limit=...) get_all(user_id=...)
125
+ # 2.x search(query, filters={...}, top_k=...) get_all(filters={...})
126
+ #
127
+ # Só que `MEM0_PIP_PACKAGES` (provisioner-contract.ts) pina `mem0ai==0.1.76` — ou seja,
128
+ # o que É INSTALADO tem a API ANTIGA e o script chamava a NOVA. Toda leitura levava
129
+ # `TypeError: Memory.search() got an unexpected keyword argument 'top_k'` ⇒ HTTP 500.
130
+ #
131
+ # O que isso produzia, e por que passou tanto tempo despercebido: `add` usa a API
132
+ # ANTIGA (linha do _handle_add) e SEMPRE funcionou. Então a memória GRAVAVA e nunca
133
+ # LIA — o agente anotava os fatos, o `recall` do boot morria no 500, o chamador
134
+ # engolia num `catch` e a sessão abria amnésica. O único sinal para o usuário era um
135
+ # `✗` de um caractere no rodapé. Diagnóstico do dono, em 31/08: "entrei e parece que
136
+ # ele nem sabe do que se trata".
137
+ #
138
+ # Tentamos a assinatura DO PIN primeiro (0.1.x) e caímos na 2.x só no `TypeError`,
139
+ # porque quem provisionou antes pode ter qualquer uma das duas no venv. `TypeError` é
140
+ # estreito de propósito: erro de backend (conexão, disco) tem de CONTINUAR subindo
141
+ # como 500 em vez de virar "lista vazia" silenciosa — conflar os dois é o defeito que
142
+ # este bloco existe para não repetir.
143
+
144
+
145
+ def _search_compat(memory, query, user_id, limit):
146
+ """`search` tolerante às duas linhas de API do mem0ai. Ver bloco acima."""
147
+ try:
148
+ return memory.search(query, user_id=user_id, limit=limit)
149
+ except TypeError:
150
+ return memory.search(query, filters={"user_id": user_id}, top_k=limit)
151
+
152
+
153
+ def _get_all_compat(memory, user_id):
154
+ """`get_all` tolerante às duas linhas de API do mem0ai. Ver bloco acima."""
155
+ try:
156
+ return memory.get_all(user_id=user_id)
157
+ except TypeError:
158
+ return memory.get_all(filters={"user_id": user_id})
159
+
160
+
118
161
  class Mem0Handler(BaseHTTPRequestHandler):
119
162
  """
120
163
  Handler HTTP que traduz requests REST ↔ chamadas ao Memory() do mem0ai.
@@ -254,8 +297,7 @@ class Mem0Handler(BaseHTTPRequestHandler):
254
297
  query = qs.get("query", "")
255
298
  limit = int(qs.get("limit", "10"))
256
299
 
257
- # mem0ai 2.0.7: entity params via filters=, paginação via top_k= (não user_id/limit).
258
- resp = self.memory.search(query, filters={"user_id": user_id}, top_k=limit)
300
+ resp = _search_compat(self.memory, query, user_id, limit)
259
301
 
260
302
  # mem0ai.search retorna {"results": [...]}
261
303
  results = resp.get("results", []) if isinstance(resp, dict) else []
@@ -268,8 +310,7 @@ class Mem0Handler(BaseHTTPRequestHandler):
268
310
  users_list = []
269
311
  for user_id in list(self.users.keys()):
270
312
  try:
271
- # mem0ai 2.0.7: get_all usa filters= e retorna {"results": [...]}.
272
- all_mems = self.memory.get_all(filters={"user_id": user_id})
313
+ all_mems = _get_all_compat(self.memory, user_id)
273
314
  except Exception:
274
315
  # F100 — erro TRANSITÓRIO no get_all NÃO é "scope vazio". Conflar os dois
275
316
  # (count=0 ⇒ untrack) DESTRÓI o tracking de um scope COM memórias num hiccup