Commit Graph
1793 Commits
Author SHA1 Message Date
Monday 49ca3cdfe8 feat(python-sdk): support event hooks and lifecycle reset (#3392)
* feat(python-sdk): support event hooks and lifecycle reset

* fix(python-sdk): limit client hooks change to event hooks

* docs(python-sdk): initialize clients in readme examples
v0.4.11 python-sdk@0.1.5 cli@0.4.11
2026-07-23 14:16:43 +08:00
Wu JiaChengandqin-ctx 62a913795c fix(parse): honor markdown frontmatter config (#3475)
* fix(parse): honor markdown frontmatter config

* refactor(parse): simplify frontmatter config handling

---------

Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-07-23 11:55:59 +08:00
d681ef3158 fix(parse): handle parentheses in Markdown image paths (#3462)
* fix(parse): handle parentheses in Markdown image paths

The image regex !\[([^\]]*)\]\(([^)]+)\) used [^)]+ for the path capture
group, which truncates at the first ) character. When document titles
or filenames contain balanced parentheses (e.g. "文档_17 (17号项目)"), the
generated image paths include ) and the regex captures a truncated,
non-existent path. This causes _resolve_image_path() to fail silently
(WARNING only), and the image is never copied to VikingFS or sent to
VLM for understanding.

Fix: replace the path capture group with (?:[^()]|\([^()]*\))+, which
allows one level of balanced parentheses inside the path while still
terminating at the correct closing ) of the Markdown image syntax.

Add focused tests covering balanced parens in directory and filename
components, URLs with parens, multiple images on one line, and
non-matching of plain links.

Fixes #3455

* fix(test): exercise MarkdownParser._image_pattern directly, remove unused import

Address review feedback on #3462:
1. Tests now import and instantiate MarkdownParser to access the
   production _image_pattern regex, instead of compiling an independent
   copy. Tests fail if the production regex regresses.
2. Remove unused `import pytest` (Ruff F401).

* fix(parse): rewrite parenthesized image paths

* test: remove extra image rewrite regression case

* fix(parse): share markdown image parsing for rewrite

* refactor(parse): keep markdown image fix minimal

---------

