mirror of
https://gitee.com/chuangxxt/share-copilot
synced 2025-06-09 18:13:24 +00:00
Compare commits
No commits in common. "b34c43db39b88a3aa693a3119c6f24c7dc85d39e" and "fd1dea3ab31cb13b1b940bb674c763ddfb309009" have entirely different histories.
b34c43db39
...
fd1dea3ab3
15
README.md
15
README.md
@ -1,15 +1,12 @@
|
|||||||
**[中文](README.md) | [English](README-EN.md)**
|
[中文](README.md) | [English](README-EN.md)
|
||||||
|
|
||||||
|
|
||||||
更新代码提示接口代理:[代码提示代理说明](readme/codeTipsProxy.md)
|
|
||||||
|
|
||||||
# share-copilot
|
# share-copilot
|
||||||
|
|
||||||
- 作为代理服务器,中转copilot插件的API的请求(也可以代理无良商贩的,自行研究)
|
- 作为代理服务器,中转copilot插件的API的请求(也可以代理无良商贩的,自行研究)
|
||||||
- 支持vscode插件和jetbrains插件
|
- 支持vscode插件和jetbrains插件
|
||||||
- 支持多用户共享一个token
|
- 支持多用户共享一个token
|
||||||
- 优化请求逻辑,降低suspended概率(别万人骑基本不会)
|
- 优化请求逻辑,降低suspended概率(别万人骑基本不会)
|
||||||

|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
简单说一下
|
简单说一下
|
||||||
@ -85,7 +82,7 @@ go build
|
|||||||
### 1.安装
|
### 1.安装
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
wget https://gitee.com/chuangxxt/share-copilot/releases/download/v2.0.4/share-copilot-linux-amd64.zip
|
wget https://gitee.com/chuangxxt/share-copilot/releases/download/1.0.2/share-copilot-linux-amd64.zip
|
||||||
```
|
```
|
||||||
```sh
|
```sh
|
||||||
unzip share-copilot-linux-amd64.zip
|
unzip share-copilot-linux-amd64.zip
|
||||||
@ -142,9 +139,7 @@ verification//自定义验证
|
|||||||
"yours_token_2",
|
"yours_token_2",
|
||||||
"yours_token_3"
|
"yours_token_3"
|
||||||
]},
|
]},
|
||||||
"verification":"",
|
"verification":""
|
||||||
"diyMsg":"",
|
|
||||||
"isModMsg":false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -179,9 +174,7 @@ scop v #查看是否运行
|
|||||||
"ghu_GZgKFwraHorAxXXUvsUclOhxiYERPsSJeNuF",
|
"ghu_GZgKFwraHorAxXXUvsUclOhxiYERPsSJeNuF",
|
||||||
"ghu_SPUTCLvkMKoeMstPJmhSlYsYvCojhkFjGubl"
|
"ghu_SPUTCLvkMKoeMstPJmhSlYsYvCojhkFjGubl"
|
||||||
]},
|
]},
|
||||||
"verification":"i_am_free",
|
"verification":"i_am_free"
|
||||||
"diyMsg":"",
|
|
||||||
"isModMsg":false
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
BIN
readme/ceshi.gif
BIN
readme/ceshi.gif
Binary file not shown.
Before Width: | Height: | Size: 562 KiB |
@ -1,68 +0,0 @@
|
|||||||
# 代码提示 代理说明
|
|
||||||
|
|
||||||
**-以windows为例**
|
|
||||||
|
|
||||||
## **vscode:**
|
|
||||||
|
|
||||||
#### 1.修改文件:**
|
|
||||||
|
|
||||||
`%userprofile%\.vscode\extensions\github.copilot-xxxx\dist\extension.js`
|
|
||||||
|
|
||||||
|
|
||||||
**1.1.extension.js全文搜索替换下面两个接口,替换为自己的url**
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
"https://copilot-proxy.githubusercontent.com"
|
|
||||||
替换为"https://127.0.0.1" (你的url)
|
|
||||||
这个是代码提示接口
|
|
||||||
---------------------------------------------------------------
|
|
||||||
"https://copilot-telemetry.githubusercontent.com/telemetry"
|
|
||||||
替换为"https://127.0.0.1/telemetry" (你的url/telemetry)
|
|
||||||
这个应该是copilot把你代码上传拿去深度学习的,直接改成null好像也不影响使用
|
|
||||||
```
|
|
||||||
|
|
||||||
**1.2.也可以使用[脚本](https://gitee.com/chuangxxt/share-copilot/releases/download/v1.0.4/vscode%E4%B8%80%E9%94%AE%E9%85%8D%E7%BD%AE%E8%84%9A%E6%9C%AC.bat)一键修改,需要将extension.js原来增加的内容删掉,再配置脚本一键修改,脚本会自动备份原来的文件**
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
|
||||||
@echo off
|
|
||||||
setlocal
|
|
||||||
|
|
||||||
:: 将127.0.0.1改为自己的Api url GITHUB_TOKEN改为自己代理服务器中间件验证内容
|
|
||||||
set "GITHUB_TOKEN=123456"
|
|
||||||
set "GITHUB_API_URL=http://127.0.0.1"
|
|
||||||
set "completionsUrl=http://127.0.0.1"
|
|
||||||
set "telemetryUrl=http://127.0.0.1/telemetry"
|
|
||||||
|
|
||||||
set "CODESPACES=true"
|
|
||||||
set "GITHUB_SERVER_URL=https://github.com"
|
|
||||||
|
|
||||||
...略...
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.测试
|
|
||||||
|
|
||||||
全部接口代理后是走一个ip了,虽然不知道有没有意义
|
|
||||||
|
|
||||||
不过可以搞点有意思的东西,修改一下配置文件
|
|
||||||
|
|
||||||
```json
|
|
||||||
"diyMsg":"//授权已经过期,重新获取-> https://gitee.com/chuangxxt/share-copilot",
|
|
||||||
"isModMsg":true
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## **jetbrains:**
|
|
||||||
|
|
||||||
代理服务器是支持的,插件我不会改,等个有缘人
|
|
||||||
|
|
||||||
我修改了插件里面js文件里面的接口,改为自己的,然后重新构建成exe,
|
|
||||||
打包后有问题,可以运行,代理联网等都正常
|
|
||||||
|
|
||||||
但是代码提示无法在ide里面显示
|
|
||||||
目前找不到原因(不懂node.js)
|
|
||||||
|
|
||||||

