feat: provider api_formats 可空继承、OpenAI 图片 edit/variation 与用量配额多项补强

- 鉴权: provider_api_keys.api_formats 改为可空,OAuth 托管 key 自动继承 provider endpoints 激活格式,相关 handler/测试同步更新
- 图片 planner: OpenAI 图片路由新增 edit/variation 操作并完善参数校验、响应合并与流式处理
- 用量: user me usage 返回区分 client_requested_stream/upstream_is_stream,前端 usage 列表筛选与展示增强
- 统计: stats_daily_model 新增 cache_creation_ephemeral_5m/1h tokens 字段与回填链路
- 配额/observability: quota repository 新增内存与 SQL 扩展,admin observability usage 字段扩充
- 其它: OAuth 导入/轮询收敛、provider 汇总与 pool admin 读写链路小修、新增 system_config 缓存与 provider template handler

Closes #318

Co-authored-by: Entropy.Xu <[email protected]>
This commit is contained in:
fawney19
2026-04-23 14:42:51 +08:00
co-authored by Entropy.Xu
parent f55f22d2e8
commit fa328e18a1
128 changed files with 5583 additions and 690 deletions
@@ -36,9 +36,11 @@ pub(crate) use self::plan_builders::{
build_passthrough_sync_plan_from_decision, build_standard_stream_plan_from_decision,
build_standard_sync_plan_from_decision, LocalStreamPlanAndReport, LocalSyncPlanAndReport,
};
pub(crate) use self::route::is_matching_stream_request as planner_is_matching_stream_request;
pub(crate) use self::specialized::{
build_local_gemini_files_stream_plan_and_reports_for_kind,
build_local_gemini_files_sync_plan_and_reports_for_kind,
build_local_image_stream_plan_and_reports_for_kind,
build_local_image_sync_plan_and_reports_for_kind,
build_local_video_sync_plan_and_reports_for_kind,
};
@@ -83,8 +85,17 @@ pub(crate) async fn maybe_build_stream_decision_payload(
trace_id: &str,
decision: &GatewayControlDecision,
body_json: &serde_json::Value,
body_base64: Option<&str>,
) -> Result<Option<GatewayControlSyncDecisionResponse>, GatewayError> {
decision::maybe_build_stream_decision_payload(state, parts, trace_id, decision, body_json).await
decision::maybe_build_stream_decision_payload(
state,
parts,
trace_id,
decision,
body_json,
body_base64,
)
.await
}
pub(crate) async fn maybe_build_sync_plan_payload(
@@ -114,7 +125,15 @@ pub(crate) async fn maybe_build_stream_plan_payload(
trace_id: &str,
decision: &GatewayControlDecision,
body_json: &serde_json::Value,
body_base64: Option<&str>,
) -> Result<Option<GatewayControlPlanResponse>, GatewayError> {
decision::maybe_build_stream_plan_payload_impl(state, parts, trace_id, decision, body_json)
.await
decision::maybe_build_stream_plan_payload_impl(
state,
parts,
trace_id,
decision,
body_json,
body_base64,
)
.await
}