Add user attribution to embedding calls — forwards user on OpenAI-compatible providers via current_llm_user(). Excludes LocalAI/Xinference (reject unknown fields). Accepts user_id on ingest/parse/chunk endpoints; redacts from logs. Omitted = unchanged. Go/vision/TTS/ASR out of scope.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes a family of table-retrieval truncation bugs and an action-session
infinite loop in the agentic RAG medium path, all root-caused on a
tabular-reasoning question
1. action_session turn cap enforced (action_session.py)
_route checked _pending_calls before attempts, so a model that kept
emitting tool calls never hit the 4-turn finalize — a single session
could burn the whole pass budget (219 retrievals / 600s observed). Added
_route_after_tool: after a tool batch, the turn budget is checked and
the session converges to finalize instead of looping back to run_action.
2. Table chunks kept whole through retrieval (search.py,
text_processing.py, action_session.py)
Three truncation points hid mid-table answer rows from the session
model:
- grep_search narrowed table chunks to 700 chars
(_GREP_OUT_CHARS_PER_CHUNK)
- _narrow_content only passed HTML tables (<table>/<tr/<td) whole —
markdown pipe tables were sentence-window narrowed
- _admit_evidence truncated the model-facing output to 1200 chars even
though the pool held the full chunk,non-table chunks keep the existing
truncation paths unchanged.
3. SCA sees more evidence (agentic_rag_graph.py, sufficient_context.py)
_SCA_VIEW_CAP 24 → 60; _SCA_CLAIMS_CONTEXT_MAX 9000 → 48000;
table-bearing evidence anchors rendered in full (bounded by the context
budget).
4. Supporting: runtime instrumentation for rounds/slots/retrievals, LLM
token accounting, slot-evidence preservation through SCA, dedup
checkpoints. Timeout/budget constants restored to upstream defaults.
---------
Co-authored-by: Loong <213221738@seu.edu.cn>
Co-authored-by: Hermes Agent <hermes-agent@localhost>
Fix non-streaming chat sending empty tools=[] (rejected by strict providers). Restored mdl.is_tools check and added helper to omit tools field when unbound.
Fix agentic search ignoring chat retrieval settings — now passes knn_top_k, weights, threshold, and top_n. knn_top_k critical for HNSW recall on large indices.
Fix#15962 — replace bare assert isinstance in KnowledgebaseService.dfs_update with safe conditions. Stored None values no longer crash table-parser parses. Matches DocumentService fix from #12815.
Fix reasoning + KB requests using models without tool-calling — now fall back to async_chat RAG path instead of answering from general knowledge.
Co-authored-by: Chen Li <george_lichne@163.com>
Fix POST /api/v1/files 500 error when parent_id doesn't exist. Removed dead delete_folder_by_pf_id call (mismatched args, no tenant scope). Now returns False and documented error response.
### Problem
When a chat assistant has a configured system prompt and the reasoning
level is set to anything other than `NONE`, the request goes through
`rag_agent()` / the agentic RAG harness. That path generated the final
answer with a fixed `FINAL_ANSWER_SYSTEM` prompt and never injected the
user-configured system prompt, so the assistant ignored
role/tone/language instructions (reported in #18833).
### What problem does this PR solve?
Closes#18116.
Fix cross-KB document ID collision (#18116). Older ID derivation excluded kb_id, causing two KBs to fight over one row. Unified derivation to be KB-scoped, with fallback for existing rows. Stranded rows are reclaimed, dataset deletion now cleans up state, and upgraded instances update in place. Tests added.
### Summary
Fixes#18653. Groq rejects every chat request on v0.27.0 with `property
'conversationId' is unsupported`, while the same chat works on Ollama.
Closes#18653
Co-authored-by: Jin Hai <haijin.chn@gmail.com>
### Summary
The fix is one line per helper — assign the `order_by(...)` result back
so the
ordering is actually applied to the query.
Co-authored-by: rsnetworkinginc <rsnetworkinginc@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
### Summary
The fix turns a negative timeout into a finite 60 second wait inside
`MysqlDatabaseLock`, which both servers accept. Callers keep expressing
"block until available", and the equivalent PostgreSQL and GaussDB work
on the same `-1` semantics (#16346, #18506) is untouched. Non-negative
timeouts keep their current behaviour.
---------
Co-authored-by: Krim <git@krim.dev>
### Summary
Multi-type memory prompts were assembled from sets, so their instruction
and output sections could change order across Python processes with
different hash seeds. Because the generated default prompt is persisted
and later compared as a string, a restart could make an untouched
default look custom and prevent it from being regenerated when memory
types change.
## Summary
- allow ISO 8601 normalization callers to provide an explicit fallback
while preserving the existing default behavior
- use the extraction conversation time when `valid_at` is missing or
invalid
- clear an invalid optional `invalid_at` instead of writing an
unparseable value
- include the rejected timestamp value in the error log
This addresses the timestamp write-through portion of #18415. It is
intentionally separate from #18462, which fixes the semantic output
prompt.
Co-authored-by: Loong <184861530+yzl0ng@users.noreply.github.com>
### Summary
- Forward each memory's stored system_prompt and user_prompt to
extract_by_llm.
- Cover both immediate save and queued extraction paths with focused
regression tests.
- Preserve the existing default-prompt fallback when stored prompts are
empty.
Fixes#18413.
### Summary
RAGFlow's "Create empty document" flow accepts names without a file
extension. The `POST /datasets/<dataset_id>/documents?type=empty` route
calls `_upload_empty_document()`, where `Path(name).suffix.lstrip(".")`
returns `""`.
In GaussDB's A/ORA compatibility mode, that empty string is persisted as
SQL `NULL`. Because `document.suffix` was defined as `NOT NULL`, the
insert failed with a constraint violation.