fix: query Dify DB directly for available models instead of API call

- Replace API-based model fetching with direct SQL query on
  provider_models table (shared PostgreSQL, no auth needed)
- Frontend: auto-detect base_url from model name when selecting
  a Dify model, set provider to 'custom'
- Remove unused requests import and API key fallback logic

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wsb1224 2026-07-24 14:20:34 +08:00
parent 6d571f56a8
commit 53346c9def
2 changed files with 45 additions and 48 deletions

View File

@ -497,53 +497,30 @@ class PptAdminService:
return {"code": 0, "data": {"models": self._BUILTIN_MODELS, "source": "builtin"}} return {"code": 0, "data": {"models": self._BUILTIN_MODELS, "source": "builtin"}}
def _fetch_dify_models(self) -> list | None: def _fetch_dify_models(self) -> list | None:
"""调用 Dify API 获取可用 LLM 模型列表,失败返回 None。""" """从 Dify 数据库直接查询已配置的 LLM 模型列表。"""
import requests
try: try:
base_url = os.getenv("DIFY_BASE_URL", "http://localhost:5001") rows = db.session.execute(db.text(
"SELECT DISTINCT pm.model_name, pm.provider_name "
# 收集可用的 API Key按优先级尝试 "FROM provider_models pm "
candidate_keys: list[str] = [] "WHERE pm.model_type = 'llm' AND pm.is_valid = true "
key_setting = SystemSetting.query.filter_by(key="dify_workspace_api_key").first() "ORDER BY pm.provider_name, pm.model_name"
if key_setting and key_setting.value: )).fetchall()
candidate_keys.append(key_setting.value) if not rows:
for env_key in ("DIFY_CHAT_APP_API_KEY", "DIFY_WORKFLOW_APP_API_KEY", return None
"BAODAN_CHAT_API_KEY", "BAODAN_WORKFLOW_API_KEY"): models = []
val = os.getenv(env_key, "").strip() for row in rows:
if val: model_name = row[0]
candidate_keys.append(val) provider_name = row[1]
# 去重保持顺序 # 从插件标识中提取简短供应商名
seen = set() short_provider = provider_name.split("/")[-1] if "/" in provider_name else provider_name
api_keys = [] models.append({
for k in candidate_keys: "provider": short_provider,
if k not in seen: "model": model_name,
seen.add(k) "label": f"{model_name}",
api_keys.append(k) })
return models
for api_key in api_keys:
try:
resp = requests.get(
f"{base_url}/v1/workspaces/current/models/model-types/llm",
headers={"Authorization": f"Bearer {api_key}"},
timeout=10,
)
if resp.status_code != 200:
continue
data = resp.json()
models = []
for item in data.get("data", []):
provider = item.get("provider", "")
for model in item.get("models", []):
model_name = model.get("model", "")
label = model.get("label", {}).get("zh_Hans", "") or model.get("label", {}).get("en_US", "") or model_name
models.append({"provider": provider, "model": model_name, "label": label})
if models:
return models
except Exception:
continue
return None
except Exception as e: except Exception as e:
logger.warning(f"从 Dify 获取模型列表失败: {e}") logger.warning(f"从 Dify 数据库获取模型列表失败: {e}")
return None return None
def get_settings(self) -> dict: def get_settings(self) -> dict:

View File

@ -159,14 +159,34 @@ function onPosterProviderChange(val: string) {
} }
} }
// base_url
const MODEL_BASE_URLS: Record<string, string> = {
'deepseek': 'https://api.deepseek.com/v1',
'minimax': 'https://api.minimax.chat/v1',
'gemini': 'https://generativelanguage.googleapis.com/v1/models',
'gpt': 'https://api.openai.com/v1',
'claude': 'https://api.anthropic.com/v1',
}
function inferBaseUrl(model: string): string {
const lower = model.toLowerCase()
for (const [keyword, url] of Object.entries(MODEL_BASE_URLS)) {
if (lower.startsWith(keyword)) return url
}
return ''
}
function applyDifyModel(target: 'ppt' | 'poster', command: string) { function applyDifyModel(target: 'ppt' | 'poster', command: string) {
const [provider, model] = command.split('|') const [, model] = command.split('|')
const baseUrl = inferBaseUrl(model)
if (target === 'ppt') { if (target === 'ppt') {
form.ppt_llm_provider = provider form.ppt_llm_provider = 'custom'
form.ppt_llm_model = model form.ppt_llm_model = model
form.ppt_llm_base_url = baseUrl
} else { } else {
form.poster_llm_provider = provider form.poster_llm_provider = 'custom'
form.poster_llm_model = model form.poster_llm_model = model
form.poster_llm_base_url = baseUrl
} }
} }