Commit Graph

202 Commits

Author SHA1 Message Date
fawney19
0c5c6b3288 refactor: 提取模型可用性查询到独立模块 ModelAvailabilityQuery
Close #101

- 新增 src/services/model/availability.py,集中管理系统级模型可用性查询条件
- 重构 models_service.py,复用 ModelAvailabilityQuery 的查询方法
- 删除 find_model_by_id 的 provider_model_name 回退逻辑
- 支持 model_mappings 正则匹配(使用 check_model_allowed_with_mappings)
- 修复 test_auth.py 中缺少的 is_locked mock 属性
- 新增 ModelAvailabilityQuery 单元测试
2026-01-18 01:45:25 +08:00
fawney19
b98fc8497f feat: 自适应 RPM 未学习时不限制,改为碰壁学习策略
- 移除自适应模式的默认初始限制(RPMDefaults.INITIAL_LIMIT)
- 未学习到边界前不限制 RPM,让系统自由运行直到遇到 429
- 前端自适应 Key 显示学习到的值或"探测中"状态
- 批量余额查询改为并行执行,提升性能
2026-01-17 23:44:53 +08:00
fawney19
f002f8de03 feat: Key 删除时自动解除不再匹配的 GlobalModel 关联
- 新增 auto_disassociate_provider_by_key_whitelist 方法检测并解除关联
- 删除 Key 后检查 Provider 剩余 Key 白名单,移除不再匹配的 Model
- 前端删除密钥后并行刷新端点列表、模型列表和模型映射

Closes #102

Co-authored-by: AAEE86 <ppk0227@hotmail.com>
2026-01-17 22:05:09 +08:00
fawney19
c71027c466 feat: 添加 Provider Ops 扩展操作系统,支持余额监控
主要更改:
- 新增 Provider Ops 服务框架,支持通过架构配置执行余额查询等扩展操作
- 后端:添加 provider_ops 服务层和 API 路由
- 前端:添加 ProviderAuthDialog 组件配置认证信息
- 前端:添加 providerOps API 和认证模板系统

UI/组件优化:
- Input 组件:新增 masked 属性,使用 CSS 遮蔽敏感信息,避免触发密码管理器
- Pagination 组件:移除首页/末页/上下页按钮,改为页码跳转输入框
- KeyFormDialog:使用 masked 属性简化 API Key 输入逻辑
- ProviderManagement:重新设计表格布局,显示余额监控数据
2026-01-17 19:50:35 +08:00
fawney19
45f071abd9 fix: 在 Provider/Endpoint/Key 变更时清除 /v1/models 列表缓存
- 将 on_key_allowed_models_changed 改为 async 函数
- 在 Provider/Endpoint/Key 的增删改操作后调用 invalidate_models_list_cache
- 优化 invalidate_models_list_cache 使用 delete_pattern 通配符删除
2026-01-16 19:42:35 +08:00
fawney19
019e148ddb refactor: 将上游模型缓存从前端迁移到后端 Redis
- 后端:定时任务刷新时将上游模型写入 Redis 缓存
- 后端:provider_query 优先从缓存读取,支持 force_refresh 参数
- 后端:auto_fetch_models 开启时改为同步获取,确保前端能立即看到数据
- 前端:移除本地缓存,只保留并发请求去重逻辑
- 前端:KeyAllowedModelsEditDialog 添加刷新上游模型按钮
2026-01-16 19:10:59 +08:00
fawney19
d5d74339dd refactor: 将 global_priority 和 rate_multiplier 改为按 API 格式配置
- 新增 global_priority_by_format 字段,支持按 API 格式设置全局优先级
- 移除已废弃的 rate_multiplier 字段,统一使用 rate_multipliers
- 移除已废弃的 timeout 字段(providers 和 provider_endpoints 表)
- 更新调度器以支持按格式的优先级排序
- 同步更新前后端类型定义和 API 接口
- 添加数据库迁移脚本,自动迁移现有数据
2026-01-16 17:53:27 +08:00
fawney19
6c98816f9f feat: 实现功能模块系统,支持模块的动态注册与启用控制
- 新增 ModuleRegistry 核心,支持模块注册、可用性检查和启用状态管理
- 新增模块管理 API(管理端和公共端),提供模块状态查询和启用控制
- 将 LDAP 功能迁移到模块系统,支持通过环境变量和数据库配置控制
- 前端新增模块管理页面和 store,支持模块启用/禁用操作
- 路由守卫集成模块状态检查,未激活模块的页面自动重定向
- 面包屑导航支持模块配置页面的层级显示
- Switch 组件新增 disabled 属性支持
2026-01-16 16:14:12 +08:00
fawney19
50343d5459 refactor: 移除 Provider/Endpoint 级别的 timeout 配置,改用全局环境变量
- 废弃 Provider.timeout 和 ProviderEndpoint.timeout 字段(保留数据库列以兼容)
- 非流式请求超时由 HTTP_REQUEST_TIMEOUT 环境变量控制(默认 300 秒)
- 流式请求首字节超时由 STREAM_FIRST_BYTE_TIMEOUT 环境变量控制(默认 30 秒)
- 移除前端表单中的超时配置输入框
- 简化 settings.py 中的 TTFB 超时解析逻辑
- 更新 API 请求/响应模型,移除 timeout 字段
- 更新导入导出功能,不再包含 timeout 配置
2026-01-16 13:08:39 +08:00
fawney19
e6a31a61db fix: 增强嵌入式错误的状态码提取与处理
- ParsedResponse 新增 embedded_status_code 字段存储嵌套状态码
- 新增 _extract_embedded_status_code 函数支持从多种格式提取状态码
- 非流式响应增加嵌套错误检测逻辑
- 统一使用 embedded_status_code 替代从 error_type 解析数字的方式
- fallback_orchestrator 使用嵌入式状态码进行错误记录
2026-01-16 11:01:05 +08:00
fawney19
8e11f3864a feat: 添加 API Key 锁定功能和请求头规则系统
1. API Key 锁定功能
- 管理员可锁定/解锁用户的 API Key
- 锁定后用户无法使用、修改或删除该 Key
- 前端显示锁定状态并禁用相关操作

