@hiperplano/aluy-cli 1.0.0-rc.37 → 1.0.0-rc.39
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.
- package/assets/mem0/aluy-mem0-server.py +46 -1
- package/dist-bundle/bin/aluy.js +256 -256
- package/dist-bundle/index.js +190 -190
- package/package.json +1 -1
|
@@ -36,7 +36,10 @@ DEFAULT_PORT = 11435
|
|
|
36
36
|
DEFAULT_HOST = "127.0.0.1"
|
|
37
37
|
ALUY_MEMORY_DIR = os.path.expanduser("~/.aluy/memory")
|
|
38
38
|
OLLAMA_BASE_URL = "http://127.0.0.1:11434"
|
|
39
|
-
|
|
39
|
+
# Embedder CONFIG-DRIVEN: o boot passa `ALUY_MEM0_EMBEDDER` (escolhido na instalação); default
|
|
40
|
+
# bge-m3 (multilíngue, forte). Trocar o embedder muda a DIMENSÃO do vetor (bge-m3/mxbai=1024,
|
|
41
|
+
# nomic=768) ⇒ o store chromadb antigo fica incompatível e o self-heal o reseta no 1º boot.
|
|
42
|
+
EMBEDDER_MODEL = os.environ.get("ALUY_MEM0_EMBEDDER", "bge-m3").strip() or "bge-m3"
|
|
40
43
|
# LLM local p/ extração de fatos (mem0 add infer=True). SEM isto o mem0 cai no
|
|
41
44
|
# default OpenAI → 401. Local-first: tudo via Ollama loopback, zero credencial.
|
|
42
45
|
LLM_MODEL = "qwen2.5:0.5b"
|
|
@@ -320,6 +323,38 @@ class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
|
|
|
320
323
|
|
|
321
324
|
|
|
322
325
|
# ── Main ──────────────────────────────────────────────────────────────────
|
|
326
|
+
EMBEDDER_MARKER = os.path.join(ALUY_MEMORY_DIR, ".embedder")
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _migrate_embedder_if_changed() -> None:
|
|
330
|
+
"""Se o embedder mudou desde o último boot (marca em `.embedder` ≠ atual), a dimensão do
|
|
331
|
+
vetor muda e o store chromadb fica incompatível ⇒ reseta proativamente. Best-effort."""
|
|
332
|
+
try:
|
|
333
|
+
prev = None
|
|
334
|
+
if os.path.exists(EMBEDDER_MARKER):
|
|
335
|
+
with open(EMBEDDER_MARKER, encoding="utf-8") as fh:
|
|
336
|
+
prev = fh.read().strip()
|
|
337
|
+
if prev is not None and prev != EMBEDDER_MODEL:
|
|
338
|
+
sys.stderr.write(
|
|
339
|
+
f"aluy-mem0: embedder mudou ({prev} → {EMBEDDER_MODEL}); "
|
|
340
|
+
"dimensão do vetor difere — resetando store p/ recriar.\n"
|
|
341
|
+
)
|
|
342
|
+
_reset_incompatible_stores()
|
|
343
|
+
os.makedirs(ALUY_MEMORY_DIR, mode=0o700, exist_ok=True)
|
|
344
|
+
except Exception: # noqa: BLE001 — migração best-effort, nunca derruba o boot
|
|
345
|
+
pass
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def _write_embedder_marker() -> None:
|
|
349
|
+
"""Grava qual embedder gerou os vetores atuais (p/ detectar troca no próximo boot)."""
|
|
350
|
+
try:
|
|
351
|
+
os.makedirs(ALUY_MEMORY_DIR, mode=0o700, exist_ok=True)
|
|
352
|
+
with open(EMBEDDER_MARKER, "w", encoding="utf-8") as fh:
|
|
353
|
+
fh.write(EMBEDDER_MODEL)
|
|
354
|
+
except Exception: # noqa: BLE001
|
|
355
|
+
pass
|
|
356
|
+
|
|
357
|
+
|
|
323
358
|
def _reset_incompatible_stores() -> None:
|
|
324
359
|
"""Move os stores de memória p/ backup, p/ recriar frescos. Chamado quando a versão atual
|
|
325
360
|
do chromadb/mem0 não lê o store de uma versão anterior (KeyError '_type' no chromadb /
|
|
@@ -367,6 +402,13 @@ def main() -> None:
|
|
|
367
402
|
# Garante o dir de store com perms corretas.
|
|
368
403
|
os.makedirs(ALUY_MEMORY_DIR, mode=0o700, exist_ok=True)
|
|
369
404
|
|
|
405
|
+
# MIGRAÇÃO DE EMBEDDER (proativa): trocar o embedder muda a DIMENSÃO do vetor (bge-m3/
|
|
406
|
+
# mxbai=1024, nomic=768). O chromadb só estoura a incompatibilidade no ADD/SEARCH (runtime),
|
|
407
|
+
# NÃO no boot — então o self-heal abaixo (que envolve só o `from_config`) não pegaria. Aqui,
|
|
408
|
+
# ANTES de subir: se o embedder mudou desde o último boot, reseta o store (a marca guarda
|
|
409
|
+
# qual embedder gerou os vetores atuais). Best-effort — nunca derruba o boot.
|
|
410
|
+
_migrate_embedder_if_changed()
|
|
411
|
+
|
|
370
412
|
# Instancia Memory() UMA vez. SELF-HEAL de upgrade: um store gravado por uma versão
|
|
371
413
|
# ANTERIOR do chromadb/mem0 pode ser ilegível pela atual (ex.: chromadb `KeyError: '_type'`
|
|
372
414
|
# na config da collection; sqlite `no such column: prev_value` no history). Em vez de
|
|
@@ -409,6 +451,9 @@ def main() -> None:
|
|
|
409
451
|
else:
|
|
410
452
|
return # inalcançável (execv substitui o processo) — só p/ o type-checker
|
|
411
453
|
|
|
454
|
+
# Store criado/aberto OK com o embedder atual — grava a marca p/ detectar troca futura.
|
|
455
|
+
_write_embedder_marker()
|
|
456
|
+
|
|
412
457
|
# Injeta no handler.
|
|
413
458
|
Mem0Handler.memory = memory
|
|
414
459
|
Mem0Handler.users = _load_users()
|