@simbimbo/memory-ocmemog 0.1.4

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +21 -0
  3. package/README.md +223 -0
  4. package/brain/__init__.py +1 -0
  5. package/brain/runtime/__init__.py +13 -0
  6. package/brain/runtime/config.py +21 -0
  7. package/brain/runtime/inference.py +83 -0
  8. package/brain/runtime/instrumentation.py +17 -0
  9. package/brain/runtime/memory/__init__.py +13 -0
  10. package/brain/runtime/memory/api.py +152 -0
  11. package/brain/runtime/memory/artifacts.py +33 -0
  12. package/brain/runtime/memory/candidate.py +89 -0
  13. package/brain/runtime/memory/context_builder.py +87 -0
  14. package/brain/runtime/memory/conversation_state.py +1825 -0
  15. package/brain/runtime/memory/distill.py +198 -0
  16. package/brain/runtime/memory/embedding_engine.py +94 -0
  17. package/brain/runtime/memory/freshness.py +91 -0
  18. package/brain/runtime/memory/health.py +42 -0
  19. package/brain/runtime/memory/integrity.py +170 -0
  20. package/brain/runtime/memory/interaction_memory.py +57 -0
  21. package/brain/runtime/memory/memory_consolidation.py +60 -0
  22. package/brain/runtime/memory/memory_gate.py +38 -0
  23. package/brain/runtime/memory/memory_graph.py +54 -0
  24. package/brain/runtime/memory/memory_links.py +109 -0
  25. package/brain/runtime/memory/memory_salience.py +235 -0
  26. package/brain/runtime/memory/memory_synthesis.py +33 -0
  27. package/brain/runtime/memory/memory_taxonomy.py +35 -0
  28. package/brain/runtime/memory/person_identity.py +83 -0
  29. package/brain/runtime/memory/person_memory.py +138 -0
  30. package/brain/runtime/memory/pondering_engine.py +577 -0
  31. package/brain/runtime/memory/promote.py +237 -0
  32. package/brain/runtime/memory/provenance.py +356 -0
  33. package/brain/runtime/memory/reinforcement.py +73 -0
  34. package/brain/runtime/memory/retrieval.py +153 -0
  35. package/brain/runtime/memory/semantic_search.py +66 -0
  36. package/brain/runtime/memory/sentiment_memory.py +67 -0
  37. package/brain/runtime/memory/store.py +400 -0
  38. package/brain/runtime/memory/tool_catalog.py +68 -0
  39. package/brain/runtime/memory/unresolved_state.py +93 -0
  40. package/brain/runtime/memory/vector_index.py +270 -0
  41. package/brain/runtime/model_roles.py +11 -0
  42. package/brain/runtime/model_router.py +22 -0
  43. package/brain/runtime/providers.py +59 -0
  44. package/brain/runtime/security/__init__.py +3 -0
  45. package/brain/runtime/security/redaction.py +14 -0
  46. package/brain/runtime/state_store.py +25 -0
  47. package/brain/runtime/storage_paths.py +41 -0
  48. package/docs/architecture/memory.md +118 -0
  49. package/docs/release-checklist.md +34 -0
  50. package/docs/reports/ocmemog-code-audit-2026-03-14.md +155 -0
  51. package/docs/usage.md +223 -0
  52. package/index.ts +726 -0
  53. package/ocmemog/__init__.py +1 -0
  54. package/ocmemog/sidecar/__init__.py +1 -0
  55. package/ocmemog/sidecar/app.py +1068 -0
  56. package/ocmemog/sidecar/compat.py +74 -0
  57. package/ocmemog/sidecar/transcript_watcher.py +425 -0
  58. package/openclaw.plugin.json +18 -0
  59. package/package.json +60 -0
  60. package/scripts/install-ocmemog.sh +277 -0
  61. package/scripts/launchagents/com.openclaw.ocmemog.guard.plist +22 -0
  62. package/scripts/launchagents/com.openclaw.ocmemog.ponder.plist +22 -0
  63. package/scripts/launchagents/com.openclaw.ocmemog.sidecar.plist +27 -0
  64. package/scripts/ocmemog-context.sh +15 -0
  65. package/scripts/ocmemog-continuity-benchmark.py +178 -0
  66. package/scripts/ocmemog-demo.py +122 -0
  67. package/scripts/ocmemog-failover-test.sh +17 -0
  68. package/scripts/ocmemog-guard.sh +11 -0
  69. package/scripts/ocmemog-install.sh +93 -0
  70. package/scripts/ocmemog-load-test.py +106 -0
  71. package/scripts/ocmemog-ponder.sh +30 -0
  72. package/scripts/ocmemog-recall-test.py +58 -0
  73. package/scripts/ocmemog-reindex-vectors.py +14 -0
  74. package/scripts/ocmemog-reliability-soak.py +177 -0
  75. package/scripts/ocmemog-sidecar.sh +46 -0
  76. package/scripts/ocmemog-soak-report.py +58 -0
  77. package/scripts/ocmemog-soak-test.py +44 -0
  78. package/scripts/ocmemog-test-rig.py +345 -0
  79. package/scripts/ocmemog-transcript-append.py +45 -0
  80. package/scripts/ocmemog-transcript-watcher.py +8 -0
  81. package/scripts/ocmemog-transcript-watcher.sh +7 -0
