package client import ( "bytes" "context" dsprotocol "ds2api/internal/deepseek/protocol" "encoding/json" "errors" "net/http" "time" "ds2api/internal/auth" "ds2api/internal/config" trans "ds2api/internal/deepseek/transport" ) func (c *Client) CallCompletion(ctx context.Context, a *auth.RequestAuth, payload map[string]any, powResp string, maxAttempts int) (*http.Response, error) { if maxAttempts <= 0 { maxAttempts = c.maxRetries } clients := c.requestClientsForAuth(ctx, a) headers := c.authHeaders(a.DeepSeekToken) headers["x-ds-pow-response"] = powResp captureSession := c.capture.Start("deepseek_completion", dsprotocol.DeepSeekCompletionURL, a.AccountID, payload) attempts := 0 for attempts < maxAttempts { resp, err := c.streamPost(ctx, clients.stream, dsprotocol.DeepSeekCompletionURL, headers, payload) if err != nil { attempts++ time.Sleep(time.Second) continue } if resp.StatusCode == http.StatusOK { if captureSession != nil { resp.Body = captureSession.WrapBody(resp.Body, resp.StatusCode) } resp = c.wrapCompletionWithAutoContinue(ctx, a, payload, powResp, resp) return resp, nil } if captureSession != nil { resp.Body = captureSession.WrapBody(resp.Body, resp.StatusCode) } _ = resp.Body.Close() attempts++ time.Sleep(time.Second) } return nil, errors.New("completion failed") } func (c *Client) streamPost(ctx context.Context, doer trans.Doer, url string, headers map[string]string, payload any) (*http.Response, error) { b, err := json.Marshal(payload) if err != nil { return nil, err } headers = c.jsonHeaders(headers) clients := c.requestClientsFromContext(ctx) req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(b)) if err != nil { return nil, err } for k, v := range headers { req.Header.Set(k, v) } resp, err := doer.Do(req) if err != nil { config.Logger.Warn("[deepseek] fingerprint stream request failed, fallback to std transport", "url", url, "error", err) req2, reqErr := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(b)) if reqErr != nil { return nil, reqErr } for k, v := range headers { req2.Header.Set(k, v) } return clients.fallbackS.Do(req2) } return resp, nil }