- Add `recall.maxCharsPerMemory` and `recall.maxTotalRecallChars` with defaults of `0`, which do not alter existing behavior. Users can opt in by setting positive values to cap injected memory context.
- Apply the budget after L1 search and before `<relevant-memories>` injection, preserving score order while truncating oversized entries and dropping overflow.
- Document the new guards in README, README_CN, and `openclaw.plugin.json`.
Removes tool exposure from the standalone `LLMRunner` when `enableTools=false`.
Some standalone text-only tasks, such as L1 extraction, expect plain text output and do not need tool access. Passing even a read-only tool subset can still encourage tool-calling behavior on OpenAI-compatible backends, which makes this path less stable than necessary.
With this change:
- `enableTools=true` keeps the existing sandboxed tool behavior
- `enableTools=false` sends no tools at all
The CMD script writes MODEL_API_KEY to .env as OPENAI_API_KEY but
does not include it in config.yaml's model section. Hermes with
provider: custom reads api_key from model.api_key in config.yaml,
not from OPENAI_API_KEY in .env. This causes 401 Authentication
Fails when users start a conversation inside the container.
Fix: add api_key field to the generated config.yaml model section.
If install_hermes_memory_tencentdb.sh is invoked directly by the root
user (e.g. fresh server with root SSH login), the prior logic:
USERNAME=$(whoami) # → "root"
if [ "$(id -u)" -eq 0 ]; then
su - $USERNAME -c "bash $TEMP_SCRIPT" # → su - root → root → loops
fi
would spin forever: ``su - root`` enters a fresh root shell that re-runs
the script, which sees EUID=0 again and ``su -``-s itself once more.
Symptom (per issue #20):
[memory-tencentdb] Running as root, switching to root for installation...
[memory-tencentdb] Running as root, switching to root for installation...
... (only Ctrl+C stops it)
Fix:
1. ``USERNAME`` resolution adds two precedence steps before
``$(whoami)`` so admins running ``sudo bash install.sh`` end up
installing for the original user instead of for root:
a. ``INSTALL_AS_USER`` env override (explicit admin choice)
b. ``SUDO_USER`` (sudo's own record of the calling user)
c. ``whoami`` (final fallback)
2. The ``id -u == 0`` branch now skips the ``su -`` step when the
target user is also root — that's the recursion-trigger case. The
script proceeds inline as root for the rest of the install.
3. A new ``elif`` arm logs a clear ``"Running as root; target user is
also root — installing in place."`` so the operator sees what's
happening.
Verified by dry-run simulation of 5 scenarios:
| Case | Branch | USERNAME |
| --------------------------------------- | ------------- | -------- |
| root SSH direct (#20 reproducer) | INLINE | root |
| non-root user direct | NORMAL | <user> |
| sudo bash install.sh from non-root user | SU | <user> |
| root + INSTALL_AS_USER=bar | SU | bar |
| root + INSTALL_AS_USER=root | INLINE | root |
Closes#20.
Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>
UNSAFE_CHAR_RE included the surrogate range [\uD800-\uDFFF] without the `u`
flag, so JS treated strings as UTF-16 code units and stripped each half of
every well-formed non-BMP code point. sanitizeText and sanitizeJsonLine
therefore destroyed emoji, CJK Extension B, math bold, etc. in tool params,
tool results, and ref-md archives.
Adding the `u` flag makes paired surrogates combine into a single code point
before matching, so the [\uD800-\uDFFF] entry now matches only lone (malformed)
surrogates, which is the original intent. All other entries (replacement char,
C0/C1 controls, zero-width chars, line separators, BOM) keep their behavior.
Added a vitest suite covering the preserved and stripped cases.
Closes#30