mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-05-28 03:33:05 +08:00
Closes #14753 ## What changed | File | Change | |---|---| | `pyproject.toml` | `requires-python` → `>=3.13,<3.15`; remove `strenum==0.4.15` | | `Dockerfile` | `uv python install 3.13`, `uv sync --python 3.13` | | `.github/workflows/tests.yml` | `uv sync --python 3.13` on both matrix legs | | `CLAUDE.md` | dev setup command + requirements note updated | | `deepdoc/parser/mineru_parser.py` | `from strenum import StrEnum` → `from enum import StrEnum` | | `agent/tools/code_exec.py` | same | `StrEnum` has been in the stdlib since Python 3.11 — the `strenum` backport package is no longer needed once the floor is 3.13. ## Why uv.lock is not regenerated `uv lock --python 3.13` fails because: 1. The infiniflow/graspologic fork pins `numpy>=1.26.4,<2.0.0` 2. `tensorflow-cpu>=2.20.0` (the first release with cp313 wheels) depends on `ml-dtypes>=0.5.1`, which requires `numpy>=2.1.0` 3. These two constraints are irreconcilable on Python 3.13 The lockfile regeneration requires loosening the `numpy` upper bound in the `infiniflow/graspologic` fork. Once that fork commit is updated and the SHA in `pyproject.toml:49` is bumped, `uv lock --python 3.13` will succeed. ## RFC corrections Two claims in the original RFC (#14753) did not hold up under code review: - **"graspologic hard-blocks 3.13"** — the infiniflow fork at the pinned commit has no `<3.13` Python constraint. The blocker is the transitive `numpy<2.0.0` conflict with tensorflow-cpu's test dependency, not a direct Python version cap. - **"free-threading throughput gains for I/O-bound workload"** — Python 3.13 free-threading requires a special `--disable-gil` build and provides no benefit for async I/O code (the GIL is already released during I/O). The real motivation is forward compatibility and improved error messages.
201 lines
7.8 KiB
Python
201 lines
7.8 KiB
Python
#
|
|
# Copyright 2024 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.
|
|
#
|
|
# AFTER UPDATING THIS FILE, PLEASE ENSURE THAT docs/references/supported_models.mdx IS ALSO UPDATED for consistency!
|
|
#
|
|
|
|
import importlib
|
|
import inspect
|
|
|
|
from enum import StrEnum
|
|
|
|
|
|
class SupportedLiteLLMProvider(StrEnum):
|
|
Tongyi_Qianwen = "Tongyi-Qianwen"
|
|
Dashscope = "Dashscope"
|
|
Bedrock = "Bedrock"
|
|
Moonshot = "Moonshot"
|
|
xAI = "xAI"
|
|
DeepInfra = "DeepInfra"
|
|
Groq = "Groq"
|
|
Cohere = "Cohere"
|
|
Gemini = "Gemini"
|
|
DeepSeek = "DeepSeek"
|
|
Nvidia = "NVIDIA"
|
|
TogetherAI = "TogetherAI"
|
|
Anthropic = "Anthropic"
|
|
Ollama = "Ollama"
|
|
LongCat = "LongCat"
|
|
CometAPI = "CometAPI"
|
|
SILICONFLOW = "SILICONFLOW"
|
|
OpenRouter = "OpenRouter"
|
|
StepFun = "StepFun"
|
|
PPIO = "PPIO"
|
|
PerfXCloud = "PerfXCloud"
|
|
Upstage = "Upstage"
|
|
NovitaAI = "NovitaAI"
|
|
Lingyi_AI = "01.AI"
|
|
GiteeAI = "GiteeAI"
|
|
AI_302 = "302.AI"
|
|
JiekouAI = "Jiekou.AI"
|
|
ZHIPU_AI = "ZHIPU-AI"
|
|
MiniMax = "MiniMax"
|
|
DeerAPI = "DeerAPI"
|
|
GPUStack = "GPUStack"
|
|
OpenAI = "OpenAI"
|
|
Azure_OpenAI = "Azure-OpenAI"
|
|
n1n = "n1n"
|
|
HunYuan = "Tencent Hunyuan"
|
|
Avian = "Avian"
|
|
Astraflow = "Astraflow"
|
|
Astraflow_CN = "Astraflow-CN"
|
|
FuturMix = "FuturMix"
|
|
|
|
|
|
FACTORY_DEFAULT_BASE_URL = {
|
|
SupportedLiteLLMProvider.Tongyi_Qianwen: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
SupportedLiteLLMProvider.Dashscope: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
SupportedLiteLLMProvider.Moonshot: "https://api.moonshot.cn/v1",
|
|
SupportedLiteLLMProvider.Ollama: "",
|
|
SupportedLiteLLMProvider.LongCat: "https://api.longcat.chat/openai",
|
|
SupportedLiteLLMProvider.CometAPI: "https://api.cometapi.com/v1",
|
|
SupportedLiteLLMProvider.SILICONFLOW: "https://api.siliconflow.cn/v1",
|
|
SupportedLiteLLMProvider.OpenRouter: "https://openrouter.ai/api/v1",
|
|
SupportedLiteLLMProvider.StepFun: "https://api.stepfun.com/v1",
|
|
SupportedLiteLLMProvider.PPIO: "https://api.ppinfra.com/v3/openai",
|
|
SupportedLiteLLMProvider.PerfXCloud: "https://cloud.perfxlab.cn/v1",
|
|
SupportedLiteLLMProvider.Upstage: "https://api.upstage.ai/v1/solar",
|
|
SupportedLiteLLMProvider.NovitaAI: "https://api.novita.ai/v3/openai",
|
|
SupportedLiteLLMProvider.Lingyi_AI: "https://api.lingyiwanwu.com/v1",
|
|
SupportedLiteLLMProvider.GiteeAI: "https://ai.gitee.com/v1/",
|
|
SupportedLiteLLMProvider.AI_302: "https://api.302.ai/v1",
|
|
SupportedLiteLLMProvider.Anthropic: "https://api.anthropic.com/",
|
|
SupportedLiteLLMProvider.JiekouAI: "https://api.jiekou.ai/openai",
|
|
SupportedLiteLLMProvider.ZHIPU_AI: "https://open.bigmodel.cn/api/paas/v4",
|
|
SupportedLiteLLMProvider.MiniMax: "https://api.minimaxi.com/v1",
|
|
SupportedLiteLLMProvider.DeerAPI: "https://api.deerapi.com/v1",
|
|
SupportedLiteLLMProvider.OpenAI: "https://api.openai.com/v1",
|
|
SupportedLiteLLMProvider.n1n: "https://api.n1n.ai/v1",
|
|
SupportedLiteLLMProvider.HunYuan: "https://api.hunyuan.cloud.tencent.com/v1",
|
|
SupportedLiteLLMProvider.Avian: "https://api.avian.io/v1",
|
|
SupportedLiteLLMProvider.Astraflow: "https://api-us-ca.umodelverse.ai/v1",
|
|
SupportedLiteLLMProvider.Astraflow_CN: "https://api.modelverse.cn/v1",
|
|
SupportedLiteLLMProvider.FuturMix: "https://futurmix.ai/v1",
|
|
}
|
|
|
|
|
|
LITELLM_PROVIDER_PREFIX = {
|
|
SupportedLiteLLMProvider.Tongyi_Qianwen: "dashscope/",
|
|
SupportedLiteLLMProvider.Dashscope: "dashscope/",
|
|
SupportedLiteLLMProvider.Bedrock: "bedrock/",
|
|
SupportedLiteLLMProvider.Moonshot: "moonshot/",
|
|
SupportedLiteLLMProvider.xAI: "xai/",
|
|
SupportedLiteLLMProvider.DeepInfra: "deepinfra/",
|
|
SupportedLiteLLMProvider.Groq: "groq/",
|
|
SupportedLiteLLMProvider.Cohere: "", # don't need a prefix
|
|
SupportedLiteLLMProvider.Gemini: "gemini/",
|
|
SupportedLiteLLMProvider.DeepSeek: "deepseek/",
|
|
SupportedLiteLLMProvider.Nvidia: "nvidia_nim/",
|
|
SupportedLiteLLMProvider.TogetherAI: "together_ai/",
|
|
SupportedLiteLLMProvider.Anthropic: "", # don't need a prefix
|
|
SupportedLiteLLMProvider.Ollama: "ollama_chat/",
|
|
SupportedLiteLLMProvider.LongCat: "openai/",
|
|
SupportedLiteLLMProvider.CometAPI: "openai/",
|
|
SupportedLiteLLMProvider.SILICONFLOW: "openai/",
|
|
SupportedLiteLLMProvider.OpenRouter: "openai/",
|
|
SupportedLiteLLMProvider.StepFun: "openai/",
|
|
SupportedLiteLLMProvider.PPIO: "openai/",
|
|
SupportedLiteLLMProvider.PerfXCloud: "openai/",
|
|
SupportedLiteLLMProvider.Upstage: "openai/",
|
|
SupportedLiteLLMProvider.NovitaAI: "openai/",
|
|
SupportedLiteLLMProvider.Lingyi_AI: "openai/",
|
|
SupportedLiteLLMProvider.GiteeAI: "openai/",
|
|
SupportedLiteLLMProvider.AI_302: "openai/",
|
|
SupportedLiteLLMProvider.JiekouAI: "openai/",
|
|
SupportedLiteLLMProvider.ZHIPU_AI: "openai/",
|
|
SupportedLiteLLMProvider.MiniMax: "openai/",
|
|
SupportedLiteLLMProvider.DeerAPI: "openai/",
|
|
SupportedLiteLLMProvider.GPUStack: "openai/",
|
|
SupportedLiteLLMProvider.OpenAI: "openai/",
|
|
SupportedLiteLLMProvider.Azure_OpenAI: "azure/",
|
|
SupportedLiteLLMProvider.n1n: "openai/",
|
|
SupportedLiteLLMProvider.HunYuan: "openai/",
|
|
SupportedLiteLLMProvider.Avian: "openai/",
|
|
SupportedLiteLLMProvider.Astraflow: "openai/",
|
|
SupportedLiteLLMProvider.Astraflow_CN: "openai/",
|
|
SupportedLiteLLMProvider.FuturMix: "openai/",
|
|
}
|
|
|
|
ChatModel = globals().get("ChatModel", {})
|
|
CvModel = globals().get("CvModel", {})
|
|
EmbeddingModel = globals().get("EmbeddingModel", {})
|
|
RerankModel = globals().get("RerankModel", {})
|
|
Seq2txtModel = globals().get("Seq2txtModel", {})
|
|
TTSModel = globals().get("TTSModel", {})
|
|
OcrModel = globals().get("OcrModel", {})
|
|
|
|
|
|
MODULE_MAPPING = {
|
|
"chat_model": ChatModel,
|
|
"cv_model": CvModel,
|
|
"embedding_model": EmbeddingModel,
|
|
"rerank_model": RerankModel,
|
|
"sequence2txt_model": Seq2txtModel,
|
|
"tts_model": TTSModel,
|
|
"ocr_model": OcrModel,
|
|
}
|
|
|
|
package_name = __name__
|
|
|
|
for module_name, mapping_dict in MODULE_MAPPING.items():
|
|
full_module_name = f"{package_name}.{module_name}"
|
|
module = importlib.import_module(full_module_name)
|
|
|
|
base_class = None
|
|
lite_llm_base_class = None
|
|
for name, obj in inspect.getmembers(module):
|
|
if inspect.isclass(obj):
|
|
if name == "Base":
|
|
base_class = obj
|
|
elif name == "LiteLLMBase":
|
|
lite_llm_base_class = obj
|
|
assert hasattr(obj, "_FACTORY_NAME"), "LiteLLMbase should have _FACTORY_NAME field."
|
|
if hasattr(obj, "_FACTORY_NAME"):
|
|
if isinstance(obj._FACTORY_NAME, list):
|
|
for factory_name in obj._FACTORY_NAME:
|
|
mapping_dict[factory_name] = obj
|
|
else:
|
|
mapping_dict[obj._FACTORY_NAME] = obj
|
|
|
|
if base_class is not None:
|
|
for _, obj in inspect.getmembers(module):
|
|
if inspect.isclass(obj) and issubclass(obj, base_class) and obj is not base_class and hasattr(obj, "_FACTORY_NAME"):
|
|
if isinstance(obj._FACTORY_NAME, list):
|
|
for factory_name in obj._FACTORY_NAME:
|
|
mapping_dict[factory_name] = obj
|
|
else:
|
|
mapping_dict[obj._FACTORY_NAME] = obj
|
|
|
|
|
|
__all__ = [
|
|
"ChatModel",
|
|
"CvModel",
|
|
"EmbeddingModel",
|
|
"RerankModel",
|
|
"Seq2txtModel",
|
|
"TTSModel",
|
|
"OcrModel",
|
|
]
|