ai-chatbot/app/(chat)/actions.ts
Your Name 8aba32d35d
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix chat pending drop when title model fails and filter auto-title vision model
2026-02-19 04:54:58 +08:00

68 lines
1.8 KiB
TypeScript

"use server";
import { generateText, type UIMessage } from "ai";
import { cookies } from "next/headers";
import type { VisibilityType } from "@/components/visibility-selector";
import { titlePrompt } from "@/lib/ai/prompts";
import { myProvider } from "@/lib/ai/providers";
import { getSystemModel } from "@/lib/ai/dynamic-provider";
import {
deleteMessagesByChatIdAfterTimestamp,
getMessageById,
updateChatVisibilityById,
} from "@/lib/db/queries";
import { getTextFromMessage } from "@/lib/utils";
export async function saveChatModelAsCookie(model: string) {
const cookieStore = await cookies();
cookieStore.set("chat-model", model);
}
export async function generateTitleFromUserMessage({
message,
}: {
message: UIMessage;
}) {
const prompt = (getTextFromMessage(message) || "").trim();
const fallbackTitle = prompt.slice(0, 20) || "新对话";
try {
// 优先使用数据库配置的模型,回退到预定义模型
let model = await getSystemModel("title");
if (!model) {
model = myProvider.languageModel("title-model");
}
const { text: title } = await generateText({
model,
system: titlePrompt,
prompt,
});
const normalized = (title || "").trim();
return normalized || fallbackTitle;
} catch (error) {
console.warn("[generateTitleFromUserMessage] fallback title:", error);
return fallbackTitle;
}
}
export async function deleteTrailingMessages({ id }: { id: string }) {
const [message] = await getMessageById({ id });
await deleteMessagesByChatIdAfterTimestamp({
chatId: message.chatId,
timestamp: message.createdAt,
});
}
export async function updateChatVisibility({
chatId,
visibility,
}: {
chatId: string;
visibility: VisibilityType;
}) {
await updateChatVisibilityById({ chatId, visibility });
}