feat: 聊天页优化 — 欢迎页、标题自动生成、消息操作
This commit is contained in:
@@ -29,8 +29,7 @@ export function formatCurrentTime(timezone?: string) {
|
||||
|
||||
export const getCurrentTime = tool({
|
||||
description: "获取当前日期和时间。可选指定时区,默认返回本地时间。",
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
execute: async ({ timezone }) => formatCurrentTime(timezone),
|
||||
execute: ({ timezone }) => Promise.resolve(formatCurrentTime(timezone)),
|
||||
inputSchema: z.object({
|
||||
timezone: z.string().optional().describe("IANA 时区名称,如 'Asia/Shanghai'、'America/New_York'"),
|
||||
}),
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
import type Database from "bun:sqlite";
|
||||
|
||||
import { createAgentUIStreamResponse, type UIMessage } from "ai";
|
||||
import { createAgentUIStreamResponse, generateText, type UIMessage } from "ai";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
import type { RuntimeMode } from "../../../shared/api";
|
||||
import type { Logger } from "../../logger";
|
||||
|
||||
import { createAlfredAgent } from "../../ai/agents/alfred-agent";
|
||||
import { buildProviderRegistry } from "../../ai/registry";
|
||||
import { wrap } from "../../db/connection";
|
||||
import { createMessage, getConversation, updateConversationTimestamp } from "../../db/conversations";
|
||||
import {
|
||||
createMessage,
|
||||
getConversation,
|
||||
updateConversation,
|
||||
updateConversationTimestamp,
|
||||
} from "../../db/conversations";
|
||||
import { models, providers } from "../../db/schema";
|
||||
import { createApiError, jsonResponse } from "../../helpers";
|
||||
import { validateIdParam } from "../../middleware";
|
||||
|
||||
export async function handleSendChat(req: Request, db: Database, mode: RuntimeMode): Promise<Response> {
|
||||
export async function handleSendChat(req: Request, db: Database, mode: RuntimeMode, logger: Logger): Promise<Response> {
|
||||
const url = new URL(req.url);
|
||||
const projectId = url.pathname.split("/")[3];
|
||||
|
||||
@@ -104,6 +110,58 @@ export async function handleSendChat(req: Request, db: Database, mode: RuntimeMo
|
||||
role: "assistant",
|
||||
});
|
||||
updateConversationTimestamp(db, conversation.id);
|
||||
|
||||
try {
|
||||
if (conversation.title === "新会话") {
|
||||
const firstUserText =
|
||||
body.messages
|
||||
?.find((m) => m.role === "user")
|
||||
?.parts?.filter((p) => p.type === "text")
|
||||
?.map((p) => p.text)
|
||||
?.join("") ?? "";
|
||||
|
||||
if (firstUserText) {
|
||||
if (firstUserText.length <= 5) {
|
||||
updateConversation(db, conversation.id, { title: firstUserText });
|
||||
} else {
|
||||
void generateText({
|
||||
model,
|
||||
prompt: `请根据以下对话开头生成一个简短标题(不超过10个字):${firstUserText}`,
|
||||
system: "你是一个标题生成助手,只返回标题文本,不要解释。",
|
||||
})
|
||||
.then((result) => {
|
||||
const title = result.text.trim().slice(0, 10);
|
||||
updateConversation(db, conversation.id, { title: title || firstUserText.slice(0, 10) });
|
||||
})
|
||||
.catch((titleError: unknown) => {
|
||||
const titleMsg = titleError instanceof Error ? titleError.message : String(titleError);
|
||||
logger.error({ conversationId: conversation.id, error: titleMsg }, "标题生成失败");
|
||||
try {
|
||||
updateConversation(db, conversation.id, { title: firstUserText.slice(0, 10) });
|
||||
} catch {
|
||||
logger.error({ conversationId: conversation.id }, "标题兜底更新失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (titleError: unknown) {
|
||||
const titleMsg = titleError instanceof Error ? titleError.message : String(titleError);
|
||||
logger.error({ conversationId: conversation.id, error: titleMsg }, "标题生成失败");
|
||||
try {
|
||||
const fallbackTitle =
|
||||
body.messages
|
||||
?.find((m) => m.role === "user")
|
||||
?.parts?.filter((p) => p.type === "text")
|
||||
?.map((p) => p.text)
|
||||
?.join("")
|
||||
?.slice(0, 10) ?? "新会话";
|
||||
updateConversation(db, conversation.id, { title: fallbackTitle });
|
||||
} catch (fallbackError: unknown) {
|
||||
const fbMsg = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
||||
logger.error({ conversationId: conversation.id, error: fbMsg }, "标题兜底更新失败");
|
||||
}
|
||||
}
|
||||
},
|
||||
uiMessages: body.messages,
|
||||
});
|
||||
|
||||
@@ -160,7 +160,7 @@ export function startServer(options: StartServerOptions) {
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleSendChat } = await import("./routes/chat/send");
|
||||
return handleSendChat(req, db, mode);
|
||||
return handleSendChat(req, db, mode, logger);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
|
||||
Reference in New Issue
Block a user