Files
bella/core.js
你的名字 7f6cf5c40c feat(chat): add chat interface and integrate with BellaAI core
- Implement chat interface with toggle functionality
- Add chat control panel to main UI
- Integrate chat with BellaAI for message processing
- Include test chat interface for debugging
- Add styling for chat components
- Support both local and cloud AI providers
2025-07-24 10:12:34 +08:00

228 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// core.js - Bella's Brain (v3)
// 贝拉的核心AI逻辑支持本地模型和云端API的混合架构
import { pipeline, env, AutoTokenizer, AutoModelForSpeechSeq2Seq } from './vendor/transformers.js';
import CloudAPIService from './cloudAPI.js';
// 本地模型配置
env.allowLocalModels = true;
env.useBrowserCache = false;
env.allowRemoteModels = false;
env.backends.onnx.logLevel = 'verbose';
env.localModelPath = './models/';
class BellaAI {
static instance = null;
static async getInstance() {
if (this.instance === null) {
this.instance = new BellaAI();
await this.instance.init();
}
return this.instance;
}
constructor() {
this.cloudAPI = new CloudAPIService();
this.useCloudAPI = false; // 默认使用本地模型
this.currentMode = 'casual'; // 聊天模式casual, assistant, creative
}
async init() {
console.log('Initializing Bella\'s core AI...');
// 优先加载LLM模型聊天功能
try {
console.log('Loading LLM model...');
this.llm = await pipeline('text2text-generation', 'Xenova/LaMini-Flan-T5-77M');
console.log('LLM model loaded successfully.');
} catch (error) {
console.error('Failed to load LLM model:', error);
// LLM加载失败但不阻止初始化
}
// 尝试加载ASR模型语音识别功能
try {
console.log('Loading ASR model...');
const modelPath = 'Xenova/whisper-asr';
const tokenizer = await AutoTokenizer.from_pretrained(modelPath);
const model = await AutoModelForSpeechSeq2Seq.from_pretrained(modelPath);
this.asr = await pipeline('automatic-speech-recognition', model, { tokenizer });
console.log('ASR model loaded successfully.');
} catch (error) {
console.warn('ASR model failed to load, voice recognition will be disabled:', error);
// ASR加载失败但不影响聊天功能
this.asr = null;
}
// TTS模型暂时禁用
// try {
// console.log('Loading TTS model...');
// this.tts = await pipeline('text-to-speech', 'Xenova/speecht5_tts', { quantized: false });
// console.log('TTS model loaded successfully.');
// } catch (error) {
// console.warn('TTS model failed to load, voice synthesis will be disabled:', error);
// this.tts = null;
// }
console.log('Bella\'s core AI initialized successfully.');
}
async think(prompt) {
try {
// 如果启用了云端API且配置正确优先使用云端服务
if (this.useCloudAPI && this.cloudAPI.isConfigured()) {
return await this.thinkWithCloudAPI(prompt);
}
// 否则使用本地模型
return await this.thinkWithLocalModel(prompt);
} catch (error) {
console.error('思考过程中出现错误:', error);
// 如果云端API失败尝试降级到本地模型
if (this.useCloudAPI) {
console.log('云端API失败降级到本地模型...');
try {
return await this.thinkWithLocalModel(prompt);
} catch (localError) {
console.error('本地模型也失败了:', localError);
}
}
return this.getErrorResponse();
}
}
// 使用云端API进行思考
async thinkWithCloudAPI(prompt) {
const enhancedPrompt = this.enhancePromptForMode(prompt);
return await this.cloudAPI.chat(enhancedPrompt);
}
// 使用本地模型进行思考
async thinkWithLocalModel(prompt) {
if (!this.llm) {
return "我还在学习如何思考,请稍等片刻...";
}
const bellaPrompt = this.enhancePromptForMode(prompt, true);
const result = await this.llm(bellaPrompt, {
max_new_tokens: 50,
temperature: 0.8,
top_k: 40,
do_sample: true,
});
// 清理生成的文本
let response = result[0].generated_text;
if (response.includes(bellaPrompt)) {
response = response.replace(bellaPrompt, '').trim();
}
return response || "我需要再想想...";
}
// 根据模式增强提示词
enhancePromptForMode(prompt, isLocal = false) {
const modePrompts = {
casual: isLocal ?
`作为一个温暖、可爱的AI伙伴贝拉用轻松亲切的语气回应${prompt}` :
`请用温暖、轻松的语气回应,就像一个贴心的朋友。保持简洁有趣:${prompt}`,
assistant: isLocal ?
`作为智能助手贝拉,提供有用、准确的帮助:${prompt}` :
`作为一个专业但温暖的AI助手提供准确有用的信息和建议${prompt}`,
creative: isLocal ?
`作为富有创意的AI伙伴贝拉发挥想象力回应${prompt}` :
`发挥创意和想象力,提供有趣、独特的回应和想法:${prompt}`
};
return modePrompts[this.currentMode] || modePrompts.casual;
}
// 获取错误回应
getErrorResponse() {
const errorResponses = [
"抱歉,我现在有点困惑,让我重新整理一下思路...",
"嗯...我需要再想想,请稍等一下。",
"我的思绪有点乱,给我一点时间整理一下。",
"让我重新组织一下语言,稍等片刻。"
];
return errorResponses[Math.floor(Math.random() * errorResponses.length)];
}
// 设置聊天模式
setChatMode(mode) {
if (['casual', 'assistant', 'creative'].includes(mode)) {
this.currentMode = mode;
return true;
}
return false;
}
// 切换AI服务提供商
switchProvider(provider) {
if (provider === 'local') {
this.useCloudAPI = false;
return true;
} else {
const success = this.cloudAPI.switchProvider(provider);
if (success) {
this.useCloudAPI = true;
}
return success;
}
}
// 设置API密钥
setAPIKey(provider, apiKey) {
return this.cloudAPI.setAPIKey(provider, apiKey);
}
// 清除对话历史
clearHistory() {
this.cloudAPI.clearHistory();
}
// 获取当前配置信息
getCurrentConfig() {
return {
useCloudAPI: this.useCloudAPI,
provider: this.useCloudAPI ? this.cloudAPI.getCurrentProvider() : { name: 'local', model: 'LaMini-Flan-T5-77M' },
mode: this.currentMode,
isConfigured: this.useCloudAPI ? this.cloudAPI.isConfigured() : true
};
}
async listen(audioData) {
if (!this.asr) {
throw new Error('语音识别模型未初始化');
}
const result = await this.asr(audioData);
return result.text;
}
async speak(text) {
if (!this.tts) {
throw new Error('语音合成模型未初始化');
}
// We need speaker embeddings for SpeechT5
const speaker_embeddings = 'models/Xenova/speecht5_tts/speaker_embeddings.bin';
const result = await this.tts(text, {
speaker_embeddings,
});
return result.audio;
}
// 获取云端API服务实例用于外部访问
getCloudAPIService() {
return this.cloudAPI;
}
}
// ES6模块导出
export { BellaAI };