|
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
@ -19,8 +19,6 @@ type Config struct {
|
|||||||
Token []string `json:"token"`
|
Token []string `json:"token"`
|
||||||
} `json:"copilot_config"`
|
} `json:"copilot_config"`
|
||||||
Verification string `json:"verification"`
|
Verification string `json:"verification"`
|
||||||
DiyMsg string `json:"diyMsg"`
|
|
||||||
IsModMsg bool `json:"isModMsg"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全局变量
|
// 全局变量
|
||||||
@ -40,7 +38,12 @@ var (
|
|||||||
requestCount = 0
|
requestCount = 0
|
||||||
//请求成功计数
|
//请求成功计数
|
||||||
successCount = 0
|
successCount = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// 测试的玩意儿
|
||||||
|
var (
|
||||||
|
diyMsg = ";//授权已经过期,重新获取-> https://www.sharecopilot.top"
|
||||||
completionUrl = "https://copilot-proxy.githubusercontent.com/v1/engines/copilot-codex/completions"
|
completionUrl = "https://copilot-proxy.githubusercontent.com/v1/engines/copilot-codex/completions"
|
||||||
telemetryUrl = "https://copilot-telemetry.githubusercontent.com/telemetry"
|
telemetryUrl = "https://copilot-telemetry.githubusercontent.com/telemetry"
|
||||||
|
isModMsg = true
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,7 @@ func VerifyRequestMiddleware() gin.HandlerFunc {
|
|||||||
if configFile.Verification != "" {
|
if configFile.Verification != "" {
|
||||||
authHeader := c.GetHeader("Authorization")
|
authHeader := c.GetHeader("Authorization")
|
||||||
if authHeader != "token "+configFile.Verification {
|
if authHeader != "token "+configFile.Verification {
|
||||||
c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"})
|
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,33 +84,65 @@ func diyBadRequest(c *gin.Context, code int, errorMessage string) {
|
|||||||
|
|
||||||
// registerProxyRoute 反向代理路由
|
// registerProxyRoute 反向代理路由
|
||||||
func registerProxyRoute(r *gin.Engine, routePath, targetURL string) {
|
func registerProxyRoute(r *gin.Engine, routePath, targetURL string) {
|
||||||
target, _ := url.Parse(targetURL)
|
target, err := url.Parse(targetURL)
|
||||||
isModMsgEnabled := configFile.IsModMsg && targetURL == completionUrl
|
if err != nil {
|
||||||
director := func(req *http.Request) {
|
panic(err)
|
||||||
req.URL.Host = target.Host
|
|
||||||
req.Host = target.Host
|
|
||||||
req.URL.Scheme = "https"
|
|
||||||
}
|
}
|
||||||
proxy := &httputil.ReverseProxy{
|
proxy := &httputil.ReverseProxy{
|
||||||
Director: director,
|
Director: func(req *http.Request) {
|
||||||
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {},
|
req.URL.Host = target.Host
|
||||||
|
req.URL.Scheme = "https"
|
||||||
|
req.Host = target.Host
|
||||||
|
},
|
||||||
|
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||||
|
},
|
||||||
}
|
}
|
||||||
r.Any(routePath, func(c *gin.Context) {
|
r.Any(routePath, func(c *gin.Context) {
|
||||||
if isModMsgEnabled {
|
proxy.Director = func(req *http.Request) {
|
||||||
modProxyResp(c)
|
req.URL.Host = target.Host
|
||||||
} else {
|
req.URL.Scheme = "https"
|
||||||
proxy.ServeHTTP(c.Writer, c.Request)
|
req.Host = target.Host
|
||||||
}
|
}
|
||||||
|
if isModMsg {
|
||||||
|
modProxyResp(c, proxy)
|
||||||
|
}
|
||||||
|
proxy.ServeHTTP(c.Writer, c.Request)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func modProxyResp(c *gin.Context) {
|
// 修改代码提示内容
|
||||||
c.Header("Content-Type", "text/plain;charset=utf-8")
|
func modProxyResp(c *gin.Context, proxy *httputil.ReverseProxy) {
|
||||||
c.Header("X-Forwarded-Proto", "http")
|
// 在代理响应之前修改响应
|
||||||
runes := []rune(configFile.DiyMsg)
|
proxy.ModifyResponse = func(response *http.Response) error {
|
||||||
for _, r := range runes {
|
responseBuffer := new(bytes.Buffer)
|
||||||
modStr := fmt.Sprintf("data: {\"id\":\"cmpl-7xy1GLgssjHEubVrPyt534VRYVF0t\",\"model\":\"cushman-ml\",\"created\":1694526422,\"choices\":[{\"text\":\"%c\",\"index\":0,\"finish_reason\":null,\"logprobs\":null}]}\n", r)
|
_, readErr := responseBuffer.ReadFrom(response.Body)
|
||||||
c.String(200, modStr)
|
if readErr != nil {
|
||||||
|
return readErr
|
||||||
|
}
|
||||||
|
responseData := responseBuffer.Bytes()
|
||||||
|
// 定义正则表达式模式
|
||||||
|
pattern := `(.*?)data:`
|
||||||
|
// 编译正则表达式
|
||||||
|
regex := regexp.MustCompile(pattern)
|
||||||
|
// 查找匹配项
|
||||||
|
match := regex.FindStringSubmatch(string(responseData))
|
||||||
|
var replacedData = ""
|
||||||
|
if len(match) >= 2 {
|
||||||
|
replacedData = match[1]
|
||||||
|
} else {
|
||||||
|
fmt.Println("No match found.")
|
||||||
|
}
|
||||||
|
// 将字符串转换为[]rune类型的字符数组
|
||||||
|
runes := []rune(diyMsg)
|
||||||
|
newStr := ""
|
||||||
|
// 遍历字符数组,对每个字符进行处理
|
||||||
|
for _, r := range runes {
|
||||||
|
// 在字符前后添加内容,生成新的字符串
|
||||||
|
newStr += fmt.Sprintf("data: {\"id\":\"cmpl-7xy1GLgssjHEubVrPyt534VRYVF0t\",\"model\":\"cushman-ml\",\"created\":1694526422,\"choices\":[{\"text\":\"%c\",\"index\":0,\"finish_reason\":null,\"logprobs\":null}]}\n", r)
|
||||||
|
}
|
||||||
|
newStr = replacedData + newStr + "data: [DONE]\n"
|
||||||
|
fmt.Println(newStr)
|
||||||
|
c.Data(response.StatusCode, response.Header.Get("Content-Type"), []byte(newStr))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
c.String(200, "data: [DONE]\n")
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user