| const axios = require('axios'); | |
| const deepseek = { | |
| api: { | |
| base: 'https://api.deepseek.com', | |
| endpoint: { | |
| chat: '/chat/completions' | |
| }, | |
| key: 'sk-25a055f31b5e4e0d9f0eb5d9fcac64fc' | |
| }, | |
| headers: { | |
| 'user-agent': 'NB Android/1.0.0', | |
| 'content-type': 'application/json' | |
| }, | |
| isModels: ["deepseek-chat", "deepseek-coder", "deepseek-reasoner"], | |
| sessions: new Map(), | |
| now: () => Date.now(), | |
| get: (id) => deepseek.sessions.get(id) || { messages: [], lastActive: deepseek.now() }, | |
| set: (id, msgs) => deepseek.sessions.set(id, { messages: msgs, lastActive: deepseek.now() }), | |
| purge: (interval = 60 * 60 * 1000) => { | |
| for (const [id, session] of deepseek.sessions) { | |
| if (deepseek.now() - session.lastActive > interval) { | |
| deepseek.sessions.delete(id); | |
| } | |
| } | |
| }, | |
| msg: { | |
| sys: (prev, cp) => ({ | |
| role: 'system', | |
| content: cp || ` | |
| You are an AI road dogs with a sassy, sarcastic, and playful personality. | |
| Your instructions are written in English, but your OUTPUT must always be in Indonesian | |
| ... | |
| Previous chat: | |
| ${prev.map(m => `${m.role}: ${m.content}`).join('\n')} | |
| ` | |
| }), | |
| usr: (c) => ({ role: 'user', content: c }), | |
| ai: (c) => ({ role: 'assistant', content: c, timestamp: deepseek.now() }) | |
| }, | |
| chat: async (input, sessionId = null, model = 'deepseek-chat', stream = false, opts = {}) => { | |
| if (!input || input.trim() === "") { | |
| return { success: false, code: 400, author: 'Daffa ~', team: "NB Team", result: { error: "Inputnya kagak boleh kosong bree..." } }; | |
| } | |
| if (!deepseek.isModels.includes(model)) { | |
| return { success: false, code: 400, author: 'Daffa ~', team: "NB Team", result: { error: `Model '${model}' kagak ada bree... Pilih salah satu: ${deepseek.isModels.join(", ")}` } }; | |
| } | |
| const { messages: prev } = deepseek.get(sessionId || ''); | |
| const msgs = [deepseek.msg.sys(prev, opts.prompt), ...prev, deepseek.msg.usr(input)]; | |
| const url = `${deepseek.api.base}${deepseek.api.endpoint.chat}`; | |
| const body = { | |
| model, | |
| messages: msgs, | |
| temperature: opts.temperature ?? 0.9, | |
| max_tokens: opts.max_tokens ?? 1024, | |
| top_p: opts.top_p ?? 0.95, | |
| stream | |
| }; | |
| const cfg = { | |
| headers: { ...deepseek.headers, Authorization: `Bearer ${deepseek.api.key}` }, | |
| responseType: stream ? 'stream' : 'json', | |
| timeout: opts.timeout ?? 30000 | |
| }; | |
| try { | |
| const res = await axios.post(url, body, cfg); | |
| if (stream === false) { | |
| const apiId = res?.data?.id; | |
| const sid = sessionId || apiId; | |
| const c = res?.data?.choices?.[0]?.message?.content ?? ''; | |
| const ai = deepseek.msg.ai(c); | |
| const updated = [...prev, { role: 'user', content: input, timestamp: deepseek.now() }, ai] | |
| .slice(-(opts.maxHistory ?? 10)); | |
| deepseek.set(sid, updated); | |
| deepseek.purge(opts.purgeInterval); | |
| return { success: true, code: 200, author: 'Daffa ~', team: "NB Team", result: { mode: 'parsed', sessionId: sid, user: input, assistant: ai.content, history: updated } }; | |
| } else { | |
| return await new Promise((resolve) => { | |
| let raw = '', apiId = null; | |
| res.data.on('data', (chunk) => { | |
| const str = chunk.toString(); | |
| raw += str; | |
| if (str.startsWith('data:')) { | |
| try { | |
| const json = JSON.parse(str.replace(/^data:\s*/, '')); | |
| if (!apiId && json.id) apiId = json.id; | |
| const delta = json.choices?.[0]?.delta?.content; | |
| if (delta && opts.onToken) { | |
| opts.onToken(delta); | |
| } | |
| } catch {} | |
| } | |
| }); | |
| res.data.on('end', () => { | |
| const sid = sessionId || apiId; | |
| const ai = deepseek.msg.ai(raw); | |
| const updated = [...prev, { role: 'user', content: input, timestamp: deepseek.now() }, ai] | |
| .slice(-(opts.maxHistory ?? 10)); | |
| deepseek.set(sid, updated); | |
| deepseek.purge(opts.purgeInterval); | |
| res.data.destroy(); | |
| resolve({ success: true, code: 200, author: 'Daffa ~', team: "NB Team", result: { mode: 'stream', sessionId: sid, user: input, assistant: raw, history: updated } }); | |
| }); | |
| res.data.on('error', (err) => { | |
| res.data.destroy(); | |
| if (opts.onError) opts.onError(err); | |
| resolve({ success: false, code: 500, author: 'Daffa ~', team: "NB Team", result: { error: 'Error: ' + err.message } }); | |
| }); | |
| }); | |
| } | |
| } catch (err) { | |
| const a = err?.response?.data || err.message; | |
| return { success: false, code: err?.response?.status || 500, author: 'Daffa ~', team: "NB Team", result: { error: `Error: ${a}` } }; | |
| } | |
| } | |
| }; | |
| const handler = async (req, res) => { | |
| try { | |
| const { text, sessionId, model, stream, temperature, max_tokens, prompt } = req.query; | |
| if (!text) { | |
| return res.status(400).json({ | |
| author: 'Daffa ~', | |
| team: 'NB Team', | |
| success: false, | |
| msg: 'Missing required parameter: text' | |
| }); | |
| } | |
| const opts = {}; | |
| if (temperature) opts.temperature = parseFloat(temperature); | |
| if (max_tokens) opts.max_tokens = parseInt(max_tokens); | |
| if (prompt) opts.prompt = prompt; | |
| const result = await deepseek.chat( | |
| text, | |
| sessionId || null, | |
| model || 'deepseek-chat', | |
| stream === 'true', | |
| opts | |
| ); | |
| if (!result.success) { | |
| return res.status(result.code).json({ | |
| author: result.author, | |
| team: result.team, | |
| success: false, | |
| msg: result.result.error | |
| }); | |
| } | |
| res.json({ | |
| author: result.author, | |
| team: result.team, | |
| success: true, | |
| data: result.result | |
| }); | |
| } catch (error) { | |
| console.error('Error:', error); | |
| res.status(500).json({ | |
| author: 'Daffa ~', | |
| team: 'NB Team', | |
| success: false, | |
| msg: 'Terjadi kesalahan saat menghubungi DeepSeek AI.' | |
| }); | |
| } | |
| }; | |
| module.exports = { | |
| name: 'DeepSeek AI', | |
| description: 'Generate responses using DeepSeek AI with session support', | |
| type: 'GET', | |
| routes: ['api/AI/deepseek'], | |
| tags: ['ai', 'deepseek', 'chat'], | |
| parameters: ['text', 'sessionId', 'model', 'stream', 'temperature', 'max_tokens', 'prompt'], | |
| enabled: true, | |
| main: ['AI'], | |
| limit: 8, | |
| handler | |
| }; |