- Add ClearAccountAffinity to mockGatewayCacheForPlatform,
openAIWSStateStoreTimeoutProbeCache, mockGatewayCacheForGemini
- Add allow_messages_dispatch field to groups/available contract test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Windows terminals may send request bodies in GBK encoding, causing
garbled prompts and upstream failures. Validate UTF-8 encoding in
readBody and return 400 for invalid encodings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pq driver treats []byte as bytea, not jsonb. Convert charJSON and
reqBody to *string before passing to ExecContext for character_info
and request_body JSONB columns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add async task management for Sora video/image generation with two
forwarding modes: OAuth (SDK) and API Key (HTTP upstream). Includes
background worker for status polling and 3-layer storage degradation
(S3 > local disk > upstream URL passthrough).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move both cards under a unified "配额限制" section wrapper for Anthropic
platform. Remove independent section wrappers from both components so
they render as plain rounded cards. Non-Anthropic apikey accounts get
their own quota section with just QuotaLimitCard.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
classifyByAffinityZone was running before filterByMinPriority, causing
high-priority accounts in the red zone to be removed before priority
filtering, allowing low-priority accounts in the green zone to be
selected instead. Move zone classification into the priority loop so
it operates within same-priority groups, with fallback to next priority
group when current group is entirely in the red zone.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- AffinityConfigCard redesigned to match QuotaLimitCard style (section title + toggle card)
- Moved from standalone section to quota area, visible for all Anthropic account types
- Green zone (base) allows empty = no limit, min=1 when set; yellow zone hidden when base unset
- Deduplicated affinity save logic in EditAccountModal (single block for all Anthropic types)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: Add AffinityZone type with GetAffinityBase/GetAffinityBuffer/GetAffinityZone
methods. Integrate classifyByAffinityZone into Layer 2 scheduling and red zone
check into Layer 1.6 affinity hit path. 17 unit tests covering all zone boundaries.
Frontend: Add AffinityConfigCard for base/buffer configuration in EditAccountModal.
Move affinity badge from status column to capacity column with zone-based coloring
(count/limit format). Extract CapacityBadge and QuotaBadge components to reduce
AccountCapacityCell from 444 to 215 lines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Anthropic OAuth/setup-token accounts are throttled by actual proxy
connection (host:port:username). Other platforms bypass the queue
entirely. Also adds unit tests for affinity and usage queue features.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New API: GET /accounts/:id/affinity-clients returns client list with
last_active timestamps from Redis ZSET scores
- New Lua script: get_affinity_clients_with_scores.lua uses ZREVRANGEBYSCORE
WITHSCORES to return both client IDs and their timestamps
- New frontend component: AffinityBadge.vue replaces inline badge with
hover popover that lazy-loads client details on first hover
- Shows client ID (monospace) + relative time (e.g. "3h ago")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Widen the per-group delay between Anthropic usage API calls from
1-1.5s to 1-2s to avoid upstream 429 rate limiting when multiple
accounts share the same proxy exit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pipeline mode only sends EVALSHA (no automatic fallback to EVAL).
If Redis restarts and script cache is lost, all pipeline Lua calls
silently fail with NOSCRIPT. Add ensureScriptLoaded() to pre-load
scripts before pipeline execution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously the count was only returned when Redis had data, causing
the badge to not display for accounts with zero affinity clients.
Now returns count=0 for all affinity-enabled accounts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GO-2026-4602 (os), GO-2026-4601 (net/url), GO-2026-4600 and
GO-2026-4599 (crypto/x509). The crypto/x509 fixes are only
available in go1.26.1+, not backported to go1.25.x.