-
-
Save huaerss/e8be428af3d0305a2bbc74e5f85ff020 to your computer and use it in GitHub Desktop.
copilot express server 版
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require("express"); | |
const axios = require("axios"); | |
const cors = require("cors"); | |
const bodyParser = require("body-parser"); | |
const crypto = require("crypto"); | |
const app = express(); | |
const defaultToken = ``; // put your github token here! | |
const ghuToken = process.env.ghuToken || defaultToken; | |
const tokenCache = { | |
[ghuToken]: null, | |
}; | |
// CORS 中间件 | |
app.use( | |
cors({ | |
origin: "*", // 允许所有来源 | |
methods: ["GET", "POST", "OPTIONS"], | |
allowedHeaders: "*", | |
credentials: true, | |
}) | |
); | |
// 用于解析JSON的中间件 | |
app.use(bodyParser.json()); | |
// 生成随机十六进制字符串的函数 | |
function genHexStr(length) { | |
return crypto.randomBytes(length).toString("hex"); | |
} | |
// 创建模拟请求头 | |
function createHeaders(authorization) { | |
return { | |
Authorization: `Bearer ${authorization}`, | |
"X-Request-Id": `${genHexStr(4)}-${genHexStr(2)}-${genHexStr( | |
2 | |
)}-${genHexStr(2)}-${genHexStr(6)}`, | |
"Vscode-Sessionid": `${genHexStr(4)}-${genHexStr(2)}-${genHexStr( | |
2 | |
)}-${genHexStr(2)}-${genHexStr(12)}`, | |
"Vscode-Machineid": genHexStr(32), | |
"Editor-Version": "vscode/1.83.1", | |
"Editor-Plugin-Version": "copilot-chat/0.8.0", | |
"Openai-Organization": "github-copilot", | |
"Openai-Intent": "conversation-panel", | |
"Content-Type": "text/event-stream; charset=utf-8", | |
"User-Agent": "GitHubCopilotChat/0.8.0", | |
Accept: "*/*", | |
"Accept-Encoding": "gzip,deflate,br", | |
Connection: "close", | |
}; | |
} | |
// 获取copilot token | |
async function getToken(githubToken) { | |
if ( | |
tokenCache[githubToken] && | |
tokenCache[githubToken]["expires_at"] * 1000 - 5 * 60 * 1000 > Date.now() | |
) { | |
return tokenCache[githubToken]["token"]; | |
} else { | |
const tokenRes = await axios.get( | |
"https://api.github.com/copilot_internal/v2/token", | |
{ | |
headers: { | |
Authorization: `token ${githubToken}`, | |
contentType: "application/json", | |
}, | |
} | |
); | |
tokenCache[githubToken] = tokenRes.data; | |
return tokenCache[githubToken]["token"]; | |
} | |
} | |
// GPT API | |
app.post("/v1/chat/completions", async (req, res) => { | |
const url = "https://api.githubcopilot.com/chat/completions"; | |
const appToken = await getToken(ghuToken); | |
try { | |
const headers = createHeaders(appToken); | |
const response = await axios.post(url, req.body, { headers: headers }); | |
// 处理响应 | |
res.set({ | |
"Transfer-Encoding": "chunked", | |
"X-Accel-Buffering": "no", | |
"Content-Type": "text/event-stream; charset=utf-8", | |
"Cache-Control": "no-cache", | |
Connection: "keep-alive", | |
}); | |
res.send(response.data); | |
} catch (error) { | |
console.error(error); | |
res.status(500).send("Error in processing request"); | |
} | |
}); | |
const PORT = process.env.PORT || 7177; | |
app.listen(PORT, () => { | |
console.log(`Server is running on http://localhost:${PORT}`); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment