sanbo commited on
Commit
8fb5936
·
1 Parent(s): ebc1025

update sth. at 2024-12-24 12:41:40

Browse files
.gitignore ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .externalNativeBuild
2
+ import-summary.txt
3
+
4
+ #java files
5
+ *.class
6
+ *.dex
7
+ .sync/
8
+
9
+ #for idea temp file
10
+ *.iws
11
+ *.ipr
12
+ *.iml
13
+ target/
14
+ .idea/
15
+ .gradle/
16
+ release/
17
+ build/
18
+ spoon/
19
+ releasebak/
20
+
21
+ #mac temp file
22
+ .idea/
23
+ __MACOSX
24
+ .DS_Store
25
+ ._.DS_Store
26
+
27
+ #for eclipse
28
+ .settings/
29
+ local.properties
30
+ *gen/
31
+ *.classpath
32
+ */bin/
33
+ bin/
34
+ .project
35
+
36
+ #temp file
37
+ *.bak
38
+
39
+ *.pmd
40
+ sh.exe.stackdump
41
+
42
+ .vs/
43
+ .vscode/
44
+
45
+ *.log
46
+ *.ctxt
47
+ .mtj.tmp/
48
+
49
+ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
50
+ hs_err_pid*
51
+
52
+ # Package Files #
53
+ # *.jar
54
+ *.war
55
+ *.nar
56
+ *.ear
57
+ *.zip
58
+ *.tar.gz
59
+ *.rar
60
+ *.cxx
61
+ *.cfg
62
+ # for nodejs
63
+ node_modules/
64
+ # for python
65
+ package-lock.json
66
+ .$*
67
+ *.drawio.bkp
68
+
69
+ firelineReport/
70
+ fireline*.jar
71
+ format.txt
72
+ google-java-format-1.12.0-all-deps.jar
73
+ google-java-format-*.jar
74
+ spoon-runner-1.7.1-jar-with-dependencies.jar
75
+ spoon-*.jar
76
+ fireline_1.7.3.jar
77
+ fireline*.jar
78
+ firelineReport/
79
+ */ProguardJson.java
80
+ */Key.java
81
+
82
+ doc/*.html
83
+ doc/*.pdf
84
+ buildSrc/.gradle/
85
+ TestCaseBase/
86
+ MultiProcess/
87
+ NezhaAppList/
88
+
89
+ # igone sdk testcase
90
+ dev-sdk/src/androidTest/
91
+ dev-sdk/src/main/java/com/analysys/plugin
Dockerfile ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 使用 Go 1.21 官方镜像作为构建环境
2
+ FROM golang:1.21 AS builder
3
+
4
+ # 禁用 CGO
5
+ ENV CGO_ENABLED=0
6
+
7
+ # 设置工作目录
8
+ WORKDIR /app
9
+
10
+ # 复制 go.mod 和 go.sum 并下载依赖
11
+ COPY go.mod go.sum ./
12
+ RUN go mod download
13
+
14
+ # 复制源代码并构建应用
15
+ COPY . .
16
+ RUN go build -ldflags "-s -w" -o /app/duck2api .
17
+
18
+ # 使用 Alpine Linux 作为最终镜像
19
+ FROM alpine:latest
20
+
21
+ # 设置工作目录
22
+ WORKDIR /app
23
+
24
+ # 从构建阶段复制编译好的应用和资源
25
+ COPY --from=builder /app/duck2api /app/duck2api
26
+
27
+ # hf 默认暴露端口
28
+ EXPOSE 7860
29
+
30
+ CMD ["/app/duck2api"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 aurora-develop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
Procfile ADDED
@@ -0,0 +1 @@
 
 
1
+ web: aurora
VERSION ADDED
@@ -0,0 +1 @@
 
 
1
+ 2.0.1
api/router.go ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package api
2
+
3
+ import (
4
+ "aurora/initialize"
5
+ "github.com/gin-gonic/gin"
6
+ "net/http"
7
+ )
8
+
9
+ var router *gin.Engine
10
+
11
+ func init() {
12
+ // 初始化gin
13
+ router = initialize.RegisterRouter()
14
+ }
15
+
16
+ func Listen(w http.ResponseWriter, r *http.Request) {
17
+ router.ServeHTTP(w, r)
18
+ }
build.sh ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ export GOPROXY=https://goproxy.io
4
+
5
+ go get
6
+
7
+ export CGO_ENABLED=0
8
+ PKG=aurora
9
+
10
+ targets=(
11
+ "windows/amd64"
12
+ "linux/amd64"
13
+ "darwin/amd64"
14
+ "windows/386"
15
+ "linux/386"
16
+ "darwin/386"
17
+ "linux/arm"
18
+ "linux/arm64"
19
+ "linux/s390x"
20
+ )
21
+
22
+ upxPath=$(command -v upx)
23
+
24
+ for target in "${targets[@]}"; do
25
+ GOOS=${target%/*}
26
+ GOARCH=${target#*/}
27
+ outputDir="bin/${GOOS}_${GOARCH}"
28
+ outputFile="${outputDir}/${PKG}"
29
+ archiveName="${PKG}-${GOOS}-${GOARCH}.tar.gz"
30
+ mkdir -p $(dirname ${outputFile})
31
+ GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="-s -w -extldflags '-static'" -o ${outputFile} *.go
32
+ if [ -n "$upxPath" ]; then
33
+ $upxPath -9 ${outputFile}
34
+ fi
35
+ # Archive the binary
36
+ if [ "$GOOS" = "windows" ]; then
37
+ zip -j "${outputDir}/${PKG}-${GOOS}-${GOARCH}.zip" "${outputFile}"
38
+ else
39
+ tar -C "${outputDir}" -czf "${outputDir}/${archiveName}" "${PKG}"
40
+ fi
41
+ done
build_docker.sh ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ ## 编译镜像
4
+ docker build -t duckapi .
5
+
6
+ ## 启动镜像
7
+ docker run -d -p 7860:7860 --name tillduck --restart=always duckapi
call_demo/hg.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ url = 'https://sanbo1200-duck2api.hf.space/completions'
5
+ headers = {
6
+ 'Content-Type': 'application/json'
7
+ }
8
+ data = {
9
+ "model": "gpt-4o-mini",
10
+ "messages": [
11
+ {"role": "system", "content": "你是一个辅助机器人"},
12
+ {"role": "user", "content": "你的知识库最后什么日期"}
13
+ ],
14
+ "stream": False
15
+ }
16
+
17
+ response = requests.post(url, headers=headers, data=json.dumps(data), stream=True)
18
+ response.encoding = 'utf-8'
19
+ # 打印返回的数据流
20
+ for line in response.iter_lines():
21
+ if line:
22
+ print(line.decode('utf-8'))
call_demo/hg_fd.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ # url = 'https://p.till.us.kg/till/https/sanbo1200-duck2api.hf.space/completions'
5
+ url = 'https://2.897653.xyz/aaabbbccc/https/sanbo1200-duck2api.hf.space/completions'
6
+ headers = {
7
+ 'Content-Type': 'application/json'
8
+ }
9
+ data = {
10
+ "model": "gpt-4o-mini",
11
+ "messages": [
12
+ {"role": "system", "content": "你是一个辅助机器人"},
13
+ {"role": "user", "content": "你的知识库最后什么日期"}
14
+ ],
15
+ "stream": False
16
+ }
17
+
18
+ response = requests.post(url, headers=headers, data=json.dumps(data), stream=True)
19
+ response.encoding = 'utf-8'
20
+ # 打印返回的数据流
21
+ for line in response.iter_lines():
22
+ if line:
23
+ print(line.decode('utf-8'))
conversion/requests/duckgo/convert.go ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package duckgo
2
+
3
+ import (
4
+ duckgotypes "aurora/typings/duckgo"
5
+ officialtypes "aurora/typings/official"
6
+ "strings"
7
+ )
8
+
9
+ func ConvertAPIRequest(api_request officialtypes.APIRequest) duckgotypes.ApiRequest {
10
+ inputModel := api_request.Model
11
+ duckgo_request := duckgotypes.NewApiRequest(inputModel)
12
+ realModel := inputModel
13
+
14
+ // 如果模型未进行映射,则直接使用输入模型,方便后续用户使用 duckduckgo 添加的新模型。
15
+ modelLower := strings.ToLower(inputModel)
16
+ switch {
17
+ case strings.HasPrefix(modelLower, "gpt-3.5"):
18
+ realModel = "gpt-4o-mini"
19
+ case strings.HasPrefix(modelLower, "claude-3-haiku"):
20
+ realModel = "claude-3-haiku-20240307"
21
+ case strings.HasPrefix(modelLower, "llama-3.1-70b"):
22
+ realModel = "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
23
+ case strings.HasPrefix(modelLower, "mixtral-8x7b"):
24
+ realModel = "mistralai/Mixtral-8x7B-Instruct-v0.1"
25
+ }
26
+
27
+ duckgo_request.Model = realModel
28
+ content := buildContent(&api_request)
29
+ duckgo_request.AddMessage("user", content)
30
+
31
+ return duckgo_request
32
+ }
33
+
34
+ func buildContent(api_request *officialtypes.APIRequest) string {
35
+ var content strings.Builder
36
+ for _, apiMessage := range api_request.Messages {
37
+ role := apiMessage.Role
38
+ if role == "user" || role == "system" || role == "assistant" {
39
+ if role == "system" {
40
+ role = "user"
41
+ }
42
+ contentStr := ""
43
+ // 判断 apiMessage.Content 是否为数组
44
+ if arrayContent, ok := apiMessage.Content.([]interface{}); ok {
45
+ // 如果是数组,遍历数组,查找第一个 type 为 "text" 的元素
46
+ for _, element := range arrayContent {
47
+ if elementMap, ok := element.(map[string]interface{}); ok {
48
+ if elementMap["type"] == "text" {
49
+ contentStr = elementMap["text"].(string)
50
+ break
51
+ }
52
+ }
53
+ }
54
+ } else {
55
+ contentStr, _ = apiMessage.Content.(string)
56
+ }
57
+ content.WriteString(role + ":" + contentStr + ";\r\n")
58
+ }
59
+ }
60
+ return content.String()
61
+ }
docker-compose.yml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ version: '3'
2
+
3
+ services:
4
+ app:
5
+ image: ghcr.io/aurora-develop/duck2api:latest
6
+ container_name: duck2api
7
+ restart: unless-stopped
8
+ ports:
9
+ - '7860:7860'
env.template ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ SERVER_HOST=0.0.0.0
2
+ SERVER_PORT=7860
3
+ FREE_ACCOUNTS=true
4
+ FREE_ACCOUNTS_NUM=1024
5
+ Authorization=
6
+ TLS_CERT=
7
+ TLS_KEY=
8
+ PROXY_URL=
go.mod ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module aurora
2
+
3
+ go 1.21
4
+
5
+ require (
6
+ github.com/EDDYCJY/fake-useragent v0.2.0
7
+ github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd
8
+ github.com/bogdanfinn/fhttp v0.5.28
9
+ github.com/bogdanfinn/tls-client v1.7.2
10
+ github.com/gin-gonic/gin v1.10.0
11
+ github.com/go-resty/resty/v2 v2.14.0
12
+ github.com/joho/godotenv v1.5.1
13
+ github.com/pkoukk/tiktoken-go v0.1.7
14
+ )
15
+
16
+ require (
17
+ github.com/PuerkitoBio/goquery v1.9.2 // indirect
18
+ github.com/andybalholm/brotli v1.1.0 // indirect
19
+ github.com/andybalholm/cascadia v1.3.2 // indirect
20
+ github.com/bogdanfinn/utls v1.6.1 // indirect
21
+ github.com/bytedance/sonic v1.12.1 // indirect
22
+ github.com/bytedance/sonic/loader v0.2.0 // indirect
23
+ github.com/cloudflare/circl v1.3.9 // indirect
24
+ github.com/cloudwego/base64x v0.1.4 // indirect
25
+ github.com/cloudwego/iasm v0.2.0 // indirect
26
+ github.com/dlclark/regexp2 v1.11.4 // indirect
27
+ github.com/gabriel-vasile/mimetype v1.4.5 // indirect
28
+ github.com/gin-contrib/sse v0.1.0 // indirect
29
+ github.com/go-playground/locales v0.14.1 // indirect
30
+ github.com/go-playground/universal-translator v0.18.1 // indirect
31
+ github.com/go-playground/validator/v10 v10.22.0 // indirect
32
+ github.com/goccy/go-json v0.10.3 // indirect
33
+ github.com/google/uuid v1.6.0 // indirect
34
+ github.com/json-iterator/go v1.1.12 // indirect
35
+ github.com/klauspost/compress v1.17.0 // indirect
36
+ github.com/klauspost/cpuid/v2 v2.2.8 // indirect
37
+ github.com/kr/text v0.2.0 // indirect
38
+ github.com/leodido/go-urn v1.4.0 // indirect
39
+ github.com/mattn/go-isatty v0.0.20 // indirect
40
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
41
+ github.com/modern-go/reflect2 v1.0.2 // indirect
42
+ github.com/pelletier/go-toml/v2 v2.2.2 // indirect
43
+ github.com/quic-go/quic-go v0.37.4 // indirect
44
+ github.com/rogpeppe/go-internal v1.12.0 // indirect
45
+ github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect
46
+ github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
47
+ github.com/ugorji/go/codec v1.2.12 // indirect
48
+ golang.org/x/arch v0.9.0 // indirect
49
+ golang.org/x/crypto v0.26.0 // indirect
50
+ golang.org/x/net v0.28.0 // indirect
51
+ golang.org/x/sys v0.24.0 // indirect
52
+ golang.org/x/text v0.17.0 // indirect
53
+ google.golang.org/protobuf v1.34.2 // indirect
54
+ gopkg.in/yaml.v3 v3.0.1 // indirect
55
+ )
go.sum ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ github.com/EDDYCJY/fake-useragent v0.2.0 h1:Jcnkk2bgXmDpX0z+ELlUErTkoLb/mxFBNd2YdcpvJBs=
2
+ github.com/EDDYCJY/fake-useragent v0.2.0/go.mod h1:5wn3zzlDxhKW6NYknushqinPcAqZcAPHy8lLczCdJdc=
3
+ github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
4
+ github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
5
+ github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd h1:oIpfrRhD7Jus41dotbK+SQjWSFRnf1cLZUYCZpF/o/4=
6
+ github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd/go.mod h1:0yO7neMeJLvKk/B/fq5votDY8rByrOPDubpvU+6saKo=
7
+ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
8
+ github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
9
+ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
10
+ github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
11
+ github.com/bogdanfinn/fhttp v0.5.28 h1:G6thT8s8v6z1IuvXMUsX9QKy3ZHseTQTzxuIhSiaaAw=
12
+ github.com/bogdanfinn/fhttp v0.5.28/go.mod h1:oJiYPG3jQTKzk/VFmogH8jxjH5yiv2rrOH48Xso2lrE=
13
+ github.com/bogdanfinn/tls-client v1.7.2 h1:vpL5qBYUfT9ueygEf1yLfymrXyUEZQatL25amfqGV8M=
14
+ github.com/bogdanfinn/tls-client v1.7.2/go.mod h1:pOGa2euqTbEkGNqE5idx5jKKfs9ytlyn3fwEw8RSP+g=
15
+ github.com/bogdanfinn/utls v1.6.1 h1:dKDYAcXEyFFJ3GaWaN89DEyjyRraD1qb4osdEK89ass=
16
+ github.com/bogdanfinn/utls v1.6.1/go.mod h1:VXIbRZaiY/wHZc6Hu+DZ4O2CgTzjhjCg/Ou3V4r/39Y=
17
+ github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
18
+ github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
19
+ github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
20
+ github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
21
+ github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
22
+ github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
23
+ github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
24
+ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
25
+ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
26
+ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
27
+ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
28
+ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
29
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
30
+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
31
+ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
32
+ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
33
+ github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
34
+ github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
35
+ github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
36
+ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
37
+ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
38
+ github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
39
+ github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
40
+ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
41
+ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
42
+ github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
43
+ github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
44
+ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
45
+ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
46
+ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
47
+ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
48
+ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
49
+ github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
50
+ github.com/go-resty/resty/v2 v2.14.0 h1:/rhkzsAqGQkozwfKS5aFAbb6TyKd3zyFRWcdRXLPCAU=
51
+ github.com/go-resty/resty/v2 v2.14.0/go.mod h1:IW6mekUOsElt9C7oWr0XRt9BNSD6D5rr9mhk6NjmNHg=
52
+ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
53
+ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
54
+ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
55
+ github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
56
+ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
57
+ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
58
+ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
59
+ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
60
+ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
61
+ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
62
+ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
63
+ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
64
+ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
65
+ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
66
+ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
67
+ github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
68
+ github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
69
+ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
70
+ github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
71
+ github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
72
+ github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
73
+ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
74
+ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
75
+ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
76
+ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
77
+ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
78
+ github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
79
+ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
80
+ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
81
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
82
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
83
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
84
+ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
85
+ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
86
+ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
87
+ github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
88
+ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
89
+ github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
90
+ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
91
+ github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
92
+ github.com/pkoukk/tiktoken-go v0.1.7 h1:qOBHXX4PHtvIvmOtyg1EeKlwFRiMKAcoMp4Q+bLQDmw=
93
+ github.com/pkoukk/tiktoken-go v0.1.7/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
94
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
95
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
96
+ github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
97
+ github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
98
+ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
99
+ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
100
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
101
+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
102
+ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
103
+ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
104
+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
105
+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
106
+ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
107
+ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
108
+ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
109
+ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
110
+ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
111
+ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
112
+ github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc=
113
+ github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng=
114
+ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
115
+ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
116
+ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
117
+ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
118
+ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
119
+ golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
120
+ golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
121
+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
122
+ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
123
+ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
124
+ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
125
+ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
126
+ golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
127
+ golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
128
+ golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
129
+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
130
+ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
131
+ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
132
+ golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
133
+ golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
134
+ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
135
+ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
136
+ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
137
+ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
138
+ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
139
+ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
140
+ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
141
+ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
142
+ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
143
+ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
144
+ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
145
+ golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
146
+ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
147
+ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
148
+ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
149
+ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
150
+ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
151
+ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
152
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
153
+ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
154
+ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
155
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
156
+ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
157
+ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
158
+ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
159
+ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
160
+ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
161
+ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
162
+ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
163
+ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
164
+ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
165
+ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
166
+ golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
167
+ golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
168
+ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
169
+ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
170
+ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
171
+ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
172
+ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
173
+ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
174
+ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
175
+ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
176
+ golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
177
+ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
178
+ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
179
+ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
180
+ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
181
+ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
182
+ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
183
+ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
184
+ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
185
+ golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
186
+ golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
187
+ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
188
+ golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
189
+ golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
190
+ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
191
+ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
192
+ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
193
+ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
194
+ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
195
+ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
196
+ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
197
+ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
198
+ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
199
+ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
200
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
201
+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
202
+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
203
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
204
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
205
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
206
+ nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
httpclient/Iaurorahttpclient.go ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package httpclient
2
+
3
+ import (
4
+ "io"
5
+ "net/http"
6
+ )
7
+
8
+ type AuroraHttpClient interface {
9
+ Request(method HttpMethod, url string, headers AuroraHeaders, cookies []*http.Cookie, body io.Reader) (*http.Response, error)
10
+ SetProxy(url string) error
11
+ }
12
+
13
+ type HttpMethod string
14
+
15
+ const (
16
+ GET HttpMethod = "GET"
17
+ POST HttpMethod = "POST"
18
+ PUT HttpMethod = "PUT"
19
+ HEAD HttpMethod = "HEAD"
20
+ DELETE HttpMethod = "DELETE"
21
+ OPTIONS HttpMethod = "OPTIONS"
22
+ )
23
+
24
+ type AuroraHeaders map[string]string
25
+
26
+ func (a AuroraHeaders) Set(key, value string) {
27
+ a[key] = value
28
+ }
httpclient/bogdanfinn/tls_client.go ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package bogdanfinn
2
+
3
+ import (
4
+ "aurora/httpclient"
5
+ "io"
6
+ "net/http"
7
+
8
+ fhttp "github.com/bogdanfinn/fhttp"
9
+ tls_client "github.com/bogdanfinn/tls-client"
10
+ "github.com/bogdanfinn/tls-client/profiles"
11
+ )
12
+
13
+ type TlsClient struct {
14
+ Client tls_client.HttpClient
15
+ ReqBefore handler
16
+ }
17
+
18
+ type handler func(r *fhttp.Request) error
19
+
20
+ func NewStdClient() *TlsClient {
21
+ client, _ := tls_client.NewHttpClient(tls_client.NewNoopLogger(), []tls_client.HttpClientOption{
22
+ tls_client.WithCookieJar(tls_client.NewCookieJar()),
23
+ tls_client.WithRandomTLSExtensionOrder(),
24
+ tls_client.WithTimeoutSeconds(600),
25
+ tls_client.WithClientProfile(profiles.Okhttp4Android13),
26
+ }...)
27
+
28
+ stdClient := &TlsClient{Client: client}
29
+ return stdClient
30
+ }
31
+
32
+ func convertResponse(resp *fhttp.Response) *http.Response {
33
+ response := &http.Response{
34
+ Status: resp.Status,
35
+ StatusCode: resp.StatusCode,
36
+ Proto: resp.Proto,
37
+ ProtoMajor: resp.ProtoMajor,
38
+ ProtoMinor: resp.ProtoMinor,
39
+ Header: http.Header(resp.Header),
40
+ Body: resp.Body,
41
+ ContentLength: resp.ContentLength,
42
+ TransferEncoding: resp.TransferEncoding,
43
+ Close: resp.Close,
44
+ Uncompressed: resp.Uncompressed,
45
+ Trailer: http.Header(resp.Trailer),
46
+ }
47
+ return response
48
+ }
49
+
50
+ func (t *TlsClient) handleHeaders(req *fhttp.Request, headers httpclient.AuroraHeaders) {
51
+ if headers == nil {
52
+ return
53
+ }
54
+ for k, v := range headers {
55
+ req.Header.Set(k, v)
56
+ }
57
+ }
58
+
59
+ func (t *TlsClient) handleCookies(req *fhttp.Request, cookies []*http.Cookie) {
60
+ if cookies == nil {
61
+ return
62
+ }
63
+ for _, c := range cookies {
64
+ req.AddCookie(&fhttp.Cookie{
65
+ Name: c.Name,
66
+ Value: c.Value,
67
+ Path: c.Path,
68
+ Domain: c.Domain,
69
+ Expires: c.Expires,
70
+ RawExpires: c.RawExpires,
71
+ MaxAge: c.MaxAge,
72
+ Secure: c.Secure,
73
+ HttpOnly: c.HttpOnly,
74
+ SameSite: fhttp.SameSite(c.SameSite),
75
+ Raw: c.Raw,
76
+ Unparsed: c.Unparsed,
77
+ })
78
+ }
79
+ }
80
+
81
+ func (t *TlsClient) Request(method httpclient.HttpMethod, url string, headers httpclient.AuroraHeaders, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
82
+ req, err := fhttp.NewRequest(string(method), url, body)
83
+ if err != nil {
84
+ return nil, err
85
+ }
86
+ t.handleHeaders(req, headers)
87
+ t.handleCookies(req, cookies)
88
+ if t.ReqBefore != nil {
89
+ if err := t.ReqBefore(req); err != nil {
90
+ return nil, err
91
+ }
92
+ }
93
+ do, err := t.Client.Do(req)
94
+ if err != nil {
95
+ return nil, err
96
+ }
97
+ return convertResponse(do), nil
98
+ }
99
+
100
+ func (t *TlsClient) SetProxy(url string) error {
101
+ return t.Client.SetProxy(url)
102
+ }
httpclient/bogdanfinn/tls_client_test.go ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package bogdanfinn
2
+
3
+ import (
4
+ "aurora/httpclient"
5
+ "fmt"
6
+ "io"
7
+ "net/http"
8
+ "os"
9
+ "strings"
10
+ "testing"
11
+
12
+ "github.com/joho/godotenv"
13
+ )
14
+
15
+ var BaseURL string
16
+
17
+ func init() {
18
+ _ = godotenv.Load(".env")
19
+ BaseURL = os.Getenv("BASE_URL")
20
+ if BaseURL == "" {
21
+ BaseURL = "https://chat.openai.com/backend-anon"
22
+ }
23
+ }
24
+ func TestTlsClient_Request(t *testing.T) {
25
+ client := NewStdClient()
26
+ userAgent := "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
27
+ proxy := "http://127.0.0.1:7990"
28
+ client.SetProxy(proxy)
29
+
30
+ apiUrl := BaseURL + "/sentinel/chat-requirements"
31
+ payload := strings.NewReader(`{"conversation_mode_kind":"primary_assistant"}`)
32
+ header := make(httpclient.AuroraHeaders)
33
+ header.Set("Content-Type", "application/json")
34
+ header.Set("User-Agent", userAgent)
35
+ header.Set("Accept", "*/*")
36
+ header.Set("oai-language", "en-US")
37
+ header.Set("origin", "https://chat.openai.com")
38
+ header.Set("referer", "https://chat.openai.com/")
39
+ header.Set("oai-device-id", "c83b24f0-5a9e-4c43-8915-3f67d4332609")
40
+ response, err := client.Request(http.MethodPost, apiUrl, header, nil, payload)
41
+ if err != nil {
42
+ return
43
+ }
44
+ defer response.Body.Close()
45
+ fmt.Println(response.StatusCode)
46
+ if response.StatusCode != 200 {
47
+ fmt.Println("Error: ", response.StatusCode)
48
+ }
49
+ }
50
+
51
+ func TestChatGPTModel(t *testing.T) {
52
+ client := NewStdClient()
53
+ userAgent := "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
54
+ proxy := "http://127.0.0.1:7990"
55
+ client.SetProxy(proxy)
56
+ apiUrl := "https://chat.openai.com/backend-anon/models"
57
+
58
+ header := make(httpclient.AuroraHeaders)
59
+ header.Set("Content-Type", "application/json")
60
+ header.Set("User-Agent", userAgent)
61
+ header.Set("Accept", "*/*")
62
+ header.Set("oai-language", "en-US")
63
+ header.Set("origin", "https://chat.openai.com")
64
+ header.Set("referer", "https://chat.openai.com/")
65
+ header.Set("oai-device-id", "c83b24f0-5a9e-4c43-8915-3f67d4332609")
66
+ response, err := client.Request(http.MethodGet, apiUrl, header, nil, nil)
67
+ if err != nil {
68
+ return
69
+ }
70
+ defer response.Body.Close()
71
+ fmt.Println(response.StatusCode)
72
+ if response.StatusCode != 200 {
73
+ fmt.Println("Error: ", response.StatusCode)
74
+ body, _ := io.ReadAll(response.Body)
75
+ fmt.Println(string(body))
76
+ return
77
+ }
78
+
79
+ type EnginesData struct {
80
+ Models []struct {
81
+ Slug string `json:"slug"`
82
+ MaxTokens int `json:"max_tokens"`
83
+ Title string `json:"title"`
84
+ Description string `json:"description"`
85
+ Tags []string `json:"tags"`
86
+ Capabilities struct {
87
+ } `json:"capabilities,omitempty"`
88
+ ProductFeatures struct {
89
+ } `json:"product_features,omitempty"`
90
+ } `json:"models"`
91
+ Categories []struct {
92
+ Category string `json:"category"`
93
+ HumanCategoryName string `json:"human_category_name"`
94
+ SubscriptionLevel string `json:"subscription_level"`
95
+ DefaultModel string `json:"default_model"`
96
+ CodeInterpreterModel string `json:"code_interpreter_model,omitempty"`
97
+ PluginsModel string `json:"plugins_model"`
98
+ } `json:"categories"`
99
+ }
100
+
101
+ }
httpclient/resty/resty_client.go ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package resty
2
+
3
+ import (
4
+ "aurora/util"
5
+ "crypto/tls"
6
+ browser "github.com/EDDYCJY/fake-useragent"
7
+ "github.com/go-resty/resty/v2"
8
+ "net/http"
9
+ "time"
10
+ )
11
+
12
+ type RestyClient struct {
13
+ Client *resty.Client
14
+ }
15
+
16
+ func NewStdClient() *RestyClient {
17
+ client := &RestyClient{
18
+ Client: resty.NewWithClient(&http.Client{
19
+ Transport: &http.Transport{
20
+ // 禁用长连接
21
+ DisableKeepAlives: true,
22
+ // 配置TLS设置,跳过证书验证
23
+ TLSClientConfig: &tls.Config{
24
+ InsecureSkipVerify: true,
25
+ },
26
+ },
27
+ }),
28
+ }
29
+ client.Client.SetBaseURL("https://chat.openai.com")
30
+ client.Client.SetRetryCount(3)
31
+ client.Client.SetRetryWaitTime(5 * time.Second)
32
+ client.Client.SetRetryMaxWaitTime(20 * time.Second)
33
+
34
+ client.Client.SetTimeout(600 * time.Second)
35
+ client.Client.SetHeader("user-agent", browser.Random()).
36
+ SetHeader("accept", "*/*").
37
+ SetHeader("accept-language", "en-US,en;q=0.9").
38
+ SetHeader("cache-control", "no-cache").
39
+ SetHeader("content-type", "application/json").
40
+ SetHeader("oai-language", util.RandomLanguage()).
41
+ SetHeader("pragma", "no-cache").
42
+ SetHeader("sec-ch-ua", `"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"`).
43
+ SetHeader("sec-ch-ua-mobile", "?0").
44
+ SetHeader("sec-ch-ua-platform", "Windows").
45
+ SetHeader("sec-fetch-dest", "empty").
46
+ SetHeader("sec-fetch-mode", "cors").
47
+ SetHeader("sec-fetch-site", "same-origin")
48
+ return client
49
+ }
50
+
51
+ //func (c *RestyClient) Request(method string, url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
52
+ //}
53
+
54
+ //func (c *RestyClient) Post(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
55
+ //}
56
+ //
57
+ //func (c *RestyClient) Get(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
58
+ //}
59
+ //
60
+ //func (c *RestyClient) Head(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
61
+ //}
62
+ //
63
+ //func (c *RestyClient) Options(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
64
+ //}
65
+ //
66
+ //func (c *RestyClient) Put(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
67
+ //}
68
+ //
69
+ //func (c *RestyClient) Delete(url string, headers map[string]string, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
70
+ //}
71
+ //
72
+ //func (c *RestyClient) SetProxy(url string) error {}
initialize/handlers.go ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package initialize
2
+
3
+ import (
4
+ duckgoConvert "aurora/conversion/requests/duckgo"
5
+ "aurora/httpclient/bogdanfinn"
6
+ "aurora/internal/duckgo"
7
+ "aurora/internal/proxys"
8
+ officialtypes "aurora/typings/official"
9
+
10
+ "github.com/gin-gonic/gin"
11
+ )
12
+
13
+ type Handler struct {
14
+ proxy *proxys.IProxy
15
+ }
16
+
17
+ func NewHandle(proxy *proxys.IProxy) *Handler {
18
+ return &Handler{proxy: proxy}
19
+ }
20
+
21
+ func optionsHandler(c *gin.Context) {
22
+ // Set headers for CORS
23
+ c.Header("Access-Control-Allow-Origin", "*")
24
+ c.Header("Access-Control-Allow-Methods", "POST")
25
+ c.Header("Access-Control-Allow-Headers", "*")
26
+ c.JSON(200, gin.H{
27
+ "message": "pong",
28
+ })
29
+ }
30
+
31
+ func (h *Handler) duckduckgo(c *gin.Context) {
32
+ var original_request officialtypes.APIRequest
33
+ err := c.BindJSON(&original_request)
34
+ if err != nil {
35
+ c.JSON(400, gin.H{"error": gin.H{
36
+ "message": "Request must be proper JSON",
37
+ "type": "invalid_request_error",
38
+ "param": nil,
39
+ "code": err.Error(),
40
+ }})
41
+ return
42
+ }
43
+ proxyUrl := h.proxy.GetProxyIP()
44
+ client := bogdanfinn.NewStdClient()
45
+ token, err := duckgo.InitXVQD(client, proxyUrl)
46
+ if err != nil {
47
+ c.JSON(500, gin.H{
48
+ "error": err.Error(),
49
+ })
50
+ return
51
+ }
52
+
53
+ translated_request := duckgoConvert.ConvertAPIRequest(original_request)
54
+ response, err := duckgo.POSTconversation(client, translated_request, token, proxyUrl)
55
+ if err != nil {
56
+ c.JSON(500, gin.H{
57
+ "error": "request conversion error",
58
+ })
59
+ return
60
+ }
61
+
62
+ defer response.Body.Close()
63
+ if duckgo.Handle_request_error(c, response) {
64
+ return
65
+ }
66
+ var response_part string
67
+ response_part = duckgo.Handler(c, response, translated_request, original_request.Stream)
68
+ if c.Writer.Status() != 200 {
69
+ return
70
+ }
71
+ if !original_request.Stream {
72
+ c.JSON(200, officialtypes.NewChatCompletionWithModel(response_part, translated_request.Model))
73
+ } else {
74
+ c.String(200, "data: [DONE]\n\n")
75
+ }
76
+ }
77
+
78
+ func (h *Handler) engines(c *gin.Context) {
79
+ type ResData struct {
80
+ ID string `json:"id"`
81
+ Object string `json:"object"`
82
+ Created int `json:"created"`
83
+ OwnedBy string `json:"owned_by"`
84
+ }
85
+
86
+ type JSONData struct {
87
+ Object string `json:"object"`
88
+ Data []ResData `json:"data"`
89
+ }
90
+
91
+ modelS := JSONData{
92
+ Object: "list",
93
+ }
94
+ var resModelList []ResData
95
+
96
+ // Supported models
97
+ modelIDs := []string{
98
+ "gpt-4o-mini",
99
+ "gpt-3.5-turbo-0125",
100
+ "claude-3-haiku-20240307",
101
+ "meta-llama/Llama-3-70b-chat-hf",
102
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
103
+ }
104
+
105
+ for _, modelID := range modelIDs {
106
+ resModelList = append(resModelList, ResData{
107
+ ID: modelID,
108
+ Object: "model",
109
+ Created: 1685474247,
110
+ OwnedBy: "duckduckgo",
111
+ })
112
+ }
113
+
114
+ modelS.Data = resModelList
115
+ c.JSON(200, modelS)
116
+ }
initialize/proxy.go ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package initialize
2
+
3
+ import (
4
+ "aurora/internal/proxys"
5
+ "bufio"
6
+ "log/slog"
7
+ "net/url"
8
+ "os"
9
+ )
10
+
11
+ func checkProxy() *proxys.IProxy {
12
+ var proxies []string
13
+ proxyUrl := os.Getenv("PROXY_URL")
14
+ if proxyUrl != "" {
15
+ proxies = append(proxies, proxyUrl)
16
+ }
17
+
18
+ if _, err := os.Stat("proxies.txt"); err == nil {
19
+ file, _ := os.Open("proxies.txt")
20
+ defer file.Close()
21
+ scanner := bufio.NewScanner(file)
22
+ for scanner.Scan() {
23
+ proxy := scanner.Text()
24
+ parsedURL, err := url.Parse(proxy)
25
+ if err != nil {
26
+ slog.Warn("proxy url is invalid", "url", proxy, "err", err)
27
+ continue
28
+ }
29
+
30
+ // 如果缺少端口信息,不是完整的代理链接
31
+ if parsedURL.Port() != "" {
32
+ proxies = append(proxies, proxy)
33
+ } else {
34
+ continue
35
+ }
36
+ }
37
+ }
38
+
39
+ if len(proxies) == 0 {
40
+ proxy := os.Getenv("http_proxy")
41
+ if proxy != "" {
42
+ proxies = append(proxies, proxy)
43
+ }
44
+ }
45
+
46
+ proxyIP := proxys.NewIProxyIP(proxies)
47
+ return &proxyIP
48
+ }
initialize/router.go ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package initialize
2
+
3
+ import (
4
+ "aurora/middlewares"
5
+ "net/http"
6
+ "os"
7
+
8
+ "github.com/gin-gonic/gin"
9
+ )
10
+
11
+ func RegisterRouter() *gin.Engine {
12
+ handler := NewHandle(
13
+ checkProxy(),
14
+ )
15
+
16
+ router := gin.Default()
17
+ router.Use(middlewares.Cors)
18
+ // // 访问根目录时,跳转到 /web
19
+ // router.GET("/", func(c *gin.Context) {
20
+ // c.JSON(200, gin.H{
21
+ // "message": "Hello, world!",
22
+ // })
23
+ // })
24
+ router.GET("/", func(c *gin.Context) {
25
+ c.Redirect(http.StatusFound, "/web")
26
+ })
27
+
28
+ router.GET("/ping", func(c *gin.Context) {
29
+ c.JSON(200, gin.H{
30
+ "message": "pong",
31
+ })
32
+ })
33
+
34
+ // 注册 prefixGroup 路由
35
+ prefixGroup := os.Getenv("PREFIX")
36
+ if prefixGroup != "" {
37
+ registerGroupRoutes(router.Group(prefixGroup), handler)
38
+ }
39
+ // 注册无前缀的路由
40
+ registerGroupRoutes(router.Group(""), handler)
41
+
42
+ return router
43
+ }
44
+ func registerGroupRoutes(group *gin.RouterGroup, handler *Handler) {
45
+ // OPTIONS 路由
46
+ group.OPTIONS("/v1/chat/completions", optionsHandler)
47
+ group.OPTIONS("/v1/chat/models", optionsHandler)
48
+ group.OPTIONS("/completions", optionsHandler)
49
+ group.OPTIONS("/models", optionsHandler)
50
+ group.OPTIONS("/api/v1/chat/completions", optionsHandler)
51
+ group.OPTIONS("/api/v1/models", optionsHandler)
52
+ group.OPTIONS("/hf/v1/chat/completions", optionsHandler)
53
+ group.OPTIONS("/hf/v1/models", optionsHandler)
54
+
55
+ // POST 路由
56
+ group.POST("/v1/chat/completions", middlewares.Authorization, handler.duckduckgo)
57
+ group.POST("/api/v1/chat/completions", middlewares.Authorization, handler.duckduckgo)
58
+ group.POST("/completions", middlewares.Authorization, handler.duckduckgo)
59
+ group.POST("/hf/v1/chat/completions", middlewares.Authorization, handler.duckduckgo)
60
+
61
+ // GET 路由
62
+ group.GET("/v1/models", middlewares.Authorization, handler.engines)
63
+ group.GET("/api/v1/models", middlewares.Authorization, handler.engines)
64
+ group.GET("/models", middlewares.Authorization, handler.engines)
65
+ group.GET("/hf/v1/models", middlewares.Authorization, handler.engines)
66
+ }
internal/duckgo/request.go ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package duckgo
2
+
3
+ import (
4
+ "aurora/httpclient"
5
+ duckgotypes "aurora/typings/duckgo"
6
+ officialtypes "aurora/typings/official"
7
+ "bufio"
8
+ "bytes"
9
+ "encoding/json"
10
+ "errors"
11
+ "io"
12
+ "net/http"
13
+ "strings"
14
+ "sync"
15
+ "time"
16
+
17
+ "github.com/gin-gonic/gin"
18
+ )
19
+
20
+ var (
21
+ Token *XqdgToken
22
+ UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
23
+ )
24
+
25
+ type XqdgToken struct {
26
+ Token string `json:"token"`
27
+ M sync.Mutex `json:"-"`
28
+ ExpireAt time.Time `json:"expire"`
29
+ }
30
+
31
+ // func InitXVQD(client httpclient.AuroraHttpClient, proxyUrl string) (string, error) {
32
+ // if Token == nil {
33
+ // Token = &XqdgToken{
34
+ // Token: "",
35
+ // M: sync.Mutex{},
36
+ // }
37
+ // }
38
+ // Token.M.Lock()
39
+ // defer Token.M.Unlock()
40
+ // if Token.Token == "" || Token.ExpireAt.Before(time.Now()) {
41
+ // status, err := postStatus(client, proxyUrl)
42
+ // if err != nil {
43
+ // return "", err
44
+ // }
45
+ // defer status.Body.Close()
46
+ // token := status.Header.Get("x-vqd-4")
47
+ // if token == "" {
48
+ // return "", errors.New("no x-vqd-4 token")
49
+ // }
50
+ // Token.Token = token
51
+ // Token.ExpireAt = time.Now().Add(time.Minute * 3)
52
+ // }
53
+ //
54
+ // return Token.Token, nil
55
+ // }
56
+
57
+ func InitXVQD(client httpclient.AuroraHttpClient, proxyUrl string) (string, error) {
58
+ if Token == nil {
59
+ Token = &XqdgToken{
60
+ Token: "",
61
+ M: sync.Mutex{},
62
+ }
63
+ }
64
+ Token.M.Lock()
65
+ defer Token.M.Unlock()
66
+
67
+ // 如果 token 已经失效或为空,尝试重新获取
68
+ if Token.Token == "" || Token.ExpireAt.Before(time.Now()) {
69
+ const maxRetries = 3 // 设置最大重试次数
70
+ const retryInterval = 2 * time.Second // 设置每次重试间隔
71
+
72
+ for retries := 0; retries < maxRetries; retries++ {
73
+ // 发送请求
74
+ status, err := postStatus(client, proxyUrl)
75
+ if err != nil {
76
+ // 如果是非网络类错误,直接返回
77
+ if retries == maxRetries-1 {
78
+ return "", err
79
+ }
80
+ // 网络错误,等待重试
81
+ time.Sleep(retryInterval)
82
+ continue
83
+ }
84
+
85
+ // 获取 x-vqd-4 token
86
+ defer status.Body.Close()
87
+ token := status.Header.Get("x-vqd-4")
88
+ if token == "" {
89
+ // 如果没有获取到 token,判断是否是最后一次重试
90
+ if retries == maxRetries-1 {
91
+ return "", errors.New("no x-vqd-4 token after retries")
92
+ }
93
+ // 没有获取到 token,等待重试
94
+ time.Sleep(retryInterval)
95
+ continue
96
+ }
97
+
98
+ // 成功获取到 token
99
+ Token.Token = token
100
+ Token.ExpireAt = time.Now().Add(time.Minute * 3)
101
+ return Token.Token, nil
102
+ }
103
+
104
+ // 重试完仍未成功,返回错误
105
+ return "", errors.New("failed to get x-vqd-4 token after retries")
106
+ }
107
+
108
+ // 如果 token 已存在且有效,直接返回
109
+ return Token.Token, nil
110
+ }
111
+
112
+ func postStatus(client httpclient.AuroraHttpClient, proxyUrl string) (*http.Response, error) {
113
+ if proxyUrl != "" {
114
+ client.SetProxy(proxyUrl)
115
+ }
116
+ header := createHeader()
117
+ header.Set("accept", "*/*")
118
+ header.Set("x-vqd-accept", "1")
119
+ response, err := client.Request(httpclient.GET, "https://duckduckgo.com/duckchat/v1/status", header, nil, nil)
120
+ if err != nil {
121
+ return nil, err
122
+ }
123
+ return response, nil
124
+ }
125
+
126
+ func POSTconversation(client httpclient.AuroraHttpClient, request duckgotypes.ApiRequest, token string, proxyUrl string) (*http.Response, error) {
127
+ if proxyUrl != "" {
128
+ client.SetProxy(proxyUrl)
129
+ }
130
+ body_json, err := json.Marshal(request)
131
+ if err != nil {
132
+ return &http.Response{}, err
133
+ }
134
+ header := createHeader()
135
+ header.Set("accept", "text/event-stream")
136
+ header.Set("x-vqd-4", token)
137
+ response, err := client.Request(httpclient.POST, "https://duckduckgo.com/duckchat/v1/chat", header, nil, bytes.NewBuffer(body_json))
138
+ if err != nil {
139
+ return nil, err
140
+ }
141
+ return response, nil
142
+ }
143
+
144
+ func Handle_request_error(c *gin.Context, response *http.Response) bool {
145
+ if response.StatusCode != 200 {
146
+ // Try read response body as JSON
147
+ var error_response map[string]interface{}
148
+ err := json.NewDecoder(response.Body).Decode(&error_response)
149
+ if err != nil {
150
+ // Read response body
151
+ body, _ := io.ReadAll(response.Body)
152
+ c.JSON(response.StatusCode, gin.H{"error": gin.H{
153
+ "message": "Unknown error",
154
+ "type": "internal_server_error",
155
+ "param": nil,
156
+ "code": "500",
157
+ "details": string(body),
158
+ }})
159
+ return true
160
+ }
161
+ c.JSON(response.StatusCode, gin.H{"error": gin.H{
162
+ "message": error_response["detail"],
163
+ "type": response.Status,
164
+ "param": nil,
165
+ "code": "error",
166
+ }})
167
+ return true
168
+ }
169
+ return false
170
+ }
171
+
172
+ func createHeader() httpclient.AuroraHeaders {
173
+ header := make(httpclient.AuroraHeaders)
174
+ header.Set("accept-language", "zh-CN,zh;q=0.9")
175
+ header.Set("content-type", "application/json")
176
+ header.Set("origin", "https://duckduckgo.com")
177
+ header.Set("referer", "https://duckduckgo.com/")
178
+ header.Set("sec-ch-ua", `"Chromium";v="120", "Google Chrome";v="120", "Not-A.Brand";v="99"`)
179
+ header.Set("sec-ch-ua-mobile", "?0")
180
+ header.Set("sec-ch-ua-platform", `"Windows"`)
181
+ header.Set("sec-fetch-dest", "empty")
182
+ header.Set("sec-fetch-mode", "cors")
183
+ header.Set("sec-fetch-site", "same-origin")
184
+ header.Set("user-agent", UA)
185
+ return header
186
+ }
187
+
188
+ func Handler(c *gin.Context, response *http.Response, oldRequest duckgotypes.ApiRequest, stream bool) string {
189
+ reader := bufio.NewReader(response.Body)
190
+ if stream {
191
+ // Response content type is text/event-stream
192
+ c.Header("Content-Type", "text/event-stream")
193
+ } else {
194
+ // Response content type is application/json
195
+ c.Header("Content-Type", "application/json")
196
+ }
197
+
198
+ var previousText strings.Builder
199
+ for {
200
+ line, err := reader.ReadString('\n')
201
+ if err != nil {
202
+ if err == io.EOF {
203
+ break
204
+ }
205
+ return ""
206
+ }
207
+ if len(line) < 6 {
208
+ continue
209
+ }
210
+ line = line[6:]
211
+ if !strings.HasPrefix(line, "[DONE]") {
212
+ var originalResponse duckgotypes.ApiResponse
213
+ err = json.Unmarshal([]byte(line), &originalResponse)
214
+ if err != nil {
215
+ continue
216
+ }
217
+ if originalResponse.Action != "success" {
218
+ c.JSON(500, gin.H{"error": "Error"})
219
+ return ""
220
+ }
221
+ responseString := ""
222
+ if originalResponse.Message != "" {
223
+ previousText.WriteString(originalResponse.Message)
224
+ translatedResponse := officialtypes.NewChatCompletionChunkWithModel(originalResponse.Message, originalResponse.Model)
225
+ responseString = "data: " + translatedResponse.String() + "\n\n"
226
+ }
227
+
228
+ if responseString == "" {
229
+ continue
230
+ }
231
+
232
+ if stream {
233
+ _, err = c.Writer.WriteString(responseString)
234
+ if err != nil {
235
+ return ""
236
+ }
237
+ c.Writer.Flush()
238
+ }
239
+ } else {
240
+ if stream {
241
+ final_line := officialtypes.StopChunkWithModel("stop", oldRequest.Model)
242
+ c.Writer.WriteString("data: " + final_line.String() + "\n\n")
243
+ }
244
+ }
245
+ }
246
+ return previousText.String()
247
+ }
internal/proxys/proxys.go ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package proxys
2
+
3
+ import "sync"
4
+
5
+ type IProxy struct {
6
+ ips []string
7
+ lock sync.Mutex
8
+ }
9
+
10
+ func NewIProxyIP(ips []string) IProxy {
11
+ return IProxy{
12
+ ips: ips,
13
+ }
14
+ }
15
+
16
+ func (p *IProxy) GetIPS() int {
17
+ return len(p.ips)
18
+ }
19
+
20
+ func (p *IProxy) GetProxyIP() string {
21
+ if p == nil {
22
+ return ""
23
+ }
24
+
25
+ p.lock.Lock()
26
+ defer p.lock.Unlock()
27
+
28
+ if len(p.ips) == 0 {
29
+ return ""
30
+ }
31
+
32
+ proxyIp := p.ips[0]
33
+ p.ips = append(p.ips[1:], proxyIp)
34
+ return proxyIp
35
+ }
main.go ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package main
2
+
3
+ import (
4
+ "aurora/initialize"
5
+ "embed"
6
+ "io/fs"
7
+ "log"
8
+ "net/http"
9
+ "os"
10
+
11
+ "github.com/gin-gonic/gin"
12
+
13
+ "github.com/acheong08/endless"
14
+ "github.com/joho/godotenv"
15
+ )
16
+
17
+ //go:embed web/*
18
+ var staticFiles embed.FS
19
+
20
+ func main() {
21
+ _ = godotenv.Load(".env")
22
+ gin.SetMode(gin.ReleaseMode)
23
+ router := initialize.RegisterRouter()
24
+ subFS, err := fs.Sub(staticFiles, "web")
25
+ if err != nil {
26
+ log.Fatal(err)
27
+ }
28
+ router.StaticFS("/web", http.FS(subFS))
29
+ host := os.Getenv("SERVER_HOST")
30
+ port := os.Getenv("SERVER_PORT")
31
+ tlsCert := os.Getenv("TLS_CERT")
32
+ tlsKey := os.Getenv("TLS_KEY")
33
+
34
+ if host == "" {
35
+ host = "0.0.0.0"
36
+ }
37
+ if port == "" {
38
+ port = os.Getenv("PORT")
39
+ if port == "" {
40
+ port = "7860"
41
+ }
42
+ }
43
+
44
+ if tlsCert != "" && tlsKey != "" {
45
+ _ = endless.ListenAndServeTLS(host+":"+port, tlsCert, tlsKey, router)
46
+ } else {
47
+ _ = endless.ListenAndServe(host+":"+port, router)
48
+ }
49
+ }
middlewares/auth.go ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package middlewares
2
+
3
+ import (
4
+ "github.com/gin-gonic/gin"
5
+ "os"
6
+ "strings"
7
+ )
8
+
9
+ func Authorization(c *gin.Context) {
10
+ customer_key := os.Getenv("Authorization")
11
+ if customer_key != "" {
12
+ authHeader := c.GetHeader("Authorization")
13
+ if authHeader == "" {
14
+ c.JSON(401, gin.H{"error": "Unauthorized"})
15
+ c.Abort()
16
+ return
17
+ }
18
+ tokenParts := strings.Split(strings.Replace(authHeader, "Bearer ", "", 1)," ")
19
+ customAccessToken := tokenParts[0]
20
+ if customer_key != customAccessToken {
21
+ c.JSON(401, gin.H{"error": "Unauthorized"})
22
+ c.Abort()
23
+ return
24
+ }
25
+ if len(tokenParts) > 1 {
26
+ openaiAccessToken := tokenParts[1]
27
+ c.Request.Header.Set("Authorization", "Bearer " + openaiAccessToken)
28
+ }
29
+ }
30
+ c.Next()
31
+ }
middlewares/cors.go ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ package middlewares
2
+
3
+ import "github.com/gin-gonic/gin"
4
+
5
+ func Cors(c *gin.Context) {
6
+ c.Header("Access-Control-Allow-Origin", "*")
7
+ c.Header("Access-Control-Allow-Methods", "*")
8
+ c.Header("Access-Control-Allow-Headers", "*")
9
+ c.Next()
10
+ }
release.bat ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ SETLOCAL
3
+
4
+ REM 指定编码为 UTF-8
5
+ chcp 65001
6
+
7
+ REM 设置要生成的可执行文件的名称
8
+ set OUTPUT_NAME=aurora
9
+
10
+ REM 设置 Go 源文件的名称
11
+ SET GOFILE=aurora
12
+
13
+ REM 设置输出目录
14
+ SET OUTPUTDIR=target
15
+
16
+ REM 确保输出目录存在
17
+ IF NOT EXIST %OUTPUTDIR% MKDIR %OUTPUTDIR%
18
+
19
+ REM 编译为 Windows/amd64
20
+ echo 开始编译 Windows/amd64
21
+ SET GOOS=windows
22
+ SET GOARCH=amd64
23
+ go build -o %OUTPUTDIR%/%OUTPUT_NAME%_windows_amd64.exe %GOFILE%
24
+ echo 编译完成 Windows/amd64
25
+
26
+ REM 编译为 Windows/386
27
+ echo 开始编译 Windows/386
28
+ SET GOOS=windows
29
+ SET GOARCH=386
30
+ go build -o %OUTPUTDIR%/%OUTPUT_NAME%_windows_386.exe %GOFILE%
31
+ echo 编译完成 Windows/386
32
+
33
+ REM 编译为 Linux/amd64
34
+ echo 开始编译 Linux/amd64
35
+ SET GOOS=linux
36
+ SET GOARCH=amd64
37
+ go build -o %OUTPUTDIR%/%OUTPUT_NAME%_linux_amd64 %GOFILE%
38
+ echo 编译完成 Linux/amd64
39
+
40
+ REM 编译为 macOS/amd64
41
+ echo 开始编译 macOS/amd64
42
+ SET GOOS=darwin
43
+ SET GOARCH=amd64
44
+ go build -o %OUTPUTDIR%/%OUTPUT_NAME%_macos_amd64 %GOFILE%
45
+ echo 编译完成 macOS/amd64
46
+
47
+ REM 编译为 freebsd/amd64
48
+ echo 开始编译 freebsd/amd64
49
+ SET GOOS=freebsd
50
+ SET GOARCH=amd64
51
+ go build -o %OUTPUTDIR%/%OUTPUT_NAME%_freebsd_amd64 %GOFILE%
52
+ echo 编译完成 freebsd/amd64
53
+
54
+ REM 结束批处理脚本
55
+ ENDLOCAL
56
+ echo 编译完成!
render.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ services:
2
+ - type: web
3
+ name: duck2api
4
+ env: docker
5
+ dockerfilePath: ./Dockerfile
6
+ plan: free
7
+
typings/duckgo/request.go ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package duckgo
2
+
3
+ type ApiRequest struct {
4
+ Model string `json:"model"`
5
+ Messages []messages `json:"messages"`
6
+ }
7
+ type messages struct {
8
+ Role string `json:"role"`
9
+ Content string `json:"content"`
10
+ }
11
+
12
+ func (a *ApiRequest) AddMessage(role string, content string) {
13
+ a.Messages = append(a.Messages, messages{
14
+ Role: role,
15
+ Content: content,
16
+ })
17
+ }
18
+
19
+ func NewApiRequest(model string) ApiRequest {
20
+ return ApiRequest{
21
+ Model: model,
22
+ }
23
+ }
typings/duckgo/response.go ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ package duckgo
2
+
3
+ type ApiResponse struct {
4
+ Message string `json:"message"`
5
+ Created int `json:"created"`
6
+ Id string `json:"id"`
7
+ Action string `json:"action"`
8
+ Model string `json:"model"`
9
+ }
typings/official/request.go ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package official
2
+
3
+ type APIRequest struct {
4
+ Messages []api_message `json:"messages"`
5
+ Stream bool `json:"stream"`
6
+ Model string `json:"model"`
7
+ PluginIDs []string `json:"plugin_ids"`
8
+ }
9
+
10
+ type api_message struct {
11
+ Role string `json:"role"`
12
+ Content interface{} `json:"content"`
13
+ }
14
+
15
+ type OpenAISessionToken struct {
16
+ SessionToken string `json:"session_token"`
17
+ }
18
+
19
+ type OpenAIRefreshToken struct {
20
+ RefreshToken string `json:"refresh_token"`
21
+ }
typings/official/response.go ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package official
2
+
3
+ import "encoding/json"
4
+
5
+ type ChatCompletionChunk struct {
6
+ ID string `json:"id"`
7
+ Object string `json:"object"`
8
+ Created int64 `json:"created"`
9
+ Model string `json:"model"`
10
+ Choices []Choices `json:"choices"`
11
+ }
12
+
13
+ func (chunk *ChatCompletionChunk) String() string {
14
+ resp, _ := json.Marshal(chunk)
15
+ return string(resp)
16
+ }
17
+
18
+ type Choices struct {
19
+ Delta Delta `json:"delta"`
20
+ Index int `json:"index"`
21
+ FinishReason interface{} `json:"finish_reason"`
22
+ }
23
+
24
+ type Delta struct {
25
+ Content string `json:"content,omitempty"`
26
+ Role string `json:"role,omitempty"`
27
+ }
28
+
29
+ func NewChatCompletionChunk(text string) ChatCompletionChunk {
30
+ return ChatCompletionChunk{
31
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
32
+ Object: "chat.completion.chunk",
33
+ Created: 0,
34
+ Model: "gpt-4o-mini",
35
+ Choices: []Choices{
36
+ {
37
+ Index: 0,
38
+ Delta: Delta{
39
+ Content: text,
40
+ },
41
+ FinishReason: nil,
42
+ },
43
+ },
44
+ }
45
+ }
46
+
47
+ func NewChatCompletionChunkWithModel(text string, model string) ChatCompletionChunk {
48
+ return ChatCompletionChunk{
49
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
50
+ Object: "chat.completion.chunk",
51
+ Created: 0,
52
+ Model: model,
53
+ Choices: []Choices{
54
+ {
55
+ Index: 0,
56
+ Delta: Delta{
57
+ Content: text,
58
+ },
59
+ FinishReason: nil,
60
+ },
61
+ },
62
+ }
63
+ }
64
+
65
+ func StopChunkWithModel(reason string, model string) ChatCompletionChunk {
66
+ return ChatCompletionChunk{
67
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
68
+ Object: "chat.completion.chunk",
69
+ Created: 0,
70
+ Model: model,
71
+ Choices: []Choices{
72
+ {
73
+ Index: 0,
74
+ FinishReason: reason,
75
+ },
76
+ },
77
+ }
78
+ }
79
+
80
+ func StopChunk(reason string) ChatCompletionChunk {
81
+ return ChatCompletionChunk{
82
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
83
+ Object: "chat.completion.chunk",
84
+ Created: 0,
85
+ Model: "gpt-4o-mini",
86
+ Choices: []Choices{
87
+ {
88
+ Index: 0,
89
+ FinishReason: reason,
90
+ },
91
+ },
92
+ }
93
+ }
94
+
95
+ type ChatCompletion struct {
96
+ ID string `json:"id"`
97
+ Object string `json:"object"`
98
+ Created int64 `json:"created"`
99
+ Model string `json:"model"`
100
+ Usage usage `json:"usage"`
101
+ Choices []Choice `json:"choices"`
102
+ }
103
+ type Msg struct {
104
+ Role string `json:"role"`
105
+ Content string `json:"content"`
106
+ }
107
+ type Choice struct {
108
+ Index int `json:"index"`
109
+ Message Msg `json:"message"`
110
+ FinishReason interface{} `json:"finish_reason"`
111
+ }
112
+ type usage struct {
113
+ PromptTokens int `json:"prompt_tokens"`
114
+ CompletionTokens int `json:"completion_tokens"`
115
+ TotalTokens int `json:"total_tokens"`
116
+ }
117
+
118
+ func NewChatCompletionWithModel(text string, model string) ChatCompletion {
119
+ return ChatCompletion{
120
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
121
+ Object: "chat.completion",
122
+ Created: int64(0),
123
+ Model: model,
124
+ Usage: usage{
125
+ PromptTokens: 0,
126
+ CompletionTokens: 0,
127
+ TotalTokens: 0,
128
+ },
129
+ Choices: []Choice{
130
+ {
131
+ Message: Msg{
132
+ Content: text,
133
+ Role: "assistant",
134
+ },
135
+ Index: 0,
136
+ },
137
+ },
138
+ }
139
+ }
140
+
141
+ func NewChatCompletion(full_test string, input_tokens, output_tokens int) ChatCompletion {
142
+ return ChatCompletion{
143
+ ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
144
+ Object: "chat.completion",
145
+ Created: int64(0),
146
+ Model: "gpt-4o-mini",
147
+ Usage: usage{
148
+ PromptTokens: input_tokens,
149
+ CompletionTokens: output_tokens,
150
+ TotalTokens: input_tokens + output_tokens,
151
+ },
152
+ Choices: []Choice{
153
+ {
154
+ Message: Msg{
155
+ Content: full_test,
156
+ Role: "assistant",
157
+ },
158
+ Index: 0,
159
+ },
160
+ },
161
+ }
162
+ }
typings/typings.go ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ package typings
2
+
3
+ type GenericResponseLine struct {
4
+ Line string `json:"line"`
5
+ Error string `json:"error"`
6
+ }
7
+
8
+ type StringStruct struct {
9
+ Text string `json:"text"`
10
+ }
util/util.go ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package util
2
+
3
+ import (
4
+ "log/slog"
5
+ "math/rand"
6
+ "time"
7
+
8
+ "github.com/pkoukk/tiktoken-go"
9
+ )
10
+
11
+ func RandomLanguage() string {
12
+ // 初始化随机数生成器
13
+ rand.Seed(time.Now().UnixNano())
14
+ // 语言列表
15
+ languages := []string{"af", "am", "ar-sa", "as", "az-Latn", "be", "bg", "bn-BD", "bn-IN", "bs", "ca", "ca-ES-valencia", "cs", "cy", "da", "de", "de-de", "el", "en-GB", "en-US", "es", "es-ES", "es-US", "es-MX", "et", "eu", "fa", "fi", "fil-Latn", "fr", "fr-FR", "fr-CA", "ga", "gd-Latn", "gl", "gu", "ha-Latn", "he", "hi", "hr", "hu", "hy", "id", "ig-Latn", "is", "it", "it-it", "ja", "ka", "kk", "km", "kn", "ko", "kok", "ku-Arab", "ky-Cyrl", "lb", "lt", "lv", "mi-Latn", "mk", "ml", "mn-Cyrl", "mr", "ms", "mt", "nb", "ne", "nl", "nl-BE", "nn", "nso", "or", "pa", "pa-Arab", "pl", "prs-Arab", "pt-BR", "pt-PT", "qut-Latn", "quz", "ro", "ru", "rw", "sd-Arab", "si", "sk", "sl", "sq", "sr-Cyrl-BA", "sr-Cyrl-RS", "sr-Latn-RS", "sv", "sw", "ta", "te", "tg-Cyrl", "th", "ti", "tk-Latn", "tn", "tr", "tt-Cyrl", "ug-Arab", "uk", "ur", "uz-Latn", "vi", "wo", "xh", "yo-Latn", "zh-Hans", "zh-Hant", "zu"}
16
+ // 随机选择一个语言
17
+ randomIndex := rand.Intn(len(languages))
18
+ return languages[randomIndex]
19
+ }
20
+
21
+ func RandomHexadecimalString() string {
22
+ rand.Seed(time.Now().UnixNano())
23
+ const charset = "0123456789abcdef"
24
+ const length = 16 // The length of the string you want to generate
25
+ b := make([]byte, length)
26
+ for i := range b {
27
+ b[i] = charset[rand.Intn(len(charset))]
28
+ }
29
+ return string(b)
30
+ }
31
+ func CountToken(input string) int {
32
+ encoding := "gpt-4o-mini"
33
+ tkm, err := tiktoken.EncodingForModel(encoding)
34
+ if err != nil {
35
+ slog.Warn("tiktoken.EncodingForModel error:", err)
36
+ return 0
37
+ }
38
+ token := tkm.Encode(input, nil, nil)
39
+ return len(token)
40
+ }
util/utils_test.go ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package util
2
+
3
+ import (
4
+ "fmt"
5
+ "testing"
6
+ )
7
+
8
+ func TestRandomHexadecimalString(t *testing.T) {
9
+ var str = RandomHexadecimalString()
10
+ fmt.Println(str)
11
+ }
vercel.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "routes": [
3
+ {
4
+ "src": "/.*",
5
+ "dest": "/api/router.go"
6
+ }
7
+ ]
8
+ }
web/avatar.png ADDED
web/icon.png ADDED
web/index.html ADDED
The diff for this file is too large to render. See raw diff