nexo-brain 7.9.30 → 7.9.31
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 +3 -1
- package/package.json +1 -1
- package/src/call_model_raw.py +38 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.31",
|
|
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,9 @@
|
|
|
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 `7.9.
|
|
21
|
+
Version `7.9.31` is the current packaged-runtime line. Patch release over `7.9.30`: fixes a wire-level bug where ``call_model_raw`` was sending ``stop_sequences=["\n", ".", " "]`` by default, which the current Anthropic Messages API rejects with HTTP 400 ``each stop sequence must contain non-whitespace``. The default is now ``None`` (no ``stop_sequences`` field sent) since ``max_tokens=3`` already caps the yes/no classifier output. A local guard rejects whitespace-only caller values up front so the error shows where the caller is, not as a remote 400. Also removes an internal design document that did not belong in the open-source distribution.
|
|
22
|
+
|
|
23
|
+
Previously in `7.9.30`: hotfix for a missing ``import sys`` in ``src/agent_runner.py`` that ruff F821 caught in CI and blocked the 7.9.29 publish workflow before any npm artifact shipped. ``nexo-brain@7.9.30`` is the first npm release that carries the 7.9.29 override-path hardening.
|
|
22
24
|
|
|
23
25
|
Previously in `7.9.29`: hardening pass on the optional LLM endpoint and auth provider override path. The bearer is now passed to the Anthropic SDK via `auth_token` so it lands in the standard `Authorization: Bearer` header (7.9.28 sent it as `X-Api-Key` and any compatible proxy rejected every request with 401). The Brain config directory is resolved on each call instead of cached at import, so LaunchAgent crons that export `NEXO_HOME` via a wrapper now reach the right `~/.nexo/config/`. The `Idempotency-Key` header accepts a caller-provided value so application-level retries reuse the same dedup key. Override mode is strict about its bearer source: if `auth_provider.json` is missing or the helper fails, the call raises `ClassifierUnavailableError` instead of falling back to the operator's real `ANTHROPIC_API_KEY`, which would otherwise leak to the custom proxy as a second header. A new end-to-end test suite drives the real SDK against a local `http.server` and asserts on captured wire headers and body, complementing the SDK-mock unit tests.
|
|
24
26
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.31",
|
|
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",
|
package/src/call_model_raw.py
CHANGED
|
@@ -469,9 +469,16 @@ def _call_anthropic_raw(
|
|
|
469
469
|
"model": wire_model,
|
|
470
470
|
"max_tokens": max_tokens,
|
|
471
471
|
"temperature": temperature,
|
|
472
|
-
"stop_sequences": stop_sequences,
|
|
473
472
|
"messages": [{"role": "user", "content": prompt}],
|
|
474
473
|
}
|
|
474
|
+
if stop_sequences:
|
|
475
|
+
# Anthropic API rejects whitespace-only stop sequences with
|
|
476
|
+
# 400 ``each stop sequence must contain non-whitespace``. The
|
|
477
|
+
# caller-validation in call_model_raw filters these out before
|
|
478
|
+
# we reach this point; the empty/None case is also covered by
|
|
479
|
+
# the truthy check above so we omit the field entirely instead
|
|
480
|
+
# of sending ``stop_sequences: null`` to the wire.
|
|
481
|
+
kwargs["stop_sequences"] = stop_sequences
|
|
475
482
|
if system:
|
|
476
483
|
kwargs["system"] = system
|
|
477
484
|
|
|
@@ -582,7 +589,20 @@ def call_model_raw(
|
|
|
582
589
|
"enforcer_classifier".
|
|
583
590
|
max_tokens — hard cap on output tokens. Default 3 (yes/no only).
|
|
584
591
|
temperature — sampling temperature. Default 0.0 (deterministic).
|
|
585
|
-
stop_sequences — early-stop strings. Default
|
|
592
|
+
stop_sequences — early-stop strings. Default ``None`` (no stop
|
|
593
|
+
sequence sent on the wire). Anthropic's API
|
|
594
|
+
rejects whitespace-only entries with
|
|
595
|
+
``each stop sequence must contain
|
|
596
|
+
non-whitespace`` (HTTP 400), so the previous
|
|
597
|
+
default of ``["\\n", ".", " "]`` made every
|
|
598
|
+
``enforcer_classifier`` request fail in
|
|
599
|
+
production. ``max_tokens=3`` already serves as
|
|
600
|
+
the hard cap for yes/no classification, so a
|
|
601
|
+
stop sequence is unnecessary by default.
|
|
602
|
+
Callers that want a deterministic stop can
|
|
603
|
+
pass e.g. ``["."]``; whitespace-only entries
|
|
604
|
+
are rejected locally with
|
|
605
|
+
``ClassifierUnavailableError``.
|
|
586
606
|
timeout — per-request timeout in seconds. Default 10.0.
|
|
587
607
|
system — optional system prompt. Default None (provider default).
|
|
588
608
|
idempotency_key — optional opaque token attached as
|
|
@@ -612,8 +632,22 @@ def call_model_raw(
|
|
|
612
632
|
Callers MUST catch this and fall back to a safer default. Fase 2 spec
|
|
613
633
|
0.20 is explicit: silence is not obedience. Never fail-open.
|
|
614
634
|
"""
|
|
615
|
-
if stop_sequences is None:
|
|
616
|
-
|
|
635
|
+
if stop_sequences is not None:
|
|
636
|
+
# Anthropic API: ``each stop sequence must contain
|
|
637
|
+
# non-whitespace`` (HTTP 400). Surface the configuration error
|
|
638
|
+
# locally instead of letting Anthropic 400 the request — and,
|
|
639
|
+
# in override mode, instead of letting the proxy translate that
|
|
640
|
+
# 400 into a misleading ``503 all_providers_down``.
|
|
641
|
+
invalid = [
|
|
642
|
+
repr(s) for s in stop_sequences
|
|
643
|
+
if not isinstance(s, str) or not s.strip()
|
|
644
|
+
]
|
|
645
|
+
if invalid:
|
|
646
|
+
raise ClassifierUnavailableError(
|
|
647
|
+
"stop_sequences contains whitespace-only or non-string "
|
|
648
|
+
f"entries: {', '.join(invalid)}; Anthropic API requires "
|
|
649
|
+
"every stop sequence to contain non-whitespace"
|
|
650
|
+
)
|
|
617
651
|
|
|
618
652
|
# Local imports to avoid circulars and keep agent_runner.py decoupled.
|
|
619
653
|
from client_preferences import ( # type: ignore
|