2. 请求头规则系统
- 将 endpoint.headers 升级为 header_rules
- 支持 set(设置)、drop(删除)、rename(重命名)操作
- 前端提供可视化规则编辑界面
- 包含数据迁移脚本

Close #37 Close #86 Close #88
2026-01-16 01:18:54 +08:00
fawney19
ea45918561 refactor: 统一请求头处理逻辑到 headers.py
- 新增 src/core/headers.py 集中管理头部处理函数
- 扩展 api_format_metadata.py 添加 extra_headers 和 protected_keys 配置
- 将各 adapter 中重复的头部方法提取到基类,统一调用 headers.py
- 移除 transport.py 中未使用的 build_provider_headers 函数
- 添加 headers 模块的单元测试
2026-01-15 22:25:56 +08:00
fawney19
dd387735d4 feat: LDAP 用户隐藏密码修改功能并应用默认配额
- /me API 返回 auth_source 字段
- 前端 Settings 页面对 LDAP 用户隐藏密码修改卡片
- LDAP 用户首次登录创建时使用系统默认配额

Close #98
2026-01-15 17:57:58 +08:00
fawney19
a223819dd7 refactor: 提取正则工具模块并清理废弃代码
前端:
- 新增 model-mapping-regex.ts 工具模块,统一正则验证和 LRU 缓存
- ModelMappingsTab/RoutingTab 重构为使用 computed 缓存匹配结果
- 移除多个组件中未使用的变量和函数
- 添加 HTMLImageElement/HTMLIFrameElement 到 ESLint 全局类型
- 修复 vitest 需要 --experimental-require-module 的问题

