@@ -25,23 +25,13 @@ import (
2525)
2626
2727const (
28- qwenUserAgent = "QwenCode/0.13 .2 (darwin; arm64)"
28+ qwenUserAgent = "QwenCode/0.14 .2 (darwin; arm64)"
2929 qwenRateLimitPerMin = 60 // 60 requests per minute per credential
3030 qwenRateLimitWindow = time .Minute // sliding window duration
3131)
3232
3333var qwenDefaultSystemMessage = []byte (`{"role":"system","content":[{"type":"text","text":"","cache_control":{"type":"ephemeral"}}]}` )
3434
35- // qwenBeijingLoc caches the Beijing timezone to avoid repeated LoadLocation syscalls.
36- var qwenBeijingLoc = func () * time.Location {
37- loc , err := time .LoadLocation ("Asia/Shanghai" )
38- if err != nil || loc == nil {
39- log .Warnf ("qwen: failed to load Asia/Shanghai timezone: %v, using fixed UTC+8" , err )
40- return time .FixedZone ("CST" , 8 * 3600 )
41- }
42- return loc
43- }()
44-
4535// qwenQuotaCodes is a package-level set of error codes that indicate quota exhaustion.
4636var qwenQuotaCodes = map [string ]struct {}{
4737 "insufficient_quota" : {},
@@ -156,22 +146,13 @@ func wrapQwenError(ctx context.Context, httpCode int, body []byte) (errCode int,
156146 // Qwen returns 403 for quota errors, 429 for rate limits
157147 if (httpCode == http .StatusForbidden || httpCode == http .StatusTooManyRequests ) && isQwenQuotaError (body ) {
158148 errCode = http .StatusTooManyRequests // Map to 429 to trigger quota logic
159- cooldown := timeUntilNextDay ()
160- retryAfter = & cooldown
161- helps .LogWithRequestID (ctx ).Warnf ("qwen quota exceeded (http %d -> %d), cooling down until tomorrow (%v) " , httpCode , errCode , cooldown )
149+ // Do not force an excessively long retry-after (e.g. until tomorrow), otherwise
150+ // the global request-retry scheduler may skip retries due to max-retry-interval.
151+ helps .LogWithRequestID (ctx ).Warnf ("qwen quota exceeded (http %d -> %d)" , httpCode , errCode )
162152 }
163153 return errCode , retryAfter
164154}
165155
166- // timeUntilNextDay returns duration until midnight Beijing time (UTC+8).
167- // Qwen's daily quota resets at 00:00 Beijing time.
168- func timeUntilNextDay () time.Duration {
169- now := time .Now ()
170- nowLocal := now .In (qwenBeijingLoc )
171- tomorrow := time .Date (nowLocal .Year (), nowLocal .Month (), nowLocal .Day ()+ 1 , 0 , 0 , 0 , 0 , qwenBeijingLoc )
172- return tomorrow .Sub (now )
173- }
174-
175156// ensureQwenSystemMessage ensures the request has a single system message at the beginning.
176157// It always injects the default system prompt and merges any user-provided system messages
177158// into the injected system message content to satisfy Qwen's strict message ordering rules.
@@ -626,19 +607,23 @@ func (e *QwenExecutor) Refresh(ctx context.Context, auth *cliproxyauth.Auth) (*c
626607}
627608
628609func applyQwenHeaders (r * http.Request , token string , stream bool ) {
629- r .Header .Set ("Content-Type" , "application/json" )
630- r .Header .Set ("Authorization" , "Bearer " + token )
631- r .Header .Set ("User-Agent" , qwenUserAgent )
632- r .Header ["X-DashScope-UserAgent" ] = []string {qwenUserAgent }
633610 r .Header .Set ("X-Stainless-Runtime-Version" , "v22.17.0" )
611+ r .Header .Set ("User-Agent" , qwenUserAgent )
634612 r .Header .Set ("X-Stainless-Lang" , "js" )
635- r .Header .Set ("X-Stainless-Arch" , "arm64" )
636- r .Header .Set ("X-Stainless-Package-Version" , "5.11.0" )
637- r .Header ["X-DashScope-CacheControl" ] = []string {"enable" }
638- r .Header .Set ("X-Stainless-Retry-Count" , "0" )
613+ r .Header .Set ("Accept-Language" , "*" )
614+ r .Header .Set ("X-Dashscope-Cachecontrol" , "enable" )
639615 r .Header .Set ("X-Stainless-Os" , "MacOS" )
640- r .Header ["X-DashScope-AuthType" ] = []string {"qwen-oauth" }
616+ r .Header .Set ("X-Dashscope-Authtype" , "qwen-oauth" )
617+ r .Header .Set ("X-Stainless-Arch" , "arm64" )
641618 r .Header .Set ("X-Stainless-Runtime" , "node" )
619+ r .Header .Set ("X-Stainless-Retry-Count" , "0" )
620+ r .Header .Set ("Accept-Encoding" , "gzip, deflate" )
621+ r .Header .Set ("Authorization" , "Bearer " + token )
622+ r .Header .Set ("X-Stainless-Package-Version" , "5.11.0" )
623+ r .Header .Set ("Sec-Fetch-Mode" , "cors" )
624+ r .Header .Set ("Content-Type" , "application/json" )
625+ r .Header .Set ("Connection" , "keep-alive" )
626+ r .Header .Set ("X-Dashscope-Useragent" , qwenUserAgent )
642627
643628 if stream {
644629 r .Header .Set ("Accept" , "text/event-stream" )
0 commit comments