nexo-brain 6.0.3 → 6.0.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/agent_runner.py +88 -19
- package/src/resonance_map.py +4 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4",
|
|
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 `6.0.
|
|
21
|
+
Version `6.0.4` is the current packaged-runtime line: `nexo chat` and the dashboard's "Open followup in Terminal" action now honour `preferences.default_resonance`. Pre-v6.0.4 both launchers picked `--model` / `--effort` straight from `config/schedule.json`'s `client_runtime_profiles`, so users who switched their Resonance in NEXO Desktop Preferences (Alto → writes `brain/calibration.json`) kept getting the stale tier cached in the legacy profile — usually `max`. A new `_resolve_interactive_model_and_effort(caller, backend, ...)` helper consults `resonance_map.resolve_model_and_effort` first and falls back to `client_runtime_profiles` only when the resonance contract is missing. `nexo_followup_terminal` joins `nexo_chat` / `desktop_new_session` / `nexo_update_interactive` in `USER_FACING_CALLERS` so the dashboard launcher resolves against the user's preference.
|
|
22
22
|
|
|
23
23
|
Previously in `6.0.2`: adds the reserved caller prefix `personal/*` so scripts living in `~/.nexo/scripts/` can invoke the automation backend with their own caller id without editing `src/resonance_map.py`. New kwarg `tier` (`"maximo"` / `"alto"` / `"medio"` / `"bajo"`) on `run_automation_prompt`, `run_automation_interactive`, `nexo_helper.run_automation_text`, `nexo_helper.run_automation_json`, and `nexo-agent-run.py --tier`. Precedence for `personal/*` callers: explicit `tier=` → explicit `reasoning_effort=` → `calibration.preferences.default_resonance` → `DEFAULT_RESONANCE` (`alto`). Registered callers keep their behaviour unchanged. New guide: [`docs/personal-scripts-guide.md`](docs/personal-scripts-guide.md).
|
|
24
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4",
|
|
4
4
|
"mcpName": "io.github.wazionapps/nexo",
|
|
5
5
|
"description": "NEXO Brain \u2014 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",
|
package/src/agent_runner.py
CHANGED
|
@@ -457,16 +457,75 @@ def _interactive_target_cwd(target: str | os.PathLike[str]) -> str:
|
|
|
457
457
|
return str(Path.cwd())
|
|
458
458
|
|
|
459
459
|
|
|
460
|
+
def _resolve_interactive_model_and_effort(
|
|
461
|
+
caller: str,
|
|
462
|
+
backend: str,
|
|
463
|
+
*,
|
|
464
|
+
preferences: dict | None = None,
|
|
465
|
+
tier: str | None = None,
|
|
466
|
+
) -> tuple[str, str]:
|
|
467
|
+
"""Return ``(model, effort)`` for an interactive launch.
|
|
468
|
+
|
|
469
|
+
v6.0.4 — interactive launchers (nexo chat, dashboard followup) were
|
|
470
|
+
picking the command flags straight from ``client_runtime_profiles``
|
|
471
|
+
(config/schedule.json), ignoring the user's ``default_resonance``
|
|
472
|
+
preference in calibration.json. That meant Preferences → "Alto"
|
|
473
|
+
never reached ``nexo chat`` even though the same preference was
|
|
474
|
+
applied correctly in headless runs (run_automation_prompt) and in
|
|
475
|
+
NEXO Desktop (lib/claude-runtime.js).
|
|
476
|
+
|
|
477
|
+
Resolution order (mirrors run_automation_prompt):
|
|
478
|
+
1. resonance_map → (model, effort) for the registered caller,
|
|
479
|
+
honouring user_default and the explicit tier override.
|
|
480
|
+
2. If the resonance_map is unavailable or returns blanks, fall
|
|
481
|
+
back to ``client_runtime_profiles`` so we stay backward
|
|
482
|
+
compatible with pre-6.0.0 installs missing resonance_tiers.json.
|
|
483
|
+
"""
|
|
484
|
+
profile = resolve_client_runtime_profile(backend, preferences=preferences)
|
|
485
|
+
model = ""
|
|
486
|
+
effort = ""
|
|
487
|
+
try:
|
|
488
|
+
from resonance_map import resolve_model_and_effort
|
|
489
|
+
|
|
490
|
+
user_default = ""
|
|
491
|
+
if isinstance(preferences, dict):
|
|
492
|
+
user_default = str(preferences.get("default_resonance") or "").strip()
|
|
493
|
+
explicit_tier = (tier or "").strip() or None
|
|
494
|
+
mapped_model, mapped_effort = resolve_model_and_effort(
|
|
495
|
+
caller,
|
|
496
|
+
backend,
|
|
497
|
+
user_default=user_default or None,
|
|
498
|
+
explicit_tier=explicit_tier,
|
|
499
|
+
)
|
|
500
|
+
if mapped_model:
|
|
501
|
+
model = mapped_model
|
|
502
|
+
if mapped_effort:
|
|
503
|
+
effort = mapped_effort
|
|
504
|
+
except Exception:
|
|
505
|
+
# resonance_map missing or caller not registered — fall back to the
|
|
506
|
+
# legacy client_runtime_profiles path so nothing explodes.
|
|
507
|
+
pass
|
|
508
|
+
if not model:
|
|
509
|
+
model = profile.get("model", "")
|
|
510
|
+
if not effort:
|
|
511
|
+
effort = profile.get("reasoning_effort", "")
|
|
512
|
+
return model, effort
|
|
513
|
+
|
|
514
|
+
|
|
460
515
|
def build_interactive_client_command(
|
|
461
516
|
*,
|
|
462
517
|
target: str | os.PathLike[str],
|
|
463
518
|
client: str | None = None,
|
|
464
519
|
preferences: dict | None = None,
|
|
520
|
+
caller: str = "nexo_chat",
|
|
521
|
+
tier: str | None = None,
|
|
465
522
|
) -> tuple[str, list[str]]:
|
|
466
523
|
prefs = preferences or load_client_preferences()
|
|
467
524
|
selected = resolve_terminal_client(client, preferences=prefs)
|
|
468
525
|
target_path = str(Path(target).expanduser())
|
|
469
|
-
|
|
526
|
+
resolved_model, resolved_effort = _resolve_interactive_model_and_effort(
|
|
527
|
+
caller, selected, preferences=prefs, tier=tier
|
|
528
|
+
)
|
|
470
529
|
startup_prompt = _interactive_startup_prompt(selected)
|
|
471
530
|
|
|
472
531
|
if selected == CLIENT_CLAUDE_CODE:
|
|
@@ -476,10 +535,10 @@ def build_interactive_client_command(
|
|
|
476
535
|
"Claude Code launcher not found in PATH. Install `claude` first."
|
|
477
536
|
)
|
|
478
537
|
cmd = [claude_bin]
|
|
479
|
-
if
|
|
480
|
-
cmd.extend(["--model",
|
|
481
|
-
if
|
|
482
|
-
cmd.extend(["--effort",
|
|
538
|
+
if resolved_model:
|
|
539
|
+
cmd.extend(["--model", resolved_model])
|
|
540
|
+
if resolved_effort:
|
|
541
|
+
cmd.extend(["--effort", resolved_effort])
|
|
483
542
|
cmd.append("--dangerously-skip-permissions")
|
|
484
543
|
if startup_prompt:
|
|
485
544
|
cmd.append(startup_prompt)
|
|
@@ -495,10 +554,10 @@ def build_interactive_client_command(
|
|
|
495
554
|
bootstrap_prompt = _load_client_bootstrap_prompt(CLIENT_CODEX)
|
|
496
555
|
if bootstrap_prompt and not _codex_managed_initial_messages_enabled():
|
|
497
556
|
cmd.extend(["-c", _codex_initial_messages_config(bootstrap_prompt)])
|
|
498
|
-
if
|
|
499
|
-
cmd.extend(["-m",
|
|
500
|
-
if
|
|
501
|
-
cmd.extend(["-c", f'model_reasoning_effort="{
|
|
557
|
+
if resolved_model:
|
|
558
|
+
cmd.extend(["-m", resolved_model])
|
|
559
|
+
if resolved_effort:
|
|
560
|
+
cmd.extend(["-c", f'model_reasoning_effort="{resolved_effort}"'])
|
|
502
561
|
cmd.extend(["-C", target_path])
|
|
503
562
|
if startup_prompt:
|
|
504
563
|
cmd.append(startup_prompt)
|
|
@@ -548,8 +607,14 @@ def run_automation_interactive(
|
|
|
548
607
|
the interactive surface honours whatever the user selected.
|
|
549
608
|
"""
|
|
550
609
|
prefs = preferences or load_client_preferences()
|
|
610
|
+
# v6.0.4 — caller+tier propagate into the builder so interactive launches
|
|
611
|
+
# honour default_resonance (previously ignored for nexo chat).
|
|
551
612
|
resolved_client, cmd = build_interactive_client_command(
|
|
552
|
-
target=target,
|
|
613
|
+
target=target,
|
|
614
|
+
client=client,
|
|
615
|
+
preferences=prefs,
|
|
616
|
+
caller=caller,
|
|
617
|
+
tier=(tier or "").strip() or None,
|
|
553
618
|
)
|
|
554
619
|
launch_env = os.environ.copy()
|
|
555
620
|
if env:
|
|
@@ -616,10 +681,14 @@ def build_followup_terminal_shell_command(
|
|
|
616
681
|
client: str | None = None,
|
|
617
682
|
preferences: dict | None = None,
|
|
618
683
|
cwd: str | os.PathLike[str] | None = None,
|
|
684
|
+
caller: str = "nexo_followup_terminal",
|
|
685
|
+
tier: str | None = None,
|
|
619
686
|
) -> tuple[str, str]:
|
|
620
687
|
prefs = preferences or load_client_preferences()
|
|
621
688
|
selected = resolve_terminal_client(client, preferences=prefs)
|
|
622
|
-
|
|
689
|
+
resolved_model, resolved_effort = _resolve_interactive_model_and_effort(
|
|
690
|
+
caller, selected, preferences=prefs, tier=tier
|
|
691
|
+
)
|
|
623
692
|
prompt = f"NEXO: execute followup from file $(cat {followup_reference})"
|
|
624
693
|
|
|
625
694
|
if selected == CLIENT_CLAUDE_CODE:
|
|
@@ -629,10 +698,10 @@ def build_followup_terminal_shell_command(
|
|
|
629
698
|
"Claude Code launcher not found in PATH. Install `claude` first."
|
|
630
699
|
)
|
|
631
700
|
cmd = [claude_bin]
|
|
632
|
-
if
|
|
633
|
-
cmd.extend(["--model",
|
|
634
|
-
if
|
|
635
|
-
cmd.extend(["--effort",
|
|
701
|
+
if resolved_model:
|
|
702
|
+
cmd.extend(["--model", resolved_model])
|
|
703
|
+
if resolved_effort:
|
|
704
|
+
cmd.extend(["--effort", resolved_effort])
|
|
636
705
|
cmd.extend(["--dangerously-skip-permissions", prompt])
|
|
637
706
|
return selected, shlex.join(cmd)
|
|
638
707
|
|
|
@@ -647,10 +716,10 @@ def build_followup_terminal_shell_command(
|
|
|
647
716
|
bootstrap_prompt = _load_client_bootstrap_prompt(CLIENT_CODEX)
|
|
648
717
|
if bootstrap_prompt and not _codex_managed_initial_messages_enabled():
|
|
649
718
|
cmd.extend(["-c", _codex_initial_messages_config(bootstrap_prompt)])
|
|
650
|
-
if
|
|
651
|
-
cmd.extend(["-m",
|
|
652
|
-
if
|
|
653
|
-
cmd.extend(["-c", f'model_reasoning_effort="{
|
|
719
|
+
if resolved_model:
|
|
720
|
+
cmd.extend(["-m", resolved_model])
|
|
721
|
+
if resolved_effort:
|
|
722
|
+
cmd.extend(["-c", f'model_reasoning_effort="{resolved_effort}"'])
|
|
654
723
|
cmd.extend(["-C", target_cwd, prompt])
|
|
655
724
|
return selected, shlex.join(cmd)
|
|
656
725
|
|
package/src/resonance_map.py
CHANGED
|
@@ -173,6 +173,10 @@ USER_FACING_CALLERS: dict[str, str] = {
|
|
|
173
173
|
"nexo_chat": USE_USER_DEFAULT_SENTINEL,
|
|
174
174
|
"desktop_new_session": USE_USER_DEFAULT_SENTINEL,
|
|
175
175
|
"nexo_update_interactive": USE_USER_DEFAULT_SENTINEL,
|
|
176
|
+
# v6.0.4 — dashboard "Open followup in Terminal" spawns a fresh
|
|
177
|
+
# interactive Claude/Codex session. Treat it like nexo_chat so the
|
|
178
|
+
# user's default_resonance preference flows through.
|
|
179
|
+
"nexo_followup_terminal": USE_USER_DEFAULT_SENTINEL,
|
|
176
180
|
}
|
|
177
181
|
|
|
178
182
|
# System-owned callers. Grouped thematically for readability.
|