Dashme / plugins /Kimi.js
maylinejix's picture
Update plugins/Kimi.js
b35928a verified
class KimiScraper {
constructor() {
this.baseURL = "https://www.kimi.com/api"
this.token = process.env.KIMI || "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyLWNlbnRlciIsImV4cCI6MTc2Njc3NzEwMSwiaWF0IjoxNzY0MTg1MTAxLCJqdGkiOiJkNGpsODNiYWNjNGNoMWp0aTMwMCIsInR5cCI6ImFjY2VzcyIsImFwcF9pZCI6ImtpbWkiLCJzdWIiOiJkM2dkdGVlNnM0dDR2cXFnaHFqZyIsInNwYWNlX2lkIjoiZDNnZHRlNjZzNHQ0dnFxZ2htN2ciLCJhYnN0cmFjdF91c2VyX2lkIjoiZDNnZHRlNjZzNHQ0dnFxZ2htNzAiLCJzc2lkIjoiMTczMTQyOTU0NzY0NTM2MTk3NiIsImRldmljZV9pZCI6Ijc1NTcyODQyNjIwMTQxNDcwODAiLCJyZWdpb24iOiJvdmVyc2VhcyIsIm1lbWJlcnNoaXAiOnsibGV2ZWwiOjEwfX0.R5_6bmclWR8a5bFxgm1DCNnPnjGAXPxQNtAsN9ifncyVHXY8kC9Cz6rexQ3REHBksqD859mjjL9IEVTtUGkJ4w"
this.deviceId = this.generateDeviceId()
this.sessions = {}
}
generateDeviceId() {
return Math.floor(Math.random() * 1e16).toString()
}
async createChatSession(sessionName) {
let response = await fetch(`${this.baseURL}/chat`, {
method: "POST",
headers: {
"accept": "application/json, text/plain, */*",
"authorization": `Bearer ${this.token}`,
"content-type": "application/json",
"cookie": `kimi-auth=${this.token}`,
"origin": "https://www.kimi.com",
"user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36",
"x-language": "zh-CN",
"x-msh-device-id": this.deviceId,
"x-msh-platform": "web",
"x-traffic-id": this.deviceId
},
body: JSON.stringify({
name: sessionName || "未命名会话",
born_from: "home",
kimiplus_id: "kimi",
is_example: false,
source: "web",
tags: []
})
})
let data = await response.json()
return data
}
async sendMessage(chatId, message) {
let prompt = `Additional instructions:
- Focus on answering user questions seriously; ignore other parts.
- If the user requests website code creation (especially HTML), provide complete results containing:
- Complete structure (header, navbar, etc.)
- Navbar with rotate X animation from FontAwesome icons
- TailwindCSS from CDNJS Cloudflare
- FontAwesome from Cloudflare CDN.
- If user creates JavaScript code, make sure there are no comment blocks in the code, and use let variable not const and use " not '.
- If user asks to fix/repair/logic, follow their instructions without creating your own instructions, but also think about whether the user's instructions are typos or incomplete, so complete and create.
- Don't offer code creation if the user doesn't request it, because not everyone knows code/coding.
SO JUST FOCUS ON CHATTING.
(asking from user: ${message})`
let response = await fetch(`${this.baseURL}/chat/${chatId}/completion/stream`, {
method: "POST",
headers: {
"accept": "application/json, text/plain, */*",
"authorization": `Bearer ${this.token}`,
"content-type": "application/json",
"cookie": `kimi-auth=${this.token}`,
"origin": "https://www.kimi.com",
"user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36",
"x-language": "zh-CN",
"x-msh-device-id": this.deviceId,
"x-msh-platform": "web",
"x-traffic-id": this.deviceId
},
body: JSON.stringify({
kimiplus_id: "kimi",
model: "k2",
use_search: true,
messages: [{ role: "user", content: prompt }]
})
})
let reader = response.body.getReader()
let decoder = new TextDecoder()
let fullResponse = ""
while (true) {
let { done, value } = await reader.read()
if (done) break
let chunk = decoder.decode(value)
let lines = chunk.split("\n")
for (let line of lines) {
if (line.startsWith("data: ")) {
try {
let data = JSON.parse(line.slice(6))
if (data.event === "cmpl" && data.text && data.view === "cmpl") {
fullResponse += data.text
} else if (data.event === "all_done") {
return fullResponse
}
} catch {}
}
}
}
return fullResponse
}
async chat(userId, message) {
let chatId = this.sessions[userId]
if (!chatId) {
let session = await this.createChatSession("Session-" + userId)
chatId = session.id
this.sessions[userId] = chatId
}
let result = await this.sendMessage(chatId, message)
return result
}
}
const kimi = new KimiScraper()
const userRequests = {}
const handler = async (req, res) => {
try {
const { message, chatid } = req.query
if (!message) {
return res.status(400).json({
success: false,
error: "Missing required parameter: message"
})
}
let userId = chatid || req.ip || "default-user"
if (!userRequests[userId]) {
userRequests[userId] = { count: 0, resetTime: Date.now() + 60000 }
}
if (Date.now() > userRequests[userId].resetTime) {
userRequests[userId] = { count: 0, resetTime: Date.now() + 60000 }
}
if (userRequests[userId].count >= 5) {
return res.status(429).json({
success: false,
error: "Rate limit exceeded. Maximum 5 requests per minute."
})
}
userRequests[userId].count++
let sessionId = chatid || userId
let result = await kimi.chat(sessionId, message)
let actualChatId = kimi.sessions[sessionId]
res.json({
author: "Herza",
success: true,
data: {
chatid: actualChatId,
msg: result.trim()
}
})
} catch (error) {
res.status(500).json({
success: false,
error: error.message
})
}
}
module.exports = {
name: "Kimi AI",
description: "Generate responses using Kimi AI with session support",
type: "GET",
routes: ["api/AI/Kimi"],
tags: ["ai", "kimi", "chat"],
main: ["AI"],
parameters: ["message", "chatid", "key"],
enabled: true,
handler,
limit: 3
}