后端:
- 移除废弃的异步数据库支持 (get_async_db, AsyncSession)
- 将 async_utils 从 database/ 迁移到 utils/
- 改进 database.py 类型标注
- 修复 email 模块的 aiosmtplib 可选导入类型问题
2026-01-15 17:03:19 +08:00
fawney19
0d26fd8c5a fix(usage): 修复活跃请求中成本字段为 0 时被错误置为 None 的问题
将 actual_cost 和 rate_multiplier 的判断条件从 `if value else None`
改为 `if value is not None else None`,确保数值 0 不会被误判为 False
2026-01-15 13:40:52 +08:00
fawney19
76f648b4eb feat(usage): 活跃请求轮询增加缓存与成本字段
- 后端 getActiveRequests 返回新增 cache_creation/read_input_tokens、actual_cost、rate_multiplier
- 前端轮询时同步更新这些字段到记录中
- 优化刷新逻辑:全局刷新开启时停止1秒轮询,关闭时恢复
2026-01-15 12:13:47 +08:00
fawney19
514bf7e3ed feat(usage): 改进请求追踪与缓存预热
- 区分请求重试与故障转移:新增 has_retry 标识亲和缓存重试
- 修正候选 TTFB 计算:记录候选自身的首字节时间而非全局时间
- Streaming 状态同步 rate_multiplier,支持按 API 格式配置
- 新增缓存预热服务:启动时预热仪表盘统计、热力图、每日统计
- 优化缓存 TTL 配置:仪表盘统计 2 分钟、热力图和每日统计 10 分钟
- 自动刷新间隔从 10 秒调整为 5 秒
2026-01-15 11:45:46 +08:00
fawney19
24b65d76b5 feat(models): Key 白名单变更时自动关联 GlobalModel
- Key 创建/更新/自动获取模型后,检查 allowed_models 变化
- 根据 GlobalModel 的映射规则自动创建 Provider 关联
- 添加缓存失效机制确保映射规则能匹配新白名单
2026-01-15 10:32:48 +08:00
fawney19
4835ca13f5 feat(models): 模型映射支持按提供商分组并自动关联
- 映射匹配结果按提供商分组显示,支持单个关联
- 保存映射规则时自动批量关联未关联的提供商
- 优化模型详情加载逻辑,并行获取最新数据
- 移除冗余的调度器日志输出
2026-01-15 02:11:44 +08:00
fawney19
0348b7d915 refactor: 废弃 rate_multiplier 字段,改进成本倍率回退逻辑
- 在前后端模型中为 rate_multiplier 添加 @deprecated 标记
- 修复 rate_multipliers 回退逻辑:当 rate_multipliers 存在但未配置当前格式时使用 1.0
- ModelMappingsTab: 删除映射后自动保存,简化空状态提示
- ModelManagement: 添加 refreshModel 事件在映射更新后刷新模型数据
- CacheAwareScheduler: 添加映射匹配调试日志,移除 candidate_models 限制
2026-01-14 21:07:28 +08:00
fawney19
bec9c3a989 refactor: 将模型别名(alias)统一重命名为模型映射(mapping)
- 重命名 API: alias-mapping-preview -> mapping-preview
- 重命名类型: AliasMatchedModel -> MappingMatchedModel 等
- 重命名字段: model_aliases -> model_mappings, alias_matched_model -> mapping_matched_model
- 重命名前端组件: ModelAliasesTab -> ModelMappingsTab
- 重命名验证函数: validate_model_aliases -> validate_model_mappings
- 同步更新相关测试用例
- 补充 ModelService 中新增/批量创建模型时的缓存失效逻辑
2026-01-14 19:35:41 +08:00
fawney19
b272109055 refactor(model-permissions): 简化 allowed_models 为纯列表格式
移除按 API 格式区分的字典模式(Dict[str, List[str]]),统一使用简单列表格式。

- 删除 normalize_allowed_models 的 api_format 参数
- 删除 check_model_allowed 的 api_format 参数
- 简化 merge_allowed_models 为直接列表交集
- 移除前端的字典模式兼容代码和警告 UI
- 删除 is_format_mode、convert_to_format_mode 等辅助函数
2026-01-14 17:57:21 +08:00
fawney19
0ed053b02f fix(model-resolution): 修复模型解析优先级和别名匹配范围
- 调整 ModelCacheService 解析优先级:优先直接匹配 GlobalModel.name,
  避免被 provider_model_name 误导到错误的 GlobalModel
- 为 check_model_allowed_with_aliases 新增 candidate_models 参数,
  限制别名匹配只能落到 Provider 实际配置的模型名上
