Preserve result.trace_id across plugin HTTP wrappers, include it in commit success and failure logs, and surface it in user-visible commit confirmations where supported.
Issue #3522 — the OpenClaw plugin's `config.apiKey` only accepted a plain
string, resolved through local `${ENV_VAR}` interpolation. `INSTALL*.md`
documented this as a known limitation: users who store their other OpenClaw
provider credentials (LLM, TTS, MCP servers) through the standard
`{source, id[, provider]}` SecretRef mechanism (env / file mount /
exec-backed vault such as 1Password, Vault, gopass) had to keep the
OpenViking key as cleartext inside `openclaw.json`.
### config.ts — `string | OpenVikingSecretRef` widening
* Add `OpenVikingSecretRef = "env"|"file"|"exec"` discriminated union type,
matching the shape OpenClaw core uses for its own credential fields
(`env` + `file` implemented in-plugin, `exec` forwarded to `child_process`
so providers like `@transmitt0r/openclaw-plugin-onepassword` can manage
the OpenViking key without SDK coupling).
* Add `resolveSecret()` resolver with explicit, actionable errors:
- env: unset var = throw, no silent empty fallback
- file: `~` expanded, UTF-8 read, whitespace trimmed; unreadable file
rethrows with the OpenViking field name prefixed so config misconfigs
surface with a clear label and path
- exec: lazy `require("node:child_process").execFileSync(provider,[id])`,
stdout trimmed, 15s timeout; errors prefixed with provider + id
- unknown source / missing id / missing exec provider = explicit throw
* `memoryOpenVikingConfigSchema.parse()` widens `rawApiKey` to
`string | OpenVikingSecretRef`, then passes it through
`resolveSecret(rawApiKey, "config.apiKey")` *before* the existing
`resolveEnvVars` pass. Plain strings transparently fall through
`resolveSecret` unchanged, so `${ENV_VAR}` interpolation is preserved
100% backward-compatibly.
* `OPENVIKING_API_KEY` env fallback is unchanged and triggers only when the
`apiKey` config key is absent — a user who deliberately sets `apiKey: ""`
still gets "" (explicitly unauthenticated), not the env fallback.
* `uiHints.apiKey.help` documents the SecretRef shape and recommends it.
### openclaw.plugin.json — widening schema + UI hints
* `configSchema.properties.apiKey` becomes `oneOf: [string, env ref, file ref, exec ref]`.
Each object variant has a `title`, `additionalProperties: false`,
`required`, and explicit description per field, so OpenClaw's config UI
can render them individually instead of showing a generic JSON object blob.
* `uiHints.apiKey.help` matches the new config.ts wording.
### INSTALL.md / INSTALL-ZH.md — SecretRef usage tables
Replace the old "plaintext / chmod 0600" caveat bullet with a 3-row table
(env / file / exec) showing example JSON + notes (Kubernetes secretKeyRef
mount for `file`, 1Password `op://` URL convention for `exec`). The
backward-compat string path is retained at the end of the new bullet so
existing deployments that haven't migrated yet still get the old permission
advice — no surprise behaviour for upgrading users.
### tests/ut/config.test.ts — SecretRef regression suite (10 new cases)
Under a new `describe("… SecretRef (#3522)")`:
1. Backward compat: `${OV_KEY}` interpolation still resolves.
2. env source — happy path with a fresh env var.
3. env source — unset var throws, no silent fallback.
4. file source — real `mkdtemp`-created file, trimmed whitespace. Cleanup
in `afterEach`.
5. file source — missing-path error message contains readable label + path.
6. exec source — `vi.spyOn(child_process.execFileSync)` asserts provider +
args, stdout trimmed.
7. exec source — missing `provider` field errors.
8. Schema validation — unknown `source` and missing `id` each throw with
error messages that name the problem.
9. Env fallback boundary — explicit `apiKey: ""` is NOT overridden by
OPENVIKING_API_KEY, but `apiKey` absent IS (backward-compat behaviour
contract pinned with a test so future refactors can't regress).
Covers every branch inside `resolveSecret()`, plus the backward-compat
contracts issue #3522 called out.
* fix(openclaw): restore peer_role routing
The plugin refactor stopped applying peer_role to message attribution and data-plane actor headers, causing assistant mode to tag user messages and route every request as the agent. Restore role-aware routing across context and tool flows.
* fix(openclaw): close peer routing isolation gaps
* fix(openclaw): separate message peers from actor scope
* feat(grep): integrate VikingDB bm25 keyword search for grep engine
* fix(grep): address CI review feedback: max-size eviction to _count_cache, use Literal, Split regex alternation into individual keywords for bm25 (max 10)
* fix(schema): use dynamic __version__ for schema_version and handle dev suffixes in version comparison
* fix(schema): upsert data to vikingdb lack of content
* chore: add benchmark for retrieval
* fix(grep): vikingdb return 200 and no results means no matching content, not necessary to fallback to local fs
* fix(benchmark): sub uri args; add report
* refactor: code format by ruff
* optimize: move grep config (engine and switch_to_remote_threshold) to ov.conf
* optimize: auto adapt remote_return_limit by agg API; rm unnecessary params in keywords search
* fix: adjust benchmark scripts
* fix(grep): store full content for BM25; use PathScope depth; reduce redundant API calls
* refactor: new benchmark
* fix: step1 add resource by real code data
* feat(benchmark): split grep benchmark into effectiveness/performance suites with async reindex
* optimize (benchmark): adjust keywords and ground truth for testing
* fix: truncate 64KB for content field
* optimize: effectiveness add resource plainly
* optimize: change param use of SearchByKeywords from "keywords" to "query"
* optimize(benchmark): refactor effectiveness scripts
* optimize: ensure raw data for content field
* optimize: fulltext analyzer's stop-words only use symbols
* fix: adapt to new ov cli for benchmark
* optimize: reuse file content to avoid re-read AGFS file
* optimize: tune grep vikingdb defaults and refresh bm25 benchmark scripts
* optimize: benchmark client timeout
* update README
* fix: rm unused param
* fix: default values in docs
* optimize: increase truncate byte size to 1MB for content field for VikingDB
* fix(logger): harden queued stream logging (#2786)
* fix(logger): replace StreamHandler with QueueHandler+QueueListener to prevent thread deadlock
When log.output='stdout' (default) and the server is managed by systemd,
concurrent log writes can deadlock because logging.StreamHandler holds a
thread lock across stream.flush() which blocks on systemd-piped file I/O.
During session.commit() phase 2, multiple async coroutines (memory
extraction, summarization) concurrently call logger.info()/warning()
with large payloads. The first thread's flush() blocks on the pipe,
while all subsequent threads block on handler.acquire() forever.
This permanently silences the server log and prevents _write_done_file()
from executing, leaving phase 2 hanging without .done.
Fix: use QueueHandler + QueueListener from stdlib logging.handlers
(Python 3.2+). QueueHandler.emit() does queue.put(record) with no lock
or I/O, returning immediately. QueueListener has a dedicated single
thread as the sole consumer touching the real StreamHandler, making
lock contention impossible.
Changes in _create_log_handler(): stdout/stderr branches now create
a shared QueueListener with unbounded queue, returning QueueHandler
instances to callers. _build_standard_handler() delegates formatter
and filter setup to the real handler in the listener thread.
Closes: #2752
* fix(logger): harden queued stream logging
---------
Co-authored-by: njuboy11 <njuboy11@users.noreply.github.com>
---------
Co-authored-by: Qin Haojie <qinhaojie.exe@bytedance.com>
Co-authored-by: njuboy11 <njuboy11@users.noreply.github.com>
Treat failed session archives as terminal skipped state so later commits can continue, and replace OpenClaw's fixed auto-commit token threshold with a context-window ratio while tolerating the deprecated config key.
Co-authored-by: LinQiang391 <linqiang391@users.noreply.github.com>
Bump plugin to 2026.6.18 across package.json, package-lock.json and install-manifest. Raise minOpenvikingVersion 0.2.9 to 0.4.1 and add recommended OpenClaw/OpenViking versions. Update the guide version matrix and add a manifest-contract test that locks the compatibility floors/recommended versions and keeps pluginVersion in sync with package.json version.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse the OpenViking client for auto-recall prechecks so remote /health probes carry the same auth and tenant headers as normal requests, preventing false recall skips behind authenticated gateways.