优化chatgpt检查

This commit is contained in:
2026-07-06 10:57:41 +08:00
parent e05db36f63
commit 713cca8f67
3 changed files with 10 additions and 23 deletions
-21
View File
@@ -38,15 +38,6 @@ var (
ErrDeadUpstream = errors.New("adobe upstream fatal error") ErrDeadUpstream = errors.New("adobe upstream fatal error")
) )
// bodyHasInsufficientCredits reports whether an Adobe response body signals the
// account has run out of generation credits ("insufficient credits"). Such an
// account is out of quota for this kind of generation, so it's treated as
// ErrQuotaExhausted: the pool marks it 限额 (per image/video kind) and fails over
// to the next account instead of surfacing a hard error to the caller.
func bodyHasInsufficientCredits(body []byte) bool {
return strings.Contains(strings.ToLower(string(body)), "insufficient credit")
}
var profileURLs = []string{ var profileURLs = []string{
"https://ims-na1.adobelogin.com/ims/profile/v1", "https://ims-na1.adobelogin.com/ims/profile/v1",
"https://adobeid-na1.services.adobe.com/ims/profile/v1", "https://adobeid-na1.services.adobe.com/ims/profile/v1",
@@ -468,9 +459,6 @@ func (c *Client) submitImage(ctx context.Context, client tlsclient.HttpClient, t
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
if bodyHasInsufficientCredits(respBody) {
return respBody, "", ErrQuotaExhausted
}
if resp.StatusCode == 401 || resp.StatusCode == 403 { if resp.StatusCode == 401 || resp.StatusCode == 403 {
if strings.EqualFold(resp.Header.Get("x-access-error"), "taste_exhausted") { if strings.EqualFold(resp.Header.Get("x-access-error"), "taste_exhausted") {
return respBody, "", ErrQuotaExhausted return respBody, "", ErrQuotaExhausted
@@ -545,9 +533,6 @@ func (c *Client) pollImage(ctx context.Context, client tlsclient.HttpClient, tok
if readErr != nil { if readErr != nil {
return nil, nil, readErr return nil, nil, readErr
} }
if bodyHasInsufficientCredits(body) {
return nil, nil, ErrQuotaExhausted
}
if b := string(body); strings.Contains(b, "system under load") || strings.Contains(b, "timeout_error") { if b := string(body); strings.Contains(b, "system under load") || strings.Contains(b, "timeout_error") {
return nil, nil, ErrTemporaryUpstream return nil, nil, ErrTemporaryUpstream
} }
@@ -646,9 +631,6 @@ func (c *Client) submitVideo(ctx context.Context, client tlsclient.HttpClient, t
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
if bodyHasInsufficientCredits(respBody) {
return respBody, "", ErrQuotaExhausted
}
if resp.StatusCode == 401 || resp.StatusCode == 403 { if resp.StatusCode == 401 || resp.StatusCode == 403 {
if strings.EqualFold(resp.Header.Get("x-access-error"), "taste_exhausted") { if strings.EqualFold(resp.Header.Get("x-access-error"), "taste_exhausted") {
return respBody, "", ErrQuotaExhausted return respBody, "", ErrQuotaExhausted
@@ -725,9 +707,6 @@ func (c *Client) pollVideo(ctx context.Context, client tlsclient.HttpClient, tok
if readErr != nil { if readErr != nil {
return nil, nil, readErr return nil, nil, readErr
} }
if bodyHasInsufficientCredits(body) {
return nil, nil, ErrQuotaExhausted
}
if resp.StatusCode == 401 || resp.StatusCode == 403 { if resp.StatusCode == 401 || resp.StatusCode == 403 {
return nil, nil, fmt.Errorf("%w (%d %s: %s)", ErrAuth, resp.StatusCode, resp.Header.Get("x-access-error"), clip(body, 300)) return nil, nil, fmt.Errorf("%w (%d %s: %s)", ErrAuth, resp.StatusCode, resp.Header.Get("x-access-error"), clip(body, 300))
} }
@@ -14,6 +14,7 @@ import (
"io" "io"
stdhttp "net/http" stdhttp "net/http"
"net/url" "net/url"
"os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
@@ -879,6 +880,9 @@ func (c *Client) getConversation(ctx context.Context, session tlsclient.HttpClie
if err := ensureOK(resp.StatusCode, body, "conversation_get"); err != nil { if err := ensureOK(resp.StatusCode, body, "conversation_get"); err != nil {
return nil, err return nil, err
} }
if dir := os.Getenv("CHATGPT_DEBUG_DUMP"); dir != "" {
_ = os.WriteFile(filepath.Join(dir, fmt.Sprintf("conv-%s-%d.json", conversationID, time.Now().UnixMilli())), body, 0o644)
}
var payload map[string]any var payload map[string]any
if err := json.Unmarshal(body, &payload); err != nil { if err := json.Unmarshal(body, &payload); err != nil {
return nil, err return nil, err
+6 -2
View File
@@ -157,8 +157,12 @@ func conversationEndedWithoutImage(conversation map[string]any) bool {
} }
if role == "assistant" { if role == "assistant" {
if content, _ := message["content"].(map[string]any); content != nil { if content, _ := message["content"].(map[string]any); content != nil {
if ct := stringValue(content["content_type"]); ct != "" && ct != "text" { // Only tool-invoking content types mean generation is underway.
return false // code/multimodal turn — generation underway // Context nodes (model_editable_context, thoughts, …) also appear
// on refused turns and must NOT suppress the detection.
switch stringValue(content["content_type"]) {
case "code", "multimodal_text":
return false
} }
} }
} }