Files
18xchat/assets/Scripts/test/ChatAIService.ts
T

204 lines
5.8 KiB
TypeScript

import { GoogleGenAI } from "@google/genai";
import { RoleConfig } from "./RoleConfig";
import { ChatHistoryManager } from "./ChatHistoryManager";
// API配置
const API_CONFIG = {
apiKey: "AIzaSyBJT_68Fc-sKPp_lYSbQmDck0otsd3uKn8",
model: "gemini-2.5-flash",
temperature: 0.7
};
/**
* AI聊天服务
* 管理多个独立的聊天实例,每个角色有独立的对话上下文
*/
export class ChatAIService {
private static _instance: ChatAIService;
private ai: GoogleGenAI;
private chatInstances: Map<number, any> = new Map();
private currentRoleId: number | null = null;
private constructor() {
this.ai = new GoogleGenAI({ apiKey: API_CONFIG.apiKey });
}
/**
* 获取单例实例
*/
public static get Instance(): ChatAIService {
if (!this._instance) {
this._instance = new ChatAIService();
}
return this._instance;
}
/**
* 创建或获取指定角色的聊天实例
* @param roleId 角色ID
*/
private createOrGetChat(roleId: number): any {
if (!this.chatInstances.has(roleId)) {
const systemInstruction = RoleConfig.getRoleInstruction(roleId);
// 从本地加载历史记录
const savedHistory = ChatHistoryManager.Instance.loadHistory(roleId);
let chat;
if(savedHistory && savedHistory.length > 0) {
chat = this.ai.chats.create({
model: API_CONFIG.model,
config: {
temperature: API_CONFIG.temperature,
systemInstruction: systemInstruction
},
history: savedHistory
});
}else{
chat = this.ai.chats.create({
model: API_CONFIG.model,
config: {
temperature: API_CONFIG.temperature,
systemInstruction: systemInstruction
}
});
}
this.chatInstances.set(roleId, chat);
if (savedHistory.length > 0) {
console.log(`Loaded ${savedHistory.length} history messages for role ${roleId}`);
} else {
console.log(`Created new chat instance for role ${roleId}`);
}
}
return this.chatInstances.get(roleId);
}
/**
* 设置当前活动的角色ID
* @param roleId 角色ID
*/
public setCurrentRole(roleId: number): void {
this.currentRoleId = roleId;
// 预创建聊天实例
this.createOrGetChat(roleId);
}
/**
* 获取当前角色ID
*/
public getCurrentRoleId(): number | null {
return this.currentRoleId;
}
/**
* 发送消息到AI
* @param roleId 角色ID
* @param message 用户消息
*/
public async sendMessage(roleId: number, message: string): Promise<string> {
try {
const chat = this.createOrGetChat(roleId);
const response = await chat.sendMessage({
message: message
});
if (response && response.text) {
console.log(`Response from role ${roleId}:`, response.text);
// 保存用户消息
ChatHistoryManager.Instance.appendMessage(roleId, {
role: "user",
parts: [{ text: message }]
});
// 保存AI回复
ChatHistoryManager.Instance.appendMessage(roleId, {
role: "model",
parts: [{ text: response.text }]
});
return response.text;
} else {
console.warn(`Empty response from role ${roleId}`);
return null;
}
} catch (error) {
console.error(`Error sending message to role ${roleId}:`, error);
return null;
}
}
/**
* 清除指定角色的聊天历史
* @param roleId 角色ID
*/
public clearChatHistory(roleId: number): void {
if (this.chatInstances.has(roleId)) {
this.chatInstances.delete(roleId);
}
// 清除本地存储的历史
ChatHistoryManager.Instance.clearHistory(roleId);
console.log(`Cleared chat history for role ${roleId}`);
}
/**
* 清除所有聊天历史
*/
public clearAllChatHistory(): void {
this.chatInstances.clear();
// 清除本地存储的所有历史
ChatHistoryManager.Instance.clearAllHistory();
console.log("Cleared all chat histories");
}
/**
* 获取当前活跃的聊天实例数量
*/
public getActiveChatCount(): number {
return this.chatInstances.size;
}
/**
* 兼容旧接口的Post方法
* @deprecated 请使用sendMessage方法
*/
public async Post(data: GPTRequest): Promise<string> {
const roleId = this.currentRoleId || 10001; // 默认使用第一个角色
const message = data.messages[0]?.content || "";
return this.sendMessage(roleId, message);
}
}
// 请求数据类型定义
export interface GPTRequest {
model: string;
messages: { role: string; content: string }[];
temperature: number;
id: string;
}
// 兼容旧名称
export type GPTResquest = GPTRequest;
// 响应数据类型定义(保留以备后用)
export interface GPTResult {
id: string;
object: string;
created: number;
model: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
choices: {
message: {
role: string;
content: string;
};
finish_reason: string;
index: number;
}[];
}