import OpenAI from "openai"; import storage from 'node-persist' import { sendMsg } from "../lib/qq"; import prompt from './prompt.txt' await storage.init(); storage.clear(); const client = new OpenAI({ baseURL: process.env.OPENAI_BASE_URL, apiKey: process.env.OPENAI_API_KEY, // logLevel: "debug" }) const tools = [{ type: "function" as const, name: "send_msg", description: "Send a message to the user. Always use this to respond to the user.", parameters: { type: "object", properties: { text: { type: "string", description: "The message content sent to the user through QQ." } }, required: ["text"], additionalProperties: false }, strict: true }] /** * * @param input 提问 * @param target_id 用户 QQ 号 */ export async function chat(input: string, target_id: string) { const chatHistoryKey = `chat_history_${target_id}`; let chatHistory: OpenAI.Responses.ResponseInput = await storage.getItem(chatHistoryKey) || []; // 添加新输入到对话历史 chatHistory.push({ role: "user", content: input }); // 保存更新后的对话历史 console.log(`[LLM] 使用对话, 历史:`, chatHistory); await storage.setItem(chatHistoryKey, chatHistory); const response = await client.responses.create({ model: process.env.CHAT_MODEL || "gpt-5-nano", instructions: prompt, reasoning: { effort: 'minimal' }, input: chatHistory, tools }); await storage.setItem(chatHistoryKey, chatHistory); // 继续调用工具,直到没有工具调用为止 await toolUseCycle(response.output); async function toolUseCycle(outputArr: OpenAI.Responses.ResponseOutputItem[]) { chatHistory.push(...outputArr); const functionCalls = (outputArr ?? []).filter(item => item.type === 'function_call'); console.log("进入 toolUseCycle, with functionCalls", functionCalls.length, "个"); console.log(JSON.stringify(chatHistory, null, 2)); if (functionCalls.length == 0) { let lastMessage = outputArr.at(-1); if (!lastMessage) return if (lastMessage.type != 'message') return if (lastMessage.role != 'assistant') return const msg = lastMessage.content.map(c => c.type == 'output_text' ? c.text : '').join(''); if (msg.trim().length > 0) { // 结束,发送最后的消息 sendMsg(msg, target_id); } return } for (const item of functionCalls ?? []) { if (item.name === "send_msg") { console.log(item.arguments); const { text } = JSON.parse(item.arguments); sendMsg(text, target_id); chatHistory.push({ type: "function_call_output", call_id: item.call_id, output: "OK" }); } } await storage.setItem(chatHistoryKey, chatHistory); const response = await client.responses.create({ model: process.env.CHAT_MODEL || "gpt-5-nano", instructions: prompt, reasoning: { effort: 'minimal' }, input: chatHistory, tools }); toolUseCycle(response.output); } } export async function resetChat(target_id: string) { const chatHistoryKey = `chat_history_${target_id}`; await storage.removeItem(chatHistoryKey); sendMsg("已为你重置对话历史。", target_id); }