fuzhengwei / fuzhengwei/WaLiAPI
配额 429 错误体按端点协议返回并携带 used/limit;两轨配额记账口径合一 + 递增封顶
- Dominant language
- Rust
- Stars
- 128
- Forks
- 39
- Avg merge
- 15h 25m
- Merged PRs (30d)
- 44
Description
### 现状(如实声明)
五端点(chat / messages / responses / embeddings / models)内联检查与 `route_plan::authorize_request` 的配额拦截**从 v0.1.x 起就存在**,且有现成测试。本 issue **不引入配额强制**,只解决四个残余缺口:
1. 429 错误体 message 均为干瘪的 "Quota exceeded",不携带 used/limit 数值——使用方与管理员无从得知差多少;
2. chat 端点 429 是纯文本,而 responses/embeddings 返回 OpenAI JSON、messages 返回 Anthropic JSON——同一把 Key 超限在不同端点得到不同形状,客户端解析必须分叉;
3. legacy 转发轨(proxy 循环)只在上游返回真实 usage 时递增配额——上游不回 usage 时该轨已算好的本地估算值只写日志不入账,与新轨(endpoint_executor 有估算兜底)口径不一致,legacy 轨系统性少记;
4. 递增是无封顶纯加法,并发窗口内 quota_used 可越过 limit。
### 方案
- 五端点配额拒绝统一改用**各自协议的既有错误构造器**(`openai_error` / `anthropic_error` / `models_error`),message 走共享模板携带 `used X / limit Y` 数值;不发明新错误结构。
- `PlanError::QuotaExceeded` 携带 (used, limit),规划期错误文案同模板;429 状态码与「Key 维度终态、不做渠道 failover」语义不变。
- legacy 轨递增条件由「上游返回 usage」改为「最终入账 total_tokens > 0」——该值已含 2xx 缺失 usage 时的本地估算(与新轨共用同一 estimate_usage 模块),两轨口径合一。
- `increment_quota` 的 UPDATE 加 `CASE WHEN` 封顶:limit > 0 时取 `MIN(quota_used + ?, limit)`,否则纯加法;六处调用点自动受益。
- `quota_limit = -1`(不限)与 0 行为零影响(纯加法路径,回归通过)。
### 已知行为声明
配额检查在请求前、递增在响应后,并发窗口内多请求可同时放行;封顶后越界幅度有界(本地单实例 + SQLite 单写者,可接受)。已在代码注释显式声明。
### 测试
五端点 429 协议形态断言(OpenAI/Anthropic 形状 + message 含 used/limit);封顶三态(limit=-1/0/>0);legacy 轨 mock 上游无 usage 的估算入账集成测试。
### 开放点(征求意见)
1. `quota_reset_period`(按日/月自动重置)是否需要?
2. 配额拒绝是否补 `Retry-After` 头(当前无自动重置周期,未加)?
3. chat 端点 401 纯文本是否一并统一为 JSON(独立小改,本 PR 未含)?
---
对应分支:`feat/capability-c01-quota-harden`(无迁移)。
Contributor guide
No contributing guide indexed for this repository
Research direction
Trace the five endpoint quota checks, route_plan::authorize_request, endpoint_executor's estimate_usage, the legacy proxy loop, and increment_quota. Run the existing quota tests and add coverage for protocol-specific 429 bodies, all three limit states, and legacy responses without usage. Done means used/limit appear in the established error shapes, both accounting paths agree, and positive limits are capped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sqlite
- Domain
- api, backend, databases, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100