nexo-brain 5.3.12 → 5.3.13
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/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/src/scripts/check-context.py +7 -1
- package/src/scripts/deep-sleep/extract.py +8 -2
- package/src/scripts/deep-sleep/synthesize.py +8 -1
- package/src/scripts/nexo-catchup.py +8 -2
- package/src/scripts/nexo-daily-self-audit.py +7 -1
- package/src/scripts/nexo-evolution-run.py +10 -2
- package/src/scripts/nexo-immune.py +8 -1
- package/src/scripts/nexo-learning-validator.py +9 -1
- package/src/scripts/nexo-postmortem-consolidator.py +9 -1
- package/src/scripts/nexo-sleep.py +7 -1
- package/src/scripts/nexo-synthesis.py +8 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.13",
|
|
4
4
|
"description": "Local cognitive runtime for Claude Code \u2014 persistent memory, overnight learning, doctor diagnostics, personal scripts, recovery-aware jobs, startup preflight, and optional dashboard/power helper.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "NEXO Brain",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.13",
|
|
4
4
|
"mcpName": "io.github.wazionapps/nexo",
|
|
5
5
|
"description": "NEXO Brain — Shared brain for AI agents. Persistent memory, semantic RAG, natural forgetting, metacognitive guard, trust scoring, 150+ MCP tools. Works with Claude Code, Codex, Claude Desktop & any MCP client. 100% local, free.",
|
|
6
6
|
"homepage": "https://nexo-brain.com",
|
|
@@ -21,6 +21,12 @@ if str(NEXO_CODE) not in sys.path:
|
|
|
21
21
|
sys.path.insert(0, str(NEXO_CODE))
|
|
22
22
|
|
|
23
23
|
from agent_runner import AutomationBackendUnavailableError, run_automation_prompt
|
|
24
|
+
try:
|
|
25
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
26
|
+
_USER_MODEL = _resolve_user_model()
|
|
27
|
+
except Exception:
|
|
28
|
+
_USER_MODEL = ""
|
|
29
|
+
|
|
24
30
|
|
|
25
31
|
|
|
26
32
|
class ContextChecker:
|
|
@@ -192,7 +198,7 @@ Rules:
|
|
|
192
198
|
try:
|
|
193
199
|
result = run_automation_prompt(
|
|
194
200
|
prompt,
|
|
195
|
-
model="opus",
|
|
201
|
+
model=_USER_MODEL or "opus",
|
|
196
202
|
timeout=300,
|
|
197
203
|
output_format="text",
|
|
198
204
|
append_system_prompt="Return exactly one valid JSON object.",
|
|
@@ -26,6 +26,12 @@ if str(NEXO_CODE) not in sys.path:
|
|
|
26
26
|
sys.path.insert(0, str(NEXO_CODE))
|
|
27
27
|
|
|
28
28
|
from agent_runner import AutomationBackendUnavailableError, run_automation_prompt
|
|
29
|
+
try:
|
|
30
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
31
|
+
_USER_MODEL = _resolve_user_model()
|
|
32
|
+
except Exception:
|
|
33
|
+
_USER_MODEL = ""
|
|
34
|
+
|
|
29
35
|
|
|
30
36
|
# No timeout -- headless automation can take as long as needed
|
|
31
37
|
CLAUDE_TIMEOUT = 21600 # 3h safety net (prevents zombie processes)
|
|
@@ -128,7 +134,7 @@ def analyze_session(
|
|
|
128
134
|
|
|
129
135
|
result = run_automation_prompt(
|
|
130
136
|
prompt,
|
|
131
|
-
model="opus",
|
|
137
|
+
model=_USER_MODEL or "opus",
|
|
132
138
|
timeout=CLAUDE_TIMEOUT,
|
|
133
139
|
output_format="text",
|
|
134
140
|
append_system_prompt=JSON_SYSTEM_PROMPT,
|
|
@@ -158,7 +164,7 @@ def analyze_session(
|
|
|
158
164
|
)
|
|
159
165
|
convert_result = run_automation_prompt(
|
|
160
166
|
convert_prompt,
|
|
161
|
-
model="sonnet",
|
|
167
|
+
model=_USER_MODEL or "sonnet",
|
|
162
168
|
timeout=120,
|
|
163
169
|
output_format="text",
|
|
164
170
|
append_system_prompt=JSON_SYSTEM_PROMPT,
|
|
@@ -18,6 +18,13 @@ import hashlib
|
|
|
18
18
|
from datetime import datetime
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
24
|
+
_USER_MODEL = _resolve_user_model()
|
|
25
|
+
except Exception:
|
|
26
|
+
_USER_MODEL = ""
|
|
27
|
+
|
|
21
28
|
NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
|
|
22
29
|
NEXO_CODE = Path(os.environ.get("NEXO_CODE", str(Path(__file__).resolve().parents[2])))
|
|
23
30
|
DEEP_SLEEP_DIR = NEXO_HOME / "operations" / "deep-sleep"
|
|
@@ -233,7 +240,7 @@ def main():
|
|
|
233
240
|
try:
|
|
234
241
|
result = run_automation_prompt(
|
|
235
242
|
prompt,
|
|
236
|
-
model="opus",
|
|
243
|
+
model=_USER_MODEL or "opus",
|
|
237
244
|
timeout=CLAUDE_TIMEOUT,
|
|
238
245
|
output_format="text",
|
|
239
246
|
allowed_tools="Read,Grep,Bash",
|
|
@@ -13,6 +13,13 @@ import sys
|
|
|
13
13
|
from datetime import datetime
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
19
|
+
_USER_MODEL = _resolve_user_model()
|
|
20
|
+
except Exception:
|
|
21
|
+
_USER_MODEL = ""
|
|
22
|
+
|
|
16
23
|
_SCRIPT_DIR = Path(__file__).resolve().parent
|
|
17
24
|
_DEFAULT_RUNTIME_ROOT = _SCRIPT_DIR.parent
|
|
18
25
|
_runtime_root = Path(os.environ.get("NEXO_CODE", str(_DEFAULT_RUNTIME_ROOT)))
|
|
@@ -126,7 +133,6 @@ def _heal_personal_schedules() -> dict:
|
|
|
126
133
|
summary = {"created": 0, "repaired": 0, "invalid": 0, "error": ""}
|
|
127
134
|
try:
|
|
128
135
|
from script_registry import reconcile_personal_scripts
|
|
129
|
-
|
|
130
136
|
result = reconcile_personal_scripts(dry_run=False)
|
|
131
137
|
ensured = result.get("ensure_schedules", {})
|
|
132
138
|
summary["created"] = len(ensured.get("created", []))
|
|
@@ -273,7 +279,7 @@ Format:
|
|
|
273
279
|
try:
|
|
274
280
|
result = run_automation_prompt(
|
|
275
281
|
prompt,
|
|
276
|
-
model="opus",
|
|
282
|
+
model=_USER_MODEL or "opus",
|
|
277
283
|
timeout=21600,
|
|
278
284
|
output_format="text",
|
|
279
285
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -40,6 +40,12 @@ from agent_runner import AutomationBackendUnavailableError, run_automation_promp
|
|
|
40
40
|
import db as nexo_db
|
|
41
41
|
from public_evolution_queue import queue_public_port_candidate
|
|
42
42
|
|
|
43
|
+
try:
|
|
44
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
45
|
+
_USER_MODEL = _resolve_user_model()
|
|
46
|
+
except Exception:
|
|
47
|
+
_USER_MODEL = ""
|
|
48
|
+
|
|
43
49
|
LOG_DIR = NEXO_HOME / "logs"
|
|
44
50
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
|
45
51
|
AUDIT_HISTORY_DIR = LOG_DIR / "self-audit"
|
|
@@ -2043,7 +2049,7 @@ Also write the machine-readable summary to {LOG_DIR}/self-audit-summary.json.
|
|
|
2043
2049
|
try:
|
|
2044
2050
|
result = run_automation_prompt(
|
|
2045
2051
|
prompt,
|
|
2046
|
-
model="opus",
|
|
2052
|
+
model=_USER_MODEL or "opus",
|
|
2047
2053
|
timeout=21600,
|
|
2048
2054
|
output_format="text",
|
|
2049
2055
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -20,6 +20,14 @@ import sys
|
|
|
20
20
|
from datetime import datetime, date, timedelta
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
26
|
+
_USER_MODEL = _resolve_user_model()
|
|
27
|
+
except Exception:
|
|
28
|
+
_USER_MODEL = ""
|
|
29
|
+
|
|
30
|
+
|
|
23
31
|
NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
|
|
24
32
|
# Auto-detect: if running from repo (src/scripts/), use src/ as NEXO_CODE
|
|
25
33
|
_script_dir = Path(__file__).resolve().parent
|
|
@@ -218,7 +226,7 @@ def call_claude_cli(prompt: str) -> str:
|
|
|
218
226
|
"""Call the configured automation backend for the managed evolution prompt."""
|
|
219
227
|
result = run_automation_prompt(
|
|
220
228
|
prompt,
|
|
221
|
-
model="opus",
|
|
229
|
+
model=_USER_MODEL or "opus",
|
|
222
230
|
timeout=CLI_TIMEOUT,
|
|
223
231
|
output_format="text",
|
|
224
232
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -234,7 +242,7 @@ def call_public_claude_cli(prompt: str, *, cwd: Path) -> str:
|
|
|
234
242
|
prompt,
|
|
235
243
|
cwd=cwd,
|
|
236
244
|
env={"NEXO_PUBLIC_CONTRIBUTION": "1"},
|
|
237
|
-
model="opus",
|
|
245
|
+
model=_USER_MODEL or "opus",
|
|
238
246
|
timeout=CLI_TIMEOUT,
|
|
239
247
|
output_format="text",
|
|
240
248
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash",
|
|
@@ -23,6 +23,13 @@ import time
|
|
|
23
23
|
from datetime import datetime, date, timedelta
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
29
|
+
_USER_MODEL = _resolve_user_model()
|
|
30
|
+
except Exception:
|
|
31
|
+
_USER_MODEL = ""
|
|
32
|
+
|
|
26
33
|
NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
|
|
27
34
|
_script_dir = Path(__file__).resolve().parent
|
|
28
35
|
_repo_src = _script_dir.parent
|
|
@@ -908,7 +915,7 @@ Write the report. Be concise — max 40 lines."""
|
|
|
908
915
|
try:
|
|
909
916
|
result = run_automation_prompt(
|
|
910
917
|
prompt,
|
|
911
|
-
model="opus",
|
|
918
|
+
model=_USER_MODEL or "opus",
|
|
912
919
|
timeout=21600,
|
|
913
920
|
output_format="text",
|
|
914
921
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -37,6 +37,13 @@ if str(NEXO_CODE) not in sys.path:
|
|
|
37
37
|
|
|
38
38
|
from agent_runner import AutomationBackendUnavailableError, run_automation_prompt
|
|
39
39
|
|
|
40
|
+
try:
|
|
41
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
42
|
+
_USER_MODEL = _resolve_user_model()
|
|
43
|
+
except Exception:
|
|
44
|
+
_USER_MODEL = ""
|
|
45
|
+
|
|
46
|
+
|
|
40
47
|
|
|
41
48
|
NEXO_DB = NEXO_HOME / "data" / "nexo.db"
|
|
42
49
|
JSON_ONLY_SYSTEM_PROMPT = (
|
|
@@ -151,7 +158,7 @@ Rules:
|
|
|
151
158
|
try:
|
|
152
159
|
result = run_automation_prompt(
|
|
153
160
|
prompt,
|
|
154
|
-
model="sonnet",
|
|
161
|
+
model=_USER_MODEL or "sonnet",
|
|
155
162
|
timeout=60,
|
|
156
163
|
output_format="text",
|
|
157
164
|
append_system_prompt=JSON_ONLY_SYSTEM_PROMPT,
|
|
@@ -231,6 +238,7 @@ def _extract_keywords(text: str) -> set:
|
|
|
231
238
|
|
|
232
239
|
def main():
|
|
233
240
|
import argparse
|
|
241
|
+
|
|
234
242
|
parser = argparse.ArgumentParser(description="Validate findings against existing NEXO learnings")
|
|
235
243
|
parser.add_argument("finding", help="The finding text to validate")
|
|
236
244
|
parser.add_argument("--category", "-c", help="Filter learnings by category")
|
|
@@ -38,6 +38,13 @@ sys.path.insert(0, str(NEXO_CODE))
|
|
|
38
38
|
|
|
39
39
|
from agent_runner import AutomationBackendUnavailableError, run_automation_prompt
|
|
40
40
|
|
|
41
|
+
try:
|
|
42
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
43
|
+
_USER_MODEL = _resolve_user_model()
|
|
44
|
+
except Exception:
|
|
45
|
+
_USER_MODEL = ""
|
|
46
|
+
|
|
47
|
+
|
|
41
48
|
NEXO_DB = NEXO_HOME / "data" / "nexo.db"
|
|
42
49
|
# Memory directory — adjust to match your project's memory location
|
|
43
50
|
MEMORY_DIR = NEXO_HOME / "memory"
|
|
@@ -212,7 +219,7 @@ Execute without asking."""
|
|
|
212
219
|
try:
|
|
213
220
|
result = run_automation_prompt(
|
|
214
221
|
prompt,
|
|
215
|
-
model="opus",
|
|
222
|
+
model=_USER_MODEL or "opus",
|
|
216
223
|
timeout=21600,
|
|
217
224
|
output_format="text",
|
|
218
225
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -348,6 +355,7 @@ def analyze_force_events():
|
|
|
348
355
|
log(f" {len(today_forces)} --force events")
|
|
349
356
|
|
|
350
357
|
from collections import Counter
|
|
358
|
+
|
|
351
359
|
memory_counts = Counter(r["memory_id"] for r in today_forces)
|
|
352
360
|
for mem_id, count in memory_counts.most_common():
|
|
353
361
|
mem = db.execute(
|
|
@@ -37,6 +37,12 @@ if str(NEXO_CODE) not in sys.path:
|
|
|
37
37
|
sys.path.insert(0, str(NEXO_CODE))
|
|
38
38
|
|
|
39
39
|
from agent_runner import AutomationBackendUnavailableError, run_automation_prompt
|
|
40
|
+
try:
|
|
41
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
42
|
+
_USER_MODEL = _resolve_user_model()
|
|
43
|
+
except Exception:
|
|
44
|
+
_USER_MODEL = ""
|
|
45
|
+
|
|
40
46
|
|
|
41
47
|
# ─── Paths ────────────────────────────────────────────────────────────────────
|
|
42
48
|
CLAUDE_DIR = NEXO_HOME
|
|
@@ -439,7 +445,7 @@ Execute without asking."""
|
|
|
439
445
|
try:
|
|
440
446
|
result = run_automation_prompt(
|
|
441
447
|
prompt,
|
|
442
|
-
model="opus",
|
|
448
|
+
model=_USER_MODEL or "opus",
|
|
443
449
|
timeout=21600,
|
|
444
450
|
output_format="text",
|
|
445
451
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|
|
@@ -18,6 +18,13 @@ import sys
|
|
|
18
18
|
from datetime import datetime, date, timedelta
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from client_preferences import resolve_user_model as _resolve_user_model
|
|
24
|
+
_USER_MODEL = _resolve_user_model()
|
|
25
|
+
except Exception:
|
|
26
|
+
_USER_MODEL = ""
|
|
27
|
+
|
|
21
28
|
HOME = Path.home()
|
|
22
29
|
NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
|
|
23
30
|
_script_dir = Path(__file__).resolve().parent
|
|
@@ -340,7 +347,7 @@ Execute without asking."""
|
|
|
340
347
|
try:
|
|
341
348
|
result = run_automation_prompt(
|
|
342
349
|
prompt,
|
|
343
|
-
model="opus",
|
|
350
|
+
model=_USER_MODEL or "opus",
|
|
344
351
|
timeout=21600,
|
|
345
352
|
output_format="text",
|
|
346
353
|
allowed_tools="Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*",
|