- redis.getWeeklyOpusCost: read only usage:opus:weekly:* (remove claude fallback)
- weeklyClaudeCostInitService: write to usage:opus:weekly:* instead of claude
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- auth.js: keep 402 status code with Opus message
- redis.js: keep dual-cost tracking (rated/real) with opus key prefix, add setWeeklyOpusCost method
- apiKeyService.js: keep both imports, serviceRates handling, and 5-param recordOpusCost
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix updateApiKey to use JSON.stringify for permissions field
- Add comma-separated string handling in normalizePermissions
- Add frontend parsing for comma-separated permissions format
Fixes issue where selecting multiple permissions (e.g. Claude + OpenAI)
would be saved as "claude,openai" instead of '["claude","openai"]'
- message_start: nest fields inside 'message' object with type: 'message'
- content_block_delta: add type field to data
- message_delta: add type field to data
- message_stop: remove usage field, just return type
- Extract usage from message_delta instead of message_stop
Additional fixes for memory leaks:
- Bedrock stream: extract _apiKeyIdBedrock, _rateLimitInfoBedrock, _requestBodyBedrock
- Non-stream requests: extract variables at block start
- Non-stream service calls: use extracted variables
- Non-stream usage recording: use extracted variables
All async callbacks now use local variables instead of req.* references,
preventing the entire request object (including large req.body with images)
from being retained by closures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Additional memory optimizations:
- Set bodyString = null after req.write() in both stream and non-stream requests
- Use let instead of const for bodyString to allow nullifying
- Store non-stream originalBodyString in bodyStore to avoid closure capture
- Clean up bodyStore in finally block for non-stream requests
This prevents V8 closures (res.on handlers) from retaining large request
body strings until stream completion.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem:
- Stream response handlers (res.on) captured requestOptions in closures
- requestOptions contained originalBodyString (~800KB per request)
- These strings couldn't be GC'd until stream completed
- With concurrent requests, memory accumulated rapidly
Solution:
- Store request body strings in this.bodyStore Map with unique ID
- Pass only bodyStoreId in requestOptions (not the 800KB string)
- Closures capture small ID, not large string
- Clean up bodyStore on request completion (success/error/timeout)
- Extract needed values before closures to avoid capturing body object
为 AWS Bedrock 服务添加 Claude 4.5 系列模型的映射支持,包括:
- Claude 4.5 Opus (claude-opus-4-5)
- Claude 4.5 Sonnet (claude-sonnet-4-5)
- Claude 4.5 Haiku (claude-haiku-4-5)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 3.5 <noreply@anthropic.com>