Skip to content

Commit 5ce8313

Browse files
author
v_frgfeng
committed
art: copilot non-streaming output
1 parent 9692d29 commit 5ce8313

File tree

4 files changed

+42
-46
lines changed

4 files changed

+42
-46
lines changed

.goreleaser.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,31 +48,31 @@ changelog:
4848
- go mod tidy
4949
groups:
5050
- title: ":arrow_up: Dependency updates" # 依赖更新
51-
regexp: '^.*?(deps|arrow_up)(\([[:word:]]+\))??!?:.+$'
51+
regexp: '^.*?(deps|:arrow_up)\(deps\)!?:.+$'
5252
order: 300
5353
- title: ":sparkles: Features" # 新功能: 例如,新功能、新页面、新组件等
54-
regexp: '^.*?(feat|sparkles)(\([[:word:]]+\))??!?:.+$'
54+
regexp: '^.*?(feat|:sparkles)(\([[:word:]]+\))??!?:.+$'
5555
order: 100
5656
- title: ":art: Refactor" # 重构: 例如,重构代码、格式化代码、移动文件等
57-
regexp: '^.*?(refactor|art)(\([[:word:]]+\))??!?:.+$'
57+
regexp: '^.*?(refactor|:art)(\([[:word:]]+\))??!?:.+$'
5858
order: 150
5959
- title: ":lock: Security updates" # 安全更新: 例如,添加安全头、更新 .gitignore、更新 .gitattributes 等
60-
regexp: '^.*?sec(\([[:word:]]+\))??!?:.+$'
60+
regexp: '^.*?(sec|:lock)(\([[:word:]]+\))??!?:.+$'
6161
order: 150
6262
- title: ":bug: Bug fixes" # 修复错误: 例如,修复 bug、修复拼写错误等
6363
regexp: '^.*?(fix|bug)(\([[:word:]]+\))??!?:.+$'
6464
order: 200
6565
- title: ":zap: Perf" # 优化相关,比如提升性能、体验。
66-
regexp: '^.*?(perf|zap)(\([[:word:]]+\))??!?:.+$'
66+
regexp: '^.*?(perf|:zap)(\([[:word:]]+\))??!?:.+$'
6767
order: 300
6868
- title: "Chore" # 杂务:通常用于描述其他不属于新功能、修复错误或重构代码的提交。 例如,更新文档、清理代码、更新依赖项、删除文件等
6969
regexp: '^.*?chore(\([[:word:]]+\))??!?:.+$'
7070
order: 300
71-
- title: ":memo: Documentation updates" # 文档更新
72-
regexp: ^.*?(doc|memo)(\([[:word:]]+\))??!?:.+$
71+
- title: ":memo: Documentation updates"
72+
regexp: ^.*?(doc|:memo)(\([[:word:]]+\))??!?:.+$
7373
order: 400
74-
- title: ":lipstick: Style" # 样式更新,页面优化
75-
regexp: ^.*?(style|lipstick)(\([[:word:]]+\))??!?:.+$
74+
- title: ":lipstick: Style"
75+
regexp: ^.*?(style|:lipstick)(\([[:word:]]+\))??!?:.+$
7676
order: 400
7777
- title: "Build process updates"
7878
regexp: ^.*?build(\([[:word:]]+\))??!?:.+$

api/copilot/copilot.go

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,6 @@ func (co *CopilotApi) CompletionsHandler(c *gin.Context) {
8989
return
9090
}
9191

