// code from goatstore // api: https://store.agi.bd const axios = require("axios"); const API_URL = "https://api.anthropic.com/v1/messages"; const MODEL = "claude-sonnet-5-5"; const MAX_HISTORY = 10; // প্রতি ইউজারের শেষ কয়টা মেসেজ মনে রাখবে const MAX_TOKENS = 1000; const CHUNK_SIZE = 1900; // Messenger-এর লিমিটের নিচে রাখা const SYSTEM_PROMPT = "You are a helpful, friendly assistant inside a Messenger group chat. " + "Always reply in the same language the user writes in (Bengali, English, Banglish, etc.). " + "Keep answers short and clear unless the user asks for detail. Avoid heavy markdown."; // userID -> [{ role, content }] const histories = new Map(); function getApiKey() { return ( (global.GoatBot && global.GoatBot.config && global.GoatBot.config.apiKeys && global.GoatBot.config.apiKeys.anthropic) || process.env.ANTHROPIC_API_KEY ); } function splitText(text) { const parts = []; for (let i = 0; i < text.length; i += CHUNK_SIZE) parts.push(text.slice(i, i + CHUNK_SIZE)); return parts; } async function askAI(userID, question) { const apiKey = getApiKey(); if (!apiKey) throw new Error("NO_KEY"); const history = histories.get(userID) || []; history.push({ role: "user", content: question }); const res = await axios.post( API_URL, { model: MODEL, max_tokens: MAX_TOKENS, system: SYSTEM_PROMPT, messages: history }, { headers: { "x-api-key": apiKey, "anthropic-version": "2023-06-01", "content-type": "application/json" }, timeout: 60000 } ); const answer = (res.data.content || []) .filter(b => b.type === "text") .map(b => b.text) .join("\n") .trim() || "কোনো উত্তর পাওয়া যায়নি।"; history.push({ role: "assistant", content: answer }); while (history.length > MAX_HISTORY) history.shift(); // history সবসময় user দিয়ে শুরু হতে হবে while (history.length && history[0].role !== "user") history.shift(); histories.set(userID, history); return answer; } async function sendAnswer({ message, event, commandName }, answer) { const parts = splitText(answer); for (let i = 0; i < parts.length; i++) { const isLast = i === parts.length - 1; await new Promise(resolve => { message.reply(parts[i], (err, info) => { // শেষ মেসেজে রিপ্লাই করলে কথোপকথন চলবে if (!err && info && isLast) { global.GoatBot.onReply.set(info.messageID, { commandName, messageID: info.messageID, author: event.senderID }); } resolve(); }); }); } } async function handle(ctx, question) { const { message, event } = ctx; try { message.reaction("⏳", event.messageID); } catch (e) { } try { const answer = await askAI(event.senderID, question); await sendAnswer(ctx, answer); try { message.reaction("✅", event.messageID); } catch (e) { } } catch (err) { try { message.reaction("❌", event.messageID); } catch (e) { } if (err.message === "NO_KEY") return message.reply("❌ API key সেট করা নেই। config.json-এ apiKeys.anthropic দিন, অথবা ANTHROPIC_API_KEY env সেট করুন।"); const status = err.response && err.response.status; if (status === 401) return message.reply("❌ API key ভুল বা মেয়াদ শেষ।"); if (status === 429) return message.reply("⏳ অনেক বেশি রিকোয়েস্ট হয়েছে, একটু পরে আবার চেষ্টা করুন।"); console.error("[ai.js]", (err.response && err.response.data) || err.message); return message.reply("❌ একটা সমস্যা হয়েছে, পরে আবার চেষ্টা করুন।"); } } module.exports = { config: { name: "ai", aliases: ["ask", "gpt"], version: "1.0", author: "Zihad", countDown: 5, role: 0, description: { en: "Chat with AI (remembers the conversation)", bn: "এআই-এর সাথে চ্যাট করুন (কথোপকথন মনে রাখে)" }, category: "ai", guide: { en: "{pn} \n{pn} clear — reset your chat history\nReply to the bot's answer to continue the conversation.", bn: "{pn} <প্রশ্ন>\n{pn} clear — আপনার চ্যাট হিস্ট্রি মুছুন\nবটের উত্তরে রিপ্লাই দিলে কথোপকথন চলতে থাকবে।" } }, onStart: async function (ctx) { const { message, event, args } = ctx; ctx.commandName = this.config.name; const input = args.join(" ").trim(); if (!input) return message.reply("💬 প্রশ্ন লিখুন।\nউদাহরণ: ai বাংলাদেশের রাজধানী কী?"); if (["clear", "reset"].includes(input.toLowerCase())) { histories.delete(event.senderID); return message.reply("🧹 আপনার চ্যাট হিস্ট্রি মুছে ফেলা হয়েছে।"); } return handle(ctx, input); }, onReply: async function (ctx) { const { event, Reply } = ctx; // শুধু যে প্রশ্ন করেছে সে-ই রিপ্লাই দিয়ে চালিয়ে যেতে পারবে if (Reply.author !== event.senderID) return; const text = (event.body || "").trim(); if (!text) return; ctx.commandName = this.config.name; return handle(ctx, text); } };