Skip to content

Commit 3077bcd

Browse files
jixiaolongYehongPanZzzxxxxyLifeng-ChenDallas98
authored
feat(ragflow): add RAGFlow search tool (#3378)
* Release/v2.2.1 (#3269) * add_greeting_fields_to_agent-develop * feat(knowledge-base): add preserve_source_file and post-index source cleanup Let knowledge bases opt out of keeping uploaded MinIO copies after indexing while retaining Elasticsearch chunks for retrieval. Default behavior remains preserve_source_file=true for backward compatibility. - Add preserve_source_file column (init.sql + v2.2.0_0601 migration) - Accept preserve_source_file on create/update and northbound/vector APIs - Support document DELETE scope=source_only and source_available in listings - Run cleanup_source Celery task when preserve_source_file is false - UI: create-KB toggle, list tag, knowledge-base preview when copy is missing - Update vector-database SDK docs and backend tests * test(data_process): stub knowledge_db, redis_service, and redis in test_worker Align setup_mocks_for_worker with test_tasks so importing backend.data_process.worker loads package __init__ without real DB/redis deps. * test(data_process): shim cleanup_source for submit_process_forward_chain tests * remove duplicate import * fix: update unit tests for greeting_message and example_questions fields * add init.sql to sonar.properites * ♻️ Improvement: API to MCP conversion service supports configuring headers. (#3194) * ♻️ Improvement: API to MCP conversion service supports configuring headers. [Specification Details] 1. Front-end and back-end modifications * ♻️ Improvement: API to MCP conversion service supports configuring headers. [Specification Details] 1. Modify the frontend, after adding, set the HTTP headers to empty. 2. Modify test cases. * ♻️ Improvement: Enhance processing of ES index names in memory banks. (#3196) [Specification Details] 1. Replace all symbols in the index name that do not meet the rules with "_". 2. Modify test cases. * feat: add active memory tools (StoreMemoryTool, SearchMemoryTool) (#3197) - Implement StoreMemoryTool for explicit memory storage during agent reasoning - Implement SearchMemoryTool for on-demand memory retrieval during conversations - Integrate tools into agent creation flow (create_agent_info.py) - Register tools in nexent_agent.py and tools/__init__.py - Add MEMORY_OPERATION tool sign for proper categorization - Fix memory_core.py cache key to include event loop ID (prevents cross-loop conflicts) - Add comprehensive test coverage for both tools - Add procedural memory verification documentation Tools follow existing patterns: lazy imports, observer integration, error handling, and respect user memory preferences (agent_share_option, disabled_agent_ids). Co-authored-by: Dallas98 <40557804+Dallas98@users.noreply.github.com> * 🐛 Bugfix: skill names and descriptions never load to context (#3205) * 🐛 Bugfix: skill names and descriptions never load to context * 🐛 Bugfix: skill names and descriptions never load to context * 🐛 Bugfix: skill names and descriptions never load to context * 🐛 Bugfix: official skills not copied to target directory * 🐛 Bugfix: official skills not copied to target directory * Feat: add selected count badges to tool/skill pool labels (#3206) Co-authored-by: chase <byzhangxin11@126.com> * 🐛 Bugfix: Fix attribution error when tool calling error (#3208) * ✨ Feat: Add support for Word document generation, preview, and download (#3191) * Feat: Add support for Word document generation, preview, and download * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Restrict uploads to a known safe workspace/output directory * 修改单元测试 * 修复单元测试 * Bugfix: Store uploaded files in Minio for conversation messages to enable file visibility in history --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * ✨Feat:Enhance prompt optimization by integrating openjiuwen and fix related bugs (#3190) * ✨Feat:add prompt optimization * 🐛Bugfix: dockerbuild failed when running pipefail in python3_11 * 🔨Optimize: Optimize prompt optimization display page and interaction methods * 🐛Bugfix: fix dependencies replication * 🎨:Optimize frontend prompts and loading interface * 🔧 Refactor: Update imports and remove redundant ENABLE_JIUWEN_SDK import in prompt_service.py * 🔧 Refactor: Correct import path for NexentCapabilityError and enhance test coverage for prompt optimization service * 🔧 Refactor: Update import paths for exception handling and improve logging formatting in prompt_service.py * 🔧 Refactor: Simplify lazy imports in jiuwen_sdk_adapter.py and update import paths in prompt_service.py * 🔧 Refactor: Enhance Jiuwen SDK adapter handling and improve test stubs in prompt_service.py and related test files * 🧪test:Pydantic model for PromptTemplateRequest in test_prompt_template_app.py * 🔧 Refactor: Remove unnecessary dependency exclusions from pyproject.toml * 🔧 Update: Upgrade huggingface_hub dependency version in pyproject.toml * 🔧 Update: Exclude unnecessary transitive dependencies and adjust huggingface_hub version in pyproject.toml * 🔧 Test: Add mock modules for unstructured inference and set up package paths in test files * 🔧 Test: Enhance test setup by adding optional SDK mocks and cleaning up module imports in data processing tests * 🔧 Test: Consolidate mock module setup for unstructured inference across multiple test files * 🔧 Test: Remove unused optional SDK mocks from test configuration * 🔧 Refactor: Clean up imports and enhance dynamic loading of fastmcp components in Docker client * 📦update:sdk dependence update * Add CAS SSO integration and improve logout handling (#3072) * feat: add CAS SSO integration * Skip CAS logout when CAS_LOGOUT_URL is unset * 取消转义 * Improve CAS logout handling and confirm user logout * Disable account deletion for CAS users * Add CAS session init SQL and k8s config * clean code * Remove agent guardrails design doc from tracking * 补充文档 --------- Co-authored-by: hhhhsc <name> * 🐛Bugfix: Remove unnecessary dependency exclusions and upgrade huggingface_hub version in pyproject.toml (#3211) * refactor: move current time from system prompt to user message for prompt cache stability (#3203) Remove {{time}} from all 4 prompt YAML templates (manager/managed × en/zh) and strip time_str from the context_utils pipeline (_format_app_context, build_skeleton_header_component, build_context_components, build_app_context_string). Also remove time from create_agent_info render kwargs and build_context_components call. In CoreAgent.run, prepend [Current time: ...] to self.task so the timestamp travels with the user message instead of being baked into the system prompt. This makes the rendered system prompt fully deterministic per (agent_id, tenant_id, version_no, language) — enabling prompt/KV cache hits across requests for the same agent config. Sync test_context_utils.py: drop time_str= from 3 test cases. Remove unused datetime imports from context_utils.py and create_agent_info.py. * 🐛 Bugfix: Fixed the issue of being unable to add MCP services via containerization. (#3213) [Specification Details] 1. Modify the DEFAULT_NETWORK_NAME when starting the MCP service in the container to match the name in docker-compose. 2. Modify the parameters passed to the add_mcp_service method; custom_headers defaults to None. * 🐛 Bugfix: Fixed the issue where uploaded text files could not be parsed during a session. (#3219) * 🐛 Bugfix: Fixed the issue where uploaded text files could not be parsed during a session. [Specification Details] 1. The return parameter of the file_process method has changed and needs to be unpacked. * 🐛 Bugfix: Fixed the issue where uploaded text files could not be parsed during a session. [Specification Details] 1. Modify test case. * 🐛 Bugfix: Fixed an issue where the MCP service could not be added correctly after updating the FastMCP version. (#3222) [Specification Details] 1. Add `kwargs` to the `create_httpx_client` function to accept all additional parameters. * 🐛 Bugfix: Fix incomplete display of tenant resources page after window resize (#3215) * Move non-shadcn ui component to other folder * Bugfix: Fix incomplete display of tenant resources page after window resize * Bugfix: Fix incomplete display of tenant resources page after window resize * Add agent marketplace repository and version pinning for sub-agents (#3239) * feat: add agent marketplace repository and pin sub-agent versions at publish Introduce ag_agent_repository_t with list/status/publish/import APIs for frozen agent snapshots. Pin selected_agent_version_no on agent relations when publishing so sub-agents resolve to a fixed version at runtime. Extend agent export/import to bundle skills in ZIP payloads and add embedding model fallback when no model name is provided. * feat: add agent marketplace repository and pin sub-agent versions at publish Introduce ag_agent_repository_t with list/status/publish/import APIs for frozen agent snapshots. Pin selected_agent_version_no on agent relations when publishing so sub-agents resolve to a fixed version at runtime. Extend agent export/import to bundle skills in ZIP payloads and add embedding model fallback when no model name is provided. * feat: add agent marketplace repository and pin sub-agent versions at publish Introduce ag_agent_repository_t with list/status/publish/import APIs for frozen agent snapshots. Pin selected_agent_version_no on agent relations when publishing so sub-agents resolve to a fixed version at runtime. Extend agent export/import to bundle skills in ZIP payloads and add embedding model fallback when no model name is provided. * feat: add agent marketplace repository and pin sub-agent versions at publish Introduce ag_agent_repository_t with list/status/publish/import APIs for frozen agent snapshots. Pin selected_agent_version_no on agent relations when publishing so sub-agents resolve to a fixed version at runtime. Extend agent export/import to bundle skills in ZIP payloads and add embedding model fallback when no model name is provided. * feat(agent): add verification configuration for agents and update related components (#3174) * feat(agent): add verification configuration for agents and update related components * feat(model): update model type labels and add monitoring dashboard translations * 🐛 Bugfix: Fix inability to select agent from agent space to edit (#3240) * Move non-shadcn ui component to other folder * Bugfix: Fix incomplete display of tenant resources page after window resize * Bugfix: Fix incomplete display of tenant resources page after window resize * Bugfix: Fix inability to select agent from agent space to edit * Bugfix: Display correct version info when viewing agent details * Update data agent and ME CAS integration documentation (#3242) * 补充dataagent对接文档 * 补充ME cas对接文档 * 补充ME cas对接文档 --------- Co-authored-by: hhhhsc <name> * ✨ Add several northbound apis (#3223) * ✨ Add several northbound apis * ✨ Add several northbound apis * ✨ Add several northbound apis * ✨ Add several northbound apis * ✨ Add several northbound apis * refactor: simplify deployment script by removing unused variables and functions (#3245) * feat(agent): add verification configuration for agents and update related components * feat(model): update model type labels and add monitoring dashboard translations * refactor(build_offline_package): simplify deployment script by removing unused variables and functions * 🐛 Bugfix: Adjust agent detail UI layout to accommodate newly added "self-verification" field (#3246) * Move non-shadcn ui component to other folder * Bugfix: Fix incomplete display of tenant resources page after window resize * Bugfix: Fix incomplete display of tenant resources page after window resize * Bugfix: Fix inability to select agent from agent space to edit * Bugfix: Display correct version info when viewing agent details * Bugfix: Adjust agent detail UI layout to accommodate newly added "self-verification" field * 补充sql (#3248) * 补充sql * 扩大limit限制 * 🐛 Bugfix: Fixed an issue where the MCP service failed to start in a Kubernetes container. (#3254) [Specification Details] 1. Modify the pod naming logic to convert all non-compliant characters to -. 2. Modify test cases. * 🐛 Bugfix: knowledge_base_search_tool called with TypeError: argument of type 'FieldInfo' is not iterable (#3259) * 🐛 Bugfix: Fixed an issue where the one-click rename function failed after importing an agent. (#3258) [Specification Details] 1. The frontend does not pass `agent_id` when calling the `regenerate_name` API. * Bugfix: Exclude attachments from assistant when saving conversation history (#3261) * Bump APP_VERSION from v2.2.0 to v2.2.1 (#3268) The default setting for client-side self-validation is "False". --------- Co-authored-by: chase <byzhangxin11@126.com> Co-authored-by: Chenlifeng <174292121+Lifeng-Chen@users.noreply.github.com> Co-authored-by: Dallas98 <40557804+Dallas98@users.noreply.github.com> Co-authored-by: Jason Wang <56037774+JasonW404@users.noreply.github.com> Co-authored-by: Xia Yichen <iamjasonxia@126.com> Co-authored-by: JeffWu <45140512+jeffwu-1999@users.noreply.github.com> Co-authored-by: WMC001 <46217886+WMC001@users.noreply.github.com> Co-authored-by: xuyaqi <xuyaqist@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: DongJiBao2001 <120021235+DongJiBao2001@users.noreply.github.com> Co-authored-by: hhhhsc701 <56435672+hhhhsc701@users.noreply.github.com> Co-authored-by: Dallas98 <990259227@qq.com> Co-authored-by: frr <64584192+wuyuanfr@users.noreply.github.com> * Revert "Release/v2.2.1 (#3269)" (#3272) This reverts commit 9ff420e. * feat(ragflow): add RAGFlow search tool - Add RAGFlowSearchTool SDK with list/str compatibility for dataset_ids and doc_id - Add backend ragflow_service and ragflow_app endpoints - Add frontend KB selector support for ragflow in ToolConfigModal and ToolTestPanel - Fix KB selection clearing when switching between tools - Fix missing inputs field in searchAgentInfo tool mapping - Clean up incorrect configParams fallback in ToolTestPanel * test(ragflow): add unit tests for RAGFlow search tool and service Add 90 tests across 4 files covering ragflow_search_tool, ragflow_service, nexent_agent RAGFlowSearchTool branch, and tool_configuration_service ragflow_search validation. Co-Authored-By: Claude <noreply@anthropic.com> * test(ragflow): fix SonarCloud issues - Add docstring to _MockTool.__init__ - Replace float == with pytest.approx() - Remove type hint from mock_observer fixture - Remove commented code - Add type: ignore for _validate_ragflow_config edge cases Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: panyehong <91180085+YehongPan@users.noreply.github.com> Co-authored-by: chase <byzhangxin11@126.com> Co-authored-by: Chenlifeng <174292121+Lifeng-Chen@users.noreply.github.com> Co-authored-by: Dallas98 <40557804+Dallas98@users.noreply.github.com> Co-authored-by: Jason Wang <56037774+JasonW404@users.noreply.github.com> Co-authored-by: Xia Yichen <iamjasonxia@126.com> Co-authored-by: JeffWu <45140512+jeffwu-1999@users.noreply.github.com> Co-authored-by: WMC001 <46217886+WMC001@users.noreply.github.com> Co-authored-by: xuyaqi <xuyaqist@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: DongJiBao2001 <120021235+DongJiBao2001@users.noreply.github.com> Co-authored-by: hhhhsc701 <56435672+hhhhsc701@users.noreply.github.com> Co-authored-by: Dallas98 <990259227@qq.com> Co-authored-by: frr <64584192+wuyuanfr@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1bd2c1c commit 3077bcd

28 files changed

Lines changed: 2198 additions & 78 deletions

backend/agents/create_agent_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ async def create_tool_config_list(
10921092
f"No embedding model found for index '{index_names[0]}'. "
10931093
f"Please configure an embedding model for this knowledge base.")
10941094
tool_config.metadata["embedding_model"] = embedding_model
1095-
elif tool_config.class_name in ["DifySearchTool", "DataMateSearchTool"]:
1095+
elif tool_config.class_name in ["DifySearchTool", "DataMateSearchTool", "RAGFlowSearchTool"]:
10961096
rerank = tool_config.params.get("rerank", False)
10971097
rerank_model_name = tool_config.params.get("rerank_model_name", "")
10981098
rerank_model = None

backend/apps/config_app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from apps.vectordatabase_app import router as vectordatabase_router
99
from apps.dify_app import router as dify_router
1010
from apps.idata_app import router as idata_router
11+
from apps.ragflow_app import router as ragflow_router
1112
from apps.file_management_app import (
1213
file_management_config_router as file_manager_router,
1314
)
@@ -68,6 +69,7 @@ async def sync_default_prompt_template_on_startup():
6869
app.include_router(tool_config_router)
6970
app.include_router(dify_router)
7071
app.include_router(idata_router)
72+
app.include_router(ragflow_router)
7173
app.include_router(monitoring_router)
7274

7375
# Choose user management router based on IS_SPEED_MODE

backend/apps/ragflow_app.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
RAGFlow App Layer
3+
FastAPI endpoints for RAGFlow knowledge base operations.
4+
"""
5+
import logging
6+
from http import HTTPStatus
7+
from typing import Annotated, Optional
8+
9+
from fastapi import APIRouter, Header, HTTPException, Query
10+
from fastapi.responses import JSONResponse
11+
12+
from consts.error_code import ErrorCode
13+
from consts.exceptions import AppException
14+
from services.ragflow_service import fetch_ragflow_datasets_impl
15+
16+
router = APIRouter(prefix="/ragflow")
17+
logger = logging.getLogger("ragflow_app")
18+
19+
20+
@router.get("/datasets")
21+
async def fetch_ragflow_datasets_api(
22+
ragflow_api_base: Annotated[str, Query(description="RAGFlow API base URL")],
23+
api_key: Annotated[str, Query(description="RAGFlow API key")],
24+
authorization: Annotated[Optional[str], Header()] = None
25+
):
26+
"""
27+
Fetch datasets (knowledge bases) from RAGFlow API.
28+
"""
29+
ragflow_api_base = ragflow_api_base.rstrip('/')
30+
31+
try:
32+
result = fetch_ragflow_datasets_impl(
33+
ragflow_api_base=ragflow_api_base,
34+
api_key=api_key,
35+
)
36+
return JSONResponse(
37+
status_code=HTTPStatus.OK,
38+
content=result
39+
)
40+
except AppException:
41+
raise
42+
except Exception as e:
43+
logger.exception("Failed to fetch RAGFlow datasets")
44+
raise AppException(ErrorCode.RAGFLOW_SERVICE_ERROR,
45+
f"Failed to fetch RAGFlow datasets: {str(e)}")

backend/consts/error_code.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ class ErrorCode(Enum):
195195
AIDP_CONNECTION_ERROR = "130503" # AIDP connection error
196196
AIDP_AUTH_ERROR = "130504" # AIDP auth error
197197

198+
# 06 - RAGFlow Service
199+
RAGFLOW_SERVICE_ERROR = "130507" # RAGFlow service error
200+
RAGFLOW_CONFIG_INVALID = "130508" # Invalid RAGFlow configuration
201+
RAGFLOW_CONNECTION_ERROR = "130509" # RAGFlow connection error
202+
RAGFLOW_AUTH_ERROR = "130510" # RAGFlow auth error
203+
RAGFLOW_RATE_LIMIT = "130511" # RAGFlow rate limit
204+
RAGFLOW_RESPONSE_ERROR = "130512" # RAGFlow response error
205+
198206
# ==================== 14 Northbound / 北向接口 ====================
199207
# 01 - Request
200208
NORTHBOUND_REQUEST_FAILED = "140101" # Northbound request failed
@@ -263,6 +271,12 @@ class ErrorCode(Enum):
263271
ErrorCode.IDATA_CONNECTION_ERROR: 502,
264272
ErrorCode.IDATA_RESPONSE_ERROR: 502,
265273
ErrorCode.IDATA_RATE_LIMIT: 429,
274+
# RAGFlow (module 13)
275+
ErrorCode.RAGFLOW_CONFIG_INVALID: 400,
276+
ErrorCode.RAGFLOW_AUTH_ERROR: 502,
277+
ErrorCode.RAGFLOW_CONNECTION_ERROR: 502,
278+
ErrorCode.RAGFLOW_RESPONSE_ERROR: 502,
279+
ErrorCode.RAGFLOW_RATE_LIMIT: 429,
266280
# AIDP (module 13)
267281
ErrorCode.AIDP_CONFIG_INVALID: 400,
268282
ErrorCode.AIDP_AUTH_ERROR: 502,

backend/consts/tool_labels.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
_category_kb = {
3434
"dify_search": ["knowledge-base"], "datamate_search": ["knowledge-base"],
3535
"idata_search": ["knowledge-base"], "haotian_search": ["knowledge-base"],
36+
"ragflow_search": ["knowledge-base"],
3637
"aidp_search": ["knowledge-base"],
3738
}
3839
_category_multimodal = {
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import json
2+
import logging
3+
from typing import Any, Dict
4+
5+
import httpx
6+
7+
from consts.error_code import ErrorCode
8+
from consts.exceptions import AppException
9+
from nexent.utils.http_client_manager import http_client_manager
10+
11+
logger = logging.getLogger("ragflow_service")
12+
13+
14+
def _validate_ragflow_config(ragflow_api_base: str, api_key: str) -> None:
15+
"""Validate RAGFlow API configuration parameters.
16+
17+
Raises AppException if any parameter is invalid.
18+
"""
19+
if not ragflow_api_base or not isinstance(ragflow_api_base, str):
20+
raise AppException(
21+
ErrorCode.RAGFLOW_CONFIG_INVALID,
22+
"RAGFlow API URL is required and must be a non-empty string"
23+
)
24+
25+
if not api_key or not isinstance(api_key, str):
26+
raise AppException(
27+
ErrorCode.RAGFLOW_CONFIG_INVALID,
28+
"RAGFlow API key is required and must be a non-empty string"
29+
)
30+
31+
32+
def _format_dataset_item(ds: Dict[str, Any]) -> Dict[str, Any]:
33+
"""Format a single RAGFlow dataset into the standard response shape."""
34+
return {
35+
"id": str(ds.get("id", "")),
36+
"name": ds.get("name", ""),
37+
"description": ds.get("description", ""),
38+
"doc_count": ds.get("doc_num", 0) or ds.get("document_count", 0),
39+
"chunk_count": ds.get("chunk_num", 0) or ds.get("chunk_count", 0),
40+
"create_time": str(ds.get("create_time", "")) or str(ds.get("create_date", "")),
41+
"update_time": str(ds.get("update_time", "")) or str(ds.get("update_date", "")),
42+
}
43+
44+
45+
def fetch_ragflow_datasets_impl(
46+
ragflow_api_base: str,
47+
api_key: str,
48+
) -> Dict[str, Any]:
49+
"""
50+
Fetch datasets from RAGFlow API.
51+
52+
Args:
53+
ragflow_api_base: RAGFlow API base URL (e.g., 'http://localhost:9380')
54+
api_key: RAGFlow API key
55+
56+
Returns:
57+
Dictionary containing datasets:
58+
{
59+
"data": [
60+
{
61+
"id": "dataset_id",
62+
"name": "Dataset Name",
63+
"description": "...",
64+
"doc_count": 10,
65+
"chunk_count": 100,
66+
"create_time": "...",
67+
"update_time": "...",
68+
}
69+
]
70+
}
71+
"""
72+
_validate_ragflow_config(ragflow_api_base, api_key)
73+
74+
api_base = ragflow_api_base.rstrip("/")
75+
url = f"{api_base}/api/v1/datasets"
76+
77+
headers = {
78+
"Authorization": f"Bearer {api_key}",
79+
"Content-Type": "application/json"
80+
}
81+
82+
logger.info(f"Fetching RAGFlow datasets from: {url}")
83+
84+
try:
85+
client = http_client_manager.get_sync_client(
86+
base_url=api_base,
87+
timeout=10.0,
88+
verify_ssl=True
89+
)
90+
response = client.get(url, headers=headers)
91+
response.raise_for_status()
92+
93+
result = response.json()
94+
95+
if result.get("code") != 0:
96+
raise AppException(
97+
ErrorCode.RAGFLOW_SERVICE_ERROR,
98+
f"RAGFlow API returned error code {result.get('code')}: "
99+
f"{result.get('message', 'Unknown error')}"
100+
)
101+
102+
datasets = result.get("data", [])
103+
return {"data": [_format_dataset_item(ds) for ds in datasets]}
104+
105+
except httpx.RequestError as e:
106+
logger.exception("RAGFlow API request failed")
107+
raise AppException(ErrorCode.RAGFLOW_CONNECTION_ERROR,
108+
f"RAGFlow API request failed: {str(e)}")
109+
except httpx.HTTPStatusError as e:
110+
logger.exception(
111+
f"RAGFlow API HTTP error: status_code={e.response.status_code}"
112+
)
113+
if e.response.status_code == 401:
114+
raise AppException(ErrorCode.RAGFLOW_AUTH_ERROR,
115+
f"RAGFlow authentication failed: {str(e)}")
116+
if e.response.status_code == 403:
117+
raise AppException(ErrorCode.RAGFLOW_AUTH_ERROR,
118+
f"RAGFlow access forbidden: {str(e)}")
119+
raise AppException(ErrorCode.RAGFLOW_SERVICE_ERROR,
120+
f"RAGFlow API HTTP error {e.response.status_code}: {str(e)}")
121+
except json.JSONDecodeError as e:
122+
logger.exception("Failed to parse RAGFlow API response")
123+
raise AppException(ErrorCode.RAGFLOW_RESPONSE_ERROR,
124+
f"Failed to parse RAGFlow API response: {str(e)}")

backend/services/tool_configuration_service.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,10 @@ async def update_tool_list(tenant_id: str, user_id: str):
483483
mcp_tools = await get_all_mcp_tools(tenant_id)
484484
except Exception as e:
485485
logger.error(f"failed to get all mcp tools, detail: {e}")
486-
raise MCPConnectionError(f"failed to get all mcp tools, detail: {e}")
486+
# Don't block local/langchain tool update when MCP is unavailable.
487+
# MCP tools will be marked as is_available=False in the DB, which
488+
# is the correct state when the MCP server is unreachable.
489+
mcp_tools = []
487490

488491
update_tool_table_from_scan_tool_list(tenant_id=tenant_id,
489492
user_id=user_id,
@@ -812,6 +815,7 @@ def _validate_local_tool(
812815
rerank = instantiation_params.get("rerank", False)
813816
rerank_model_name = instantiation_params.get("rerank_model_name", "")
814817
rerank_model = None
818+
815819
if rerank and rerank_model_name:
816820
rerank_model = get_rerank_model(tenant_id=tenant_id, model_name=rerank_model_name)
817821

@@ -820,6 +824,12 @@ def _validate_local_tool(
820824
'rerank_model': rerank_model,
821825
}
822826
tool_instance = tool_class(**params)
827+
elif tool_name == "ragflow_search":
828+
# RAGFlowSearchTool does not accept rerank/rerank_model_name params
829+
# RAGFlow handles reranking internally via its API
830+
filtered_params = {k: v for k, v in instantiation_params.items()
831+
if k not in ["rerank_model", "rerank", "rerank_model_name"]}
832+
tool_instance = tool_class(**filtered_params)
823833
elif tool_name in ("haotian_search", "aidp_search"):
824834
# Haotian and AIDP share the same instantiation shape: drop the
825835
# backend-only rerank keys and explicitly set observer=None

deploy/sql/migrations/v2.3.0_0624_add_labels_to_ag_tool_info.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ WITH label_map AS (
1818
"search_memory": "search", "knowledge_base_search": "search",
1919
"dify_search": "knowledge-base", "datamate_search": "knowledge-base",
2020
"idata_search": "knowledge-base", "haotian_search": "knowledge-base",
21+
"ragflow_search": "knowledge-base",
2122
"aidp_search": "knowledge-base",
2223
"analyze_image": "multimodal", "analyze_audio": "multimodal",
2324
"analyze_video": "multimodal", "analyze_text_file": "multimodal",

0 commit comments

Comments
 (0)