From a5fcc9edae506d7e3e68b78ac0c360a60a9f46bf Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Sat, 20 Dec 2025 20:46:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=AF=B9=E8=AF=9D):=20=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E7=AE=A1=E7=90=86=E6=94=AF=E6=8C=81=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 对话创建接口支持关联助手ID和系统提示词 - 对话查询接口返回关联的助手信息 - 聊天接口支持使用助手系统提示词 - useConversations Hook 扩展助手相关参数 --- src/app/api/chat/route.ts | 17 ++++++++++++++--- src/app/api/conversations/[id]/route.ts | 22 ++++++++++++++++++++-- src/app/api/conversations/route.ts | 4 +++- src/hooks/useConversations.ts | 12 +++++++++++- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/app/api/chat/route.ts b/src/app/api/chat/route.ts index 856218c..af164e9 100644 --- a/src/app/api/chat/route.ts +++ b/src/app/api/chat/route.ts @@ -269,15 +269,26 @@ export async function POST(request: Request) { try { const cchUrl = settings.cchUrl || 'http://localhost:13500'; - // 获取系统提示词 - const baseSystemPrompt = conversation.systemPrompt || settings.systemPrompt || DEFAULT_SYSTEM_PROMPT; + // 获取系统提示词(叠加模式) + // 1. 始终使用 DEFAULT_SYSTEM_PROMPT 作为基础 + // 2. 如果对话有关联助手的提示词(conversation.systemPrompt),则叠加到默认提示词后面 + // 3. 助手提示词替代设置页面的自定义提示词,不替代默认提示词 const currentDate = new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long', }); - const systemPrompt = baseSystemPrompt.replace('{{CURRENT_DATE}}', currentDate); + const basePrompt = DEFAULT_SYSTEM_PROMPT.replace('{{CURRENT_DATE}}', currentDate); + + // 叠加助手提示词 + let systemPrompt = basePrompt; + if (conversation.systemPrompt) { + systemPrompt = `${basePrompt}\n\n---\n\n## 🎭 当前助手角色设定\n\n${conversation.systemPrompt}`; + console.log('[API/chat] 🎭 使用助手提示词:', conversation.systemPrompt.substring(0, 100) + '...'); + } else { + console.log('[API/chat] 📝 无助手提示词,使用默认提示词'); + } // 获取温度参数 const temperature = parseFloat(conversation.temperature || settings.temperature || '0.7'); diff --git a/src/app/api/conversations/[id]/route.ts b/src/app/api/conversations/[id]/route.ts index 1d06050..5b77f3c 100644 --- a/src/app/api/conversations/[id]/route.ts +++ b/src/app/api/conversations/[id]/route.ts @@ -1,6 +1,6 @@ import { NextResponse } from 'next/server'; import { db } from '@/drizzle/db'; -import { conversations, messages } from '@/drizzle/schema'; +import { conversations, messages, assistants } from '@/drizzle/schema'; import { eq, asc, and } from 'drizzle-orm'; import { getCurrentUser } from '@/lib/auth'; @@ -41,9 +41,23 @@ export async function GET(request: Request, { params }: RouteParams) { orderBy: [asc(messages.createdAt)], }); + // 如果有关联助手,获取助手信息 + let assistant = null; + if (conversation.assistantId) { + assistant = await db.query.assistants.findFirst({ + where: eq(assistants.id, conversation.assistantId), + }); + } + return NextResponse.json({ ...conversation, messages: messageList, + assistant: assistant ? { + id: assistant.id, + name: assistant.name, + icon: assistant.icon, + description: assistant.description, + } : null, }); } catch (error) { console.error('Failed to get conversation:', error); @@ -68,7 +82,7 @@ export async function PUT(request: Request, { params }: RouteParams) { const { id } = await params; const body = await request.json(); - const { title, isPinned, isArchived } = body; + const { title, isPinned, isArchived, model } = body; // 验证对话属于当前用户 const existingConversation = await db.query.conversations.findFirst({ @@ -101,6 +115,10 @@ export async function PUT(request: Request, { params }: RouteParams) { updateData.isArchived = isArchived; } + if (model !== undefined) { + updateData.model = model; + } + const [updated] = await db .update(conversations) .set(updateData) diff --git a/src/app/api/conversations/route.ts b/src/app/api/conversations/route.ts index acd1030..2a6a84a 100644 --- a/src/app/api/conversations/route.ts +++ b/src/app/api/conversations/route.ts @@ -48,7 +48,7 @@ export async function POST(request: Request) { } const body = await request.json(); - const { title, model, tools, enableThinking } = body; + const { title, model, tools, enableThinking, assistantId, systemPrompt } = body; const conversationId = nanoid(); @@ -61,6 +61,8 @@ export async function POST(request: Request) { tools: tools || [], enableThinking: enableThinking || false, userId: user.userId, // 关联当前用户 + assistantId: assistantId || null, // 关联助手 + systemPrompt: systemPrompt || null, // 对话专属系统提示词(来自助手) }) .returning(); diff --git a/src/hooks/useConversations.ts b/src/hooks/useConversations.ts index d65e22d..0c32697 100644 --- a/src/hooks/useConversations.ts +++ b/src/hooks/useConversations.ts @@ -3,8 +3,16 @@ import { useState, useEffect, useCallback } from 'react'; import type { Conversation, Message } from '@/drizzle/schema'; +export interface AssistantInfo { + id: number; + name: string; + icon: string | null; + description: string | null; +} + export interface ConversationWithMessages extends Conversation { messages: Message[]; + assistant?: AssistantInfo | null; } export function useConversations() { @@ -34,6 +42,8 @@ export function useConversations() { model: string; tools?: string[]; enableThinking?: boolean; + assistantId?: number; + systemPrompt?: string; }) => { try { const response = await fetch('/api/conversations', { @@ -54,7 +64,7 @@ export function useConversations() { const updateConversation = useCallback(async ( conversationId: string, - data: { title?: string; isPinned?: boolean; isArchived?: boolean } + data: { title?: string; isPinned?: boolean; isArchived?: boolean; model?: string } ) => { try { const response = await fetch(`/api/conversations/${conversationId}`, {