From 62595de79faa15844ac1dd2cfd4bb044828ccecc Mon Sep 17 00:00:00 2001 From: chiyi Date: Mon, 13 Jul 2026 00:06:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9C=81=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/provider/chatgpt/client.go | 25 ++++++++++++--------- backend/internal/provider/grok/video.go | 7 +++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/backend/internal/provider/chatgpt/client.go b/backend/internal/provider/chatgpt/client.go index d3710e4..fb5f09f 100644 --- a/backend/internal/provider/chatgpt/client.go +++ b/backend/internal/provider/chatgpt/client.go @@ -69,7 +69,11 @@ func (c *Client) SetProxy(proxy string) { } func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model, aspectRatio, resolution string, refs [][]byte) ([]byte, map[string]any, error) { - session, err := c.newSession(accessToken) + // Everything except the generation submit egresses on the local IP. Only + // startImageGeneration (the /backend-api/f/conversation POST) goes through + // the proxy; the bootstrap / chat-requirements / reference upload / prepare + // handshake and the poll / resolve / download run direct. + session, err := c.newDirectSession(accessToken) if err != nil { return nil, nil, err } @@ -100,7 +104,12 @@ func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model, if err != nil { return nil, nil, err } - conversationID, fileIDs, sedimentIDs, err := c.startImageGeneration(ctx, session, accessToken, effectivePrompt, reqs, conduitToken, model, uploadedRefs) + // The generation submit is the only request that egresses via the proxy. + submitSession, err := c.newSession(accessToken) + if err != nil { + return nil, nil, err + } + conversationID, fileIDs, sedimentIDs, err := c.startImageGeneration(ctx, submitSession, accessToken, effectivePrompt, reqs, conduitToken, model, uploadedRefs) if err != nil { return nil, nil, err } @@ -110,12 +119,6 @@ func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model, refIDs := uploadedRefIDSet(uploadedRefs) fileIDs = dropIDs(fileIDs, refIDs) sedimentIDs = dropIDs(sedimentIDs, refIDs) - // Poll / resolve / download run on the local IP (fresh direct session); - // only the submit phase above egressed via the proxy. - session, err = c.newDirectSession(accessToken) - if err != nil { - return nil, nil, err - } fileIDs, sedimentIDs, err = c.pollForImage(ctx, session, accessToken, conversationID, fileIDs, sedimentIDs, refIDs, pollBudget(ctx)) if err != nil { return nil, nil, err @@ -224,9 +227,9 @@ func (c *Client) newSession(accessToken string) (tlsclient.HttpClient, error) { return c.newSessionP(accessToken, true) } -// newDirectSession egresses on the local IP (never the proxy). Used for the -// poll / resolve / download phase; only the anti-bot-guarded submit phase -// (bootstrap, chat-requirements, upload, conversation create) uses the proxy. +// newDirectSession egresses on the local IP (never the proxy). Used for +// everything except the generation submit (the /backend-api/f/conversation +// POST), which is the only request that uses the proxy. func (c *Client) newDirectSession(accessToken string) (tlsclient.HttpClient, error) { return c.newSessionP(accessToken, false) } diff --git a/backend/internal/provider/grok/video.go b/backend/internal/provider/grok/video.go index a8da0c8..ad4b136 100644 --- a/backend/internal/provider/grok/video.go +++ b/backend/internal/provider/grok/video.go @@ -68,9 +68,10 @@ func (c *Client) GenerateVideo(ctx context.Context, token, prompt, aspectRatio, // Self-heal the x-statsig-id anti-bot challenge for THIS session before the // gated submit. Without it the header falls back to the static defaults, // which go stale on a new grok web build and make conversations/new answer - // 403 (anti-bot). Fetch via the proxy client so the derived seed matches the - // submit's egress IP. Failure is non-fatal (statsigID then uses defaults). - c.ensureChallenge(ctx, submitClient, token) + // 403 (anti-bot). Fetch on the local IP (the proxy is rotating, so pinning + // the seed to a proxy egress IP is pointless). Failure is non-fatal + // (statsigID then uses defaults). + c.ensureChallenge(ctx, directClient, token) // Image-to-video: upload each reference frame and collect its asset URL. var imageRefs []string