mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-10 05:14:48 +08:00
Feat: optional url v1 (#16774)
This commit is contained in:
@@ -2008,7 +2008,8 @@
|
||||
"max_tokens": 512,
|
||||
"model_type": "embedding"
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.baichuan-ai.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "Jina",
|
||||
@@ -2641,7 +2642,8 @@
|
||||
"model_type": "speech2text",
|
||||
"is_tools": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.stepfun.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "NVIDIA",
|
||||
@@ -3586,7 +3588,8 @@
|
||||
"max_tokens": 4000,
|
||||
"model_type": "embedding"
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.upstage.ai/v1/solar"
|
||||
},
|
||||
{
|
||||
"name": "NovitaAI",
|
||||
@@ -3713,7 +3716,8 @@
|
||||
"max_tokens": 8192,
|
||||
"model_type": "embedding"
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.novita.ai/v3/openai"
|
||||
},
|
||||
{
|
||||
"name": "SILICONFLOW",
|
||||
@@ -4840,7 +4844,8 @@
|
||||
"max_tokens": 32768,
|
||||
"model_type": "chat"
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.ppinfra.com/v3/openai"
|
||||
},
|
||||
{
|
||||
"name": "Replicate",
|
||||
@@ -5003,7 +5008,8 @@
|
||||
"thinking"
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://spark-api-open.xf-yun.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "BaiduYiyan",
|
||||
@@ -6199,7 +6205,8 @@
|
||||
"model_type": "rerank",
|
||||
"is_tools": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.302.ai/v1"
|
||||
},
|
||||
{
|
||||
"name": "CometAPI",
|
||||
@@ -6493,7 +6500,8 @@
|
||||
"model_type": "tts",
|
||||
"is_tools": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.cometapi.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "LongCat",
|
||||
@@ -6810,7 +6818,8 @@
|
||||
"model_type": "tts",
|
||||
"is_tools": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.deerapi.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "Jiekou.AI",
|
||||
@@ -7464,7 +7473,8 @@
|
||||
"max_tokens": 32768,
|
||||
"model_type": "rerank"
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.jiekou.ai/openai"
|
||||
},
|
||||
{
|
||||
"name": "MinerU",
|
||||
@@ -7996,14 +8006,16 @@
|
||||
"model_type": "chat",
|
||||
"is_tools": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"url": "https://api.avian.io/v1"
|
||||
},
|
||||
{
|
||||
"name": "RAGcon",
|
||||
"logo": "",
|
||||
"tags": "LLM,TEXT EMBEDDING,TTS,TEXT RE-RANK,SPEECH2TEXT,IMAGE2TEXT",
|
||||
"status": "1",
|
||||
"llm": []
|
||||
"llm": [],
|
||||
"url": "https://connect.ragcon.com/v1"
|
||||
},
|
||||
{
|
||||
"name": "Xiaomi",
|
||||
|
||||
@@ -38,6 +38,7 @@ from rag.llm import FACTORY_DEFAULT_BASE_URL, LITELLM_PROVIDER_PREFIX, Supported
|
||||
from rag.llm.key_utils import _normalize_replicate_key
|
||||
from rag.llm.tool_decorator import FunctionToolSession, is_tool
|
||||
from rag.nlp import is_chinese, is_english
|
||||
from rag.utils.url_utils import ensure_v1
|
||||
|
||||
|
||||
class LLMErrorCode(StrEnum):
|
||||
@@ -218,8 +219,9 @@ def _move_litellm_provider_body_fields(provider: SupportedLiteLLMProvider | str
|
||||
class Base(ABC):
|
||||
def __init__(self, key, model_name, base_url, **kwargs):
|
||||
timeout = int(os.environ.get("LLM_TIMEOUT_SECONDS", 600))
|
||||
self.client = OpenAI(api_key=key, base_url=base_url, timeout=timeout)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url, timeout=timeout)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url, timeout=timeout)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=self.base_url, timeout=timeout)
|
||||
self.model_name = model_name
|
||||
# Configure retry parameters
|
||||
self.max_retries = kwargs.get("max_retries", int(os.environ.get("LLM_MAX_RETRIES", 5)))
|
||||
@@ -783,7 +785,6 @@ class XinferenceChat(Base):
|
||||
def __init__(self, key=None, model_name="", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
super().__init__(key, model_name, base_url, **kwargs)
|
||||
|
||||
|
||||
@@ -793,7 +794,6 @@ class HuggingFaceChat(Base):
|
||||
def __init__(self, key=None, model_name="", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
super().__init__(key, model_name.split("___")[0], base_url, **kwargs)
|
||||
|
||||
|
||||
@@ -803,7 +803,6 @@ class ModelScopeChat(Base):
|
||||
def __init__(self, key=None, model_name="", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
super().__init__(key, model_name.split("___")[0], base_url, **kwargs)
|
||||
|
||||
|
||||
@@ -894,8 +893,7 @@ class LocalAIChat(Base):
|
||||
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
self.client = OpenAI(api_key="empty", base_url=base_url)
|
||||
self.client = OpenAI(api_key="empty", base_url=self.base_url)
|
||||
self.model_name = model_name.split("___")[0]
|
||||
|
||||
|
||||
@@ -1032,9 +1030,8 @@ class LmStudioChat(Base):
|
||||
def __init__(self, key, model_name, base_url, **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
super().__init__(key, model_name, base_url, **kwargs)
|
||||
self.client = OpenAI(api_key="lm-studio", base_url=base_url)
|
||||
self.client = OpenAI(api_key="lm-studio", base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ from openai.lib.azure import AzureOpenAI, AsyncAzureOpenAI
|
||||
from common.token_utils import num_tokens_from_string, total_token_count_from_response
|
||||
from rag.nlp import is_english
|
||||
from rag.prompts.generator import vision_llm_describe_prompt
|
||||
from rag.utils.url_utils import ensure_v1
|
||||
|
||||
|
||||
from common.misc_utils import thread_pool_exec
|
||||
@@ -267,9 +268,10 @@ class GptV4(Base):
|
||||
def __init__(self, key, model_name="gpt-4-vision-preview", lang="Chinese", base_url="https://api.openai.com/v1", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.openai.com/v1"
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.api_key = key
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
super().__init__(**kwargs)
|
||||
@@ -309,8 +311,9 @@ class AzureGptV4(GptV4):
|
||||
|
||||
def __init__(self, key, model_name, lang="Chinese", **kwargs):
|
||||
api_key, api_version = _resolve_azure_credentials(key)
|
||||
self.client = AzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version)
|
||||
self.async_client = AsyncAzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version)
|
||||
self.base_url = ensure_v1(kwargs["base_url"])
|
||||
self.client = AzureOpenAI(api_key=api_key, azure_endpoint=self.base_url, api_version=api_version)
|
||||
self.async_client = AsyncAzureOpenAI(api_key=api_key, azure_endpoint=self.base_url, api_version=api_version)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -551,8 +554,9 @@ class StepFunCV(GptV4):
|
||||
def __init__(self, key, model_name="step-1v-8k", lang="Chinese", base_url="https://api.stepfun.com/v1", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.stepfun.com/v1"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -572,9 +576,9 @@ class VolcEngineCV(GptV4):
|
||||
except JSONDecodeError:
|
||||
api_key = key
|
||||
llm_name = model_name
|
||||
|
||||
self.client = OpenAI(api_key=api_key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=api_key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=api_key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=api_key, base_url=self.base_url)
|
||||
self.model_name = llm_name
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -586,9 +590,9 @@ class LmStudioCV(GptV4):
|
||||
def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
self.client = OpenAI(api_key="lm-studio", base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key="lm-studio", base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key="lm-studio", base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key="lm-studio", base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -600,9 +604,9 @@ class OpenAI_APICV(GptV4):
|
||||
def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name.split("___")[0]
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -647,8 +651,9 @@ class OpenRouterCV(GptV4):
|
||||
except JSONDecodeError:
|
||||
api_key = key
|
||||
provider_order = ""
|
||||
self.client = OpenAI(api_key=api_key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=api_key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=api_key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=api_key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
Base.__init__(self, **kwargs)
|
||||
@@ -677,7 +682,7 @@ class LocalAICV(GptV4):
|
||||
def __init__(self, key, model_name, base_url, lang="Chinese", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local cv model url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key="empty", base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key="empty", base_url=base_url)
|
||||
self.model_name = model_name.split("___")[0]
|
||||
@@ -689,7 +694,7 @@ class XinferenceCV(GptV4):
|
||||
_FACTORY_NAME = "Xinference"
|
||||
|
||||
def __init__(self, key, model_name="", lang="Chinese", base_url="", **kwargs):
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.model_name = model_name
|
||||
@@ -703,7 +708,7 @@ class GPUStackCV(GptV4):
|
||||
def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.model_name = model_name
|
||||
@@ -727,7 +732,8 @@ class OllamaCV(Base):
|
||||
def __init__(self, key, model_name, lang="Chinese", **kwargs):
|
||||
from ollama import Client
|
||||
|
||||
self.client = Client(host=kwargs["base_url"])
|
||||
self.base_url = ensure_v1(kwargs["base_url"])
|
||||
self.client = Client(host=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
self.keep_alive = kwargs.get("ollama_keep_alive", int(os.environ.get("OLLAMA_KEEP_ALIVE", -1)))
|
||||
@@ -1359,8 +1365,9 @@ class RAGconCV(GptV4):
|
||||
base_url = "https://connect.ragcon.com/v1"
|
||||
|
||||
# Initialize client
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.async_client = AsyncOpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ from common import settings
|
||||
from common.exceptions import ModelException
|
||||
from common.token_utils import num_tokens_from_string, truncate, total_token_count_from_response
|
||||
from rag.llm.key_utils import _normalize_replicate_key
|
||||
from rag.utils.url_utils import ensure_v1
|
||||
import logging
|
||||
import base64
|
||||
|
||||
@@ -259,7 +260,8 @@ class OpenAIEmbed(Base):
|
||||
def __init__(self, key, model_name="text-embedding-ada-002", base_url="https://api.openai.com/v1"):
|
||||
if not base_url:
|
||||
base_url = "https://api.openai.com/v1"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
def _call(self, batch):
|
||||
@@ -281,7 +283,7 @@ class LocalAIEmbed(Base):
|
||||
def __init__(self, key, model_name, base_url):
|
||||
if not base_url:
|
||||
raise ValueError("Local embedding model url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key="empty", base_url=base_url)
|
||||
self.model_name = model_name.split("___")[0]
|
||||
|
||||
@@ -320,7 +322,9 @@ class AzureEmbed(OpenAIEmbed):
|
||||
from openai.lib.azure import AzureOpenAI
|
||||
|
||||
api_key, api_version = _resolve_azure_credentials(key)
|
||||
self.client = AzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version)
|
||||
self.base_url = ensure_v1(kwargs["base_url"])
|
||||
self.client = AzureOpenAI(api_key=api_key, azure_endpoint=self.base_url, api_version=api_version)
|
||||
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -465,7 +469,8 @@ class OllamaEmbed(Base):
|
||||
_special_tokens = ["<|endoftext|>"]
|
||||
|
||||
def __init__(self, key, model_name, **kwargs):
|
||||
self.client = Client(host=kwargs["base_url"]) if not key or key == "x" else Client(host=kwargs["base_url"], headers={"Authorization": f"Bearer {key}"})
|
||||
self.base_url = ensure_v1(kwargs["base_url"])
|
||||
self.client = Client(host=self.base_url) if not key or key == "x" else Client(host=self.base_url, headers={"Authorization": f"Bearer {key}"})
|
||||
self.model_name = model_name
|
||||
self.keep_alive = kwargs.get("ollama_keep_alive", int(os.environ.get("OLLAMA_KEEP_ALIVE", -1)))
|
||||
|
||||
@@ -502,7 +507,7 @@ class XinferenceEmbed(Base):
|
||||
_FACTORY_NAME = "Xinference"
|
||||
|
||||
def __init__(self, key, model_name="", base_url=""):
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
@@ -805,7 +810,7 @@ class NvidiaEmbed(Base):
|
||||
if not base_url:
|
||||
base_url = "https://integrate.api.nvidia.com/v1/embeddings"
|
||||
self.api_key = key
|
||||
self.base_url = base_url
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.headers = {
|
||||
"accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
@@ -844,7 +849,7 @@ class LmStudioEmbed(LocalAIEmbed):
|
||||
def __init__(self, key, model_name, base_url):
|
||||
if not base_url:
|
||||
raise ValueError("Local llm url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key="lm-studio", base_url=base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
@@ -855,7 +860,7 @@ class OpenAI_APIEmbed(OpenAIEmbed):
|
||||
def __init__(self, key, model_name, base_url):
|
||||
if not base_url:
|
||||
raise ValueError("url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.model_name = model_name.split("___")[0]
|
||||
|
||||
@@ -1147,7 +1152,7 @@ class GPUStackEmbed(OpenAIEmbed):
|
||||
def __init__(self, key, model_name, base_url):
|
||||
if not base_url:
|
||||
raise ValueError("url cannot be None")
|
||||
base_url = urljoin(base_url, "v1")
|
||||
base_url = ensure_v1(base_url)
|
||||
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
@@ -27,6 +27,7 @@ from openai import OpenAI
|
||||
from openai.lib.azure import AzureOpenAI
|
||||
|
||||
from common.token_utils import num_tokens_from_string
|
||||
from rag.utils.url_utils import ensure_v1
|
||||
|
||||
|
||||
class Base(ABC):
|
||||
@@ -56,7 +57,8 @@ class GPTSeq2txt(Base):
|
||||
def __init__(self, key, model_name="whisper-1", base_url="https://api.openai.com/v1", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.openai.com/v1"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -134,7 +136,8 @@ class AzureSeq2txt(Base):
|
||||
_FACTORY_NAME = "Azure-OpenAI"
|
||||
|
||||
def __init__(self, key, model_name, lang="Chinese", **kwargs):
|
||||
self.client = AzureOpenAI(api_key=key, azure_endpoint=kwargs["base_url"], api_version="2024-02-01")
|
||||
self.base_url = ensure_v1(kwargs["base_url"])
|
||||
self.client = AzureOpenAI(api_key=key, azure_endpoint=self.base_url, api_version="2024-02-01")
|
||||
self.model_name = model_name
|
||||
self.lang = lang
|
||||
|
||||
@@ -143,7 +146,7 @@ class XinferenceSeq2txt(Base):
|
||||
_FACTORY_NAME = "Xinference"
|
||||
|
||||
def __init__(self, key, model_name="whisper-small", **kwargs):
|
||||
self.base_url = kwargs.get("base_url", None)
|
||||
self.base_url = ensure_v1(kwargs["base_url"]) if kwargs.get("base_url") else None
|
||||
self.model_name = model_name
|
||||
self.key = key
|
||||
|
||||
@@ -256,7 +259,8 @@ class GiteeSeq2txt(Base):
|
||||
def __init__(self, key, model_name="whisper-1", base_url="https://ai.gitee.com/v1/", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://ai.gitee.com/v1/"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -266,8 +270,8 @@ class DeepInfraSeq2txt(Base):
|
||||
def __init__(self, key, model_name, base_url="https://api.deepinfra.com/v1/openai", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.deepinfra.com/v1/openai"
|
||||
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -277,7 +281,8 @@ class CometAPISeq2txt(Base):
|
||||
def __init__(self, key, model_name="whisper-1", base_url="https://api.cometapi.com/v1", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.cometapi.com/v1"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -287,7 +292,8 @@ class DeerAPISeq2txt(Base):
|
||||
def __init__(self, key, model_name="whisper-1", base_url="https://api.deerapi.com/v1", **kwargs):
|
||||
if not base_url:
|
||||
base_url = "https://api.deerapi.com/v1"
|
||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.client = OpenAI(api_key=key, base_url=self.base_url)
|
||||
self.model_name = model_name
|
||||
|
||||
|
||||
@@ -366,7 +372,7 @@ class RAGconSeq2txt(Base):
|
||||
if not base_url:
|
||||
base_url = "https://connect.ragcon.com/v1"
|
||||
|
||||
self.base_url = base_url
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.model_name = model_name
|
||||
self.key = key
|
||||
self.lang = lang
|
||||
|
||||
@@ -40,6 +40,7 @@ from pydantic import BaseModel, conint
|
||||
|
||||
from common.http_client import sync_request
|
||||
from common.token_utils import num_tokens_from_string
|
||||
from rag.utils.url_utils import ensure_v1
|
||||
|
||||
|
||||
class ServeReferenceAudio(BaseModel):
|
||||
@@ -88,7 +89,7 @@ class HTTPBasedTTS(Base):
|
||||
|
||||
def __init__(self, key, model_name, base_url, **kwargs):
|
||||
self.model_name = model_name
|
||||
self.base_url = base_url
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.api_key = key
|
||||
self.headers = {"Content-Type": "application/json"}
|
||||
if key and key != "x":
|
||||
@@ -504,7 +505,7 @@ class RAGconTTS(Base):
|
||||
if not base_url:
|
||||
base_url = "https://connect.ragcon.com/v1"
|
||||
|
||||
self.base_url = base_url
|
||||
self.base_url = ensure_v1(base_url)
|
||||
self.api_key = key
|
||||
self.model_name = model_name
|
||||
self.headers = {"accept": "application/json", "Content-Type": "application/json", "Authorization": f"Bearer {self.api_key}"}
|
||||
|
||||
50
rag/utils/url_utils.py
Normal file
50
rag/utils/url_utils.py
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
import re
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
|
||||
def ensure_v1(url: str) -> str:
|
||||
"""Ensure the URL ends with a versioned path segment like ``/v1``.
|
||||
|
||||
If the path already contains a segment matching ``v{digit}`` (e.g. ``/v1``,
|
||||
``/v2``, ``/v3``), the URL is returned unchanged. Otherwise the base host
|
||||
is kept and ``/v1`` is appended.
|
||||
|
||||
Examples::
|
||||
|
||||
>>> ensure_v1("https://api.example.com")
|
||||
'https://api.example.com/v1'
|
||||
>>> ensure_v1("https://api.example.com/v1")
|
||||
'https://api.example.com/v1'
|
||||
>>> ensure_v1("https://api.example.com/v2/chat")
|
||||
'https://api.example.com/v2/chat'
|
||||
>>> ensure_v1("https://api.example.com/api/v3")
|
||||
'https://api.example.com/api/v3'
|
||||
"""
|
||||
if not url:
|
||||
return url
|
||||
|
||||
parsed = urlparse(url)
|
||||
path = parsed.path.rstrip("/")
|
||||
|
||||
# Check if any path segment matches v{digit}, e.g. /v1, /v2, /v3
|
||||
if re.search(r"/v\d+(?:/|$)", path + "/"):
|
||||
return url
|
||||
|
||||
# No versioned segment found – append /v1
|
||||
new_path = (path + "/v1") if path else "/v1"
|
||||
return urlunparse((parsed.scheme, parsed.netloc, new_path, parsed.params, parsed.query, parsed.fragment))
|
||||
Reference in New Issue
Block a user