(client **bogdanfinn.TlsClient, secret **tokens.Secret, translatedRequest chatgpt_types.ChatGPTRequest, proxyUrl string, stream bool, state *chatgpt.ChatClientState)
| 77 | } |
| 78 | |
| 79 | func (h *Handler) postConversationGptClientOrder(client **bogdanfinn.TlsClient, secret **tokens.Secret, translatedRequest chatgpt_types.ChatGPTRequest, proxyUrl string, stream bool, state *chatgpt.ChatClientState) (*http.Response, *websocket.Conn, int, error) { |
| 80 | if state != nil { |
| 81 | state.ApplyToRequest(&translatedRequest) |
| 82 | } |
| 83 | turnTraceID := uuid.NewString() |
| 84 | |
| 85 | // 对齐浏览器顺序: sentinel 流程必须在 prepare 流程之前完成。 |
| 86 | // 浏览器先调用 /sentinel/req → /chat-requirements/prepare → /sentinel/ping → |
| 87 | // /chat-requirements/finalize 获取 sentinel token, |
| 88 | // 然后才走 /f/conversation/prepare (none→sent→success) 获取 conduit token。 |
| 89 | // conduit token 在 sentinel 上下文中签发,服务器据此判定客户端可信度与模型路由。 |
| 90 | // |
| 91 | // 旧顺序 (prepare → sentinel → conversation) 导致 conduit token |
| 92 | // 在无 sentinel 上下文签发,服务器识别为低可信客户端 → mini 池。 |
| 93 | turnStile, status, err := h.initTurnStileWithRetryState(client, secret, proxyUrl, state) |
| 94 | if err != nil { |
| 95 | return nil, nil, status, err |
| 96 | } |
| 97 | |
| 98 | // 对齐浏览器 2026-06: sentinel 流程完成后调用 /conversation/init |
| 99 | chatgpt.POSTConversationInit(*client, *secret, state) |
| 100 | |
| 101 | // 对齐浏览器: WebSocket 在 sentinel 后、prepare 前连接,给服务端时间注册 |
| 102 | var wsConn *websocket.Conn |
| 103 | if stream { |
| 104 | wsConn, err = chatgpt.DialChatWebsocketWithStateAndProxy(*client, *secret, state, proxyUrl) |
| 105 | if err != nil { |
| 106 | return nil, nil, http.StatusInternalServerError, err |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // 三态 prepare 携带 sentinel token 头 |
| 111 | conduitToken, err := chatgpt.PrepareConversationConduitFullWithSentinel(*client, translatedRequest, *secret, proxyUrl, turnTraceID, state, turnStile) |
| 112 | if err != nil { |
| 113 | if wsConn != nil { |
| 114 | wsConn.Close() |
| 115 | } |
| 116 | return nil, nil, http.StatusInternalServerError, err |
| 117 | } |
| 118 | |
| 119 | response, err := chatgpt.POSTconversationPreparedWithState(*client, translatedRequest, *secret, turnStile, proxyUrl, conduitToken, turnTraceID, state) |
| 120 | if err != nil { |
| 121 | if wsConn != nil { |
| 122 | wsConn.Close() |
| 123 | } |
| 124 | return nil, nil, http.StatusInternalServerError, err |
| 125 | } |
| 126 | return response, wsConn, http.StatusOK, nil |
| 127 | } |
| 128 | |
| 129 | func (h *Handler) refresh(c *gin.Context) { |
| 130 | var refreshToken officialtypes.OpenAIRefreshToken |
no test coverage detected