fix(canvas): 分镜与视频模型 - 按端点协议适配并修复分镜生成

* fix(backend): 分镜生成 - 自动修复携带原始剧情并支持有界重试

* fix(canvas): 视频模型 - 按端点协议拉取模型并适配分镜视频节点

* fix(canvas): 视频模型 - 保留已有协议并刷新分镜节点模型

* fix(canvas): 引用图预览 - 修正提示面板代码格式

---------

Co-authored-by: sikongyue <3155157671@qq.com>
Co-authored-by: ddCat <2695092045@qq.com>
This commit is contained in:
爱笑的毛毛虫
2026-08-10 01:42:47 +08:00
committed by GitHub
parent a4063b01c9
commit d9440e31dd
10 changed files with 195 additions and 65 deletions

View File

@@ -1095,13 +1095,18 @@ export async function fetchImageModels(config: Pick<AiConfig, "baseUrl" | "apiKe
}
}
export async function fetchChannelModels(channel: ModelChannel, viaBackend = false) {
export type ChannelModelCatalogItem = { id: string; supportedEndpointTypes?: string[] };
export type ChannelModelFetchResult = { models: string[]; catalog: ChannelModelCatalogItem[] };
export async function fetchChannelModels(channel: ModelChannel, viaBackend = false): Promise<ChannelModelFetchResult> {
if (!viaBackend) {
return fetchImageModels({ baseUrl: channel.baseUrl, apiKey: channel.apiKey, apiFormat: channel.apiFormat });
const models = await fetchImageModels({ baseUrl: channel.baseUrl, apiKey: channel.apiKey, apiFormat: channel.apiFormat });
return { models, catalog: models.map((id) => ({ id })) };
}
try {
// 登录态由同源后端代取模型目录,避免每个 OpenAI 兼容服务分别维护浏览器 CORS 白名单。
const response = await axios.post<{ code?: number; data?: { models?: string[] }; msg?: string }>(
const response = await axios.post<{ code?: number; data?: { models?: Array<string | ChannelModelCatalogItem> }; msg?: string }>(
resolveBackendApiUrl("/api/ai/models"),
{
baseUrl: channel.baseUrl,
@@ -1114,7 +1119,16 @@ export async function fetchChannelModels(channel: ModelChannel, viaBackend = fal
if (typeof response.data.code === "number" && response.data.code !== 0) {
throw new Error(response.data.msg || "读取模型失败");
}
return Array.from(new Set((response.data.data?.models || []).map((model) => model.trim()).filter(Boolean))).sort((a, b) => a.localeCompare(b));
const catalog = new Map<string, ChannelModelCatalogItem>();
for (const item of response.data.data?.models || []) {
const entry = typeof item === "string" ? { id: item.trim() } : { id: String(item.id || "").trim(), supportedEndpointTypes: Array.isArray(item.supportedEndpointTypes) ? item.supportedEndpointTypes : undefined };
if (!entry.id) continue;
const existing = catalog.get(entry.id);
catalog.set(entry.id, existing || entry);
}
const models = Array.from(catalog.keys()).sort((a, b) => a.localeCompare(b));
const sortedCatalog = Array.from(catalog.values()).sort((a, b) => a.id.localeCompare(b.id));
return { models, catalog: sortedCatalog };
} catch (error) {
throw new Error(readAxiosError(error, "读取模型失败"));
}