add scheduler api

This commit is contained in:
maojindao55
2025-02-24 17:00:23 +08:00
parent cf4249b970
commit b52f2acfd5
3 changed files with 177 additions and 14 deletions

126
functions/api/scheduler.ts Normal file
View File

@@ -0,0 +1,126 @@
import { modelConfigs, shedulerAICharacter } from '../../src/config/aiCharacters';
import OpenAI from 'openai';
interface AICharacter {
id: string;
name: string;
tags?: string[];
}
interface MessageHistory {
role: string;
content: string;
name: string;
}
export async function onRequestPost({ env, request }) {
try {
const { message, history, availableAIs } = await request.json();
const selectedAIs = await scheduleAIResponses(message, history, availableAIs);
return Response.json({
selectedAIs: selectedAIs
});
} catch (error) {
console.error(error);
return Response.json(
{ error: error.message },
{ status: 500 }
);
}
}
async function analyzeMessageWithAI(message: string, allTags: string[]): Promise<string[]> {
const shedulerAI = shedulerAICharacter(message, allTags);
const modelConfig = modelConfigs.find(config => config.model === shedulerAI.model);
const openai = new OpenAI({
apiKey: modelConfig.apiKey,
baseURL: modelConfig.baseURL, // DeepSeek API 的基础URL
});
const prompt = shedulerAI.custom_prompt;
try {
const completion = await openai.chat.completions.create({
model: shedulerAI.model,
messages: [
{ role: "user", content: prompt }
],
});
const matchedTags = completion.choices[0].message.content?.split(',').map(tag => tag.trim()) || [];
return matchedTags;
} catch (error) {
console.error('AI分析失败:', error);
return [];
}
}
async function scheduleAIResponses(
message: string,
history: MessageHistory[],
availableAIs: AICharacter[]
): Promise<string[]> {
// 1. 收集所有可用的标签
const allTags = new Set<string>();
availableAIs.forEach(ai => {
ai.tags?.forEach(tag => allTags.add(tag));
});
// 2. 使用AI模型分析消息并匹配标签
const matchedTags = await analyzeMessageWithAI(message, Array.from(allTags));
// 3. 计算每个AI的匹配分数
const aiScores = new Map<string, number>();
const messageLC = message.toLowerCase();
for (const ai of availableAIs) {
if (!ai.tags) continue;
let score = 0;
// 标签匹配分数
matchedTags.forEach(tag => {
if (ai.tags?.includes(tag)) {
score += 2; // 每个匹配的标签得2分
}
});
// 直接提到AI名字额外加分
if (messageLC.includes(ai.name.toLowerCase())) {
score += 5;
}
// 历史对话相关性加分
const recentHistory = history.slice(-5); // 只看最近5条消息
recentHistory.forEach(hist => {
if (hist.name === ai.name && hist.content.length > 0) {
score += 1; // 最近有参与对话的AI加分
}
});
if (score > 0) {
aiScores.set(ai.id, score);
}
}
// 4. 根据分数排序选择AI
const sortedAIs = Array.from(aiScores.entries())
.sort((a, b) => b[1] - a[1])
.map(([id]) => id);
// 5. 如果没有匹配到任何AI随机选择1-2个
if (sortedAIs.length === 0) {
const maxResponders = Math.min(2, availableAIs.length);
const numResponders = Math.floor(Math.random() * maxResponders) + 1;
const shuffledAIs = [...availableAIs]
.sort(() => Math.random() - 0.5)
.slice(0, numResponders);
return shuffledAIs.map(ai => ai.id);
}
// 6. 限制最大回复数量
const MAX_RESPONDERS = 3;
return sortedAIs.slice(0, MAX_RESPONDERS);
}