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.
 
 
 
 

82 lines
2.4 KiB

import { generateText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { type LanguageModel } from "ai";
import { getSystemModelWithProviderById, getModelWithProviderById } from "#server/service/llm";
import { updateSession } from "./session";
import log4js from "logger";
const logger = log4js.getLogger("APP");
function resolveModel(
provider: {
name: string;
apiKey: string | null;
baseUrl: string | null;
parseMode: string;
},
modelId: string,
): LanguageModel {
const baseUrl = provider.baseUrl?.replace(/\/+$/, "") || undefined;
if (provider.parseMode === "openai") {
const openai = createOpenAI({
apiKey: provider.apiKey || undefined,
baseURL: baseUrl,
});
return openai(modelId) as unknown as LanguageModel;
}
const openaiCompatible = createOpenAICompatible({
name: provider.name,
apiKey: provider.apiKey || undefined,
baseURL: baseUrl || "https://api.openai.com/v1",
});
return openaiCompatible(modelId) as LanguageModel;
}
export async function generateSessionTitle(
sessionId: string,
firstUserMessage: string,
firstAssistantMessage: string,
titleModelId: number,
userId: number | null,
): Promise<void> {
try {
const modelRow = userId
? await getModelWithProviderById(titleModelId, userId)
: await getSystemModelWithProviderById(titleModelId);
if (!modelRow) {
logger.warn("[AGENT-TITLE] titleModelId=%d not found, skip", titleModelId);
return;
}
const { model, provider } = modelRow;
if (!provider.apiKey) {
logger.warn("[AGENT-TITLE] provider has no apiKey, skip");
return;
}
const languageModel = resolveModel(provider, model.modelId);
const prompt = `请根据以下对话生成一个简短的标题(不超过20个字,不要加引号、不要加书名号):
用户: ${firstUserMessage.slice(0, 500)}
助手: ${firstAssistantMessage.slice(0, 500)}
标题:`;
const result = await generateText({
model: languageModel,
prompt,
maxOutputTokens: 200,
});
const title = result.text.trim().slice(0, 100);
if (title) {
await updateSession(sessionId, { title });
logger.info("[AGENT-TITLE] sessionId=%s title=%s", sessionId, title);
}
} catch (err) {
logger.error("[AGENT-TITLE] sessionId=%s error: %s", sessionId, err instanceof Error ? err.message : String(err));
}
}