92-
// 默认流式输出
93-
isStream := true
94-
if b, ok := req["stream"]; ok && b.(bool) == false {
95-
isStream = false
96-
}
97-
9892
if model, ok := req["model"]; ok && model == "gemini-pro" || model == openai.GPT432K {
9993
global.SugarLog.Debugw("CompletionsHandler gemini-pro model", "model", model)
10094
genApi := &genai.GenApi{}
@@ -115,7 +109,7 @@ func (co *CopilotApi) CompletionsHandler(c *gin.Context) {
115109
response.FailWithOpenAIError(http.StatusUnauthorized, err.Error(), c)
116110
return
117111
}
118-
err = CompletionsRequest(c, req, isStream, copilotToken)
112+
err = CompletionsRequest(c, req, copilotToken)
119113
// 如果 token 过期,重新获取一次 token
120114
if errors.Is(err, TokenExpiredError) {
121115
CopilotTokenCache.Delete(token) // 删除缓存
@@ -127,7 +121,7 @@ func (co *CopilotApi) CompletionsHandler(c *gin.Context) {
127121
return
128122
}
129123
global.SugarLog.Infow("CompletionsHandler http get token is success")
130-
err = CompletionsRequest(c, req, isStream, coCopilotToken)
124+
err = CompletionsRequest(c, req, coCopilotToken)
131125
if err != nil {
132126
global.SugarLog.Errorw("CompletionsHandler CompletionsRequest retry request error", "err", err)
133127
response.FailWithOpenAIError(http.StatusBadGateway, err.Error(), c)
@@ -150,19 +144,13 @@ func (co *CopilotApi) CompletionsOfficialHandler(c *gin.Context) {
150144
return
151145
}
152146

153-
// 默认流式输出
154-
isStream := true
155-
if b, ok := req["stream"]; ok && b.(bool) == false {
156-
isStream = false
157-
}
158-
159147
token, err := utils.GetAuthToken(c, "Bearer")
160148
if err != nil {
161149
global.SugarLog.Errorw("CompletionsOfficialHandler get auth token err", "err", err.Error())
162150
response.FailWithOpenAIError(http.StatusUnauthorized, err.Error(), c)
163151
return
164152
}
165-
err = CompletionsRequest(c, req, isStream, token)
153+
err = CompletionsRequest(c, req, token)
166154
if err != nil {
167155
global.SugarLog.Warnw("CompletionsOfficialHandler CompletionsRequest request error", "err", err, "token", token)
168156
response.FailWithOpenAIError(http.StatusInternalServerError, err.Error(), c)
@@ -190,27 +178,27 @@ func GetCopilotTokenWithCache(token string) (copilotToken string, err error) {
190178
}
191179

192180
// CompletionsRequest 请求 Copilot CompletionsHandler 接口
193-
func CompletionsRequest(c *gin.Context, req map[string]interface{}, isStream bool, copilotToken string) (err error) {
194-
url := global.Config.Copilot.CompletionsURL
181+
func CompletionsRequest(c *gin.Context, req map[string]interface{}, copilotToken string) (err error) {
182+
completionsURL := global.Config.Copilot.CompletionsURL
195183
resp, err := Client.SetRetryCount(1).R().
196184
AddRetryCondition(func(r *resty.Response, err error) bool {
197185
if err != nil && strings.Contains(err.Error(), "connection reset by peer") {
198-
global.SugarLog.Warnw("CompletionsRequest Client connection reset by peer", "stream", isStream, "err", err.Error())
186+
global.SugarLog.Warnw("CompletionsRequest Client connection reset by peer", "err", err.Error())
199187
}
200188
var netErr net.Error
201189
if errors.As(err, &netErr) && netErr.Timeout() {
202-
global.SugarLog.Warnw("CompletionsRequest Client timeout err, retry", "stream", isStream, "err", netErr.Error())
190+
global.SugarLog.Warnw("CompletionsRequest Client timeout err, retry", "err", netErr.Error())
203191
return true
204192
}
205193
return false
206194
}).
207195
SetDoNotParseResponse(true).
208196
SetHeaders(GetCompletionsHeader(copilotToken)).
209197
SetBody(req).
210-
Post(url)
198+
Post(completionsURL)
211199

212200
if err != nil {
213-
global.SugarLog.Errorw("CompletionsRequest http error", "err", err, "url", url, "req", req, "copilotToken", copilotToken)
201+
global.SugarLog.Errorw("CompletionsRequest http error", "err", err, "completionsURL", completionsURL, "req", req, "copilotToken", copilotToken)
214202
response.FailWithOpenAIError(http.StatusInternalServerError, err.Error(), c)
215203
return
216204
}
@@ -219,33 +207,31 @@ func CompletionsRequest(c *gin.Context, req map[string]interface{}, isStream boo
219207

220208
respContentType := resp.Header().Get("Content-Type")
221209
if resp.StatusCode() != http.StatusOK {
222-
global.SugarLog.Warnw("CompletionsRequest respContentType", "respContentType", respContentType, "stream", isStream, "statusCode", resp.StatusCode())
210+
global.SugarLog.Warnw("CompletionsRequest respContentType", "respContentType", respContentType, "statusCode", resp.StatusCode())
223211
}
224212

225-
if strings.Contains(respContentType, "text/plain") {
213+
w := c.Writer
214+
215+
if strings.Contains(respContentType, "text/plain") { // 有错误信息
226216
body, err := io.ReadAll(reader)
227217
if err != nil {
228-
global.SugarLog.Errorw("CompletionsHandler reader body err", "stream", isStream, "err", err)
218+
global.SugarLog.Errorw("CompletionsHandler reader body err", "err", err)
229219
return err
230220
}
231221
bodyStr := strings.TrimRight(string(body), "\n")
232222
if bodyStr == "unauthorized: token expired" {
233-
global.SugarLog.Errorw("CompletionsHandler token expired", "stream", isStream, "body", bodyStr)
223+
global.SugarLog.Errorw("CompletionsHandler token expired", "body", bodyStr)
234224
return TokenExpiredError
235225
}
236-
global.SugarLog.Infow("CompletionsHandler response error", "stream", isStream, "body", bodyStr, "copilotToken", copilotToken)
226+
global.SugarLog.Infow("CompletionsHandler response error", "body", bodyStr, "copilotToken", copilotToken)
237227
response.FailWithOpenAIError(resp.StatusCode(), bodyStr, c)
238228
return nil
239-
}
240-
241-
w := c.Writer
242-
// 非流式输出
243-
if !isStream {
244-
utils.SetNotStreamHeaders(c)
229+
} else if strings.Contains(respContentType, "application/json") { // json 格式 非流式
230+
utils.SetJsonHeaders(c)
245231
flusher, _ := w.(http.Flusher)
246232
body, readErr := io.ReadAll(reader)
247233
if readErr != nil {
248-
global.SugarLog.Errorw("CompletionsHandler reader body err", "stream", isStream, "err", readErr)
234+
global.SugarLog.Errorw("CompletionsHandler reader body err", "respContentType", respContentType, "req", req, "err", readErr)
249235
return readErr
250236
}
251237
w.Write(body)
@@ -260,7 +246,7 @@ func CompletionsRequest(c *gin.Context, req map[string]interface{}, isStream boo
260246
if err == io.EOF {
261247
break
262248
} else if err != nil {
263-
global.SugarLog.Errorw("CompletionsHandler reader err", "stream", isStream, "err", err)
249+
global.SugarLog.Errorw("CompletionsHandler reader err", "err", err)
264250
break
265251
}
266252
w.Write(line)

api/genai/genai.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type GenApi struct {
2222
func (g *GenApi) CompletionsHandler(c *gin.Context) {
2323
token, err := utils.GetAuthToken(c, "Bearer")
2424
if err != nil {
25-
global.SugarLog.Errorw("CompletionsHandler Get hearder token error", "error", err)
25+
global.SugarLog.Errorw("CompletionsHandler Get header token error", "error", err)
2626
response.FailWithOpenAIError(http.StatusUnauthorized, err.Error(), c)
2727
return
2828
}

pkg/utils/http.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,22 @@ func SetEventStreamHeaders(c *gin.Context) {
3535
c.Writer.Header().Set("X-Accel-Buffering", "no") // // 禁用nginx缓存,防止nginx会缓存数据导致数据流是一段一段的
3636
}
3737

38-
// SetNotStreamHeaders 设置非SSE的响应头
39-
func SetNotStreamHeaders(c *gin.Context) {
38+
// SetJsonHeaders 设置非SSE的响应头
39+
func SetJsonHeaders(c *gin.Context) {
4040
c.Writer.Header().Set("Content-Type", "application/json")
4141
c.Writer.Header().Set("Cache-Control", "no-cache")
4242
c.Writer.Header().Set("Connection", "keep-alive")
4343
c.Writer.Header().Set("Transfer-Encoding", "chunked")
4444
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
4545
c.Writer.Header().Set("X-Accel-Buffering", "no") // // 禁用nginx缓存,防止nginx会缓存数据导致数据流是一段一段的
4646
}
47+
48+
// SetCustomHeaders 设置自定义的响应头
49+
func SetCustomHeaders(c *gin.Context, contentType string) {
50+
c.Writer.Header().Set("Content-Type", contentType)
51+
c.Writer.Header().Set("Cache-Control", "no-cache")
52+
c.Writer.Header().Set("Connection", "keep-alive")
53+
c.Writer.Header().Set("Transfer-Encoding", "chunked")
54+
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
55+
c.Writer.Header().Set("X-Accel-Buffering", "no") // // 禁用nginx缓存,防止nginx会缓存数据导致数据流是一段一段的
56+
}

0 commit comments

Comments
 (0)