feat(对话): 扩展对话管理支持助手关联
- 对话创建接口支持关联助手ID和系统提示词 - 对话查询接口返回关联的助手信息 - 聊天接口支持使用助手系统提示词 - useConversations Hook 扩展助手相关参数
This commit is contained in:
parent
2d4bdfb7f5
commit
a5fcc9edae
@ -269,15 +269,26 @@ export async function POST(request: Request) {
|
|||||||
try {
|
try {
|
||||||
const cchUrl = settings.cchUrl || 'http://localhost:13500';
|
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', {
|
const currentDate = new Date().toLocaleDateString('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
weekday: 'long',
|
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');
|
const temperature = parseFloat(conversation.temperature || settings.temperature || '0.7');
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import { db } from '@/drizzle/db';
|
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 { eq, asc, and } from 'drizzle-orm';
|
||||||
import { getCurrentUser } from '@/lib/auth';
|
import { getCurrentUser } from '@/lib/auth';
|
||||||
|
|
||||||
@ -41,9 +41,23 @@ export async function GET(request: Request, { params }: RouteParams) {
|
|||||||
orderBy: [asc(messages.createdAt)],
|
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({
|
return NextResponse.json({
|
||||||
...conversation,
|
...conversation,
|
||||||
messages: messageList,
|
messages: messageList,
|
||||||
|
assistant: assistant ? {
|
||||||
|
id: assistant.id,
|
||||||
|
name: assistant.name,
|
||||||
|
icon: assistant.icon,
|
||||||
|
description: assistant.description,
|
||||||
|
} : null,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get conversation:', 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 { id } = await params;
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const { title, isPinned, isArchived } = body;
|
const { title, isPinned, isArchived, model } = body;
|
||||||
|
|
||||||
// 验证对话属于当前用户
|
// 验证对话属于当前用户
|
||||||
const existingConversation = await db.query.conversations.findFirst({
|
const existingConversation = await db.query.conversations.findFirst({
|
||||||
@ -101,6 +115,10 @@ export async function PUT(request: Request, { params }: RouteParams) {
|
|||||||
updateData.isArchived = isArchived;
|
updateData.isArchived = isArchived;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model !== undefined) {
|
||||||
|
updateData.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
const [updated] = await db
|
const [updated] = await db
|
||||||
.update(conversations)
|
.update(conversations)
|
||||||
.set(updateData)
|
.set(updateData)
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const { title, model, tools, enableThinking } = body;
|
const { title, model, tools, enableThinking, assistantId, systemPrompt } = body;
|
||||||
|
|
||||||
const conversationId = nanoid();
|
const conversationId = nanoid();
|
||||||
|
|
||||||
@ -61,6 +61,8 @@ export async function POST(request: Request) {
|
|||||||
tools: tools || [],
|
tools: tools || [],
|
||||||
enableThinking: enableThinking || false,
|
enableThinking: enableThinking || false,
|
||||||
userId: user.userId, // 关联当前用户
|
userId: user.userId, // 关联当前用户
|
||||||
|
assistantId: assistantId || null, // 关联助手
|
||||||
|
systemPrompt: systemPrompt || null, // 对话专属系统提示词(来自助手)
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,16 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import type { Conversation, Message } from '@/drizzle/schema';
|
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 {
|
export interface ConversationWithMessages extends Conversation {
|
||||||
messages: Message[];
|
messages: Message[];
|
||||||
|
assistant?: AssistantInfo | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useConversations() {
|
export function useConversations() {
|
||||||
@ -34,6 +42,8 @@ export function useConversations() {
|
|||||||
model: string;
|
model: string;
|
||||||
tools?: string[];
|
tools?: string[];
|
||||||
enableThinking?: boolean;
|
enableThinking?: boolean;
|
||||||
|
assistantId?: number;
|
||||||
|
systemPrompt?: string;
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/conversations', {
|
const response = await fetch('/api/conversations', {
|
||||||
@ -54,7 +64,7 @@ export function useConversations() {
|
|||||||
|
|
||||||
const updateConversation = useCallback(async (
|
const updateConversation = useCallback(async (
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
data: { title?: string; isPinned?: boolean; isArchived?: boolean }
|
data: { title?: string; isPinned?: boolean; isArchived?: boolean; model?: string }
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/conversations/${conversationId}`, {
|
const response = await fetch(`/api/conversations/${conversationId}`, {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user