Commit Graph
387 Commits
Author SHA1 Message Date
AutoCoderandCodex 15e5284062 fix(openclaw): read L2 content in memory recall (#2002)
Co-authored-by: Codex <codex@example.com>
2026-05-13 15:06:27 +08:00
Evo 22e86a7e18 docs(opencode-plugin): update Memory Recall section for chat.message hook (#1977) (#2004) 2026-05-13 11:13:30 +08:00
Hao Zhe 81d1b5afd7 feat(langchain): add LangChain and LangGraph context adapters (#1964)
* feat(langchain-langgraph): add adapter primitives

* feat(langchain-langgraph): add context backend lifecycle

* fix(langchain-langgraph): harden context backend integration

* fix(langchain-langgraph): accept canonical store result URIs

* docs(langchain): point users to runnable examples

* docs(langchain): add missing integration examples

* refactor(langchain): address integration review feedback

* fix(langchain): address review-blocking integration bugs

* fix(langchain): honor user ids and safe store filters

* fix(langchain): reject unsupported store TTL writes
2026-05-12 16:28:11 +08:00
Jiahao Cao 31a31ff4d1 refactor(plugin):Merge OpenCode plugins (#1859)
* Merge opencode plugins

* update:readme&install docs

* Fix Opencode plugin packaging issues

Rename wrapper to .mjs, clean install docs, align README/INSTALL wording with the current directory layout, remove invalid README_ZH.md from package files, and pin @opencode-ai/plugin version.

* Address OpenCode plugin review feedback - Remove OpenViking server auto-start logic from the plugin runtime - Replace fixed-interval auto commits with lifecycle-boundary commits - Commit sessions on compaction, deletion, error, and plugin shutdown - Exclude source-install wrapper files from the npm package - Update docs to clarify wrapper usage and remove deprecated config fields

* fix(opencode-plugin): persist memory recall via chat.message synthetic parts

Replace experimental.chat.messages.transform recall injection with chat.message.

Inject recalled memories as hidden synthetic text parts persisted in session history.

Preserve idempotency with relevant-memories marker detection and update README wording.
2026-05-12 15:41:43 +08:00
A0nameless0man 32d9aa17a2 refactor(opencode-plugin): migrate auto recall from chat.messages.transform to chat.message hook (#1977)
Replace experimental.chat.messages.transform (stateless, non-persistent) with chat.message + synthetic:true parts for persistent injection. Eliminates context drift, redundant searches, and poor KV-cache hit rate across tool call continuations. Removes dead code: RecallMessagePart, RecallWithParts, extractLatestUserText, appendToLastTextPart. Adds runAutoRecall() shared function. Net -28 lines (-82/+54).
2026-05-12 15:34:06 +08:00
Evo 4237d5018f docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947 (#1948)
* docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947

* docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947

* docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947

* docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947

* docs(retrieval): align score_propagation_alpha default 0.5→1.0 with #1947
2026-05-11 18:00:39 +08:00
Mingjian QueandGPT-5.5 0073ce7e05 fix(openclaw): split OpenViking import tools (#1946)
Replace the ambiguous OpenClaw ov_import surface with explicit add_resource and add_skill tools and slash commands.

Guide media attachment imports through the existing OpenViking temp-upload and resource import APIs instead of invented upload endpoints.

Update docs, plugin manifest, and unit coverage for the split import commands.

Co-authored-by: GPT-5.5 <noreply@openai.com>
2026-05-10 15:51:32 +08:00
LinQiang391andLinQiang391 d0ab0d4700 chore: release setup helper 0.3.0 (#1941)
Co-authored-by: LinQiang391 <linqiang391@users.noreply.github.com>
2026-05-09 17:10:29 +08:00
Mingjian Que 0a960dc538 fix(openclaw): add plugin load path before enable (#1913) 2026-05-09 09:57:48 +08:00
t0saki 31bcfd2bd7 feat(claude-code-plugin): session-start profile injection, /ov status command, tool-output capture cleanup (#1914)
* feat(claude-code-plugin): inject user profile + memory listings on session start

Previously, profile/preferences/entities only reached the agent when the
user's prompt happened to trigger semantic auto-recall (UserPromptSubmit).
Trivial first prompts (e.g. `git status`) left the agent with no identity
context.

Session-start hook now always builds a profile injection block —
profile.md plus a description-annotated recursive ls of preferences/ and
entities/ — composed into the same <openviking-context source="..."> envelope
that already carries archive context on resume/compact. Subagents are
unaffected (they go through subagent-start.mjs).

Budget enforcement uses a CJK-aware token estimate (codepoint >= 0x3000
counts at 1.5 tokens, else chars/4) so a "10k token budget" reflects real
tokenizer cost for Chinese content rather than the 4-6× undercount the
flat chars/4 heuristic produces.

Profile truncation on overflow keeps the head (identity facts) and tail
(most-recent timeline events), eliding the noisy middle, instead of
hard-cutting at the head.

Each invocation mirrors the composed payload to ~/.openviking/last_inject.md
for user-facing audit.

New env vars / config (config.mjs):
- OPENVIKING_NO_AUTO_INJECT (bool, default false) — kill switch for the new
  injection; auto-recall is unaffected.
- OPENVIKING_PROFILE_TOKEN_BUDGET (int, default 10000) — total cap for the
  block; profile gets up to half, listings split the remainder.

* feat(claude-code-plugin): add /ov slash command for plugin status

Tight five-section status report covering: server URL + /health latency,
resolved identity (account/user/agent), last session-start injection
(size, age, audit-file path), last auto-recall (item count, top score,
token budget use), and toggle state for the three injection paths
(auto-inject / auto-recall / auto-capture).

Final line shows where url + api_key were actually resolved from (env vs
ovcli.conf vs default), per the same priority chain config.mjs uses —
rather than enumerating every file on disk that *could have* contributed.

Reuses existing ~/.openviking/state/ files (last-recall.json,
last-session-event.json) and the audit file written by session-start.mjs;
no new server-side state.

* fix(cc-memory-plugin): drop tool output by default; keep tool input verbatim

After #1849 / #1850 the plugin captured tool I/O at a 4 KB-per-block cap
under one knob (TOOL_BLOCK_MAX_CHARS = 4096). Field thinking surfaced
two refinements:

1. **Tool *output* (tool_result content) is mostly noise for memory
   extraction.** Memory extraction cares about user preferences, project
   context, decisions, and what the agent did — not about the bytes a
   tool happened to return. The agent's prose around the tool call almost
   always summarizes the meaningful bit ("I checked the docs and confirmed
   X"); the raw 4 KB of fetched markdown adds nothing the prose doesn't
   already cover. Storing it just inflates session size and extraction
   token cost.

   Renamed TOOL_BLOCK_MAX_CHARS → TOOL_RESULT_MAX_CHARS and changed
   default to 0. When 0, tool_result blocks are dropped entirely. Operators
   wanting replay-style archives can set >0 to retain truncated output.

2. **Tool *input* should not be truncated.** Inputs are agent-authored
   (URLs, file paths, queries, commands). They're usually short, and a
   pathologically long input is itself signal worth surfacing — a
   memory extractor seeing "agent ran `bash` with a 10 KB script" learns
   something the truncated form would hide.

   Replaced truncateForLog(block.input) with formatToolInput(block.input),
   which JSON-serializes structured inputs but applies no length cap.

Both changes apply symmetrically to auto-capture.mjs and subagent-stop.mjs.

* fix(claude-code-plugin): address Copilot review on PR #1914

Nine review comments, all valid:

profile-inject.mjs:
- header doc said chars/4 but estimateTokens is CJK-aware → fixed
- estimateTokens now exported so callers can log token counts that match
  the budget logic
- elideProfile derived maxChars from maxTokens*4, but the estimator counts
  CJK at 1.5 tokens/char → for CJK profiles the truncated string could
  still bust the token cap. New tokensToCharsBudget() converts using the
  content's actual CJK density
- formatListing always included header + first entry, so very small budgets
  silently violated the cap. Now: stub-out when header alone exceeds
  budget; only emit "+N more" tail when it fits; close silently otherwise
- profileBytes was UTF-16 char count, labeled "B" → renamed to profileChars

session-start.mjs:
- header doc said budget=5000, code default is 10000 → doc fix
- local estimateTokens was flat chars/4 while injection enforces CJK-aware
  budget → import the shared estimator from profile-inject so logs match
  reality
- /health probe ran even when no injection path would fire (e.g.
  NO_AUTO_INJECT=1 + startup) → short-circuit before the network call
- profileBytes references updated to profileChars

ov-status.mjs:
- header doc said "Active config file + env overrides" but the bottom
  block was removed earlier → header fixed to describe Auth source
- auth source detection only considered env + ovcli.conf; could misreport
  "(none)" when key was actually coming from ov.conf claude_code.apiKey
  or server.root_api_key. Now mirrors config.mjs's full priority chain
  (env → ovcli.conf → ov.conf → default)
2026-05-08 18:52:44 +08:00
LinQiang391andLinQiang391 72a3cd29f0 feat(openclaw-plugin): support OpenClaw install and ClawHub release flow (#1904)
Squashes OpenClaw plugin install compatibility, setup helper source-build support, built dist output, and ClawHub release workflow updates into one publish commit.

Co-authored-by: LinQiang391 <linqiang391@users.noreply.github.com>
2026-05-08 17:38:04 +08:00
a5649a4d20 chore(agent-tools): converge MCP tool names (#1851)
* chore(agent-tools): converge MCP tool names

Rename model-visible explicit memory tools without adding a new agent HTTP API or changing existing CLI behavior.

Keep OV server /mcp store renamed to remember while preserving its existing session write and commit implementation.

Rename Codex MCP openviking_store to remember and keep its original session create/message/commit/cleanup flow; leave OpenClaw memory_store and ov add-memory unchanged.

Co-authored-by: GPT-5.5 <noreply@openai.com>

* refactor(agent-tools): align MCP and search tool names

Apply the search-tool alignment patch across Codex MCP, OpenClaw, OV MCP docs, and focused tests.

Co-authored-by: wlff123 <wulf234@163.com>

Co-authored-by: GPT-5.5 <noreply@openai.com>

---------

Co-authored-by: GPT-5.5 <noreply@openai.com>
2026-05-08 10:50:20 +08:00
Evo f10e900433 docs(openclaw-plugin): drop agent_end from README hook list per #1866 (#1871)
#1866 explicitly removed the agent_end hook from index.ts because OpenClaw 5.2 blocks that typed hook for non-bundled plugins without conversation access; session routing is now recorded through session_start/session_end. README.md and README_CN.md still listed agent_end in the hook-layer summary.
2026-05-07 21:10:48 +08:00
t0saki acec33bb5f fix(server,plugin): readable OV session id + MCP store role_id (#1895)
* refactor(claude-code-plugin): readable OV session id (cc-<uuid>__agent-<id>)

Replace the SHA-256-derived `cc-<hash>` form with a literal embedding of the
CC session_id, so OV/CC ids can be matched by eye instead of via shasum.
Subagent isolation still works by appending `__agent-<agentId>` to the parent
id, preserving lineage in the string itself.

Old `cc-<hash>` sessions are left untouched (no migration); they expire
naturally as users start new CC sessions.

Docs (zh/en) gain a short subsection explaining the format and where to find
the live cc_session_id ↔ ov_session_id pair (~/.openviking/state/last-capture.json).

* fix(server): MCP store now resolves role_id via shared ctx helper

Messages stored through the MCP `store` tool persisted with `role_id=null`
because that path called `Session.add_message` directly, skipping the HTTP
router's `_resolve_message_role_id` fallback (user.user_id for role=user,
user.agent_id for role=assistant).

Lift the resolver onto `RequestContext.resolve_role_id(role, override=None)`
so both call paths share one implementation:
- HTTP `POST /api/v1/sessions/{id}/messages` now calls
  `_ctx.resolve_role_id(request.role, request.role_id)`.
- MCP `store` tool calls `ctx.resolve_role_id(msg.role)` per message.

Drop the now-vestigial `http_request: Request` parameter from the HTTP
add_message handler (the local resolver was the only thing using it).

* fix(server): address copilot review on PR #1895

- identity.py: rename `role` → `message_role` in resolve_role_id signature so
  it doesn't shadow `RequestContext.role` (the authz role). Also adds blank
  line after ToolContext docstring to satisfy ruff format.
- tests/server/test_api_sessions.py: drop now-unused `http_request=...` and
  the `auth_mode` / `api_key_manager` plumbing from `_call_add_message_route`
  helper and its call sites — these were only needed by the resolver's stale
  `http_request` parameter, which the previous commit deleted.
- tests/server/test_mcp_endpoint.py: add regression test asserting MCP `store`
  now passes the resolved role_id (user.user_id for user, user.agent_id for
  assistant) to Session.add_message. Also fixes a pre-existing import bug
  (`list_dir` → `ls`) that was preventing the whole file from being collected.
2026-05-07 19:22:53 +08:00
A0nameless0man 437cf314f1 fix(deploy): Helm readiness probe 改用 /ready 端点 (#1884)
K8s readiness probe 应使用 /ready 端点区分进程存活和可服务流量。
/ready 检查 AGFS、VectorDB、APIKeyManager 等子系统健康状况。
livenessProbe 保持不变继续使用 /health。
2026-05-07 16:52:16 +08:00
t0saki 268147d110 feat(claude-code-plugin): OpenViking statusline (opt-in) (#1890)
* feat(claude-code-plugin): add OpenViking statusline (opt-in)

A one-line OV status renders under the CC input box: server health,
last-turn recall stats, pending capture, and queue alerts. Network
calls share a 5 s file cache and have a 250 ms hard timeout so the
statusline never blocks render.

- scripts/statusline.mjs: main entry, ANSI degrade, 80-char cap
- scripts/lib/state.mjs: atomic JSON state writer + TTL reader
- scripts/lib/server-probe.mjs: cached /health (+ /observer/queue)
- auto-recall / auto-capture: write last-recall.json / last-capture.json
- setup-helper/install.sh: opt-in prompt; replace-or-skip for existing
  user statusline; backup + restore-instructions
- bump plugin version 0.2.0 -> 0.3.0

* fix(claude-code-plugin): give /observer/queue its own 250ms budget

Queue probe was sharing the /health 250 ms budget; on remote servers
where /health used 200ms+, the queue probe got ~50ms or was skipped
entirely, so queue_healthy flapped between false (when /health was
fast) and null (when /health was slow). Result: ⚠ queue badge appeared
intermittently even when the queue was consistently unhealthy.

Worst-case statusline latency goes from 250ms to 500ms; typical case
is unchanged (~150ms) since both endpoints respond in tens of ms when
the server is healthy.

* fix(claude-code-plugin): loosen statusline timeout to 1s, show archive count

- 250ms was too aggressive for remote OV servers; ordinary network jitter
  (200-400ms /health) was producing spurious "OV ✗ offline" flicker.
  Bumped to 1s per endpoint. Worst case render is now ~2s but the 5s
  cache amortises this to once per 5s window per session.

- pending_tokens is a sawtooth: it climbs to commit_threshold then snaps
  to 0 on commit. Showing only "X/20k tok" of a long conversation read
  as "we only captured X tokens", which hid the work already archived.
  Now the statusline also shows "N arch" — the running commit_count
  pulled from the OV session metadata. So a long session now shows
  e.g. "✎ 573/20k tok · 2 arch" instead of just "✎ 573/20k tok".

* fix(claude-code-plugin): drop ⚠ queue badge — false-alarm by design

QueueObserver.is_healthy() is derived from QueueManager.has_errors(),
which is `any(q._error_count > 0 for q in queues)`. _error_count is a
lifetime cumulative counter that never resets, so any server with a
single transient embedding failure ever flips is_healthy to false
forever — even when the next 1000 jobs all succeed.

Real example from a production server: 41 jobs processed, 2 historic
errors (95%+ success rate), is_healthy returns false. The badge then
appears constantly for users whose OV experience is fine.

Removing the badge and the second network round-trip. Connectivity
(OV ✓), recall activity (↩ N mem), and capture progress (✎ N/20k arch)
already cover whether OV is functioning end-to-end.

* feat(claude-code-plugin): four new statusline signals

- ↩ N mem (0.92): max recall score appended in parens. Quality hint
  without an extra segment. auto-recall.mjs now writes top_score in
  last-recall.json.

- ✗ N dropped: turns that auto-capture failed to push this batch. Not
  sticky — auto-capture overwrites last-capture.json each Stop hook,
  so transient failures clear themselves on next success. Sustained
  failures stay visible (which is when the user needs to know).

- 🔗 resumed / 🔗 compact: session-start.mjs writes a 1-min TTL
  event when CC source is resume or compact. Lets the user see that
  OV did re-hydrate context across restarts instead of having to
  guess.

- +N today: cross-session daily commit_count. auto-capture maintains
  daily-stats.json (resets on date rollover). Hidden when 0 to keep
  fresh-day mornings unobtrusive. Distinct from per-session "M arch"
  which only counts the current CC session.

Truncation order verified: server → recall → capture → dropped (alert)
→ resumed (info) → today (info). 80-char cap drops the lowest-priority
tail when the line gets crowded.

* fix(claude-code-plugin): drop "tok" unit from statusline size numbers

Recall side: `tokens_used` is a chars/4 heuristic (estimateTokens in
auto-recall.mjs), not real tokens. For CJK-heavy text the heuristic
underestimates by 2-4x, so labelling it "tok" is misleading.

Capture side: `pending_tokens` comes from the server, but the server's
own counter is also approximate. Mixing the two under the same label
invites the wrong mental model.

Just drop the unit. The magnitude is meaningful on its own (1.2k =
medium injection, 573/20k = 3% of next archive). Configuration field
names (recallTokenBudget, commitTokenThreshold) keep "Token" so we
don't churn user-facing config.

* fix(claude-code-plugin): drop recall size number — heuristic was misleading

The "1.2k" between mem count and latency was estimateTokens(text) =
ceil(text.length / 4) on the assembled injection block. For CJK-heavy
content the heuristic underestimates by 2-4x, which is enough that
showing the number does more harm than presenting count + score +
latency alone.

Capture side keeps "573/20k" because the server reports pending_tokens
itself (more accurate, and the ratio against threshold is meaningful
even if the absolute count is approximate).

* fix(claude-code-plugin): always emit session-event marker on resume/compact

Statusline expected `🔗 resumed/compact` to reflect that the event happened,
but session-start.mjs only wrote the marker when `formatArchiveContext` had
something to inject. Fresh sessions with no prior archive saw a `/compact`
silently — statusline showed nothing, leaving the user wondering whether the
hook fired at all.

Move the writeJsonState call ahead of the no-archive early return and tag
the payload with `had_context: false` for the empty case. The badge now
fires on every resume/compact event with a 1-minute TTL.

`✎` capture pending is unaffected — that segment is gated on
`cc_session_id === sessionId` and after `/branch` there's no Stop hook for
the new session yet, which is correct (stale capture from a different
session would be misleading).

* docs(claude-code-plugin): add STATUSLINE.md personalization guide

Statusline has more knobs than env vars expose — segment ordering, colors,
composing with another statusline, custom segments, state file shapes — and
the integration doc is the wrong venue for that level of detail. Add a
recipe-style guide aimed at an AI assistant reading it end-to-end, so users
can ask Claude Code "personalize my statusline" instead of spelunking source.

- examples/claude-code-memory-plugin/docs/STATUSLINE.md: recipes (drop a
  segment, recolor, compose, reset state, add a custom segment) + state
  file schemas + pointers to the canonical files. Defers env-var reference
  back to docs/en/agent-integrations/02-claude-code.md.
- install.sh: print a copy-pasteable seed prompt at the end of install. Not
  intrusive — no auto-launch, just a tip the user can ignore.
- docs/{en,zh}/agent-integrations/02-claude-code.md: cross-link the new doc
  from the Statusline section.

* docs(claude-code-plugin): anchor STATUSLINE.md paths to install location

Recipes referenced \`scripts/statusline.mjs\` etc. with no anchor, so an
agent reading the doc had no way to resolve them — `~/.openviking/openviking-repo/examples/claude-code-memory-plugin/scripts/...`
is far enough off the beaten path that "go look in scripts/" doesn't land.

Define \`\$REPO\` / \`\$PLUGIN\` / \`\$STATE\` once at the top with how to
verify each (jq on settings.json, find as fallback), then propagate the
prefixes through every recipe. The install seed prompt already passes the
absolute path of STATUSLINE.md, so the chain is now self-contained.

* feat(claude-code-plugin): segment glossary + yellow ⚠ slow + dual-purpose install tip

Three small refinements after seeing the statusline in the wild:

- statusline.mjs: split the unhealthy branch — `OV ⚠ slow` (yellow) when
  the probe times out, `OV ✗ offline` (red) when it errors. Slow ≠ dead;
  red was alarmist for transient lag (e.g. remote SaaS GC pauses).

- examples/claude-code-memory-plugin/docs/STATUSLINE.md: add "What each
  segment means" — a full glossary covering every state combination
  (✓/⚠/✗/⚡, ↩, ✎ in its three forms, dropped, 🔗 resumed/compact, +N
  today), plus a "missing when?" troubleshooting list. The integration
  docs only had four example lines, two of which were stale; the canonical
  reference now lives next to the code.

- docs/{en,zh}/agent-integrations/02-claude-code.md: refresh the example
  block (drop stale `1.2k tok` / `12k/20k tok`, add ⚠ slow + 🔗 resumed
  + +N today rows), and broaden the cross-link to advertise both
  explanation and personalization.

- install.sh: rewrite the seed prompt as "walk me through what each
  segment means, then ask if I want to personalize" — covers the more
  common "what does this badge mean?" path before customization.

* docs: link STATUSLINE.md via absolute GitHub URL, not relative path

VitePress only ships docs under \`docs/\`, but STATUSLINE.md lives in
\`examples/claude-code-memory-plugin/docs/\` (next to the plugin code, where
it logically belongs). Relative \`../../examples/...\` resolved on GitHub
but 404'd on the published docs site.

Use an absolute https://github.com/volcengine/OpenViking/blob/main/...
URL — works in both renders, and a parenthetical note tells readers why.

* docs: drop the parenthetical about why the link goes to GitHub

It was meta — readers don't need to know why the link's absolute. Just click.

* docs(claude-code-plugin): move STATUSLINE.md to plugin root

A docs/ folder with one file is awkward when README.md and README_CN.md
already sit at the plugin root. Moves STATUSLINE.md alongside them and
fixes up:

- Stale opening line that pointed at the integration doc for the segment
  glossary — that glossary now lives in STATUSLINE.md itself, so the
  cross-reference is just for env vars.
- Drop the "(path notation defined just below)" parenthetical (meta).
- Update the install seed prompt and the en/zh integration cross-links to
  the new path.

* fix(claude-code-plugin): address Copilot review on PR #1890

Code:
- state.mjs: derive STATE_DIR from \$OPENVIKING_HOME (with ~ expansion) so
  the override the docs already advertised actually works. Default
  unchanged. Was hard-coded to homedir().
- auto-recall.mjs: rename \`session_id\` → \`cc_session_id\` in last-recall.json
  to match last-capture.json / last-session-event.json. STATUSLINE.md
  schema already used \`cc_session_id\`. No reader filtered on the recall
  field, so this is a schema-cleanup, not a behavior change.
- install.sh: quote the plugin path inside the JSON \`command\` value, so
  CC's /bin/sh -c invocation tolerates spaces / metacharacters in
  \$REPO_DIR (custom OPENVIKING_REPO_DIR locations).
- install.sh: mktemp inside ~/.claude/ instead of \$TMPDIR, so the final
  rename is within one filesystem (atomic). Was crossing tmpfs/$HOME on
  Linux, where \`mv\` falls back to copy+unlink and isn't crash-safe.

Comments / docs (drift from earlier "drop tok / 250→1000ms" passes):
- server-probe.mjs: header comment said "Hard 250 ms" while the constant
  is 1000. Replaced with a forward-reference to the constant block which
  already explains the choice.
- README.md / README_CN.md: refresh the example block (drop \`1.2k tok\` /
  \`12k/20k tok\`, add \`⚠ slow\` / \`🔗 resumed\` / \`+N today\` rows), correct
  the hard-timeout sentence (250 ms → 1 s), cross-link STATUSLINE.md.
- install.sh: the \`info\` sample at registration time was also stale.

* chore(claude-code-plugin): version 0.3.0 → 0.2.1

Statusline is additive and opt-in — no API breaks, no behavior change for
existing installs that skip the prompt. A patch bump fits better than a
minor.
2026-05-07 16:38:15 +08:00
t0saki 5576bb2842 fix(cc-plugin): drop --scope from plugin commands, add legacy install path (#1876)
* fix(cc-plugin): drop --scope from plugin commands, add legacy-mode install path

- Removed `--scope user` from `claude plugin marketplace add` and
  `claude plugin install` everywhere (install.sh + READMEs + docs).
  These commands default to user scope already, and older 2.0.x builds
  (e.g. 2.0.76) reject the flag outright. Kept `--scope user` on
  `claude mcp add` because its default is `local` (current-project only)
  and the flag has been supported since MCP first shipped.
- install.sh now probes for `claude plugin` subcommand existence rather
  than parsing version strings. If absent, prompts the user to enable
  legacy compatibility mode, which wires the same functionality through
  `claude mcp add` + a JSON-merge into ~/.claude/settings.json. The
  modern path also falls back to legacy on plugin-install failure.
- Legacy mode keeps `${VAR}` placeholders single-quoted so Claude Code
  expands them at MCP launch time (the rc wrapper injects the values),
  rather than letting the shell expand them to empty strings at install
  time. Settings.json is backed up with a timestamp before the merge,
  and the merged JSON is validated before overwriting.
- Documented the legacy path in both READMEs and the agent-integration
  docs (EN + CN), with a pointer from the docs back to the README.

* fix(cc-plugin): highlight 'source rc' final step in installer

The script runs in a subshell (bash <(curl ...)), so it can't source
the rc back into the user's interactive shell. Make the manual
follow-up step visually unmissable with bold + color, and explain why
auto-source isn't possible in a comment.

* fix(cc-plugin): address copilot review on legacy install path

- mktemp + XXXXXX for tmp files (was $$ — predictable, symlink-race
  on shared /tmp).
- Replace sed substitution with jq walk + gsub. $plugin_dir comes from
  OPENVIKING_REPO_DIR (user-configurable) and may contain &, |, \
  which would corrupt sed. jq with --arg is byte-safe.
- Wrap the merge jq in an explicit if-branch so 'set -e' can't kill the
  script before cleanup runs. Drop the now-redundant post-validation
  jq -e (a successful jq run already guarantees valid JSON output).
- README EN/CN: clarify that the 'plugin enable --scope user' tip only
  applies on newer builds that accept --scope, removing the apparent
  contradiction with the surrounding 'older builds reject --scope'.
2026-05-06 23:50:05 +08:00
Mingjian Que 3ebbb5baaa fix(openclaw): support capability contracts on 5.2 (#1866)
OpenClaw 5.2 gates non-bundled plugin capabilities from the manifest before relying on runtime registration. The previous OpenViking manifest only identified the plugin as kind=context-engine, so 5.2 could classify it as non-capability, emit diagnostics for agent tools registered without contracts.tools, and leave real gateway/agent runs falling back from the openviking context engine even when inspect loaded it manually.

Declare startup/capability activation and the tool contract list so the plugin is loaded as a plain capability plugin and its registered tools match manifest contracts. Register the ov_archive_expand factory tool with an explicit name so it can be matched to contracts.tools.

Drop the agent_end hook registration because 5.2 blocks that typed hook for non-bundled plugins without conversation access, and this plugin already records agent routing through session_start/session_end.

Harden the memory-chain e2e to find only the current run's OpenViking session, assert the unique marker is persisted, and exit non-zero on assertion failures.
2026-05-06 16:50:53 +08:00
Evo c968848169 docs(opencode-plugin): document account/user tenant config from #1820 (#1861)
* docs(opencode-plugin): document account/user tenant config from #1820

* docs(opencode-plugin): document account/user tenant config from #1820 (zh)
2026-05-06 14:34:15 +08:00
chenjw 44d3cc41b1 Feat/memory isolation 支持群聊模式 (#1711) 2026-05-06 10:45:06 +08:00
Eurakaxun 5b3c68c559 fix(openclaw-plugin): merge consecutive user turns (#1724) (#1858) 2026-05-06 09:35:38 +08:00
t0saki e69ae7e08f fix(cc-memory-plugin): stop silently dropping tool-heavy batches; remove MIGRATION.md (#1850)
Follow-up to #1849. Two issues surfaced after merge:

1. **Data loss on tool-heavy batches** (Copilot review on #1849).
   With tool I/O now inlined in per-turn text (4 KB cap per block), an
   ordinary multi-tool turn easily pushes formatTurnsAsText(captureTurns)
   over the 24 KB captureMaxLength. The previous code path:

       const combined = formatTurnsAsText(captureTurns);
       const decision = shouldCapture(combined);
       if (!decision.capture) {
           saveState(... allTurns.length);  // advance past these turns
           return;
       }

   silently dropped the entire batch and advanced state past the dropped
   turns, so they were unreachable on subsequent hook fires. Reproduced
   with a synthetic 4-tool turn (combined length ~32 KB > 24 KB cap).

   shouldCapture() was designed for single-user-message filtering — its
   length bounds, command/non_content/question_only checks, and keyword
   trigger requirement all misfire at the batch level:
     - JSON-shaped tool I/O can match the punctuation-only regex
     - a leading "/cmd" user turn flips the whole batch to a reject
     - a single "why?" turn tags the whole batch as question_only

   Replaced with a batch-appropriate decision: skip only empty batches,
   and in keyword mode require at least one user turn to carry a trigger
   phrase. Per-turn substance is already bounded by TOOL_BLOCK_MAX_CHARS
   during harvest, so no upper-bound batch check is needed.

2. **MIGRATION.md removed.** The file documented the old user-only-capture
   default as an intentional design choice, which the new default
   (capture both sides + tool I/O) contradicts. Rather than rewriting
   the rationale, the file is removed; nothing in the plugin or repo
   references it.
2026-05-04 19:12:23 +08:00
t0saki 5d83e66855 fix(cc-memory-plugin): default-capture assistant turns + inline tool I/O (#1849)
The plugin was silently shipping with two flaws that gutted memory extraction
quality on the main-session path:

1. **captureAssistantTurns defaulted false.** The auto-capture path filtered
   out every assistant turn unless the operator explicitly opted in, while
   the subagent-stop path always pushed both sides. Same plugin, same config
   — different sessions ended up half-empty (main) vs. full (subagent), and
   nothing in the docs flagged the divergence. Default flipped to true; the
   env var still allows opting out.

2. **Tool I/O was dropped, only tool names survived.** When an assistant
   ran WebFetch / Read / Bash, the captured turn only got a
   "[tools used: WebFetch, Read]" summary — the URL fetched, the file read,
   and the result returned were all discarded. Memory extractors saw "agent
   used a tool" without any of the substantive context. Both auto-capture
   and subagent-stop now inline "[tool: NAME] <input>" for tool_use blocks
   and "[tool result] <output>" for tool_result blocks, each truncated to
   4096 chars to bound runaway sizes.

The redundant "[tools used: ...]" suffix in pushTurnsToOv is removed since
the same info is now inline. README defaults updated.
2026-05-04 19:00:24 +08:00
t0saki 36a281a5be feat: harden MCP add_resource + cc-memory-plugin claude wrapper (#1846)
* feat(mcp): restrict add_resource to remote URLs, point local files to ov CLI

The MCP add_resource tool previously accepted any path string and passed it
straight to the resource service, which on a remote-deployed OV server would
either fail (path only exists on the client) or read server-local files —
neither of which is the intended behavior, and the latter is a security hole.

Apply the same require_remote_resource_source guard the REST router already
uses, and on rejection return a clear hint pointing the user at `ov add-resource`
for local files. Also enable enforce_public_remote_targets to match the REST
contract.

* fix(cc-memory-plugin): make claude wrapper friendlier — honor env, fix null-key bug

The shell wrapper installed by setup-helper/install.sh (and documented in
README/README_CN) had four issues:

1. Hardcoded ~/.openviking/ovcli.conf — ignored OPENVIKING_CLI_CONFIG_FILE,
   the env var the `ov` CLI itself reads (crates/ov_cli/src/config.rs:6).
   Same repo, two contradictory contracts.
2. Unconditionally overrode caller's OPENVIKING_URL / OPENVIKING_API_KEY,
   stomping on direnv/explicit exports. Should be conf-as-fallback, env-wins.
3. `jq -r '.url'` returns the literal string "null" when the key is missing,
   producing OPENVIKING_API_KEY=null and 401s downstream. Use `// empty`
   instead, matching what install.sh already does correctly elsewhere
   (line 82-83 of the same script).
4. No fallback if `jq` isn't on PATH at invocation time — silently emitted
   empty values that overrode the caller's env.

Also have install.sh resolve OVCLI_CONF via OPENVIKING_CLI_CONFIG_FILE so
re-running the installer with that env set updates the right file.

The plugin's hooks (scripts/config.mjs) already do all this correctly —
this just brings the wrapper and installer up to the same standard.

* fix(cc-memory-plugin): install at --scope user so plugin is active everywhere

`--scope local` ties plugin enablement to $REPO_DIR's .claude/settings.local.json.
The moment the user `cd`s anywhere else and runs `claude`, the plugin shows up as
disabled and they have to run `claude plugin enable …` manually — defeating the
"one-shot installer" goal.

Switch both `marketplace add` and `plugin install` to `--scope user`, and add
a defensive `claude plugin enable … --scope user` afterwards to handle Claude
Code versions where install leaves the plugin disabled. README/README_CN
updated to match (and to call out the scope=local pitfall).

* refactor(mcp): reorder add_resource hint — try ov first, install as fallback

The previous hint led with "Install: curl |bash" and put "Run: ov add-resource"
as step 3. For an LLM agent reading this error, the natural reaction is to
copy the install command verbatim — even when `ov` is already on PATH, which
is the common case for users who already have OpenViking set up.

Reorder so step 1 is just `ov add-resource <path>`, step 2 is the install
fallback only if `ov` is missing, and step 3 is the ovcli.conf step that's
explicitly tagged as remote-/multi-tenant-only. Cheaper, less noisy, and
won't push agents to re-run curl|bash unnecessarily.

* style: ruff format — drop redundant quote escapes
2026-05-04 15:57:07 +08:00
t0saki 8c01e97ee4 feat(cc-memory-plugin): persistent session and recall redesign (#1615)
## feat(cc-memory-plugin): implement persistent sessions, native MCP, and async write path

This update transitions the Claude Code memory plugin from a one-shot capture model to a persistent, per-session integration with OpenViking. It introduces native MCP support directly from the FastAPI server, significantly expands the tool surface, and optimizes performance via detached async write hooks.

### Core Engineering & Capabilities
* **Persistent Sessions:** Reworked lifecycle hooks (SessionStart, PreCompact, SessionEnd) to maintain stable session IDs across the entire Claude Code conversation.
* **Native MCP Endpoint:** Replaced the Node.js MCP subprocess with a native `/mcp` endpoint on the OpenViking server.
    * Expands to 9 specialized tools: `search`, `read`, `list`, `store`, `add_resource`, `forget`, `grep`, `glob`, and `health`.
    * Propagates identity headers (`X-OpenViking-Account`, `X-OpenViking-User`) through the MCP transport.
* **Async Write Path:** Introduced a detached worker pattern for `auto-capture`, `session-end`, and `subagent-stop` hooks. Claude Code no longer blocks on network round-trips to the OpenViking server.
* **Multi-Source Recall:** Enhanced `auto-recall` to search across memories, resources, and skills with URI-deduplication and score-based filtering.

### Configuration & Integration
* **Unified Auth:** Standardized on `Authorization: Bearer` tokens.
* **Config Resolution:** Established a clear priority chain: **Env Vars → ovcli.conf → ov.conf → Defaults**.
    * Added comprehensive environment variable coverage for all tuning fields (e.g., `OPENVIKING_SCORE_THRESHOLD`, `OPENVIKING_COMMIT_TOKEN_THRESHOLD`).
* **One-Line Installer:** Added an interactive bash installer (`install.sh`) that handles dependencies, `ovcli.conf` setup, and marketplace registration, with support for both self-hosted and Volcengine Cloud options.

### Bug Fixes & Refinement
* **Self-Injection Prevention:** Implemented block-stripping logic in `auto-capture` to prevent the plugin from re-storing its own injected context blocks into the memory pool.
* **Session Bypass:** Fixed a bug where `session-start` and `subagent-start` ignored bypass patterns.
* **Subagent Isolation:** Implemented `SubagentStart/Stop` hooks with isolated session IDs and specialized agent headers for memory segregation.
* **Docs & Maintenance:** Bumped version to `0.2.2`; added comprehensive agent integration guides; fixed Vue interpolation and markdown fence issues in documentation.
2026-05-04 13:10:44 +08:00
Eurakaxunandwlff123 51342319b4 Introduce Working Memory v2: 7-section session memory, anti-bloat guards, sliding-window tokens, and OpenClaw integration (#1782)
* feat(wm): WM v2 core - 7-section structure, pending_tokens, anti-bloat guard

Server-side implementation of Working Memory v2:

- 7-section structured WM format with section integrity guards

- pending_tokens sliding window for live session tracking (O(1) read)

- Anti-bloat Key Facts guard (dedup, capping, consolidation sentinel)

- Regex recovery fallback for malformed LLM WM output

- commitKeepRecentCount: keep recent messages live after commit

- WM v2 prompt templates (ov_wm_v2.yaml, ov_wm_v2_update.yaml)

- CommitRequest model with keep_recent_count parameter

* fix(wm): address 4 code review findings

- Replace hardcoded debug log path with configurable workspace path

- Add _rebuild_pending_tokens() after _update_message_in_jsonl()

- Detect WM v2 format via _is_wm_v2 to route legacy sessions to creation path

- Pass latest_archive_overview to creation template for legacy-aware bootstrapping

* test(wm): add unit tests for WM v2 guards, growth, and merge guardrails

- 62 tests for section guards, regex recovery, pending_tokens, merge logic

- 6 tests for anti-bloat growth behavior (dedup, capping, consolidation)

- 3 tests for dynamic reminders, key facts consolidation, and URL pruning guard

* feat(plugin): WM v2 plugin integration + ov_archive_search tool

- Add ov_archive_search tool for keyword-grep across session archives

- Add grepSessionArchives() client method for /api/v1/search/grep endpoint

- Rewrite system prompt to describe WM v2 structured sections

- Simplify archive index assembly (remove preAbstracts/budget processing)

- Add keepRecentCount to commitSession calls (afterTurn=cfg, compact=0)

- Add commitKeepRecentCount to plugin config schema

* fix(wm): post-feature refinements for WM v2

- Replace _wm_debug file logging with logger.debug
- Defensive clamps for pending_tokens / keep_recent_count
- Include tool/context parts in WM generation formatting
- Limit Open Issues anti-drift restore to one round (allow stale resolution)
- Resolve commitSession merge conflict in plugin
- Edge case tests + plugin tests update

* fix(wm): restore Phase 2 request tracking, archive_uri, and agentId

* docs(wm): add WM v2 design overview

---------

Co-authored-by: wlff123 <wlff123@users.noreply.github.com>
2026-05-02 22:09:59 +08:00
AutoCoder 4d6f5b65bd fix(openclaw): route auto recall through assemble (#1835) 2026-05-01 16:39:32 +08:00
x__dot 17cfaac87c fix(openclaw-plugin): unify session and agent-prefix routing across compact, commit, and tools (#1832)
* fix(openclaw): align compact session id and agent prefix routing

* fix(openclaw-plugin): align compact session id and agent prefix routing
2026-05-01 13:49:16 +08:00
BT.Wood(Tang Bo Hao) e6e4683839 fix(memory): include tenant headers in opencode plugin (#1820) 2026-04-30 14:14:40 +08:00
bot-of-qin-ctxandqin-ctx 9c08d716ca fix(openclaw): treat agent_prefix as prefix only (#1809)
* fix(openclaw): treat agent_prefix as prefix only

* fix(openclaw): treat agent_prefix as prefix only

---------

Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-04-29 22:42:56 +08:00
baojun-zhang d7fdb489ce feat(observability): support header param while OTLP export (#1805)
* feat(observability): support header param while OTLP export

* feat(observability): support header param while OTLP export
2026-04-29 20:14:31 +08:00
Qin Haojie 08dcfc10ac fix(openclaw-plugin): stop synthesizing tenant headers (#1789) 2026-04-29 11:49:37 +08:00
LinQiang391 dac750e144 refactor(openclaw-plugin): remove local mode and rename agentId to agent_prefix (#1783)
Made-with: Cursor
2026-04-28 22:42:49 +08:00
Qin Haojie b35d38a323 feat(config): 配置检索打分和 embedding 输入 (#1770)
* feat(retrieval): configure hotness score blending

* feat(retrieval): configure score propagation alpha

* test(retrieval): trim redundant propagation coverage

* feat(embedding): centralize token estimation

* fix(embedding): use shared token estimator

* fix(embedding): narrow token truncation scope
2026-04-28 19:04:24 +08:00
Eurakaxun 16c0bfe76f fix(openclaw-plugin): use character budget for auto recall (#1740) 2026-04-28 18:57:25 +08:00
baojun-zhang 64682ae189 feat(encryption): make apikey hash encryption as single switch (#1736)
* feat(encryption): make apikey hash encryption as single switch

* feat(encryption): add break change note
2026-04-27 19:23:23 +08:00
r266-tech 670a69c550 docs(openclaw-plugin): sync recall placeholder defaults to 5000/8000 (#1638)
PR #1617 (merged 2026-04-22 by qin-ctx) raised DEFAULT_RECALL_MAX_CONTENT_CHARS
from 500 to 5000 and DEFAULT_RECALL_TOKEN_BUDGET from 2000 to 8000 (validated on
locomo-small: 65.7% -> 88.6% accuracy). openclaw.plugin.json UI hints still
showed the old values, so users opening the plugin config panel see "500" and
"2000" as suggested defaults while the effective runtime value is now 5000/8000.

Refs: #1617
2026-04-25 17:45:55 +08:00
baojun-zhangandMaojiaSheng 17d2c5603e feat(observability): unify observability context && support otel && etc. (#1666)
* feat(observability): unify OTLP metrics export, log/trace context, and telemetry bridging
- - Add OTLP metrics http/grpc exporter that pushes MetricRegistry snapshots
- - Decouple telemetry response payload from telemetry collection; always finish() and bridge summary to metrics
- - Unify observability config under server.observability (metrics/traces/logs siblings); update ov.conf.example and docs (zh/en)
- - Improve log/trace correlation via structured context injection
- - Add/adjust tests for exporter lifecycle, config loader, metrics/telemetry runtime
- BREAKING CHANGE: remove legacy telemetry.* config path; use server.observability.*

* feat(observability): import Status/StatusCode for LogToSpanEventFilter

* feat(observability): fix check issue

* feat(observability): format code

---------

Co-authored-by: MaojiaSheng <shengmaojia@bytedance.com>
2026-04-24 21:32:25 +08:00
MaojiaShengandopenviking 85986a91bd fix: apikey security: API Key 管理重构与安全增强 (#1686)
* fix: apikey security

* fix: apikey security

* fix: apikey security

* fix: apikey security

---------

Co-authored-by: openviking <openviking@example.com>
2026-04-24 20:13:36 +08:00
Nono f006e392e8 feat(git): added azure devops support (#1625) (#1642)
* feat(git): added azure devops support (#1625)

* fix(git): reject Azure DevOps UI URLs in parser

* fix(git): restore www domains in network guard fallback
2026-04-23 21:34:17 +08:00
AutoCoder 44efb0667e Align context-engine assemble test with toolCall output (#1641) 2026-04-22 20:33:53 +08:00
lililiandMoss 6c76318013 fix(plugin): 修复 OpenClaw 工具调用消息格式不兼容导致的 toolResult 孤儿错误 (#1632)
* fix(plugin): canonicalize tool message format for OpenClaw Responses API

The OpenClaw Responses API replay path only recognizes `toolCall` blocks
(with `arguments` field), but the OpenViking context engine plugin was
emitting `toolUse` blocks (with `input` field) from its assembled context.
This mismatch caused `toolResult` orphan errors on subsequent turns after
tool use.

Changes:
- convertToAgentMessages: emit toolCall+arguments instead of
  toolUse+input, matching the OpenClaw canonical format
- Add canonicalizeAgentMessages() to normalize legacy/variant block
  formats (toolUse, functionCall, tool_call) into toolCall before
  sanitizeToolUseResultPairing
- Add canonicalizeAssistantBlock() for per-block normalization with
  id/name/arguments field mapping
- messageDigest: update type guard from toolUse to toolCall

This preserves backward compatibility on input (old toolUse blocks are
still accepted and normalized) while ensuring output always matches the
current OpenClaw Responses API contract.

* fix(plugin): address review feedback on PR #1632

- Remove 'unknown' fallback for toolResult.toolName in canonicalizeAgentMessages();
  preserve undefined to let downstream normalizeToolResultName() backfill from paired toolCall
- Remove 'unknown' fallback for tool_name in convertToAgentMessages() structured path;
  only set toolName on toolResult when the value exists
- Only include toolName on toolResult when present (not always)
- Update test expectations: toolUse → toolCall, input → arguments
- Update README/README_CN: describe canonical output format with backward-compat note

---------

Co-authored-by: Moss <moss@openclaw.ai>
2026-04-22 18:22:28 +08:00
Qin Haojie f7cab2d55d fix: change openclaw mode into remote (#1634) 2026-04-22 15:30:42 +08:00
dingbenanddingben.db@bytedance.com <dingben.db@bytedance.com@bytedance.com> 557b173515 feat(vectordb): add volcengine_api_key data-plane backend for VikingDB (#1588)
* feat(vectordb): add volcengine_api_key data-plane backend for VikingDB

* fix: comment

---------

Co-authored-by: dingben.db@bytedance.com <dingben.db@bytedance.com@bytedance.com>
2026-04-22 14:55:10 +08:00
Eurakaxun 299166c928 adjust default value for recallTokenBudget and recallMaxContentChars. (#1617) 2026-04-22 11:47:59 +08:00
r266-tech 0b6f2d5edf docs(skill): sync ov add-memory output example after #1613 (#1627)
PR #1613 changed 'ov add-memory' to print 'OK' instead of
memories_extracted count because commit runs async.
The SKILL.md example still showed the old count output.
2026-04-22 11:46:26 +08:00
Hao ZheandZayn Jarvis 01403312ea feat(vlm): add Codex, Kimi, and GLM VLM support (#1444)
* feat(vlm): add Codex OAuth-backed VLM setup and docs

* fix(codex): address PR review follow-up issues

* feat(vlm): add Kimi and GLM backends

* refactor(vlm): simplify codex auth flow and docs

* fix: update code comments and doctor validation

* chore: update uv.lock after merge

* Refine Codex auth flow and VLM backend integrations

* Take over mirrored Codex auth on refresh

* feat(vlm): refine provider setup and auth flow

* style: format VLM and setup files

* style: fix lint import ordering

* fix(codex): harden auth refresh and disable streaming

* fix(codex): translate tool history and refresh auth safely

* style(lint): fix changed-file ruff violations

* fix(init): refine cloud VLM setup prompts

* style(lint): format setup wizard changes

---------

Co-authored-by: Zayn Jarvis <zhiheng.liu@bytedance.com>
2026-04-22 11:01:23 +08:00
LinQiang391 b0c2fbb2ed fix: Windows .bat env read/write, shell escaping, ov.conf validation, remove hardcoded paths (#1620)
Made-with: Cursor
2026-04-22 09:13:15 +08:00
x__dotandjohnny ef2513c3e7 feat(openclaw-plugin): align auth, namespace, and role id handling (#1606)
* feat(plugin): multi-tenant identity, agent scope mode, and resource recall

Made-with: Cursor

* fix(openclaw-plugin): avoid default tenant fallback

* feat(openclaw-plugin): add server auth mode handling

* feat(openclaw-plugin): add server auth mode and canonical namespace config

* feat(openclaw-plugin): propagate sender role id in session writes

* test(openclaw-plugin): add multi-tenant coverage and Chinese report

* docs(openclaw-plugin): update Chinese multi-tenant docs

* fix(openclaw-plugin): align default namespace policy and shared role id logic

* test(auth): drop unintended test_auth changes from plugin PR

* fix(openclaw-plugin): preserve tenant headers for api key root flows

---------

Co-authored-by: johnny <1667704220@qq.com>
2026-04-21 16:02:06 +08:00
LinQiang391 09bb76cf61 feat: add ClawHub publishing, setup wizard, and OPENCLAW_STATE_DIR support (#1587)
Made-with: Cursor
2026-04-21 11:27:46 +08:00