Conversation
…aker Remove 3 recordEndpointFailure calls from response-handler streaming error paths (fake-200, non-200 HTTP, stream abort). These are key-level errors where the endpoint itself responded successfully. Only forwarder-level failures (timeout, network error) and probe failures should penalize the endpoint circuit breaker. Previously, a single bad API key could trip the endpoint breaker (threshold=3, open=5min), making ALL keys on that endpoint unavailable.
fix: 修复供应商克隆时因浅拷贝引用共享导致源供应商数据被意外污染的问题
* feat: 增强配置表单输入警告提示 * fix: 修复 expiresAt 显示与配额刷新输入边界 * fix: 修复 expiresAt 解析兜底并改善刷新间隔输入体验 * fix: 刷新间隔输入取整并复用 clamp --------- Co-authored-by: tesgth032 <tesgth032@users.noreply.github.com>
…udit (#773) * feat(circuit-breaker): endpoint circuit breaker default-off + 524 decision chain audit - Add ENABLE_ENDPOINT_CIRCUIT_BREAKER env var (default: false) to gate endpoint-level circuit breaker - Gate isEndpointCircuitOpen, recordEndpointFailure, recordEndpointSuccess, triggerEndpointCircuitBreakerAlert behind env switch - Add initEndpointCircuitBreaker() startup cleanup: clear stale Redis keys when feature disabled - Gate endpoint filtering in endpoint-selector (getPreferredProviderEndpoints, getEndpointFilterStats) - Fix 524 vendor-type timeout missing from decision chain: add chain entry with reason=vendor_type_all_timeout in forwarder - Add vendor_type_all_timeout to ProviderChainItem reason union type (both backend session.ts and frontend message.ts) - Add timeline rendering for vendor_type_all_timeout in provider-chain-formatter - Replace hardcoded Chinese strings in provider-selector circuit_open details with i18n keys - Add i18n translations for vendor_type_all_timeout and filterDetails (5 languages: zh-CN, zh-TW, en, ja, ru) - Enhance LogicTraceTab to render filterDetails via i18n lookup with fallback - Add endpoint_pool_exhausted and vendor_type_all_timeout to provider-chain-popover isActualRequest/getItemStatus - Add comprehensive unit tests for all changes (endpoint-circuit-breaker, endpoint-selector, provider-chain-formatter) * fix(i18n): fix Russian grammar errors and rate_limited translations - Fix Russian: "конечная точкаов" -> "конечных точек" (11 occurrences) - Fix Russian: "Ограничение стоимости" -> "Ограничение скорости" (rate_limited) - Fix zh-CN: "费用限制" -> "速率限制" (filterDetails.rate_limited) - Fix zh-TW: "費用限制" -> "速率限制" (filterDetails.rate_limited) - Add initEndpointCircuitBreaker() to dev environment in instrumentation.ts
…_BREAKER Make vendor type circuit breaker controlled by the same ENABLE_ENDPOINT_CIRCUIT_BREAKER switch as endpoint circuit breaker. When disabled (default), vendor type CB will never trip or block providers, resolving user confusion about "vendor type temporary circuit breaker" skip reasons in decision chain. Changes: - Add ENABLE_ENDPOINT_CIRCUIT_BREAKER check in isVendorTypeCircuitOpen() - Add switch check in recordVendorTypeAllEndpointsTimeout() - Add tests for switch on/off behavior Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: Key 并发上限默认继承用户限制 - RateLimitGuard:Key limitConcurrentSessions=0 时回退到 User limitConcurrentSessions\n- Key 配额/使用量接口:并发上限按有效值展示\n- 单测覆盖并发继承逻辑;补齐 probe 测试的 endpoint-circuit-breaker mock 导出\n- 同步更新 biome.json schema 版本以匹配当前 Biome CLI * docs: 补齐并发上限解析工具注释 * refactor: 合并 Key 限额查询并补充并发单测 - getKeyQuotaUsage/getKeyLimitUsage:通过 leftJoin 一次取回 User 并发上限,避免额外查询\n- 新增 resolveKeyConcurrentSessionLimit 单测,覆盖关键分支\n- 修复 vacuum-filter bench 中的 Biome 报错 * fix: my-usage 并发上限继承用户限制 - getMyQuota:Key 并发为 0/null 时回退到 User 并发上限,保持与 Guard/Key 配额一致\n- 新增单测覆盖 Key->User 并发继承 * test: 补齐 my-usage 并发继承场景 - MyUsageQuota.keyLimitConcurrentSessions 收敛为 number(0 表示无限制)\n- OpenAPI 响应 schema 同步为非 nullable\n- my-usage 并发继承测试补充 Key>0 与 User=0 场景 --------- Co-authored-by: tesgth032 <tesgth032@users.noreply.github.com>
Summary of ChangesHello @ding113, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This release, version 0.5.6, focuses on bolstering system resilience through refined circuit breaker mechanisms and improving the user experience with enhanced validation and clearer feedback in the UI. Key changes include the introduction of a configurable endpoint-level circuit breaker, intelligent inheritance for concurrent session limits, and more informative warnings for user and provider settings. These updates aim to provide a more robust and user-friendly platform by preventing cascading failures and guiding users with better input validation. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🧪 测试结果
总体结果: ✅ 所有测试通过 |
There was a problem hiding this comment.
Code Review
This pull request introduces a new version, v0.5.6, which brings several significant features and improvements. A new endpoint-level circuit breaker has been added, controlled by the ENABLE_ENDPOINT_CIRCUIT_BREAKER flag. This feature is well-implemented, including a startup cleanup mechanism for when it's disabled. The concurrent session limit logic has been improved to allow keys to inherit limits from their parent user, providing more flexible configuration. The user interface has been enhanced with several warnings for common configuration mistakes, such as invalid API key formats and potentially problematic quota lease settings. Additionally, the accuracy of the circuit breaker has been improved by correctly isolating endpoint health from key-level or application-level errors. The PR also includes extensive internationalization updates and a large number of new unit tests, which significantly increase the quality and robustness of the codebase. Overall, this is a high-quality pull request with well-designed features and important bug fixes. The code is clean, well-tested, and demonstrates good software engineering practices.
| export function InlineWarning({ children, className }: InlineWarningProps) { | ||
| return ( | ||
| <div | ||
| className={cn( |
There was a problem hiding this comment.
[Medium] [TYPE-MISSING-VALIDATION] InlineWarning component lacks ARIA attributes for screen reader accessibility
Why this is a problem: The InlineWarning component renders a visual warning (amber text + icon) but has no role="status" or aria-live="polite" attribute. Screen reader users will not be notified when these warnings appear. The existing codebase consistently uses role="alert" for form field error messages (see form-field.tsx:89, form-field.tsx:218, date-picker-field.tsx:158). Since this is a non-blocking warning (less urgent than an error), role="status" with aria-live="polite" is the appropriate pattern.
Suggested fix:
export function InlineWarning({ children, className }: InlineWarningProps) {
return (
<div
role="status"
aria-live="polite"
className={cn(
"flex items-start gap-1.5 text-xs text-amber-600 dark:text-amber-400",
className
)}
>
<AlertTriangle className="mt-0.5 h-3.5 w-3.5 shrink-0" aria-hidden="true" />
<span className="min-w-0">{children}</span>
</div>
);
}There was a problem hiding this comment.
Code Review Summary
This XL release PR (v0.5.6) introduces three well-structured feature areas: endpoint-level circuit breaker isolation, key concurrent session limit inheritance, and form input validation enhancements. The changes are architecturally sound with comprehensive test coverage. One accessibility issue was identified in the new InlineWarning component.
PR Size: XL
- Lines changed: 2434 (2261 additions, 173 deletions)
- Files changed: 67
Split suggestion: This XL PR bundles three independent feature areas. Future releases could benefit from splitting into separate PRs: (1) circuit breaker isolation, (2) concurrent limit inheritance, (3) form validation/UX enhancements. Each area has clean boundaries and independent test suites.
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 0 | 0 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 0 | 0 |
| Types | 0 | 0 | 1 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
High Priority Issues (Should Fix)
- [Medium] InlineWarning missing ARIA attributes (
src/components/ui/inline-warning.tsx:17): The newInlineWarningcomponent lacksrole="status"andaria-live="polite"attributes. The existing codebase consistently usesrole="alert"for form field feedback (seeform-field.tsx,date-picker-field.tsx). Since this is a non-blocking warning,role="status"witharia-live="polite"is the appropriate pattern. See inline comment for suggested fix.
Review Coverage
- Logic and correctness - Clean (circuit breaker isolation logic is sound; concurrent limit inheritance with
resolveKeyConcurrentSessionLimithandles edge cases well including NaN, Infinity, negatives) - Security (OWASP Top 10) - Clean (no injection vectors, no hardcoded secrets, proper input validation in api-key-warnings)
- Error handling - Clean (initEndpointCircuitBreaker properly logs and handles Redis failures; instrumentation try/catch blocks are appropriate)
- Type safety - One issue (InlineWarning accessibility, see above)
- Documentation accuracy - Clean (comments match code behavior; i18n strings added for all 5 languages)
- Test coverage - Adequate (new test files cover circuit breaker isolation, concurrent limit inheritance, deep copy safety, date input parsing, API key warnings, quota lease warnings)
- Code clarity - Good (structuredClone for deep copy in provider-form-context is a clean fix; parseYmdToLocalEndOfDay has proper round-trip validation)
Automated review by Claude AI
| timeline += ` ${icon} ${f.name} (${f.details || f.reason})\n`; | ||
| const detailsText = f.details | ||
| ? t(`filterDetails.${f.details}`) !== `filterDetails.${f.details}` | ||
| ? t(`filterDetails.${f.details}`) |
There was a problem hiding this comment.
[HIGH] [LOGIC-BUG] filterDetails translation fallback detection is wrong, causing raw i18n fallback keys to be rendered
Evidence:
- At
src/lib/utils/provider-chain-formatter.ts:415-419:const detailsText = f.details ? t(`filterDetails.${f.details}`) !== `filterDetails.${f.details}` ? t(`filterDetails.${f.details}`) : f.details : f.reason;
- This repo configures missing translations to fall back to a namespaced key. In
src/i18n/request.ts:40-42:getMessageFallback: ({ namespace, key }) => { return `${namespace}.${key}`; },
Why this is a problem: When a filterDetails.* key is missing (e.g. details values that are not IDs like "供应商已禁用"), t(...) becomes something like "provider-chain.filterDetails.供应商已禁用". That will always pass the current !== check and gets rendered, so the provider-chain timeline shows fallback keys instead of the intended raw detail text.
Suggested fix (use t.has() like LogicTraceTab does):
type ProviderChainTranslator = ((key: string, values?: Record<string, string | number>) => string) & {
has?: (key: string) => boolean;
};
// ...inside formatProviderTimeline(...)
const detailsText = f.details
? (() => {
const detailsKey = `filterDetails.${f.details}`;
return t.has?.(detailsKey) ? t(detailsKey) : f.details;
})()
: f.reason;There was a problem hiding this comment.
Code Review Summary
XL release PR touching proxy forwarding, endpoint/vendor-type circuit breaker behavior, UI forms, i18n messages, and a large set of tests. One user-visible regression was found in provider-chain timeline formatting where missing filterDetails.* translations render as namespaced fallback keys instead of the intended raw details.
PR Size: XL
- Lines changed: 2434
- Files changed: 67
- Suggested split (to make review/rollback safer):
- Endpoint circuit breaker toggle + init + endpoint selector changes + tests
- Vendor-type timeout reason + provider chain i18n updates + logs UI rendering
- Concurrent session limit inheritance (actions + rate-limit guard) + tests
- UI warnings (InlineWarning, UserForm expiry parsing, System settings warnings, API key warnings) + i18n
- Tooling/config changes (.env.example, biome schema bump, deploy scripts)
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 1 | 0 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 0 | 0 |
| Types | 0 | 0 | 0 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
Critical Issues (Must Fix)
None.
High Priority Issues (Should Fix)
src/lib/utils/provider-chain-formatter.ts:415-filterDetailstranslation check usest(key) !== key, but missing translations fall back to${namespace}.${key}in this repo, so unknown details render asprovider-chain.filterDetails.*instead of raw detail text.
Review Coverage
- Logic and correctness
- Security (OWASP Top 10)
- Error handling
- Type safety
- Documentation accuracy
- Test coverage
- Code clarity
Automated review by Codex AI
There was a problem hiding this comment.
- Identified open PR: #775
release v0.5.6(2261 additions / 173 deletions / 67 files) → size/XL label applied. - Left an inline review comment for a user-visible regression in provider-chain timeline i18n fallback handling at
src/lib/utils/provider-chain-formatter.ts:415(missingfilterDetails.*translations render asprovider-chain.filterDetails.*instead of raw details). - Submitted the required PR review summary via
gh pr review.
Summary
Release v0.5.6 — merges
devintomain. This release includes endpoint circuit breaker operational improvements (opt-in toggle, 524 decision chain visibility), a fix for Key concurrent session limit inheritance, enhanced configuration form warnings, and a provider clone deep-copy bug fix.Included PRs
Related Issues
Changes
Core: Endpoint Circuit Breaker (opt-in toggle)
ENABLE_ENDPOINT_CIRCUIT_BREAKER(defaultfalse) — endpoint-level CB is now opt-inisEndpointCircuitOpen,recordEndpointFailure,recordEndpointSuccess, andtriggerEndpointCircuitBreakerAlertare all no-opsinitEndpointCircuitBreaker) clears stale Redis keys and in-memory state when the feature is disabledisVendorTypeCircuitOpen,recordVendorTypeAllEndpointsTimeout) also respects this toggleendpoint-selectorskips circuit-open checks entirely when disabledrecordEndpointFailurefor stream aborts, fake-200s, or non-200 HTTP errors (these are key-level errors, not endpoint connectivity failures)Core: 524 Vendor-Type Timeout in Decision Chain
vendor_type_all_timeoutreason added toProviderChainItemtype andProxySessionprovider-chain-formatterrenders 524 vendor-type timeout with provider details, status code, error, and explanatory notefilterDetailsi18n section added forvendor_type_circuit_open,circuit_open,circuit_half_open,rate_limitedBug Fix: Key Concurrent Session Limit Inheritance (#769)
resolveKeyConcurrentSessionLimit(keyLimit, userLimit)utility inconcurrent-session-limit.tsProxyRateLimitGuard,getKeyQuotaUsage,getMyQuota, andgetKeysactionsBug Fix: Provider Clone Deep-Copy (#739)
createInitialStatein provider form context now usesstructuredClonebefore extracting fieldsRESET_FORMreducer deep-copiesdefaultInitialStateto prevent shared references after resetEnhancement: Configuration Form Warnings (#768)
InlineWarningUI component (inline-warning.tsx)api-key-warnings.ts,quota-lease-warnings.ts,date-input.tsSupporting Changes
deploy.sh,deploy.ps1) includeENABLE_ENDPOINT_CIRCUIT_BREAKER=falseLogicTraceTab: rendersfilterDetailswith i18n lookup and fallbackprovider-chain-popover: rendersvendor_type_all_timeoutentriesprovider-selector: minor formatting (no logic change)forwarder.ts: records 524 vendor-type timeout to decision chainTesting
Automated Tests Added/Updated
endpoint-circuit-breaker.test.ts— 6 new tests for disabled state (no-op behavior, stale state cleanup)vendor-type-circuit-breaker.test.ts— tests for disabled toggle behaviorendpoint-selector.test.ts— tests for skipping circuit check when disabledconcurrent-session-limit.test.ts— unit tests forresolveKeyConcurrentSessionLimitkey-quota-concurrent-inherit.test.ts— Key concurrent limit fallback to Usermy-usage-concurrent-inherit.test.ts—getMyQuotaconcurrent limit inheritanceprovider-form-clone-deep-copy.test.ts— deep-copy isolation for clone/edit/create modesapi-key-warnings.test.ts— API key warning detectionquota-lease-warnings.test.ts— quota/lease warning thresholdsdate-input.test.ts— date formatting and parsing utilitiesprovider-chain-formatter.test.ts—vendor_type_all_timeoutrenderingresponse-handler-endpoint-circuit-isolation.test.ts— verifies endpoint CB is NOT called for key-level errorsrate-limit-guard.test.ts— concurrent limit inheritance in proxy guarduser-form-expiry-clear-ui.test.tsx— updated to use locale-safe date formattingNew Environment Variables
ENABLE_ENDPOINT_CIRCUIT_BREAKERfalsetrue, endpoints with consecutive failures are temporarily blocked.Checklist
Description enhanced by Claude AI