69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
|
|
import { Injectable, NotFoundException, Logger } from '@nestjs/common';
|
|||
|
|
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
|||
|
|
import { ContentSafetyService } from '../content-safety/content-safety.service';
|
|||
|
|
|
|||
|
|
@Injectable()
|
|||
|
|
export class RagChatService {
|
|||
|
|
private readonly logger = new Logger(RagChatService.name);
|
|||
|
|
|
|||
|
|
constructor(
|
|||
|
|
private readonly prisma: PrismaService,
|
|||
|
|
private readonly safety?: ContentSafetyService,
|
|||
|
|
) {}
|
|||
|
|
|
|||
|
|
async createSession(userId: string, knowledgeBaseId: string, title?: string) {
|
|||
|
|
return this.prisma.chatSession.create({
|
|||
|
|
data: { userId, knowledgeBaseId, title: title || '新对话' },
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async listSessions(userId: string, kbId?: string) {
|
|||
|
|
return this.prisma.chatSession.findMany({
|
|||
|
|
where: { userId, ...(kbId ? { knowledgeBaseId: kbId } : {}) },
|
|||
|
|
orderBy: { updatedAt: 'desc' },
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async getMessages(sessionId: string) {
|
|||
|
|
return this.prisma.chatMessage.findMany({
|
|||
|
|
where: { sessionId },
|
|||
|
|
orderBy: { createdAt: 'asc' },
|
|||
|
|
include: { citations: true },
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async sendMessage(userId: string, sessionId: string, content: string) {
|
|||
|
|
const session = await this.prisma.chatSession.findUnique({ where: { id: sessionId } });
|
|||
|
|
if (!session || session.userId !== userId) throw new NotFoundException('对话不存在');
|
|||
|
|
|
|||
|
|
// Content safety check on user input
|
|||
|
|
const inputCheck = await this.safety?.check(content, { userId, contentType: 'rag_input' });
|
|||
|
|
if (inputCheck && !inputCheck.safe) {
|
|||
|
|
return { blocked: true, message: '输入包含违规内容,请修改后重试' };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Save user message
|
|||
|
|
await this.prisma.chatMessage.create({
|
|||
|
|
data: { sessionId, role: 'user', content },
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Generate AI response (simplified — real RAG pipeline in M3)
|
|||
|
|
const reply = `感谢提问。基于知识库内容,我暂时无法生成完整回答(RAG 检索管道将在后续版本完善)。`;
|
|||
|
|
const aiMsg = await this.prisma.chatMessage.create({
|
|||
|
|
data: { sessionId, role: 'ai', content: reply, tokens: reply.length },
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Update session timestamp
|
|||
|
|
await this.prisma.chatSession.update({ where: { id: sessionId }, data: { updatedAt: new Date() } });
|
|||
|
|
|
|||
|
|
return { message: aiMsg, citations: [] };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async deleteSession(sessionId: string) {
|
|||
|
|
await this.prisma.chatCitation.deleteMany({ where: { message: { sessionId } } });
|
|||
|
|
await this.prisma.chatMessage.deleteMany({ where: { sessionId } });
|
|||
|
|
await this.prisma.chatSession.delete({ where: { id: sessionId } });
|
|||
|
|
return { success: true };
|
|||
|
|
}
|
|||
|
|
}
|