ocerebro 0.4.4 → 0.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocerebro",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)",
5
5
  "main": "bin/ocerebro.js",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ocerebro"
7
- version = "0.4.4"
7
+ version = "0.4.5"
8
8
  description = "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -6,6 +6,7 @@ from typing import Any, Dict, List, Optional
6
6
  import sqlite3
7
7
  import json
8
8
  from datetime import datetime
9
+ from src.forgetting.gc import calculate_rfms_score
9
10
 
10
11
 
11
12
  def create_router(
@@ -24,6 +25,11 @@ def create_router(
24
25
  router.entities_db = entities_db
25
26
  router.cerebro_path = cerebro_path
26
27
 
28
+ @router.get("/ping")
29
+ async def get_ping():
30
+ """Retorna o cerebro_path atual do servidor"""
31
+ return {"cerebro_path": str(router.cerebro_path)}
32
+
27
33
  @router.get("/status")
28
34
  async def get_status():
29
35
  """Retorna status geral do sistema"""
@@ -242,7 +248,6 @@ def create_router(
242
248
  memories = []
243
249
  for row in rows:
244
250
  # Calcula GC risk
245
- from src.forgetting.gc import calculate_rfms_score
246
251
  memory_dict = dict(row)
247
252
  gc_risk = 1.0 - calculate_rfms_score(memory_dict)
248
253
 
@@ -1,5 +1,6 @@
1
1
  """Servidor standalone do Dashboard do OCerebro - roda como processo separado"""
2
2
 
3
+ import os
3
4
  import sys
4
5
  from pathlib import Path
5
6
 
@@ -13,9 +14,10 @@ from src.mcp.server import CerebroMCP
13
14
  def main():
14
15
  """Inicia o servidor standalone"""
15
16
  port = int(sys.argv[1]) if len(sys.argv) > 1 else 7999
17
+ cerebro_path = Path(sys.argv[2]) if len(sys.argv) > 2 else None
16
18
 
17
- # Inicializa componentes
18
- mcp = CerebroMCP()
19
+ # Inicializa componentes com o path correto
20
+ mcp = CerebroMCP(cerebro_path=cerebro_path)
19
21
 
20
22
  dashboard = DashboardServer(
21
23
  cerebro_path=mcp.cerebro_path,
@@ -25,7 +27,14 @@ def main():
25
27
  )
26
28
 
27
29
  if dashboard.start(port):
30
+ # Salva PID para poder ser morto quando precisar trocar de contexto
31
+ pid_file = Path.home() / ".ocerebro_dashboard.pid"
32
+ pid_file.write_text(str(os.getpid()), encoding="utf-8")
33
+
28
34
  print(f"Dashboard rodando em http://localhost:{port}")
35
+ print(f"Cerebro path: {mcp.cerebro_path}")
36
+ print(f"PID: {os.getpid()}")
37
+
29
38
  # Mantém vivo
30
39
  import time
31
40
  while True:
package/src/mcp/server.py CHANGED
@@ -791,6 +791,22 @@ Uma chamada por memória. O sistema salva e indexa automaticamente.
791
791
  except Exception:
792
792
  pass # Falha silenciosa se frontmatter inválido
793
793
 
794
+ # Indexar no metadata_db para aparecer no dashboard
795
+ if self.metadata_db:
796
+ tags_str = tags if isinstance(tags, str) else ",".join(tags) if isinstance(tags, list) else ""
797
+ self.metadata_db.insert({
798
+ "id": mem_name,
799
+ "type": m_type,
800
+ "project": project,
801
+ "title": frontmatter.get("title", mem_name) if frontmatter else mem_name,
802
+ "content": body_content,
803
+ "tags": tags_str,
804
+ "created_at": datetime.now().isoformat(),
805
+ "updated_at": datetime.now().isoformat(),
806
+ "layer": "auto",
807
+ "path": str(file_path),
808
+ })
809
+
794
810
  return f"✅ Memória '{mem_name}' salva em {file_path}"
795
811
 
796
812
  def _remember(self, args: Dict[str, Any]) -> str:
@@ -900,6 +916,7 @@ Uma chamada por memória. O sistema salva e indexa automaticamente.
900
916
  try:
901
917
  import subprocess
902
918
  import sys
919
+ import requests
903
920
 
904
921
  port = args.get("port", 7999)
905
922
 
@@ -911,6 +928,33 @@ Uma chamada por memória. O sistema salva e indexa automaticamente.
911
928
  sock.close()
912
929
  is_running = result == 0
913
930
 
931
+ if is_running:
932
+ # Verifica se o servidor está usando o cerebro_path correto
933
+ try:
934
+ resp = requests.get(f"http://127.0.0.1:{port}/api/ping", timeout=2)
935
+ if resp.status_code == 200:
936
+ data = resp.json()
937
+ running_path = data.get("cerebro_path", "")
938
+ current_path = str(self.cerebro_path.absolute())
939
+
940
+ if running_path != current_path:
941
+ # Path diferente - precisa reiniciar o servidor
942
+ # Lê o PID e mata o processo antigo
943
+ pid_file = Path.home() / ".ocerebro_dashboard.pid"
944
+ if pid_file.exists():
945
+ try:
946
+ old_pid = int(pid_file.read_text(encoding="utf-8").strip())
947
+ import os
948
+ os.kill(old_pid, 9) # SIGKILL
949
+ pid_file.unlink() # Remove o arquivo PID
950
+ except Exception:
951
+ pass # Processo já morreu ou erro ao matar
952
+
953
+ # Agora is_running será False e vamos reiniciar abaixo
954
+ is_running = False
955
+ except Exception:
956
+ pass # Se falhar o ping, tenta reiniciar mesmo assim
957
+
914
958
  if not is_running:
915
959
  # Inicia como processo separado (persiste após o MCP terminar)
916
960
  server_script = Path(__file__).parent.parent / "dashboard" / "standalone_server.py"
@@ -919,8 +963,7 @@ Uma chamada por memória. O sistema salva e indexa automaticamente.
919
963
 
920
964
  # Inicia processo em background
921
965
  subprocess.Popen(
922
- [sys.executable, str(server_script), str(port)],
923
- cwd=str(Path(__file__).parent.parent.parent),
966
+ [sys.executable, str(server_script), str(port), str(self.cerebro_path.absolute())],
924
967
  stdout=subprocess.DEVNULL,
925
968
  stderr=subprocess.DEVNULL,
926
969
  start_new_session=True # Desacoplado do processo pai