2581 Commits
Author SHA1 Message Date
hezhang-1216zhanghe.1216 <@bytedance.com>qin-ctx
85b40a1fcd feat(tree): 支持目录过滤及 L0/L1 内容展示 (#5334)
* feat(tree): 支持目录过滤及 L0/L1 内容展示

新增目录过滤、摘要与概览控制参数,确保过滤先于分页且 L0/L1 不占节点额度;同步 CLI、SDK、文档及测试。

* refactor(tree): 移除废弃的 agent 私有入口

统一通过公开 tree 接口验证 agent 输出,避免重复维护旧转发逻辑。

* refactor(tree): 复用统一的 L1 概览读取入口

移除 Tree 专用的 Overview 读取流程,统一复用 overview 方法,减少权限检查、兼容路径及异常处理的重复维护。

* test(tree): 精简测试并集中核心契约覆盖

* fix(tree): 将目录过滤下沉至分页前

---------

Co-authored-by: zhanghe.1216 <@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-09-28 11:30:13 +08:00
Zayn Jarvis 3f3108a562 docs: refresh WeChat group QR code (#5415) 2026-09-28 10:33:46 +08:00
chenjwandTRAE CLI a09a9d20a8 feat(compile): 通过 --skill memory 支持记忆整理模式 (#5178)
* feat(compile): add memory consolidation mode via `--skill memory`

Add an in-process memory consolidation mode to `ov compile`. When `--skill`
is the sentinel value `memory`, CompileService runs the existing memory
framework (ConsolidationExtractContextProvider -> ExtractLoop -> MemoryUpdater)
directly inside OpenViking core to dedup/merge/split/compact an existing
memory-type directory in place, conforming to that type's schema. The default
skill path (VikingBot Wiki compile) is unchanged.

Highlights:
- New ConsolidationExtractContextProvider: agentic exploration with ls/search/read
  tools seeded by a recursive listing; single schema inferred from --to; space
  (self/peer) taken from the canonical --to URI so listing never depends on an
  empty ctx.user_id.
- MemoryCompileRunner: session.commit-lite task shape (task_tracker + one
  in-process asyncio.Task, no QueueFS re-delivery), bound to a root span so a
  trace_id is recorded; result reports adds/updates/deletes (file URIs only,
  memory_diff.json semantics) classified via read_file_contents.
- MemoryLsTool: add recursive listing (relative paths, 500-node cap with
  truncation) and stop hiding subdirectories so subfoldered dirs are not
  misreported as empty. Only the compile provider exposes ls, so session.commit
  is unaffected.
- CLI: --from optional (required for normal mode, rejected for memory mode);
  help gains a memory example.
- Fix a syntax regression in crates/ragfs/src/lock/provider.rs test module that
  blocked `make build` (unrelated to compile; introduced by #4908).
- Docs: document the memory mode in ov-compile-design.md.
- Tests: unit tests for provider/runner/request validation; integration script
  test_compile_memory_xiaomei.py with merge/split/dedup/preferences cases.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* docs(compile): document memory consolidation mode

Add a dedicated user-facing page (zh + en) for `ov compile --skill memory`
covering when to use it, usage, parameters, behavior, and the adds/updates/
deletes result. Link it from the context-compilation overview. The VitePress
sidebar picks the new page up automatically from the directory listing.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(compile): honor language and cancellation

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: migrate files when URI fields change

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: materialize URI moves at apply time

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: inherit source links on explicit merge

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* test(memory): cover rename conflict and streaming migration

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* test(compile): assert URI migration diff semantics

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* docs(compile): clarify cross-type link migration

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: fail rename on target read errors

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: preserve omitted URI identity fields

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: rebase URI moves on latest source

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: protect occupied empty rename targets

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: reject case-only URI moves

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* docs(compile): document URI migration semantics

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: validate explicit replacement targets

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: reject case-only replacement moves

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: rerender managed links after URI moves

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* test(compile): add repeatable Chinese URI rename case

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* test(compile): cover bidirectional URI renames

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: remove empty directories after URI moves

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory(prompts): lowercase filename identity segments

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: consolidate memories-root in one extract loop

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* docs(compile): document memory-root consolidation and failure semantics

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* test(compile): add memory_root and deterministic rename cases

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory(compile): honor Account templates and preserve merged duplicate links

- MemoryCompileRunner._consolidate now resolves the Account-level memory
  template snapshot via resolve_account_memory_registry(), matching the
  session.commit extract path, so consolidation no longer overwrites
  operator-customized content templates with deployment defaults.
- _inherit_deleted_link_relations now tracks the deleted source URI for
  each inherited link. Implicit rename targets only exclude contributions
  copied from their own migration source, so links unique to a duplicate
  merged into the same target (delete_replacements) are folded in and the
  neighbor backlinks match.
- Regression tests cover the Account-template snapshot and a same-batch
  rename+merge where only the duplicate holds a link to a third file.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: preserve rename sources through session commit queue

- ExtractLoop._updated_uri_for_existing_operation only considers an
  identity-field change a rename when the merged value actually differs
  from the current one, and returns the source URI unchanged when the
  regenerated candidate matches it. Legacy paths whose new template
  differs only in case (e.g. preferences user "Alice") no longer trip
  the case-only migration guard on plain content updates.
- clone_operation_for_uri no longer drops old_memory_file_content when
  the target URI differs from the source. The upstream
  _materialize_uri_migrations still detects the mismatch and generates
  a write-new + delete-old migration, but the queue clone keeps the
  source content so the migration can inherit prior body and links
  instead of turning a rename into an empty new record.
- python_protocol contract preamble drops the misleading "Unknown
  business fields are ignored" clause; unknown fields raise at parse
  time, so the note was inaccurate.
- Regression tests cover legacy case-only preferences updates going
  through ExtractLoop and split_request_by_merge_group preserving the
  rename source for the add + delete pair.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* vikingbot(cli): pin openviking log stream to stderr before eager imports

vikingbot chat --eval / -e commits to a stdout JSON contract. Downstream
consumers like benchmark/locomo/vikingbot/run_eval.py parse stdout with
json.loads, so any log line on stdout breaks the parse and drops
token_usage and iteration to defaults (0). That is what caused
Total prompt tokens=0 and Avg iteration=0 in the LoCoMo summary.

Move the openviking / openviking_cli log redirection into a module-level
_preimport_redirect_openviking_logs_to_stderr() that runs before any
vikingbot.agent.* or openviking.* imports. Those imports call get_logger()
at module load time, which loads ov.conf and can emit warnings (e.g.
"Ignoring unknown config field") through openviking_cli's shared
QueueListener whose default output is stdout. Force the "stdout" listener
plus real StreamHandler pair into existence up front and rebind its
stream to stderr. Also move the in-chat() redirect ahead of ensure_config
and extend it to swap the shared stdout handler as a second-line guard.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory(python-protocol): silently drop unknown-field edits

Extraction DSL programs occasionally reference a field name that does not
exist in the memory schema. Failing the whole program on this is
brittle: unrelated valid statements in the same commit are lost. Match
the tolerance kwargs already have on create()/set()/update() and treat
unknown-field attribute access as a compile-time no-op: return a
_FieldHandle flagged is_noop=True, and skip any .update()/.edit()/.drop()
chained on it plus the final _apply_field_handle. Sibling operations on
real fields keep applying.

Update the corresponding regression tests: replace the literal-`field`
placeholder rejection test with two new cases asserting the whole program
still commits and a real content.edit() still lands when a bogus field
appears in the same batch.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* memory: tree-lock delete parents so overview cleanup covers empty dir rm

`generate_overview` recursively removes a memory directory once the last file
is deleted, but `_operation_tree_lock_paths` only tree-locked rename source
parents. Batches that plain-deleted the last file in a directory ran the
follow-up `rm -r` under a lease that did not cover the parent, and RAGFS
rejected the request with "pathlock lease ref does not cover the requested
operation". Add each delete's parent directory (unless a same-directory
rename replaces it) to the tree-lock set.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

---------

Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-26 16:30:28 +08:00
t0sakiandTRAE CLI 276dfffc80 fix(codex-plugin): exclude host startup context from captured sessions (#5392)
* fix(codex-plugin): skip host startup context during capture

* fix(codex-plugin): handle legacy AGENTS startup headers

Co-authored-by: TRAE CLI <traecli@bytedance.com>

---------

Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-25 17:33:57 +08:00
z1gon 7abd338e6d fix(mcp): mark whole-call failures as errors (#5078)
* fix(mcp): mark whole-call failures as errors

* fix(mcp): preserve literal tool registration

* fix(mcp): preserve annotations and flag remaining tool failures
2026-09-25 17:08:58 +08:00
t0saki 3e02c6ac29 fix(dsh-plugin): drop the plugin group from the bundle patch (#5390)
DSH's plugin manager lists every bundle row, group rows included, but
resolves row state and toggles through the running-plugin inventory,
which skips group entries. The outer `@deepseek-ai/cordis-plugin-group`
row therefore always showed as disabled, and enabling it failed with
`unknown-plugin`.

The group only isolated the `openvikingMemory` service, which nothing
consumes, so the bundle now inserts the runtime row directly under the
same row id. Desktop toggles and id-targeted overrides keep applying,
and the docs show the id-targeted override form, which also applies to
the old nested layout.
2026-09-25 16:13:46 +08:00
z1gon a86caca701 feat(mcp): advertise tool behavior annotations (#5075) 2026-09-25 15:32:24 +08:00
z1gonandstarship-s cef8be2294 fix(hermes-plugin): bind settings to initialized profile (#5374)
* fix(hermes-plugin): bind settings to initialized profile

* fix(hermes-plugin): keep launch secrets scoped across routed profiles

* fix(hermes-plugin): retain frozen launch secrets under multiplex

---------

Co-authored-by: starship-s <45587122+starship-s@users.noreply.github.com>
2026-09-25 14:58:34 +08:00
z1gon 4e5c873a46 fix(plugins): align Kimi manifest version with integration (#5376) 2026-09-25 14:45:37 +08:00
Zayn Jarvis 046c10d666 docs(deploy): refine enterprise deployment install steps (#5388)
* docs(deploy): add material request, image sync, node labels, and license fingerprint steps

* docs(deploy): add model Secret Template, skopeo import, and completion criteria
2026-09-25 14:20:43 +08:00
Johnny 597ef15750 feat(dsh-plugin): add the plugin card's icon and localized descriptions (#5362)
The card resolves its text and icon through the package `exports` map, so a
manifest exporting only `.` left it with neither: export `./package.json` and
`./locale/*.json`, declare `icon: ./icon.svg`, ship both in `files`, and add
the English and Chinese dictionaries. The mark draws in one ink per colour
scheme (black on light surfaces, white on dark) rather than a fixed gradient,
so it stays legible on the card's dark background.

The peer ranges also admit the `0.1.7-rc` series from `rc.2` on, a pre-release
series semver otherwise rejects.

Version 0.5.7, as the repository's version-bump check requires.
2026-09-25 14:01:24 +08:00
Zayn Jarvis 8458ea5442 ci: append daily star history to the stat branch on each release (#5387) 2026-09-25 12:35:17 +08:00
t0sakiandTRAE CLI 4e5136e440 docs(dsh): clarify recall budgets and category quotas (#5381)
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-25 12:02:58 +08:00
t0sakiandTRAE CLI 7fcb42377c fix(dsh): resolve workspace peer settings per session (#5380)
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-25 12:02:40 +08:00
z1gon 4edc30b068 fix(plugins): filter hook capture before truncation (#5375)
* fix(capture): filter hook-host turns before truncation

(cherry picked from commit 6b05eb47a529eb49b53f4a2bdf9ee574453ad2cf)

* chore(plugins): bump versions for shared capture change
2026-09-24 23:39:57 +08:00
z1gonandhemingzhe 92dcf00f83 fix(plugins): share capture filtering across adapters (#5359)
* fix(pi): honor conversation capture filters in faithful mode

Apply the shared turn filter before capture decisions so configured rules cannot be bypassed by takeover or attached tool parts, while preserving tool values and behavior without applicable rules.

(cherry picked from commit e8fb6c9476)
Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

* fix(opencode): wire captureFilters through config and the capture path

captureFilters (sed-style redaction rules, e.g. s/sk-.../[REDACTED-SK]/g)
was defined in the shared capture-utils library but never reached the
OpenCode capture path: lib/config.mjs had no mapping for the key and
memory-session's buildCapturePayload applied no filtering, so secrets
typed into OpenCode sessions were captured verbatim. The Codex plugin
applies the identical library correctly (issue #4984).

- map captureFilters in config (file key, OPENVIKING_CAPTURE_FILTERS env
  override as JSON, non-string entries dropped)
- apply filterCaptureParts() to extracted parts in buildCapturePayload,
  mirroring the Codex reference flow (role-level drops skip the turn;
  an empty filtered result gates capture)
- cover config mapping, env override and validation in tests

(cherry picked from commit b5bd21930d)
Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

* refactor(capture): share sanitized filter path across adapters

* test(capture): preserve mixed tool messages and cover OpenCode v2

* fix(capture): cap mixed text and preserve dated logs

* fix(capture): use shared shaping in Claude Code hooks

* fix(capture): sanitize fallback text once

---------

Signed-off-by: Hao Zhe <haozhe4547@gmail.com>
Co-authored-by: hemingzhe <hehesmilett@163.com>
2026-09-24 22:46:20 +08:00
z1gon 53360209b9 fix(hermes): rotate read-only session state for recall (#5372) 2026-09-24 22:21:27 +08:00
MaojiaShengandTRAE CLI a6ad6f818f chore: split session.py into session sub-modules (#5363)
Extract working-memory, archive, checkpoint, and tool-output
externalization logic from session.py into dedicated modules:

- working_memory.py: working-memory assembly and inline-image redaction
- archive_store.py: archive state/read and abstract extraction
- checkpoints.py: checkpoint planning and snapshots
- tool_output_externalizer.py: externalized tool result storage/hydration

Session delegates to these modules while preserving its public API.
Also aligns the session_auto_commit configuration with the split.

Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-24 20:49:03 +08:00
zihengli f6f8d42a5b fix: feishu_project_auth_refresh (#5350)
(cherry picked from commit d427f25ef4)
2026-09-24 18:26:23 +08:00
hezhang-1216Claude Sonnet 4.6 noreply@anthropic.comzhanghe.1216 <@bytedance.com>
6c601a9d41 feat(fs): 为 ls 和 tree 增加分页状态 (#5330)
* feat(fs): 为 ls 和 tree 增加分页状态

通过 N+1 探测准确返回 has_more,并在 CLI 与 MCP 中提示后续节点。

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

* docs(fs): 补充 ls 和 tree 分页说明

记录 has_more 的响应位置、过滤语义及 CLI 后续节点提示。

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

* fix(cli): 保持分页 JSON 结果结构兼容

将 has_more 提升为 CLI 顶层元数据,避免把原有 result 数组嵌套为对象。

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

* fix(cli): 修复 TUI 文件树解析分页响应

适配 ls 返回的 result 和 has_more 结构,同时兼容旧版数组响应,避免目录被错误显示为空。

---------

Co-authored-by: zhanghe.1216 <@bytedance.com>
2026-09-24 18:17:31 +08:00
Qin Haojie 5684cceba1 fix(vlm): 透传工作记忆生成错误并复用共享重试 (#5364)
* fix(vlm): fail fast on context limits and surface working memory failures

* fix(session): propagate model failures through existing task handling
2026-09-24 18:16:46 +08:00
baojun-zhang c9a869cb14 chore(storage): remove ripgrep command invoke (#5369)
* chore(storage): remove ripgrep command invoke

* chore(storage): remove unused unit test
2026-09-24 17:46:26 +08:00
t0sakiandTRAE CLI b100cdefcd fix(docs): simplify language selector label (#5366)
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-24 17:28:24 +08:00
HMYDK 3b9928ee40 fix(hermes): skip writes for non-primary agent contexts (#5353)
The provider ignored the host-provided agent_context, so sessions started
for scheduled cron jobs, delegated subagents, and flush forks recorded
turns and committed into OpenViking exactly like interactive sessions.
Fixed-prompt output landed in the memory bank as user context and every
scheduled run paid summarization plus extraction.

Read agent_context in initialize() (default "primary", so hosts that
predate the keyword keep the previous behavior) and skip sync_turn,
on_session_end, on_session_switch, and on_memory_write for the
non-primary set. Recall and prefetch are unchanged.

Fixes #5345
2026-09-24 17:23:11 +08:00
ligjnandligjn fc0916bf3e fix(opencode-plugin): run session inject and recall in parallel on chat.message (#5149)
opencode awaits chat.message before persisting/broadcasting the user
message, so the serial session-inject -> recall waterfall stacks remote
latency onto message display (3-5s on the first message of a session
with a remote embedding endpoint; #5148). The two injections are
independent after hook entry; overlap them the way the dsh plugin
does (#4643).

Co-authored-by: ligjn <ligjn@users.noreply.github.com>
2026-09-24 17:22:34 +08:00
dvd233 37390e6d71 fix(dsh): respect broad MCP recall scope (#5346) 2026-09-24 17:21:27 +08:00
zhanggaoyuanandTRAE CLI a78c612976 feat(metrics): track queue processing latency (#5365)
* feat(metrics): track queue processing latency

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* chore(grafana): keep serverless dashboard external

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(metrics): preserve queue enqueue timestamp precision

---------

Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-24 17:01:42 +08:00
dvd233 c63785b60a fix(opencode-plugin): discard captured message parts from state snapshots (#5179) 2026-09-24 16:22:56 +08:00
t0sakiandTRAE CLI 41180e1ba5 feat(docs): follow browser language and remember manual preferences (#5351)
* feat(docs): resolve language automatically and preserve explicit links

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(docs): point breadcrumbs to pages after retiring language home anchors

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(docs): preserve localized documentation homepages

Co-authored-by: TRAE CLI <traecli@bytedance.com>

---------

Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-24 15:36:51 +08:00
t0sakiandTrent Telfer 12076389da feat(opencode-plugin): support OpenCode v2 (#5341)
* feat(opencode-plugin): support the OpenCode v2 plugin API

OpenCode 2 does not run v1 hook plugins. Keep the existing server()
entrypoint and add setup() so one package serves both, adapting MCP,
recall, capture, and lifecycle events to the v2 shapes.

Refs #5226

* fix(opencode-plugin): align v2 lifecycle handling

* docs(opencode-plugin): document v2 support

* fix(opencode-plugin): preserve capture across v2 compaction

* fix(opencode-plugin): drop reasoning and keep state on failed v2 executions

v2 capture turned reasoning blocks into assistant text, so chain-of-thought
reached memory extraction and inflated pending tokens. v1 parts and the shared
capture filter drop reasoning; v2 now does the same.

A failed v2 execution ends one turn, not the session. Mapping it to v1's
session.error committed and deleted the session state, so a later capture
without a cursor resent every earlier turn. Failed executions now take the
same idle path as succeeded and interrupted ones.

* fix(opencode-plugin): scope v2 capture to the plugin location and persist its cursor

One OpenCode v2 service runs a plugin instance per location, and the plugin
event stream carries every location's events. Each instance therefore
captured and committed every session, storing each message once per open
project. Handle only lifecycle events whose session belongs to this
location, resolved from session.created or ctx.session.get because execution
events carry no envelope location.

The capture cursor lived only in memory, and the shared session state file
is rewritten by every instance, so a reloaded or evicted instance could
resend the transcript since the last compaction. Keep the cursor in plugin
storage and remove it when the session is deleted.

* docs(opencode-plugin): describe v2 commit points and location scoping

---------

Co-authored-by: Trent Telfer <4094016+ttelfer@users.noreply.github.com>
2026-09-24 15:35:07 +08:00
runyunzhouandqin-ctx d370ca6a7d feat(config): isolate account runtime resources (#5323)
* feat(config): isolate account runtime resources

* fix(runtime): harden account resource lifecycle

* test: streamline account runtime coverage

* refactor(config): remove redundant account runtime paths

* fix(config): make runtime publication loop-safe

* fix(config): order runtime change notifications

* test: align vector fixtures after rebase

* test: add account runtime isolation e2e coverage

* test: consolidate account runtime coverage into existing contracts

---------

Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-09-24 15:08:56 +08:00
zhanggaoyuan ce917dde90 fix(memory): avoid fake user uri examples (#5302) 2026-09-24 14:57:05 +08:00
Qin Haojie 707a6da62d fix(vectordb): 在检索引擎中归一化 cosine 分数 (#5358)
* fix(vectordb): normalize local cosine search scores to [0, 1]

* fix(vectordb): normalize scores in engines without rebuilding indexes
2026-09-24 14:40:40 +08:00
hezhang-1216andzhanghe.1216 <@bytedance.com> 2b7efd566f fix(queue): 修复写入等待遗漏下游索引任务 (#5357)
显式传递原请求 telemetry_id,避免 collector 缺失时下游索引任务脱离 wait=true 的等待范围。

Co-authored-by: zhanghe.1216 <@bytedance.com>
2026-09-24 14:27:11 +08:00
d8f675445b fix: 统一存储 URI 规范化并兼容中文路径 (#5328)
* fix(overview): preserve unicode viking URIs

Stop percent-encoding Chinese path segments in generated markdown overview links so copied URIs remain usable by ov commands. Keep escaping only markdown-sensitive ASCII characters and normalize rewritten legacy URIs to the same form.

Co-authored-by: TRAE CLI <noreply@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix: 统一存储 URI 规范化并兼容历史空格路径

在 write/add-resource 写入前生成 canonical URI,并为 content/read 增加受限的 %20 历史路径回退,修复 存量的Overview 链接读取失败。

* test: 精简 URI 规范化的重复测试

将中文链接、空格路径和受限读取回退的覆盖合入已有契约测试,删除重复用例及闲置辅助函数。

---------

Co-authored-by: zhoujiahui.01 <zhoujiahui.01@bytedance.com>
Co-authored-by: TRAE CLI <noreply@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>
Co-authored-by: zhanghe.1216 <@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-09-24 14:26:29 +08:00
Zayn Jarvis 18abb3cc71 docs: add Enterprise Deployment guides (checklist, install, operations) (#5361)
* docs: add Enterprise Deployment guides (checklist, install, operations)

Restore the bilingual Enterprise Deployment section that was drafted on
2026-09-22 but lost from the working tree before it was committed.

- Add zh/en guides 19-deployment-checklist, 20-private-deployment and
  21-private-operations under Configuration & Deployment as a nested
  sidebar group in docs-navigation.ts.
- Link the section from 03-deployment and the home deployment strip;
  fix the Helm chart path (deploy/helm/openviking) and install flags.
- Register VPButton globally for the contact CTA on the install page.
- Keep the source/verification notes in docs/.vitepress/deployment-context.md
  (excluded from site output and llms.txt).

* test(docs): expect the Enterprise Deployment group after Server Deployment
2026-09-24 14:20:11 +08:00
yufeng 2562688c05 fix(web-studio): improve experience search, platform icons, and ACL UI (#5356)
* fix(web-studio): improve experience search, icons, and ACL UI

* fix(web-studio): merge direct and inherited ACL grants

* fix(web-studio): keep experience search visible and widen ACL drawer
2026-09-24 12:15:11 +08:00
Zayn Jarvisandwzc1753 e6cb80e498 fix(mcp): default list to viking:// and flag line-ending mismatches in edit (#5344)
`list` was the only listing tool whose `uri` was required; `tree` and `glob`
already default to viking://, so a call without a uri failed validation
instead of listing the root.

When `edit` finds no match but the old_string would match after normalizing
CRLF/LF, the error now says so instead of only asking for a re-read.

Co-authored-by: wzc1753 <81469626+wzc1753@users.noreply.github.com>
2026-09-24 11:55:15 +08:00
Zayn Jarvis 9ecb2863a7 fix(openclaw): stop offering the legacy person peer role at install time (#5355)
Setup (--peer-role, the interactive prompt) and the installer
(--peer-role, OPENVIKING_PEER_ROLE, the interactive prompt) now reject
"person" and say it was renamed to "sender". Existing configs that still say
peer_role=person keep working: config parsing, the plugin manifest enum and
reads of the current config are unchanged.
2026-09-24 11:44:11 +08:00
Zayn Jarvis 8a0d362647 fix(openclaw): widen to unscoped recall when peer_role=sender has no sender (#5347)
* fix(openclaw): widen to unscoped recall when peer_role=sender has no sender

OpenClaw does not pass runtimeContext to context-engine assemble(), and cron,
heartbeat and webchat turns carry no sender. With peer_role=sender the plugin
threw "requires a sender identity" there, so auto-recall failed every turn and
tools without a sender errored.

Peer scoping is soft isolation: a missing sender now warns and continues as an
unscoped request (no X-OpenViking-Actor-Peer), like the MCP proxy (#5132).
memory_forget refuses in that state, since an unscoped search could pick and
delete another sender's memory. Capture already stored no peer_id when the
sender is missing and is unchanged.

* fix(openclaw): let memory_forget widen like find when the sender is missing

Peer scoping is soft isolation; forget follows the same unscoped fallback
as recall and find instead of refusing.
2026-09-24 11:43:50 +08:00
Zayn Jarvis becab9a014 docs(config): document x-opencode-session header for OpenCode Go VLM (#5342) 2026-09-24 11:42:36 +08:00
Zayn Jarvisandsomewhere1994 20a97022d5 fix(agent-hook): stamp the effective peer into captured messages (#5343)
Cursor, TRAE, ZCode and Kimi Code capture through addAgentMessages and sent
their peer only as the X-OpenViking-Actor-Peer header. Session routes never
read that header (they use get_session_request_context), so messages landed
without a peer and their memories went to the user-level layer instead of
peers/<peer>. Claude Code and Codex already put peer_id in the body.

addAgentMessages now takes the peer and stamps it on payloads that do not
name one; the hook passes the same effective peer the header carries. When
peer mode is off the peer is empty and nothing is stamped.

Co-authored-by: somewhere1994 <108641179+somewhere1994@users.noreply.github.com>
2026-09-24 11:42:23 +08:00
ydflowandydflow de1c5c4954 fix(dsh-plugin): pass recallExcludeUris so subtrees can be excluded from recall (#5312)
`recall-core.mjs` reads `options.excludeUris` and forwards it as the search
request's `exclude_uris`, but the DSH runtime built its recall options without
that key, so no configuration could stop a subtree from being recalled. The
generated per-directory context files (`viking://user/<space>/skills`,
`viking://user/<space>/resources`, `viking://agent/skills`) came back as ordinary
hits and carry only boilerplate text — on a vague prompt, 3 of 7 returned entries
were these files. The only remedy was deleting the data.

Add a `recallExcludeUris` list knob to the shared config schema and pass
`cfg.recallExcludeUris` through as `excludeUris` from the DSH recall call, which
is the single place that builds those options. The schema entry lands in
`memory-plugin-shared/lib` and is propagated to the claude-code and codex copies
by `sync.mjs`; those two plugins are marked `committed: true` there because a
host installs them from a directory in this repository, so their vendored copies
belong in git. `recall-core.mjs` already caps the forwarded list at 200 entries
and omits the field entirely when the list is empty, so the default behaviour and
the request body are unchanged.

Validation, from `examples/dsh-memory-plugin` after
`node ../memory-plugin-shared/sync.mjs` and `npm install`:
`node --test *.test.mjs` 77 tests, 76 passed, 0 failed, 1 skipped. The new
`recallExcludeUris reaches the search request` failed before the change with
`exclude_uris` undefined in the request body and passes after it; the companion
case asserts no `exclude_uris` field is sent when the knob is unset.
`node --check` passes on all three changed source files.

`examples/claude-code-memory-plugin` fails 6 tests in
`scripts/auto-capture.test.mjs` on this Windows machine. Those tests spawn a real
subprocess that talks to a mock server on 127.0.0.1; they fail identically with
this change stashed and with a pristine checkout, so they are pre-existing and
environmental rather than caused by this change.

Co-authored-by: ydflow <314143294+ydflow@users.noreply.github.com>
2026-09-23 22:56:07 +08:00
wangyuandwangyu134 14a7b8126e fix(plugins): find the installer runtime in the fetched checkout (#5280)
ensure_checkout's SRC_ROOT assignment dies with the command substitution that
calls it, so install_lib_dir never sees the checkout under REPO_DIR. OpenCode
is the only host that reads the installer's JavaScript from there, so it alone
failed with "Installer runtime not found"; REPO_DIR is now a candidate.

Co-authored-by: wangyu134 <wangyu134@58.com>
2026-09-23 22:47:57 +08:00
t0sakiandcocolord 4196550942 fix(pi): make takeover archive-safe and recoverable (#5321)
* fix(pi): keep covered system messages during takeover

transformContext() sliced covered system messages off with the user
turns, dropping the model's tool declarations and instructions on
pi >= 0.86, where the leading system message carries the base prompt and
tools and later system messages carry mid-conversation tool changes,
section updates and appended instructions. The overview stands in for
the archived conversation only, never for the system state.

Keep every system message in [0, boundaryIdx) in front of the overview
in original order; leave a system message inside the retained tail where
it is. On 0.80.3 there are no system messages in the branch, so this
preserves nothing and the behaviour is unchanged. On 0.87 the host
reconciles declared tools against the executable set each request, so
keeping the declarations introduces no duplicate.

Regression tests assert tool loadout and system prompt across pi's real
merge (@earendil-works/pi-ai getCurrentTools/getCurrentSystemPrompt),
resolved from any pi install and skipped on pi < 0.86 where there is
nothing to preserve.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(pi): align takeover archives with trim boundaries

Sync and drain the current branch before committing, calculate keep_recent_count from the actual capture projection, and freeze the exact boundary while asynchronous archive summaries are pending. Only a successful archive with its own non-empty overview may advance context trimming.

Persist capture gaps caused by permanent delivery failures, block takeover across those gaps, and make native compaction fail open while retaining Pi’s first-kept boundary.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* feat(pi): add takeover archive recovery hints

Persist the exact archive and history URIs and append a recovery footer after the bounded overview. Only advertise list/read when both tools are active; grep remains optional and captured history is not described as the full raw transcript.

Document the delivery and pending-archive behavior and bump the stable Pi extension to 0.4.1.

Co-authored-by: TRAE CLI <traecli@bytedance.com>

* fix(pi): anchor the takeover boundary on a pi entry id

The boundary was frozen on getBranch() entries as a user-turn count plus
the fingerprint of the entry in front of it, then applied to the context
hook's messages. getBranch() also holds takeover's own ov-takeover state
entries, which sit in front of every next user turn, model changes and,
after a pi compaction, the compacted-away prefix; the context messages
hold none of them. The fingerprint disagreed on the very next request and
the boundary reset, so takeover committed archives but never trimmed.
After a pi compaction the turn count overshot the context as well.

Make the boundary the id of the entry the covered prefix ends at. Freeze
and apply it on pi's context projection of the branch (compaction-aware,
context edits applied) and map the first kept user entry onto the hook's
messages by timestamp. Messages between the boundary and that turn - a
run that went on after a keepRecentTurns 0 commit, a branch summary /tree
left at the boundary - are covered by no archive and stay. A boundary
outside the active context sends the full context and is kept for a
return to that branch. 0.4.0 state is adopted on the first context hook,
and the pending archive shrinks to the archive and its boundary entry.

Persist takeover state on transitions and at shutdown instead of every
turn, since each entry carries the overview.

With takeover on, startup drained the current session and never replayed
other sessions' queued entries. Drain this session first, then hand the
rest to the generic replay once none of this session's entries remain for
it to drop untracked.

tests/takeover-session-manager.test.mjs drives the core against pi's real
SessionManager. It fails on the previous head; it passes on pi 0.87.0,
and its state-entry, compaction and tree-navigation checks also pass on
0.80.3 and 0.86.1.

* fix(pi): keep takeover inside the host's handler budget

pi hosts cap every extension event handler at 30s; omp logs "handler
timed out after 30000ms", drops the result and lets the handler run on
(#5275). Takeover polled the archive summary inside turn_end - 15 reads
2s apart, 28s before any real work - and a summary that never came
(phase 2 failed, or Working Memory disabled on the server) left a pending
archive that repeated that wait on every later turn.

Nothing waits for a summary in turn_end any more. The commit's overview
is read once; a pending archive is read once per later turn_end and once
in before_agent_start, so a summary finished between prompts or pi -p
processes trims the next request. When the commit's task has ended, or
the server no longer knows it, and a last read still finds nothing, the
pending archive is dropped and its frozen token pressure spent. A pending
archive whose boundary left the active context is dropped without a
read.

Each handler gives takeover a 25s deadline from its start. The drain gets
the time the commit does not need, the commit gets the time one read does
not need, and with less than 10s left the commit waits for a later turn.
The compaction handler still polls, because pi needs its summary now,
but only until the deadline; when it hands compaction back to pi it no
longer resets the boundary, since pi may yet cancel or fail its own
compaction. The drain's default budget drops from 60s to 10s, as startup
replay runs inside before_agent_start too.

Refer to boundaries saved by 0.4.1 and earlier as count-based, since the
released 0.4.1 still writes them, and bump the extension to 0.4.2.

* fix(pi): tell a finished archive by the server's own markers

A pending archive is dropped once no summary can come any more. That was
decided through GET /api/v1/tasks/{id}, but task records expire and a
server replica may not know another's task. The server keeps an archive's
terminal state in the archive itself instead: .done, written last once
commit phase 2 completed (after the Working Memory when that is enabled,
recording working_memory_enabled=false when it is not), and .failed.json
once phase 2 failed for good. Read those markers, as #5320 does to decide
completion, and drop the task lookup.

Co-authored-by: cocolord <17559402+cocolord@users.noreply.github.com>

---------

Co-authored-by: cocolord <17559402+cocolord@users.noreply.github.com>
2026-09-23 22:47:51 +08:00
Lusen DongandTRAE CLI 36ec2f5602 fix(storage): requeue semantic directory lock conflicts (#5340)
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-23 20:54:25 +08:00
Qin Haojie e2011f2948 feat(acl): 默认继承全员管理权限并支持创建时授权 (#5266)
* feat(acl): default shared resources to inherited manager access

Use immutable user:* manage at the shared root and inherit permissions without
extra creator grants. Tolerate temporarily different ACL index snapshots.

* feat(acl): unify permissions under attrs and support creation attributes

* refactor(acl): accept top-level ACL on resource creation

* fix(acl): bind import permissions to authorized targets

Reject internal ingestion options from public resource arguments and defer
ACL authorization until the final import target has been resolved.

* refactor(acl): isolate import permissions from parser arguments

Build ingestion options from explicit public inputs and keep parser arguments out
of post-processing so they cannot supply internal ACL updates. Remove redundant
mkdir ACL handling and make permission snapshot selection easier to follow.

* fix(acl): release import locks after permission failures

Release locally acquired leases when source commit fails or is cancelled,
and ensure artifact cleanup cannot skip post-processing lock release.

* fix(docs): use CLI labels in ACL API references

* refactor(acl): restore dedicated permission interfaces

Restore standalone ACL HTTP, CLI and SDK operations while keeping attrs
focused on its existing attributes. Retain creation-time ACL support and
align the documentation with the final permission model and interfaces.

* fix(acl): authorize connector imports before creating watches

Reject ACL changes before reserving a Watch so denied requests cannot leave it stuck executing. Cover denial and submission cancellation in the existing Watch cleanup test.

* fix(web-studio): align ACL guidance and restriction status

Describe inherited permissions without creator privileges in both locales. Show access restriction only for restricted mode and verify the existing toggle flow against inherited management grants.
2026-09-23 20:52:49 +08:00
1c04d1cd94 feat(tags): support explicit clear mode (#5327)
Add clear semantics across resource ingestion, content writes, reindexing, RNFV scalar planning, SDKs, CLI, and Web Studio. Treat empty replace tags as a no-op while preserving clear through durable queues and only updating vector scalars when the normalized value changes.

Co-authored-by: TRAE CLI <noreply@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-09-23 17:54:24 +08:00
z1gon c2c6407314 fix(hermes): mirror native memory replacements and removals (#5281)
* fix(hermes): mirror native memory replacements and removals

Port the provider implementation from NousResearch/hermes-agent#100187 at 32f75a9e6728a9a3d2f50a870dab3715a1f34fd7, which continues #85860. Keep the existing profile and connection-generation fixes, use relative imports and context-preserving workers, and cover the external loader and native-memory bridge.

* test(hermes): retain native memory mirror regression coverage

* fix(hermes): require committed entry identity and report indexing failures

* fix(hermes): clarify asynchronous add indexing status
2026-09-23 17:36:05 +08:00
t0saki 12748051a6 chore(dsh-plugin): bump to 0.5.2 to publish the format v4 fix (#5335) 2026-09-23 17:33:04 +08:00