mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
fix(provider): 修复 Windsurf 原生工具桥接
This commit is contained in:
@@ -2684,9 +2684,31 @@ function isWindsurfUnavailableKey(key: EndpointAPIKey): boolean {
|
||||
return code === 'banned' || code === 'forbidden' || code === 'quarantined'
|
||||
}
|
||||
|
||||
function getPositiveQuotaNumber(value: unknown): number | undefined {
|
||||
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : undefined
|
||||
}
|
||||
|
||||
function windsurfCooldownHasPositiveReset(key: EndpointAPIKey): boolean {
|
||||
const quota = getQuotaSnapshotForProvider(key, 'windsurf')
|
||||
const rateLimit = quota?.rate_limit
|
||||
if (rateLimit && typeof rateLimit === 'object') {
|
||||
const retryAfterMs =
|
||||
getPositiveQuotaNumber(rateLimit.retry_after_ms)
|
||||
?? getPositiveQuotaNumber(rateLimit.retryAfterMs)
|
||||
if (retryAfterMs !== undefined) return true
|
||||
}
|
||||
|
||||
const rateLimitWindow = getQuotaWindow(quota, 'rate_limit')
|
||||
return (
|
||||
getPositiveQuotaNumber(rateLimitWindow?.reset_seconds) !== undefined
|
||||
|| getPositiveQuotaNumber(rateLimitWindow?.reset_at) !== undefined
|
||||
)
|
||||
}
|
||||
|
||||
function isWindsurfExhaustedKey(key: EndpointAPIKey): boolean {
|
||||
const code = String(getQuotaSnapshotForProvider(key, 'windsurf')?.code || '').trim().toLowerCase()
|
||||
return code === 'exhausted' || code === 'rate_limited' || code === 'rate_limit' || code === 'cooldown'
|
||||
if (code === 'cooldown') return windsurfCooldownHasPositiveReset(key)
|
||||
return code === 'exhausted' || code === 'rate_limited' || code === 'rate_limit'
|
||||
}
|
||||
|
||||
function getWindsurfQuotaStatusLabel(key: EndpointAPIKey): string {
|
||||
@@ -2694,7 +2716,8 @@ function getWindsurfQuotaStatusLabel(key: EndpointAPIKey): string {
|
||||
const label = quota?.label?.trim()
|
||||
if (label) return label
|
||||
const code = String(quota?.code || '').trim().toLowerCase()
|
||||
return code === 'rate_limited' || code === 'rate_limit' || code === 'cooldown' ? '速率受限' : '额度耗尽'
|
||||
if (code === 'cooldown') return '冷却中'
|
||||
return code === 'rate_limited' || code === 'rate_limit' ? '速率受限' : '额度耗尽'
|
||||
}
|
||||
|
||||
function getWindsurfModelPreview(key: EndpointAPIKey): string | null {
|
||||
|
||||
@@ -127,6 +127,16 @@ describe('providerKeyQuota', () => {
|
||||
},
|
||||
},
|
||||
}, 'windsurf')).toBe('冷却中')
|
||||
|
||||
expect(getQuotaDisplayText({
|
||||
status_snapshot: {
|
||||
quota: {
|
||||
provider_type: 'windsurf',
|
||||
code: 'cooldown',
|
||||
exhausted: false,
|
||||
},
|
||||
},
|
||||
}, 'windsurf')).toBe('冷却中')
|
||||
})
|
||||
|
||||
it('includes Windsurf quota windows and model availability in display text', () => {
|
||||
@@ -160,6 +170,44 @@ describe('providerKeyQuota', () => {
|
||||
},
|
||||
},
|
||||
}, 'windsurf')).toBe('日剩余 75.0% | 周剩余 50.0% | Prompt 剩余 12/20 | Flex 剩余 3/5 | 可用模型 7 个')
|
||||
|
||||
expect(getQuotaDisplayText({
|
||||
status_snapshot: {
|
||||
quota: {
|
||||
provider_type: 'windsurf',
|
||||
code: 'cooldown',
|
||||
label: '冷却中',
|
||||
exhausted: false,
|
||||
rate_limit: {
|
||||
limited: true,
|
||||
has_capacity: true,
|
||||
messages_remaining: -1,
|
||||
max_messages: -1,
|
||||
},
|
||||
allowed_models_count: 118,
|
||||
windows: [
|
||||
{
|
||||
code: 'daily',
|
||||
remaining_ratio: 0.99,
|
||||
},
|
||||
{
|
||||
code: 'weekly',
|
||||
remaining_ratio: 1,
|
||||
},
|
||||
{
|
||||
code: 'prompt',
|
||||
remaining_value: 100,
|
||||
limit_value: 100,
|
||||
},
|
||||
{
|
||||
code: 'rate_limit',
|
||||
reset_seconds: null,
|
||||
is_exhausted: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}, 'windsurf')).toBe('日剩余 99.0% | 周剩余 100.0% | Prompt 剩余 100/100 | 可用模型 118 个')
|
||||
})
|
||||
|
||||
it('uses Windsurf model availability when no quota window is present', () => {
|
||||
|
||||
@@ -76,6 +76,24 @@ function getQuotaWindow(
|
||||
return getQuotaWindows(quota).find(window => normalizeText(window.code)?.toLowerCase() === normalizedCode) ?? null
|
||||
}
|
||||
|
||||
function positiveNumber(value: unknown): number | null {
|
||||
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null
|
||||
}
|
||||
|
||||
function windsurfCooldownHasPositiveReset(quota: QuotaStatusSnapshot): boolean {
|
||||
const rateLimit = quota.rate_limit
|
||||
if (rateLimit && typeof rateLimit === 'object') {
|
||||
const retryAfterMs = positiveNumber(rateLimit.retry_after_ms) ?? positiveNumber(rateLimit.retryAfterMs)
|
||||
if (retryAfterMs != null) return true
|
||||
}
|
||||
|
||||
const rateLimitWindow = getQuotaWindow(quota, 'rate_limit')
|
||||
return (
|
||||
positiveNumber(rateLimitWindow?.reset_seconds) != null
|
||||
|| positiveNumber(rateLimitWindow?.reset_at) != null
|
||||
)
|
||||
}
|
||||
|
||||
function getQuotaWindowsByScope(
|
||||
quota: QuotaStatusSnapshot | null | undefined,
|
||||
scope: string,
|
||||
@@ -219,7 +237,10 @@ function getWindsurfQuotaText(quota: QuotaStatusSnapshot): string | null {
|
||||
if (code === 'banned' || code === 'forbidden' || code === 'quarantined') {
|
||||
return normalizeText(quota.label) || '账号不可用'
|
||||
}
|
||||
if (code === 'rate_limited' || code === 'rate_limit' || code === 'cooldown') {
|
||||
if (code === 'cooldown' && windsurfCooldownHasPositiveReset(quota)) {
|
||||
return normalizeText(quota.label) || '冷却中'
|
||||
}
|
||||
if (code === 'rate_limited' || code === 'rate_limit') {
|
||||
return normalizeText(quota.label) || '速率受限'
|
||||
}
|
||||
if (code === 'exhausted') {
|
||||
@@ -258,6 +279,10 @@ function getWindsurfQuotaText(quota: QuotaStatusSnapshot): string | null {
|
||||
|
||||
if (parts.length > 0) return parts.join(' | ')
|
||||
|
||||
if (code === 'cooldown') {
|
||||
return normalizeText(quota.label) || '冷却中'
|
||||
}
|
||||
|
||||
return normalizeText(quota.label)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user