Alcex commited on
Commit
dca6a23
·
1 Parent(s): 1b33bd6

Add application file

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
.chglog/CHANGELOG.tpl.md ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{ range .Versions }}
2
+ <a name="{{ .Tag.Name }}"></a>
3
+ ## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
4
+ {{ range .CommitGroups -}}
5
+ ### {{ .Title }}
6
+ {{ range .Commits -}}
7
+ - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
8
+ {{ end }}
9
+ {{ end -}}
10
+
11
+ {{- if .RevertCommits -}}
12
+ ### Reverts
13
+ {{ range .RevertCommits -}}
14
+ - {{ .Revert.Header }}
15
+ {{ end }}
16
+ {{ end -}}
17
+
18
+ {{- if .MergeCommits -}}
19
+ ### Pull Requests
20
+ {{ range .MergeCommits -}}
21
+ - {{ .Header }}
22
+ {{ end }}
23
+ {{ end -}}
24
+
25
+ {{- if .NoteGroups -}}
26
+ {{ range .NoteGroups -}}
27
+ ### {{ .Title }}
28
+ {{ range .Notes }}
29
+ {{ .Body }}
30
+ {{ end }}
31
+ {{ end -}}
32
+ {{ end -}}
33
+ {{ end -}}
34
+
35
+ {{- if .Versions }}
36
+ [Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
37
+ {{ range .Versions -}}
38
+ {{ if .Tag.Previous -}}
39
+ [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
40
+ {{ end -}}
41
+ {{ end -}}
42
+ {{ end -}}
.chglog/config.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ style: github
2
+ template: CHANGELOG.tpl.md
3
+ info:
4
+ title: CHANGELOG
5
+ repository_url: https://github.com/aurorax-neo/free-gpt3.5-2api
6
+ options:
7
+ commits:
8
+ # filters:
9
+ # Type:
10
+ # - feat
11
+ # - fix
12
+ # - perf
13
+ # - refactor
14
+ commit_groups:
15
+ # title_maps:
16
+ # feat: Features
17
+ # fix: Bug Fixes
18
+ # perf: Performance Improvements
19
+ # refactor: Code Refactoring
20
+ header:
21
+ pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
22
+ pattern_maps:
23
+ - Type
24
+ - Scope
25
+ - Subject
26
+ notes:
27
+ keywords:
28
+ - BREAKING CHANGE
.gitattributes DELETED
@@ -1 +0,0 @@
1
- *.html linguist-language=Go
 
 
.github/workflows/Auto Release.yml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Auto Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'release-v*'
7
+
8
+ env:
9
+ APP_NAME: free-gpt3.5-2api
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - name: Set up Go
22
+ uses: actions/setup-go@v5
23
+ with:
24
+ go-version: 'stable'
25
+ check-latest: true
26
+
27
+ - name: Build Binary
28
+ run: |
29
+ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ${{ env.APP_NAME }} -a -ldflags '-s -w -extldflags "-static"' . && rm -rf artifact && mkdir -p artifact && cp ${{ env.APP_NAME }} artifact/${{ env.APP_NAME }} && cd artifact && tar -czvf ../${{ env.APP_NAME }}-linux-amd64.tar.gz * && cd ..
30
+ GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -o ${{ env.APP_NAME }} -a -ldflags '-s -w -extldflags "-static"' . && rm -rf artifact && mkdir -p artifact && cp ${{ env.APP_NAME }} artifact/${{ env.APP_NAME }} && cd artifact && tar -czvf ../${{ env.APP_NAME }}-darwin-amd64.tar.gz * && cd ..
31
+ GOOS=freebsd GOARCH=amd64 CGO_ENABLED=0 go build -o ${{ env.APP_NAME }} -a -ldflags '-s -w -extldflags "-static"' . && rm -rf artifact && mkdir -p artifact && cp ${{ env.APP_NAME }} artifact/${{ env.APP_NAME }} && cd artifact && tar -czvf ../${{ env.APP_NAME }}-freebsd-amd64.tar.gz * && cd ..
32
+ GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o ${{ env.APP_NAME }} -a -ldflags '-s -w -extldflags "-static"' . && rm -rf artifact && mkdir -p artifact && cp ${{ env.APP_NAME }} artifact/${{ env.APP_NAME }}.exe && cd artifact && tar -czvf ../${{ env.APP_NAME }}-windows-amd64.tar.gz * && cd ..
33
+
34
+ - name: Upload Artifact
35
+ uses: actions/upload-artifact@main
36
+ with:
37
+ name: ${{ env.APP_NAME }}-pre-built.zip
38
+ path: |
39
+ ${{ env.APP_NAME }}-windows-amd64.tar.gz
40
+ ${{ env.APP_NAME }}-linux-amd64.tar.gz
41
+ ${{ env.APP_NAME }}-darwin-amd64.tar.gz
42
+ ${{ env.APP_NAME }}-freebsd-amd64.tar.gz
43
+
44
+ - name: Get Release Name
45
+ shell: bash
46
+ id: grn
47
+ run: echo "tag=$(echo $GITHUB_REF | sed 's|refs/tags/||')" >> $GITHUB_OUTPUT
48
+
49
+ - name: Generate Changelog
50
+ id: changelog
51
+ run: |
52
+ export PATH=$PATH:$HOME/go/bin
53
+ go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest
54
+ git-chglog -o CHANGELOG.md ${{ steps.grn.outputs.tag }}
55
+
56
+ - name: Release
57
+ id: release
58
+ uses: softprops/action-gh-release@v2
59
+ if: startsWith(github.ref, 'refs/tags/')
60
+ env:
61
+ # GITHUB_TOKEN
62
+ GITHUB_TOKEN: ${{ secrets.GB_TOKEN }}
63
+ with:
64
+ # tag_name: 使用 tag
65
+ tag_name: ${{ github.ref }}
66
+ # release_name: 使用 tag
67
+ name: ${{ steps.grn.outputs.tag }}
68
+ # body: 使用 changelog
69
+ body_path: CHANGELOG.md
70
+ # 草稿
71
+ draft: false
72
+ # 预发布
73
+ prerelease: false
74
+ # 自动生成 release notes
75
+ generate_release_notes: true
76
+ # 上传文件
77
+ files: |
78
+ ${{ env.APP_NAME }}-linux-amd64.tar.gz
79
+ ${{ env.APP_NAME }}-windows-amd64.tar.gz
80
+ ${{ env.APP_NAME }}-darwin-amd64.tar.gz
81
+ ${{ env.APP_NAME }}-freebsd-amd64.tar.gz
82
+
83
+ - name: Delete Workflow Runs
84
+ uses: Mattraks/delete-workflow-runs@v2
85
+ with:
86
+ token: ${{ secrets.GB_TOKEN }}
87
+ repository: ${{ github.repository }}
88
+ retain_days: 1
89
+ keep_minimum_runs: 8
.github/workflows/Build Docker Image.yml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build Docker Image
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'release-v*'
7
+ workflow_dispatch:
8
+
9
+ env:
10
+ GHCR_REPO: ghcr.io/aurorax-neo/free-gpt3.5-2api
11
+
12
+ jobs:
13
+ main:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - name: Get Docker Image Tag
22
+ shell: bash
23
+ id: get_docker_image_tag
24
+ run: echo "tag=$(echo $GITHUB_REF | sed 's|refs/tags/release-v||')" >> $GITHUB_OUTPUT
25
+
26
+ - name: Set Up QEMU
27
+ uses: docker/setup-qemu-action@v3
28
+
29
+ - name: Set Up Docker Buildx
30
+ uses: docker/setup-buildx-action@v3
31
+
32
+ - name: Login To GitHub Container Registry
33
+ uses: docker/login-action@v3
34
+ with:
35
+ registry: ghcr.io
36
+ username: ${{ github.repository_owner }}
37
+ password: ${{ secrets.GB_TOKEN }}
38
+
39
+ - name: Cache Docker Layers
40
+ uses: actions/cache@v4
41
+ with:
42
+ path: /tmp/.buildx-cache
43
+ key: "${{ runner.os }}-buildx-${{ github.sha }}"
44
+ restore-keys: |
45
+ ${{ runner.os }}-buildx-
46
+
47
+ - name: Build Docker Image And Push To GHCR
48
+ uses: docker/build-push-action@v5
49
+ with:
50
+ push: true
51
+ context: .
52
+ platforms: linux/amd64,linux/arm64
53
+ file: Dockerfile
54
+ tags: |
55
+ ${{ env.GHCR_REPO }}:latest
56
+ ${{ env.GHCR_REPO }}:${{ steps.get_docker_image_tag.outputs.tag }}
57
+ ${{ env.GHCR_REPO }}:${{ github.sha }}
58
+ cache-from: type=local,src=/tmp/.buildx-cache
59
+ cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
60
+
61
+ - name: Delete Workflow Runs
62
+ uses: Mattraks/delete-workflow-runs@v2
63
+ with:
64
+ token: ${{ secrets.GB_TOKEN }}
65
+ repository: ${{ github.repository }}
66
+ retain_days: 1
67
+ keep_minimum_runs: 8
.gitignore CHANGED
@@ -1,15 +1,185 @@
1
- tools/authenticator/100-ACCOUNTS_COMPILED.txt
2
- tools/authenticator/accounts.txt
3
- tools/authenticator/proxies.txt
4
- tools/authenticator/authenticated_accounts.txt
5
- tools/authenticator/access_tokens.txt
6
- *.txt
7
- aurora
8
- chatgpttoapi
9
- tools/authenticator/.proxies.txt.swp
10
- .env
11
- *.har
12
- .idea/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /logs/
 
14
  /target/
15
- /bin/
 
1
+ ### JetBrains template
2
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
3
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
4
+
5
+ # User-specific stuff
6
+ .idea/**/workspace.xml
7
+ .idea/**/tasks.xml
8
+ .idea/**/usage.statistics.xml
9
+ .idea/**/dictionaries
10
+ .idea/**/shelf
11
+
12
+ # AWS User-specific
13
+ .idea/**/aws.xml
14
+
15
+ # Generated files
16
+ .idea/**/contentModel.xml
17
+
18
+ # Sensitive or high-churn files
19
+ .idea/**/dataSources/
20
+ .idea/**/dataSources.ids
21
+ .idea/**/dataSources.local.xml
22
+ .idea/**/sqlDataSources.xml
23
+ .idea/**/dynamic.xml
24
+ .idea/**/uiDesigner.xml
25
+ .idea/**/dbnavigator.xml
26
+
27
+ # Gradle
28
+ .idea/**/gradle.xml
29
+ .idea/**/libraries
30
+
31
+ # Gradle and Maven with auto-import
32
+ # When using Gradle or Maven with auto-import, you should exclude module files,
33
+ # since they will be recreated, and may cause churn. Uncomment if using
34
+ # auto-import.
35
+ # .idea/artifacts
36
+ # .idea/compiler.xml
37
+ # .idea/jarRepositories.xml
38
+ # .idea/modules.xml
39
+ # .idea/*.iml
40
+ # .idea/modules
41
+ # *.iml
42
+ # *.ipr
43
+
44
+ # CMake
45
+ cmake-build-*/
46
+
47
+ # Mongo Explorer plugin
48
+ .idea/**/mongoSettings.xml
49
+
50
+ # File-based project format
51
+ *.iws
52
+
53
+ # IntelliJ
54
+ out/
55
+
56
+ # mpeltonen/sbt-idea plugin
57
+ .idea_modules/
58
+
59
+ # JIRA plugin
60
+ atlassian-ide-plugin.xml
61
+
62
+ # Cursive Clojure plugin
63
+ .idea/replstate.xml
64
+
65
+ # SonarLint plugin
66
+ .idea/sonarlint/
67
+
68
+ # Crashlytics plugin (for Android Studio and IntelliJ)
69
+ com_crashlytics_export_strings.xml
70
+ crashlytics.properties
71
+ crashlytics-build.properties
72
+ fabric.properties
73
+
74
+ # Editor-based Rest Client
75
+ .idea/httpRequests
76
+
77
+ # Android studio 3.1+ serialized cache file
78
+ .idea/caches/build_file_checksums.ser
79
+
80
+ ### Go template
81
+ # If you prefer the allow list template instead of the deny list, see community template:
82
+ # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
83
+ #
84
+ # Binaries for programs and plugins
85
+ *.exe
86
+ *.exe~
87
+ *.dll
88
+ *.so
89
+ *.dylib
90
+
91
+ # Test binary, built with `go test -c`
92
+ *.test
93
+
94
+ # Output of the go coverage tool, specifically when used with LiteIDE
95
+ *.out
96
+
97
+ # Dependency directories (remove the comment below to include it)
98
+ # vendor/
99
+
100
+ # Go workspace file
101
+ go.work
102
+
103
+ ### GoLand template
104
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
105
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
106
+
107
+ # User-specific stuff
108
+ .idea/**/workspace.xml
109
+ .idea/**/tasks.xml
110
+ .idea/**/usage.statistics.xml
111
+ .idea/**/dictionaries
112
+ .idea/**/shelf
113
+
114
+ # AWS User-specific
115
+ .idea/**/aws.xml
116
+
117
+ # Generated files
118
+ .idea/**/contentModel.xml
119
+
120
+ # Sensitive or high-churn files
121
+ .idea/**/dataSources/
122
+ .idea/**/dataSources.ids
123
+ .idea/**/dataSources.local.xml
124
+ .idea/**/sqlDataSources.xml
125
+ .idea/**/dynamic.xml
126
+ .idea/**/uiDesigner.xml
127
+ .idea/**/dbnavigator.xml
128
+
129
+ # Gradle
130
+ .idea/**/gradle.xml
131
+ .idea/**/libraries
132
+
133
+ # Gradle and Maven with auto-import
134
+ # When using Gradle or Maven with auto-import, you should exclude module files,
135
+ # since they will be recreated, and may cause churn. Uncomment if using
136
+ # auto-import.
137
+ # .idea/artifacts
138
+ # .idea/compiler.xml
139
+ # .idea/jarRepositories.xml
140
+ # .idea/modules.xml
141
+ # .idea/*.iml
142
+ # .idea/modules
143
+ # *.iml
144
+ # *.ipr
145
+
146
+ # CMake
147
+ cmake-build-*/
148
+
149
+ # Mongo Explorer plugin
150
+ .idea/**/mongoSettings.xml
151
+
152
+ # File-based project format
153
+ *.iws
154
+
155
+ # IntelliJ
156
+ out/
157
+
158
+ # mpeltonen/sbt-idea plugin
159
+ .idea_modules/
160
+
161
+ # JIRA plugin
162
+ atlassian-ide-plugin.xml
163
+
164
+ # Cursive Clojure plugin
165
+ .idea/replstate.xml
166
+
167
+ # SonarLint plugin
168
+ .idea/sonarlint/
169
+
170
+ # Crashlytics plugin (for Android Studio and IntelliJ)
171
+ com_crashlytics_export_strings.xml
172
+ crashlytics.properties
173
+ crashlytics-build.properties
174
+ fabric.properties
175
+
176
+ # Editor-based Rest Client
177
+ .idea/httpRequests
178
+
179
+ # Android studio 3.1+ serialized cache file
180
+ .idea/caches/build_file_checksums.ser
181
+
182
  /logs/
183
+ /.env
184
  /target/
185
+ /CHANGELOG.md
Dockerfile CHANGED
@@ -1,30 +1,21 @@
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
- # 暴露端口
28
- EXPOSE 8080
29
 
30
- CMD ["/app/duck2api"]
 
 
1
  FROM golang:1.21 AS builder
2
 
 
3
  ENV CGO_ENABLED=0
4
 
 
5
  WORKDIR /app
6
 
 
7
  COPY go.mod go.sum ./
8
  RUN go mod download
9
 
 
10
  COPY . .
11
+ RUN go build -o /app/free-gpt3.5-2api .
12
 
 
13
  FROM alpine:latest
14
 
 
15
  WORKDIR /app
16
 
17
+ COPY --from=builder /app/free-gpt3.5-2api /app/free-gpt3.5-2api
 
18
 
19
+ EXPOSE 3040
 
20
 
21
+ CMD [ "./free-gpt3.5-2api" ]
FreeGpt35/FreeGpt35.go ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package FreeGpt35
2
+
3
+ import (
4
+ "encoding/json"
5
+ "fmt"
6
+ ProofWork2 "free-gpt3.5-2api/ProofWork"
7
+ "free-gpt3.5-2api/ProxyPool"
8
+ "free-gpt3.5-2api/RequestClient"
9
+ "free-gpt3.5-2api/common"
10
+ "free-gpt3.5-2api/config"
11
+ "free-gpt3.5-2api/constant"
12
+ "github.com/aurorax-neo/go-logger"
13
+ fhttp "github.com/bogdanfinn/fhttp"
14
+ "github.com/google/uuid"
15
+ "io"
16
+ )
17
+
18
+ var (
19
+ BaseUrl = config.BaseUrl
20
+ ChatUrl = BaseUrl + "/backend-anon/conversation"
21
+ AuthUrl = BaseUrl + "/backend-anon/sentinel/chat-requirements"
22
+ OfficialBaseURLS = []string{"https://chat.openai.com", "https://chatgpt.com"}
23
+ )
24
+
25
+ // NewFreeAuthType 定义一个枚举类型
26
+ type NewFreeAuthType int
27
+
28
+ const (
29
+ NewFreeAuthNormal NewFreeAuthType = 0 //正常获取
30
+ NewFreeAuthRefresh NewFreeAuthType = 1 // 刷新获取
31
+ )
32
+
33
+ type FreeGpt35 struct {
34
+ RequestClient RequestClient.RequestClient
35
+ Proxy *ProxyPool.Proxy
36
+ MaxUseCount int
37
+ ExpiresAt int64
38
+ FreeAuth *freeAuth
39
+ Ua string
40
+ Cookies []*fhttp.Cookie
41
+ }
42
+
43
+ type freeAuth struct {
44
+ OaiDeviceId string `json:"-"`
45
+ Persona string `json:"persona"`
46
+ Arkose arkose `json:"arkose"`
47
+ Turnstile turnstile `json:"turnstile"`
48
+ ProofWork ProofWork2.ProofWork `json:"proofofwork"`
49
+ Token string `json:"token"`
50
+ }
51
+
52
+ type arkose struct {
53
+ Required bool `json:"required"`
54
+ Dx string `json:"dx"`
55
+ }
56
+
57
+ type turnstile struct {
58
+ Required bool `json:"required"`
59
+ }
60
+
61
+ // NewFreeGpt35 创建 FreeGpt35 实例 0 无论网络是否被标记限制都获取 1 在网络未标记时才能获取
62
+ func NewFreeGpt35(newType NewFreeAuthType, maxUseCount int, expiresAt int64) *FreeGpt35 {
63
+ // 创建 FreeGpt35 实例
64
+ freeGpt35 := &FreeGpt35{
65
+ MaxUseCount: maxUseCount,
66
+ ExpiresAt: expiresAt,
67
+ FreeAuth: &freeAuth{},
68
+ }
69
+ // 获取请求客户端
70
+ err := freeGpt35.newRequestClient()
71
+ if err != nil {
72
+ logger.Logger.Debug(err.Error())
73
+ return nil
74
+ }
75
+ // 获取并设置代理
76
+ err = freeGpt35.getProxy(newType)
77
+ if err != nil {
78
+ logger.Logger.Debug(err.Error())
79
+ return nil
80
+ }
81
+ // 获取cookies
82
+ if common.IsStrInArray(BaseUrl, OfficialBaseURLS) {
83
+ err = freeGpt35.getCookies()
84
+ if err != nil {
85
+ logger.Logger.Debug(err.Error())
86
+ return nil
87
+ }
88
+ }
89
+ // 获取 FreeAuth
90
+ err = freeGpt35.newFreeAuth(newType)
91
+ if err != nil {
92
+ logger.Logger.Debug(err.Error())
93
+ return nil
94
+ }
95
+ return freeGpt35
96
+ }
97
+
98
+ func (FG *FreeGpt35) NewRequest(method, url string, body io.Reader) (*fhttp.Request, error) {
99
+ request, err := RequestClient.NewRequest(method, url, body)
100
+ if err != nil {
101
+ return nil, err
102
+ }
103
+ request.Header.Set("accept", "*/*")
104
+ request.Header.Set("accept-language", "zh-CN,zh;q=0.9,zh-Hans;q=0.8,en;q=0.7")
105
+ for _, cookie := range FG.Cookies {
106
+ request.AddCookie(cookie)
107
+ }
108
+ request.Header.Set("oai-language", "en-US")
109
+ request.Header.Set("origin", common.GetOrigin(url))
110
+ request.Header.Set("referer", common.GetOrigin(url))
111
+ request.Header.Set("sec-ch-ua", `"Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"`)
112
+ request.Header.Set("sec-ch-ua-mobile", "?0")
113
+ request.Header.Set("sec-ch-ua-platform", `"Windows"`)
114
+ request.Header.Set("sec-fetch-dest", "empty")
115
+ request.Header.Set("sec-fetch-mode", "cors")
116
+ request.Header.Set("sec-fetch-site", "same-origin")
117
+ request.Header.Set("user-agent", FG.Ua)
118
+ return request, nil
119
+ }
120
+
121
+ func (FG *FreeGpt35) newRequestClient() error {
122
+ // 请求客户端
123
+ FG.RequestClient = RequestClient.NewTlsClient(300, constant.ClientProfile)
124
+ if FG.RequestClient == nil {
125
+ errStr := fmt.Sprint("RequestClient is nil")
126
+ logger.Logger.Debug(errStr)
127
+ return fmt.Errorf(errStr)
128
+ }
129
+ return nil
130
+ }
131
+
132
+ func (FG *FreeGpt35) getProxy(newFreeAuthType NewFreeAuthType) error {
133
+ // 获取代理池
134
+ ProxyPoolInstance := ProxyPool.GetProxyPoolInstance()
135
+ // 获取代理
136
+ FG.Proxy = ProxyPoolInstance.GetProxy()
137
+ // 判断代理是否可用
138
+ if FG.Proxy.CanUseAt > common.GetTimestampSecond(0) && newFreeAuthType == NewFreeAuthRefresh {
139
+ errStr := fmt.Sprint(FG.Proxy.Link, ": Proxy restricted, Reuse at ", FG.Proxy.CanUseAt)
140
+ return fmt.Errorf(errStr)
141
+ }
142
+ // Ua
143
+ FG.Ua = FG.Proxy.Ua
144
+ // 补全cookies
145
+ FG.Cookies = append(FG.Cookies, FG.Proxy.Cookies...)
146
+ // 设置代理
147
+ err := FG.RequestClient.SetProxy(FG.Proxy.Link.String())
148
+ if err != nil {
149
+ errStr := fmt.Sprint("SetProxy Error: ", err)
150
+ logger.Logger.Debug(errStr)
151
+ }
152
+ return nil
153
+ }
154
+
155
+ func (FG *FreeGpt35) getCookies() error {
156
+ // 获取cookies
157
+ request, err := FG.NewRequest("GET", fmt.Sprint(BaseUrl, "/?oai-dm=1"), nil)
158
+ if err != nil {
159
+ return err
160
+ }
161
+ // 设置请求头
162
+ request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
163
+ // 发送 GET 请求
164
+ response, err := FG.RequestClient.Do(request)
165
+ if err != nil {
166
+ return err
167
+ }
168
+ defer func(Body io.ReadCloser) {
169
+ _ = Body.Close()
170
+ }(response.Body)
171
+ if response.StatusCode != 200 {
172
+ return fmt.Errorf("StatusCode: %d", response.StatusCode)
173
+ }
174
+ // 获取cookies
175
+ cookies := response.Cookies()
176
+ for i, cookie := range cookies {
177
+ if cookie.Name == "oai-did" {
178
+ FG.FreeAuth.OaiDeviceId = cookie.Value
179
+ cookies = append(cookies[:i], cookies[i+1:]...)
180
+ }
181
+ if cookie.Name == "__Secure-next-auth.callback-url" {
182
+ cookie.Value = BaseUrl
183
+ }
184
+ }
185
+ // 设置cookies
186
+ FG.Cookies = append(FG.Cookies, cookies...)
187
+ return nil
188
+ }
189
+
190
+ func (FG *FreeGpt35) newFreeAuth(newFreeAuthType NewFreeAuthType) error {
191
+ // 生成新的设备 ID
192
+ if FG.FreeAuth.OaiDeviceId == "" {
193
+ FG.FreeAuth.OaiDeviceId = uuid.New().String()
194
+ }
195
+ // 创建请求
196
+ request, err := FG.NewRequest("POST", AuthUrl, nil)
197
+ if err != nil {
198
+ return err
199
+ }
200
+ // 设置请求头
201
+ request.Header.Set("Content-Type", "application/json")
202
+ request.Header.Set("oai-device-id", FG.FreeAuth.OaiDeviceId)
203
+ // 发送 POST 请求
204
+ response, err := FG.RequestClient.Do(request)
205
+ if err != nil {
206
+ return err
207
+ }
208
+ if response.StatusCode != 200 {
209
+ logger.Logger.Debug(fmt.Sprint("newFreeAuth: StatusCode: ", response.StatusCode))
210
+ if (response.StatusCode == 429 || response.StatusCode == 403) && newFreeAuthType == NewFreeAuthRefresh {
211
+ FG.Proxy.CanUseAt = common.GetTimestampSecond(300)
212
+ logger.Logger.Debug(fmt.Sprint("newFreeAuth: Proxy(", FG.Proxy.Link, ")restricted, Reuse at ", FG.Proxy.CanUseAt))
213
+ }
214
+ return fmt.Errorf("StatusCode: %d", response.StatusCode)
215
+ } else if newFreeAuthType == 0 {
216
+ // 成功后更新代理的可用时间
217
+ FG.Proxy.CanUseAt = common.GetTimestampSecond(0)
218
+ logger.Logger.Debug(fmt.Sprint("newFreeAuth: Proxy(", FG.Proxy.Link, ")Reuse at ", FG.Proxy.CanUseAt))
219
+ }
220
+ defer func(Body io.ReadCloser) {
221
+ _ = Body.Close()
222
+ }(response.Body)
223
+ if err := json.NewDecoder(response.Body).Decode(&FG.FreeAuth); err != nil {
224
+ return err
225
+ }
226
+ // ProofWork
227
+ if FG.FreeAuth.ProofWork.Required {
228
+ FG.FreeAuth.ProofWork.Ospt = ProofWork2.CalcProofToken(FG.FreeAuth.ProofWork.Seed, FG.FreeAuth.ProofWork.Difficulty, request.Header.Get("User-Agent"))
229
+ }
230
+ return nil
231
+ }
FreeGpt35Pool/FreeGpt35Pool.go ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package FreeGpt35Pool
2
+
3
+ import (
4
+ "fmt"
5
+ "free-gpt3.5-2api/FreeGpt35"
6
+ "free-gpt3.5-2api/common"
7
+ "free-gpt3.5-2api/config"
8
+ "free-gpt3.5-2api/queue"
9
+ "github.com/aurorax-neo/go-logger"
10
+ "sync"
11
+ "time"
12
+ )
13
+
14
+ var (
15
+ instance *FreeGpt35Pool
16
+ once sync.Once
17
+ )
18
+
19
+ type FreeGpt35Pool struct {
20
+ queue *queue.Queue
21
+ capacity int // 队列容量
22
+ }
23
+
24
+ func newFreeGpt35Pool(capacity int) *FreeGpt35Pool {
25
+ return &FreeGpt35Pool{
26
+ queue: queue.New(),
27
+ capacity: capacity,
28
+ }
29
+ }
30
+
31
+ func GetFreeGpt35PoolInstance() *FreeGpt35Pool {
32
+ once.Do(func() {
33
+ logger.Logger.Info(fmt.Sprint("Init FreeGpt35Pool..."))
34
+ // 初始化 FreeGpt35Pool
35
+ instance = newFreeGpt35Pool(config.PoolMaxCount)
36
+ // 定时刷新 FreeGpt35Pool
37
+ instance.refreshFreeGpt35Pool(time.Millisecond * 256)
38
+ //
39
+ logger.Logger.Info(fmt.Sprint("Init FreeGpt35Pool Success", ", PoolMaxCount: ", config.PoolMaxCount, ", AuthExpirationDate: ", config.AuthED))
40
+ })
41
+ return instance
42
+ }
43
+
44
+ func (G *FreeGpt35Pool) refreshFreeGpt35Pool(sleep time.Duration) {
45
+ // 检测 FreeGpt35Pool 是否已满
46
+ common.AsyncLoopTask(sleep, func() {
47
+ // 判断 FreeGpt35Pool 是否已满
48
+ if G.IsFull() {
49
+ return
50
+ }
51
+ // 获取新 FreeGpt35 实例
52
+ gpt35 := FreeGpt35.NewFreeGpt35(FreeGpt35.NewFreeAuthRefresh, 1, common.GetTimestampSecond(config.AuthED))
53
+ // 判断 FreeGpt35 实例是否有效
54
+ if G.isLiveGpt35(gpt35) {
55
+ // 入队新 FreeGpt35 实例
56
+ G.AddFreeGpt35(gpt35)
57
+ }
58
+ })
59
+ // 检测并移除无效 FreeGpt35 实例
60
+ common.AsyncLoopTask(sleep, func() {
61
+ // 遍历队列中的所有元素
62
+ G.queue.Traverse(func(n *queue.Node) {
63
+ // 判断是否为无效 FreeGpt35 实例
64
+ if !G.isLiveGpt35(n.Value.(*FreeGpt35.FreeGpt35)) {
65
+ // 移除无效 FreeGpt35 实例
66
+ G.queue.Remove(n)
67
+ }
68
+ })
69
+ })
70
+ }
71
+
72
+ func (G *FreeGpt35Pool) isLiveGpt35(gpt35 *FreeGpt35.FreeGpt35) bool {
73
+ //判断是否为空
74
+ if gpt35 == nil ||
75
+ gpt35.MaxUseCount <= 0 || //无可用次数
76
+ gpt35.ExpiresAt <= common.GetTimestampSecond(0) {
77
+ return false
78
+ }
79
+ return true
80
+ }
81
+
82
+ func (G *FreeGpt35Pool) GetFreeGpt35(retry int) *FreeGpt35.FreeGpt35 {
83
+ // 获取 FreeGpt35 实例
84
+ n := G.queue.Peek()
85
+ if n != nil {
86
+ gpt35 := n.Value.(*FreeGpt35.FreeGpt35)
87
+ if G.isLiveGpt35(gpt35) { //有缓存
88
+ // 深拷贝
89
+ gpt35_ := common.DeepCopyStruct(gpt35).(*FreeGpt35.FreeGpt35)
90
+ // 减少 FreeGpt35 实例的最大使用次数
91
+ gpt35.MaxUseCount--
92
+ // 判断 FreeGpt35 实例是否有效 无效则移除
93
+ if !G.isLiveGpt35(gpt35) {
94
+ G.queue.Dequeue()
95
+ }
96
+ return gpt35_
97
+ } else if retry > 0 {
98
+ time.Sleep(time.Millisecond * 128)
99
+ return G.GetFreeGpt35(retry - 1)
100
+ }
101
+ }
102
+ // 缓存内无可用 FreeGpt35 实例,返回新 FreeGpt35 实例
103
+ return FreeGpt35.NewFreeGpt35(FreeGpt35.NewFreeAuthNormal, 1, common.GetTimestampSecond(config.AuthED))
104
+ }
105
+
106
+ // GetSize 获取队列当前元素个数
107
+ func (G *FreeGpt35Pool) GetSize() int {
108
+ return G.queue.Len()
109
+ }
110
+
111
+ // GetCapacity 获取队列容量
112
+ func (G *FreeGpt35Pool) GetCapacity() int {
113
+ return G.capacity
114
+ }
115
+
116
+ // IsFull 检查队列是否已满
117
+ func (G *FreeGpt35Pool) IsFull() bool {
118
+ return G.GetSize() == G.capacity
119
+ }
120
+
121
+ // AddFreeGpt35 入队
122
+ func (G *FreeGpt35Pool) AddFreeGpt35(v *FreeGpt35.FreeGpt35) bool {
123
+ if G.IsFull() || v == nil {
124
+ return false
125
+ }
126
+ G.queue.Enqueue(v)
127
+ return true
128
+ }
LICENSE DELETED
@@ -1,21 +0,0 @@
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 DELETED
@@ -1 +0,0 @@
1
- web: aurora
 
 
ProofWork/ProofWork.go ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ProofWork
2
+
3
+ import (
4
+ "encoding/base64"
5
+ "encoding/hex"
6
+ "encoding/json"
7
+ "golang.org/x/crypto/sha3"
8
+ "math/rand"
9
+ "time"
10
+ )
11
+
12
+ var (
13
+ numberCollisions = 100000
14
+ cores = []int{8, 12, 16, 24}
15
+ screens = []int{3000, 4000, 6000}
16
+ timeLayout = "Mon Jan 2 2006 15:04:05"
17
+ )
18
+
19
+ type ProofWork struct {
20
+ Difficulty string `json:"difficulty,omitempty"`
21
+ Required bool `json:"required"`
22
+ Seed string `json:"seed,omitempty"`
23
+ Ospt string `json:"-"`
24
+ }
25
+
26
+ func getParseTime() string {
27
+ now := time.Now()
28
+ return now.Format(timeLayout) + " GMT" + now.Format("-0700 MST (MST)")
29
+ }
30
+
31
+ func getConfig(userAgent string) []interface{} {
32
+ rand.New(rand.NewSource(time.Now().UnixNano()))
33
+ core := cores[rand.Intn(4)]
34
+ rand.New(rand.NewSource(time.Now().UnixNano()))
35
+ screen := screens[rand.Intn(3)]
36
+ return []interface{}{core + screen, getParseTime(), int64(4294705152), 0, userAgent}
37
+
38
+ }
39
+
40
+ func CalcProofToken(seed string, diff string, userAgent string) string {
41
+ config := getConfig(userAgent)
42
+ hasher := sha3.New512()
43
+ for i := 0; i < numberCollisions; i++ {
44
+ config[3] = i
45
+ jsonStr, _ := json.Marshal(config)
46
+ base := base64.StdEncoding.EncodeToString(jsonStr)
47
+ hasher.Write([]byte(seed + base))
48
+ hash := hasher.Sum(nil)
49
+ hasher.Reset()
50
+ if hex.EncodeToString(hash[:len(diff)]) <= diff {
51
+ return "gAAAAAB" + base
52
+ }
53
+ }
54
+ return "gAAAAABwQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + base64.StdEncoding.EncodeToString([]byte(`"`+seed+`"`))
55
+ }
ProxyPool/ProxyPool.go ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ProxyPool
2
+
3
+ import (
4
+ "fmt"
5
+ "free-gpt3.5-2api/common"
6
+ "free-gpt3.5-2api/config"
7
+ "free-gpt3.5-2api/constant"
8
+ "github.com/aurorax-neo/go-logger"
9
+ fhttp "github.com/bogdanfinn/fhttp"
10
+ "net/url"
11
+ "sync"
12
+ "time"
13
+ )
14
+
15
+ var (
16
+ Instance *ProxyPool
17
+ Once sync.Once
18
+ )
19
+
20
+ type ProxyPool struct {
21
+ Proxies []*Proxy
22
+ Index int
23
+ }
24
+
25
+ type Proxy struct {
26
+ Link *url.URL
27
+ CanUseAt int64
28
+ Ua string
29
+ Cookies []*fhttp.Cookie
30
+ }
31
+
32
+ func GetProxyPoolInstance() *ProxyPool {
33
+ Once.Do(func() {
34
+ logger.Logger.Info(fmt.Sprint("Init ProxyPool..."))
35
+ // 初始化 ProxyPool
36
+ Instance = NewProxyPool(nil)
37
+ // 遍历配置文件中的代理 添加到代理池
38
+ for _, px := range config.Proxy {
39
+ proxy := NewProxy(px, common.GetTimestampSecond(0), constant.Ua)
40
+ _ = proxy.getCookies()
41
+ Instance.AddProxy(proxy)
42
+ }
43
+ //定时刷新代理cookies
44
+ common.AsyncLoopTask(1*time.Minute, func() {
45
+ for _, proxy := range Instance.Proxies {
46
+ _ = proxy.getCookies()
47
+ }
48
+ })
49
+ logger.Logger.Info(fmt.Sprint("Init ProxyPool Success"))
50
+ })
51
+ return Instance
52
+ }
53
+
54
+ func NewProxyPool(proxies []*Proxy) *ProxyPool {
55
+ proxy := NewProxy("", common.GetTimestampSecond(0), constant.Ua)
56
+ _ = proxy.getCookies()
57
+ return &ProxyPool{
58
+ Proxies: append([]*Proxy{proxy}, proxies...),
59
+ Index: 0,
60
+ }
61
+ }
62
+
63
+ func (PP *ProxyPool) GetProxy() *Proxy {
64
+ PP.Index = (PP.Index + 1) % len(PP.Proxies)
65
+ // 如果配置了代理 不会使用无代理
66
+ if PP.Index == 0 && len(PP.Proxies) > 1 {
67
+ PP.Index = 1
68
+ }
69
+ // 返回代理
70
+ return PP.Proxies[PP.Index]
71
+ }
72
+
73
+ func (PP *ProxyPool) AddProxy(proxy *Proxy) {
74
+ PP.Proxies = append(PP.Proxies, proxy)
75
+ }
76
+
77
+ func NewProxy(link string, cannotUseTime int64, ua string) *Proxy {
78
+ return &Proxy{
79
+ Link: common.ParseUrl(link),
80
+ CanUseAt: cannotUseTime,
81
+ Ua: ua,
82
+ }
83
+ }
84
+
85
+ func (P *Proxy) getCookies() error {
86
+ return nil
87
+ }
README.md CHANGED
@@ -1,90 +1,94 @@
1
- # duck2api
2
 
 
3
 
 
4
 
5
- # 交流群
6
- https://t.me/aurora_develop
7
-
8
- # Web端
9
-
10
- 访问http://你的服务器ip:8080/web
11
-
12
- ![web使用](https://jsd.cdn.zzko.cn/gh/xiaozhou26/tuph@main/images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202024-04-07%20111706.png)
13
 
14
- ## Deploy
15
 
 
 
 
 
 
16
 
17
- ### Render部署
18
- [![Deploy](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy)
19
 
20
- ### 编译部署
21
 
22
- ```bash
23
- git clone https://github.com/aurora-develop/duck2api
24
- cd duck2api
25
- go build -o duck2api
26
- chmod +x ./duck2api
27
- ./duck2api
28
  ```
29
 
30
- ### Docker部署
31
- ## Docker部署
32
- 您需要安装Docker和Docker Compose。
33
 
34
- ```bash
35
- docker run -d \
36
- --name duck2api \
37
- -p 8080:8080 \
38
- ghcr.io/aurora-develop/duck2api:latest
39
  ```
40
-
41
- ## Docker Compose部署
42
- 创建一个新的目录,例如duck2api,并进入该目录:
43
- ```bash
44
- mkdir duck2api
45
- cd duck2api
46
  ```
47
- 在此目录中下载库中的docker-compose.yml文件:
48
 
49
- ```bash
50
- docker-compose up -d
51
  ```
52
-
53
- ## Usage
54
-
55
- ```bash
56
- curl --location 'http://你的服务器ip:8080/v1/chat/completions' \
57
  --header 'Content-Type: application/json' \
58
- --data '{
59
- "model": "gpt-3.5-turbo",
60
- "messages": [{"role": "user", "content": "Say this is a test!"}],
61
- "stream": true
62
- }'
 
 
 
 
 
63
  ```
64
- 支持claude和gpt-3.5-turbo
65
- ## 高级设置
66
 
67
- 默认情况不需要设置,除非你有需求
68
 
69
  ### 环境变量
 
 
 
 
 
 
 
 
 
 
 
70
  ```
71
 
72
- Authorization=your_authorization 用户认证 key。
73
- TLS_CERT=path_to_your_tls_cert 存储TLS(传输层安全协议)证书的路径。
74
- TLS_KEY=path_to_your_tls_key 存储TLS(传输层安全协议)证书的路径。
75
- PROXY_URL=your_proxy_url 添加代理池来。
 
 
 
 
 
76
  ```
77
 
78
- ## 鸣谢
79
 
80
- 感谢各位大佬的pr支持,感谢。
 
 
81
 
 
82
 
83
- ## 参考项目
 
 
84
 
 
85
 
86
- https://github.com/xqdoo00o/ChatGPT-to-API
87
 
88
- ## License
89
 
90
- MIT License
 
1
+ # [free-gpt3.5-2api](https://github.com/aurorax-neo/free-gpt3.5-2api)
2
 
3
+ ## 接口
4
 
5
+ #### /v1/tokens
6
 
7
+ ```
8
+ curl --location --request GET 'http://127.0.0.1:9846/v1/tokens' \
9
+ --header 'Authorization: Bearer abc'
10
+ ```
 
 
 
 
11
 
12
+ 返回示例说明:`count`为授权池中可用授权数,如果`count` 为 `0`请检查`ip`是否支持 `openai`
13
 
14
+ ```
15
+ {
16
+ "count": 0
17
+ }
18
+ ```
19
 
20
+ #### /v1/chat/completions
 
21
 
22
+ ###### 支持返回stream和json
23
 
24
+ ```
25
+ http://<ip>:<port>/v1/chat/completions
 
 
 
 
26
  ```
27
 
28
+ ##### 示例
 
 
29
 
 
 
 
 
 
30
  ```
31
+ curl http://127.0.0.1:9846
 
 
 
 
 
32
  ```
 
33
 
 
 
34
  ```
35
+ curl --location --request POST 'http://127.0.0.1:9846/v1/chat/completions' \
36
+ --header 'Authorization: Bearer abc' \
 
 
 
37
  --header 'Content-Type: application/json' \
38
+ --data-raw '{
39
+ "model": "gpt-3.5-turbo",
40
+ "messages": [
41
+ {
42
+ "role": "user",
43
+ "content": "西红柿炒钢丝球怎么做?"
44
+ }
45
+ ],
46
+ "stream": false
47
+ }'
48
  ```
 
 
49
 
50
+ ## 配置
51
 
52
  ### 环境变量
53
+
54
+ ```
55
+ LOG_LEVEL=info # debug, info, warn, error
56
+ LOG_PATH= # 日志文件路径,默认为空(不生成日志文件)
57
+ BIND=0.0.0.0 # 127.0.0.1
58
+ PORT=3040
59
+ PROXY= # http://127.0.0.1:7890,http://127.0.0.1:7890 已支持多个代理(英文 "," 分隔)
60
+ AUTHORIZATIONS= # abc,bac (英文 "," 分隔)
61
+ BASE_URL= # 默认:https://chat.openai.com
62
+ POOL_MAX_COUNT=64 # max number of connections to keep in the pool 默认:64
63
+ AUTH_ED=600 # expiration time for the authorization in seconds 默认:600
64
  ```
65
 
66
+ ###### 也可使用与程序同目录下 `.env` 文件配置上述字段
67
+
68
+
69
+ ### docker部署
70
+
71
+ ##### 1 .创建文件夹
72
+
73
+ ```
74
+ mkdir -p $PWD/free-gpt3.5-2api
75
  ```
76
 
77
+ ##### 2.拉取镜像启动
78
 
79
+ ```
80
+ docker run -itd --name=free-gpt3.5-2api -p 9846:3040 ghcr.io/aurorax-neo/free-gpt3.5-2api
81
+ ```
82
 
83
+ ##### 3.更新容器
84
 
85
+ ```
86
+ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR free-gpt3.5-2api --debug
87
+ ```
88
 
89
+ ### Koyeb部署
90
 
91
+ ###### 注意:`Regions`请选择支持`openai`免登的区域!!!
92
 
93
+ [![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?type=docker&name=free-gpt3-5-2api&region=par&ports=3040;http;/&image=ghcr.io/aurorax-neo/free-gpt3.5-2api)
94
 
 
RequestClient/RequestClient.go ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ package RequestClient
2
+
3
+ import (
4
+ fhttp "github.com/bogdanfinn/fhttp"
5
+ )
6
+
7
+ type RequestClient interface {
8
+ Do(req *fhttp.Request) (*fhttp.Response, error)
9
+ SetProxy(link string) error
10
+ }
RequestClient/TlsClient.go ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package RequestClient
2
+
3
+ import (
4
+ fhttp "github.com/bogdanfinn/fhttp"
5
+ tlsClient "github.com/bogdanfinn/tls-client"
6
+ "github.com/bogdanfinn/tls-client/profiles"
7
+ "io"
8
+ "math/rand"
9
+ "time"
10
+ )
11
+
12
+ type TlsClient struct {
13
+ client tlsClient.HttpClient
14
+ }
15
+
16
+ func NewTlsClient(timeoutSeconds int, clientProfile profiles.ClientProfile) *TlsClient {
17
+ jar := tlsClient.NewCookieJar()
18
+ options := []tlsClient.HttpClientOption{
19
+ tlsClient.WithTimeoutSeconds(timeoutSeconds),
20
+ tlsClient.WithClientProfile(clientProfile),
21
+ tlsClient.WithNotFollowRedirects(),
22
+ tlsClient.WithCookieJar(jar),
23
+ }
24
+ client, err := tlsClient.NewHttpClient(tlsClient.NewNoopLogger(), options...)
25
+ if err != nil {
26
+ return nil
27
+ }
28
+ return &TlsClient{
29
+ client: client,
30
+ }
31
+ }
32
+
33
+ func RandomClientProfile() profiles.ClientProfile {
34
+ // 初始化随机数生成器
35
+ seed := time.Now().UnixNano()
36
+ rng := rand.New(rand.NewSource(seed))
37
+ clientProfiles := []profiles.ClientProfile{
38
+ profiles.Firefox_102,
39
+ profiles.Safari_15_6_1,
40
+ profiles.Safari_16_0,
41
+ profiles.Chrome_110,
42
+ profiles.Okhttp4Android13,
43
+ profiles.CloudflareCustom,
44
+ profiles.Firefox_117,
45
+ }
46
+ // 随机选择一个
47
+ randomIndex := rng.Intn(len(clientProfiles))
48
+ return clientProfiles[randomIndex]
49
+ }
50
+
51
+ func NewRequest(method, url string, body io.Reader) (*fhttp.Request, error) {
52
+ request, err := fhttp.NewRequest(method, url, body)
53
+ if err != nil {
54
+ return nil, err
55
+ }
56
+ return request, nil
57
+
58
+ }
59
+
60
+ func (T *TlsClient) Do(req *fhttp.Request) (*fhttp.Response, error) {
61
+ response, err := T.client.Do(req)
62
+ if err != nil {
63
+ return nil, err
64
+ }
65
+ return response, nil
66
+ }
67
+
68
+ func (T *TlsClient) SetProxy(link string) error {
69
+ if link == "" {
70
+ return nil
71
+ }
72
+ err := T.client.SetProxy(link)
73
+ if err != nil {
74
+ return err
75
+ }
76
+ return nil
77
+ }
VERSION DELETED
@@ -1 +0,0 @@
1
- 2.0.0
 
 
api/router.go DELETED
@@ -1,18 +0,0 @@
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 DELETED
@@ -1,41 +0,0 @@
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/common.go ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package common
2
+
3
+ import (
4
+ "bytes"
5
+ "encoding/json"
6
+ "fmt"
7
+ fhttp "github.com/bogdanfinn/fhttp"
8
+ "github.com/bogdanfinn/fhttp/httputil"
9
+ "github.com/gin-gonic/gin"
10
+ jsoniter "github.com/json-iterator/go"
11
+ "math/rand"
12
+ "net/url"
13
+ "os"
14
+ "path/filepath"
15
+ "reflect"
16
+ "strings"
17
+ "time"
18
+ )
19
+
20
+ func ErrorResponse(c *gin.Context, code int, msg interface{}, err interface{}) {
21
+ c.AbortWithStatusJSON(code, gin.H{
22
+ "detail": struct {
23
+ Code int `json:"code"`
24
+ Msg interface{} `json:"msg"`
25
+ Error interface{} `json:"error"`
26
+ }{
27
+ Code: code,
28
+ Msg: msg,
29
+ Error: err,
30
+ },
31
+ })
32
+ return
33
+ }
34
+
35
+ // GetTimestampSecond 获取当前时间戳 + 指定 秒
36
+ func GetTimestampSecond(second int) int64 {
37
+ return time.Now().Add(time.Second * time.Duration(second)).Unix()
38
+ }
39
+
40
+ func ParseUrl(link string) *url.URL {
41
+ if link == "" {
42
+ return &url.URL{}
43
+ }
44
+ u, err := url.Parse(link)
45
+ if err != nil {
46
+ return &url.URL{}
47
+ }
48
+ return u
49
+ }
50
+
51
+ func GetOrigin(link string) string {
52
+ u := ParseUrl(link)
53
+ if u == nil {
54
+ return ""
55
+ }
56
+ return u.Scheme + "://" + u.Host
57
+ }
58
+
59
+ func Struct2BytesBuffer(v interface{}) (*bytes.Buffer, error) {
60
+ data := new(bytes.Buffer)
61
+ err := json.NewEncoder(data).Encode(v)
62
+ if err != nil {
63
+ return nil, err
64
+ }
65
+ return data, nil
66
+ }
67
+
68
+ func Struct2Bytes(v interface{}) ([]byte, error) {
69
+ // 创建一个jsonIter的Encoder
70
+ configCompatibleWithStandardLibrary := jsoniter.ConfigCompatibleWithStandardLibrary
71
+ // 将结构体转换为JSON文本并保持顺序
72
+ bytes_, err := configCompatibleWithStandardLibrary.Marshal(v)
73
+ if err != nil {
74
+ return nil, err
75
+ }
76
+ return bytes_, nil
77
+ }
78
+
79
+ func SplitAndAddBearer(authTokens string) []string {
80
+ var authTokenList []string
81
+ for _, v := range strings.Split(authTokens, ",") {
82
+ authTokenList = append(authTokenList, "Bearer "+v)
83
+ }
84
+ return authTokenList
85
+ }
86
+
87
+ func GetRand() rand.Rand {
88
+ // 初始化随机数生成器
89
+ seed := time.Now().UnixNano()
90
+ rng := rand.New(rand.NewSource(seed))
91
+ return *rng
92
+ }
93
+
94
+ func RandomLanguage() string {
95
+ // 初始化随机数生成器
96
+ rng := GetRand()
97
+ // 语言列表
98
+ 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"}
99
+ // 随机选择一个语言
100
+ randomIndex := rng.Intn(len(languages))
101
+ return languages[randomIndex]
102
+ }
103
+
104
+ // GetAbsPathAndGenerate 获取绝对路径并生成文件或文件夹
105
+ func GetAbsPathAndGenerate(path string, isFilePath bool, content string) string {
106
+ // 获取绝对路径
107
+ path = GetAbsPath(path)
108
+ if isFilePath {
109
+ // 判断文件是否存在
110
+ if isExist := fileIsExistAndCreat(path, content); isExist {
111
+ return path
112
+ }
113
+ } else {
114
+ // 判断文件夹是否存在
115
+ if isExist := dirIsExistAndMkdir(path, false); isExist {
116
+ return path
117
+ }
118
+ }
119
+ return path
120
+ }
121
+
122
+ // GetAbsPath 获取绝对路径
123
+ func GetAbsPath(path string) string {
124
+ if !filepath.IsAbs(path) {
125
+ absPath, err := filepath.Abs(path)
126
+ if err != nil {
127
+ return ""
128
+ }
129
+ return absPath
130
+ }
131
+ return path
132
+ }
133
+
134
+ func dirIsExistAndMkdir(dirPath string, isFile bool) bool {
135
+ // 判断路径是否存在
136
+ _, err := os.Stat(dirPath)
137
+ dir := dirPath
138
+ if err != nil {
139
+ if isFile {
140
+ dir = filepath.Dir(dirPath)
141
+ }
142
+ // 创建路径
143
+ err := os.MkdirAll(dir, os.ModePerm)
144
+ if err != nil {
145
+ return false
146
+ }
147
+ }
148
+ return true
149
+ }
150
+
151
+ func fileIsExistAndCreat(filePath string, content string) bool {
152
+ //判断文件是否存在
153
+ _, err := os.Stat(filePath)
154
+ if err != nil {
155
+ // 判断文件夹是否存在
156
+ if isExist := dirIsExistAndMkdir(filePath, true); !isExist {
157
+ return false
158
+ }
159
+ // 创建文件
160
+ _, err := os.Create(filePath)
161
+ if err != nil {
162
+ return false
163
+ }
164
+ if content != "" {
165
+ // 写入content
166
+ file, _ := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0777)
167
+ _, _ = file.Write([]byte(content))
168
+ defer func(file *os.File) {
169
+ _ = file.Close()
170
+ }(file)
171
+ }
172
+ }
173
+ return true
174
+ }
175
+
176
+ // AsyncTimingTask 定时任务 参数含函数
177
+ func AsyncTimingTask(nanosecond time.Duration, fun func()) {
178
+ go func() {
179
+ timerChan := time.After(nanosecond)
180
+ // 使用for循环阻塞等待定时器的信号
181
+ for {
182
+ // 通过select语句监听定时器通道和其他事件
183
+ select {
184
+ case <-timerChan:
185
+ fun()
186
+ // 重新设置定时器,以便下一次执行
187
+ timerChan = time.After(nanosecond)
188
+ }
189
+ time.Sleep(time.Millisecond * 100)
190
+ }
191
+ }()
192
+ }
193
+
194
+ // AsyncLoopTask AsyncTimingTask 定时任务 参数含函数
195
+ func AsyncLoopTask(sleep time.Duration, fun func()) {
196
+ go func() {
197
+ for {
198
+ fun()
199
+ time.Sleep(sleep)
200
+ }
201
+ }()
202
+ }
203
+
204
+ // DeepCopyStruct 深拷贝函数
205
+ func DeepCopyStruct(src interface{}) interface{} {
206
+ // 获取源对象的类型信息
207
+ srcType := reflect.TypeOf(src)
208
+ // 创建目标对象
209
+ dst := reflect.New(srcType).Elem()
210
+
211
+ // 深拷贝过程
212
+ deepCopyValue(reflect.ValueOf(src), dst)
213
+
214
+ return dst.Interface()
215
+ }
216
+
217
+ // 递归进行深拷贝
218
+ func deepCopyValue(src, dst reflect.Value) {
219
+ switch src.Kind() {
220
+ case reflect.Ptr:
221
+ if src.IsNil() {
222
+ dst.Set(src)
223
+ return
224
+ }
225
+ // 递归处理指针指向的内容
226
+ newDst := reflect.New(src.Elem().Type())
227
+ deepCopyValue(src.Elem(), newDst.Elem())
228
+ dst.Set(newDst)
229
+ case reflect.Struct:
230
+ for i := 0; i < src.NumField(); i++ {
231
+ // 递归处理结构体的字段
232
+ deepCopyValue(src.Field(i), dst.Field(i))
233
+ }
234
+ default:
235
+ // 检查目标值是否支持设置
236
+ if dst.CanSet() {
237
+ // 处理基本类型和数组、切片、映射等
238
+ dst.Set(src)
239
+ }
240
+ }
241
+ }
242
+
243
+ func RandomHexadecimalString() string {
244
+ rng := GetRand()
245
+ const charset = "0123456789abcdef"
246
+ const length = 16 // The length of the string you want to generate
247
+ b := make([]byte, length)
248
+ for i := range b {
249
+ b[i] = charset[rng.Intn(len(charset))]
250
+ }
251
+ return string(b)
252
+ }
253
+
254
+ // OutRequest 打印请求.
255
+ func OutRequest(req *fhttp.Request) {
256
+ dump, err := httputil.DumpRequestOut(req, true)
257
+ if err != nil {
258
+ fmt.Println("Error dumping request:", err)
259
+ } else {
260
+ fmt.Println(string(dump))
261
+ }
262
+ }
263
+
264
+ // OutResponse 打印响应.
265
+ func OutResponse(res *fhttp.Response) {
266
+ dump, err := httputil.DumpResponse(res, true)
267
+ if err != nil {
268
+ fmt.Println("Error dumping response:", err)
269
+ } else {
270
+ fmt.Println(string(dump))
271
+ }
272
+ }
273
+
274
+ func IsStrInArray(str string, strS []string) bool {
275
+ // 如果 strS 为空,直接返回 true
276
+ if len(strS) == 0 {
277
+ return true
278
+ }
279
+ for _, v := range strS {
280
+ if v == str {
281
+ return true
282
+ }
283
+ }
284
+ return false
285
+ }
config/config.go ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package config
2
+
3
+ import (
4
+ "free-gpt3.5-2api/common"
5
+ "github.com/joho/godotenv"
6
+ "os"
7
+ "strconv"
8
+ "strings"
9
+ )
10
+
11
+ var (
12
+ Bind string
13
+ Port string
14
+ Proxy []string
15
+ AUTHORIZATIONS []string
16
+ BaseUrl string
17
+ PoolMaxCount int
18
+ AuthED int
19
+ )
20
+
21
+ func init() {
22
+ _ = godotenv.Load()
23
+ // Bind
24
+ Bind = os.Getenv("BIND")
25
+ if Bind == "" {
26
+ Bind = "0.0.0.0"
27
+ }
28
+ // PORT
29
+ Port = os.Getenv("PORT")
30
+ if Port == "" {
31
+ Port = "3040"
32
+ }
33
+ // PROXY
34
+ proxy := os.Getenv("PROXY")
35
+ if proxy != "" {
36
+ Proxy = strings.Split(proxy, ",")
37
+ }
38
+ // AUTH_TOKEN
39
+ authorizations := os.Getenv("AUTHORIZATIONS")
40
+ if authorizations == "" {
41
+ AUTHORIZATIONS = []string{}
42
+ } else {
43
+ //以,分割 AUTH_TOKEN 并且为每个AUTH_TOKEN前面加上Bearer
44
+ AUTHORIZATIONS = common.SplitAndAddBearer(authorizations)
45
+ }
46
+ // BASE_URL
47
+ BaseUrl = os.Getenv("BASE_URL")
48
+ if BaseUrl == "" {
49
+ BaseUrl = "https://chatgpt.com"
50
+ } else {
51
+ BaseUrl = strings.TrimRight(BaseUrl, "/")
52
+ }
53
+ // POOL_MAX_COUNT
54
+ poolMaxCount := os.Getenv("POOL_MAX_COUNT")
55
+ var err error
56
+ if poolMaxCount == "" {
57
+ PoolMaxCount = 64
58
+ } else {
59
+ PoolMaxCount, err = strconv.Atoi(poolMaxCount)
60
+ if err != nil {
61
+ PoolMaxCount = 64
62
+ }
63
+ }
64
+ // AUTH_ED
65
+ authED := os.Getenv("AUTH_ED")
66
+ if authED == "" {
67
+ AuthED = 600
68
+ } else {
69
+ AuthED, err = strconv.Atoi(authED)
70
+ if err != nil {
71
+ AuthED = 600
72
+ }
73
+ }
74
+ }
constant/constant.go ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package constant
2
+
3
+ import "github.com/bogdanfinn/tls-client/profiles"
4
+
5
+ var (
6
+ ClientProfile = profiles.Safari_15_6_1
7
+ )
8
+
9
+ const (
10
+ Ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
11
+ )
conversion/requests/duckgo/convert.go DELETED
@@ -1,30 +0,0 @@
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
- // 默认模型3.5
11
- duckgo_request := duckgotypes.NewApiRequest("gpt-3.5-turbo-0125")
12
- // 检查并更新模型为 claude- 开头的情况
13
- if strings.HasPrefix(strings.ToLower(api_request.Model), "claude") {
14
- duckgo_request.Model = "claude-3-haiku-20240307"
15
- }
16
- content := buildContent(&api_request)
17
- duckgo_request.AddMessage("user", content)
18
- return duckgo_request
19
- }
20
-
21
- func buildContent(api_request *officialtypes.APIRequest) string {
22
- var content strings.Builder
23
- for _, apiMessage := range api_request.Messages {
24
- role := apiMessage.Role
25
- if role == "user" || role == "system" || role == "assistant" {
26
- content.WriteString(role + ":" + apiMessage.Content + ";\r\n")
27
- }
28
- }
29
- return content.String()
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docker-compose.yml DELETED
@@ -1,9 +0,0 @@
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
- - '8080:8080'
 
 
 
 
 
 
 
 
 
 
env.template CHANGED
@@ -1,8 +1,8 @@
1
- SERVER_HOST=0.0.0.0
2
- SERVER_PORT=8080
3
- FREE_ACCOUNTS=true
4
- FREE_ACCOUNTS_NUM=1024
5
- Authorization=
6
- TLS_CERT=
7
- TLS_KEY=
8
- PROXY_URL=
 
1
+ LOG_LEVEL=info # debug, info, warn, error
2
+ BIND=127.0.0.1 #
3
+ PORT=8080
4
+ PROXY=
5
+ AUTHORIZATIONS=
6
+ POOL_MAX_COUNT=5 # max number of connections to keep in the pool
7
+ AUTH_ED=180 # expiration time for the authorization in seconds
8
+ AUTH_USE_COUNT=5 # number of times an authorization can be used
go.mod CHANGED
@@ -1,56 +1,50 @@
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.27
9
  github.com/bogdanfinn/tls-client v1.7.2
10
  github.com/gin-gonic/gin v1.9.1
11
- github.com/go-resty/resty/v2 v2.12.0
12
  github.com/google/uuid v1.6.0
13
- github.com/gorilla/websocket v1.5.1
14
  github.com/joho/godotenv v1.5.1
15
- github.com/pkoukk/tiktoken-go v0.1.6
16
- github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c
 
17
  )
18
 
19
  require (
20
- github.com/PuerkitoBio/goquery v1.9.1 // indirect
21
  github.com/andybalholm/brotli v1.0.5 // indirect
22
- github.com/andybalholm/cascadia v1.3.2 // indirect
23
  github.com/bogdanfinn/utls v1.6.1 // indirect
24
- github.com/bytedance/sonic v1.10.1 // indirect
25
- github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
26
- github.com/chenzhuoyu/iasm v0.9.0 // indirect
27
- github.com/cloudflare/circl v1.3.6 // indirect
28
- github.com/dlclark/regexp2 v1.10.0 // indirect
29
  github.com/gabriel-vasile/mimetype v1.4.2 // indirect
30
  github.com/gin-contrib/sse v0.1.0 // indirect
31
  github.com/go-playground/locales v0.14.1 // indirect
32
  github.com/go-playground/universal-translator v0.18.1 // indirect
33
- github.com/go-playground/validator/v10 v10.15.4 // indirect
34
  github.com/goccy/go-json v0.10.2 // indirect
35
- github.com/json-iterator/go v1.1.12 // indirect
36
- github.com/klauspost/compress v1.17.0 // indirect
37
- github.com/klauspost/cpuid/v2 v2.2.5 // indirect
38
- github.com/kr/text v0.2.0 // indirect
39
  github.com/leodido/go-urn v1.2.4 // indirect
40
  github.com/mattn/go-isatty v0.0.19 // indirect
41
  github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
42
  github.com/modern-go/reflect2 v1.0.2 // indirect
43
- github.com/pelletier/go-toml/v2 v2.1.0 // indirect
44
- github.com/quic-go/quic-go v0.37.4 // indirect
45
  github.com/rogpeppe/go-internal v1.12.0 // indirect
46
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect
47
  github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
48
  github.com/ugorji/go/codec v1.2.11 // indirect
49
- golang.org/x/arch v0.5.0 // indirect
50
- golang.org/x/crypto v0.21.0 // indirect
 
 
51
  golang.org/x/net v0.22.0 // indirect
52
  golang.org/x/sys v0.18.0 // indirect
53
  golang.org/x/text v0.14.0 // indirect
54
- google.golang.org/protobuf v1.31.0 // indirect
55
  gopkg.in/yaml.v3 v3.0.1 // indirect
56
  )
 
1
+ module free-gpt3.5-2api
2
 
3
  go 1.21
4
 
5
  require (
6
+ github.com/aurorax-neo/go-logger v0.0.0-20240421094709-1eb4bda786d5
7
+ github.com/bogdanfinn/fhttp v0.5.28
 
8
  github.com/bogdanfinn/tls-client v1.7.2
9
  github.com/gin-gonic/gin v1.9.1
 
10
  github.com/google/uuid v1.6.0
 
11
  github.com/joho/godotenv v1.5.1
12
+ github.com/json-iterator/go v1.1.12
13
+ github.com/launchdarkly/eventsource v1.7.1
14
+ golang.org/x/crypto v0.21.0
15
  )
16
 
17
  require (
 
18
  github.com/andybalholm/brotli v1.0.5 // indirect
 
19
  github.com/bogdanfinn/utls v1.6.1 // indirect
20
+ github.com/bytedance/sonic v1.9.1 // indirect
21
+ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
22
+ github.com/cloudflare/circl v1.3.7 // indirect
 
 
23
  github.com/gabriel-vasile/mimetype v1.4.2 // indirect
24
  github.com/gin-contrib/sse v0.1.0 // indirect
25
  github.com/go-playground/locales v0.14.1 // indirect
26
  github.com/go-playground/universal-translator v0.18.1 // indirect
27
+ github.com/go-playground/validator/v10 v10.14.0 // indirect
28
  github.com/goccy/go-json v0.10.2 // indirect
29
+ github.com/klauspost/compress v1.16.7 // indirect
30
+ github.com/klauspost/cpuid/v2 v2.2.4 // indirect
 
 
31
  github.com/leodido/go-urn v1.2.4 // indirect
32
  github.com/mattn/go-isatty v0.0.19 // indirect
33
  github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
34
  github.com/modern-go/reflect2 v1.0.2 // indirect
35
+ github.com/pelletier/go-toml/v2 v2.0.8 // indirect
36
+ github.com/quic-go/quic-go v0.42.0 // indirect
37
  github.com/rogpeppe/go-internal v1.12.0 // indirect
38
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect
39
  github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
40
  github.com/ugorji/go/codec v1.2.11 // indirect
41
+ go.uber.org/multierr v1.11.0 // indirect
42
+ go.uber.org/zap v1.27.0 // indirect
43
+ golang.org/x/arch v0.3.0 // indirect
44
+ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
45
  golang.org/x/net v0.22.0 // indirect
46
  golang.org/x/sys v0.18.0 // indirect
47
  golang.org/x/text v0.14.0 // indirect
48
+ google.golang.org/protobuf v1.33.0 // indirect
49
  gopkg.in/yaml.v3 v3.0.1 // indirect
50
  )
go.sum CHANGED
@@ -1,37 +1,24 @@
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.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
4
- github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
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.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
8
  github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
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.27 h1:+glR3k8v5nxfUSk7+J3M246zEQ2yadhS0vLq1utK71A=
12
- github.com/bogdanfinn/fhttp v0.5.27/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.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
18
- github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
19
- github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
20
- github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
21
  github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
 
22
  github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
23
- github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
24
- github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
25
- github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
26
- github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
27
- github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
28
- github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
29
- github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
30
  github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
31
  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
32
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
- github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
34
- github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
35
  github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
36
  github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
37
  github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
@@ -46,16 +33,12 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
46
  github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
47
  github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
48
  github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
49
- github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs=
50
- github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
51
- github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA=
52
- github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0=
53
  github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
54
  github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
55
  github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
56
  github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
57
- github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
58
- github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
59
  github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
60
  github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
61
  github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -63,22 +46,23 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE
63
  github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
64
  github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
65
  github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
66
- github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
67
- github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
68
  github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
69
  github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
70
  github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
71
  github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
72
- github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
73
- github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
74
  github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
75
- github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
76
- github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
77
- github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
78
  github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
79
  github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
80
  github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
81
  github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 
 
 
 
82
  github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
83
  github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
84
  github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
@@ -92,102 +76,64 @@ github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
92
  github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
93
  github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
94
  github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
95
- github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
96
- github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
97
- github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
98
- github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
99
  github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
100
  github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
101
- github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
102
- github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
103
  github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
104
  github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
105
  github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
106
  github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
107
  github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
108
  github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 
 
109
  github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
110
  github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
111
  github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
112
  github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
113
  github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
114
- github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
115
- github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
116
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc=
117
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng=
118
  github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
119
  github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
120
  github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
121
  github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
122
- github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c h1:nj17XsSTwprsZUDXLldOUZmqz7VlHsLCeXXFOE6Q+Mk=
123
- github.com/xqdoo00o/funcaptcha v0.0.0-20240403090732-1b604d808f6c/go.mod h1:7aCyoW5MHDUsoooMVLqKe0F7W9HMPUvDG3bXqw++8XA=
124
- github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 
 
 
125
  golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
126
- golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y=
127
- golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
128
- golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
129
- golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
130
- golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
131
  golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
132
  golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
133
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
134
- golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
135
- golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
136
- golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
137
- golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
138
- golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
139
- golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
140
- golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
141
- golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
142
  golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
143
  golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
144
- golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
145
- golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
146
- golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
147
- golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
148
- golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
149
- golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
150
- golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
151
- golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
152
- golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
153
  golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
154
- golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
155
- golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
156
- golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
157
  golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
158
  golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
159
- golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
160
- golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
161
- golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
162
- golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
163
- golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
164
- golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
165
- golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
166
- golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
167
- golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
168
- golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
169
- golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
170
- golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
171
  golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
172
  golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
173
- golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
174
- golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
175
- golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
176
- golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
177
- golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
178
- golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
179
  golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
180
  golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
181
- golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
182
- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
183
- google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
184
- google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
185
- google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
186
  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
187
  gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
188
  gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 
 
189
  gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
190
  gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
191
  gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
192
- nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
193
  rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 
 
 
 
 
 
 
1
  github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
2
  github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
3
+ github.com/aurorax-neo/go-logger v0.0.0-20240421094709-1eb4bda786d5 h1:L1ei0BPLvE/ld4KAh4bKVAn5tDYOdJz0SuxlbuzfKzQ=
4
+ github.com/aurorax-neo/go-logger v0.0.0-20240421094709-1eb4bda786d5/go.mod h1:BJsRG1ECcXTHwiz2zaMYxFkeXh+MpQVs6nWYphLT244=
5
+ github.com/bogdanfinn/fhttp v0.5.28 h1:G6thT8s8v6z1IuvXMUsX9QKy3ZHseTQTzxuIhSiaaAw=
6
+ github.com/bogdanfinn/fhttp v0.5.28/go.mod h1:oJiYPG3jQTKzk/VFmogH8jxjH5yiv2rrOH48Xso2lrE=
7
  github.com/bogdanfinn/tls-client v1.7.2 h1:vpL5qBYUfT9ueygEf1yLfymrXyUEZQatL25amfqGV8M=
8
  github.com/bogdanfinn/tls-client v1.7.2/go.mod h1:pOGa2euqTbEkGNqE5idx5jKKfs9ytlyn3fwEw8RSP+g=
9
  github.com/bogdanfinn/utls v1.6.1 h1:dKDYAcXEyFFJ3GaWaN89DEyjyRraD1qb4osdEK89ass=
10
  github.com/bogdanfinn/utls v1.6.1/go.mod h1:VXIbRZaiY/wHZc6Hu+DZ4O2CgTzjhjCg/Ou3V4r/39Y=
11
  github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
12
+ github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
13
+ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
 
14
  github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
15
+ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
16
  github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
17
+ github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
18
+ github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
 
 
 
 
 
19
  github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
20
  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
21
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 
 
22
  github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
23
  github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
24
  github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 
33
  github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
34
  github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
35
  github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
36
+ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
37
+ github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 
 
38
  github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
39
  github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
40
  github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
41
  github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 
 
42
  github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
43
  github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
44
  github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 
46
  github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
47
  github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
48
  github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 
 
49
  github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
50
  github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
51
  github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
52
  github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
53
+ github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
54
+ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
55
  github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
56
+ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
57
+ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
 
58
  github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
59
  github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
60
  github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
61
  github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
62
+ github.com/launchdarkly/eventsource v1.7.1 h1:StoRQeiPyrcQIXjlQ7b5jWMzHW4p+GGczN2r2oBhujg=
63
+ github.com/launchdarkly/eventsource v1.7.1/go.mod h1:LHxSeb4OnqznNZxCSXbFghxS/CjIQfzHovNoAqbO/Wk=
64
+ github.com/launchdarkly/go-test-helpers/v2 v2.2.0 h1:L3kGILP/6ewikhzhdNkHy1b5y4zs50LueWenVF0sBbs=
65
+ github.com/launchdarkly/go-test-helpers/v2 v2.2.0/go.mod h1:L7+th5govYp5oKU9iN7To5PgznBuIjBPn+ejqKR0avw=
66
  github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
67
  github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
68
  github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 
76
  github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
77
  github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
78
  github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
79
+ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
80
+ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 
 
81
  github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
82
  github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
83
+ github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
84
+ github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
85
  github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
86
  github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
87
  github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
88
  github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
89
  github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
90
  github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
91
+ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
92
+ github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
93
  github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
94
  github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
95
  github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
96
  github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
97
  github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
98
+ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
99
+ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
100
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc=
101
  github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng=
102
  github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
103
  github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
104
  github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
105
  github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
106
+ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
107
+ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
108
+ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
109
+ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
110
+ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
111
+ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
112
  golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
113
+ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
114
+ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 
 
 
115
  golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
116
  golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
117
+ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
118
+ golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
 
 
 
 
 
 
 
119
  golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
120
  golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
121
+ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 
 
 
 
 
 
 
 
122
  golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 
 
 
123
  golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
124
  golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 
 
 
 
 
 
 
 
 
 
 
 
125
  golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
126
  golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 
 
 
 
 
 
127
  golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
128
  golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
129
+ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
130
+ google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 
 
 
131
  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
132
  gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
133
  gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
134
+ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
135
+ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
136
  gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
137
  gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
138
  gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 
139
  rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
httpclient/Iaurorahttpclient.go DELETED
@@ -1,28 +0,0 @@
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 DELETED
@@ -1,101 +0,0 @@
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.WithTimeoutSeconds(600),
24
- tls_client.WithClientProfile(profiles.Safari_15_6_1),
25
- }...)
26
-
27
- stdClient := &TlsClient{Client: client}
28
- return stdClient
29
- }
30
-
31
- func convertResponse(resp *fhttp.Response) *http.Response {
32
- response := &http.Response{
33
- Status: resp.Status,
34
- StatusCode: resp.StatusCode,
35
- Proto: resp.Proto,
36
- ProtoMajor: resp.ProtoMajor,
37
- ProtoMinor: resp.ProtoMinor,
38
- Header: http.Header(resp.Header),
39
- Body: resp.Body,
40
- ContentLength: resp.ContentLength,
41
- TransferEncoding: resp.TransferEncoding,
42
- Close: resp.Close,
43
- Uncompressed: resp.Uncompressed,
44
- Trailer: http.Header(resp.Trailer),
45
- }
46
- return response
47
- }
48
-
49
- func (t *TlsClient) handleHeaders(req *fhttp.Request, headers httpclient.AuroraHeaders) {
50
- if headers == nil {
51
- return
52
- }
53
- for k, v := range headers {
54
- req.Header.Set(k, v)
55
- }
56
- }
57
-
58
- func (t *TlsClient) handleCookies(req *fhttp.Request, cookies []*http.Cookie) {
59
- if cookies == nil {
60
- return
61
- }
62
- for _, c := range cookies {
63
- req.AddCookie(&fhttp.Cookie{
64
- Name: c.Name,
65
- Value: c.Value,
66
- Path: c.Path,
67
- Domain: c.Domain,
68
- Expires: c.Expires,
69
- RawExpires: c.RawExpires,
70
- MaxAge: c.MaxAge,
71
- Secure: c.Secure,
72
- HttpOnly: c.HttpOnly,
73
- SameSite: fhttp.SameSite(c.SameSite),
74
- Raw: c.Raw,
75
- Unparsed: c.Unparsed,
76
- })
77
- }
78
- }
79
-
80
- func (t *TlsClient) Request(method httpclient.HttpMethod, url string, headers httpclient.AuroraHeaders, cookies []*http.Cookie, body io.Reader) (*http.Response, error) {
81
- req, err := fhttp.NewRequest(string(method), url, body)
82
- if err != nil {
83
- return nil, err
84
- }
85
- t.handleHeaders(req, headers)
86
- t.handleCookies(req, cookies)
87
- if t.ReqBefore != nil {
88
- if err := t.ReqBefore(req); err != nil {
89
- return nil, err
90
- }
91
- }
92
- do, err := t.Client.Do(req)
93
- if err != nil {
94
- return nil, err
95
- }
96
- return convertResponse(do), nil
97
- }
98
-
99
- func (t *TlsClient) SetProxy(url string) error {
100
- return t.Client.SetProxy(url)
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
httpclient/bogdanfinn/tls_client_test.go DELETED
@@ -1,101 +0,0 @@
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 DELETED
@@ -1,72 +0,0 @@
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 DELETED
@@ -1,110 +0,0 @@
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
- resModelList = append(resModelList, ResData{
97
- ID: "gpt-3.5-turbo-0125",
98
- Object: "model",
99
- Created: 1685474247,
100
- OwnedBy: "duckgo",
101
- })
102
- resModelList = append(resModelList, ResData{
103
- ID: "claude-3-haiku-20240307",
104
- Object: "model",
105
- Created: 1685474247,
106
- OwnedBy: "duckgo",
107
- })
108
- modelS.Data = resModelList
109
- c.JSON(200, modelS)
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
initialize/proxy.go DELETED
@@ -1,48 +0,0 @@
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 DELETED
@@ -1,35 +0,0 @@
1
- package initialize
2
-
3
- import (
4
- "aurora/middlewares"
5
-
6
- "github.com/gin-gonic/gin"
7
- )
8
-
9
- func RegisterRouter() *gin.Engine {
10
- handler := NewHandle(
11
- checkProxy(),
12
- )
13
-
14
- router := gin.Default()
15
- router.Use(middlewares.Cors)
16
-
17
- router.GET("/", func(c *gin.Context) {
18
- c.JSON(200, gin.H{
19
- "message": "Hello, world!",
20
- })
21
- })
22
-
23
- router.GET("/ping", func(c *gin.Context) {
24
- c.JSON(200, gin.H{
25
- "message": "pong",
26
- })
27
- })
28
-
29
- router.OPTIONS("/v1/chat/completions", optionsHandler)
30
- router.OPTIONS("/v1/chat/models", optionsHandler)
31
- authGroup := router.Group("").Use(middlewares.Authorization)
32
- authGroup.POST("/v1/chat/completions", handler.duckduckgo)
33
- authGroup.GET("/v1/models", handler.engines)
34
- return router
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
internal/duckgo/request.go DELETED
@@ -1,188 +0,0 @@
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
- "github.com/gin-gonic/gin"
12
- "io"
13
- "net/http"
14
- "strings"
15
- "sync"
16
- "time"
17
- )
18
-
19
- var (
20
- Token *XqdgToken
21
- UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
22
- )
23
-
24
- type XqdgToken struct {
25
- Token string `json:"token"`
26
- M sync.Mutex `json:"-"`
27
- ExpireAt time.Time `json:"expire"`
28
- }
29
-
30
- func InitXVQD(client httpclient.AuroraHttpClient, proxyUrl string) (string, error) {
31
- if Token == nil {
32
- Token = &XqdgToken{
33
- Token: "",
34
- M: sync.Mutex{},
35
- }
36
- }
37
- Token.M.Lock()
38
- defer Token.M.Unlock()
39
- if Token.Token == "" || Token.ExpireAt.Before(time.Now()) {
40
- status, err := postStatus(client, proxyUrl)
41
- if err != nil {
42
- return "", err
43
- }
44
- defer status.Body.Close()
45
- token := status.Header.Get("x-vqd-4")
46
- if token == "" {
47
- return "", errors.New("no x-vqd-4 token")
48
- }
49
- Token.Token = token
50
- Token.ExpireAt = time.Now().Add(time.Minute * 5)
51
- }
52
-
53
- return Token.Token, nil
54
- }
55
-
56
- func postStatus(client httpclient.AuroraHttpClient, proxyUrl string) (*http.Response, error) {
57
- if proxyUrl != "" {
58
- client.SetProxy(proxyUrl)
59
- }
60
- header := createHeader()
61
- header.Set("accept", "*/*")
62
- header.Set("x-vqd-accept", "1")
63
- response, err := client.Request(httpclient.GET, "https://duckduckgo.com/duckchat/v1/status", header, nil, nil)
64
- if err != nil {
65
- return nil, err
66
- }
67
- return response, nil
68
- }
69
-
70
- func POSTconversation(client httpclient.AuroraHttpClient, request duckgotypes.ApiRequest, token string, proxyUrl string) (*http.Response, error) {
71
- if proxyUrl != "" {
72
- client.SetProxy(proxyUrl)
73
- }
74
- body_json, err := json.Marshal(request)
75
- if err != nil {
76
- return &http.Response{}, err
77
- }
78
- header := createHeader()
79
- header.Set("accept", "text/event-stream")
80
- header.Set("x-vqd-4", token)
81
- response, err := client.Request(httpclient.POST, "https://duckduckgo.com/duckchat/v1/chat", header, nil, bytes.NewBuffer(body_json))
82
- if err != nil {
83
- return nil, err
84
- }
85
- return response, nil
86
- }
87
-
88
- func Handle_request_error(c *gin.Context, response *http.Response) bool {
89
- if response.StatusCode != 200 {
90
- // Try read response body as JSON
91
- var error_response map[string]interface{}
92
- err := json.NewDecoder(response.Body).Decode(&error_response)
93
- if err != nil {
94
- // Read response body
95
- body, _ := io.ReadAll(response.Body)
96
- c.JSON(response.StatusCode, gin.H{"error": gin.H{
97
- "message": "Unknown error",
98
- "type": "internal_server_error",
99
- "param": nil,
100
- "code": "500",
101
- "details": string(body),
102
- }})
103
- return true
104
- }
105
- c.JSON(response.StatusCode, gin.H{"error": gin.H{
106
- "message": error_response["detail"],
107
- "type": response.Status,
108
- "param": nil,
109
- "code": "error",
110
- }})
111
- return true
112
- }
113
- return false
114
- }
115
-
116
- func createHeader() httpclient.AuroraHeaders {
117
- header := make(httpclient.AuroraHeaders)
118
- header.Set("accept-language", "zh-CN,zh;q=0.9")
119
- header.Set("content-type", "application/json")
120
- header.Set("origin", "https://duckduckgo.com")
121
- header.Set("referer", "https://duckduckgo.com/")
122
- header.Set("sec-ch-ua", `"Chromium";v="120", "Google Chrome";v="120", "Not-A.Brand";v="99"`)
123
- header.Set("sec-ch-ua-mobile", "?0")
124
- header.Set("sec-ch-ua-platform", `"Windows"`)
125
- header.Set("user-agent", UA)
126
- return header
127
- }
128
-
129
- func Handler(c *gin.Context, response *http.Response, oldRequest duckgotypes.ApiRequest, stream bool) string {
130
- reader := bufio.NewReader(response.Body)
131
- if stream {
132
- // Response content type is text/event-stream
133
- c.Header("Content-Type", "text/event-stream")
134
- } else {
135
- // Response content type is application/json
136
- c.Header("Content-Type", "application/json")
137
- }
138
-
139
- var previousText strings.Builder
140
- for {
141
- line, err := reader.ReadString('\n')
142
- if err != nil {
143
- if err == io.EOF {
144
- break
145
- }
146
- return ""
147
- }
148
- if len(line) < 6 {
149
- continue
150
- }
151
- line = line[6:]
152
- if !strings.HasPrefix(line, "[DONE]") {
153
- var originalResponse duckgotypes.ApiResponse
154
- err = json.Unmarshal([]byte(line), &originalResponse)
155
- if err != nil {
156
- continue
157
- }
158
- if originalResponse.Action != "success" {
159
- c.JSON(500, gin.H{"error": "Error"})
160
- return ""
161
- }
162
- responseString := ""
163
- if originalResponse.Message != "" {
164
- previousText.WriteString(originalResponse.Message)
165
- translatedResponse := officialtypes.NewChatCompletionChunkWithModel(originalResponse.Message, originalResponse.Model)
166
- responseString = "data: " + translatedResponse.String() + "\n\n"
167
- }
168
-
169
- if responseString == "" {
170
- continue
171
- }
172
-
173
- if stream {
174
- _, err = c.Writer.WriteString(responseString)
175
- if err != nil {
176
- return ""
177
- }
178
- c.Writer.Flush()
179
- }
180
- } else {
181
- if stream {
182
- final_line := officialtypes.StopChunkWithModel("stop", oldRequest.Model)
183
- c.Writer.WriteString("data: " + final_line.String() + "\n\n")
184
- }
185
- }
186
- }
187
- return previousText.String()
188
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
internal/proxys/proxys.go DELETED
@@ -1,35 +0,0 @@
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 CHANGED
@@ -1,50 +1,35 @@
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
  gin.SetMode(gin.ReleaseMode)
22
- router := initialize.RegisterRouter()
23
- subFS, err := fs.Sub(staticFiles, "web")
24
- if err != nil {
25
- log.Fatal(err)
26
- }
27
- router.StaticFS("/web", http.FS(subFS))
28
-
29
- _ = godotenv.Load(".env")
30
- host := os.Getenv("SERVER_HOST")
31
- port := os.Getenv("SERVER_PORT")
32
- tlsCert := os.Getenv("TLS_CERT")
33
- tlsKey := os.Getenv("TLS_KEY")
34
-
35
- if host == "" {
36
- host = "0.0.0.0"
37
- }
38
- if port == "" {
39
- port = os.Getenv("PORT")
40
- if port == "" {
41
- port = "8080"
42
- }
43
- }
44
-
45
- if tlsCert != "" && tlsKey != "" {
46
- _ = endless.ListenAndServeTLS(host+":"+port, tlsCert, tlsKey, router)
47
- } else {
48
- _ = endless.ListenAndServe(host+":"+port, router)
49
  }
 
 
 
50
  }
 
1
  package main
2
 
3
  import (
4
+ "fmt"
5
+ "free-gpt3.5-2api/FreeGpt35Pool"
6
+ "free-gpt3.5-2api/ProxyPool"
7
+ "free-gpt3.5-2api/config"
8
+ "free-gpt3.5-2api/router"
9
+ "github.com/aurorax-neo/go-logger"
 
10
  "github.com/gin-gonic/gin"
 
 
 
11
  )
12
 
13
+ func Init() {
14
+ ProxyPool.GetProxyPoolInstance()
15
+ FreeGpt35Pool.GetFreeGpt35PoolInstance()
16
+ }
17
 
18
  func main() {
19
+ // Init
20
+ Init()
21
+ // Initialize HTTP server
22
  gin.SetMode(gin.ReleaseMode)
23
+ server := gin.New()
24
+ server.Use(gin.Recovery())
25
+ // 设置路由
26
+ router.SetRouter(server)
27
+ // 提示服务启动
28
+ host := config.Bind
29
+ if config.Bind == "0.0.0.0" {
30
+ host = "127.0.0.1"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
+ logger.Logger.Info(fmt.Sprint("Server started on http://", host, ":", config.Port))
33
+ // 启动 HTTP 服务器
34
+ _ = server.Run(fmt.Sprint(config.Bind, ":", config.Port))
35
  }
middlewares/auth.go DELETED
@@ -1,31 +0,0 @@
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 DELETED
@@ -1,10 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
queue/queue.go ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package queue
2
+
3
+ type (
4
+ Queue struct {
5
+ start, end *Node
6
+ length int
7
+ }
8
+ Node struct {
9
+ Value interface{}
10
+ next *Node
11
+ }
12
+ )
13
+
14
+ // New 新建一个队列
15
+ func New() *Queue {
16
+ return &Queue{nil, nil, 0}
17
+ }
18
+
19
+ // Dequeue 出队
20
+ func (Q *Queue) Dequeue() *Node {
21
+ if Q.length == 0 {
22
+ return nil
23
+ }
24
+ n := Q.start
25
+ if Q.length == 1 {
26
+ Q.start = nil
27
+ Q.end = nil
28
+ } else {
29
+ Q.start = Q.start.next
30
+ }
31
+ Q.length--
32
+ return n
33
+ }
34
+
35
+ // Enqueue 入队
36
+ func (Q *Queue) Enqueue(value interface{}) {
37
+ n := &Node{value, nil}
38
+ if Q.length == 0 {
39
+ Q.start = n
40
+ Q.end = n
41
+ } else {
42
+ Q.end.next = n
43
+ Q.end = n
44
+ }
45
+ Q.length++
46
+ }
47
+
48
+ // Len 获取队列长度
49
+ func (Q *Queue) Len() int {
50
+ return Q.length
51
+ }
52
+
53
+ // Peek 返回队列的第一个元素
54
+ func (Q *Queue) Peek() *Node {
55
+ if Q.length == 0 {
56
+ return nil
57
+ }
58
+ return Q.start
59
+ }
60
+
61
+ // Remove 移除指定节点
62
+ func (Q *Queue) Remove(n *Node) {
63
+ if Q.length == 0 || n == nil {
64
+ return
65
+ }
66
+
67
+ // 如果移除的是队列的第一个元素
68
+ if n == Q.start {
69
+ Q.start = Q.start.next
70
+ if Q.start == nil {
71
+ // 如果移除后队列为空,则end也应该设置为nil
72
+ Q.end = nil
73
+ }
74
+ Q.length--
75
+ return
76
+ }
77
+
78
+ // 找到n的前一个节点
79
+ prevNode := Q.start
80
+ for prevNode != nil && prevNode.next != n {
81
+ prevNode = prevNode.next
82
+ }
83
+
84
+ if prevNode == nil {
85
+ // 没有找到n的前一个节点(n不在队列中)
86
+ return
87
+ }
88
+
89
+ // 移除节点n
90
+ prevNode.next = n.next
91
+ // 如果移除的是最后一个元素,更新end指针
92
+ if n.next == nil {
93
+ Q.end = prevNode
94
+ }
95
+ Q.length--
96
+ }
97
+
98
+ // Traverse 遍历队列
99
+ func (Q *Queue) Traverse(cb func(n *Node)) {
100
+ if Q.length == 0 {
101
+ return
102
+ }
103
+ for n := Q.start; n != nil; n = n.next {
104
+ cb(n)
105
+ }
106
+ }
release.bat CHANGED
@@ -5,10 +5,10 @@ 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
 
5
  chcp 65001
6
 
7
  REM 设置要生成的可执行文件的名称
8
+ set OUTPUT_NAME=free-gpt3.5-2api
9
 
10
  REM 设置 Go 源文件的名称
11
+ SET GOFILE=main.go
12
 
13
  REM 设置输出目录
14
  SET OUTPUTDIR=target
render.yaml DELETED
@@ -1,7 +0,0 @@
1
- services:
2
- - type: web
3
- name: duck2api
4
- env: docker
5
- dockerfilePath: ./Dockerfile
6
- plan: free
7
-
 
 
 
 
 
 
 
 
router/middleware.go ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package router
2
+
3
+ import (
4
+ "fmt"
5
+ "free-gpt3.5-2api/common"
6
+ "free-gpt3.5-2api/config"
7
+ "github.com/aurorax-neo/go-logger"
8
+ "github.com/gin-gonic/gin"
9
+ )
10
+
11
+ // Ping 测试接口
12
+ func Ping(c *gin.Context) {
13
+ c.JSON(200, gin.H{
14
+ "message": "pong",
15
+ })
16
+ }
17
+
18
+ // V1Cors 跨域中间件
19
+ func V1Cors(c *gin.Context) {
20
+ // 允许跨域
21
+ c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
22
+ c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
23
+ c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
24
+ c.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept")
25
+ c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
26
+ // 如果是OPTIONS请求,直接返回
27
+ if c.Request.Method == "OPTIONS" {
28
+ c.AbortWithStatus(204)
29
+ return
30
+ }
31
+ c.Next()
32
+ }
33
+
34
+ // V1Request 请求中间件
35
+ func V1Request(c *gin.Context) {
36
+ // 打印请求摘要 方法 url ip - user-agent 格式化输出
37
+ infoStr := fmt.Sprint(" -> ", c.Request.Method, " ", c.Request.URL.String(), " - ", c.ClientIP(), " - ", c.Request.Header.Get("User-Agent"))
38
+ logger.Logger.Info(infoStr)
39
+ c.Next()
40
+ }
41
+
42
+ // V1Auth 验证v1 api 的token
43
+ func V1Auth(c *gin.Context) {
44
+ authToken := c.Request.Header.Get("Authorization")
45
+ if authToken == "" && len(config.AUTHORIZATIONS) > 0 {
46
+ common.ErrorResponse(c, 401, "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY)", nil)
47
+ return
48
+ }
49
+ // 判断 authToken 是否在 config.CONFIG.AUTHORIZATIONS 列表
50
+ if !common.IsStrInArray(authToken, config.AUTHORIZATIONS) {
51
+ common.ErrorResponse(c, 401, "Incorrect API key provided: sk-4yNZz***************************************6mjw.", nil)
52
+ return
53
+ }
54
+ c.Next()
55
+ }
56
+
57
+ // V1Response 响应中间件
58
+ func V1Response(c *gin.Context) {
59
+ c.Next()
60
+ // 打印响应摘要 方法 url 状态码
61
+ infoStr := fmt.Sprint(" <- ", c.Request.Method, " ", c.Request.URL.String(), " - ", c.Writer.Status())
62
+ logger.Logger.Info(infoStr)
63
+ }
router/router.go ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package router
2
+
3
+ import (
4
+ v1 "free-gpt3.5-2api/service/v1"
5
+ "free-gpt3.5-2api/service/v1Chat"
6
+ "github.com/gin-gonic/gin"
7
+ "net/http"
8
+ )
9
+
10
+ func SetRouter(router *gin.Engine) {
11
+ router.GET("/", Index)
12
+ router.GET("/ping", Ping)
13
+ v1Router := router.Group("/v1")
14
+ v1Router.Use(V1Cors)
15
+ v1Router.Use(V1Request)
16
+ v1Router.Use(V1Response)
17
+ v1Router.Use(V1Auth)
18
+ v1Router.GET("/tokens", v1.Tokens)
19
+ v1Router.OPTIONS("/chat/completions", nil)
20
+ v1Router.POST("/chat/completions", v1Chat.Completions)
21
+ }
22
+
23
+ func Index(c *gin.Context) {
24
+ c.String(http.StatusOK, "Hello,This is free-gpt3.5-2api.")
25
+ }
service/v1/tokens.go ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package v1
2
+
3
+ import (
4
+ "fmt"
5
+ "free-gpt3.5-2api/FreeGpt35Pool"
6
+ "github.com/aurorax-neo/go-logger"
7
+ "github.com/gin-gonic/gin"
8
+ )
9
+
10
+ type TokensResp struct {
11
+ Count int `json:"count"`
12
+ }
13
+
14
+ func Tokens(c *gin.Context) {
15
+ resp := &TokensResp{
16
+ Count: FreeGpt35Pool.GetFreeGpt35PoolInstance().GetSize(),
17
+ }
18
+ logger.Logger.Info(fmt.Sprint("FreeGpt35Pool Tokens: ", resp.Count))
19
+ c.JSON(200, resp)
20
+ }
service/v1/util.go ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package v1
2
+
3
+ import (
4
+ "free-gpt3.5-2api/service/v1Chat/reqModel"
5
+ "github.com/google/uuid"
6
+ "math/rand"
7
+ )
8
+
9
+ func MappingModel(model string) string {
10
+ var modelMapping = map[string]string{
11
+ "gpt-3.5-turbo": "text-davinci-002-render-sha",
12
+ "gpt-3.5-turbo-16k": "text-davinci-002-render-sha",
13
+ "gpt-3.5-turbo-16k-0613": "text-davinci-002-render-sha",
14
+ "gpt-3.5-turbo-0301": "text-davinci-002-render-sha",
15
+ "gpt-3.5-turbo-0613": "text-davinci-002-render-sha",
16
+ "gpt-3.5-turbo-1106": "text-davinci-002-render-sha",
17
+ }
18
+ if model == "" {
19
+ return "text-davinci-002-render-sha"
20
+ }
21
+ if v, ok := modelMapping[model]; ok {
22
+ return v
23
+ }
24
+ return "text-davinci-002-render-sha"
25
+ }
26
+
27
+ func GenerateID(length int) string {
28
+ const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
29
+ id := "chatcmpl-"
30
+ for i := 0; i < length; i++ {
31
+ id += string(charset[rand.Intn(len(charset))])
32
+ }
33
+ return id
34
+ }
35
+
36
+ func ApiReq2ChatReq35(apiReq *reqModel.ApiReq) (chatReq *reqModel.ChatReq35) {
37
+ messages := make([]reqModel.ChatMessages, 0)
38
+ for _, apiMessage := range apiReq.Messages {
39
+ chatMessage := reqModel.ChatMessages{
40
+ Author: reqModel.ChatAuthor{
41
+ Role: apiMessage.Role,
42
+ },
43
+ Content: reqModel.ChatContent{
44
+ ContentType: "text",
45
+ Parts: []string{apiMessage.Content},
46
+ },
47
+ }
48
+ messages = append(messages, chatMessage)
49
+ }
50
+
51
+ chatReq = &reqModel.ChatReq35{
52
+ Action: "next",
53
+ Messages: messages,
54
+ ParentMessageId: uuid.New().String(),
55
+ Model: MappingModel(apiReq.Model),
56
+ TimeZoneOffsetMin: -180,
57
+ Suggestions: make([]string, 0),
58
+ HistoryAndTrainingDisabled: true,
59
+ ConversationMode: reqModel.ChatConversationMode{
60
+ Kind: "primary_assistant",
61
+ },
62
+ WebsocketRequestId: uuid.New().String(),
63
+ }
64
+ return chatReq
65
+ }
service/v1Chat/completions.go ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package v1Chat
2
+
3
+ import (
4
+ "free-gpt3.5-2api/common"
5
+ "free-gpt3.5-2api/service/v1Chat/reqModel"
6
+ "github.com/gin-gonic/gin"
7
+ "net/http"
8
+ )
9
+
10
+ func Completions(c *gin.Context) {
11
+ // 从请求中获取参数
12
+ apiReq := &reqModel.ApiReq{}
13
+ err := c.BindJSON(apiReq)
14
+ if err != nil {
15
+ common.ErrorResponse(c, http.StatusBadRequest, "Invalid parameter", nil)
16
+ return
17
+ }
18
+ Gpt35Completions(c, apiReq)
19
+ }
service/v1Chat/gpt35Completions.go ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package v1Chat
2
+
3
+ import (
4
+ "encoding/json"
5
+ "fmt"
6
+ "free-gpt3.5-2api/FreeGpt35"
7
+ "free-gpt3.5-2api/FreeGpt35Pool"
8
+ "free-gpt3.5-2api/common"
9
+ "free-gpt3.5-2api/service/v1"
10
+ "free-gpt3.5-2api/service/v1Chat/reqModel"
11
+ "free-gpt3.5-2api/service/v1Chat/respModel"
12
+ "github.com/aurorax-neo/go-logger"
13
+ fhttp "github.com/bogdanfinn/fhttp"
14
+ "github.com/gin-gonic/gin"
15
+ "github.com/launchdarkly/eventsource"
16
+ "io"
17
+ "net/http"
18
+ "strings"
19
+ )
20
+
21
+ func Gpt35Completions(c *gin.Context, apiReq *reqModel.ApiReq) {
22
+ // 获取 FreeGpt35 实例
23
+ ChatGpt35 := FreeGpt35Pool.GetFreeGpt35PoolInstance().GetFreeGpt35(3)
24
+ if ChatGpt35 == nil {
25
+ errStr := "please restart the program、change the IP address、use a proxy to try again."
26
+ logger.Logger.Error(errStr)
27
+ common.ErrorResponse(c, http.StatusUnauthorized, errStr, nil)
28
+ return
29
+ }
30
+ // 转换请求
31
+ ChatReq35 := v1.ApiReq2ChatReq35(apiReq)
32
+ // 请求参数
33
+ body, err := common.Struct2BytesBuffer(ChatReq35)
34
+ if err != nil {
35
+ logger.Logger.Error(err.Error())
36
+ common.ErrorResponse(c, http.StatusInternalServerError, "", err)
37
+ return
38
+
39
+ }
40
+ // 生成请求
41
+ request, err := ChatGpt35.NewRequest(fhttp.MethodPost, FreeGpt35.ChatUrl, body)
42
+ if err != nil || request == nil {
43
+ errStr := "Request is nil or error"
44
+ logger.Logger.Error("Request is nil or error")
45
+ common.ErrorResponse(c, http.StatusInternalServerError, errStr, err)
46
+ return
47
+ }
48
+ // 设置请求头
49
+ request.Header.Set("Content-Type", "application/json")
50
+ request.Header.Set("oai-device-id", ChatGpt35.FreeAuth.OaiDeviceId)
51
+ request.Header.Set("openai-sentinel-chat-requirements-token", ChatGpt35.FreeAuth.Token)
52
+ if ChatGpt35.FreeAuth.ProofWork.Required {
53
+ request.Header.Set("Openai-Sentinel-Proof-Token", ChatGpt35.FreeAuth.ProofWork.Ospt)
54
+ }
55
+ // 发送请求
56
+ response, err := ChatGpt35.RequestClient.Do(request)
57
+ if err != nil {
58
+ errStr := "RequestClient Do error"
59
+ logger.Logger.Error(fmt.Sprint(errStr, " ", err))
60
+ common.ErrorResponse(c, http.StatusInternalServerError, errStr, err)
61
+ return
62
+ }
63
+ defer func(Body io.ReadCloser) {
64
+ _ = Body.Close()
65
+ }(response.Body)
66
+ if response.StatusCode != http.StatusOK {
67
+ errStr := "Request error"
68
+ logger.Logger.Error(fmt.Sprint(errStr, " ", response.StatusCode))
69
+ common.ErrorResponse(c, response.StatusCode, errStr, nil)
70
+ return
71
+ }
72
+ // 流式返回
73
+ if apiReq.Stream {
74
+ __CompletionsStream(c, apiReq, response)
75
+ } else { // 非流式回应
76
+ __CompletionsNoStream(c, apiReq, response)
77
+ }
78
+ }
79
+
80
+ func __CompletionsStream(c *gin.Context, apiReq *reqModel.ApiReq, resp *fhttp.Response) {
81
+ defer func(Body io.ReadCloser) {
82
+ _ = Body.Close()
83
+ }(resp.Body)
84
+ messageTemp := ""
85
+ decoder := eventsource.NewDecoder(resp.Body)
86
+ // 响应id
87
+ id := v1.GenerateID(29)
88
+ handlingSigns := false
89
+ for {
90
+ event, err := decoder.Decode()
91
+ if err != nil {
92
+ logger.Logger.Error(err.Error())
93
+ common.ErrorResponse(c, http.StatusInternalServerError, "", err)
94
+ break
95
+ }
96
+ name := event.Event()
97
+ data := event.Data()
98
+ // 空白数据不处理
99
+ if data == "" {
100
+ continue
101
+ }
102
+ // 结束标志
103
+ if data == "[DONE]" {
104
+ // 生成响应 stream
105
+ apiRespStream := respModel.NewApiRespStream(id, apiReq.Model, "", "stop")
106
+ // 生成响应 bytes
107
+ bytes, err := common.Struct2Bytes(apiRespStream)
108
+ if err != nil {
109
+ logger.Logger.Error(err.Error())
110
+ continue
111
+ }
112
+ // 发送响应
113
+ c.SSEvent(name, fmt.Sprint(" ", string(bytes)))
114
+ // 结束
115
+ c.SSEvent(name, " [DONE]")
116
+ return
117
+ }
118
+ chatResp35 := &respModel.ChatResp35{}
119
+ err = json.Unmarshal([]byte(data), chatResp35)
120
+ if chatResp35.Error != nil && !handlingSigns {
121
+ logger.Logger.Error(fmt.Sprint(chatResp35.Error))
122
+ common.ErrorResponse(c, http.StatusInternalServerError, "", chatResp35.Error)
123
+ return
124
+ }
125
+ // 脏数据不处理
126
+ if err != nil {
127
+ continue
128
+ }
129
+ // 被block
130
+ if contentIsBlocked(chatResp35) {
131
+ // 返回响应
132
+ common.ErrorResponse(c, http.StatusBadRequest, "content is blocked.", "")
133
+ return
134
+ }
135
+ // 仅处理assistant的消息
136
+ if chatResp35.Message.Author.Role == "assistant" && (chatResp35.Message.Status == "in_progress" || handlingSigns) {
137
+ // handlingSigns 置为 true
138
+ handlingSigns = true
139
+ // 仅处理第一个part
140
+ parts := chatResp35.Message.Content.Parts[0]
141
+ // 去除重复数据
142
+ content := strings.Replace(parts, messageTemp, "", 1)
143
+ messageTemp = parts
144
+ // 空白数据不处理
145
+ if content == "" {
146
+ continue
147
+ }
148
+ // 生成响应 stream
149
+ apiRespStream := respModel.NewApiRespStream(id, apiReq.Model, content, "")
150
+ // 生成响应 bytes
151
+ bytes, err := common.Struct2Bytes(apiRespStream)
152
+ if err != nil {
153
+ logger.Logger.Error(err.Error())
154
+ continue
155
+ }
156
+ // 发送响应
157
+ c.SSEvent(name, fmt.Sprint(" ", string(bytes)))
158
+ // 继续
159
+ continue
160
+ }
161
+ }
162
+ }
163
+
164
+ func __CompletionsNoStream(c *gin.Context, apiReq *reqModel.ApiReq, resp *fhttp.Response) {
165
+ defer func(Body io.ReadCloser) {
166
+ _ = Body.Close()
167
+ }(resp.Body)
168
+ content := ""
169
+ decoder := eventsource.NewDecoder(resp.Body)
170
+ handlingSigns := false
171
+ for {
172
+ event, err := decoder.Decode()
173
+ if err != nil {
174
+ logger.Logger.Error(err.Error())
175
+ common.ErrorResponse(c, http.StatusInternalServerError, "", err)
176
+ return
177
+ }
178
+ data := event.Data()
179
+ // 空白数据不处理
180
+ if data == "" {
181
+ continue
182
+ }
183
+ // 结束标志
184
+ if data == "[DONE]" {
185
+ apiRespObj := respModel.NewApiRespJson(v1.GenerateID(29), apiReq.Model, content)
186
+ // 返回响应
187
+ c.JSON(http.StatusOK, apiRespObj)
188
+ return
189
+ }
190
+ chatResp35 := &respModel.ChatResp35{}
191
+ err = json.Unmarshal([]byte(data), chatResp35)
192
+ if chatResp35.Error != nil && !handlingSigns {
193
+ logger.Logger.Error(fmt.Sprint(chatResp35.Error))
194
+ common.ErrorResponse(c, http.StatusInternalServerError, "", chatResp35.Error)
195
+ return
196
+ }
197
+ // 被block
198
+ if contentIsBlocked(chatResp35) {
199
+ // 返回响应
200
+ common.ErrorResponse(c, http.StatusBadRequest, "content is blocked.", "")
201
+ return
202
+ }
203
+ // 脏数据不处理
204
+ if err != nil {
205
+ continue
206
+ }
207
+ // 仅处理assistant的消息
208
+ if chatResp35.Message.Author.Role == "assistant" && (chatResp35.Message.Status == "in_progress" || handlingSigns) {
209
+ // handlingSigns 置为 true
210
+ handlingSigns = true
211
+ // 如果不包含上一次的数据则不处理
212
+ if !strings.Contains(chatResp35.Message.Content.Parts[0], content) {
213
+ continue
214
+ }
215
+ // 仅处理第一个part
216
+ content = chatResp35.Message.Content.Parts[0]
217
+ // 空白数据不处理
218
+ if content == "" {
219
+ continue
220
+ }
221
+ continue
222
+ }
223
+ }
224
+ }
225
+
226
+ func contentIsBlocked(chatResp35 *respModel.ChatResp35) bool {
227
+ if !chatResp35.IsCompletion && chatResp35.ModerationResponse.Blocked {
228
+ return true
229
+ }
230
+ return false
231
+ }
service/v1Chat/reqModel/apiReq.go ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package reqModel
2
+
3
+ type ApiReq struct {
4
+ Messages []ApiMessage `json:"messages"`
5
+ Model string `json:"model"`
6
+ Stream bool `json:"stream"`
7
+ PluginIds []string `json:"plugin_ids"`
8
+ NewMessages string `json:"-"`
9
+ }
10
+
11
+ type ApiMessage struct {
12
+ Role string `json:"role"`
13
+ Content string `json:"content"`
14
+ }
service/v1Chat/reqModel/chatReq.go ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package reqModel
2
+
3
+ type ChatAuthor struct {
4
+ Role string `json:"role"`
5
+ }
6
+
7
+ type ChatContent struct {
8
+ ContentType string `json:"content_type"`
9
+ Parts []string `json:"parts"`
10
+ }
11
+
12
+ type ChatMessages struct {
13
+ Author ChatAuthor `json:"author"`
14
+ Content ChatContent `json:"content"`
15
+ }
16
+
17
+ type ChatConversationMode struct {
18
+ Kind string `json:"kind"`
19
+ }
20
+
21
+ type ChatReq35 struct {
22
+ Action string `json:"action"`
23
+ Messages []ChatMessages `json:"messages"`
24
+ ParentMessageId string `json:"parent_message_id"`
25
+ Model string `json:"model"`
26
+ TimeZoneOffsetMin int `json:"timezone_offset_min"`
27
+ Suggestions []string `json:"suggestions"`
28
+ HistoryAndTrainingDisabled bool `json:"history_and_training_disabled"`
29
+ ConversationMode ChatConversationMode `json:"conversation_mode"`
30
+ WebsocketRequestId string `json:"websocket_request_id"`
31
+ }