nexo-brain 5.4.7 → 5.4.9
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/README.md +1 -1
- package/package.json +6 -2
- package/src/agent_runner.py +64 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.9",
|
|
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/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
[Watch the overview video](https://nexo-brain.com/watch/) · [Watch on YouTube](https://www.youtube.com/watch?v=i2lkGhKyVqI) · [Open the infographic](https://nexo-brain.com/assets/nexo-brain-infographic-v5.png)
|
|
20
20
|
|
|
21
|
-
Version `5.4.
|
|
21
|
+
Version `5.4.9` is the current packaged-runtime line: headless Protocol Enforcer — all crons get enforcement rules automatically.
|
|
22
22
|
|
|
23
23
|
Previously in `5.4.6`: runtime dependency management in `nexo update` + daily auto-update cron.
|
|
24
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.9",
|
|
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",
|
|
@@ -61,7 +61,11 @@
|
|
|
61
61
|
"postinstall": "node bin/postinstall.js"
|
|
62
62
|
},
|
|
63
63
|
"runtimeDependencies": [
|
|
64
|
-
{
|
|
64
|
+
{
|
|
65
|
+
"name": "@anthropic-ai/claude-code",
|
|
66
|
+
"type": "npm-global",
|
|
67
|
+
"optional": false
|
|
68
|
+
}
|
|
65
69
|
],
|
|
66
70
|
"engines": {
|
|
67
71
|
"node": ">=18"
|
package/src/agent_runner.py
CHANGED
|
@@ -56,7 +56,6 @@ class TerminalClientUnavailableError(AgentRunnerError):
|
|
|
56
56
|
class AutomationBackendUnavailableError(AgentRunnerError):
|
|
57
57
|
"""Raised when the configured automation backend is unavailable."""
|
|
58
58
|
|
|
59
|
-
|
|
60
59
|
def _canonical_pricing_model(model: str) -> str:
|
|
61
60
|
lowered = str(model or "").strip().lower()
|
|
62
61
|
lowered = lowered.split("[", 1)[0]
|
|
@@ -533,6 +532,63 @@ def _build_codex_prompt(
|
|
|
533
532
|
return prompt
|
|
534
533
|
|
|
535
534
|
|
|
535
|
+
def _build_enforcement_system_prompt() -> str:
|
|
536
|
+
"""Build a system prompt fragment from tool-enforcement-map.json for headless sessions.
|
|
537
|
+
|
|
538
|
+
Reads the map and generates concise enforcement rules that the model must follow.
|
|
539
|
+
Only includes 'must' and 'should' level tools — 'none' tools are omitted.
|
|
540
|
+
"""
|
|
541
|
+
map_path = NEXO_HOME / "tool-enforcement-map.json"
|
|
542
|
+
if not map_path.exists():
|
|
543
|
+
for candidate in [
|
|
544
|
+
Path(__file__).parent.parent / "tool-enforcement-map.json",
|
|
545
|
+
]:
|
|
546
|
+
if candidate.exists():
|
|
547
|
+
map_path = candidate
|
|
548
|
+
break
|
|
549
|
+
else:
|
|
550
|
+
return ""
|
|
551
|
+
try:
|
|
552
|
+
data = json.loads(map_path.read_text())
|
|
553
|
+
except Exception:
|
|
554
|
+
return ""
|
|
555
|
+
|
|
556
|
+
lines = ["[PROTOCOL ENFORCEMENT — these rules are mandatory]"]
|
|
557
|
+
must_rules = []
|
|
558
|
+
should_rules = []
|
|
559
|
+
|
|
560
|
+
for tool_name, tool in data.get("tools", {}).items():
|
|
561
|
+
enf = tool.get("enforcement", {})
|
|
562
|
+
level = enf.get("level", "none")
|
|
563
|
+
if level == "none":
|
|
564
|
+
continue
|
|
565
|
+
rules = enf.get("rules", [])
|
|
566
|
+
rule_descs = [r.get("description", "") for r in rules if r.get("description")]
|
|
567
|
+
notes = enf.get("notes", "")
|
|
568
|
+
if rule_descs:
|
|
569
|
+
desc = f"{tool_name}: {'; '.join(rule_descs)}"
|
|
570
|
+
elif notes:
|
|
571
|
+
desc = f"{tool_name}: {notes[:120]}"
|
|
572
|
+
else:
|
|
573
|
+
rule_types = [r.get("type", "") for r in rules]
|
|
574
|
+
desc = f"{tool_name} ({', '.join(rule_types)})" if rule_types else tool_name
|
|
575
|
+
if level == "must":
|
|
576
|
+
must_rules.append(desc)
|
|
577
|
+
elif level == "should":
|
|
578
|
+
should_rules.append(desc)
|
|
579
|
+
|
|
580
|
+
if must_rules:
|
|
581
|
+
lines.append("MUST (violation creates protocol debt):")
|
|
582
|
+
for r in must_rules:
|
|
583
|
+
lines.append(f" - {r}")
|
|
584
|
+
if should_rules:
|
|
585
|
+
lines.append("SHOULD (recommended, check if relevant):")
|
|
586
|
+
for r in should_rules:
|
|
587
|
+
lines.append(f" - {r}")
|
|
588
|
+
|
|
589
|
+
return "\n".join(lines) if (must_rules or should_rules) else ""
|
|
590
|
+
|
|
591
|
+
|
|
536
592
|
def run_automation_prompt(
|
|
537
593
|
prompt: str,
|
|
538
594
|
*,
|
|
@@ -562,6 +618,13 @@ def run_automation_prompt(
|
|
|
562
618
|
reasoning_effort = profile["reasoning_effort"]
|
|
563
619
|
selected_backend = _resolve_available_backend(selected_backend, preferences=prefs)
|
|
564
620
|
|
|
621
|
+
enforcement_fragment = _build_enforcement_system_prompt()
|
|
622
|
+
if enforcement_fragment:
|
|
623
|
+
if append_system_prompt:
|
|
624
|
+
append_system_prompt = append_system_prompt + "\n\n" + enforcement_fragment
|
|
625
|
+
else:
|
|
626
|
+
append_system_prompt = enforcement_fragment
|
|
627
|
+
|
|
565
628
|
cwd_path = Path(cwd).expanduser().resolve() if cwd else Path.cwd()
|
|
566
629
|
run_env = _headless_env(env)
|
|
567
630
|
extra_args = list(extra_args or [])
|