Co-authored-by: zhangyu.34 <zhangyu.34@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-07-23 11:33:26 +08:00
Yuanqing ZHAOandYuanqing Zhao 40dd05271c perf(vectordb): micro-batch compatible cuVS searches (#3382)
* perf(vectordb): micro-batch compatible cuVS searches

* fix(vectordb): serialize micro-batch device admission

* perf(vectordb): pipeline warm cuVS micro-batch admission

* docs(cuvs): align micro-batching guidance

* fix(cuvs): warm-batch empty filters

---------

Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-23 11:10:52 +08:00
Zayn Jarvis 997e750ccc fix(ov): redact gateway secrets in config show and create root key with 0600 (#3411)
* fix(ov): redact gateway secrets in config show and create root key with 0600

Sweep findings: E-02, E-03. Prevent credential disclosure in output and at key creation.

* test(ov): drop trivial init-key permission test

The 0600 fix is a one-line OpenOptions::mode; a dedicated tokio+tempfile
test module for a single mode assertion is not worth its weight. The
redaction test in store.rs (a real multi-case security behavior) stays.
2026-07-23 10:47:28 +08:00
Zayn Jarvis 3043e25194 docs(openclaw): document manual plugin configuration (#3446)
* docs(openclaw): document manual plugin configuration

* docs(openclaw): clarify manual config safety

* docs(openclaw): sync manual config guidance
2026-07-23 10:46:53 +08:00
Zayn Jarvis 8da91a860b fix(bot): pass sender_name in all channel adapters (#3399)
* fix(bot): pass sender_name in all channel adapters

Sweep findings: C-01. Supply display-name fallbacks so inbound messages reach the bus.

* fix(bot): make sender_name optional and wire real WhatsApp pushName

Root-cause guard: _handle_message required sender_name positionally, but
InboundMessage.sender_name is str|None=None and context.py already falls back
to sender_id, so the required-ness was an accidental signature/contract
mismatch. Make it optional (reordered after the still-required chat_id/content;
all 11 call sites use keyword args) so no future adapter can crash on it.

WhatsApp: the previous call read data.get("senderName")/data.get("pushName"),
neither of which the bridge ever sends, so it silently always fell back to the
numeric id. Forward baileys' msg.pushName through the bridge payload and read it
in Python, so WhatsApp group chats show real display names like other channels.
2026-07-23 10:45:33 +08:00
yufeng 82f5383fd5 docs: add Python installer tabs (#3481)
* docs: add Python installer tabs

* docs: clarify installed commands
2026-07-23 10:41:18 +08:00
yijie zhao 09cd4782df fix: allow opencode recall after session context (#3464)
* fix: allow opencode recall after session context

* test: cover opencode recall with session context
2026-07-22 19:32:13 +08:00
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
baojun-zhang dad04e37b8 build(ragfs): clean stale .venv ragfs_python artifacts to avoid site-packages override (#3318) 2026-07-22 19:24:02 +08:00
Evo 0d2c1516a2 docs(transaction): align crash-recovery guidance with the 30-minute lock expiry (#3338)
* docs(transaction): align lock expiry guidance

* docs(transaction): align Chinese lock expiry guidance
2026-07-22 19:23:26 +08:00
Yu Zhang 93162b2fd3 fix(sdk-typescript): distinguish cancellation from timeout (#3369) 2026-07-22 19:21:32 +08:00
Qin Haojie fd098cfd65 fix(cli): preserve structured API errors (#3379)
* fix(error): preserve structured errors in cli

* fix(cli): preserve status for non-json errors
2026-07-22 18:06:48 +08:00
baojun-zhang 2b78fff498 Fix dual path lock (#3454)
* fix(storage): add short timeout for encrypted dual-path write locks

* Reduce PathLockEngine poll interval from 0.2s to 0.1s.
2026-07-22 16:08:01 +08:00
Wu JiaCheng 061359a2f5 fix(parse): normalize MIME aliases with parameters (#3393) 2026-07-22 15:44:43 +08:00
blakejia 12b4aab13d docs: add S3-compatible storage pitfalls to multi-write guide (#3390)
- Add directory_marker_mode: none to all S3 config examples
- Add S3-compatible storage notes with required fields table
- Add Docker networking guidance for Linux vs macOS/Windows
- Remove private IP addresses from examples (use localhost)
- Apply changes to both English and Chinese versions
2026-07-22 15:34:21 +08:00
Wu JiaCheng 63c878e60e fix(parse): import extensionless README files (#3394) 2026-07-22 15:29:13 +08:00
Rocke Dong ef43b0fc37 fix(deps): restore openviking-sdk lock entry (#3441) 2026-07-22 15:28:24 +08:00
Qin Haojie 339817d981 fix(resource): isolate external parsing queue (#3448)
Keep local resource ingestion from waiting behind UnderstandingAPI jobs while preserving durable queue recovery.
2026-07-22 15:11:50 +08:00
agent a93769b828 fix(memory): propagate transaction lock handles to nested writes (#3444)
* fix(memory): propagate transaction lock handles

* chore(memory): narrow lock propagation fix
2026-07-22 15:06:48 +08:00
yufeng a949517f27 docs: add OpenViking Helper integration and fix stale links (#3445)
* docs: add OpenViking Helper integration

* docs: use mock data in Helper screenshots
sdk/go/v0.0.1
2026-07-22 14:14:57 +08:00
Zayn JarvisandClaude Fable 5 94827db8f5 docs: revamp README — sell first, link detail to docs.openviking.ai (#3395)
* docs: revamp README for readability, route detail to docs.openviking.ai

The README had grown to ~850 lines, 60% of it provider-config JSON that
duplicates the deployed configuration guide. Rewritten to ~253 lines:

- Lead with what the product is, a Studio screenshot, and five feature
  bullets, each outlinked to docs.openviking.ai
- Move benchmarks (LoCoMo, tau2-bench, HotpotQA) above the fold; drop two
  derived tables in favor of one-sentence summaries + ./benchmark links
- Collapse install to the init/doctor golden path; all provider JSON,
  ov.conf templates, env vars, and Windows setup now route to the
  configuration guide (verified live)
- Add the previously missing "Use it with your agent" section linking all
  10 integration docs
- README_CN (zh docs links) and README_JA (en docs links; ja docs not
  deployed) rewritten to mirror section-for-section
- New hero screenshot docs/images/studio-playground.png from
  openviking.ai/studio

All 76 external URLs and every repo-relative link verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4oDxmJojygyomsz9BBhhn

* docs: fix review findings — restore uncovered detail, drop false pointers

Adversarial review of the revamp found four claims pointing at coverage
that does not exist:

- Restore `cargo install --git ... ov_cli` build-from-source path (was
  deleted with no docs destination; docset has no cargo install anywhere)
- Restore `ov reindex` mode documentation (vectors_only /
  semantic_and_vectors / prune_orphans / --dry-run / no alias warning) —
  covered by no linked doc
- Remove "per-agent breakdown is in ./benchmark" (benchmark/ holds
  reproduction scripts, not result tables)
- Remove "Reproduce it from ./benchmark" on the 5-dataset RAG summary
  (adapters exist for only 3 of 5 datasets)

Also: EN/JA quick-start grep example now targets docs/en instead of
docs/zh. Applied identically to README.md, README_CN.md, README_JA.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4oDxmJojygyomsz9BBhhn

* docs: apply review feedback — blog philosophy link, deployed doc links, drop dead widgets

- Link the design-philosophy essay (The Database Paradigm for Context
  Engineering, blog.openviking.ai) from the Why section so the old
  README's design narrative has a durable home; add Blog to community
- Switch remaining ./docs about-us links (header + community, incl. QR
  anchors) to docs.openviking.ai; zh anchors verified against deployed
  page ids (#飞书群 / #微信群)
- Remove the star-history chart (service currently renders nothing) and
  the stale "May 2026 Update" banner line
- Caption now states the Studio link is a live demo, no install needed

Applied identically to README.md, README_CN.md, README_JA.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4oDxmJojygyomsz9BBhhn

* docs: benchmark charts, easier quick start, logo padding

- Replace the three benchmark tables with one theme-aware SVG chart
  (light/dark via <picture>): LoCoMo and tau2-bench as grouped bars,
  gray = without OpenViking, blue = with. HotpotQA leaves the README;
  full results link to the benchmark report on blog.openviking.ai.
  Hand-written SVG, exact numbers from the tables — no generated images.
- Rework Quick start reading flow: nohup folds into the install block,
  note that pip install already ships the ov client CLI, close with a
  two-link "Next steps" (CLI setup, Deployment). ov reindex modes and
  the cargo source install move to the CLI setup doc (en+zh) so the
  README stays an easy entry.
- Shrink logo artwork to 0.7 inside the same 842x842 canvas for
  breathing room.

Applied to README.md, README_CN.md, README_JA.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4oDxmJojygyomsz9BBhhn

* docs: enlarge logo artwork 1.1x within same canvas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4oDxmJojygyomsz9BBhhn

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 10:28:32 +10:00
Jiahui Zhou 4295dfdef0 docs(cli): update ov cli readme (#3388) 2026-07-22 00:01:59 +10:00
Yuanqing ZHAOandYuanqing Zhao 2d84a6f13c perf(cuvs): improve recovery scalability and filtered-search efficiency (#3311)
* perf(index): avoid materializing descendant path strings

* perf(cuvs): compact host vector shadow

* perf(storage): prune redundant tenant path scopes

* fix(cuvs): synchronize worker-thread searches

* perf(cuvs): stream dense shadow recovery

* test(storage): cover cross-user path scopes

* perf(storage): page candidate recovery scans

* perf(cuvs): accelerate adaptive filter routing

* perf(cuvs): reduce filtered-search host overhead

---------

Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-21 15:59:58 +08:00
Jiahui Zhou 5390bd5e54 fix: require all retrieval tags in search (#3097) 2026-07-21 11:54:01 +08:00
yufeng 085aaf832d docs: correct context paths and refine navigation (#3385) 2026-07-21 11:45:17 +08:00
ShaoZegangByte 39dc01e2a5 feat(resource): support Feishu/Lark URL imports via UnderstandingAPI (#3320)
* feat(resource):add lark understand api

* fix(resource):add lark understand api env

* fix(resource):add lark understand api

* fix(resource):understand api pr

* fix(resource):add test

* fix(resource):handle deferred URIs for async Feishu imports

* fix(resource):fix Ruff issues in lark import

* fix: persist final resource URI for async UnderstandingAPI tasks

* fix: clean up cancelled async UnderstandingAPI scheduling

* fix: getattr defer_target_resolution
2026-07-21 11:08:13 +08:00
Yuanqing ZHAOandYuanqing Zhao e1cea0998b perf(vectordb): avoid hydrating unrequested vectors (#3375)
Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-20 19:13:00 +08:00
Evo dd31e3a05a docs(resources): clarify uploaded snapshot watch limits (#3363) 2026-07-20 19:10:49 +08:00
Qin Haojie 370fe45f6f fix(auth): serialize API key registry writes (#3377)
Prevent concurrent account and user registry updates from racing in AGFS.
2026-07-20 17:51:07 +08:00
huangruitengandhuangruiteng f093fafd1b fix(feishu): preserve title prefixes in resource names (#3366)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-20 17:16:49 +08:00
Hao Zhe 3b2571b36e feat(openclaw): add catalog icon (#3362) 2026-07-20 14:55:30 +08:00
Qin Haojie 1d4bf132ed fix(task): 修复 add-resource 任务重启后无法恢复 (#3334)
* fix(task): recover add-resource jobs after restart

Persist asynchronous add-resource work in QueueFS so interrupted jobs can resume instead of leaving tasks running forever.

* fix(queue): omit parser args from prepared jobs

* fix(queue): fail when semantic source is missing
2026-07-20 14:07:27 +08:00
Yu Zhang 295ce577b1 fix(memory): isolate unresolved URI operations (#3299)
* fix(memory): isolate unresolved URI operations

* fix(memory): preserve deletes when URI resolution fails
2026-07-20 10:31:41 +08:00
huangruitengandhuangruiteng 810a22d881 docs: isolate OpenViking installs for Hermes (#3365)
* docs: isolate OpenViking installs for Hermes

* docs: keep install guidance scoped to Hermes

---------

Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-20 08:21:03 +08:00
黄云龙 c8fd73aaca fix(session): return in-flight archive messages in get_session_context (#3129) (#3149)
* fix(session): return in-flight archive messages in get_session_context (#3129)

Seed latest_completed_index from 0 instead of commit_count so that
archives whose Phase 1 has completed (messages written, commit_count
advanced) but whose Phase 2 is still running (.done not yet written)
are treated as pending rather than already completed.

The release/0.3.x implementation seeded from 0 and did not have
this bug; the regression was introduced when commit_count was
adopted as the seed value.

* test(session): deterministic regression for pending archive context (#3129)

Replace the monkey-patched commit_async test with a direct
filesystem-state test that sets up the post-Phase-1 archive
(messages.jsonl present, commit_count advanced, no .done marker)
and asserts get_session_context still surfaces the archived
messages.

This is deterministic regardless of the queue-worker architecture
because it creates the archive state directly via the mock AGFS
and loads a fresh session from that state, never calling
commit_async or touching the session compressor.
2026-07-20 08:18:25 +08:00
kujomyandkujomy 5ca69cb5d8 fix(resource): reject watch_interval on uploaded one-shot sources instead of silently watching a frozen snapshot (#3324)
Co-authored-by: kujomy <kujomy@users.noreply.github.com>
2026-07-19 21:37:45 +08:00
Kchenandchenpengfei 5f945fa8e6 fix(path_lock): (#3353)
# 并发精确路径锁下父目录幂等创建设计

## 问题

两个并发写请求分别写入不同文件时,可能需要在同一个父目录中创建精确路径锁文件。如果该父目录尚不存在,两个加锁流程都可能先观察到目录不存在,随后递归创建同一个目录。其中一个 `mkdir` 成功,另一个收到 `EEXIST`/already-exists;此时所需目录其实已经存在。

`PathLockEngine._ensure_directory_exists_async` 当前将所有 `mkdir` 异常都视为失败。因此,竞争失败一方的加锁结果为 `False`,内容写入链路最终向调用方返回 HTTP 409 `resource is busy`。

## 预期行为

并发场景下,目录创建应具有幂等语义:

- 如果 `mkdir` 抛出异常,但重新执行 `stat` 后确认目标已经是目录,则目录准备成功。
- 如果目标仍不存在、无法查询,或者目标是非目录条目,则保持原有失败行为。
- 本次修改只影响路径锁所需父目录的准备流程,不改变锁冲突、等待超时和 HTTP 错误语义。

## 实现方案

修改 `openviking/storage/transaction/path_lock.py` 中的 `PathLockEngine._ensure_directory_exists_async`:

1. 保留现有的首次 `stat` 和递归创建父目录流程。
2. 调用 `mkdir(path)` 创建当前目录。
3. 如果 `mkdir` 抛出异常,立即通过 `_is_existing_directory_async(path)` 重新查询目录状态。
4. 如果重新查询确认目标是目录,则返回成功。这样既能处理明确的 `EEXIST`,也能兼容存储后端对该错误的包装;只有在所需文件系统状态已经成立时才忽略异常。
5. 如果重新查询未确认目标是目录,则记录原始 `mkdir` 异常并返回失败。

不增加通用重试循环。如果竞争方在该路径创建的是文件而不是目录,不能将其视为成功。

## 回归测试

在 `tests/transaction/test_exact_path_lock.py` 中增加一个可稳定复现竞态的异步测试:

- 初始文件系统中存在 `/local/default/resources`,但不存在其下的共享子目录。
- 并发为共享子目录下两个不同文件获取精确路径锁,例如 `shared/a.md` 和 `shared/b.md`。
- 通过测试 AGFS 的同步点,保证两个加锁流程首次对 `shared` 执行 `stat` 时都看到目录不存在,然后才允许任一方执行 `mkdir(shared)`。
- 允许一个 `mkdir(shared)` 创建目录,另一个抛出 already-exists 异常。
- 断言两个精确路径锁都获取成功,并且创建了两个不同的锁文件。

该测试在现有实现上必须失败:竞争失败一方的 `mkdir` 异常会进入 `_ensure_directory_exists_async` 的失败分支。

## 非目标

- 不修改调用方 `upsertTextWithConflictFallback` 的行为。
- 不调整 `resource is busy` 的可重试分类。
- 不修改精确路径锁与目录树锁之间的冲突规则。
- 不为其他 AGFS 异常增加通用重试。

Co-authored-by: chenpengfei <chenpengfei@bytedance.com>
2026-07-19 19:17:11 +08:00
huangruitengandhuangruiteng 379c19f66e fix(codex): preserve recall on Windows spawn failure (#3308)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-19 13:35:41 +08:00
huangruitengandhuangruiteng d16a92c63f fix(memory): restore vectorization after redo recovery (#3331)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-18 00:25:30 +08:00
DuTao 55a9d12cd6 1. 优化评测参数化; (#3332)
2. 优化评测显示;
3. 修复gpt-5.6 api返回 无 choices时bot兼容问题。
2026-07-17 17:46:57 +08:00
Hao Zhe ebe7fa2a7d fix(plugins): align OpenCode and OpenClaw contracts (#3232) 2026-07-17 17:06:27 +08:00
chenjw 8fd8fd1b0b fix(lock): extend default lock expiration to 30 minutes (#3321) 2026-07-17 13:59:55 +08:00
huangruitengandhuangruiteng f0d241e4a0 fix(bot): enable logs for config-started gateway (#3319)
Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
2026-07-17 10:56:16 +08:00
ef4d97ebe3 feat(snapshot): support path-filtered commit history (#3271)
* feat(snapshot): support path-filtered commit history

* refactor(snapshot): reuse SDK git log implementation

* fix(snapshot): harden path-filtered log resource limits

* chore: remove stale SDK lock entry

---------

Co-authored-by: zhanghaoyu.la <zhanghaoyu.la@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
v0.4.10
2026-07-16 19:53:40 +08:00
Yuanqing ZHAOandYuanqing Zhao fa19ac0a75 perf(vectordb): coalesce auto cuVS rebuilds during bulk ingest (#3277)
* perf(vectordb): coalesce auto cuVS rebuilds during bulk ingest

Add an opt-in bulk-ingest maintenance scope that coalesces Auto cuVS background rebuilds across multiple write batches.

- defer derived GPU maintenance until the outermost bulk scope exits while keeping native writes and persistence visible per call
- harden the background worker against debounce, generation, shutdown, and stale-candidate races
- preserve suspension across index replacement and retire replaced workers
- wait for the final Auto GPU snapshot before vectordb_perf records search QPS
- document that the scope is non-transactional and only schedules readiness on exit

Auto cuVS and background rebuild remain disabled by default. Native CPU and remote backends use no-op hooks, so their existing behavior and dtype are unchanged.

* fix(vectordb): reject stale index replacements

* fix(vectordb): harden bulk rebuild lifecycle

---------

Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com>
2026-07-16 18:59:16 +08:00
Qin Haojie 4723f055bd fix(memory): restore event content rendering (#3300)
Restore the ExtractContext helpers required by the events template so extracted event memories retain their rendered body.
2026-07-16 18:04:44 +08:00
MaojiaShengandqin-ctx 3c70f8d370 feat(parse): add large image processing for image parser (#3265)
* feat(parse): add large image processing for image parser

- Add large_image_processor.py: detect large images (>10MB or >4096px),
  create low-res previews, split into grid tiles, and generate grid
  overlay images with tile labels
- Refactor ImageParser.parse() to integrate large image processing pipeline
- Enable SVG-to-PNG conversion in utils.py (cairosvg/wand)
- Rename ImageConfig.max_dimension to preview_max_dimension and add new
  config fields: max_file_size_mb, max_tile_size_mb, max_tile_dimension_px,
  tile_overlap_px, large_image_threshold_dimension
- Update ov.conf.example with new image config options

* fix(parse): correct tile dimension comment from 1024px to 2048px

* fix(parse): fix tile label path in grid overlay to include tiles/ directory

* fix(parse): register missing image extensions for ImageParser

TIFF, ICO, DIB, ICNS, SGI, JP2 were not in IMAGE_EXTENSIONS, causing
them to fallback to TextParser. All are supported by PIL.

* fix(parse): preserve PNG format for tiles instead of always converting to JPEG

* fix(parse): address review feedback for large image processing

- Wire config.image to ImageParser in ParserRegistry (was missing)
- Remove unnecessary preview creation for small images (broke LA mode PNG)
- Enforce max_tile_size_mb on tiles with quality reduction and resize fallback
- Remove 64-tile hard cap that conflicted with max_tile_dimension_px
- Add comment explaining why original file is not saved for large images

* refactor(parse): remove max_tile_size_mb as it is a soft suggestion

max_tile_size_mb was a soft constraint that was not enforced
consistently. Remove it from config, constants, and all enforcement
logic. Tile dimension (max_tile_dimension_px) remains the sole constraint.

* fix(parse): use CJK-capable font for grid overlay labels

The old font loading only tried macOS-specific paths and fell back to
PIL's default bitmap font, which cannot render CJK characters in
filenames. Add a cross-platform CJK font lookup that covers Linux
(Noto/Droid/WQY/DejaVu), macOS (PingFang), and Windows (MSYH/SimSun).

* fix(parse): convert non-VLM-supported image formats to PNG on save

Image formats like TIFF, ICO, DIB, ICNS, SGI, JP2 are not recognized
by VLM backends (OpenAI/LiteLLM/VolcEngine only support PNG/JPEG/GIF/
WebP/BMP) or by embedding_utils for image vectorization. When a file
with one of these extensions is parsed, convert it to PNG and use a
.png extension so that downstream pipelines see consistent data.

SVG files (already PNG-converted via cairosvg) also get the .png
extension for the same reason.

* fix(parse): import io for SVG conversion

---------

Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-07-16 17:37:05 +08:00
19ca274a24 fix(retrieve): bound reranker input size (#3289)
* fix(retrieve): bound reranker input size

* fix(retrieve): make rerank input limit opt-in

---------

Co-authored-by: huangruiteng <huangruiteng@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-07-16 17:19:38 +08:00