@@ -26,10 +26,44 @@ type Handler struct {
2626 token * tokens.AccessToken
2727}
2828
29+ func writeChatCompletionStreamDone (c * gin.Context , stopSent bool , model string , conversationID string ) {
30+ if ! stopSent {
31+ finalLine := officialtypes .StopChunkWithConversation ("stop" , model , conversationID )
32+ c .Writer .WriteString ("data: " + finalLine .String () + "\n \n " )
33+ c .Writer .Flush ()
34+ }
35+ c .Writer .WriteString ("data: [DONE]\n \n " )
36+ c .Writer .Flush ()
37+ }
38+
2939func NewHandle (proxy * proxys.IProxy , token * tokens.AccessToken ) * Handler {
3040 return & Handler {proxy : proxy , token : token }
3141}
3242
43+ // initTurnStileWithRetry 初始化 turnstile,当 paid token 返回 401 时自动禁用并轮询下一个
44+ func (h * Handler ) initTurnStileWithRetry (client * * bogdanfinn.TlsClient , secret * * tokens.Secret , proxyUrl string ) (* chatgpt.TurnStile , int , error ) {
45+ for {
46+ (* client ).SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
47+ turnStile , status , err := chatgpt .InitTurnStile (* client , * secret , proxyUrl )
48+ if err == nil {
49+ return turnStile , status , nil
50+ }
51+ if status == http .StatusUnauthorized && * secret != nil && ! (* secret ).IsFree && (* secret ).Token != "" {
52+ if ! h .token .DisableSecret ((* secret ).Token ) {
53+ return nil , status , err
54+ }
55+ newSecret := h .token .GetPaidSecret ()
56+ if newSecret == nil || newSecret .Token == "" {
57+ return nil , status , err
58+ }
59+ * secret = newSecret
60+ * client = bogdanfinn .NewStdClient ()
61+ continue
62+ }
63+ return nil , status , err
64+ }
65+ }
66+
3367func (h * Handler ) refresh (c * gin.Context ) {
3468 var refreshToken officialtypes.OpenAIRefreshToken
3569 err := c .BindJSON (& refreshToken )
@@ -202,8 +236,7 @@ func (h *Handler) nightmare(c *gin.Context) {
202236
203237 uid := uuid .NewString ()
204238 client := bogdanfinn .NewStdClient ()
205- client .SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
206- turnStile , status , err := chatgpt .InitTurnStile (client , secret , proxyUrl )
239+ turnStile , status , err := h .initTurnStileWithRetry (& client , & secret , proxyUrl )
207240 if err != nil {
208241 c .JSON (status , gin.H {
209242 "message" : err .Error (),
@@ -225,25 +258,44 @@ func (h *Handler) nightmare(c *gin.Context) {
225258
226259 response , err := chatgpt .POSTconversation (client , translated_request , secret , turnStile , proxyUrl )
227260 if err != nil {
228- c .JSON (500 , gin.H {
229- "error" : "request conversion error" ,
230- })
261+ c .JSON (500 , gin.H {"error" : gin.H {
262+ "message" : err .Error (),
263+ "type" : "request_conversion_error" ,
264+ "param" : "model" ,
265+ "code" : "request_conversion_error" ,
266+ }})
231267 return
232268 }
233269 defer response .Body .Close ()
234270 if chatgpt .Handle_request_error (c , response ) {
235271 return
236272 }
237273 var full_response string
274+ var conversationID string
275+ var sentinel []map [string ]interface {}
276+ var stopSent bool
238277
239278 if os .Getenv ("STREAM_MODE" ) == "false" {
240279 original_request .Stream = false
241280 }
281+ if original_request .Stream {
282+ c .Writer .Header ().Set ("Content-Type" , "text/event-stream" )
283+ c .Writer .Header ().Set ("Cache-Control" , "no-cache" )
284+ c .Writer .Header ().Set ("Connection" , "keep-alive" )
285+ c .Writer .Header ().Set ("X-Accel-Buffering" , "no" )
286+ }
242287 for i := 3 ; i > 0 ; i -- {
243288 var continue_info * chatgpt.ContinueInfo
244- var response_part string
245- response_part , continue_info = chatgpt .Handler (c , response , client , secret , uid , translated_request , original_request .Stream , reqModel )
246- full_response += response_part
289+ result := chatgpt .HandlerDetailed (c , response , client , secret , uid , translated_request , original_request .Stream , reqModel )
290+ continue_info = result .Continue
291+ full_response += result .Text
292+ if result .ConversationID != "" {
293+ conversationID = result .ConversationID
294+ }
295+ sentinel = append (sentinel , result .Sentinel ... )
296+ if result .StopSent {
297+ stopSent = true
298+ }
247299 if continue_info == nil {
248300 break
249301 }
@@ -254,9 +306,12 @@ func (h *Handler) nightmare(c *gin.Context) {
254306
255307 response , err := chatgpt .POSTconversation (client , translated_request , secret , turnStile , proxyUrl )
256308 if err != nil {
257- c .JSON (500 , gin.H {
258- "error" : "request conversion error" ,
259- })
309+ c .JSON (500 , gin.H {"error" : gin.H {
310+ "message" : err .Error (),
311+ "type" : "request_conversion_error" ,
312+ "param" : "model" ,
313+ "code" : "request_conversion_error" ,
314+ }})
260315 return
261316 }
262317 defer response .Body .Close ()
@@ -269,9 +324,9 @@ func (h *Handler) nightmare(c *gin.Context) {
269324 }
270325 if ! original_request .Stream {
271326 output_tokens := util .CountToken (full_response )
272- c .JSON (200 , officialtypes .NewChatCompletion (full_response , input_tokens , output_tokens , reqModel ))
327+ c .JSON (200 , officialtypes .NewChatCompletionWithMetadata (full_response , input_tokens , output_tokens , reqModel , conversationID , sentinel ))
273328 } else {
274- c . String ( 200 , "data: [DONE] \n \n " )
329+ writeChatCompletionStreamDone ( c , stopSent , reqModel , conversationID )
275330 }
276331}
277332
@@ -322,8 +377,7 @@ func (h *Handler) responses(c *gin.Context) {
322377
323378 uid := uuid .NewString ()
324379 client := bogdanfinn .NewStdClient ()
325- client .SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
326- turnStile , status , err := chatgpt .InitTurnStile (client , secret , proxyUrl )
380+ turnStile , status , err := h .initTurnStileWithRetry (& client , & secret , proxyUrl )
327381 if err != nil {
328382 c .JSON (status , gin.H {
329383 "message" : err .Error (),
@@ -342,7 +396,12 @@ func (h *Handler) responses(c *gin.Context) {
342396
343397 response , err := chatgpt .POSTconversation (client , translated_request , secret , turnStile , proxyUrl )
344398 if err != nil {
345- c .JSON (500 , gin.H {"error" : "request conversion error" })
399+ c .JSON (500 , gin.H {"error" : gin.H {
400+ "message" : err .Error (),
401+ "type" : "request_conversion_error" ,
402+ "param" : "model" ,
403+ "code" : "request_conversion_error" ,
404+ }})
346405 return
347406 }
348407 defer response .Body .Close ()
@@ -366,7 +425,12 @@ func (h *Handler) responses(c *gin.Context) {
366425
367426 response , err = chatgpt .POSTconversation (client , translated_request , secret , turnStile , proxyUrl )
368427 if err != nil {
369- c .JSON (500 , gin.H {"error" : "request conversion error" })
428+ c .JSON (500 , gin.H {"error" : gin.H {
429+ "message" : err .Error (),
430+ "type" : "request_conversion_error" ,
431+ "param" : "model" ,
432+ "code" : "request_conversion_error" ,
433+ }})
370434 return
371435 }
372436 defer response .Body .Close ()
@@ -447,8 +511,7 @@ func (h *Handler) imageGenerations(c *gin.Context) {
447511 }
448512
449513 client := bogdanfinn .NewStdClient ()
450- client .SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
451- turnStile , status , err := chatgpt .InitTurnStile (client , secret , proxyUrl )
514+ turnStile , status , err := h .initTurnStileWithRetry (& client , & secret , proxyUrl )
452515 if err != nil {
453516 c .JSON (status , gin.H {
454517 "message" : err .Error (),
@@ -622,9 +685,9 @@ func (h *Handler) engines(c *gin.Context) {
622685
623686 models := []string {
624687 "auto" ,
625- "gpt-5. 5-instant" ,
688+ "gpt-5- 5-instant" ,
626689 "gpt-5-5-thinking" ,
627- "gpt-5. 5-pro" ,
690+ "gpt-5- 5-pro" ,
628691 "gpt-5" ,
629692 "gpt-4o" ,
630693 "gpt-4o-mini" ,
@@ -817,8 +880,7 @@ func (h *Handler) tts(c *gin.Context) {
817880 }
818881
819882 client := bogdanfinn .NewStdClient ()
820- client .SetCookies ("https://chatgpt.com" , chatgpt .BasicCookies )
821- turnStile , status , err := chatgpt .InitTurnStile (client , secret , proxyUrl )
883+ turnStile , status , err := h .initTurnStileWithRetry (& client , & secret , proxyUrl )
822884 if err != nil {
823885 c .JSON (status , gin.H {
824886 "message" : err .Error (),
@@ -901,7 +963,7 @@ func (h *Handler) chatgptConversation(c *gin.Context) {
901963 }
902964
903965 client := bogdanfinn .NewStdClient ()
904- turnStile , status , err := chatgpt . InitTurnStile ( client , secret , proxyUrl )
966+ turnStile , status , err := h . initTurnStileWithRetry ( & client , & secret , proxyUrl )
905967 if err != nil {
906968 c .JSON (status , gin.H {
907969 "message" : err .Error (),
0 commit comments