mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-06 11:28:38 +08:00
Add backward compat APIs (#14427)
### What problem does this PR solve? Add backward compat APIs: ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@@ -301,6 +301,10 @@ client_urls_prefix = [
|
||||
register_page(path) for directory in pages_dir for path in search_pages_path(directory)
|
||||
]
|
||||
|
||||
# Register backward compatibility routes for deprecated APIs
|
||||
from api.apps.backward_compat import register_backward_compat_routes
|
||||
register_backward_compat_routes(app)
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
async def not_found(error):
|
||||
|
||||
384
api/apps/backward_compat.py
Normal file
384
api/apps/backward_compat.py
Normal file
@@ -0,0 +1,384 @@
|
||||
#
|
||||
# Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
"""
|
||||
Backward compatibility layer for deprecated API endpoints.
|
||||
|
||||
This module adds support for old API routes that were deprecated during the
|
||||
RESTful API migration. Each deprecated route forwards to the corresponding
|
||||
new API implementation.
|
||||
|
||||
Deprecated APIs and their replacements:
|
||||
- POST /api/v1/chats/{chat_id}/completions -> POST /api/v1/chat/completions
|
||||
- POST /api/v1/chats_openai/{chat_id}/chat/completions -> POST /api/v1/openai/{chat_id}/chat/completions
|
||||
- PUT /api/v1/chats/{chat_id}/sessions/{session_id} -> PATCH /api/v1/chats/{chat_id}/sessions/{session_id}
|
||||
- DELETE /api/v1/chats -> DELETE /api/v1/chats/{chat_id} (with body)
|
||||
- GET /api/v1/file/* -> GET /api/v1/files*
|
||||
- POST /api/v1/file/* -> POST /api/v1/files*
|
||||
- POST /api/v1/sessions/related_questions -> POST /api/v1/chat/recommandation
|
||||
- PUT (chunk update) -> PATCH (chunk update)
|
||||
"""
|
||||
import logging
|
||||
|
||||
from quart import Blueprint, request
|
||||
|
||||
from api.apps import login_required
|
||||
from api.apps.restful_apis import chat_api, file_api, chunk_api, openai_api, document_api
|
||||
from api.apps.services import file_api_service
|
||||
from api.utils.api_utils import get_data_error_result, get_json_result, add_tenant_id_to_kwargs
|
||||
|
||||
manager = Blueprint("backward_compat", __name__)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Chat Completion APIs
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/chats/<chat_id>/completions", methods=["POST"])
|
||||
@login_required
|
||||
async def deprecated_chat_completions(chat_id):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/chat/completions instead.
|
||||
|
||||
Old path: POST /api/v1/chats/{chat_id}/completions
|
||||
New path: POST /api/v1/chat/completions
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/chats/%s/completions is deprecated. "
|
||||
"Please use /api/v1/chat/completions instead.",
|
||||
chat_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await chat_api.session_completion(chat_id)
|
||||
|
||||
|
||||
@manager.route("/chats_openai/<chat_id>/chat/completions", methods=["POST"])
|
||||
@login_required
|
||||
async def deprecated_openai_chat_completions(chat_id):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/openai/{chat_id}/chat/completions instead.
|
||||
|
||||
Old path: POST /api/v1/chats_openai/{chat_id}/chat/completions
|
||||
New path: POST /api/v1/openai/{chat_id}/chat/completions
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/chats_openai/%s/chat/completions is deprecated. "
|
||||
"Please use /api/v1/openai/%s/chat/completions instead.",
|
||||
chat_id, chat_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await openai_api.openai_chat_completions(chat_id)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Chat Session APIs
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/chats/<chat_id>/sessions/<session_id>", methods=["PUT"])
|
||||
@login_required
|
||||
async def deprecated_update_session(chat_id, session_id):
|
||||
"""
|
||||
Deprecated: Use PATCH /api/v1/chats/{chat_id}/sessions/{session_id} instead.
|
||||
|
||||
Old path: PUT /api/v1/chats/{chat_id}/sessions/{session_id}
|
||||
New path: PATCH /api/v1/chats/{chat_id}/sessions/{session_id}
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint PUT /api/v1/chats/%s/sessions/%s is deprecated. "
|
||||
"Please use PATCH /api/v1/chats/%s/sessions/%s instead.",
|
||||
chat_id, session_id, chat_id, session_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await chat_api.patch_session(chat_id, session_id)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# File APIs (Old /api/v1/file/* -> New /api/v1/files*)
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/file/get/<file_id>", methods=["GET"])
|
||||
@login_required
|
||||
async def deprecated_file_get(file_id):
|
||||
"""
|
||||
Deprecated: Use GET /api/v1/files/{file_id} instead.
|
||||
|
||||
Old path: GET /api/v1/file/get/{file_id}
|
||||
New path: GET /api/v1/files/{file_id}
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/get/%s is deprecated. "
|
||||
"Please use /api/v1/files/%s instead.",
|
||||
file_id, file_id,
|
||||
)
|
||||
# Forward to the new API implementation (download)
|
||||
return await file_api.download(file_id=file_id)
|
||||
|
||||
|
||||
@manager.route("/file/list", methods=["GET"])
|
||||
@login_required
|
||||
async def deprecated_file_list():
|
||||
"""
|
||||
Deprecated: Use GET /api/v1/files instead.
|
||||
|
||||
Old path: GET /api/v1/file/list?...
|
||||
New path: GET /api/v1/files?...
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/list is deprecated. "
|
||||
"Please use /api/v1/files instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.list_files()
|
||||
|
||||
|
||||
@manager.route("/file/all_parent_folder", methods=["GET"])
|
||||
@login_required
|
||||
async def deprecated_file_all_parent_folder():
|
||||
"""
|
||||
Deprecated: Use GET /api/v1/files/{file_id}/ancestors instead.
|
||||
|
||||
Old path: GET /api/v1/file/all_parent_folder?file_id=...
|
||||
New path: GET /api/v1/files/{file_id}/ancestors
|
||||
"""
|
||||
file_id = request.args.get("file_id")
|
||||
if not file_id:
|
||||
return get_data_error_result(message="`file_id` query parameter is required")
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/all_parent_folder is deprecated. "
|
||||
"Please use /api/v1/files/%s/ancestors instead.",
|
||||
file_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.ancestors(file_id=file_id)
|
||||
|
||||
|
||||
@manager.route("/file/parent_folder", methods=["GET"])
|
||||
@login_required
|
||||
async def deprecated_file_parent_folder():
|
||||
"""
|
||||
Deprecated: Use GET /api/v1/files/{file_id}/parent instead.
|
||||
|
||||
Old path: GET /api/v1/file/parent_folder?file_id=...
|
||||
New path: GET /api/v1/files/{file_id}/parent
|
||||
"""
|
||||
file_id = request.args.get("file_id")
|
||||
if not file_id:
|
||||
return get_data_error_result(message="`file_id` query parameter is required")
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/parent_folder is deprecated. "
|
||||
"Please use /api/v1/files/%s/parent instead.",
|
||||
file_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.parent_folder(file_id=file_id)
|
||||
|
||||
|
||||
@manager.route("/file/root_folder", methods=["GET"])
|
||||
@login_required
|
||||
async def deprecated_file_root_folder():
|
||||
"""
|
||||
Deprecated: Root folder is now accessible via GET /api/v1/files with parent_id=...
|
||||
|
||||
Old path: GET /api/v1/file/root_folder
|
||||
New path: GET /api/v1/files?parent_id=<root_id>
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/root_folder is deprecated. "
|
||||
"Please use /api/v1/files with appropriate parent_id instead."
|
||||
)
|
||||
# Forward to the new API implementation with empty parent_id to get root
|
||||
return await file_api.list_files()
|
||||
|
||||
|
||||
@manager.route("/file/create", methods=["POST"])
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
async def deprecated_file_create(tenant_id=None):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/files instead.
|
||||
|
||||
Old path: POST /api/v1/file/create
|
||||
New path: POST /api/v1/files
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/create is deprecated. "
|
||||
"Please use POST /api/v1/files instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.create_or_upload(tenant_id=tenant_id)
|
||||
|
||||
|
||||
@manager.route("/file/upload", methods=["POST"])
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
async def deprecated_file_upload(tenant_id=None):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/files (with multipart/form-data) instead.
|
||||
|
||||
Old path: POST /api/v1/file/upload
|
||||
New path: POST /api/v1/files
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/upload is deprecated. "
|
||||
"Please use POST /api/v1/files with multipart/form-data instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.create_or_upload(tenant_id=tenant_id)
|
||||
|
||||
|
||||
@manager.route("/file/mv", methods=["POST"])
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
async def deprecated_file_mv(tenant_id=None):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/files/move instead.
|
||||
|
||||
Old path: POST /api/v1/file/mv
|
||||
New path: POST /api/v1/files/move
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/mv is deprecated. "
|
||||
"Please use POST /api/v1/files/move instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await file_api.move(tenant_id=tenant_id)
|
||||
|
||||
|
||||
@manager.route("/file/rename", methods=["POST"])
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
async def deprecated_file_rename(tenant_id=None):
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/files/move with new_name instead.
|
||||
|
||||
Old path: POST /api/v1/file/rename
|
||||
New path: POST /api/v1/files/move
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/rename is deprecated. "
|
||||
"Please use POST /api/v1/files/move with `new_name` instead."
|
||||
)
|
||||
# Transform the old API format to new format
|
||||
req = await request.get_json()
|
||||
# Old API used `file_id` and `name`, new API uses `src_file_ids` and `new_name`
|
||||
src_file_ids = [req.get("file_id")]
|
||||
new_name = req.get("name")
|
||||
# Call the underlying service directly with transformed data
|
||||
try:
|
||||
success, result = await file_api_service.move_files(
|
||||
tenant_id, src_file_ids, None, new_name
|
||||
)
|
||||
if success:
|
||||
return get_json_result(data=result)
|
||||
else:
|
||||
return get_data_error_result(message=result)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
return get_data_error_result(message="Internal server error")
|
||||
|
||||
|
||||
@manager.route("/file/rm", methods=["POST"])
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
async def deprecated_file_rm(tenant_id=None):
|
||||
"""
|
||||
Deprecated: Use DELETE /api/v1/files instead.
|
||||
|
||||
Old path: POST /api/v1/file/rm
|
||||
New path: DELETE /api/v1/files
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/rm is deprecated. "
|
||||
"Please use DELETE /api/v1/files instead."
|
||||
)
|
||||
# Transform POST with body to DELETE behavior
|
||||
# The new API expects a JSON body with `ids`
|
||||
return await file_api.delete(tenant_id=tenant_id)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Related Questions API
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/sessions/related_questions", methods=["POST"])
|
||||
@login_required
|
||||
async def deprecated_related_questions():
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/chat/recommandation instead.
|
||||
|
||||
Old path: POST /api/v1/sessions/related_questions
|
||||
New path: POST /api/v1/chat/recommandation
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/sessions/related_questions is deprecated. "
|
||||
"Please use /api/v1/chat/recommandation instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await chat_api.recommandation()
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Chunk Update API (PUT -> PATCH)
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/datasets/<dataset_id>/documents/<document_id>/chunks/<chunk_id>", methods=["PUT"])
|
||||
@login_required
|
||||
async def deprecated_update_chunk(dataset_id, document_id, chunk_id):
|
||||
"""
|
||||
Deprecated: Use PATCH /api/v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id} instead.
|
||||
|
||||
Old path: PUT /api/v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id}
|
||||
New path: PATCH /api/v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id}
|
||||
"""
|
||||
logging.warning(
|
||||
"API endpoint PUT /api/v1/datasets/%s/documents/%s/chunks/%s is deprecated. "
|
||||
"Please use PATCH instead.",
|
||||
dataset_id, document_id, chunk_id,
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
return await chunk_api.patch_chunk(dataset_id, document_id, chunk_id)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# File Upload Info API
|
||||
# =============================================================================
|
||||
|
||||
@manager.route("/file/upload_info", methods=["POST"])
|
||||
@login_required
|
||||
async def deprecated_file_upload_info():
|
||||
"""
|
||||
Deprecated: Use POST /api/v1/documents/upload instead.
|
||||
|
||||
Old path: POST /api/v1/file/upload_info
|
||||
New path: POST /api/v1/documents/upload
|
||||
"""
|
||||
from api.apps import current_user
|
||||
|
||||
logging.warning(
|
||||
"API endpoint /api/v1/file/upload_info is deprecated. "
|
||||
"Please use POST /api/v1/documents/upload instead."
|
||||
)
|
||||
# Forward to the new API implementation
|
||||
# Need to pass tenant_id explicitly since we're calling the function directly
|
||||
tenant_id = current_user.id
|
||||
return await document_api.upload_info(tenant_id=tenant_id)
|
||||
|
||||
|
||||
def register_backward_compat_routes(app_instance):
|
||||
"""
|
||||
Register all backward compatibility routes with the app.
|
||||
"""
|
||||
app_instance.register_blueprint(manager, url_prefix="/api/v1")
|
||||
logging.info("Backward compatibility routes registered successfully.")
|
||||
@@ -608,6 +608,15 @@ async def bulk_delete_chats():
|
||||
if not ids:
|
||||
return get_json_result(data={})
|
||||
else:
|
||||
# keep backward compatibility, DELETE with chat_id in request body
|
||||
chat_id = req.get("chat_id")
|
||||
if chat_id:
|
||||
try:
|
||||
if not DialogService.update_by_id(chat_id, {"status": StatusEnum.INVALID.value}):
|
||||
return get_data_error_result(message=f"Failed to delete chat {chat_id}")
|
||||
return get_json_result(data=True)
|
||||
except Exception as ex:
|
||||
return server_error_response(ex)
|
||||
return get_json_result(data={})
|
||||
|
||||
errors = []
|
||||
@@ -1017,7 +1026,7 @@ async def recommendation():
|
||||
@manager.route("/chat/completions", methods=["POST"]) # noqa: F821
|
||||
@login_required
|
||||
@validate_request("messages")
|
||||
async def session_completion():
|
||||
async def session_completion(chat_id_in_arg=""):
|
||||
req = await get_request_json()
|
||||
msg = []
|
||||
for m in req["messages"]:
|
||||
@@ -1028,6 +1037,7 @@ async def session_completion():
|
||||
msg.append(m)
|
||||
message_id = msg[-1].get("id") if msg else None
|
||||
chat_id = req.pop("chat_id", "") or ""
|
||||
chat_id = chat_id or chat_id_in_arg
|
||||
session_id = req.pop("session_id", "") or ""
|
||||
chat_model_id = req.pop("llm_id", "")
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ async def create_or_upload(tenant_id: str = None):
|
||||
@manager.route("/files", methods=["GET"]) # noqa: F821
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
def list_files(tenant_id: str = None):
|
||||
async def list_files(tenant_id: str = None):
|
||||
"""
|
||||
List files under a folder.
|
||||
---
|
||||
@@ -303,7 +303,7 @@ async def download(tenant_id: str = None, file_id: str = None):
|
||||
@manager.route("/files/<file_id>/parent", methods=["GET"]) # noqa: F821
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
def parent_folder(tenant_id: str = None, file_id: str = None):
|
||||
async def parent_folder(tenant_id: str = None, file_id: str = None):
|
||||
"""
|
||||
Get parent folder of a file.
|
||||
---
|
||||
@@ -334,7 +334,7 @@ def parent_folder(tenant_id: str = None, file_id: str = None):
|
||||
@manager.route("/files/<file_id>/ancestors", methods=["GET"]) # noqa: F821
|
||||
@login_required
|
||||
@add_tenant_id_to_kwargs
|
||||
def ancestors(tenant_id: str = None, file_id: str = None):
|
||||
async def ancestors(tenant_id: str = None, file_id: str = None):
|
||||
"""
|
||||
Get all ancestor folders of a file.
|
||||
---
|
||||
|
||||
@@ -37,6 +37,10 @@ A complete reference for RAGFlow's RESTful API. Before proceeding, please ensure
|
||||
|
||||
Creates a model response for a given chat conversation.
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `POST /api/v1/chats_openai/{chat_id}/chat/completions` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
This API follows the same request and response format as OpenAI's API. It allows you to interact with the model in a manner similar to how you would with [OpenAI's API](https://platform.openai.com/docs/api-reference/chat/create).
|
||||
|
||||
#### Request
|
||||
@@ -2369,6 +2373,10 @@ Failure:
|
||||
|
||||
Updates content or configurations for a specified chunk.
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `PUT /api/v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id}` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
#### Request
|
||||
|
||||
- Method: PATCH
|
||||
@@ -2908,11 +2916,11 @@ curl --request POST \
|
||||
- `"temperature"`: `float`
|
||||
Controls the randomness of the model's predictions. A lower temperature results in more conservative responses, while a higher temperature yields more creative and diverse responses. Defaults to `0.1`.
|
||||
- `"top_p"`: `float`
|
||||
Also known as “nucleus sampling”, this parameter sets a threshold to select a smaller set of words to sample from. It focuses on the most likely words, cutting off the less probable ones. Defaults to `0.3`
|
||||
Also known as "nucleus sampling", this parameter sets a threshold to select a smaller set of words to sample from. It focuses on the most likely words, cutting off the less probable ones. Defaults to `0.3`
|
||||
- `"presence_penalty"`: `float`
|
||||
This discourages the model from repeating the same information by penalizing words that have already appeared in the conversation. Defaults to `0.4`.
|
||||
- `"frequency penalty"`: `float`
|
||||
Similar to the presence penalty, this reduces the model’s tendency to repeat the same words frequently. Defaults to `0.7`.
|
||||
Similar to the presence penalty, this reduces the model's tendency to repeat the same words frequently. Defaults to `0.7`.
|
||||
- `"prompt_config"`: (*Body parameter*), `object`
|
||||
Instructions for the LLM to follow. A `prompt_config` object may contain the following attributes:
|
||||
- `"system"`: `string` The prompt content.
|
||||
@@ -3071,11 +3079,11 @@ curl --request PUT \
|
||||
- `"temperature"`: `float`
|
||||
Controls the randomness of the model's predictions. A lower temperature results in more conservative responses, while a higher temperature yields more creative and diverse responses. Defaults to `0.1`.
|
||||
- `"top_p"`: `float`
|
||||
Also known as “nucleus sampling”, this parameter sets a threshold to select a smaller set of words to sample from. It focuses on the most likely words, cutting off the less probable ones. Defaults to `0.3`
|
||||
Also known as "nucleus sampling", this parameter sets a threshold to select a smaller set of words to sample from. It focuses on the most likely words, cutting off the less probable ones. Defaults to `0.3`
|
||||
- `"presence_penalty"`: `float`
|
||||
This discourages the model from repeating the same information by penalizing words that have already appeared in the conversation. Defaults to `0.4`.
|
||||
- `"frequency penalty"`: `float`
|
||||
Similar to the presence penalty, this reduces the model’s tendency to repeat the same words frequently. Defaults to `0.7`.
|
||||
Similar to the presence penalty, this reduces the model's tendency to repeat the same words frequently. Defaults to `0.7`.
|
||||
- `"prompt_config"`: (*Body parameter*), `object`
|
||||
- `"similarity_threshold"`: (*Body parameter*), `float`
|
||||
- `"vector_similarity_weight"`: (*Body parameter*), `float`
|
||||
@@ -3326,6 +3334,10 @@ Failure:
|
||||
|
||||
Deletes chat assistants by ID.
|
||||
|
||||
:::caution DEPRECATED
|
||||
The `chat_id` in the request body is deprecated, please use `ids` list.
|
||||
:::
|
||||
|
||||
#### Request
|
||||
|
||||
- Method: DELETE
|
||||
@@ -3584,6 +3596,10 @@ Failure:
|
||||
|
||||
Updates a session of a specified chat assistant.
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `PUT /api/v1/chats/{chat_id}/sessions/{session_id}` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
#### Request
|
||||
|
||||
- Method: PATCH
|
||||
@@ -4009,6 +4025,10 @@ Failure:
|
||||
|
||||
Starts a chat completion request. The same endpoint supports three modes:
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `POST /api/v1/chats/{chat_id}/completions` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
- No `chat_id`: talk directly with the tenant's default chat model.
|
||||
- With `chat_id` but no `session_id`: use that chat's configuration and automatically create a new session.
|
||||
- With both `chat_id` and `session_id`: continue an existing chat session.
|
||||
@@ -5215,6 +5235,10 @@ Failure:
|
||||
|
||||
Generates five to ten alternative question strings from the user's original query to retrieve more relevant search results.
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `POST /api/v1/sessions/related_questions` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
This operation requires a `Bearer Login Token`, which typically expires with in 24 hours. You can find it in the Request Headers in your browser easily as shown below:
|
||||
|
||||

|
||||
@@ -6441,7 +6465,7 @@ Success
|
||||
"data": [
|
||||
{
|
||||
"agent_id": "8db9c8eddfcc11f0b5da84ba59bc53c7",
|
||||
"content": "User Input: who am I?\nAgent Response: To address the question \"who am I?\", let's follow the logical steps outlined in the instructions:\n\n1. **Understand the User’s Request**: The user is asking for a clarification or identification of their own self. This is a fundamental question about personal identity.\n\n2. **Decompose the Request**: The request is quite simple and doesn't require complex decomposition. The core task is to provide an answer that identifies the user in some capacity.\n\n3. **Execute the Subtask**:\n - **Identify the nature of the question**: The user is seeking to understand their own existence or their sense of self.\n - **Assess the context**: The context is not explicitly given, so the response will be general.\n - **Provide a response**: The answer should acknowledge the user's inquiry into their identity.\n\n4. **Validate Accuracy and Consistency**: The response should be consistent with the general understanding of the question. Since the user has not provided specific details about their identity, the response should be broad and open-ended.\n\n5. **Summarize the Final Result**: The user is asking \"who am I?\" which is an inquiry into their own identity. The answer is that the user is the individual who is asking the question. Without more specific information, a detailed description of their identity cannot be provided.\n\nSo, the final summary would be:\n\nThe user is asking the question \"who am I?\" to seek an understanding of their own identity. The response to this question is that the user is the individual who is posing the question. Without additional context or details, a more comprehensive description of the user's identity cannot be given.",
|
||||
"content": "User Input: who am I?\nAgent Response: To address the question \"who am I?\", let's follow the logical steps outlined in the instructions:\n\n1. **Understand the User's Request**: The user is asking for a clarification or identification of their own self. This is a fundamental question about personal identity.\n\n2. **Decompose the Request**: The request is quite simple and doesn't require complex decomposition. The core task is to provide an answer that identifies the user in some capacity.\n\n3. **Execute the Subtask**:\n - **Identify the nature of the question**: The user is seeking to understand their own existence or their sense of self.\n - **Assess the context**: The context is not explicitly given, so the response will be general.\n - **Provide a response**: The answer should acknowledge the user's inquiry into their identity.\n\n4. **Validate Accuracy and Consistency**: The response should be consistent with the general understanding of the question. Since the user has not provided specific details about their identity, the response should be broad and open-ended.\n\n5. **Summarize the Final Result**: The user is asking \"who am I?\" which is an inquiry into their own identity. The answer is that the user is the individual who is asking the question. Without more specific information, a detailed description of their identity cannot be provided.\n\nSo, the final summary would be:\n\nThe user is asking the question \"who am I?\" to seek an understanding of their own identity. The response to this question is that the user is the individual who is posing the question. Without additional context or details, a more comprehensive description of the user's identity cannot be given.",
|
||||
"forget_at": "None",
|
||||
"invalid_at": "None",
|
||||
"memory_id": "6c8983badede11f083f184ba59bc53c7",
|
||||
@@ -6632,7 +6656,11 @@ Failure
|
||||
|
||||
**GET** `/api/v1/system/healthz`
|
||||
|
||||
Check the health status of RAGFlow’s dependencies (database, Redis, document engine, object storage).
|
||||
Check the health status of RAGFlow's dependencies (database, Redis, document engine, object storage).
|
||||
|
||||
:::caution DEPRECATED
|
||||
The previous endpoint `GET /v1/system/healthz` is deprecated. Please use this endpoint instead.
|
||||
:::
|
||||
|
||||
#### Request
|
||||
|
||||
@@ -6713,6 +6741,10 @@ Explanation:
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url http://{address}/api/v1/files \
|
||||
--header 'Content-Type: multipart/form-data' \
|
||||
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
||||
--form 'file=@./test1.txt' \
|
||||
--form 'file=@./test2.pdf' \
|
||||
--form 'parent_id={folder_id}'
|
||||
```
|
||||
|
||||
@@ -6912,6 +6944,10 @@ Failure:
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url http://{address}/api/v1/files \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
||||
--data '{
|
||||
"name": "New Folder",
|
||||
"type": "folder",
|
||||
"parent_id": "{folder_id}"
|
||||
@@ -6984,6 +7020,10 @@ Failure:
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
|
||||
- `parent_id`: (*Filter parameter*), `string`
|
||||
The folder ID to list files from. If not specified, the root folder is used by default.
|
||||
- `keywords`: (*Filter parameter*), `string`
|
||||
Search keyword to filter files by name.
|
||||
- `page`: (*Filter parameter*), `integer`
|
||||
Specifies the page on which the files will be displayed. Defaults to `1`.
|
||||
@@ -7059,6 +7099,10 @@ Failure:
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
|
||||
- `file_id`: (*Path parameter*), `string`, *Required*
|
||||
The ID of the file whose immediate parent folder to retrieve.
|
||||
|
||||
#### Response
|
||||
|
||||
Success:
|
||||
@@ -7112,6 +7156,10 @@ Failure:
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
|
||||
- `file_id`: (*Path parameter*), `string`, *Required*
|
||||
The ID of the file whose parent folders to retrieve.
|
||||
|
||||
#### Response
|
||||
|
||||
Success:
|
||||
@@ -7171,6 +7219,10 @@ Failure:
|
||||
curl --request DELETE \
|
||||
--url http://{address}/api/v1/files \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
||||
--data '{
|
||||
"ids": ["file_id_1", "file_id_2"]
|
||||
}'
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
@@ -7226,6 +7278,10 @@ Failure:
|
||||
--output ./downloaded_file.txt
|
||||
```
|
||||
|
||||
##### Request parameters
|
||||
|
||||
- `file_id`: (*Path parameter*), `string`, *Required*
|
||||
The ID of the file to download.
|
||||
|
||||
#### Response
|
||||
|
||||
@@ -7270,6 +7326,10 @@ Failure:
|
||||
- `"dest_file_id"`: `string`, *Optional*
|
||||
- `"new_name"`: `string`, *Optional*
|
||||
|
||||
##### Request examples
|
||||
|
||||
Move files to a folder:
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url http://{address}/api/v1/files/move \
|
||||
|
||||
@@ -259,7 +259,7 @@ def test_list_files_validation_error(monkeypatch):
|
||||
module = _load_file_api_module(monkeypatch)
|
||||
monkeypatch.setattr(module, "validate_and_parse_request_args", lambda _request, _schema: (None, "bad args"))
|
||||
|
||||
res = module.list_files("tenant1")
|
||||
res = _run(module.list_files("tenant1"))
|
||||
assert res["code"] == 400
|
||||
assert res["message"] == "bad args"
|
||||
|
||||
@@ -330,8 +330,8 @@ def test_download_falls_back_to_document_storage(monkeypatch):
|
||||
def test_parent_and_ancestors_use_new_routes(monkeypatch):
|
||||
module = _load_file_api_module(monkeypatch)
|
||||
|
||||
parent_res = module.parent_folder("tenant1", "file1")
|
||||
ancestors_res = module.ancestors("tenant1", "file1")
|
||||
parent_res = _run(module.parent_folder("tenant1", "file1"))
|
||||
ancestors_res = _run(module.ancestors("tenant1", "file1"))
|
||||
|
||||
assert parent_res["code"] == 0
|
||||
assert parent_res["data"]["parent_folder"]["id"] == "parent1"
|
||||
|
||||
@@ -79,6 +79,10 @@ def _load_apps_module(monkeypatch):
|
||||
api_utils_mod.server_error_response = _server_error_response
|
||||
monkeypatch.setitem(sys.modules, "api.utils.api_utils", api_utils_mod)
|
||||
|
||||
backward_compat_mod = ModuleType("api.apps.backward_compat")
|
||||
backward_compat_mod.register_backward_compat_routes = lambda _app: None
|
||||
monkeypatch.setitem(sys.modules, "api.apps.backward_compat", backward_compat_mod)
|
||||
|
||||
module_name = "test_apps_init_unit_module"
|
||||
module_path = repo_root / "api" / "apps" / "__init__.py"
|
||||
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
||||
|
||||
Reference in New Issue
Block a user