- 对 allowed_set 排序以确保别名匹配结果的确定性
- 调整 HTTP_READ_TIMEOUT 默认值从 300s 改为 60s
- 优化 ModelMappingTab 组件布局,将正则表达式提取到 Key 级别展示
- 补充 .env.example 超时配置文档
2026-01-14 17:29:04 +08:00
fawney19
ec3c5994d9 fix(orchestration): 处理流式响应中的嵌入式错误
- 新增对 EmbeddedErrorException 的处理逻辑
- 客户端错误(如 prompt too long)停止重试并抛出异常
- 服务端错误允许重试或故障转移
- 将 _is_client_error 改为公开方法 is_client_error
2026-01-14 15:43:02 +08:00
fawney19
5e4099a588 fix(proxy): 新增响应头过滤函数,避免透传不兼容的上游头
添加 filter_proxy_response_headers 函数过滤 content-length、content-encoding、
transfer-encoding 等 hop-by-hop 和 body-dependent 头,防止客户端解码失败。
统一在 chat_handler_base、cli_handler_base、stream_telemetry 和 usage recorder
中使用该函数处理响应头透传。
2026-01-14 14:50:33 +08:00
fawney19
a8813cfb89 feat(keys): 新增密钥自动获取模型功能
- 添加 auto_fetch_models 字段支持定时从上游 API 获取可用模型
- 添加 locked_models 字段支持锁定模型,刷新时不会被删除
- 新增 ModelFetchScheduler 调度器定期执行模型获取任务
- 前端 KeyFormDialog 添加自动获取模型开关
- 前端 KeyAllowedModelsEditDialog 支持模型锁定操作
- ProviderDetailDrawer 显示密钥同步状态
- 数据库迁移添加新字段
2026-01-14 13:12:19 +08:00
fawney19
85decd7487 feat: 实现 GlobalModel 别名匹配系统
主要更改:
- GlobalModel 支持 model_aliases 配置,允许使用正则表达式定义别名规则
- Provider Key 的 allowed_models 现在可以通过别名规则匹配 GlobalModel
- 新增 ModelAliasesTab 组件用于管理模型别名配置
- Provider 详情页新增别名映射预览功能,展示 Key 白名单与 GlobalModel 别名的匹配关系
- 路由预览 API 返回 Key 的 allowed_models 信息

安全特性:
- 使用 regex 库的原生超时保护(100ms)防止 ReDoS 攻击
- 别名规则数量限制(50 条/模型)和长度限制(200 字符)
- 别名映射预览 API 添加超时保护和结果截断

其他改进:
- GlobalModel 更新/删除时使用行级锁防止并发竞态
- 缓存失效逻辑优化,支持异步清理和正则缓存清空
- 路由 Tab 布局重构,使用 flexbox 替代绝对定位
2026-01-13 16:04:15 +08:00
fawney19
09e0f594ff refactor: 重构限流系统和健康监控,支持按 API 格式区分
- 将 adaptive_concurrency 重命名为 adaptive_rpm,从并发控制改为 RPM 控制
- 健康监控器支持按 API 格式独立管理健康度和熔断器状态
- 新增 model_permissions 模块,支持按格式配置允许的模型
- 重构前端提供商相关表单组件,新增 Collapsible UI 组件
- 新增数据库迁移脚本支持新的数据结构
2026-01-10 18:48:35 +08:00
fawney19
ea35efe440 perf: 优化 HTTP 客户端连接池复用
- 新增 get_proxy_client() 方法,相同代理配置复用同一客户端
- 添加 LRU 淘汰策略,代理客户端上限 50 个防止内存泄漏
- 新增 get_default_client_async() 异步线程安全版本
- 使用模块级锁避免类属性初始化竞态条件
- 优化 ConcurrencyManager 使用 Redis MGET 批量获取减少往返
- 添加 get_pool_stats() 连接池统计信息接口
2026-01-08 13:34:59 +08:00
fawney19
1521ce5a96 feat: 添加负载均衡调度模式
- 新增 load_balance 调度模式,同优先级内随机轮换
- 前端支持三种调度模式切换:缓存亲和、负载均衡、固定顺序
2026-01-08 03:20:04 +08:00
fawney19
d378630b38 perf: 添加多层缓存优化减少数据库查询
- 新增 ProviderCacheService 缓存 Provider 和 ProviderAPIKey 数据
- SystemConfigService 添加进程内缓存(TTL 60秒)
- API Key last_used_at 更新添加节流策略(60秒间隔)
- HTTP 连接池配置改为可配置,支持根据 Worker 数量自动计算
- 前端优先级管理改用 health_score 显示健康度
2026-01-08 02:34:59 +08:00
fawney19
e33d5b952c feat: 所有计费模板支持按次计费,调整端点默认重试次数为 2
- 为 Claude、OpenAI、豆包、Gemini 计费模板添加 request 维度
- 支持通过 price_per_request 配置按次计费(如图片生成模型)
- 将端点 max_retries 默认值从 3 改为 2(请求一次 + 重试一次)
2026-01-07 20:15:30 +08:00
fawney19
4345ac2ba2 fix: 添加系统配置项默认值,避免前端获取配置时报错
添加以下配置项到 DEFAULT_CONFIGS:
- email_suffix_mode/email_suffix_list (邮箱后缀限制)
- audit_log_retention_days (审计日志保留天数)
- smtp_* (SMTP 邮件服务器配置)
2026-01-07 20:01:17 +08:00
fawney19
a12b43ce5c refactor: 清理数据库字段命名歧义
- users 表:重命名 allowed_endpoints 为 allowed_api_formats(修正历史命名错误)
- api_keys 表:删除 allowed_endpoints 字段(未使用的功能)
- providers 表:删除 rate_limit 字段(与 rpm_limit 重复)
- usage 表:重命名 provider 为 provider_name(避免与 provider_id 外键混淆)

