You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
1.8 KiB
56 lines
1.8 KiB
import { requireUser } from "#server/utils/context";
|
|
import { getProviderById, getModelById } from "#server/service/llm";
|
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
import { streamText } from "ai";
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
if (!user) {
|
|
throw createError({ statusCode: 401, statusMessage: "未登录" });
|
|
}
|
|
|
|
const body = await readBody(event);
|
|
const { modelId: llmModelId, messages, enableThinking } = body as {
|
|
modelId: number;
|
|
messages: { role: "user" | "assistant" | "system"; content: string }[];
|
|
enableThinking?: boolean;
|
|
};
|
|
|
|
if (!llmModelId || !messages || !Array.isArray(messages) || messages.length === 0) {
|
|
throw createError({ statusCode: 400, statusMessage: "参数无效" });
|
|
}
|
|
|
|
const model = await getModelById(llmModelId, user.id);
|
|
if (!model) {
|
|
throw createError({ statusCode: 404, statusMessage: "模型不存在" });
|
|
}
|
|
|
|
const provider = await getProviderById(model.providerId, user.id);
|
|
if (!provider) {
|
|
throw createError({ statusCode: 404, statusMessage: "供应商不存在" });
|
|
}
|
|
|
|
if (provider.status !== "active") {
|
|
throw createError({ statusCode: 400, statusMessage: "供应商已禁用" });
|
|
}
|
|
|
|
if (!provider.apiKey) {
|
|
throw createError({ statusCode: 400, statusMessage: "供应商未配置 API Key" });
|
|
}
|
|
|
|
const baseUrl = provider.baseUrl?.replace(/\/+$/, "") || undefined;
|
|
|
|
const openai = createOpenAI({
|
|
apiKey: provider.apiKey,
|
|
baseURL: baseUrl,
|
|
});
|
|
|
|
const result = streamText({
|
|
model: openai(model.modelId),
|
|
messages,
|
|
maxTokens: model.maxTokens || undefined,
|
|
...(enableThinking ? { providerOptions: { openai: { reasoningEffort: 'high' } } } : {}),
|
|
});
|
|
|
|
return result.toDataStreamResponse({ sendReasoning: true });
|
|
});
|
|
|