Commit Graph

7930 Commits

Author SHA1 Message Date
Lynn
11b2dfcfdd Fix: handle llm_setting switch (#17745) 2026-08-04 10:02:14 +08:00
maoyifeng
594a4640e3 GO CLI: add enterprise empty Dao files (#17750)
GO CLI: add enterprise empty Dao files
2026-08-03 23:01:01 +08:00
Jack
3fd4ead26b fix(chunker): JSON path merges globally and keeps over-budget items whole (#17739)
Fixes two TokenChunker **json-path** over-segmentation bugs that diverge
from Python's `rag/app` chunkers (tracked as `go_bug` known-diffs).
2026-08-03 22:17:59 +08:00
Jack
39ba8ae0bb test(chunker): self-contained guard for splitOversizedUnit running-sum flush (#17740)
## Summary

Adds a self-contained regression guard for `splitOversizedUnitWith`
after PR #17729
aligned it with Python's `rag/nlp._split_oversized_unit` running-sum
flush.

#17729 shipped a `slack=1` relaxation in `token_strict_cap_test.go` (the
oversized
unit is now sub-split with the same running-sum flush Python uses, which
can leave a
piece one token over the nominal budget due to cl100k non-additivity).
This PR adds
the missing positive proof that the sub-split boundaries are correct, so
the relaxed
assertion is no longer unguarded.

## Changes

- `split_oversized_guard_test.go` (new, self-contained — no harness
loader, no
  `testdata`; the Python oracle is inlined):
- `TestSplitOversizedUnitRunningSumMatchesPython`: asserts the exact
piece
boundaries (live tokenizer) match Python's `_split_oversized_unit`,
compensating
    the `slack=1` relaxation from #17729.
- `TestSplitOversizedUnitDeadTokenizerCollapses`: asserts a
zero-counting tokenizer
collapses the B1 paragraph into exactly one chunk, catching a silently
dead encoder
    that a non-empty-result check would miss.

## Notes

- Test function names are deliberately distinct from PR #17735's
`TestSplitOversizedUnitMatchesPython`, so the two PRs verify
independently and do not
  conflict at merge time.
- PR #17735 (golden parity harness) is intentionally left unchanged per
the split plan.

## Test plan

`bash build.sh --test ./internal/ingestion/component/chunker/` — green,
including both
new tests.

Co-authored-by: CodeBuddy <noreply@cnb.cool>
2026-08-03 22:15:41 +08:00
Jin Hai
86021932ae Go: fix warnings (#17738)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-03 21:30:01 +08:00
jay77721
d357eea8ef feat(go-models): migrate batch 5 model drivers to unified handlers (#17700)
## Summary

Relate to #17284. Completes the batch 5 migration of 7 OpenAI-compatible
drivers (`vllm`, `volcengine`, `xai`, `xiaomi`, `xinference`, `xunfei`,
`zhipu-ai`) onto the unified request/response helpers
(`doRequest`/`doStreamRequest` +
`HandleNonStreamingResponse`/`HandleStreamingResponse` +
`ParserConfig`), established by `deepseek` in #17634.

This branch is rebased on the current `pr/migrate-models-batch5` and
fixes the issues in the previous state of the PR.

Co-authored-by: Haruko386 <tryeverypossible@163.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 20:19:22 +08:00
buua436
1d141aff18 fix: optimize dataflow indexing and logs (#17737) 2026-08-03 19:15:44 +08:00
Jack
e997fd655a fix(tokenizer): load cl100k BPE table from disk instead of failing silently offline (#17712)
## Summary

RAGFlow's Go tokenizer silently returned **0 tokens for every string**
whenever the `cl100k_base` BPE table could not be loaded — which is the
normal case for an offline/air-gapped Go server. This PR makes the
loader resolve the table from disk (where RAGFlow actually ships it) and
fail loudly when it is genuinely missing.

## Root cause

`tiktoken-go`'s stock loader downloads the encoding table over HTTP and
caches it under `TIKTOKEN_CACHE_DIR`. That does not work for RAGFlow:

- `TIKTOKEN_CACHE_DIR` is exported **only inside the Python process**
(`common/token_utils.py`). `docker/entrypoint.sh` launches the Go binary
(`bin/ragflow_server`) from a shell, so the Go process never inherits
the variable.
- The Dockerfile *does* ship the table (under its sha1 name in the
working directory), but nothing told the Go side to look there.
- Reaching `openaipublic.blob.core.windows.net` at runtime is not an
option for air-gapped installs, and is unreliable where that host is
blocked.

The failure was **silent**: `NumTokensFromString` returns `0` when the
encoder fails to build, and a `sync.Once` memoizes that error for the
process lifetime. Every token count became `0`, so chunk merging never
crossed its token budget and an entire document collapsed into a single
chunk. Python has no such failure mode because its encoder is built at
import time (a missing table aborts startup instead of degrading).

## Fix

Register a local-only `BpeLoader` via `tiktoken.SetBpeLoader`
(`internal/tokenizer/bpe_loader.go`) that resolves the table from disk
**only**, in priority order:

1. `TIKTOKEN_CACHE_DIR` / `DATA_GYM_CACHE_DIR` (honored so operators who
already configured one keep working).
2. The working directory, the executable's directory, and all of their
ancestors — matching the Dockerfile layout (table under its sha1 name in
the install root).
3. A `ragflow_deps/<basename>` checkout produced by
`ragflow_deps/download_deps.py`.

It **never performs network I/O**. When nothing is found it returns an
error listing every path it tried (pointing at `download_deps.py` or
`TIKTOKEN_CACHE_DIR`), so a genuinely missing table fails loudly instead
of degrading to zero.

## Test plan

- `internal/tokenizer/bpe_loader_test.go` (unit tier, runs under `bash
build.sh --test ./internal/tokenizer/...`):
- Loader reads from `TIKTOKEN_CACHE_DIR`, `DATA_GYM_CACHE_DIR`, the
sha1-named file in the working dir, and the bundled `ragflow_deps/`
name.
  - Explicit cache dir wins over the bundled vocab.
  - A malformed table is reported as an error rather than skipped.
- A genuinely missing table reports the candidates it tried (no network
attempt).
- `NumTokensFromString` matches Python-derived anchors (`""`→0,
`"hello"`→1, `"hello world"`→2, `"hello, world!"`→4, `"世界"`→3, `"Hello
世界 🌍"`→8, `"RAGFlow"`→3).

## Notes

- `.github/workflows/tests.yml` currently excludes `internal/tokenizer`
from `go test`, so these tests do not run in CI. The tokenizer fix is
exercised in CI indirectly via the chunker package once a
token-count-sensitive parity case lands (tracked separately). Consider
including `internal/tokenizer` in CI as a follow-up.
- Supported deployments already ship the table (`download_deps.py` →
`ragflow_deps/cl100k_base.tiktoken`; Dockerfile → `<sha1>` in cwd), so
no `ENV` change is required for the fix to take effect. Setting `ENV
TIKTOKEN_CACHE_DIR` in the Dockerfile remains a cheap
belt-and-suspenders hardening that can be done separately.

🤖 Generated with [CodeBuddy Code](https://cnb.cool/codebuddy)

---------

Co-authored-by: CodeBuddy <noreply@codebuddy.ai>
Co-authored-by: CodeBuddy Code <noreply@cnb.cool>
Co-authored-by: CodeBuddy <noreply@tencent.com>
2026-08-03 19:03:08 +08:00
Haruko386
a75e733b39 fix: qwen can not get model list (#17709)
### Summary

As title
2026-08-03 18:08:16 +08:00
Haruko386
858c48a88e fix: jina’s incorrect return value: modelname (#17716)
### Summary

As title:
2026-08-03 18:07:55 +08:00
Haruko386
9adcd59586 fix(provider): support editing fetched model types before save (#17728)
### Summary

As title

now can edit
2026-08-03 18:07:41 +08:00
euvre
f9fd764c4e Fix overlapping CJK text lines in docx file preview (#17693) 2026-08-03 17:56:06 +08:00
euvre
8b83c52966 fix(web): MCP edit dialog cancel/save buttons not closing (#17713) 2026-08-03 17:53:25 +08:00
balibabu
f116001b1d Fix: The agent version page exported an incorrect DSL format. (#17736) 2026-08-03 17:52:53 +08:00
chanx
fe9167ac18 fix: fix the filter error in dataset page (#17734) 2026-08-03 17:49:31 +08:00
jay77721
31264bafb2 feat(go-models): migrate batch 4 model drivers to unified handlers (#17699)
## Summary

Relate to #17284

Migrate 10 OpenAI-compatible drivers (`orcarouter`, `perplexity`,
`ppio`, `qiniu`, `ragcon`, `stepfun`, `togetherai`, `tokenhub`,
`tokenpony`, `upstage`) to use the unified response handlers
(`HandleNonStreamingResponse` / `HandleStreamingResponse`), following
the same pattern established by `deepseek` in #17634.

- Cut ~150 lines per driver (1436 lines removed, 62 added across 10
files).
- No functional changes — pure deduplication of HTTP plumbing.
- Each driver now routes through `baseModel.doRequest()` and
`HandleNonStreamingResponse()`.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 17:48:45 +08:00
Jack
3e86227a14 fix(chunker): align splitOversizedUnitWith with Python running-sum flush (#17729)
## Summary

Align Go `splitOversizedUnitWith` with Python
`rag/nlp._split_oversized_unit` so the whitespace-atom sub-split
produces byte-identical chunk boundaries.

### Root cause of the divergence
cl100k token counting is **not additive across whitespace joins**
(`token(a)+token(b) != token(a+b)`). Go previously used the exact
joined-string fit check `countFn(current+atom) > budget`, while Python
accumulates a running sum `current_tokens + a_tokens > budget`. The two
formulas disagree by one atom at the boundary, so Go and Python emitted
the same chunk *count* but shifted *text*.

### Changes
- `splitOversizedUnitWith` (`token.go`): replace the exact joined-string
fit check with the running-sum check (mirroring Python's
`current_tokens` accumulator), and after a flush keep the overflow
whitespace atom (`current += atom`) instead of dropping it.
- `token_strict_cap_test.go`: relax
`TestMergeByTokenSizeFromJSON_OversizedUnitIsSubSplit` to allow the same
cl100k non-additive +1 overshoot Python exhibits (the invariant — an
oversized unit is sub-split, not collapsed — is preserved).

### Test plan
`bash build.sh --test ./internal/ingestion/component/chunker/...` —
green.

## Note
Test infrastructure for this change (golden parity harness,
`split_oversized_test.go`, `testdata/parity/**`, `known_diffs.json`,
`capture_golden.py`/`live_chunk.py`, and the `go-cmp` dependency
promotion) is split into a separate, stacked PR #17735 so this PR stays
minimal (production code only).

This PR is **independent of #17712** (the offline BPE loader). It is
based on `upstream/main` and contains only this change; no BPE-loader
code is included.

Co-authored-by: CodeBuddy <noreply@cnb.cool>
2026-08-03 17:48:39 +08:00
buua436
9ccb23e661 fix: align pipeline delimiter chunking (#17723) 2026-08-03 17:47:08 +08:00
buua436
3e7cfbe052 refa: simplify RAPTOR tree clustering and configuration (#17614) 2026-08-03 17:46:50 +08:00
Jin Hai
e290a0d476 Go: fix resource leak (#17733)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-03 17:39:47 +08:00
Zhichang Yu
c69a2d4798 [go] Merged memory extractor with ingestion task handler (#17730)
Routes async memory extraction through the shared ingestion NATS
pipeline via task_type=memory, removing the dedicated Redis consumer.
Memory failures ack terminally, transient errors nack for redelivery.
2026-08-03 17:08:14 +08:00
buua436
8ac047d11a fix: synchronize chat model configuration (#17717) dev-20260803 2026-08-03 16:43:53 +08:00
balibabu
a12dee5524 Fix: On the second page of agent version, switch the page size to empty. (#17732) 2026-08-03 16:41:59 +08:00
balibabu
10db22c756 Fix: Every variable in the chat settings is required. (#17727) 2026-08-03 16:41:47 +08:00
balibabu
8494f242d7 Fix: In the model settings, setting the degree of freedom to 0 and then saving caused the DeepSeek model call to fail. (#17725) 2026-08-03 16:41:33 +08:00
Kevin Hu
3b4a96d421 Refactor: refine wiki plan procedure. (#17579)
### Summary

Refine wiki plan procedure.

---------

Co-authored-by: Yingfeng Zhang <yingfeng.zhang@gmail.com>
Co-authored-by: buua436 <sz_buua@foxmail.com>
2026-08-03 16:03:17 +08:00
Lynn
51af9e2eae Fix: set chunk_num before set_progress, avoid race condition (#17724) 2026-08-03 15:52:23 +08:00
euvre
59b682e6a4 Fix: false success toast when deleting non-existent Langfuse config (#17719) 2026-08-03 15:51:32 +08:00
Wang Qi
bb1879ba35 REDIS: allkeys-lru -> volatile-lru to avoid got evict if lack of memory (#17720)
Follow on PR: #17707
2026-08-03 15:44:59 +08:00
Jack
1f8e9af644 fix(chunker): honor configured delimiters as soft boundaries in TokenChunker (#17721)
## Summary

`TokenChunker._invoke` discarded the user's configured `delimiters`
whenever no backtick-wrapped delimiter was present: it passed a
hardcoded `""` to `naive_merge`, so the configured delimiters (including
the default `["\n"]`) were never forwarded. `naive_merge` then ignored
the newline sentence boundary and cut chunks **mid-sentence** once the
token budget was exceeded.

## Root cause

`token_chunker.py:326` called `naive_merge(payload, chunk_token_size,
"", overlapped_percent)`. `_compile_delimiter_pattern` intentionally
returns `""` for bare (non-backtick) delimiters — that return value is a
*path selector* (empty → token-budget merge; non-empty → hard
`_split_text_by_pattern` split). The bug was not in that selector but in
the `else` branch, which threw away `self._param.delimiters` instead of
forwarding it.

## Fix

Forward the configured delimiters as a soft boundary:

```python
else naive_merge(
    payload,
    self._param.chunk_token_size,
    "".join(self._param.delimiters),
    overlapped_percent,
)
```

`naive_merge` already parses the string via the canonical
`parse_delimiter_field`, so bare and backtick-wrapped delimiters are
honored as soft boundaries while the token budget is still respected.
The path-selection role of `_compile_delimiter_pattern` is untouched:
backtick-wrapped delimiters still select the hard
`_split_text_by_pattern` path; bare delimiters still take the
token-budget merge path. No regression for any previously-working
(wrapped-delimiter) configuration.

## Test

Adds `rag/flow/tests/test_token_chunker_delimiter.py`:
- `test_token_chunker_token_size_mode_does_not_split_sentences` — fails
on the old code (3 sentences cut mid-stream), passes after the fix.
- `test_naive_merge_empty_delimiter_ignores_newline_break` — root-cause
companion asserting `naive_merge("")` cuts while `naive_merge("\n")`
preserves boundaries.

Both tests skip when the tokenizer is unavailable (dead-tokenizer
guard).

## Note

This branch contains only this one-line fix on top of `main`; it is
intentionally independent of the unrelated tokenizer/offline-BPE work.

Co-authored-by: CodeBuddy <noreply@codebuddy.ai>
2026-08-03 15:31:40 +08:00
jay77721
1478aa4ced feat(go-models): migrate batch 3 model drivers to unified handlers (#17698)
## Summary

Relate to #17284

Migrate 10 OpenAI-compatible drivers (`minimax`, `mistral`,
`modelscope`, `moonshot`, `n1n`, `novita`, `ollama`, `openai`,
`openai_api_compatible`, `openrouter`) to use the unified response
handlers (`HandleNonStreamingResponse` / `HandleStreamingResponse`),
following the same pattern established by `deepseek` in #17634.

- Cut ~150 lines per driver (1692 lines removed, 172 added across 10
files).
- `openai_api_compatible` gains `ChatWithMessages` +
`ChatStreamlyWithSender` required by the unified handler infrastructure.
- `openai` driver preserves `reasoning_content` extraction for o-series
models.
- All drivers: pure deduplication of HTTP plumbing.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 15:08:55 +08:00
Jin Hai
bddc941814 Go: add context to storage (#17690)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-03 15:08:21 +08:00
maoyifeng
2dbdaf951d CI: change gitee token to env (#17718)
1. change gitee token to env
2. restore   pull_request_target to pull_request
2026-08-03 14:30:01 +08:00
maoyifeng
3874ef8765 Dockerfile base part separate to base image (#17701)
Unify open-source and closed-source Dockerfile expect nginx
1. per install tools to base image
2. fix copy nginx config
3. fix copy entrypoint*.sh
4. fix go ci error
5. add comment
2026-08-03 14:29:48 +08:00
euvre
ef9feef0c4 fix(go-models): add StepFun Step Plan base URL (#17704) 2026-08-03 13:55:59 +08:00
euvre
04918f88bf Go: support ids filter in list datasets API (#17705) 2026-08-03 13:54:44 +08:00
jay77721
75586c0be1 feat(go-models): migrate batch 2 model drivers to unified handlers (#17697)
## Summary

Relate to #17284

Migrate 10 OpenAI-compatible drivers (`gitee`, `gpustack`, `greenpt`,
`huaweicloud`, `huggingface`, `hunyuan`, `jiekouai`, `jina`, `lmstudio`,
`localai`) to use the unified response handlers
(`HandleNonStreamingResponse` / `HandleStreamingResponse`), following
the same pattern established by `deepseek` in #17634.

- Cut ~150 lines per driver (1398 lines removed, 155 added across 10
files).
- `greenpt` gains `ChatWithMessages` + `ChatStreamlyWithSender` required
by the unified handler infrastructure.
- All other drivers: pure deduplication of HTTP plumbing.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthoric.com>
2026-08-03 13:54:35 +08:00
Wang Qi
ab703b6ded Fix: Cache the SECRET_KEY, if it is not set, RAGFlow will auto gen one, but if Redis evict keys due to lack of memory, it will cause re-generate secret key, that cause all requests 401 (#17707) 2026-08-03 13:48:35 +08:00
balibabu
62457075d4 Fix: Accidentally deleted the previously selected chat. (#17710) 2026-08-03 13:45:35 +08:00
Wang Qi
a1a79ab98c Fix: add doc_type_kwd back (#17658) 2026-08-03 13:21:22 +08:00
balibabu
cb28bd4e7e Fix: Upload an image without filling in any text and press Enter; the image should not disappear. (#17632) 2026-08-03 13:09:13 +08:00
jay77721
194f75f401 feat(go-models): migrate batch 1 model drivers to unified handlers (#17696)
## Summary

Relate to #17284

Migrate 10 OpenAI-compatible drivers (`302ai`, `aliyun`, `astraflow`,
`avian`, `azure_openai`, `baichuan`, `baidu`, `cometapi`, `deepinfra`,
`futurmix`) to use the unified response handlers
(`HandleNonStreamingResponse` / `HandleStreamingResponse`), following
the same pattern established by `deepseek` in #17634.

- Cut ~150 lines per driver (1507 lines removed, 144 added across 10
files).
- No functional changes — pure deduplication of HTTP plumbing.
- Each driver now routes through `baseModel.doRequest()` and
`HandleNonStreamingResponse()`.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-03 12:13:43 +08:00
balibabu
5aa60cbb67 Fix: Deleting temporary chat resulted in an error. (#17694) 2026-08-03 11:49:12 +08:00
euvre
8353fc7855 fix: XunFei Spark provider API key verification and model listing (#17652) 2026-08-03 11:25:25 +08:00
Zhichang Yu
4e78f1f440 Port Python agentic search to Go (nav service, harness, tools) (#17702)
Port Python rag/advanced_rag agentic search to Go: ES-backed dataset-nav
service, agentic-search harness, and agent tools.

Includes agentic-search port plan and self-review docs.
2026-08-03 11:16:16 +08:00
Lynn
2e0dda59fc Fix: handle html tags in empty_response (#17657) 2026-08-03 11:14:18 +08:00
jay77721
288be805f1 feat(go-models): migrate nvidia/siliconflow/groq/longcat to unified h… (#17643)
## Summary

Relate to #17284

Migrate four OpenAI-compatible drivers (`nvidia`, `siliconflow`, `groq`,
`longcat`) to use the unified response handlers
(`HandleNonStreamingResponse` / `HandleStreamingResponse`), following
the same pattern established by `deepseek` in #17634.

- Cut ~100 lines per driver (541 lines removed, 19 added across 4
files).
- `nvidia` now extracts token usage (previously had none).
- All four drivers produce the unified `StreamUsage` log.
2026-08-03 10:05:25 +08:00
Jin Hai
266837eb33 Go: add context to redis client (#17689)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-02 22:50:54 +08:00
Jin Hai
b2521ebf51 Go: refactor log and config (#17684)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-02 20:55:19 +08:00
S
d4ceeee4ed refactor(nlp): collapse 6 delimiter-parser implementations into one canonical helper (#17383) (#17387)
## Summary

Six sites used to read the same `parser_config.delimiter` field with
divergent grammars:

- `rag.nlp.get_delimiters` (PDF/DOCX/HTML/EPUB/JSON/CSV/XLSX/email/book)
- `rag.nlp.naive_merge` (custom-delimiter branch)
- `rag.nlp.naive_merge_with_images`
- `rag.nlp._build_cks`
- `deepdoc.parser.txt_parser.parser_txt` (.txt, code)
-
`deepdoc.parser.markdown_parser.MarkdownElementExtractor.get_delimiters`

The six implementations disagreed on bare-vs-wrapped chars, dedupe, sort
order, CRLF normalization, and `re.I` (#17384). The shipped default ``
`\n!?;。;!?` `` was a no-op for `.md` because the markdown path only
matched backtick-wrapped tokens.

## Changes

- **new:** `rag/nlp/delim.py` with `parse_delimiter_field` and
`compile_delimiter_pattern`. Single source of truth. CRLF normalization
at the top; longest-first stable sort; insertion-ordered dedupe; no
`re.I`.
- **refactor:** all six call sites delegate to the helper.
  - `rag/nlp/__init__.py::get_delimiters` becomes a thin shim.
- `deepdoc/parser/txt_parser.py::parser_txt` drops the
`[encode/decode/unicode_escape]` round-trip.
- `deepdoc/parser/markdown_parser.py::get_delimiters` honors bare chars
(fixes [1]).
- **tests:** `test/unit_test/rag/test_delim.py` (85 tests) — helper,
acceptance table, frontend parity, static guard against re-inlining.
- **tests:** `test/unit_test/rag/test_delimiter_case_sensitive.py` (from
#17386) updated to retarget the static check at the new helper +
AST-based broader scan.

## Acceptance criteria

- All six sites produce the same regex pattern for the same input.
- Shipped default keeps working for `.txt` / `.pdf` / `.docx`.
- Shipped default for `.md` now splits (was a silent no-op).
- Tooltip example `` `\n##;` `` produces three effective delimiters
regardless of file type.
- Bare whitespace inputs split on every occurrence.
- Backtick-wrapped whitespace splits only on the exact N-char sequence.
- CRLF-line-ending documents split identically to LF-line-ending
documents.
- 123 tests pass (85 new + 38 existing).

## Rebase protocol

As #17385 and #17386 evolve, this branch will be rebased on top. The
only overlap between this PR's diff and the other two is
`test_delimiter_case_sensitive.py`, where #17383 modifies the static
check to point at the new helper location.

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
2026-08-02 17:07:14 +08:00