fix: disable sub2api builtin temp unschedulable
This commit is contained in:
@@ -1041,75 +1041,8 @@ function defaultCodexPoolConfig(): CodexPoolConfig {
|
||||
|
||||
export function defaultCodexTempUnschedulablePolicy(): CodexTempUnschedulablePolicy {
|
||||
return {
|
||||
enabled: true,
|
||||
rules: [
|
||||
{
|
||||
statusCode: 400,
|
||||
keywords: ["invalid_encrypted_content", "encrypted content", "could not be verified", "could not be decrypted", "bad_response_status_code", "model_not_found", "no available channel for model", "unsupported", "not supported", "not support", "暂不支持", "可用模型"],
|
||||
durationMinutes: 120,
|
||||
description: "Stable upstream 400 model-routing or Responses encrypted-content compatibility failures should use another account.",
|
||||
},
|
||||
{
|
||||
statusCode: 401,
|
||||
keywords: ["unauthorized", "invalid api key", "invalid_api_key", "authentication", "recovered upstream error"],
|
||||
durationMinutes: 120,
|
||||
description: "Credential/auth failures should use the longest cooldown.",
|
||||
},
|
||||
{
|
||||
statusCode: 403,
|
||||
keywords: ["forbidden", "access denied", "quota", "billing", "capacity", "weekly limit", "less than 10% of your weekly limit left", "run /status for a breakdown", "recovered upstream error"],
|
||||
durationMinutes: 120,
|
||||
description: "Permission, quota, or account-state failures should use the longest cooldown.",
|
||||
},
|
||||
{
|
||||
statusCode: 429,
|
||||
keywords: ["capacity", "rate limit", "rate_limit", "quota", "weekly limit", "less than 10% of your weekly limit left", "run /status for a breakdown", "too many requests", "overloaded", "resource_exhausted", "recovered upstream error"],
|
||||
durationMinutes: 10,
|
||||
description: "Capacity and rate-limit responses are often temporary; start with a ten-minute cooldown and use another account.",
|
||||
},
|
||||
{
|
||||
statusCode: 500,
|
||||
keywords: ["capacity", "overloaded", "temporarily unavailable", "temporary", "upstream", "recovered upstream error"],
|
||||
durationMinutes: 10,
|
||||
description: "Transient upstream server failures should start with a ten-minute cooldown and prefer another account.",
|
||||
},
|
||||
{
|
||||
statusCode: 502,
|
||||
keywords: ["capacity", "overloaded", "temporarily unavailable", "temporary", "upstream", "bad gateway", "upstream request failed", "unknown error", "context deadline exceeded", "context canceled", "websocket dial", "handshake response", "recovered upstream error"],
|
||||
durationMinutes: 30,
|
||||
description: "Gateway upstream failures, including recovered upstream error wrappers, should cool down longer.",
|
||||
},
|
||||
{
|
||||
statusCode: 413,
|
||||
keywords: ["openai_error", "payload too large", "request too large", "context length", "context window", "maximum context"],
|
||||
durationMinutes: 30,
|
||||
description: "Large-context upstream failures should cool down the selected account so a larger-context channel can handle the request.",
|
||||
},
|
||||
{
|
||||
statusCode: 503,
|
||||
keywords: ["capacity", "overloaded", "temporarily unavailable", "temporary", "upstream", "recovered upstream error", "model_not_found", "no available channel for model"],
|
||||
durationMinutes: 30,
|
||||
description: "Service unavailable and upstream model-routing failures should cool down longer than one-off transient failures.",
|
||||
},
|
||||
{
|
||||
statusCode: 504,
|
||||
keywords: ["gateway timeout", "timeout", "upstream", "upstream request failed", "unknown error", "context deadline exceeded", "context canceled", "recovered upstream error"],
|
||||
durationMinutes: 30,
|
||||
description: "Gateway timeout responses should cool down the selected account so another account can handle the next request.",
|
||||
},
|
||||
{
|
||||
statusCode: 524,
|
||||
keywords: ["timeout", "a timeout occurred", "cloudflare", "gateway timeout", "upstream", "upstream request failed", "unknown error", "context deadline exceeded", "context canceled", "recovered upstream error"],
|
||||
durationMinutes: 30,
|
||||
description: "Cloudflare 524 timeout responses should cool down the selected account so another account can handle the next request.",
|
||||
},
|
||||
{
|
||||
statusCode: 529,
|
||||
keywords: ["capacity", "overloaded", "temporarily unavailable", "temporary", "recovered upstream error"],
|
||||
durationMinutes: 30,
|
||||
description: "Provider overloaded responses should cool down longer than generic transient failures and use another account.",
|
||||
},
|
||||
],
|
||||
enabled: false,
|
||||
rules: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1542,8 +1475,8 @@ function compactProfile(profile: CodexProfile): Record<string, unknown> {
|
||||
trustUpstream: profile.trustUpstream,
|
||||
capacity: profile.capacity,
|
||||
loadFactor: profile.loadFactor,
|
||||
tempUnschedulableEnabled: profile.tempUnschedulable.enabled && profile.tempUnschedulable.rules.length > 0,
|
||||
tempUnschedulableRuleCount: profile.tempUnschedulable.enabled ? profile.tempUnschedulable.rules.length : 0,
|
||||
tempUnschedulableEnabled: profile.tempUnschedulable.enabled,
|
||||
tempUnschedulableRuleCount: profile.tempUnschedulable.rules.length,
|
||||
apiKeyPresent: profile.apiKey !== null && profile.apiKey.length > 0,
|
||||
ok: profile.ok,
|
||||
error: profile.error,
|
||||
@@ -1552,24 +1485,23 @@ function compactProfile(profile: CodexProfile): Record<string, unknown> {
|
||||
}
|
||||
|
||||
export function renderSub2ApiTempUnschedulableCredentials(policy: CodexTempUnschedulablePolicy): Record<string, unknown> {
|
||||
if (!policy.enabled) return {};
|
||||
return {
|
||||
temp_unschedulable_enabled: policy.enabled && policy.rules.length > 0,
|
||||
temp_unschedulable_rules: policy.enabled
|
||||
? policy.rules.map((rule) => ({
|
||||
error_code: rule.statusCode,
|
||||
keywords: [...rule.keywords],
|
||||
duration_minutes: rule.durationMinutes,
|
||||
description: rule.description ?? "",
|
||||
}))
|
||||
: [],
|
||||
temp_unschedulable_enabled: policy.enabled,
|
||||
temp_unschedulable_rules: policy.rules.map((rule) => ({
|
||||
error_code: rule.statusCode,
|
||||
keywords: [...rule.keywords],
|
||||
duration_minutes: rule.durationMinutes,
|
||||
description: rule.description ?? "",
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
function tempUnschedulableSummary(policy: CodexTempUnschedulablePolicy): Record<string, unknown> {
|
||||
return {
|
||||
enabled: policy.enabled && policy.rules.length > 0,
|
||||
ruleCount: policy.enabled ? policy.rules.length : 0,
|
||||
statusCodes: policy.enabled ? policy.rules.map((rule) => rule.statusCode) : [],
|
||||
enabled: policy.enabled,
|
||||
ruleCount: policy.rules.length,
|
||||
statusCodes: policy.rules.map((rule) => rule.statusCode),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3711,8 +3643,9 @@ def account_payload(profile, group_id):
|
||||
if upstream_user_agent:
|
||||
credentials["user_agent"] = upstream_user_agent
|
||||
temp_unschedulable = temp_unschedulable_credentials(profile)
|
||||
credentials["temp_unschedulable_enabled"] = temp_unschedulable["enabled"]
|
||||
credentials["temp_unschedulable_rules"] = temp_unschedulable["rules"]
|
||||
if temp_unschedulable["enabled"]:
|
||||
credentials["temp_unschedulable_enabled"] = True
|
||||
credentials["temp_unschedulable_rules"] = temp_unschedulable["rules"]
|
||||
return {
|
||||
"name": profile["accountName"],
|
||||
"notes": f"UniDesk-managed Codex profile {profile['profile']} from {profile['configFile']} and {profile['authFile']}; secret source={profile['apiKeySource']}; fingerprint={profile['apiKeyFingerprint']}.",
|
||||
@@ -4803,8 +4736,8 @@ def normalize_temp_unschedulable_credentials(credentials):
|
||||
"description": description,
|
||||
})
|
||||
return {
|
||||
"enabled": enabled and len(rules) > 0,
|
||||
"rules": rules if enabled else [],
|
||||
"enabled": enabled,
|
||||
"rules": rules,
|
||||
}
|
||||
|
||||
def summarize_temp_unschedulable_rules(rules):
|
||||
@@ -4819,6 +4752,8 @@ def summarize_temp_unschedulable_rules(rules):
|
||||
def success_body_reclassification_requirement():
|
||||
for name in sorted(EXPECTED_ACCOUNT_TEMP_UNSCHEDULABLE):
|
||||
expected = normalize_temp_unschedulable_credentials(EXPECTED_ACCOUNT_TEMP_UNSCHEDULABLE[name])
|
||||
if expected["enabled"] is not True:
|
||||
continue
|
||||
for rule in expected["rules"]:
|
||||
error_code = rule.get("error_code")
|
||||
keywords = rule.get("keywords") or []
|
||||
@@ -4844,6 +4779,8 @@ def model_routing_400_failover_requirement():
|
||||
preferred = ["暂不支持", "可用模型", "unsupported model", "model not supported", "does not support", "not supported", "model_not_found", "no available channel for model"]
|
||||
for name in sorted(EXPECTED_ACCOUNT_TEMP_UNSCHEDULABLE):
|
||||
expected = normalize_temp_unschedulable_credentials(EXPECTED_ACCOUNT_TEMP_UNSCHEDULABLE[name])
|
||||
if expected["enabled"] is not True:
|
||||
continue
|
||||
for rule in expected["rules"]:
|
||||
error_code = rule.get("error_code")
|
||||
keywords = rule.get("keywords") or []
|
||||
|
||||
Reference in New Issue
Block a user