同步更新前后端所有相关代码
2026-01-07 19:53:32 +08:00
fawney19
fbe303a3cd fix: 补充 cost.py 中 Provider 未实现模型时的 else 分支处理 2026-01-07 16:13:53 +08:00
fawney19
0061fc04b7 feat: 添加访问令牌管理功能并升级至 0.2.4
- 新增 Management Token(访问令牌)功能,支持创建、更新、删除和管理
- 前端添加访问令牌管理页面,支持普通用户和管理员
- 后端实现完整的令牌生命周期管理 API
- 添加数据库迁移脚本创建 management_tokens 表
- Nginx 配置添加 gzip 压缩,优化响应传输
- Dialog 组件添加 persistent 属性,防止意外关闭
- 为管理后台 API 添加详细的中文文档注释
- 简化多处类型注解,统一代码风格
2026-01-07 14:55:07 +08:00
fawney19
00562dd1d4 feat: 添加 LDAP 认证支持
- 新增 LDAP 服务和 API 接口
- 添加 LDAP 配置管理页面
- 登录页面支持 LDAP/本地认证切换
- 数据库迁移支持 LDAP 相关字段
2026-01-06 14:38:42 +08:00
fawney19
35e29d46bd refactor: 抽取统一计费模块,支持配置驱动的多厂商计费
- 新增 src/services/billing/ 模块,包含计费计算器、模板和使用量映射
- 将 ChatAdapterBase 和 CliAdapterBase 中的计费逻辑重构为调用 billing 模块
- 为每个 adapter 添加 BILLING_TEMPLATE 类属性,指定计费模板
- 支持 Claude/OpenAI/Gemini 三种计费模板,支持阶梯计费和缓存 TTL 定价
- 新增 tests/services/billing/ 单元测试
2026-01-05 16:48:59 +08:00
fawney19
e5f12fddd9 feat: 流式预读增强与自适应并发算法优化
流式预读增强:
- 新增预读字节上限(64KB),防止无换行响应导致内存增长
- 预读结束后检测非 SSE 格式的错误响应(HTML 页面、纯 JSON 错误)
- 抽取 check_html_response 和 check_prefetched_response_error 到 utils.py

自适应并发算法优化(边界记忆 + 渐进探测):
- 缩容策略:从乘性减少改为边界 -1,一次 429 即可收敛到真实限制附近
- 扩容策略:普通扩容不超过已知边界,探测性扩容可谨慎突破(每次 +1)
- 仅在并发限制 429 时记录边界,避免 RPM/UNKNOWN 类型覆盖
2026-01-05 12:17:45 +08:00
fawney19
4fa9a1303a feat: 优化首字时间和 streaming 状态的记录时序
改进 streaming 状态更新机制:
- 统一在首次输出时记录 TTFB 并更新 streaming 状态
- 重构 CliMessageHandlerBase 中的状态更新逻辑,消除重复
- 确保 provider/key 信息在 streaming 状态更新时已可用

前端改进:
- 添加 first_byte_time_ms 字段支持
- 管理员接口支持返回 provider/api_key_name 字段
- 优化活跃请求轮询逻辑,更准确地判断是否需要刷新完整数据

