chore(prep): shared groundwork for the parallel task batch

多 agent 并行批次的协调提交(消除全部共享文件冲突面):
- 迁移 0004:id_session + ob_event 两表(T3/T4 用,任务不再写迁移)
- ORM:UserSession / ObEvent;错误码:九个新码(40xxx/60006,含 meta)
- 配置:四档 tiers / refresh TTL / 任务奖励注册表 / 埋点上限 / COS 直传全套
- 骨架:packages/analytics + packages/storage + events/uploads 空路由(已注册)
- deps:AnalyticsServiceDep / StorageServiceDep;DailyBudgetGuard 接收 tiers
- uv add cos-python-sdk-v5;import-linter/CI/Makefile 纳入两个新包
This commit is contained in:
xsl
2026-08-14 16:02:54 +08:00
parent 2009aa938c
commit 9e7a886863
20 changed files with 380 additions and 6 deletions
Executable → Regular
+64
View File
@@ -106,6 +106,67 @@ class Settings(BaseSettings):
llm_daily_budget_enabled: bool = True
llm_daily_budget_cents: Decimal = Decimal("100000")
llm_budget_timezone_offset_hours: int = 8
# 四档分级降级(架构 §13.3,T-P1-25b)。JSON 为列表:
# [{"threshold":0.8,"name":"degrade_secondary","blocked":["hd_export"],...}]
# blocked 支持 "*"; allow 仅 block_all 档有意义(纯文本对话放行)。
llm_budget_tiers: list[dict[str, Any]] = Field(
default_factory=lambda: [
{"threshold": 0.6, "name": "warn", "blocked": []},
{
"threshold": 0.8,
"name": "degrade_secondary",
"blocked": ["hd_export", "report_regen"],
},
{"threshold": 0.9, "name": "degrade_generation", "blocked": ["hairstyle", "tryon"]},
{"threshold": 1.0, "name": "block_all", "blocked": "*", "allow": ["agent_chat"]},
],
alias="LLM_BUDGET_TIERS_JSON",
)
# --- Auth: refresh sessions (FR-ACC-05) --------------------------------
refresh_token_ttl_seconds: int = 2_592_000 # 30 天
# --- 任务奖励(FR-BILL-03/04,配置化)-----------------------------------
# amount 全部是占位值 1:正式数值待产品在产品方案 §3.2 定稿后改 env,不改代码。
# claim_period 决定幂等粒度(同一任务同周期只能领一次)。
task_bonus_rules: dict[str, dict[str, Any]] = Field(
default_factory=lambda: {
"sign_in": {"quota_key": "agent_chat", "amount": 1, "claim_period": "day"},
"profile_complete": {
"quota_key": "agent_chat",
"amount": 1,
"claim_period": "lifetime",
},
"report_feedback": {"quota_key": "report_regen", "amount": 1, "claim_period": "day"},
"share_report": {"quota_key": "tryon", "amount": 1, "claim_period": "day"},
"invite_friend": {"quota_key": "tryon", "amount": 1, "claim_period": "day"},
},
alias="TASK_BONUS_RULES_JSON",
)
# --- 客户端埋点(FR-SYS-06)---------------------------------------------
events_max_batch: int = 50
events_props_max_bytes: int = 8192
# --- 腾讯云 COS 直传(FR-SYS-03 / T-P1-27)------------------------------
cos_region: str = "ap-shanghai"
cos_secret_id: str = ""
cos_secret_key: str = ""
cos_bucket_temp: str = "meida-temp" # 临时桶,2 小时生命周期(CR-02)
cos_bucket_user: str = "meida-user"
cos_bucket_kb: str = "meida-kb"
cos_bucket_report: str = "meida-report"
cos_presign_expire_seconds: int = 600
upload_max_bytes: int = 20_971_520 # 20MB
upload_allowed_types: str = "image/jpeg,image/png,image/webp"
# scene → {"bucket": "temp"|"user"|"kb"|"report"}。新增上传场景只改这里。
upload_scenes: dict[str, dict[str, Any]] = Field(
default_factory=lambda: {
"report_photo": {"bucket": "temp"},
"avatar": {"bucket": "temp"},
},
alias="UPLOAD_SCENES_JSON",
)
# --- Observability -----------------------------------------------------
otel_enabled: bool = False
@@ -118,6 +179,9 @@ class Settings(BaseSettings):
"llm_cost_rates",
"llm_cost_rates_peak",
"llm_default_cost_rate",
"llm_budget_tiers",
"task_bonus_rules",
"upload_scenes",
mode="before",
)
@classmethod