@@ -0,0 +1,89 @@
1
+ from __future__ import annotations
2
+
3
+ import uuid
4
+ import json
5
+ from typing import Dict, Any
6
+
7
+ from brain.runtime.instrumentation import emit_event
8
+ from brain.runtime import state_store
9
+ from brain.runtime.memory import provenance, store
10
+ from brain.runtime.security import redaction
11
+
12
+
13
+ LOGFILE = state_store.reports_dir() / "brain_memory.log.jsonl"
14
+
15
+
16
+ def create_candidate(
17
+ source_event_id: int,
18
+ distilled_summary: str,
19
+ verification_points: list[str],
20
+ confidence_score: float,
21
+ metadata: Dict[str, Any] | None = None,
22
+ ) -> Dict[str, Any]:
23
+ summary, redacted = redaction.redact_text(distilled_summary)
24
+ verification_lines = []
25
+ for point in verification_points:
26
+ clean, _ = redaction.redact_text(str(point))
27
+ verification_lines.append(clean)
28
+
29
+ normalized_metadata = provenance.normalize_metadata(metadata, source="candidate")
30
+
31
+ conn = store.connect()
32
+ row = conn.execute(
33
+ "SELECT candidate_id FROM candidates WHERE source_event_id=? AND distilled_summary=?",
34
+ (source_event_id, summary),
35
+ ).fetchone()
36
+ if row:
37
+ conn.close()
38
+ emit_event(LOGFILE, "brain_memory_candidate_duplicate", status="ok", source_event_id=source_event_id)
39
+ return {"candidate_id": row[0], "duplicate": True}
40
+
41
+ candidate_id = str(uuid.uuid4())
42
+ verification_status = "verified" if verification_lines else "unverified"
43
+ conn.execute(
44
+ """
45
+ INSERT INTO candidates (
46
+ candidate_id, source_event_id, distilled_summary, verification_points,
47
+ confidence_score, status, verification_status, metadata_json, schema_version
48
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
49
+ """,
50
+ (
51
+ candidate_id,
52
+ source_event_id,
53
+ summary,
54
+ "\n".join(verification_lines),
55
+ confidence_score,
56
+ "pending",
57
+ verification_status,
58
+ json.dumps(normalized_metadata, ensure_ascii=False),
59
+ store.SCHEMA_VERSION,
60
+ ),
61
+ )
62
+ conn.execute(
63
+ "INSERT INTO memory_events (event_type, source, details_json, schema_version) VALUES (?, ?, ?, ?)",
64
+ (
65
+ "candidate_created",
66
+ str(source_event_id),
67
+ json.dumps({"candidate_id": candidate_id, "redacted": redacted, "verification_status": verification_status}),
68
+ store.SCHEMA_VERSION,
69
+ ),
70
+ )
71
+ conn.commit()
72
+ conn.close()
73
+ emit_event(LOGFILE, "brain_memory_candidate_created", status="ok", source_event_id=source_event_id, redacted=redacted)
74
+ return {"candidate_id": candidate_id, "duplicate": False}
75
+
76
+
77
+ def get_candidate(candidate_id: str) -> Dict[str, Any] | None:
78
+ conn = store.connect()
79
+ row = conn.execute(
80
+ """
81
+ SELECT candidate_id, source_event_id, distilled_summary, verification_points,
82
+ confidence_score, status, verification_status, metadata_json
83
+ FROM candidates
84
+ WHERE candidate_id=?
85
+ """,
86
+ (candidate_id,),
87
+ ).fetchone()
88
+ conn.close()
89
+ return dict(row) if row else None
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Dict, Iterable, List
4
+
5
+ from brain.runtime.instrumentation import emit_event
6
+ from brain.runtime import state_store
7
+ from brain.runtime.memory import retrieval
8
+
9
+
10
+ def build_context(
11
+ prompt: str,
12
+ max_context_blocks: int = 5,
13
+ *,
14
+ memory_queries: Iterable[str] | None = None,
15
+ memory_priorities: Iterable[str] | None = None,
16
+ role_id: str | None = None,
17
+ ) -> Dict[str, List[str]]:
18
+ emit_event(state_store.reports_dir() / "brain_memory.log.jsonl", "brain_memory_context_build_start", status="ok")
19
+ queries = [query for query in (memory_queries or ()) if isinstance(query, str) and query.strip()]
20
+ categories = [category for category in (memory_priorities or ()) if isinstance(category, str) and category.strip()]
21
+ role_priorities: List[str] = []
22
+ if role_id:
23
+ try:
24
+ from brain.runtime.roles import role_registry
25
+ role = role_registry.get_role(role_id)
26
+ role_priorities = list(role.memory_priority) if role else []
27
+ except Exception:
28
+ role_priorities = []
29
+ combined_priorities = [*categories, *role_priorities]
30
+ if queries:
31
+ mem = retrieval.retrieve_for_queries(queries, categories=combined_priorities or None)
32
+ else:
33
+ mem = retrieval.retrieve(prompt, categories=combined_priorities or None)
34
+
35
+ ranked_blocks: List[Dict[str, str | float]] = []
36
+ for item in mem.get("knowledge", []):
37
+ ranked_blocks.append(
38
+ {
39
+ "content": item.get("content"),
40
+ "source": "knowledge",
41
+ "score": float(item.get("score") or item.get("confidence") or 0.0),
42
+ }
43
+ )
44
+ for item in mem.get("tasks", []):
45
+ ranked_blocks.append(
46
+ {
47
+ "content": item.get("content"),
48
+ "source": "tasks",
49
+ "score": float(item.get("score") or item.get("confidence") or 0.0),
50
+ }
51
+ )
52
+ if role_priorities:
53
+ for item in ranked_blocks:
54
+ if item.get("source") in role_priorities:
55
+ item["score"] = float(item.get("score", 0.0)) + 0.2
56
+ emit_event(
57
+ state_store.reports_dir() / "brain_memory.log.jsonl",
58
+ "brain_role_context_weighted",
59
+ status="ok",
60
+ role_id=role_id,
61
+ priorities=len(role_priorities),
62
+ )
63
+ ranked_blocks.sort(key=lambda item: item.get("score", 0.0), reverse=True)
64
+ if len(ranked_blocks) > max_context_blocks:
65
+ ranked_blocks = ranked_blocks[:max_context_blocks]
66
+ emit_event(state_store.reports_dir() / "brain_memory.log.jsonl", "brain_memory_context_trim", status="ok")
67
+
68
+ context_blocks = [item["content"] for item in ranked_blocks if item.get("content")]
69
+ context_scores = [item.get("score", 0.0) for item in ranked_blocks]
70
+ synthesis = mem.get("synthesis", []) if isinstance(mem, dict) else []
71
+ for item in synthesis[:2]:
72
+ summary = item.get("summary") if isinstance(item, dict) else None
73
+ if summary:
74
+ context_blocks.append(str(summary))
75
+
76
+ context = {
77
+ "context_blocks": context_blocks,
78
+ "context_scores": context_scores,
79
+ "ranked_blocks": ranked_blocks,
80
+ "knowledge": mem.get("knowledge", []),
81
+ "tasks": mem.get("tasks", []),
82
+ "directives": [item["content"] if isinstance(item, dict) else item for item in mem.get("directives", [])],
83
+ "reflections": [item["content"] if isinstance(item, dict) else item for item in mem.get("reflections", [])],
84
+ "used_queries": queries,
85
+ }
86
+ emit_event(state_store.reports_dir() / "brain_memory.log.jsonl", "brain_memory_context_build_complete", status="ok")
87
+ return context