数据库与 API:
- UsageService.get_active_requests_status 添加 include_admin_fields 参数
- 管理员接口调用时启用该参数以获取额外信息
2026-01-05 10:31:34 +08:00
fawney19
b34cfb676d fix: streaming 状态更新时传递 provider 相关 ID 信息
在 update_usage_status 方法中增加 provider_id、provider_endpoint_id
和 provider_api_key_id 参数,确保流式请求进入 streaming 状态时
能正确记录这些字段。
2026-01-05 09:12:03 +08:00
fawney19
3064497636 refactor: 改进上游错误消息的提取和传递
- 新增 extract_error_message 工具函数,统一错误消息提取逻辑
- 在 HTTPStatusError 异常上附加 upstream_response 属性,保留原始错误
- 优先使用上游响应内容作为错误消息,而非异常字符串表示
- 移除错误消息的长度限制(500/1000 字符)
- 修复边界条件检查,使用 startswith 匹配 "Unable to read" 前缀
- 简化 result.py 中的条件判断逻辑
2026-01-05 03:18:55 +08:00
fawney19
e7db76e581 refactor: API Key 过期时间改用日期选择器,rate_limit 支持无限制
- 前端:将过期时间设置从"天数输入"改为"日期选择器",更直观
- 后端:新增 expires_at 字段(ISO 日期格式),兼容旧版 expire_days
- rate_limit 字段现在支持 null 表示无限制,移除默认值 100
- 解析逻辑:过期时间设为当天 UTC 23:59:59.999999
2026-01-05 02:16:16 +08:00
fawney19
689339117a refactor: 提取 ModelMultiSelect 组件并支持失效模型检测
- 新增 ModelMultiSelect 组件,支持显示和移除已失效的模型
- 新增 useInvalidModels composable 检测 allowed_models 中的无效引用
- 重构 StandaloneKeyFormDialog 和 UserFormDialog 使用新组件
- 补充 GlobalModel 删除逻辑的设计说明注释
2026-01-05 01:20:58 +08:00
fawney19
b202765be4 perf: 优化流式响应 TTFB,将数据库状态更新移至 yield 后执行
- StreamUsageTracker: 先 yield 首个 chunk 再更新 streaming 状态
- EnhancedStreamUsageTracker: 同步添加 TTFB 记录和状态更新逻辑
- 确保客户端首字节响应不受数据库操作延迟影响
2026-01-05 00:13:23 +08:00
fawney19
3bbf3073df feat: 所有 Provider 失败时透传上游错误信息
- FallbackOrchestrator 在所有候选组合失败后保留最后的错误信息
- 从 httpx.HTTPStatusError 提取上游状态码和响应内容
- ProviderNotAvailableException 携带上游错误信息
- ErrorResponse 在返回错误时透传上游状态码和响应
2026-01-04 23:50:15 +08:00
fawney19
f46aaa2182 debug: 添加 streaming 状态更新时 provider 为空的调试日志
- base_handler: 更新 streaming 状态时检测并记录 provider 为空的情况
- cli_handler_base: 修复预读数据为空时未更新 streaming 状态的问题
- usage service: 检测状态变为 streaming 但 provider 仍为 pending 的异常
2026-01-04 23:16:01 +08:00
fawney19
a2f33a6c35 perf: 拆分热力图为独立接口并添加 Redis 缓存
- 新增独立热力图 API 端点 (/api/admin/usage/heatmap, /api/users/me/usage/heatmap)
- 添加 Redis 缓存层 (5分钟 TTL),减少数据库查询
- 用户角色变更时清除热力图缓存
- 前端并行加载统计数据和热力图,添加加载/错误状态显示
- 修复 cache_decorator 缺少 JSON 解析错误处理的问题
- 更新 docker-compose 启动命令提示
2026-01-04 22:42:58 +08:00
fawney19
c3a5878b1b feat: 优化用量查询分页和热力图性能
- 用量查询接口添加 limit/offset 分页参数支持
- 热力图统计从实时查询 Usage 表改为读取预计算的 StatsDaily/StatsUserDaily 表
- 修复 avg_response_time_ms 为 0 时被错误跳过的问题
2026-01-04 18:02:47 +08:00
RWDai
3e4309eba3 Enhance LDAP auth config handling 2026-01-04 16:27:02 +08:00