diff --git a/apps/locales/en_US/LC_MESSAGES/django.po b/apps/locales/en_US/LC_MESSAGES/django.po
index 7bfbe7b0222..9eebebaa08b 100644
--- a/apps/locales/en_US/LC_MESSAGES/django.po
+++ b/apps/locales/en_US/LC_MESSAGES/django.po
@@ -9434,4 +9434,92 @@ msgstr ""
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:76
msgid "Tokenhub sync_transcribe endpoint"
-msgstr ""
\ No newline at end of file
+msgstr ""
+
+
+msgid "Add logo"
+msgstr "Add logo"
+
+msgid "Custom watermark content, at most 16 characters, drawn in the bottom-right."
+msgstr "Custom watermark content, at most 16 characters, drawn in the bottom-right."
+
+msgid "Designed for Agent workloads, using a MoE architecture that supports interleaved thinking, structured output, Function Calling and Cache caching."
+msgstr "Designed for Agent workloads, using a MoE architecture that supports interleaved thinking, structured output, Function Calling and Cache caching."
+
+msgid "Frame rate"
+msgstr "Frame rate"
+
+msgid "Hunyuan HY-Video 1.5 image-to-video model."
+msgstr "Hunyuan HY-Video 1.5 image-to-video model."
+
+msgid "Hunyuan HY-Video 1.5 text-to-video model."
+msgstr "Hunyuan HY-Video 1.5 text-to-video model."
+
+msgid "Hunyuan Hy-Image 3.0 text-to-image model."
+msgstr "Hunyuan Hy-Image 3.0 text-to-image model."
+
+msgid "Hunyuan's latest role-playing model based on the Hunyuan model with role-playing scene fine-tuning."
+msgstr "Hunyuan's latest role-playing model based on the Hunyuan model with role-playing scene fine-tuning."
+
+msgid "Hunyuan's role-playing model with better basic effects in role-playing scenarios."
+msgstr "Hunyuan's role-playing model with better basic effects in role-playing scenarios."
+
+msgid "Output video frame rate: 16, 24, 30."
+msgstr "Output video frame rate: 16, 24, 30."
+
+msgid "Output video resolution: 480p, 720p, 1080p."
+msgstr "Output video resolution: 480p, 720p, 1080p."
+
+msgid "Prompt rewrite"
+msgstr "Prompt rewrite"
+
+msgid "Tencent Hybrid multilingual translation model."
+msgstr "Tencent Hybrid multilingual translation model."
+
+msgid "Tencent TokenHub multimodal embedding model, 2048 dimensions."
+msgstr "Tencent TokenHub multimodal embedding model, 2048 dimensions."
+
+msgid "Tencent TokenHub multimodal embedding model, 4096 dimensions."
+msgstr "Tencent TokenHub multimodal embedding model, 4096 dimensions."
+
+msgid "Tencent TokenHub text embedding model, 1024 dimensions."
+msgstr "Tencent TokenHub text embedding model, 1024 dimensions."
+
+msgid "Tencent TokenHub text embedding model, 2560 dimensions."
+msgstr "Tencent TokenHub text embedding model, 2560 dimensions."
+
+msgid "Tencent YT-Video 2.0 image-to-video model."
+msgstr "Tencent YT-Video 2.0 image-to-video model."
+
+msgid "The latest generation productivity model with upgraded Agent and complex task execution capabilities."
+msgstr "The latest generation productivity model with upgraded Agent and complex task execution capabilities."
+
+msgid "TokenHub Hy-Image v3-generation endpoint"
+msgstr "TokenHub Hy-Image v3-generation endpoint"
+
+msgid "TokenHub OpenAI compatible embeddings endpoint"
+msgstr "TokenHub OpenAI compatible embeddings endpoint"
+
+msgid "TokenHub OpenAI compatible endpoint"
+msgstr "TokenHub OpenAI compatible endpoint"
+
+msgid "TokenHub video endpoint. Use the base (e.g. https://tokenhub.tencentmaas.com/v1) or a full submit/query URL."
+msgstr "TokenHub video endpoint. Use the base (e.g. https://tokenhub.tencentmaas.com/v1) or a full submit/query URL."
+
+msgid "Tuned on real business scenarios, balancing effectiveness and cost-effectiveness, with reinforced Coding, long-text, reasoning and Agent capabilities."
+msgstr "Tuned on real business scenarios, balancing effectiveness and cost-effectiveness, with reinforced Coding, long-text, reasoning and Agent capabilities."
+
+msgid "Watermark footnote"
+msgstr "Watermark footnote"
+
+msgid "Whether the model should rewrite and optimize the prompt before generation."
+msgstr "Whether the model should rewrite and optimize the prompt before generation."
+
+msgid "Whether to add the AI-generated logo to the video. 1: add logo; 0: no logo (requires console approval for independent control)."
+msgstr "Whether to add the AI-generated logo to the video. 1: add logo; 0: no logo (requires console approval for independent control)."
+
+msgid "Width and height must be in [512, 2048] and the area must not exceed 1024x1024. If not passed, the model auto-selects the closest preset size."
+msgstr "Width and height must be in [512, 2048] and the area must not exceed 1024x1024. If not passed, the model auto-selects the closest preset size."
+
+msgid "api_key is required"
+msgstr "api_key is required"
\ No newline at end of file
diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po
index 854ba48d6d2..ff4bfeb6a8f 100644
--- a/apps/locales/zh_CN/LC_MESSAGES/django.po
+++ b/apps/locales/zh_CN/LC_MESSAGES/django.po
@@ -9559,3 +9559,117 @@ msgstr "自动"
msgid "Tokenhub sync_transcribe endpoint"
msgstr "Tokenhub 同步转写接口地址"
+msgid "Add logo"
+msgstr "添加标识"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Custom watermark content, at most 16 characters, drawn in the bottom-right."
+msgstr "自定义水印内容,最多16个字符,绘制在右下角。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Designed for Agent workloads, using a MoE architecture that supports interleaved thinking, structured output, Function Calling and Cache caching."
+msgstr "专为 Agent 场景设计,采用 MoE 架构,支持交织思考、结构化输出、Function Calling 和 Cache 缓存。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Frame rate"
+msgstr "帧率"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan HY-Video 1.5 image-to-video model."
+msgstr "混元 HY-Video 1.5 图生视频模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan HY-Video 1.5 text-to-video model."
+msgstr "混元 HY-Video 1.5 文生视频模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan Hy-Image 3.0 text-to-image model."
+msgstr "混元 Hy-Image 3.0 文生图模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan's latest role-playing model based on the Hunyuan model with role-playing scene fine-tuning."
+msgstr "基于混元模型并在角色扮演场景微调的最新角色扮演模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan's role-playing model with better basic effects in role-playing scenarios."
+msgstr "在角色扮演场景中基础效果更优的混元角色扮演模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Output video frame rate: 16, 24, 30."
+msgstr "输出视频帧率:16、24、30。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Output video resolution: 480p, 720p, 1080p."
+msgstr "输出视频分辨率:480p、720p、1080p。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Prompt rewrite"
+msgstr "提示词改写"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent Hybrid multilingual translation model."
+msgstr "腾讯混元多语言翻译模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub multimodal embedding model, 2048 dimensions."
+msgstr "腾讯 TokenHub 多模态向量模型,2048 维。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub multimodal embedding model, 4096 dimensions."
+msgstr "腾讯 TokenHub 多模态向量模型,4096 维。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub text embedding model, 1024 dimensions."
+msgstr "腾讯 TokenHub 文本向量模型,1024 维。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub text embedding model, 2560 dimensions."
+msgstr "腾讯 TokenHub 文本向量模型,2560 维。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent YT-Video 2.0 image-to-video model."
+msgstr "腾讯 YT-Video 2.0 图生视频模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "The latest generation productivity model with upgraded Agent and complex task execution capabilities."
+msgstr "采用全新一代生产力模型,升级了 Agent 与复杂任务执行能力。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "TokenHub Hy-Image v3-generation endpoint"
+msgstr "TokenHub Hy-Image v3-generation 接口"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/embedding.py
+msgid "TokenHub OpenAI compatible embeddings endpoint"
+msgstr "TokenHub OpenAI 兼容向量接口"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/llm.py
+msgid "TokenHub OpenAI compatible endpoint"
+msgstr "TokenHub OpenAI 兼容接口"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "TokenHub video endpoint. Use the base (e.g. https://tokenhub.tencentmaas.com/v1) or a full submit/query URL."
+msgstr "TokenHub 视频接口。可使用根地址(如 https://tokenhub.tencentmaas.com/v1)或完整的 submit/query 地址。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tuned on real business scenarios, balancing effectiveness and cost-effectiveness, with reinforced Coding, long-text, reasoning and Agent capabilities."
+msgstr "针对真实业务场景调优,兼顾效果与成本,强化了 Coding、长文本、推理和 Agent 能力。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Watermark footnote"
+msgstr "水印角标"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Whether the model should rewrite and optimize the prompt before generation."
+msgstr "模型是否在生成前改写并优化提示词。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Whether to add the AI-generated logo to the video. 1: add logo; 0: no logo (requires console approval for independent control)."
+msgstr "是否为生成视频添加 AI 标识。1:添加标识;0:不添加标识(需在控制台申请开启独立控制)。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Width and height must be in [512, 2048] and the area must not exceed 1024x1024. If not passed, the model auto-selects the closest preset size."
+msgstr "宽和高必须在 [512, 2048] 之间,且面积不得超过 1024x1024。不传时由模型自动选择最接近的预设尺寸。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/embedding.py
+msgid "api_key is required"
+msgstr "api_key 必填"
\ No newline at end of file
diff --git a/apps/locales/zh_Hant/LC_MESSAGES/django.po b/apps/locales/zh_Hant/LC_MESSAGES/django.po
index 0d3560db467..3d69eeaa926 100644
--- a/apps/locales/zh_Hant/LC_MESSAGES/django.po
+++ b/apps/locales/zh_Hant/LC_MESSAGES/django.po
@@ -9559,3 +9559,117 @@ msgstr "自動"
msgid "Tokenhub sync_transcribe endpoint"
msgstr "Tokenhub 同步轉寫接口地址"
+msgid "Add logo"
+msgstr "加入標示"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Custom watermark content, at most 16 characters, drawn in the bottom-right."
+msgstr "自訂浮水印內容,最多16個字元,繪製在右下角。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Designed for Agent workloads, using a MoE architecture that supports interleaved thinking, structured output, Function Calling and Cache caching."
+msgstr "專為 Agent 場景設計,採用 MoE 架構,支援交織思考、結構化輸出、Function Calling 與 Cache 快取。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Frame rate"
+msgstr "幀率"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan HY-Video 1.5 image-to-video model."
+msgstr "混元 HY-Video 1.5 圖生影片模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan HY-Video 1.5 text-to-video model."
+msgstr "混元 HY-Video 1.5 文生影片模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan Hy-Image 3.0 text-to-image model."
+msgstr "混元 Hy-Image 3.0 文生圖模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan's latest role-playing model based on the Hunyuan model with role-playing scene fine-tuning."
+msgstr "基於混元模型並在角色扮演場景微調的最新角色扮演模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Hunyuan's role-playing model with better basic effects in role-playing scenarios."
+msgstr "在角色扮演場景中基礎效果更優的混元角色扮演模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Output video frame rate: 16, 24, 30."
+msgstr "輸出影片幀率:16、24、30。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Output video resolution: 480p, 720p, 1080p."
+msgstr "輸出影片解析度:480p、720p、1080p。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Prompt rewrite"
+msgstr "提示詞改寫"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent Hybrid multilingual translation model."
+msgstr "騰訊混元多語言翻譯模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub multimodal embedding model, 2048 dimensions."
+msgstr "騰訊 TokenHub 多模態向量模型,2048 維。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub multimodal embedding model, 4096 dimensions."
+msgstr "騰訊 TokenHub 多模態向量模型,4096 維。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub text embedding model, 1024 dimensions."
+msgstr "騰訊 TokenHub 文字向量模型,1024 維。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent TokenHub text embedding model, 2560 dimensions."
+msgstr "騰訊 TokenHub 文字向量模型,2560 維。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tencent YT-Video 2.0 image-to-video model."
+msgstr "騰訊 YT-Video 2.0 圖生影片模型。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "The latest generation productivity model with upgraded Agent and complex task execution capabilities."
+msgstr "採用全新一代生產力模型,升級了 Agent 與複雜任務執行能力。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "TokenHub Hy-Image v3-generation endpoint"
+msgstr "TokenHub Hy-Image v3-generation 介面"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/embedding.py
+msgid "TokenHub OpenAI compatible embeddings endpoint"
+msgstr "TokenHub OpenAI 相容向量介面"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/llm.py
+msgid "TokenHub OpenAI compatible endpoint"
+msgstr "TokenHub OpenAI 相容介面"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "TokenHub video endpoint. Use the base (e.g. https://tokenhub.tencentmaas.com/v1) or a full submit/query URL."
+msgstr "TokenHub 影片介面。可使用根位址(如 https://tokenhub.tencentmaas.com/v1)或完整的 submit/query 位址。"
+
+#: apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+msgid "Tuned on real business scenarios, balancing effectiveness and cost-effectiveness, with reinforced Coding, long-text, reasoning and Agent capabilities."
+msgstr "針對真實業務場景調優,兼顧效果與成本,強化了 Coding、長文本、推理和 Agent 能力。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Watermark footnote"
+msgstr "浮水印角標"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Whether the model should rewrite and optimize the prompt before generation."
+msgstr "模型是否在生成前改寫並最佳化提示詞。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/ttv.py
+msgid "Whether to add the AI-generated logo to the video. 1: add logo; 0: no logo (requires console approval for independent control)."
+msgstr "是否為生成影片加入 AI 標示。1:加入標示;0:不加入標示(需在控制台申請開啟獨立控制)。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/tti.py
+msgid "Width and height must be in [512, 2048] and the area must not exceed 1024x1024. If not passed, the model auto-selects the closest preset size."
+msgstr "寬和高必須在 [512, 2048] 之間,且面積不得超過 1024x1024。未傳時由模型自動選擇最接近的預設尺寸。"
+
+#: apps/models_provider/impl/tencent_model_provider/credential/embedding.py
+msgid "api_key is required"
+msgstr "api_key 必填"
\ No newline at end of file
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/__init__.py b/apps/models_provider/impl/tencent_cloud_model_provider/__init__.py
deleted file mode 100644
index 2dc4ab10db4..00000000000
--- a/apps/models_provider/impl/tencent_cloud_model_provider/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# coding=utf-8
-"""
- @project: maxkb
- @Author:虎
- @file: __init__.py.py
- @date:2024/3/28 16:25
- @desc:
-"""
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/credential/__init__.py b/apps/models_provider/impl/tencent_cloud_model_provider/credential/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/credential/llm.py b/apps/models_provider/impl/tencent_cloud_model_provider/credential/llm.py
deleted file mode 100644
index 1da026f99c8..00000000000
--- a/apps/models_provider/impl/tencent_cloud_model_provider/credential/llm.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# coding=utf-8
-"""
- @project: MaxKB
- @Author:虎
- @file: llm.py
- @date:2024/7/11 18:32
- @desc:
-"""
-from typing import Dict
-
-from django.utils.translation import gettext_lazy as _, gettext
-from langchain_core.messages import HumanMessage
-
-from common import forms
-from common.exception.app_exception import AppApiException
-from common.forms import BaseForm, TooltipLabel
-from models_provider.base_model_provider import BaseModelCredential, ValidCode
-from common.utils.logger import maxkb_logger
-
-class TencentCloudLLMModelParams(BaseForm):
- temperature = forms.SliderField(TooltipLabel(_('Temperature'),
- _('Higher values make the output more random, while lower values make it more focused and deterministic')),
- required=True, default_value=0.7,
- _min=0.1,
- _max=1.0,
- _step=0.01,
- precision=2)
-
- max_tokens = forms.SliderField(
- TooltipLabel(_('Output the maximum Tokens'),
- _('Specify the maximum number of tokens that the model can generate')),
- required=True, default_value=8192,
- _min=1,
- _max=100000,
- _step=1,
- precision=0)
-
-
-class TencentCloudLLMModelCredential(BaseForm, BaseModelCredential):
-
- def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
- raise_exception=False):
- model_type_list = provider.get_model_type_list()
- if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{model_type} Model type is not supported').format(model_type=model_type))
-
- for key in ['api_base', 'api_key']:
- if key not in model_credential:
- if raise_exception:
- raise AppApiException(ValidCode.valid_error.value, gettext('{key} is required').format(key=key))
- else:
- return False
- try:
-
- model = provider.get_model(model_type, model_name, model_credential, **model_params)
- model.invoke([HumanMessage(content=gettext('Hello'))])
- except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
- if isinstance(e, AppApiException):
- raise e
- if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext(
- 'Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
- else:
- return False
- return True
-
- def encryption_dict(self, model: Dict[str, object]):
- return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
-
- api_base = forms.TextInputField('API URL', required=True)
- api_key = forms.PasswordInputField('API Key', required=True)
-
- def get_model_params_setting_form(self, model_name):
- return TencentCloudLLMModelParams()
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/icon/__init__.py b/apps/models_provider/impl/tencent_cloud_model_provider/icon/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/icon/tencent_cloud_icon_svg b/apps/models_provider/impl/tencent_cloud_model_provider/icon/tencent_cloud_icon_svg
deleted file mode 100644
index ff559eaff44..00000000000
--- a/apps/models_provider/impl/tencent_cloud_model_provider/icon/tencent_cloud_icon_svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/model/__init__.py b/apps/models_provider/impl/tencent_cloud_model_provider/model/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/model/llm.py b/apps/models_provider/impl/tencent_cloud_model_provider/model/llm.py
deleted file mode 100644
index 101fbba50e9..00000000000
--- a/apps/models_provider/impl/tencent_cloud_model_provider/model/llm.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# coding=utf-8
-"""
- @project: maxkb
- @Author:虎
- @file: llm.py
- @date:2024/4/18 15:28
- @desc:
-"""
-from typing import Dict
-
-from common.config.tokenizer_manage_config import TokenizerManage
-from models_provider.base_model_provider import MaxKBBaseModel
-from models_provider.impl.base_chat_open_ai import BaseChatOpenAI
-
-
-def custom_get_token_ids(text: str):
- tokenizer = TokenizerManage.get_tokenizer()
- return tokenizer.encode(text)
-
-
-class TencentCloudChatModel(MaxKBBaseModel, BaseChatOpenAI):
-
- @staticmethod
- def is_cache_model():
- return False
-
- @staticmethod
- def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
- optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
- azure_chat_open_ai = TencentCloudChatModel(
- model=model_name,
- openai_api_base=model_credential.get('api_base'),
- openai_api_key=model_credential.get('api_key'),
- custom_get_token_ids=custom_get_token_ids,
- **optional_params,
- )
- return azure_chat_open_ai
-
diff --git a/apps/models_provider/impl/tencent_cloud_model_provider/tencent_cloud_model_provider.py b/apps/models_provider/impl/tencent_cloud_model_provider/tencent_cloud_model_provider.py
deleted file mode 100644
index 3a6bd9c2041..00000000000
--- a/apps/models_provider/impl/tencent_cloud_model_provider/tencent_cloud_model_provider.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# coding=utf-8
-"""
- @project: maxkb
- @Author:虎
- @file: openai_model_provider.py
- @date:2024/3/28 16:26
- @desc:
-"""
-import os
-
-from common.utils.common import get_file_content
-from models_provider.base_model_provider import IModelProvider, ModelProvideInfo, ModelInfo, \
- ModelTypeConst, ModelInfoManage
-from models_provider.impl.openai_model_provider.credential.embedding import OpenAIEmbeddingCredential
-from models_provider.impl.openai_model_provider.credential.image import OpenAIImageModelCredential
-from models_provider.impl.openai_model_provider.credential.llm import OpenAILLMModelCredential
-from models_provider.impl.openai_model_provider.credential.stt import OpenAISTTModelCredential
-from models_provider.impl.openai_model_provider.credential.tti import OpenAITextToImageModelCredential
-from models_provider.impl.openai_model_provider.credential.tts import OpenAITTSModelCredential
-from models_provider.impl.openai_model_provider.model.embedding import OpenAIEmbeddingModel
-from models_provider.impl.openai_model_provider.model.image import OpenAIImage
-from models_provider.impl.openai_model_provider.model.llm import OpenAIChatModel
-from models_provider.impl.openai_model_provider.model.stt import OpenAISpeechToText
-from models_provider.impl.openai_model_provider.model.tti import OpenAITextToImage
-from models_provider.impl.openai_model_provider.model.tts import OpenAITextToSpeech
-from models_provider.impl.tencent_cloud_model_provider.credential.llm import TencentCloudLLMModelCredential
-from models_provider.impl.tencent_cloud_model_provider.model.llm import TencentCloudChatModel
-from maxkb.conf import PROJECT_DIR
-from django.utils.translation import gettext_lazy as _
-
-openai_llm_model_credential = TencentCloudLLMModelCredential()
-model_info_list = [
- ModelInfo('deepseek-v3', '', ModelTypeConst.LLM,
- openai_llm_model_credential, TencentCloudChatModel
- ),
- ModelInfo('deepseek-r1', '', ModelTypeConst.LLM,
- openai_llm_model_credential, TencentCloudChatModel
- ),
-]
-
-model_info_manage = (
- ModelInfoManage.builder()
- .append_model_info_list(model_info_list)
- .append_default_model_info(
- ModelInfo('deepseek-v3', '', ModelTypeConst.LLM,
- openai_llm_model_credential, TencentCloudChatModel
- ))
- .build()
-)
-
-
-class TencentCloudModelProvider(IModelProvider):
-
- def get_model_info_manage(self):
- return model_info_manage
-
- def get_model_provide_info(self):
- return ModelProvideInfo(provider='model_tencent_cloud_provider', name=_('Tencent Cloud'), icon=get_file_content(
- os.path.join(PROJECT_DIR, "apps", 'models_provider', 'impl', 'tencent_cloud_model_provider',
- 'icon',
- 'tencent_cloud_icon_svg')))
diff --git a/apps/models_provider/impl/tencent_model_provider/credential/embedding.py b/apps/models_provider/impl/tencent_model_provider/credential/embedding.py
index 4f31cc11066..b71630af869 100644
--- a/apps/models_provider/impl/tencent_model_provider/credential/embedding.py
+++ b/apps/models_provider/impl/tencent_model_provider/credential/embedding.py
@@ -1,40 +1,55 @@
+# coding=utf-8
+
from typing import Dict
from django.utils.translation import gettext as _
from common import forms
from common.exception.app_exception import AppApiException
-from common.forms import BaseForm
+from common.forms import BaseForm, TooltipLabel
from models_provider.base_model_provider import BaseModelCredential, ValidCode
from common.utils.logger import maxkb_logger
-class TencentEmbeddingCredential(BaseForm, BaseModelCredential):
- def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
- raise_exception=True) -> bool:
+class TencentEmbeddingCredential(BaseForm, BaseModelCredential):
+ def is_valid(
+ self, model_type, model_name, model_credential: Dict[str, object], model_params, provider, raise_exception=True
+ ):
model_type_list = provider.get_model_type_list()
- if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
- raise AppApiException(ValidCode.valid_error.value,
- _('{model_type} Model type is not supported').format(model_type=model_type))
- self.valid_form(model_credential)
+ if not any(mt.get("value") == model_type for mt in model_type_list):
+ raise AppApiException(
+ ValidCode.valid_error.value, _("{model_type} Model type is not supported").format(model_type=model_type)
+ )
+
+ if "api_key" not in model_credential:
+ if raise_exception:
+ raise AppApiException(ValidCode.valid_error.value, _("api_key is required"))
+ return False
+
try:
model = provider.get_model(model_type, model_name, model_credential)
- model.embed_query(_('Hello'))
+ model.embed_query(_("Hello"))
except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
+ maxkb_logger.error(f"Exception: {e}", exc_info=True)
if isinstance(e, AppApiException):
raise e
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- _('Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ _("Verification failed, please check whether the parameters are correct: {error}").format(
+ error=str(e)
+ ),
+ )
else:
return False
return True
- def encryption_dict(self, model: Dict[str, object]) -> Dict[str, object]:
- encrypted_secret_key = super().encryption(model.get('SecretKey', ''))
- return {**model, 'SecretKey': encrypted_secret_key}
+ def encryption_dict(self, model: Dict[str, object]):
+ return {**model, "api_key": super().encryption(model.get("api_key", ""))}
- SecretId = forms.PasswordInputField('SecretId', required=True)
- SecretKey = forms.PasswordInputField('SecretKey', required=True)
+ base_url = forms.TextInputField(
+ label=TooltipLabel(_("API URL"), _("TokenHub OpenAI compatible embeddings endpoint")),
+ required=False,
+ default_value="https://tokenhub.tencentmaas.com/v1",
+ )
+ api_key = forms.PasswordInputField(_("API Key"), required=True)
diff --git a/apps/models_provider/impl/tencent_model_provider/credential/image.py b/apps/models_provider/impl/tencent_model_provider/credential/image.py
index 746d0dc1d8e..1ca90803a4b 100644
--- a/apps/models_provider/impl/tencent_model_provider/credential/image.py
+++ b/apps/models_provider/impl/tencent_model_provider/credential/image.py
@@ -1,11 +1,12 @@
# coding=utf-8
"""
- @project: MaxKB
- @Author:虎
- @file: llm.py
- @date:2024/7/11 18:41
- @desc:
+@project: MaxKB
+@Author:虎
+@file: llm.py
+@date:2024/7/11 18:41
+@desc:
"""
+
from typing import Dict
from django.utils.translation import gettext_lazy as _, gettext
@@ -19,61 +20,79 @@
class TencentModelParams(BaseForm):
- temperature = forms.SliderField(TooltipLabel(_('Temperature'),
- _('Higher values make the output more random, while lower values make it more focused and deterministic')),
- required=True, default_value=1.0,
- _min=0.1,
- _max=1.9,
- _step=0.01,
- precision=2)
+ temperature = forms.SliderField(
+ TooltipLabel(
+ _("Temperature"),
+ _("Higher values make the output more random, while lower values make it more focused and deterministic"),
+ ),
+ required=True,
+ default_value=1.0,
+ _min=0.1,
+ _max=1.9,
+ _step=0.01,
+ precision=2,
+ )
max_tokens = forms.SliderField(
- TooltipLabel(_('Output the maximum Tokens'),
- _('Specify the maximum number of tokens that the model can generate')),
- required=True, default_value=8192,
+ TooltipLabel(
+ _("Output the maximum Tokens"), _("Specify the maximum number of tokens that the model can generate")
+ ),
+ required=True,
+ default_value=8192,
_min=1,
_max=100000,
_step=1,
- precision=0)
+ precision=0,
+ )
class TencentVisionModelCredential(BaseForm, BaseModelCredential):
-
- def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
- raise_exception=False):
+ def is_valid(
+ self,
+ model_type: str,
+ model_name,
+ model_credential: Dict[str, object],
+ model_params,
+ provider,
+ raise_exception=False,
+ ):
model_type_list = provider.get_model_type_list()
- if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{model_type} Model type is not supported').format(model_type=model_type))
- for key in ['api_key', 'api_base']:
+ if not any(list(filter(lambda mt: mt.get("value") == model_type, model_type_list))):
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("{model_type} Model type is not supported").format(model_type=model_type),
+ )
+ for key in ["api_key", "api_base"]:
if key not in model_credential:
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value, gettext('{key} is required').format(key=key))
+ raise AppApiException(ValidCode.valid_error.value, gettext("{key} is required").format(key=key))
else:
return False
try:
model = provider.get_model(model_type, model_name, model_credential, **model_params)
- res = model.stream([HumanMessage(content=[{"type": "text", "text": gettext('Hello')}])])
+ res = model.stream([HumanMessage(content=[{"type": "text", "text": gettext("Hello")}])])
for chunk in res:
maxkb_logger.info(chunk)
except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
+ maxkb_logger.error(f"Exception: {e}", exc_info=True)
if isinstance(e, AppApiException):
raise e
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext(
- 'Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("Verification failed, please check whether the parameters are correct: {error}").format(
+ error=str(e)
+ ),
+ )
else:
return False
return True
def encryption_dict(self, model: Dict[str, object]):
- return {**model, 'api_key': super().encryption(model.get('api_key', ''))}
+ return {**model, "api_key": super().encryption(model.get("api_key", ""))}
- api_base = forms.TextInputField('API URL', required=True, default_value='https://api.hunyuan.cloud.tencent.com/v1')
- api_key = forms.PasswordInputField('API Key', required=True)
+ api_base = forms.TextInputField("API URL", required=True, default_value="https://tokenhub.tencentmaas.com/v1")
+ api_key = forms.PasswordInputField("API Key", required=True)
def get_model_params_setting_form(self, model_name):
return TencentModelParams()
diff --git a/apps/models_provider/impl/tencent_model_provider/credential/llm.py b/apps/models_provider/impl/tencent_model_provider/credential/llm.py
index b4d254ee020..931105203e0 100644
--- a/apps/models_provider/impl/tencent_model_provider/credential/llm.py
+++ b/apps/models_provider/impl/tencent_model_provider/credential/llm.py
@@ -1,5 +1,7 @@
# coding=utf-8
+from typing import Dict
+
from django.utils.translation import gettext_lazy as _, gettext
from langchain_core.messages import HumanMessage
@@ -9,61 +11,84 @@
from models_provider.base_model_provider import BaseModelCredential, ValidCode
from common.utils.logger import maxkb_logger
+
class TencentLLMModelParams(BaseForm):
- temperature = forms.SliderField(TooltipLabel(_('Temperature'),
- _('Higher values make the output more random, while lower values make it more focused and deterministic')),
- required=True, default_value=0.5,
- _min=0.1,
- _max=2.0,
- _step=0.01,
- precision=2)
+ temperature = forms.SliderField(
+ TooltipLabel(
+ _("Temperature"),
+ _("Higher values make the output more random, while lower values make it more focused and deterministic"),
+ ),
+ required=True,
+ default_value=0.5,
+ _min=0.1,
+ _max=2.0,
+ _step=0.01,
+ precision=2,
+ )
+ max_tokens = forms.SliderField(
+ TooltipLabel(
+ _("Output the maximum Tokens"), _("Specify the maximum number of tokens that the model can generate")
+ ),
+ required=True,
+ default_value=8192,
+ _min=1,
+ _max=100000,
+ _step=1,
+ precision=0,
+ )
-class TencentLLMModelCredential(BaseForm, BaseModelCredential):
- REQUIRED_FIELDS = ['hunyuan_app_id', 'hunyuan_secret_id', 'hunyuan_secret_key']
- @classmethod
- def _validate_model_type(cls, model_type, provider, raise_exception=False):
- if not any(mt['value'] == model_type for mt in provider.get_model_type_list()):
- if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{model_type} Model type is not supported').format(model_type=model_type))
- return False
- return True
-
- @classmethod
- def _validate_credential_fields(cls, model_credential, raise_exception=False):
- missing_keys = [key for key in cls.REQUIRED_FIELDS if key not in model_credential]
- if missing_keys:
- if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{keys} is required').format(keys=", ".join(missing_keys)))
- return False
- return True
+class TencentLLMModelCredential(BaseForm, BaseModelCredential):
+ def is_valid(
+ self,
+ model_type: str,
+ model_name,
+ model_credential: Dict[str, object],
+ model_params,
+ provider,
+ raise_exception=False,
+ ):
+ model_type_list = provider.get_model_type_list()
+ if not any(list(filter(lambda mt: mt.get("value") == model_type, model_type_list))):
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("{model_type} Model type is not supported").format(model_type=model_type),
+ )
- def is_valid(self, model_type, model_name, model_credential, model_params, provider, raise_exception=False):
- if not (self._validate_model_type(model_type, provider, raise_exception) and
- self._validate_credential_fields(model_credential, raise_exception)):
- return False
+ for key in ["api_base", "api_key"]:
+ if key not in model_credential:
+ if raise_exception:
+ raise AppApiException(ValidCode.valid_error.value, gettext("{key} is required").format(key=key))
+ else:
+ return False
try:
model = provider.get_model(model_type, model_name, model_credential, **model_params)
- model.invoke([HumanMessage(content=gettext('Hello'))])
+ model.invoke([HumanMessage(content=gettext("Hello"))])
except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
+ maxkb_logger.error(f"Exception: {e}", exc_info=True)
+ if isinstance(e, AppApiException):
+ raise e
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext(
- 'Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
- return False
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("Verification failed, please check whether the parameters are correct: {error}").format(
+ error=str(e)
+ ),
+ )
+ else:
+ return False
return True
- def encryption_dict(self, model):
- return {**model, 'hunyuan_secret_key': super().encryption(model.get('hunyuan_secret_key', ''))}
+ def encryption_dict(self, model: Dict[str, object]):
+ return {**model, "api_key": super().encryption(model.get("api_key", ""))}
- hunyuan_app_id = forms.TextInputField('APP ID', required=True)
- hunyuan_secret_id = forms.PasswordInputField('SecretId', required=True)
- hunyuan_secret_key = forms.PasswordInputField('SecretKey', required=True)
+ api_base = forms.TextInputField(
+ label=TooltipLabel(_("API URL"), _("TokenHub OpenAI compatible endpoint")),
+ required=True,
+ default_value="https://tokenhub.tencentmaas.com/v1",
+ )
+ api_key = forms.PasswordInputField(_("API Key"), required=True)
def get_model_params_setting_form(self, model_name):
return TencentLLMModelParams()
diff --git a/apps/models_provider/impl/tencent_model_provider/credential/stt.py b/apps/models_provider/impl/tencent_model_provider/credential/stt.py
index a03684cb40d..9e667eedc36 100644
--- a/apps/models_provider/impl/tencent_model_provider/credential/stt.py
+++ b/apps/models_provider/impl/tencent_model_provider/credential/stt.py
@@ -1,4 +1,3 @@
-
from common import forms
from common.exception.app_exception import AppApiException
from common.forms import BaseForm, TooltipLabel
@@ -7,11 +6,12 @@
from models_provider.base_model_provider import BaseModelCredential, ValidCode
from common.utils.logger import maxkb_logger
+
class TencentSSTModelParams(BaseForm):
EngSerViceType = forms.SingleSelect(
- TooltipLabel(_('Engine model type'), _('If not passed, the default value is 16k_zh (Chinese universal)')),
+ TooltipLabel(_("Engine model type"), _("If not passed, the default value is 16k_zh (Chinese universal)")),
required=True,
- default_value='16k_zh',
+ default_value="16k_zh",
option_list=[
{"value": "8k_zh", "label": _("Chinese telephone universal")},
{"value": "8k_en", "label": _("English telephone universal")},
@@ -34,21 +34,24 @@ class TencentSSTModelParams(BaseForm):
{"value": "16k_hi", "label": _("Hindi")},
{"value": "16k_fr", "label": _("French")},
{"value": "16k_de", "label": _("German")},
- {"value": "16k_zh_dialect", "label": _("Multiple dialects, supporting 23 dialects")}
+ {"value": "16k_zh_dialect", "label": _("Multiple dialects, supporting 23 dialects")},
],
- value_field='value',
- text_field='label'
+ value_field="value",
+ text_field="label",
)
+
class TencentSTTModelCredential(BaseForm, BaseModelCredential):
REQUIRED_FIELDS = ["SecretId", "SecretKey"]
@classmethod
def _validate_model_type(cls, model_type, provider, raise_exception=False):
- if not any(mt['value'] == model_type for mt in provider.get_model_type_list()):
+ if not any(mt["value"] == model_type for mt in provider.get_model_type_list()):
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{model_type} Model type is not supported').format(model_type=model_type))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("{model_type} Model type is not supported").format(model_type=model_type),
+ )
return False
return True
@@ -57,33 +60,38 @@ def _validate_credential_fields(cls, model_credential, raise_exception=False):
missing_keys = [key for key in cls.REQUIRED_FIELDS if key not in model_credential]
if missing_keys:
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{keys} is required').format(keys=", ".join(missing_keys)))
+ raise AppApiException(
+ ValidCode.valid_error.value, gettext("{keys} is required").format(keys=", ".join(missing_keys))
+ )
return False
return True
def is_valid(self, model_type, model_name, model_credential, model_params, provider, raise_exception=False):
- if not (self._validate_model_type(model_type, provider, raise_exception) and
- self._validate_credential_fields(model_credential, raise_exception)):
+ if not (
+ self._validate_model_type(model_type, provider, raise_exception)
+ and self._validate_credential_fields(model_credential, raise_exception)
+ ):
return False
try:
model = provider.get_model(model_type, model_name, model_credential, **model_params)
model.check_auth()
except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
+ maxkb_logger.error(f"Exception: {e}", exc_info=True)
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext(
- 'Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("Verification failed, please check whether the parameters are correct: {error}").format(
+ error=str(e)
+ ),
+ )
return False
return True
def encryption_dict(self, model):
- return {**model, 'SecretKey': super().encryption(model.get('SecretKey', ''))}
+ return {**model, "SecretKey": super().encryption(model.get("SecretKey", ""))}
- SecretId = forms.PasswordInputField('SecretId', required=True)
- SecretKey = forms.PasswordInputField('SecretKey', required=True)
+ SecretId = forms.PasswordInputField("SecretId", required=True)
+ SecretKey = forms.PasswordInputField("SecretKey", required=True)
def get_model_params_setting_form(self, model_name):
return TencentSSTModelParams()
diff --git a/apps/models_provider/impl/tencent_model_provider/credential/tti.py b/apps/models_provider/impl/tencent_model_provider/credential/tti.py
index 98df630b4d7..4d63943bcde 100644
--- a/apps/models_provider/impl/tencent_model_provider/credential/tti.py
+++ b/apps/models_provider/impl/tencent_model_provider/credential/tti.py
@@ -5,76 +5,96 @@
from common import forms
from common.exception.app_exception import AppApiException
from common.forms import BaseForm, TooltipLabel
-from models_provider.base_model_provider import BaseModelCredential, ValidCode
+from common.forms.switch_field import SwitchField
from common.utils.logger import maxkb_logger
+from models_provider.base_model_provider import BaseModelCredential, ValidCode
+
+# 37 preset sizes from the TokenHub Hy-Image docs (width x height, area <= 1024x1024).
+_HY_IMAGE_SIZES = [
+ "2048x512",
+ "1984x512",
+ "1920x512",
+ "1856x512",
+ "1792x512",
+ "1728x512",
+ "1664x512",
+ "1600x512",
+ "1536x512",
+ "1472x576",
+ "1408x640",
+ "1344x704",
+ "1280x768",
+ "1216x832",
+ "1152x896",
+ "1088x960",
+ "1024x1024",
+ "960x1088",
+ "896x1152",
+ "832x1216",
+ "768x1280",
+ "704x1344",
+ "640x1408",
+ "576x1472",
+ "512x1536",
+ "512x1600",
+ "512x1664",
+ "512x1728",
+ "512x1792",
+ "512x1856",
+ "512x1920",
+ "512x1984",
+ "512x2048",
+ "768x1024",
+ "720x1280",
+ "1024x768",
+ "1280x720",
+]
+
class TencentTTIModelParams(BaseForm):
- Style = forms.SingleSelect(
- TooltipLabel(_('painting style'), _('If not passed, the default value is 201 (Japanese anime style)')),
- required=True,
- default_value='201',
- option_list=[
- {'value': '000', 'label': _('Not limited to style')},
- {'value': '101', 'label': _('ink painting')},
- {'value': '102', 'label': _('concept art')},
- {'value': '103', 'label': _('Oil painting 1')},
- {'value': '118', 'label': _('Oil Painting 2 (Van Gogh)')},
- {'value': '104', 'label': _('watercolor painting')},
- {'value': '105', 'label': _('pixel art')},
- {'value': '106', 'label': _('impasto style')},
- {'value': '107', 'label': _('illustration')},
- {'value': '108', 'label': _('paper cut style')},
- {'value': '109', 'label': _('Impressionism 1 (Monet)')},
- {'value': '119', 'label': _('Impressionism 2')},
- {'value': '110', 'label': '2.5D'},
- {'value': '111', 'label': _('classical portraiture')},
- {'value': '112', 'label': _('black and white sketch')},
- {'value': '113', 'label': _('cyberpunk')},
- {'value': '114', 'label': _('science fiction style')},
- {'value': '115', 'label': _('dark style')},
- {'value': '116', 'label': '3D'},
- {'value': '117', 'label': _('vaporwave')},
- {'value': '201', 'label': _('Japanese animation')},
- {'value': '202', 'label': _('monster style')},
- {'value': '203', 'label': _('Beautiful ancient style')},
- {'value': '204', 'label': _('retro anime')},
- {'value': '301', 'label': _('Game cartoon hand drawing')},
- {'value': '401', 'label': _('Universal realistic style')},
- ],
- value_field='value',
- text_field='label'
+ size = forms.SingleSelect(
+ TooltipLabel(
+ _("Image size"),
+ _(
+ "Width and height must be in [512, 2048] and the area must not exceed 1024x1024. If not passed, the "
+ "model auto-selects the closest preset size."
+ ),
+ ),
+ required=False,
+ default_value="1024x1024",
+ option_list=[{"value": value, "label": value} for value in _HY_IMAGE_SIZES],
+ value_field="value",
+ text_field="label",
)
- Resolution = forms.SingleSelect(
- TooltipLabel(_('Generate image resolution'), _('If not transmitted, the default value is 768:768.')),
- required=True,
- default_value='768:768',
- option_list=[
- {'value': '768:768', 'label': '768:768(1:1)'},
- {'value': '768:1024', 'label': '768:1024(3:4)'},
- {'value': '1024:768', 'label': '1024:768(4:3)'},
- {'value': '1024:1024', 'label': '1024:1024(1:1)'},
- {'value': '720:1280', 'label': '720:1280(9:16)'},
- {'value': '1280:720', 'label': '1280:720(16:9)'},
- {'value': '768:1280', 'label': '768:1280(3:5)'},
- {'value': '1280:768', 'label': '1280:768(5:3)'},
- {'value': '1080:1920', 'label': '1080:1920(9:16)'},
- {'value': '1920:1080', 'label': '1920:1080(16:9)'},
- ],
- value_field='value',
- text_field='label'
+ revise = SwitchField(
+ TooltipLabel(
+ _("Prompt rewrite"), _("Whether the model should rewrite and optimize the prompt before generation.")
+ ),
+ attrs={"active-value": True, "inactive-value": False},
+ default_value=True,
+ )
+
+ footnote = forms.TextInputField(
+ TooltipLabel(
+ _("Watermark footnote"), _("Custom watermark content, at most 16 characters, drawn in the bottom-right.")
+ ),
+ required=False,
+ default_value="",
)
class TencentTTIModelCredential(BaseForm, BaseModelCredential):
- REQUIRED_FIELDS = ['hunyuan_secret_id', 'hunyuan_secret_key']
+ REQUIRED_FIELDS = ["api_key"]
@classmethod
def _validate_model_type(cls, model_type, provider, raise_exception=False):
- if not any(mt['value'] == model_type for mt in provider.get_model_type_list()):
+ if not any(mt["value"] == model_type for mt in provider.get_model_type_list()):
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{model_type} Model type is not supported').format(model_type=model_type))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("{model_type} Model type is not supported").format(model_type=model_type),
+ )
return False
return True
@@ -83,33 +103,42 @@ def _validate_credential_fields(cls, model_credential, raise_exception=False):
missing_keys = [key for key in cls.REQUIRED_FIELDS if key not in model_credential]
if missing_keys:
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext('{keys} is required').format(keys=", ".join(missing_keys)))
+ raise AppApiException(
+ ValidCode.valid_error.value, gettext("{keys} is required").format(keys=", ".join(missing_keys))
+ )
return False
return True
def is_valid(self, model_type, model_name, model_credential, model_params, provider, raise_exception=False):
- if not (self._validate_model_type(model_type, provider, raise_exception) and
- self._validate_credential_fields(model_credential, raise_exception)):
+ if not (
+ self._validate_model_type(model_type, provider, raise_exception)
+ and self._validate_credential_fields(model_credential, raise_exception)
+ ):
return False
try:
model = provider.get_model(model_type, model_name, model_credential, **model_params)
model.check_auth()
except Exception as e:
- maxkb_logger.error(f'Exception: {e}', exc_info=True)
+ maxkb_logger.error(f"Exception: {e}", exc_info=True)
if raise_exception:
- raise AppApiException(ValidCode.valid_error.value,
- gettext(
- 'Verification failed, please check whether the parameters are correct: {error}').format(
- error=str(e)))
+ raise AppApiException(
+ ValidCode.valid_error.value,
+ gettext("Verification failed, please check whether the parameters are correct: {error}").format(
+ error=str(e)
+ ),
+ )
return False
return True
def encryption_dict(self, model):
- return {**model, 'hunyuan_secret_key': super().encryption(model.get('hunyuan_secret_key', ''))}
+ return {**model, "api_key": super().encryption(model.get("api_key", ""))}
- hunyuan_secret_id = forms.PasswordInputField('SecretId', required=True)
- hunyuan_secret_key = forms.PasswordInputField('SecretKey', required=True)
+ base_url = forms.TextInputField(
+ label=TooltipLabel(_("API URL"), _("TokenHub Hy-Image v3-generation endpoint")),
+ required=False,
+ default_value="https://tokenhub.tencentmaas.com/v1/wand/hunyuan-image/v3-generation",
+ )
+ api_key = forms.PasswordInputField(_("API Key"), required=True)
def get_model_params_setting_form(self, model_name):
return TencentTTIModelParams()
diff --git a/apps/models_provider/impl/tencent_model_provider/icon/tencent_icon_svg b/apps/models_provider/impl/tencent_model_provider/icon/tencent_icon_svg
index 6cec08b74c2..622cc802394 100644
--- a/apps/models_provider/impl/tencent_model_provider/icon/tencent_icon_svg
+++ b/apps/models_provider/impl/tencent_model_provider/icon/tencent_icon_svg
@@ -1,5 +1,4 @@
-
+
+
\ No newline at end of file
diff --git a/apps/models_provider/impl/tencent_model_provider/model/embedding.py b/apps/models_provider/impl/tencent_model_provider/model/embedding.py
index 6392ca3e64f..8357a30a76a 100644
--- a/apps/models_provider/impl/tencent_model_provider/model/embedding.py
+++ b/apps/models_provider/impl/tencent_model_provider/model/embedding.py
@@ -1,41 +1,84 @@
-
+# coding=utf-8
+
from typing import Dict, List
-from langchain_core.embeddings import Embeddings
-from tencentcloud.common import credential
-from tencentcloud.hunyuan.v20230901.hunyuan_client import HunyuanClient
-from tencentcloud.hunyuan.v20230901.models import GetEmbeddingRequest
+import requests
-from models_provider.base_model_provider import MaxKBBaseModel
+from common.utils.logger import maxkb_logger
+from models_provider.base_model_provider import MaxKBBaseEmbeddingModel
-class TencentEmbeddingModel(MaxKBBaseModel, Embeddings):
- def embed_documents(self, texts: List[str]) -> List[List[float]]:
- return [self.embed_query(text) for text in texts]
+class TencentEmbeddingModel(MaxKBBaseEmbeddingModel):
+ """腾讯 TokenHub 向量模型(OpenAI Embeddings 兼容接口)。
- def embed_query(self, text: str) -> List[float]:
- request = GetEmbeddingRequest()
- request.Input = text
- res = self.client.GetEmbedding(request)
- return res.Data[0].Embedding
-
- def __init__(self, secret_id: str, secret_key: str, model_name: str):
- self.secret_id = secret_id
- self.secret_key = secret_key
+ 文本向量:POST /v1/embeddings
+ 多模态向量:POST /v1/embeddings/multimodal(kinfra-vl-embedding-* 支持文本、图片、视频)
+ """
+
+ DEFAULT_BASE_URL: str = "https://tokenhub.tencentmaas.com/v1"
+ REQUEST_TIMEOUT: tuple = (10, 60)
+
+ def __init__(self, api_key: str, model_name: str, base_url: str, params: dict = None):
+ self.api_key = api_key
self.model_name = model_name
- cred = credential.Credential(
- secret_id, secret_key
- )
- self.client = HunyuanClient(cred, "")
+ self.base_url = (base_url or self.DEFAULT_BASE_URL).rstrip("/")
+ self.params = params or {}
+
+ @staticmethod
+ def is_cache_model():
+ return False
@staticmethod
- def new_instance(model_type: str, model_name: str, model_credential: Dict[str, str], **model_kwargs):
+ def new_instance(model_type: str, model_name: str, model_credential: Dict[str, object], **model_kwargs):
+ optional_params = MaxKBBaseEmbeddingModel.filter_optional_params(model_kwargs)
return TencentEmbeddingModel(
- secret_id=model_credential.get('SecretId'),
- secret_key=model_credential.get('SecretKey'),
+ api_key=model_credential.get("api_key"),
model_name=model_name,
+ base_url=model_credential.get("base_url") or TencentEmbeddingModel.DEFAULT_BASE_URL,
+ params=optional_params,
)
- def _generate_auth_token(self):
- # Example method to generate an authentication token for the model API
- return f"{self.secret_id}:{self.secret_key}"
+ def supports_image_embedding(self) -> bool:
+ return "vl-embedding" in self.model_name
+
+ def _embedding_url(self) -> str:
+ if self.supports_image_embedding():
+ return f"{self.base_url}/embeddings/multimodal"
+ return f"{self.base_url}/embeddings"
+
+ def _post(self, payload: dict) -> dict:
+ headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
+ response = requests.post(self._embedding_url(), headers=headers, json=payload, timeout=self.REQUEST_TIMEOUT)
+ response.raise_for_status()
+ return response.json()
+
+ @staticmethod
+ def _extract_embedding(result: dict) -> List[float]:
+ data = result.get("data") or []
+ if not data:
+ maxkb_logger.error(f"Tencent TokenHub embedding returned no data: {result}")
+ raise RuntimeError("Tencent TokenHub embedding API returned no embedding")
+ return data[0].get("embedding", [])
+
+ def embed_documents(self, texts: List[str]) -> List[List[float]]:
+ if self.supports_image_embedding():
+ # 多模态接口单次请求融合为一个向量,逐条处理
+ return [self._embed_multimodal([{"type": "text", "text": text}]) for text in texts]
+ payload = {"model": self.model_name, "input": texts, "encoding_format": "float", **self.params}
+ result = self._post(payload)
+ return [item.get("embedding", []) for item in result.get("data", [])]
+
+ def embed_query(self, text: str) -> List[float]:
+ if self.supports_image_embedding():
+ return self._embed_multimodal([{"type": "text", "text": text}])
+ payload = {"model": self.model_name, "input": text, "encoding_format": "float", **self.params}
+ return self._extract_embedding(self._post(payload))
+
+ def embed_images(self, images: List[str]) -> List[List[float]]:
+ if not self.supports_image_embedding():
+ return []
+ return [self._embed_multimodal([{"type": "image_url", "image_url": {"url": url}}]) for url in images]
+
+ def _embed_multimodal(self, items: list) -> List[float]:
+ payload = {"model": self.model_name, "input": items, "encoding_format": "float", **self.params}
+ return self._extract_embedding(self._post(payload))
diff --git a/apps/models_provider/impl/tencent_model_provider/model/image.py b/apps/models_provider/impl/tencent_model_provider/model/image.py
index 42b11723e98..617a2361ac0 100644
--- a/apps/models_provider/impl/tencent_model_provider/model/image.py
+++ b/apps/models_provider/impl/tencent_model_provider/model/image.py
@@ -5,14 +5,13 @@
class TencentVision(MaxKBBaseModel, BaseChatOpenAI):
-
@staticmethod
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
return TencentVision(
model_name=model_name,
- openai_api_base=model_credential.get('api_base') or 'https://api.hunyuan.cloud.tencent.com/v1',
- openai_api_key=model_credential.get('api_key'),
+ openai_api_base=model_credential.get("api_base") or "https://tokenhub.tencentmaas.com/v1",
+ openai_api_key=model_credential.get("api_key"),
# stream_options={"include_usage": True},
streaming=True,
stream_usage=True,
diff --git a/apps/models_provider/impl/tencent_model_provider/model/llm.py b/apps/models_provider/impl/tencent_model_provider/model/llm.py
index e86edd54b9a..151e0973ec8 100644
--- a/apps/models_provider/impl/tencent_model_provider/model/llm.py
+++ b/apps/models_provider/impl/tencent_model_provider/model/llm.py
@@ -1,45 +1,54 @@
# coding=utf-8
-from typing import List, Dict, Optional, Any
+from typing import Dict, List
-from langchain_core.messages import BaseMessage
+from langchain_core.messages import BaseMessage, get_buffer_string
+from common.config.tokenizer_manage_config import TokenizerManage
from models_provider.base_model_provider import MaxKBBaseModel
-from models_provider.impl.tencent_model_provider.model.hunyuan import ChatHunyuan
+from models_provider.impl.base_chat_open_ai import BaseChatOpenAI
-class TencentModel(MaxKBBaseModel, ChatHunyuan):
- @staticmethod
- def is_cache_model():
- return False
-
- def __init__(self, model_name: str, credentials: Dict[str, str], streaming: bool = False, **kwargs):
- hunyuan_app_id = credentials.get('hunyuan_app_id')
- hunyuan_secret_id = credentials.get('hunyuan_secret_id')
- hunyuan_secret_key = credentials.get('hunyuan_secret_key')
+def custom_get_token_ids(text: str):
+ tokenizer = TokenizerManage.get_tokenizer()
+ return tokenizer.encode(text)
- optional_params = MaxKBBaseModel.filter_optional_params(kwargs)
- if not all([hunyuan_app_id, hunyuan_secret_id, hunyuan_secret_key]):
- raise ValueError(
- "All of 'hunyuan_app_id', 'hunyuan_secret_id', and 'hunyuan_secret_key' must be provided in credentials.")
+class TencentModel(MaxKBBaseModel, BaseChatOpenAI):
+ """Tencent TokenHub LLM model.
- super().__init__(model=model_name, hunyuan_app_id=hunyuan_app_id, hunyuan_secret_id=hunyuan_secret_id,
- hunyuan_secret_key=hunyuan_secret_key, streaming=streaming,
- temperature=optional_params.get('temperature', 1.0)
- )
+ TokenHub aggregates Tencent Hunyuan and other providers behind an
+ OpenAI Chat Completions compatible API, see
+ https://cloud.tencent.com/document/product/1823/132252
+ """
@staticmethod
- def new_instance(model_type: str, model_name: str, model_credential: Dict[str, object],
- **model_kwargs) -> 'TencentModel':
- streaming = model_kwargs.pop('streaming', False)
- return TencentModel(model_name=model_name, credentials=model_credential, streaming=streaming, **model_kwargs)
+ def is_cache_model():
+ return False
- def get_last_generation_info(self) -> Optional[Dict[str, Any]]:
- return self.usage_metadata
+ @staticmethod
+ def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
+ optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
+ streaming = model_kwargs.get("streaming", False)
+ return TencentModel(
+ model=model_name,
+ openai_api_base=model_credential.get("api_base"),
+ openai_api_key=model_credential.get("api_key"),
+ streaming=streaming,
+ custom_get_token_ids=custom_get_token_ids,
+ **optional_params,
+ )
def get_num_tokens_from_messages(self, messages: List[BaseMessage]) -> int:
- return self.usage_metadata.get('PromptTokens', 0)
+ try:
+ return super().get_num_tokens_from_messages(messages)
+ except Exception:
+ tokenizer = TokenizerManage.get_tokenizer()
+ return sum([len(tokenizer.encode(get_buffer_string([m]))) for m in messages])
def get_num_tokens(self, text: str) -> int:
- return self.usage_metadata.get('CompletionTokens', 0)
+ try:
+ return super().get_num_tokens(text)
+ except Exception:
+ tokenizer = TokenizerManage.get_tokenizer()
+ return len(tokenizer.encode(text))
diff --git a/apps/models_provider/impl/tencent_model_provider/model/stt.py b/apps/models_provider/impl/tencent_model_provider/model/stt.py
index f09ced2c7b0..6240c1c2394 100644
--- a/apps/models_provider/impl/tencent_model_provider/model/stt.py
+++ b/apps/models_provider/impl/tencent_model_provider/model/stt.py
@@ -25,10 +25,10 @@ class TencentSpeechToText(MaxKBBaseModel, BaseSpeechToText):
def __init__(self, **kwargs):
super().__init__(**kwargs)
- self.hunyuan_secret_id = kwargs.get('hunyuan_secret_id')
- self.hunyuan_secret_key = kwargs.get('hunyuan_secret_key')
- self.model = kwargs.get('model')
- self.params = kwargs.get('params')
+ self.hunyuan_secret_id = kwargs.get("hunyuan_secret_id")
+ self.hunyuan_secret_key = kwargs.get("hunyuan_secret_key")
+ self.model = kwargs.get("model")
+ self.params = kwargs.get("params")
@staticmethod
def is_cache_model():
@@ -37,16 +37,16 @@ def is_cache_model():
@staticmethod
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
return TencentSpeechToText(
- hunyuan_secret_id=model_credential.get('SecretId'),
- hunyuan_secret_key=model_credential.get('SecretKey'),
+ hunyuan_secret_id=model_credential.get("SecretId"),
+ hunyuan_secret_key=model_credential.get("SecretKey"),
model=model_name,
params=model_kwargs,
- **model_kwargs
+ **model_kwargs,
)
def check_auth(self):
cwd = os.path.dirname(os.path.abspath(__file__))
- with open(f'{cwd}/iat_mp3_16k.mp3', 'rb') as f:
+ with open(f"{cwd}/iat_mp3_16k.mp3", "rb") as f:
self.speech_to_text(f)
def speech_to_text(self, audio_file):
@@ -67,11 +67,11 @@ def speech_to_text(self, audio_file):
# 实例化一个请求对象,每个接口都会对应一个request对象
req = models.SentenceRecognitionRequest()
params = {
- "EngSerViceType": self.params.get('EngSerViceType'),
+ "EngSerViceType": self.params.get("EngSerViceType"),
"SourceType": 1,
"VoiceFormat": "mp3",
"Data": _v.decode(),
- **self.params
+ **self.params,
}
req.from_json_string(json.dumps(params))
@@ -80,13 +80,12 @@ def speech_to_text(self, audio_file):
# 输出json格式的字符串回包
return resp.Result
-
except TencentCloudSDKException as err:
maxkb_logger.error(f":Error: {str(err)}: {traceback.format_exc()}")
raise err
-DEFAULT_WAND_BASE_URL = 'https://tokenhub.tencentmaas.com/v1/wand/asrproxy/sync_transcribe'
+DEFAULT_WAND_BASE_URL = "https://tokenhub.tencentmaas.com/v1/wand/asrproxy/sync_transcribe"
class TencentWandSpeechToText(MaxKBBaseModel, BaseSpeechToText):
@@ -97,10 +96,10 @@ class TencentWandSpeechToText(MaxKBBaseModel, BaseSpeechToText):
def __init__(self, **kwargs):
super().__init__(**kwargs)
- self.api_key = kwargs.get('api_key')
- self.model = kwargs.get('model')
- self.params = kwargs.get('params') or {}
- self.base_url = kwargs.get('base_url') or DEFAULT_WAND_BASE_URL
+ self.api_key = kwargs.get("api_key")
+ self.model = kwargs.get("model")
+ self.params = kwargs.get("params") or {}
+ self.base_url = kwargs.get("base_url") or DEFAULT_WAND_BASE_URL
@staticmethod
def is_cache_model():
@@ -109,19 +108,19 @@ def is_cache_model():
@staticmethod
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
instance_kwargs = {
- "api_key": model_credential.get('api_key'),
+ "api_key": model_credential.get("api_key"),
"model": model_name,
"params": model_kwargs,
**model_kwargs,
}
- base_url = model_credential.get('base_url')
+ base_url = model_credential.get("base_url")
if base_url:
instance_kwargs["base_url"] = base_url
return TencentWandSpeechToText(**instance_kwargs)
def check_auth(self):
cwd = os.path.dirname(os.path.abspath(__file__))
- with open(f'{cwd}/iat_mp3_16k.mp3', 'rb') as f:
+ with open(f"{cwd}/iat_mp3_16k.mp3", "rb") as f:
self.speech_to_text(f)
def speech_to_text(self, audio_file):
@@ -129,7 +128,7 @@ def speech_to_text(self, audio_file):
payload = {"model": self.model}
# 仅使用上传音频文件的 base64 data,不提供 input_url 兜底
audio_data = audio_file.read()
- payload["data"] = base64.b64encode(audio_data).decode('utf-8')
+ payload["data"] = base64.b64encode(audio_data).decode("utf-8")
for key in ("source", "voice_encode_format"):
if self.params.get(key):
payload[key] = self.params[key]
@@ -148,7 +147,7 @@ def speech_to_text(self, audio_file):
text = output.get("text")
if not text:
sentences = output.get("sentences") or []
- text = " ".join([s.get('text', '') for s in sentences if s.get('text')])
+ text = " ".join([s.get("text", "") for s in sentences if s.get("text")])
return text
except Exception as e:
maxkb_logger.error(f"WAND ASR Error: {str(e)}: {traceback.format_exc()}")
diff --git a/apps/models_provider/impl/tencent_model_provider/model/tti.py b/apps/models_provider/impl/tencent_model_provider/model/tti.py
index 4e2c080d830..8dcc73dd2c9 100644
--- a/apps/models_provider/impl/tencent_model_provider/model/tti.py
+++ b/apps/models_provider/impl/tencent_model_provider/model/tti.py
@@ -1,93 +1,79 @@
# coding=utf-8
-import json
-import logging
-from typing import Dict
+import traceback
+from typing import Dict, Optional
+import requests
from django.utils.translation import gettext as _
-from tencentcloud.common import credential
-from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
-from tencentcloud.common.profile.client_profile import ClientProfile
-from tencentcloud.common.profile.http_profile import HttpProfile
-from tencentcloud.hunyuan.v20230901 import hunyuan_client, models
from common.utils.logger import maxkb_logger
from models_provider.base_model_provider import MaxKBBaseModel
from models_provider.impl.base_tti import BaseTextToImage
-from models_provider.impl.tencent_model_provider.model.hunyuan import ChatHunyuan
+
+
+DEFAULT_WAND_IMAGE_BASE_URL = "https://tokenhub.tencentmaas.com/v1/wand/hunyuan-image/v3-generation"
class TencentTextToImageModel(MaxKBBaseModel, BaseTextToImage):
- hunyuan_secret_id: str
- hunyuan_secret_key: str
+ api_key: str
model: str
params: dict
+ base_url: Optional[str] = DEFAULT_WAND_IMAGE_BASE_URL
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.api_key = kwargs.get("api_key")
+ self.model = kwargs.get("model")
+ self.params = kwargs.get("params") or {}
+ self.base_url = kwargs.get("base_url") or DEFAULT_WAND_IMAGE_BASE_URL
@staticmethod
def is_cache_model():
return False
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
- self.hunyuan_secret_id = kwargs.get('hunyuan_secret_id')
- self.hunyuan_secret_key = kwargs.get('hunyuan_secret_key')
- self.model = kwargs.get('model_name')
- self.params = kwargs.get('params')
-
@staticmethod
- def new_instance(model_type: str, model_name: str, model_credential: Dict[str, object],
- **model_kwargs) -> 'TencentTextToImageModel':
- optional_params = {'params': {'Style': '201', 'Resolution': '768:768'}}
+ def new_instance(
+ model_type: str, model_name: str, model_credential: Dict[str, object], **model_kwargs
+ ) -> "TencentTextToImageModel":
+ optional_params = {"params": {"size": "1024x1024"}}
for key, value in model_kwargs.items():
- if key not in ['model_id', 'use_local', 'streaming']:
- optional_params['params'][key] = value
- return TencentTextToImageModel(
- model=model_name,
- hunyuan_secret_id=model_credential.get('hunyuan_secret_id'),
- hunyuan_secret_key=model_credential.get('hunyuan_secret_key'),
- **optional_params
- )
+ if key not in ["model_id", "use_local", "streaming"]:
+ optional_params["params"][key] = value
+ instance_kwargs = {
+ "api_key": model_credential.get("api_key"),
+ "model": model_name,
+ "params": optional_params["params"],
+ **optional_params,
+ }
+ base_url = model_credential.get("base_url")
+ if base_url:
+ instance_kwargs["base_url"] = base_url
+ return TencentTextToImageModel(**instance_kwargs)
def check_auth(self):
- chat = ChatHunyuan(hunyuan_app_id='111111',
- hunyuan_secret_id=self.hunyuan_secret_id,
- hunyuan_secret_key=self.hunyuan_secret_key,
- model="hunyuan-standard")
- res = chat.invoke(_('Hello'))
- # print(res)
+ self.generate_image(_("Hello"), None)
def generate_image(self, prompt: str, negative_prompt: str = None):
try:
- # 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
- # 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
- # 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
- cred = credential.Credential(self.hunyuan_secret_id, self.hunyuan_secret_key)
- # 实例化一个http选项,可选的,没有特殊需求可以跳过
- httpProfile = HttpProfile()
- httpProfile.endpoint = "hunyuan.tencentcloudapi.com"
-
- # 实例化一个client选项,可选的,没有特殊需求可以跳过
- clientProfile = ClientProfile()
- clientProfile.httpProfile = httpProfile
- # 实例化要请求产品的client对象,clientProfile是可选的
- client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou", clientProfile)
-
- # 实例化一个请求对象,每个接口都会对应一个request对象
- req = models.TextToImageLiteRequest()
- params = {
- "Prompt": prompt,
- "NegativePrompt": negative_prompt,
- "RspImgType": "url",
- **self.params
+ payload = {"model": self.model, "prompt": prompt}
+ payload.update({key: value for key, value in self.params.items() if value not in (None, "")})
+ headers = {
+ "Authorization": f"Bearer {self.api_key}",
+ "Content-Type": "application/json",
}
- req.from_json_string(json.dumps(params))
-
- # 返回的resp是一个TextToImageLiteResponse的实例,与请求对象对应
- resp = client.TextToImageLite(req)
+ response = requests.post(self.base_url, headers=headers, json=payload, timeout=300)
+ response.raise_for_status()
+ result = response.json()
+ data = result.get("data") or []
file_urls = []
-
- file_urls.append(resp.ResultImage)
+ for item in data:
+ url = item.get("url")
+ if url:
+ file_urls.append(url)
+ if not file_urls:
+ maxkb_logger.error(f"Tencent Text to Image API returned no urls: {result}")
+ raise RuntimeError("Tencent Text to Image API returned no image urls")
return file_urls
- except TencentCloudSDKException as err:
- maxkb_logger.error(f"Tencent Text to Image API call failed: {err}")
+ except requests.RequestException as err:
+ maxkb_logger.error(f"Tencent Text to Image API call failed: {err}: {traceback.format_exc()}")
raise RuntimeError(f"Tencent Text to Image API call failed: {err}") from err
diff --git a/apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py b/apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
index 60455c374dc..336a47dc079 100644
--- a/apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
+++ b/apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py
@@ -4,7 +4,11 @@
import os
from common.utils.common import get_file_content
from models_provider.base_model_provider import (
- IModelProvider, ModelProvideInfo, ModelInfo, ModelTypeConst, ModelInfoManage
+ IModelProvider,
+ ModelProvideInfo,
+ ModelInfo,
+ ModelTypeConst,
+ ModelInfoManage,
)
from models_provider.impl.tencent_model_provider.credential.embedding import TencentEmbeddingCredential
from models_provider.impl.tencent_model_provider.credential.image import TencentVisionModelCredential
@@ -12,121 +16,207 @@
from models_provider.impl.tencent_model_provider.credential.stt import TencentSTTModelCredential
from models_provider.impl.tencent_model_provider.credential.tokenhub_stt import TencentTokenhubSTTModelCredential
from models_provider.impl.tencent_model_provider.credential.tti import TencentTTIModelCredential
+from models_provider.impl.tencent_model_provider.credential.ttv import TencentTTVModelCredential
from models_provider.impl.tencent_model_provider.model.embedding import TencentEmbeddingModel
from models_provider.impl.tencent_model_provider.model.image import TencentVision
from models_provider.impl.tencent_model_provider.model.llm import TencentModel
from models_provider.impl.tencent_model_provider.model.stt import TencentSpeechToText, TencentWandSpeechToText
from models_provider.impl.tencent_model_provider.model.tti import TencentTextToImageModel
+from models_provider.impl.tencent_model_provider.model.ttv import TencentVideoModel
from maxkb.conf import PROJECT_DIR
from django.utils.translation import gettext as _
+
def _create_model_info(model_name, description, model_type, credential_class, model_class):
return ModelInfo(
name=model_name,
desc=description,
model_type=model_type,
model_credential=credential_class(),
- model_class=model_class
+ model_class=model_class,
)
def _get_tencent_icon_path():
- return os.path.join(PROJECT_DIR, "apps", 'models_provider', 'impl', 'tencent_model_provider',
- 'icon', 'tencent_icon_svg')
+ return os.path.join(
+ PROJECT_DIR, "apps", "models_provider", "impl", "tencent_model_provider", "icon", "tencent_icon_svg"
+ )
def _initialize_model_info():
- model_info_list = [_create_model_info(
- 'hunyuan-pro',
- _('The most effective version of the current hybrid model, the trillion-level parameter scale MOE-32K long article model. Reaching the absolute leading level on various benchmarks, with complex instructions and reasoning, complex mathematical capabilities, support for function call, and application focus optimization in fields such as multi-language translation, finance, law, and medical care'),
- ModelTypeConst.LLM,
- TencentLLMModelCredential,
- TencentModel
- ),
- _create_model_info(
- 'hunyuan-standard',
- _('A better routing strategy is adopted to simultaneously alleviate the problems of load balancing and expert convergence. For long articles, the needle-in-a-haystack index reaches 99.9%'),
+ model_info_list = [
+ _create_model_info(
+ "hy4-preview",
+ _("The latest generation productivity model with upgraded Agent and complex task execution capabilities."),
+ ModelTypeConst.LLM,
+ TencentLLMModelCredential,
+ TencentModel,
+ ),
+ _create_model_info(
+ "hy3",
+ _(
+ "Tuned on real business scenarios, balancing effectiveness and cost-effectiveness, with reinforced Coding, long-text, reasoning and Agent capabilities."
+ ),
ModelTypeConst.LLM,
TencentLLMModelCredential,
- TencentModel),
+ TencentModel,
+ ),
_create_model_info(
- 'hunyuan-lite',
- _('Upgraded to MOE structure, the context window is 256k, leading many open source models in multiple evaluation sets such as NLP, code, mathematics, industry, etc.'),
+ "hy3-preview",
+ _(
+ "Designed for Agent workloads, using a MoE architecture that supports interleaved thinking, structured output, Function Calling and Cache caching."
+ ),
ModelTypeConst.LLM,
TencentLLMModelCredential,
- TencentModel),
+ TencentModel,
+ ),
_create_model_info(
- 'hunyuan-role',
- _("Hunyuan's latest version of the role-playing model, a role-playing model launched by Hunyuan's official fine-tuning training, is based on the Hunyuan model combined with the role-playing scene data set for additional training, and has better basic effects in role-playing scenes."),
+ "hy-mt2-pro",
+ _("Tencent Hybrid multilingual translation model."),
ModelTypeConst.LLM,
TencentLLMModelCredential,
- TencentModel),
+ TencentModel,
+ ),
_create_model_info(
- 'hunyuan-functioncall',
- _("Hunyuan's latest MOE architecture FunctionCall model has been trained with high-quality FunctionCall data and has a context window of 32K, leading in multiple dimensions of evaluation indicators."),
+ "hy-mt2-plus",
+ _("Tencent Hybrid multilingual translation model."),
ModelTypeConst.LLM,
TencentLLMModelCredential,
- TencentModel),
+ TencentModel,
+ ),
_create_model_info(
- 'hunyuan-code',
- _("Hunyuan's latest code generation model, after training the base model with 200B high-quality code data, and iterating on high-quality SFT data for half a year, the context long window length has been increased to 8K, and it ranks among the top in the automatic evaluation indicators of code generation in the five major languages; the five major languages In the manual high-quality evaluation of 10 comprehensive code tasks that consider all aspects, the performance is in the first echelon."),
+ "hy-mt2-lite",
+ _("Tencent Hybrid multilingual translation model."),
ModelTypeConst.LLM,
TencentLLMModelCredential,
- TencentModel),
+ TencentModel,
+ ),
_create_model_info(
- 'asr-sentence',
- _("This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."),
+ "hunyuan-role-latest",
+ _("Hunyuan's latest role-playing model based on the Hunyuan model with role-playing scene fine-tuning."),
+ ModelTypeConst.LLM,
+ TencentLLMModelCredential,
+ TencentModel,
+ ),
+ _create_model_info(
+ "hy-role",
+ _("Hunyuan's role-playing model with better basic effects in role-playing scenarios."),
+ ModelTypeConst.LLM,
+ TencentLLMModelCredential,
+ TencentModel,
+ ),
+ _create_model_info(
+ "asr-sentence",
+ _(
+ "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
+ ),
ModelTypeConst.STT,
TencentSTTModelCredential,
- TencentSpeechToText),
+ TencentSpeechToText,
+ ),
_create_model_info(
- 'wand-asr-v1',
- _(''),
- ModelTypeConst.STT,
- TencentTokenhubSTTModelCredential,
- TencentWandSpeechToText),
+ "wand-asr-v1", _(""), ModelTypeConst.STT, TencentTokenhubSTTModelCredential, TencentWandSpeechToText
+ ),
_create_model_info(
- 'hy-asr-3.0-preview',
- _(''),
- ModelTypeConst.STT,
- TencentTokenhubSTTModelCredential,
- TencentWandSpeechToText),
+ "hy-asr-3.0-preview", _(""), ModelTypeConst.STT, TencentTokenhubSTTModelCredential, TencentWandSpeechToText
+ ),
]
- tencent_embedding_model_info = _create_model_info(
- 'hunyuan-embedding',
- _("Tencent's Hunyuan Embedding interface can convert text into high-quality vector data. The vector dimension is 1024 dimensions."),
- ModelTypeConst.EMBEDDING,
- TencentEmbeddingCredential,
- TencentEmbeddingModel
- )
+ model_info_embedding_list = [
+ _create_model_info(
+ "kinfra-text-embedding-0.6b",
+ _("Tencent TokenHub text embedding model, 1024 dimensions."),
+ ModelTypeConst.EMBEDDING,
+ TencentEmbeddingCredential,
+ TencentEmbeddingModel,
+ ),
+ _create_model_info(
+ "kinfra-text-embedding-4b",
+ _("Tencent TokenHub text embedding model, 2560 dimensions."),
+ ModelTypeConst.EMBEDDING,
+ TencentEmbeddingCredential,
+ TencentEmbeddingModel,
+ ),
+ _create_model_info(
+ "kinfra-vl-embedding-2b",
+ _("Tencent TokenHub multimodal embedding model, 2048 dimensions."),
+ ModelTypeConst.EMBEDDING,
+ TencentEmbeddingCredential,
+ TencentEmbeddingModel,
+ ),
+ _create_model_info(
+ "kinfra-vl-embedding-8b",
+ _("Tencent TokenHub multimodal embedding model, 4096 dimensions."),
+ ModelTypeConst.EMBEDDING,
+ TencentEmbeddingCredential,
+ TencentEmbeddingModel,
+ ),
+ ]
+ tencent_embedding_model_info = model_info_embedding_list[0]
+
+ model_info_vision_list = [
+ _create_model_info(
+ "hunyuan-vision",
+ _("Mixed element visual model"),
+ ModelTypeConst.IMAGE,
+ TencentVisionModelCredential,
+ TencentVision,
+ )
+ ]
- model_info_embedding_list = [tencent_embedding_model_info]
-
- model_info_vision_list = [_create_model_info(
- 'hunyuan-vision',
- _('Mixed element visual model'),
- ModelTypeConst.IMAGE,
- TencentVisionModelCredential,
- TencentVision)]
-
- model_info_tti_list = [_create_model_info(
- 'hunyuan-dit',
- _('Hunyuan graph model'),
- ModelTypeConst.TTI,
- TencentTTIModelCredential,
- TencentTextToImageModel)]
-
- model_info_manage = ModelInfoManage.builder() \
- .append_model_info_list(model_info_list) \
- .append_model_info_list(model_info_embedding_list) \
- .append_model_info_list(model_info_vision_list) \
- .append_default_model_info(model_info_vision_list[0]) \
- .append_model_info_list(model_info_tti_list) \
- .append_default_model_info(model_info_tti_list[0]) \
- .append_default_model_info(model_info_list[0]) \
- .append_default_model_info(tencent_embedding_model_info) \
+ model_info_tti_list = [
+ _create_model_info(
+ "hy-image-v3",
+ _("Hunyuan Hy-Image 3.0 text-to-image model."),
+ ModelTypeConst.TTI,
+ TencentTTIModelCredential,
+ TencentTextToImageModel,
+ )
+ ]
+
+ model_info_ttv_list = [
+ _create_model_info(
+ "hy-video-1.5",
+ _("Hunyuan HY-Video 1.5 text-to-video model."),
+ ModelTypeConst.TTV,
+ TencentTTVModelCredential,
+ TencentVideoModel,
+ )
+ ]
+
+ model_info_itv_list = [
+ _create_model_info(
+ "hy-video-1.5",
+ _("Hunyuan HY-Video 1.5 image-to-video model."),
+ ModelTypeConst.ITV,
+ TencentTTVModelCredential,
+ TencentVideoModel,
+ ),
+ _create_model_info(
+ "yt-video-2.0",
+ _("Tencent YT-Video 2.0 image-to-video model."),
+ ModelTypeConst.ITV,
+ TencentTTVModelCredential,
+ TencentVideoModel,
+ ),
+ ]
+
+ model_info_manage = (
+ ModelInfoManage.builder()
+ .append_model_info_list(model_info_list)
+ .append_model_info_list(model_info_embedding_list)
+ .append_model_info_list(model_info_vision_list)
+ .append_default_model_info(model_info_vision_list[0])
+ .append_model_info_list(model_info_tti_list)
+ .append_default_model_info(model_info_tti_list[0])
+ .append_model_info_list(model_info_ttv_list)
+ .append_default_model_info(model_info_ttv_list[0])
+ .append_model_info_list(model_info_itv_list)
+ .append_default_model_info(model_info_itv_list[0])
+ .append_default_model_info(model_info_list[0])
+ .append_default_model_info(tencent_embedding_model_info)
.build()
+ )
return model_info_manage
@@ -140,15 +230,11 @@ def get_model_info_manage(self):
def get_model(self, model_type, model_name, model_credential, **model_kwargs):
# STT 模型:模型名不以 asr- 开头的一律走 Tencent Tokenhub WAND 识别
- if model_type == ModelTypeConst.STT.name and not model_name.startswith('asr-'):
+ if model_type == ModelTypeConst.STT.name and not model_name.startswith("asr-"):
return TencentWandSpeechToText.new_instance(model_type, model_name, model_credential, **model_kwargs)
return super().get_model(model_type, model_name, model_credential, **model_kwargs)
def get_model_provide_info(self):
icon_path = _get_tencent_icon_path()
icon_data = get_file_content(icon_path)
- return ModelProvideInfo(
- provider='model_tencent_provider',
- name=_('Tencent Hunyuan'),
- icon=icon_data
- )
+ return ModelProvideInfo(provider="model_tencent_provider", name=_("Tencent Hunyuan"), icon=icon_data)