Your Name 9cb6a779c3
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix: align agent avatar with auto image model setting
2026-02-20 17:51:10 +08:00

126 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { auth } from "@/app/(auth)/auth";
import {
getAgentAiModelWithProvider,
getDefaultAiModel,
getEnabledAiModelsWithProvider,
getSiteSettings,
} from "@/lib/db/queries";
import { ChatSDKError } from "@/lib/errors";
import { isAiModelAgentAuto } from "@/lib/db/ai-model-flags";
function sortModelsForDisplay<T extends { sortOrder?: number | null; displayName?: string | null }>(
models: T[]
) {
return [...models].sort((a, b) => {
const leftOrder = Number.isFinite(a.sortOrder as number) ? Number(a.sortOrder) : 0;
const rightOrder = Number.isFinite(b.sortOrder as number) ? Number(b.sortOrder) : 0;
if (leftOrder !== rightOrder) return leftOrder - rightOrder;
const leftName = String(a.displayName || "");
const rightName = String(b.displayName || "");
return leftName.localeCompare(rightName, "zh-Hans-CN");
});
}
// 获取前端可用的 AI 模型列表(需要登录但不需要管理员权限)
export async function GET() {
try {
const session = await auth();
if (!session?.user) {
return new ChatSDKError("unauthorized:chat").toResponse();
}
// 只获取主模型(不包括子模型),子模型由后端根据 videoParams.mode 自动选择
const modelsWithProvider = await getEnabledAiModelsWithProvider(false);
const agentModelWithProvider = await getAgentAiModelWithProvider();
const defaultModel = await getDefaultAiModel();
const siteSettings = await getSiteSettings();
const visibleModelsWithProvider = sortModelsForDisplay(
modelsWithProvider
.filter(({ model }) => !isAiModelAgentAuto(model))
.map((item) => item.model)
);
const visibleModelIdSet = new Set(visibleModelsWithProvider.map((m) => m.id));
const visibleModelsWithProviderSorted = modelsWithProvider.filter(({ model }) =>
visibleModelIdSet.has(model.id)
).sort((a, b) => {
const left = visibleModelsWithProvider.findIndex((m) => m.id === a.model.id);
const right = visibleModelsWithProvider.findIndex((m) => m.id === b.model.id);
return left - right;
});
// 转换为前端需要的格式
const models = visibleModelsWithProviderSorted.map(({ model, provider }) => ({
id: model.id,
modelId: model.modelId,
displayName: model.displayName,
avatarUrl: model.avatarUrl,
description: model.description,
supportsVision: model.supportsVision,
supportsImageGen: model.supportsImageGen,
isDefault: model.isDefault,
providerName: provider.name,
providerType: provider.type,
isSubModel: model.isSubModel,
parentModelId: model.parentModelId,
capabilities: model.capabilities, // 🆕 返回子模型的能力配置
imageGenConfig: model.imageGenConfig,
sortOrder: model.sortOrder ?? 0,
}));
// Agent 模式在前端展示头像/参数时,优先使用“Agent模式 - 默认生图模型”的配置
// 避免展示成分析模型(如视觉模型)的头像,导致与管理员设置不一致
const imageGenModelsWithProvider = visibleModelsWithProviderSorted.filter(
({ model }) => model.supportsImageGen
);
const configuredAutoImageModelId =
typeof siteSettings?.canvasAutoModeDefaultModelId === "string"
? siteSettings.canvasAutoModeDefaultModelId.trim()
: "";
const configuredAutoImageModel = configuredAutoImageModelId
? imageGenModelsWithProvider.find(
({ model }) => model.id === configuredAutoImageModelId
)
: undefined;
const defaultImageGenModel =
(defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
defaultModel.supportsImageGen
? imageGenModelsWithProvider.find(({ model }) => model.id === defaultModel.id)
: undefined) || imageGenModelsWithProvider[0];
const agentDisplayModelWithProvider =
configuredAutoImageModel ||
defaultImageGenModel ||
agentModelWithProvider ||
null;
const resolvedDefaultModelId =
(defaultModel &&
!isAiModelAgentAuto(defaultModel) &&
models.some((model) => model.id === defaultModel.id)
? defaultModel.id
: models.find((model) => model.isDefault)?.id) ??
models[0]?.id ??
null;
return Response.json({
models,
defaultModelId: resolvedDefaultModelId,
agentModel: agentDisplayModelWithProvider
? {
id: agentDisplayModelWithProvider.model.id,
displayName: agentDisplayModelWithProvider.model.displayName,
avatarUrl: agentDisplayModelWithProvider.model.avatarUrl,
providerType: agentDisplayModelWithProvider.provider.type,
imageGenConfig: agentDisplayModelWithProvider.model.imageGenConfig,
}
: null,
});
} catch (error) {
if (error instanceof ChatSDKError) {
return error.toResponse();
}
return new ChatSDKError("offline:chat").toResponse();
}
}