Commit Graph
104 Commits
Author SHA1 Message Date
Yu Zhangandzhangyu.34 a57adb951f fix(rerank): support DashScope nested request/response envelope (#3463)
* fix(rerank): support DashScope nested request/response envelope

OpenAIRerankClient sent a flat request body ({"model", "query",
"documents"}) and parsed "results" at the top level of the response.
DashScope (qwen3-rerank) requires a nested envelope:

  Request:  {"model", "input": {"query", "documents"}, "parameters": ...}
  Response: {"output": {"results": [...]}, "request_id", "usage"}

This caused DashScope rerank to silently fail — the response had no
top-level "results" key, so the client returned None.

Changes:
- Add _is_dashscope() to detect DashScope endpoints by host marker.
- Add _build_request_body() that produces the nested envelope for
  DashScope and the flat body for standard OpenAI/Cohere services.
- Add _extract_results() that reads output.results for DashScope and
  top-level results for standard services.
- Accept both "relevance_score" (singular, DashScope) and
  "relevance_scores" (plural, some providers) in result items.
- Add 13 tests covering host detection, body construction, response
  parsing, end-to-end mocked flows for both providers, plural key
  handling, empty documents, and sparse results.

Fixes #3459

* fix(rerank): detect DashScope protocol by URL path, not hostname

Reviewer noted the previous hostname-based switch broke the documented
qwen3-rerank compatible-api endpoint (/compatible-api/v1/reranks), which
must use the flat OpenAI-style body and top-level results.

Switch to path-based detection: only /api/v1/services/rerank uses the
native nested input/output envelope; everything else (including the
DashScope compatible-api and generic OpenAI/Cohere gateways) keeps the
flat protocol. Rename _is_dashscope -> _uses_nested_envelope for clarity.

Add regression tests covering the compatible-api flat path and reconcile
the existing native-path fixtures to the nested envelope.

* docs(rerank): use qwen3-rerank for compatible-api example

The compatible-api/v1/reranks endpoint uses the flat OpenAI-compatible
protocol; qwen3-vl-rerank is a native-envelope model served at
/api/v1/services/rerank. Align the example model with the endpoint the
implementation selects by URL path.

---------

Co-authored-by: zhangyu.34 <zhangyu.34@bytedance.com>
2026-07-22 19:30:41 +08:00
huangruitengandhuangruiteng 0cf36f483e fix(deps): align bot requests with chardet 7 (#3282)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-16 11:09:20 +08:00
Qin Haojie d47f2106ee refactor: remove unused and deprecated APIs (#3272)
Delete dead compatibility paths and test-only helpers so unsupported APIs do not remain as accidental contracts.
2026-07-16 10:49:56 +08:00
Qin Haojie ca70bc0649 refactor(embedding): remove unused batch APIs (#3260) 2026-07-15 16:44:57 +08:00
Jiahui Zhou 1c46d44fbc Fix/reindex preserve owners (#3096)
* fix: preserve reindex content owners

feat: allow trusted admin role assertion

feat: prune orphan vectors during reindex

fix: harden reindex memory body reads

feat: expose reindex prune options in clients

fix(cli): prefer workspace sdk for compat clients

fix: harden reindex prune orphans

* test: align reindex expectations after rebase
2026-07-14 20:38:30 +08:00
huangruitengandhuangruiteng 7d48a230e6 test(resource): isolate service fixtures (#3203)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-13 14:04:16 +08:00
huangruitengandhuangruiteng 378173705b fix: show configured VLM in status without usage (#3148)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-11 16:42:00 +08:00
huangruitengandhuangruiteng 2f5b2e27e1 fix(rerank): accept sparse indexed results (#3121)
* fix(rerank): accept sparse indexed results

* fix(rerank): warn on sparse provider results

---------

Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-11 10:00:56 +08:00
Yuanqing ZHAOandYuanqing Zhao 7e6a0515f9 perf(cuvs): optimize filters, rebuilds, concurrency, and memory (#3092)
* perf(cuvs): fast-path cached native filter routes

* perf(cuvs): parallelize auto filter preflight

* perf(cuvs): add search route telemetry

* test(cuvs): use a valid telemetry vector dimension

* perf(cuvs): reuse native filter preflight results

* perf(cuvs): allow concurrent snapshot searches

* perf(cuvs): coalesce optional background rebuilds

* perf(cuvs): coordinate per-GPU build admission

* perf(cuvs): add opt-in float16 search

* build(cuvs): support vector benchmark harnesses

* perf(cuvs): bound concurrent GPU searches

* perf(cuvs): avoid partial background rebuilds

* fix(cuvs): address rebuild and telemetry review feedback

* fix(cuvs): defer rebuild until index initialization

---------

Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-10 17:22:34 +08:00
Qin Haojie 3003ed61d7 feat(retrieval): support image search (#3093)
Add multimodal image vectorization and image query support across the server, SDKs, and CLI.
2026-07-09 16:42:53 +08:00
Yuanqing ZHAOandYuanqing Zhao 39c778c953 feat: add cuVS vector search backend (#2974)
* feat: add cuVS vector search backend

* docs: add agent memory benchmark strategy

* bench: add cuVS index performance harness

* bench: add public ANN dataset tuning

* docs: record preliminary cuVS index results

* docs: clarify warm index latency

* docs: order cuVS before qdrant

* bench: aggregate independent index runs

* bench: order aggregate variants consistently

* docs: add repeatable index scaling results

* bench: add collection lifecycle benchmark

* docs: add collection lifecycle results

* perf: cache prepared cuvs filters

* docs: report prepared filter cache results

* bench: add async vector concurrency benchmark

* bench: aggregate service concurrency runs

* docs: add async concurrency results

* docs: clarify cuVS dtype behavior

* feat: add memory-aware cuVS auto mode

* feat: reuse native filters for cuVS search

* docs: publish cuVS integration plan as Markdown

* fix: route selective filters before cuVS rebuild

* docs: record selective-first routing results

---------

Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-07 12:21:10 +08:00
Evo 631d7ca98f fix(storage): block deleting the write-protected viking://agent root (parity with #2873) (#2914)
* fix(storage): block deleting write-protected viking://agent root

The delete-namespace guard rejected viking:// and viking://user but not the
account-shared viking://agent root that the sibling write guard already
forbids, so a non-root user could rm(viking://agent, recursive=True) and
recursively wipe account-wide agent skills/endpoints/tools/payments. Mirror
the write guard's bare-agent-root rejection; concrete sub-paths stay deletable.
Parity with #2873.

* test(storage): cover delete rejection of bare viking://agent root
2026-07-01 15:46:53 +08:00
Evo c2384e1d49 fix(storage): honor delete-protected roots on mv source (parity with #2873) (#2898)
#2873 added a delete guard so rm("viking://") / rm("viking://user") raise
PermissionDenied before any side effect. mv() is the sister destructive op
(copy + recursive rm of the source) but only guards the source via the write
guard _ensure_mutable_access, which does not reject the bare "viking://"
account root. So a normal user calling mv from the bare root (HTTP filesystem,
WebDAV MOVE, CLI) reaches the recursive source delete the guard was meant to
forbid.

Apply _ensure_delete_access to the mv source (it is recursively rm'd), keeping
the write guard on the destination. The guard is additive, so it can only
reject more (the protected bare root), never loosen the existing
write-namespace checks; concrete subtree URIs used by internal callers
(watch_manager, semantic_processor) are unaffected.

Adds a parametrized regression test mirroring the existing rm protected-root
test: bare-root mv sources now raise before any AGFS stat/rm.
2026-06-30 19:34:22 +08:00
Zayn Jarvis c528dfd1af Block deleting protected VikingFS roots (#2873) 2026-06-29 14:38:13 +08:00
baojun-zhang e07464e327 reactor(ragfs): prevent recursive backup sync loop by moving default backup workspace and renaming config key (#2767) 2026-06-25 16:05:45 +08:00
87329714dd feat(grep): integrate VikingDB bm25 keyword search for grep engine (#2144)
* 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>
2026-06-24 18:46:02 +08:00
Jiahui Zhou 5a433e5a75 docs: add release guide and align SDK tag format (#2765)
* docs: add release guide and align SDK tag format

* fix: restrict main package release tag discovery

* fix: constrain CLI version tag discovery
2026-06-22 17:15:31 +08:00
Evo 5c74473d04 Prefer AVX2 over AVX512 by default on Windows (#2685) 2026-06-17 20:49:37 +08:00
tuofangandfang 2d56bd71f4 feat(ragfs): add CachedFileSystem and Redis/Mooncake/Yuanrong cache providers (#2520)
* add CachedFileSystem + CacheProvider trait and Mooncake/Yuanrong Provide

add CachedFileSystem + CacheProvider trait and Mooncake/Yuanrong Provide

* Handle poisoned known_keys mutexes in cache providers

* Add configurable cache support to ragfs python

* Add Redis cache provider support

* Prune native cache providers from default build

* Add RAGFS cache guides in Chinese and English

* delete .cargo/config.toml

* Fix stale cache invalidation across shared wrappers

* Document Yuanrong native concurrency limits

* add CachedFileSystem + CacheProvider trait and Mooncake/Yuanrong Provide

add CachedFileSystem + CacheProvider trait and Mooncake/Yuanrong Provide

* Handle poisoned known_keys mutexes in cache providers

* Add configurable cache support to ragfs python

* Add Redis cache provider support

* Prune native cache providers from default build

* Add RAGFS cache guides in Chinese and English

* delete .cargo/config.toml

* Fix stale cache invalidation across shared wrappers

* Document Yuanrong native concurrency limits

* Limit directory cache entries and add regression test

* docs: add TOS s3fs backend test design

* Add runtime cache config override

* add build guides for mooncake and yuanrong

* fix _FakeConfig test with cache

* fix(ragfs): cache encrypted data below the encryption layer

- pass runtime cache config to the Rust binding
- cache ciphertext instead of decrypted content
- disable cache for encrypted multi-write mounts
- update tests and provider build documentation

* fix(ragfs): invalidate cache after same-mount raw copy

Ensure copy_within_mount invalidates the cached destination file and
parent directory after the raw backend fast path writes data directly.
This prevents stale reads and stale directory metadata when cache is
enabled and Python cp() uses the same-mount copy optimization.

Add a regression test covering overwrite copy followed by read/list.

* fix(ragfs): preserve multi-write discovery through cache layer

Allow MountableFS::as_multiwrite() to unwrap CachedFileSystem when
discovering the underlying MultiWriteWrappedFS. This preserves
multi-write admin paths and same-mount copy behavior for cache-enabled,
unencrypted multi-write mounts.

Add a regression test covering sync status, sync retry, same-mount copy,
and unmount behavior for cached unencrypted multi-write mounts.

* feat(ragfs): add cache-aware tree traversal mode

- add configurable tree traversal mode to cache policy
- keep default tree behavior delegated to backend
- allow cached traversal to reuse read_dir directory cache
- bypass cached traversal for multi-write backends
- add regression coverage for tree cache behavior and fallbacks

* docs: design cache-aware grep traversal

* feat(ragfs): add cache-aware grep traversal

Introduce a shared cache traversal mode for recursive APIs and use it to
optionally run grep through CachedFileSystem.

- add CacheTraversalMode with backend and cached_traversal modes
- keep CacheTreeMode as a compatibility alias
- route tree and grep through cached traversal only when explicitly enabled
- reuse cached read_dir entries and full-file reads during grep traversal
- keep multi-write traversal on the backend path
- expose storage.agfs.cache.traversal_mode in Python config
- raise max cached directory entries threshold to 4096
- add regression tests for grep cache traversal and traversal config

* Optimize cached grep generation validation

* Parallelize cached grep file scanning

---------

Co-authored-by: fang <fang@fangMacBook-Air.local>
2026-06-17 16:01:52 +08:00
baojun-zhang eff7e67037 feat(storage): support content-type auto-detecting in S3 case (#2668)
* feat(storage): support content-type auto-detecting in S3 case

* feat(storage): update code doc
2026-06-16 18:24:17 +08:00
Zayn Jarvis 56c903afc6 fix(cli): normalize skill zip paths (#2615)
* fix(cli): normalize skill zip paths

* refactor: share relative path sanitization

* refactor: centralize safe viking uri joins

* test: cover posix skill upload paths
2026-06-15 19:14:16 +08:00
marchpureandhaoxingjun e9d474539e fix zip root detection with macOS metadata (#2550)
Co-authored-by: haoxingjun <haoxingjun@bytedance.com>
2026-06-11 16:48:01 +08:00
Qin Haojie e06671b351 feat(session): 将 session 存储到 user 命名空间 (#2556)
* feat(session): store sessions in user namespace

* fix(session): tolerate legacy commit body fields
2026-06-11 14:33:00 +08:00
baojun-zhang 7ee1481e1d feature(storage): support multi write storage (#2466)
* feature(storage): support multi write storage

* refactor(storage): simplify multiwrite logic and consolidate test helpers

* refactor(storage): extract multibackend and shape modules and tighten multi-write wrapper boundaries

* refactor(storage): refactor write pipeline
2026-06-08 11:12:15 +08:00
baojun-zhang e492cbd16f refactor(encryption): using rust refactor encryption (#2444) 2026-06-05 17:26:26 +08:00
Qin Haojie ff258768c2 feat(memory): 引入 User/Peer 记忆隔离模型 (#2236)
* feat(memory): introduce user and peer memory isolation

Unify agent-scoped memory behavior into user-owned memory spaces, add peer_id compatibility for session and retrieval paths, and wire memory_policy through session commit flows.

* feat(memory): align session identity around peer IDs

* feat(search): pass peer id through retrieval

* refactor(memory): remove agent identity from integrations

* fix(memory): isolate peer identity from self extraction

* fix(tau2): provision benchmark user configs

* fix(auth): allow admin keys to access data APIs

* fix(openclaw): enable peer memory policy for peer roles

* fix(openclaw): resolve sender for peer recall

* refactor(session): simplify memory extraction routing

* refactor(ov-cli): reduce formatting-only diff

* refactor(message): remove unused message helpers

* refactor(retrieval): simplify peer target resolution

* refactor(namespace): remove deprecated agent namespace policy

* fix(agent): propagate peer id through integrations

* fix(auth): align integration clients with api-key mode
2026-06-05 10:55:48 +08:00
Qin Haojie 72ec6f9287 feat(resources): persist async add-resource tasks (#2433)
* feat(resources): persist async add-resource tasks

* fix(cli): surface add-resource API errors

* fix(resources): fail async task on queue errors
2026-06-04 20:14:09 +08:00
Qin Haojie 96df42f2a9 refactor(memory): remove legacy memory v1 (#2264) 2026-05-27 19:49:38 +08:00
Qin Haojie f2f8076f31 fix(ovpack): skip missing semantic sidecars (#2265) 2026-05-27 18:25:54 +08:00
bot-of-qin-ctxandqin-ctx c0f4c0667b Fix/semantic target sync (#2207)
* fix(storage): sync semantic target before DAG

* Update CONTRIBUTING_CN.md (#2206)

* Update CONTRIBUTING_CN.md

---------

Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-05-23 23:27:39 +08:00
Qin Haojie 2406c0e6e1 refactor(storage): 异步化存储锁与 IO (#2143)
* refactor(storage): async storage lock IO

Move AGFS and storage lock paths onto async wrappers while preserving lock handoff semantics.

* refactor: streamline async task tracking

Collapse TaskTracker lifecycle operations into async-only APIs and align callers/tests with the new boundary. Also throttle repeated memory/path lock wait warnings to reduce noisy retry logs.
2026-05-22 14:03:18 +08:00
Qin Haojie cfb19a50ca fix(storage): isolate async clients and semantic refresh (#2168)
Cache async SDK clients per event loop to avoid cross-loop reuse in worker threads.
Move memory vectorization into semantic queue refresh and preserve target sync state for resource updates.
2026-05-21 17:24:52 +08:00
Zayn Jarvis d6a024efa5 feat(docker)!: drop legacy console (keep BFF + Caddy), ship web-studio in pip, fix favicons (#2160)
The OpenViking docker image still launched the legacy `openviking/console`
standalone service on port 8020. Now that web-studio is bundled into the OV
server itself at /studio (see #2156), that process is redundant and the
port is just a confusing artefact.

This change retires the old console (python package + 8020 + console-frontend
favicons) but **keeps the in-compose Caddy as a stable single-ingress on
port 1934**, just simplified to one upstream now that there's no 8020. The
server-side BFF at `openviking/server/routers/console.py` (under
`/api/v1/console/*`) is also kept — web-studio uses the same endpoints.

**The OAuth authorize page (`openviking/server/oauth/router.py`) is
deliberately untouched in this PR** — the console-link button and Quick
authorize same-origin panel will be re-pointed at web-studio in a focused
follow-up.

BREAKING CHANGES:
- Port 8020 is gone from the docker image and docker-compose.yml; Caddy at
  1934 now forwards everything to 1933 (web-studio lives at /studio there).
  Anything bookmarked at `http://host:8020/...` must migrate to
  `http://host:1933/studio/`.
- `python -m openviking.console.bootstrap` no longer exists; the python
  package `openviking.console` has been removed.

Pip packaging:
- web-studio dist is now shipped inside the wheel under
  `openviking/web_studio/dist/` (mirroring the old `openviking/console/static/`
  layout). The dockerfile copies `--from=web-studio-builder /web-studio/dist`
  into the source tree before `uv sync`, so the wheel produced by the
  default docker build always carries the SPA. Building the wheel without
  running `npm run build` first leaves the directory empty, which gracefully
  degrades /studio to a 404 without breaking server startup.
- Favicon assets (`favicon.ico` / `favicon-32.png` / `apple-touch-icon.png`,
  ~11 KB total) are duplicated into `openviking/server/static/` and shipped
  via package-data so `/favicon.*` and `/mcp/favicon.*` routes are always
  registered, regardless of whether the web-studio dist is bundled.
- `pyproject.toml` and `setup.py` `package-data` drop `console/static/**`
  and add `server/static/**` + `web_studio/dist/**`.
- New favicons (the 16/32/180 set in both `openviking/server/static/` and
  `web-studio/public/`) are downscaled from the canonical
  `web-studio/public/openviking-icon.png`, so the small-icon family matches
  the SPA's high-res rel="icon" target — the studio tab icon now stays
  consistent whether the browser uses the HTML link tag or falls back to
  auto-fetching `/favicon.ico`.

Server:
- `openviking/server/app.py` now reads `/studio` from
  `Path(__file__).parent.parent / 'web_studio' / 'dist'` by default;
  `OPENVIKING_WEB_STUDIO_DIR` still wins for dev mode pointing at a
  repo-local build. Favicon routes are unconditionally registered and
  load from `openviking/server/static/`.
- `openviking/observability/usage_audit/projection.py` drops the legacy
  `/console/*` skip prefix (the BFF prefix `/api/v1/console/*` remains).

Docker:
- `web-studio-builder` stage moved earlier (Stage 2) so its dist can flow
  into `py-builder` before `uv sync` runs.
- Runtime stage no longer separately copies the dist or sets
  `OPENVIKING_WEB_STUDIO_DIR`; the in-package path is the default.
- Entrypoint renamed `openviking-console-entrypoint.sh` -> `openviking-entrypoint.sh`
  and stripped of the `python -m openviking.console.bootstrap` launch.
- `EXPOSE 1933 8020` -> `EXPOSE 1933`.
- `docker-compose.yml` drops the openviking service's 8020 port mapping;
  the caddy service stays but no longer needs port 8020 exposed.
- `Caddyfile` simplified to a single `:1934 { reverse_proxy openviking:1933 }`
  — the legacy `/console/*` route to :8020 is gone.

Docs:
- en/zh quickstart updated to drop the 8020 mapping and explain that the
  API server now also serves `/studio`.
- Other guides (`12-public-access.md`, `11-oauth.md`, `05-observability.md`,
  `04-setup-for-agent.md`, `03-deployment.md`) are intentionally left for a
  focused follow-up PR alongside the OAuth quick-authorize reintroduction.

Tests:
- Deleted `tests/misc/test_console_{proxy,static_assets}.py` (covered the
  removed console package). `tests/observability/test_console_router.py`
  stays — it covers the BFF, which remains.
2026-05-21 16:41:29 +08:00
Qin Haojie 77b604a641 fix(storage): 优化路径锁与语义刷新并发 (#2029)
* fix(storage): refine path lock semantic refresh concurrency

Use exact path locks for source commits, tree locks only for lifecycle and schema scopes, and coalesce derived semantic writes to avoid stale summary overwrites under concurrent resource and memory updates.

* chore: split benchmark changes into separate PR

* chore: keep semantic refresh design notes out of docs

* style: format lock changes

* fix: preserve resource lifecycle locks

* Revert "fix: preserve resource lifecycle locks"

This reverts commit d2fb274f85.

* fix(resource): simplify lifecycle locking

* fix(queuefs): consolidate semantic sidecar writes
2026-05-14 20:44:28 +08:00
MaojiaSheng a1c9e5080b feat: add ov observer filesystem, and optimize mkdir frequency (#2045)
* feat: ov add-resource (spec -L --level), ov stat (return count for dir)

* feat: ov add-resource (spec -L --level), ov stat (return count for dir)

* feat: Add VLM backup configuration for automatic failover

- Add backup field to VLMConfig with recursive backup prevention
- Implement FailoverVLM wrapper class for automatic failover
- Support rate limit, timeout, server error triggers
- Add comprehensive unit tests

* feat: Add VLM backup configuration for automatic failover

* feat: Add VLM backup configuration for automatic failover

* ov observer filesystem

* ov observer filesystem
2026-05-14 18:21:26 +08:00
Qin Haojie 9d36b2fd83 feat(console): 增加 Usage/Audit Dashboard BFF (#2016)
* feat(console): add usage audit dashboard BFF

* feat(console): add usage audit retention config

* docs(console): remove local usage audit design doc
2026-05-14 18:19:42 +08:00
Jiahui Zhou fa0be9c958 feat: make queuefs backend configurable (#2018)
fix: harden request wait tracker against queue races

update

refactor queuefs mode config

docs: document queuefs mode and refactor mount resolver
2026-05-13 18:31:07 +08:00
yepper ddcd3fb9c8 chore(format): align python and c++ file formatting (#2001)
* chore(format): align python and c++ file formatting

* chore: update urllib3 to 2.7.0 and clean test imports

1. bump urllib3 dependency from 2.6.3 to 2.7.0
2. remove unused pytest import and RoleScope import from test file

* style: format list comprehensions and lambda function for readability

Adjust the line breaks in the list comprehension in the VikingSearchTool class to follow standard Python formatting conventions, and rewrap the lambda assignment in the test case to improve code readability without changing functionality.

* style: fix line wrapping and remove extra blank line

- remove stray blank line in ov_server.py
- wrap long logger.info line in memory.py for better readability

* style: fix targeted ruff lint violations

* chore: clean up unused imports and reorder code

This commit removes unused imports, reorders import statements for better consistency,
and simplifies some test file imports. Changes include:
- Remove redundant blank lines and unused imports across multiple test files and core modules
- Reorder imports in openviking hooks module to follow standard layout
- Fix import ordering in memory isolation handler
- Simplify php parser type imports
- Move volcengine mock import to correct position in test file

* refactor(uri utils): remove extra blank lines in uri.py

clean up redundant whitespace to improve code readability
2026-05-13 17:53:09 +08:00
zexuyannandjinze 19ae28abc9 fix(parse): preserve source_name when zip single root differs (#1991)
* fix(parse): preserve source_name when zip single root differs

ZipParser collapsed any zip whose top level held a single directory and
unconditionally dropped source_name. For CLI add-resource on a directory
whose only child differs in name (e.g. user uploads "access/" containing
just "access-dns/"), this silently dropped the user-named parent layer:
the resource landed at "<parent>/access-dns" instead of
"<parent>/access/access-dns".

Only collapse when source_name is absent or its stem matches the single
root dir name (the legacy "tt_b.zip" wrapping "tt_b/" case). When
source_name names a distinct outer layer, parse the extract root and
keep source_name so DirectoryParser preserves it as dir_name.

* fix(parse): compare basename before stem in zip single-root collapse

Path(source_name).stem drops trailing dotted segments, so source_name
"v1.2" against a zip whose single root is "v1.2/" would fail the
equality check and re-wrap the content, producing
"viking://resources/v1.2/v1.2/...". Compare the leaf name first so
dotted names match exactly, and keep the stem fallback for the
"tt_b.zip" wrapping "tt_b/" case.

Also adds end-to-end regression tests that drive ZipParser +
DirectoryParser + TreeBuilder.finalize_from_temp against an in-memory
VikingFS and assert the final root_uri, so future changes in
DirectoryParser or TreeBuilder can't silently drop the outer layer.

---------

Co-authored-by: jinze <yanzexu.yzx@antgroup.com>
2026-05-12 19:11:21 +08:00
Qin Haojie 5fdbfd4e49 feat(ovpack): support vector snapshots and consistency checks (#1965)
* feat(ovpack): add vector snapshot backup support

* feat(ovpack): add vector snapshots and consistency checks

* fix(ovpack): validate reserved paths and index expectations

* fix(ovpack): limit consistency report output

* fix(ovpack): isolate archive content namespace

* chore(ovpack): move consistency cli under system
2026-05-11 21:11:42 +08:00
Qin Haojie e648b2679c feat(ovpack): add v2 manifest and backup restore (#1927)
* feat(ovpack): add v2 manifest and conflict policy

Add a portable OVPack manifest for scalar metadata and make imports validate scope, derived files, and conflicts before writing.

* fix(ovpack): remove import vectorize option

Make OVPack imports always rebuild vectors in the target environment, keep legacy packages compatible, and reject unsupported manifest versions before writing.

* fix(ovpack): remove force import alias

Use on_conflict as the single OVPack import conflict policy and reject removed force inputs.

* fix(ovpack): regenerate runtime vector metadata

Keep type portable but stop exporting or applying created_at, updated_at, and active_count from OVPack manifests.

* fix(ovpack): validate manifest contents

* fix(ovpack): require manifests for imports

* fix(ovpack): close manifest validation gaps

* fix(ovpack): defer parent creation until validation passes

* fix(ovpack): remove export size guard

* fix(ovpack): support session and scope-root restores

* docs(ovpack): document full backup migration

* feat(ovpack): add backup restore workflow

* fix(ovpack): validate import scope compatibility
2026-05-11 11:09:35 +08:00
Jiahui Zhou b0139c1932 Persist task tracker (#1949)
* feat(tracker): persist task tracker state across instances

fix: default task tracker to memory backend

* refactor: scope persistent task paths by user
2026-05-11 11:06:31 +08:00
baojun-zhang c8ff9e3575 perf(storage): optimize VikingFS grep implementation (#1731)
* perf(storage): optimize VikingFS grep implementation
- add ripgrep support and native local grep fallback for LocalFS mode
- normalize grep path handling and improve regression test coverage

* perf(storage): optimize VikingFS grep implementation
- add ripgrep support and native local grep fallback for LocalFS mode
- normalize grep path handling and improve regression test coverage

* perf(storage): format code

* perf(storage): support async grep

* feat(encryption): Push `exclude_uri` and `level_limit` down to the backend to ensure that the limits take effect after the same set of filtering conditions. &&  The default implementation also follows the same path contract as LocalFS, returning the path relative to the query root

* feat(encryption): Push `exclude_uri` and `level_limit` down to the backend to ensure that the limits take effect after the same set of filtering conditions. &&  The default implementation also follows the same path contract as LocalFS, returning the path relative to the query root

* fix(storage): relativize localfs exclude_path against grep query root && disable parent .gitignore inheritance in localfs rg fast path && add HTTP AGFS grep support for exclude_path and level_limit
2026-05-07 19:41:33 +08:00
euyua9 2fb5cc1ec6 fix: reject mismatched ragfs cpython extensions (#1854)
* fix: reject mismatched ragfs cpython extensions

* fix: reject windows ragfs cpython tag drift
2026-05-06 11:31:11 +08:00
Qin Haojie 964998daca fix(ragfs): load Windows abi3 pyd artifact (#1801) 2026-04-29 20:10:07 +08:00
Jiahui Zhou c0ecbe3096 fix(ragfs): make s3 key normalization chars configurable (#1767) 2026-04-28 14:46:31 +08:00
Qin Haojieanddingben.db@bytedance.com <dingben.db@bytedance.com@bytedance.com> 6aa62c1b87 fix(ragfs): 仅加载 abi3 binding 产物 (#1756)
* feat(agfs): support overriding queuefs db_path via config

Add a new optional `storage.agfs.queue_db_path` field to AGFSConfig so
the queuefs sqlite database can be relocated outside the workspace via
config. This helps when the workspace volume does not support sqlite
(e.g. some network filesystems returning disk I/O errors on PRAGMA/WAL),
allowing the queue db to be placed on a local path like `/tmp/queue.db`.

When not set, the default path `{storage.workspace}/_system/queue/queue.db`
is preserved, keeping backwards compatibility.

* fix(ragfs): load only abi3 binding artifacts

Avoid stale cpython-specific ragfs_python artifacts shadowing rebuilt abi3 extensions so queuefs sqlite persistence uses the current Rust binding.

---------

Co-authored-by: dingben.db@bytedance.com <dingben.db@bytedance.com@bytedance.com>
2026-04-27 21:30:44 +08:00
yepper 44c8aa0c46 fix(resource): preserve temp tree for incremental add-resource (#1755) 2026-04-27 21:28:29 +08:00
Qin Haojie 92f0caa563 fix(docker): resolve image version explicitly (#1698)
Avoid Docker builds defaulting OpenViking package metadata to 0.0.0 and document the required build arg for local image builds.
2026-04-25 10:19:20 +08:00
Jiahui Zhou ce090be826 feat(ragfs): add s3 key normalization encoding (#1685) 2026-04-24 19:44:19 +08:00