Conversation
- 合并上游可视化配置编辑器功能 - 合并认证文件索引显示功能 - 合并日志加载优化 - 保留本地自定义后端监控 API 架构
…de-quota Revert "feat(ui): added claude quota display"
…ing to Auth Files page
- 将 totalTokens 字段替换为 cachedTokens,展示缓存 token 数据 - 新增 formatCompactTokenNumber 函数,支持 K/M 紧凑格式显示 - 调整表格列宽适配新字段,优化数值对齐显示
…ons and unused modal types
合并上游 main 分支,包含俄语国际化、Kimi OAuth、UI 重构、 类型安全加固等更新。保留本地 Kiro OAuth 功能,同时引入 上游新增的类型安全工具函数。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 各监控组件(KpiCards, ModelDistribution, DailyTrend等)改为调用服务端聚合API - MonitorPage 移除客户端数据聚合逻辑,大幅简化 - monitor.ts 工具函数移除 UsageData 依赖和前端时间过滤 - RequestLogs 修复选中筛选后下拉选项只剩一项的 bug
Add Claude quota section to the Quota Management page, using the Anthropic OAuth usage API (api.anthropic.com/api/oauth/usage) to display utilization across all rate limit windows (5-hour, 7-day, Opus, Sonnet, etc.) and extra usage credits.
Changes: - Add Kiro quota management with quota info display on quota page - Support quota refresh on Auth Files page for Kiro credentials - Display base quota and free trial quota separately - Reset time format as M/D HH:MM - Fix OAuthPage start_url renamed to startUrl - Add CLIProxyAPI and example to .gitignore Modified files: - .gitignore (modified) - src/components/quota/quotaConfigs.ts (modified) - src/i18n/locales/en.json (modified) - src/i18n/locales/ru.json (modified) - src/i18n/locales/zh-CN.json (modified) - src/pages/AuthFilesPage.tsx (modified) - src/pages/OAuthPage.tsx (modified) - src/types/quota.ts (modified) - src/utils/quota/constants.ts (modified) - src/utils/quota/parsers.ts (modified) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ptimization feat(ai-providers): 优化 OpenAI 编辑页 UI,支持批量与按 Key 单独测试模型连通性
feat(quota): add Claude OAuth usage quota detection
…ameters and ensure uniqueness fix(ai-providers): Optimize configuration synchronization logic in OpenAI editing layout
Adapted from upstream 243eaf2. Our loadKeyStats/refreshKeyStats already catch internally, but adding .catch(() => {}) at call sites prevents unhandled rejections if internals are refactored later.
- Show priority value on AuthFileCard when the credential has a priority field - Add sort dropdown (Default / A-Z Name / Priority) to the credentials list - Priority sort orders credentials from highest to lowest - Add i18n translations for zh-CN, en, and ru Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add note field to the credential field editor (PrefixProxyEditorModal) - Store note as a string in the credential JSON file - Display note on AuthFileCard with 2-line clamp for long text - Note is saved when non-empty, removed from JSON when cleared - Add i18n translations for zh-CN, en, and ru Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…vg icon refactor(CodexSection, ProviderNav, AiProvidersPage, OAuthPage): update icon imports to use new codex.svg
…o use SelectionCheckbox component
There was a problem hiding this comment.
Pull request overview
This PR introduces a flexible API key list type to allow api-keys YAML entries to be specified as either plain strings or objects (e.g., {api-key: "...", name: "..."}), and updates callers/tests to use the new type.
Changes:
- Add
FlexAPIKeyListwith custom YAML unmarshalling and switchSDKConfig.APIKeysto this type. - Update internal usages (config diffing, access provider registration, management handlers) to handle the new API key list type.
- Update tests to construct configs using
FlexAPIKeyList.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
internal/config/sdk_config.go |
Adds FlexAPIKeyList and changes SDKConfig.APIKeys to use it with YAML unmarshalling logic. |
sdk/config/config.go |
Re-exports FlexAPIKeyList for SDK consumers. |
internal/access/config_access/provider.go |
Casts FlexAPIKeyList to []string for key normalization/registration. |
internal/api/handlers/management/config_lists.go |
Adapts API key list management endpoints to work with FlexAPIKeyList. |
internal/watcher/diff/config_diff.go |
Casts API key lists to []string for trimmed deep-equality comparisons. |
internal/watcher/diff/config_diff_test.go |
Updates config construction to use FlexAPIKeyList. |
internal/api/server_test.go |
Updates test server config to use FlexAPIKeyList. |
sdk/cliproxy/service_usage_persistence_test.go |
Updates test config to use FlexAPIKeyList. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| func (l *FlexAPIKeyList) UnmarshalYAML(value *yaml.Node) error { | ||
| if value.Kind != yaml.SequenceNode { | ||
| return nil |
There was a problem hiding this comment.
FlexAPIKeyList.UnmarshalYAML returns nil when api-keys is not a YAML sequence. That means mis-typed configs like api-keys: "sk-..." (scalar) or other invalid shapes will silently produce an empty key list, which can effectively disable API-key auth (Manager.Authenticate returns nil when no providers are registered). Consider returning a non-nil error (or explicitly supporting scalar-as-single-key) so invalid config fails fast instead of silently weakening auth.
| return nil | |
| return &yaml.TypeError{ | |
| Errors: []string{"api-keys must be a YAML sequence"}, | |
| } |
| case yaml.MappingNode: | ||
| var obj struct { | ||
| Key string `yaml:"api-key"` | ||
| } | ||
| if err := node.Decode(&obj); err == nil { | ||
| if key := strings.TrimSpace(obj.Key); key != "" { | ||
| result = append(result, key) | ||
| } | ||
| } |
There was a problem hiding this comment.
In the mapping-node branch, YAML decode errors and missing/empty api-key values are silently ignored. This can lead to partially loaded key sets (or none) without any feedback, again risking unintended unauthenticated operation. Consider returning an error when a mapping entry cannot be decoded or when api-key is missing/blank, rather than skipping it.
| // FlexAPIKeyList is a []string that can unmarshal YAML entries in either plain | ||
| // string form ("sk-xxx") or object form ({api-key: "sk-xxx", name: "Alice"}). | ||
| // This allows the config file to store display names alongside keys without | ||
| // breaking the authentication logic, which only needs the key value. | ||
| type FlexAPIKeyList []string | ||
|
|
||
| func (l *FlexAPIKeyList) UnmarshalYAML(value *yaml.Node) error { | ||
| if value.Kind != yaml.SequenceNode { | ||
| return nil | ||
| } | ||
| result := make([]string, 0, len(value.Content)) | ||
| for _, node := range value.Content { | ||
| switch node.Kind { | ||
| case yaml.ScalarNode: | ||
| if key := strings.TrimSpace(node.Value); key != "" { | ||
| result = append(result, key) | ||
| } | ||
| case yaml.MappingNode: | ||
| var obj struct { | ||
| Key string `yaml:"api-key"` | ||
| } | ||
| if err := node.Decode(&obj); err == nil { | ||
| if key := strings.TrimSpace(obj.Key); key != "" { | ||
| result = append(result, key) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| *l = result | ||
| return nil | ||
| } |
There was a problem hiding this comment.
FlexAPIKeyList introduces new config parsing behavior (accepting scalar vs object items, trimming, and filtering). There are existing config loading tests in internal/config/*_test.go; please add test cases covering (1) string entries, (2) object entries with api-key (+ optional name), and (3) invalid shapes to ensure the desired error/behavior is locked in (especially because it affects authentication).
No description provided.