## Summary
Fixes embedding inputs being emptied and documents chunker
heading-detection parity.
- `component/tokenizer.go`: `truncateForEmbedding` now mirrors Python
`common/token_utils.py:183-185` `truncate(string, max_len)` (keep the
first `max_len` tokens). For an unconfigured embedder reporting
`maxTokens <= 0`, instead of mirroring Python's `truncate` (which
returns `""` for `max_len <= 0` and would make the embeddings API reject
the batch with "inputs cannot be empty"), Go **clamps the limit to a
safe default** (`defaultEmbeddingTokenLimit = 8192`) so truncation stays
active and never produces empty inputs. The previous code returned `""`
for `maxTokens <= 10`, which emptied non-empty chunks into the batch and
triggered the API error.
- A **10-token safety margin** is reserved (mirroring Python's embedding
path `rag/svr/task_executor.py` which uses `mdl.max_length - 10`) so Go
does not over-send tokens to hard-capped embedding APIs; it is only
applied when the limit `> 10` so small limits remain non-empty.
- The clamp is applied **centrally inside `truncateForEmbedding`**,
covering both Builtin and generic callers — no separate
`model_service.go` change is required.
- `component/chunker/title.go`: comment-only — documents the
already-ported PDF-outline detection (omission 1.5 / Gap C) and the
hardcoded `BULLET_PATTERN` fallback (omission 1.7 / Gap C), porting
`common.py:_outline_similarity` and `rag/nlp` `BULLET_PATTERN`.
- `tokenizer_unit_test.go`: update truncation expectations to the new
positive-keeps-tokens / non-positive-clamps-to-default behaviour.
## Test plan
- `tokenizer_unit_test.go` updated for the new truncation behaviour
(`TestTruncateForEmbedding_SmallMaxTokens`,
`TestTruncateForEmbedding_UnconfiguredClampsToDefault`).
- `./build.sh --test ./internal/ingestion/component/` passes.
🤖 Generated with [CodeBuddy Code](https://cnb.cool/codebuddy)
Ports doc-level auto-metadata extraction to Go and adds the
knowledge_compiler component with scheduler/routing. Fixes Extractor
metadata injection type assertion and enable_metadata default-on.
## Summary
Remediates CVE-2026-0994 (HIGH) in `protobuf` by adding
`protobuf>=5.29.6` to `constraint-dependencies` in `pyproject.toml`.
| CVE | Severity | Package | Installed | Fixed in |
|---|---|---|---|---|
| CVE-2026-0994 | HIGH | protobuf | 5.29.5 | 5.29.6 |
`protobuf` is a transitive dependency pulled in by `google-api-core`,
`googleapis-common-protos`, `grpcio-status`, and `opentelemetry-proto`.
It was stuck at 5.29.5 because the lockfile hadn't been re-resolved.
## Summary
- StepFun serves domestic (China) and international markets from
different domains.
- Add a `china` region URL (`api.stepfun.com`) alongside the existing
`default` (`api.stepfun.ai`) so tenants in China can route correctly.
## Change
- `conf/models/stepfun.json`: add `"china":
"https://api.stepfun.com/v1"` to the `url` map.
## Why
- Chinese AI/LLM providers commonly maintain separate URLs for domestic
vs. international markets. Keeping both options available matches the
existing pattern used by other providers (e.g. GiteeAI).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
## Summary
- Add provider-local Chat, Embedding, and Rerank response structures
with usage mapping.
- Align streaming usage and tool-call state handling across Gitee,
OpenRouter, Jiekou.AI, and Hunyuan.
- Preserve Jina's non-streaming behavior and explicit unsupported
streaming response, while fixing Jiekou.AI thinking=false handling.
## Summary
When `STORAGE_IMPL=AWS_S3`, the Admin Service status page keeps showing
MinIO. Three things conspire:
1. `admin/server/config.py::load_configurations` only knows the
`minio` and `minio_0` config keys. An `s3` block lands on the
`case _:` branch and logs `Unknown configuration key: s3`
(issue #17294).
2. `admin/server/services.py::ServiceMgr.get_all_services` filters
retrieval services by `DOC_ENGINE` but has no equivalent filter
for `file_store` services by `STORAGE_IMPL`. A stale MinIO block
is returned regardless of the active backend.
3. The wired health check is hardcoded to `check_minio_alive`, which
calls `settings.MINIO['host']`. With `STORAGE_IMPL=AWS_S3` that
block is uninitialized, so the check always times out.
Fixes#17294
## Summary
Remediates three HIGH severity CVEs in `pyasn1` by bumping the existing
`constraint-dependencies` entry from `>=0.6.3` to `>=0.6.4` in
`pyproject.toml`.
| CVE | Severity | Package | Installed | Fixed in |
|---|---|---|---|---|
| CVE-2026-59884 | HIGH | pyasn1 | 0.6.3 | 0.6.4 |
| CVE-2026-59885 | HIGH | pyasn1 | 0.6.3 | 0.6.4 |
| CVE-2026-59886 | HIGH | pyasn1 | 0.6.3 | 0.6.4 |
`pyasn1` is a transitive dependency (pulled in via `google-auth` / `rsa`
/ `pyasn1-modules`). A previous constraint (`>=0.6.3`) was added for
CVE-2026-30922 but two additional vulnerabilities were disclosed that
require 0.6.4.
### Summary
The **aimlapi.com** provider added in #17311 does not identify itself on
any of its outgoing requests, so its traffic cannot be attributed to the
integration. This PR adds the two headers AIMLAPI expects —
`X-AIMLAPI-Source` and `X-AIMLAPI-Partner-ID` — to every request the
provider makes.
### Summary
The Go Anthropic driver's `ChatStreamlyWithSender`
(internal/entity/models/anthropic.go) was a stub that always returned
`"no such method"`, so any caller requesting a streamed response from a
Claude model via the Go path failed outright — diverging from the Python
`AnthropicCV` driver, which already supports streaming.
This implements the method by opening the Messages API with
`stream=true` and parsing the SSE response via the shared
`ParseSSEStream` helper, forwarding `text_delta`/`thinking_delta`
content through the `sender` callback and treating `message_stop` as the
terminal event — consistent with the other Go drivers in this package
(e.g. Cohere).
Fixes#17333
---------
Co-authored-by: Abhay Yadav <abhayyadav@Abhays-MacBook-Air.local>
### Summary
Add token usage reporting for the LongCat (Meituan) model provider.
Related
to #17284.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
### Summary
Adds a `tenki` sandbox provider that runs each agent code execution in a
disposable Tenki (https://tenki.cloud) microVM (create → exec → destroy,
no volumes or snapshots).
Registration mirrors PR #15039, configure `api_key` and `project_id` in
Admin > Sandbox Settings.
Both runtimes are covered:
- Python: `agent/sandbox/providers/tenki.py` (structured results +
artifact collection).
- Go: `internal/agent/sandbox/tenki.go`, mirroring the e2b provider and
wired into the provider manager.
`tenki-sandbox` is an optional dependency (it requires `protobuf>=6.31`,
which differs from RAGFlow's pinned gRPC stack), lazily imported with a
clear error when missing; installation is documented in the sandbox
quickstart.
Unit tests cover execution, structured results, artifacts
(symlink/size/extension limits), non-zero exit, timeout, error mapping,
and idempotent destroy.
---------
Co-authored-by: yiming.wang <yiming.wang@luxor.com>
## Summary
This PR hardens the Go ingestion **Extractor** and **LLM retry** paths
and closes several Python->Go parity gaps in the keyword/question/tag
extraction flow.
- **Generic retry utility** (`internal/common/retry.go`):
`RetryWithBackoff` with exponential backoff (default 3 retries, 2s
initial delay, capped at 1m), context-aware sleep, and a `maxRetries<=0`
fast path. Covered by `internal/common/retry_test.go`.
- **LLM retry reuse**: `agent/component/llm_retry.go` now delegates to
`common.RetryWithBackoff` instead of an inline loop (behavior preserved:
ctx cancellation short-circuits the backoff).
- **Extractor LLM calls** (`extractor.go`):
- `call()` now retries transient LLM failures via `RetryWithBackoff`
(retry exhaustion fails the chunk instead of silently skipping).
- Sets `temperature = 0.2`, matching Python `generator.py:230,245`.
- Runs keyword and question extraction **concurrently** per chunk when
both are enabled (`task_executor.py:444-448`), with mutex-guarded map
writes to avoid data races.
- Substitutes `{field_name}` placeholders (including `{chunks}` -> chunk
text) in `prompt`/`system_prompt` before the call, mirroring Python
`string_format` (`extractor.py:102-103`); unmatched placeholders are
left as-is.
- Falls back to the **tenant default chat model** when `llm_id` is empty
(`task_executor.py:573-574`).
- Strips `` **greedily** (`strings.LastIndex`) in
`cleanExtractionResult`.
- **Auto-tagging** (`extractor_tag.go`): drops the `in.llmID != ""`
guards so an empty `llm_id` no longer skips tagging (uses the tenant
default model), and strips `` greedily in `parseTaggerResponse`.
- **Docs**: fixes a misleading `PresentationChunker` docstring that
claimed per-slide `image`/`position` output (the PPTX path emits none —
unlike PDF), and removes a stale `docs/migration_python_go_diff.md`
reference in `media_dispatch.go`.
## Test plan
- `bash build.sh --test ./internal/common/...` — passes (new retry
utility + tests).
- `bash build.sh --test ./internal/ingestion/component/...` — passes
(extractor/chunker/schema).
- `gofmt` and lefthook pre-commit checks pass.
Note: the personal `docs/migration_python_go_diff.md` working notebook
in the tree is intentionally **not** part of this PR.
---------
Co-authored-by: CodeBuddy <noreply@codebuddy.ai>
## Summary
GreenPT is a European AI provider with an OpenAI-compatible API,
optimized infrastructure, and datacenters powered by 100% renewable
energy.
This adds native GreenPT support across RAGFlow’s Go-first provider
system and its Python compatibility layer:
- discovers the current catalog from `GET /v1/models`
- features `glm-5.2` and `kimi-k2.7-code` for chat and coding
- supports `green-embedding` through `/v1/embeddings`
- supports `green-rerank` through `/v1/rerank`
- supports `green-s` and `green-s-pro` speech-to-text through
`/v1/listen`
- adds provider configuration, UI icon, and supported-provider
documentation