diff --git a/.helloagents/CHANGELOG.md b/.helloagents/CHANGELOG.md
index 5d7c9ea..9f37272 100644
--- a/.helloagents/CHANGELOG.md
+++ b/.helloagents/CHANGELOG.md
@@ -9,6 +9,10 @@
### 变更
+- **[settings/proxy/usage/admin-ui]**: 运行时设置可在后台配置,新增队列日限额与直写比例并接入 UsageLimiter — by lsy
+ - 方案: [202603180031_usage-queue-simplified](archive/2026-03/202603180031_usage-queue-simplified/)
+- **[cache/settings/proxy/usage/admin-ui]**: 引入分组缓存与自动失效,面板/日志/模型短期缓存可配置,清理节流并补齐索引 — by lsy
+ - 方案: [202603172242_cache-strategy-optimizations](plan/202603172242_cache-strategy-optimizations/)
- **[deploy/proxy/settings]**: 调整 stream usage 默认值并避免部署覆盖云端变量 — by lsy
- 方案: [202603170025_runtime-defaults-no-override](archive/2026-03/202603170025_runtime-defaults-no-override/)
- **[admin-ui/usage]**: 使用日志渠道筛选改为搜索多选,分页条数与列偏好本地记忆 — by lsy
diff --git a/.helloagents/modules/admin-ui.md b/.helloagents/modules/admin-ui.md
index 1364ff8..74d7c56 100644
--- a/.helloagents/modules/admin-ui.md
+++ b/.helloagents/modules/admin-ui.md
@@ -38,7 +38,10 @@
- 站点管理内置一键签到入口,展示今日签到结果(基于后台写回的 `last_checkin_*`)
- 系统设置增加定时签到开关与时间(中国时间)
- 系统设置提供模型失败冷却分钟数配置
-- 系统设置展示运行时配置(只读),以卡片显示名称 + 环境变量名 + 当前值,并提示在部署环境中修改环境变量
+- 系统设置提供运行时配置可编辑(上游超时、流式解析模式/上限、队列开关/日限额/直写比例)
+- 系统设置展示运行时配置(只读),以卡片显示名称 + 环境变量名 + 当前值,并提示设置优先生效
+- 系统设置提供缓存开关与 TTL(面板/日志/模型/鉴权/渠道/调用令牌/设置)配置
+- 系统设置展示缓存版本号并提供刷新入口
- 列表分页页脚统一使用页码导航 + 每页条数选择,并显示总页数(无数据时显示 0 页)
- 每页条数选择与列显示偏好本地持久化
- 页面布局拆分为“标题区 + 筛选区 + 数据区”,避免单一大卡片堆叠
diff --git a/.helloagents/modules/dashboard.md b/.helloagents/modules/dashboard.md
index 9c9333a..3502b78 100644
--- a/.helloagents/modules/dashboard.md
+++ b/.helloagents/modules/dashboard.md
@@ -14,6 +14,7 @@
- 可选筛选:`channel_ids` / `token_ids` / `model`
- 管理台默认展示全量时间范围,并在趋势卡片内提供统计颗粒(按日/周/月)
- 统计颗粒与时间范围在前端本地存储并优先复用
+- `GET /api/dashboard` 支持短时缓存(TTL 可配置,版本化失效)
## 依赖关系
- `usage_logs` 表
diff --git a/.helloagents/modules/models.md b/.helloagents/modules/models.md
index a6eca4c..6137577 100644
--- a/.helloagents/modules/models.md
+++ b/.helloagents/modules/models.md
@@ -13,6 +13,7 @@
- 使用“模型广场测试结果”作为可用模型来源
- 模型归一化支持字符串数组与对象数组(对象取 `id` 字段)
- 管理台模型广场支持搜索、渠道筛选与分页展示
+- `GET /api/models` 支持短时缓存(TTL 可配置,版本化失效)
## 依赖关系
- `channels` 表
diff --git a/.helloagents/modules/proxy.md b/.helloagents/modules/proxy.md
index a9f1ba1..e7b5a20 100644
--- a/.helloagents/modules/proxy.md
+++ b/.helloagents/modules/proxy.md
@@ -17,6 +17,8 @@
- 调用令牌按模型列表匹配选择,未配置或无列表时回退 `channels.api_key`
- 调用令牌模型列表来自渠道连通测试写回
- done-hub 仅使用 `base_url`,不再按多地址切换
+- 令牌鉴权、启用渠道与调用令牌支持短时缓存;禁用/变更会触发分组缓存版本失效
+- 失败冷却/阈值判断不做跨请求缓存,确保即时生效
- 支持从非流式 JSON、响应头与流式 SSE(含 `response.usage` 与 `usageMetadata`)解析 usage 字段
- 流式请求自动补 `stream_options.include_usage=true` 以便上游返回 usage
- 流式 usage 解析支持 `full/lite/off` 模式(`lite` 仅解析包含 usage 的事件,并可限制最大扫描字节)
@@ -24,6 +26,8 @@
- 可配置失败重试轮询(响应 5xx/429 时触发)
- 记录流式请求标记、首 token 延迟与推理强度到 usage_logs
- 使用日志与模型能力写入可通过 `USAGE_QUEUE` 异步化(队列不可用时自动回退同步写入)
+- 队列写入采用“两态简化逻辑”:未超限时按比例直写/队列,超限后全部直写
+- 队列日限额由 `UsageLimiter` DO 维护,限制 `USAGE_QUEUE` 的日内发送量
- 当 usage 解析被跳过或超限时,会记录 `usage_skipped/usage_missing` 用于可观测性
- 上游类型由 `metadata_json.site_type` 决定(`openai/anthropic/gemini`,其他类型视为 openai 兼容)
- 允许 `metadata_json.model_mapping` 将下游模型映射为上游模型
@@ -37,7 +41,9 @@
- 仅 429/5xx/408/timeout/exception 计入冷却,4xx 请求错误不触发冷却
- 映射模型场景失败时同时记录下游模型错误,确保冷却窗口生效
- 上游成功响应会刷新能力表,清空错误并延长可用窗口
-- CPU 保护开关(环境变量): `PROXY_STREAM_USAGE_MODE`, `PROXY_STREAM_USAGE_MAX_BYTES`, `PROXY_STREAM_USAGE_MAX_PARSERS`, `PROXY_USAGE_QUEUE_ENABLED`
+- 运行时配置优先读取 settings,环境变量仅回退
+- CPU 保护相关配置: `proxy_stream_usage_mode`, `proxy_stream_usage_max_bytes`, `proxy_stream_usage_max_parsers`, `proxy_usage_queue_enabled`
+- 队列策略配置: `usage_queue_daily_limit`, `usage_queue_direct_write_ratio`
- 默认值: `PROXY_STREAM_USAGE_MODE=full`, `PROXY_STREAM_USAGE_MAX_BYTES=0`, `PROXY_STREAM_USAGE_MAX_PARSERS=0`, `PROXY_USAGE_QUEUE_ENABLED=true`
- `PROXY_STREAM_USAGE_MAX_BYTES` 与 `PROXY_STREAM_USAGE_MAX_PARSERS` 设为 `0` 表示无限制
diff --git a/.helloagents/modules/settings.md b/.helloagents/modules/settings.md
index 3f40a39..991d939 100644
--- a/.helloagents/modules/settings.md
+++ b/.helloagents/modules/settings.md
@@ -12,15 +12,38 @@
## 行为规范
- 配置写入后即时生效
-- 未配置时使用环境变量默认值
+- 未配置时使用环境变量/默认值回退
- 定时签到时间使用 `HH:mm` 格式(默认 `00:10`,中国时间)
- 更新签到时间后会触发 `CheckinScheduler` 重新调度
- 若更新后当前时间已超过新签到时间,当日可再次触发自动签到
- 模型失败冷却以分钟计(默认 10 分钟),用于跳过最近失败的渠道/模型
-- 代理 CPU 降载相关开关使用环境变量(非 DB 设置)
-- `GET /api/settings` 额外返回 `runtime_config`(环境变量读取结果),用于展示流式 usage 解析与队列状态
-- 运行时配置默认值为 `PROXY_STREAM_USAGE_MODE=full`、`PROXY_STREAM_USAGE_MAX_BYTES=0`、`PROXY_STREAM_USAGE_MAX_PARSERS=0`
-- 运行时配置中 `PROXY_STREAM_USAGE_MAX_BYTES/PROXY_STREAM_USAGE_MAX_PARSERS` 设为 `0` 表示无限制
+- 运行时配置可写入 settings(环境变量作为回退)
+- `GET /api/settings` 返回:
+ - `runtime_settings`(可写配置值)
+ - `runtime_config`(生效值 + 队列绑定/生效状态)
+- 运行时配置字段:
+ - `proxy_upstream_timeout_ms`
+ - `proxy_stream_usage_mode`
+ - `proxy_stream_usage_max_bytes`
+ - `proxy_stream_usage_max_parsers`
+ - `proxy_usage_queue_enabled`
+ - `usage_queue_daily_limit`
+ - `usage_queue_direct_write_ratio`
+- 运行时配置默认值:
+ - `PROXY_STREAM_USAGE_MODE=full`
+ - `PROXY_STREAM_USAGE_MAX_BYTES=0`
+ - `PROXY_STREAM_USAGE_MAX_PARSERS=0`
+ - `PROXY_UPSTREAM_TIMEOUT_MS=30000`
+ - `usage_queue_daily_limit=10000`
+ - `usage_queue_direct_write_ratio=0.5`
+- `PROXY_STREAM_USAGE_MAX_BYTES/PROXY_STREAM_USAGE_MAX_PARSERS` 设为 `0` 表示无限制
+- 缓存配置字段:
+ - `cache_enabled`
+ - `cache_ttl_dashboard_seconds` / `cache_ttl_usage_seconds` / `cache_ttl_models_seconds`
+ - `cache_ttl_tokens_seconds` / `cache_ttl_channels_seconds` / `cache_ttl_call_tokens_seconds`
+ - `cache_ttl_settings_seconds`
+- `cache_config` 中包含分组版本号(dashboard/usage/models/tokens/channels/call_tokens/settings),用于精准失效
+- `POST /api/settings/cache/refresh` 会 bump 所有缓存版本(用于紧急刷新)
## 依赖关系
- `settings` 表
diff --git a/.helloagents/modules/usage.md b/.helloagents/modules/usage.md
index 0823ac9..f619245 100644
--- a/.helloagents/modules/usage.md
+++ b/.helloagents/modules/usage.md
@@ -11,8 +11,10 @@
## 行为规范
- 代理调用统一写入 `usage_logs`(含无可用渠道/冷却提前返回)
- 使用日志可通过 `USAGE_QUEUE` 异步写入(可能存在短暂延迟)
+- 队列写入受 `usage_queue_daily_limit` 限制,超限后自动回退为 Worker 直写
- 流式 usage 解析被跳过或超限时会记录 `usage_skipped/usage_missing` 以便排查
- 保留天数可配置,查询时触发清理
+- `GET /api/usage` 支持短时缓存(TTL 可配置,版本化失效)
- 查询结果附带渠道与令牌名称
- `GET /api/usage` 支持 `offset/limit` 分页并返回 `total`
- 支持按 `model/channel/token/status` 关键词搜索(保留 `channel_id/token_id` 精确过滤,新增 `channel_ids`/`token_ids`/`models`/`statuses` 多选过滤)
diff --git a/apps/ui/src/App.tsx b/apps/ui/src/App.tsx
index 8b13dee..22ab7f8 100644
--- a/apps/ui/src/App.tsx
+++ b/apps/ui/src/App.tsx
@@ -305,8 +305,12 @@ const App = () => {
);
const [checkinLastRun, setCheckinLastRun] = useState(null);
const [, setPendingActions] = useState>(() => new Set());
- const pendingActionsRef = useRef>(new Set());
- const noticeTimersRef = useRef
+
+
运行时配置
+
+ 以下配置可在后台修改,环境变量仅作为回退值。
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ proxy_upstream_timeout_ms: target?.value ?? "",
+ });
+ }}
+ />
+
+ 设置为 0 表示不限制超时。
+
+
+
+
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ proxy_stream_usage_max_bytes: target?.value ?? "",
+ });
+ }}
+ />
+
+ 0 表示不限制。
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ proxy_stream_usage_max_parsers: target?.value ?? "",
+ });
+ }}
+ />
+
+ 0 表示不限制。
+
+
+
+
+
+
+ 启用用量队列
+
+
+ 启用后将按比例把 usage 写入队列。
+
+
+
{
+ onFormChange({ proxy_usage_queue_enabled: next });
+ }}
+ />
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ usage_queue_daily_limit: target?.value ?? "",
+ });
+ }}
+ />
+
+ 达到上限后自动切回 Worker 直写。
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ usage_queue_direct_write_ratio: target?.value ?? "",
+ });
+ }}
+ />
+
+ 示例:0.5 表示 50% 直写。
+
+
+
+
+
+
+ 启用面板缓存
+
+
+ 对数据面板、日志列表与模型列表启用短时缓存,降低 D1 读取量。
+
+
+
{
+ onFormChange({ cache_enabled: next });
+ }}
+ />
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_dashboard_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+ 0 表示关闭该接口缓存。
+
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_usage_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+ 日志查询建议设置较短 TTL。
+
+
+
+
+ {
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_models_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+
+
+
{
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_tokens_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+ 禁用令牌会自动失效,不影响即时生效。
+
+
+
+
+ {
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_channels_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+
+
+ {
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_call_tokens_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+
+
+ {
+ const target = event.currentTarget as HTMLInputElement | null;
+ onFormChange({
+ cache_ttl_settings_seconds: target?.value ?? "",
+ });
+ }}
+ />
+
+
+
+ 缓存版本:
+ {cacheConfig
+ ? `tokens ${cacheConfig.version_tokens}, channels ${cacheConfig.version_channels}, call_tokens ${cacheConfig.version_call_tokens}, models ${cacheConfig.version_models}, dashboard ${cacheConfig.version_dashboard}, usage ${cacheConfig.version_usage}, settings ${cacheConfig.version_settings}`
+ : "-"}
+
+
+