Files

1 line
4.7 KiB
JSON

{"repo": "alsetyaardana/q-assistant-wa", "files": {"src/llm.js": {"35bef49ab7501eb5f172b841a3b69317e02ff8a7": {"t": 1785746667.6343985, "n": 2184, "h": "607a4d95932de10d", "c": "import OpenAI from \"openai\";\nimport { SYSTEM_PROMPT, ALLOWED_TOOL_NAMES, checkOutput } from \"./guardrails.js\";\nimport { listAllowedTools, callTool } from \"./mcpClient.js\";\n\nconst deepseek = new OpenAI({\n apiKey: process.env.DEEPSEEK_API_KEY,\n baseURL: process.env.DEEPSEEK_BASE_URL || \"https://api.deepseek.com\",\n});\n\nconst MODEL = process.env.DEEPSEEK_MODEL || \"deepseek-chat\";\nconst MAX_TOOL_HOPS = 4;\n\n// Simple in-memory per-chat history. Fine for a personal/small-team bot;\n// swap for a persistent store if this needs to survive restarts.\nconst histories = new Map();\n\nfunction getHistory(chatId) {\n if (!histories.has(chatId)) {\n histories.set(chatId, [{ role: \"system\", content: SYSTEM_PROMPT }]);\n }\n return histories.get(chatId);\n}\n\nexport async function reply(chatId, userText) {\n const history = getHistory(chatId);\n history.push({ role: \"user\", content: userText });\n\n const tools = await listAllowedTools();\n\n for (let hop = 0; hop < MAX_TOOL_HOPS; hop++) {\n const completion = await deepseek.chat.completions.create({\n model: MODEL,\n messages: history,\n tools: tools.length ? tools : undefined,\n });\n\n const msg = completion.choices[0].message;\n history.push(msg);\n\n if (!msg.tool_calls || msg.tool_calls.length === 0) {\n const safe = checkOutput(msg.content ?? \"\");\n history[history.length - 1].content = safe;\n return safe;\n }\n\n for (const call of msg.tool_calls) {\n const name = call.function.name;\n let output;\n if (!ALLOWED_TOOL_NAMES.has(name)) {\n // Should never happen since only whitelisted tools are advertised,\n // but refuse explicitly if the model hallucinates a tool name.\n output = \"Tool tidak diizinkan.\";\n } else {\n try {\n const args = JSON.parse(call.function.arguments || \"{}\");\n output = await callTool(name, args);\n } catch (err) {\n output = `Error memanggil tool: ${err.message}`;\n }\n }\n history.push({\n role: \"tool\",\n tool_call_id: call.id,\n content: output,\n });\n }\n }\n\n return \"Maaf, saya kesulitan memproses permintaan ini. Coba pertanyaan lain?\";\n}\n"}, "c73621a46c7c92a25f10f3b23f7077d65f402d54": {"t": 1785766709.914871, "n": 2184, "h": "607a4d95932de10d", "c": "import OpenAI from \"openai\";\nimport { SYSTEM_PROMPT, ALLOWED_TOOL_NAMES, checkOutput } from \"./guardrails.js\";\nimport { listAllowedTools, callTool } from \"./mcpClient.js\";\n\nconst deepseek = new OpenAI({\n apiKey: process.env.DEEPSEEK_API_KEY,\n baseURL: process.env.DEEPSEEK_BASE_URL || \"https://api.deepseek.com\",\n});\n\nconst MODEL = process.env.DEEPSEEK_MODEL || \"deepseek-chat\";\nconst MAX_TOOL_HOPS = 4;\n\n// Simple in-memory per-chat history. Fine for a personal/small-team bot;\n// swap for a persistent store if this needs to survive restarts.\nconst histories = new Map();\n\nfunction getHistory(chatId) {\n if (!histories.has(chatId)) {\n histories.set(chatId, [{ role: \"system\", content: SYSTEM_PROMPT }]);\n }\n return histories.get(chatId);\n}\n\nexport async function reply(chatId, userText) {\n const history = getHistory(chatId);\n history.push({ role: \"user\", content: userText });\n\n const tools = await listAllowedTools();\n\n for (let hop = 0; hop < MAX_TOOL_HOPS; hop++) {\n const completion = await deepseek.chat.completions.create({\n model: MODEL,\n messages: history,\n tools: tools.length ? tools : undefined,\n });\n\n const msg = completion.choices[0].message;\n history.push(msg);\n\n if (!msg.tool_calls || msg.tool_calls.length === 0) {\n const safe = checkOutput(msg.content ?? \"\");\n history[history.length - 1].content = safe;\n return safe;\n }\n\n for (const call of msg.tool_calls) {\n const name = call.function.name;\n let output;\n if (!ALLOWED_TOOL_NAMES.has(name)) {\n // Should never happen since only whitelisted tools are advertised,\n // but refuse explicitly if the model hallucinates a tool name.\n output = \"Tool tidak diizinkan.\";\n } else {\n try {\n const args = JSON.parse(call.function.arguments || \"{}\");\n output = await callTool(name, args);\n } catch (err) {\n output = `Error memanggil tool: ${err.message}`;\n }\n }\n history.push({\n role: \"tool\",\n tool_call_id: call.id,\n content: output,\n });\n }\n }\n\n return \"Maaf, saya kesulitan memproses permintaan ini. Coba pertanyaan lain?\";\n}\n"}}}}