nexo-brain 1.5.1 → 1.5.2

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": "nexo-brain",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "mcpName": "io.github.wazionapps/nexo",
5
5
  "description": "NEXO — Cognitive co-operator for Claude Code. Atkinson-Shiffrin memory, semantic RAG, knowledge graph, HNSW vector indexing, trust scoring, and metacognitive error prevention.",
6
6
  "bin": {
@@ -79,6 +79,44 @@ def adjust_trust(points: int, context: str):
79
79
  pass
80
80
 
81
81
 
82
+ def add_learning(category: str, title: str, content: str) -> bool:
83
+ """Add a learning to nexo.db using real schema."""
84
+ if not NEXO_DB.exists():
85
+ return False
86
+ try:
87
+ now = datetime.now().timestamp()
88
+ conn = sqlite3.connect(str(NEXO_DB))
89
+ conn.execute(
90
+ "INSERT INTO learnings (category, title, content, created_at, updated_at, reasoning) VALUES (?, ?, ?, ?, ?, ?)",
91
+ (category, title, content, now, now, "Deep Sleep overnight analysis")
92
+ )
93
+ conn.commit()
94
+ conn.close()
95
+ return True
96
+ except Exception as e:
97
+ print(f" Error adding learning: {e}", file=sys.stderr)
98
+ return False
99
+
100
+
101
+ def add_followup(followup_id: str, description: str, date: str = None) -> bool:
102
+ """Add a followup to nexo.db using real schema."""
103
+ if not NEXO_DB.exists():
104
+ return False
105
+ try:
106
+ now = datetime.now().timestamp()
107
+ conn = sqlite3.connect(str(NEXO_DB))
108
+ conn.execute(
109
+ "INSERT OR IGNORE INTO followups (id, description, date, status, created_at, updated_at, reasoning) VALUES (?, ?, ?, 'PENDIENTE', ?, ?, ?)",
110
+ (followup_id, description, date or "", now, now, "Deep Sleep overnight analysis")
111
+ )
112
+ conn.commit()
113
+ conn.close()
114
+ return True
115
+ except Exception as e:
116
+ print(f" Error adding followup: {e}", file=sys.stderr)
117
+ return False
118
+
119
+
82
120
  def apply(analysis: dict):
83
121
  """Apply all findings from deep sleep analysis."""
84
122
  memory_dir = find_memory_dir()
@@ -88,32 +126,44 @@ def apply(analysis: dict):
88
126
 
89
127
  print(f"\nApplying findings for {date}...")
90
128
 
91
- # 1. Uncaptured corrections → feedback memories (high/critical only)
129
+ # 1. Uncaptured corrections → learnings + feedback memories
92
130
  for i, correction in enumerate(analysis.get("uncaptured_corrections", [])):
93
131
  severity = correction.get("severity", "medium")
94
- if severity not in ("high", "critical"):
95
- continue
96
-
97
132
  category = correction.get("category", "process")
98
133
  content = correction.get("what_nexo_should_have_saved", "")
99
134
  quote = correction.get("quote", "")
100
135
 
101
- safe_name = category.replace(" ", "_").lower()
102
- filename = f"ds_{date}_{safe_name}_{i}.md"
103
- write_feedback_memory(
104
- memory_dir, filename,
105
- name=content[:60],
106
- description=f"Deep sleep detected uncaptured correction ({severity})",
107
- content=f"{content}\n\n**Why:** User said: \"{quote}\"\nContext: {correction.get('context', '')}\n\n**How to apply:** {content}"
108
- )
109
- memory_entries.append({
110
- "title": content[:40],
111
- "filename": filename,
112
- "summary": f"Deep sleep {date}, severity {severity}"
113
- })
114
- actions_taken.append(f"feedback_write: {filename}")
115
-
116
- # 2. Trust adjustments for critical violations
136
+ # All corrections learnings
137
+ learning_title = f"[Deep Sleep] {content[:80]}"
138
+ learning_content = f"User said: \"{quote}\"\nContext: {correction.get('context', '')}\nRepeated: {correction.get('times_repeated', 1)} times"
139
+ if add_learning(category, learning_title, learning_content):
140
+ actions_taken.append(f"learning_add: {learning_title[:50]}")
141
+
142
+ # High/critical also feedback memories
143
+ if severity in ("high", "critical"):
144
+ safe_name = category.replace(" ", "_").lower()
145
+ filename = f"ds_{date}_{safe_name}_{i}.md"
146
+ write_feedback_memory(
147
+ memory_dir, filename,
148
+ name=content[:60],
149
+ description=f"Deep sleep detected uncaptured correction ({severity})",
150
+ content=f"{content}\n\n**Why:** User said: \"{quote}\"\nContext: {correction.get('context', '')}\n\n**How to apply:** {content}"
151
+ )
152
+ memory_entries.append({
153
+ "title": content[:40],
154
+ "filename": filename,
155
+ "summary": f"Deep sleep {date}, severity {severity}"
156
+ })
157
+ actions_taken.append(f"feedback_write: {filename}")
158
+
159
+ # 2. Missed commitments → followups
160
+ for i, commitment in enumerate(analysis.get("missed_commitments", [])):
161
+ fid = f"NF-DS-{date}-{i}"
162
+ desc = f"[Deep Sleep] {commitment.get('commitment', '')[:100]}"
163
+ if add_followup(fid, desc, commitment.get("due_date")):
164
+ actions_taken.append(f"followup: {desc[:50]}")
165
+
166
+ # 3. Trust adjustments for critical violations
117
167
  critical_violations = [v for v in analysis.get("protocol_violations", []) if v.get("severity") == "critical"]
118
168
  if critical_violations:
119
169
  points = -3 * len(critical_violations)