Compare commits

...

6 Commits

Author SHA1 Message Date
CI Bot 4e837ec761 style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 4s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 5s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m17s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m13s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 21s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m12s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 20s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m4s
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m17s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 3m41s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m24s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 6m0s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m0s
CI/CD Pipeline / Validate - Style (push) Failing after 6m15s
AI Code Review / AI Code Review (pull_request) Successful in 7m11s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m36s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 3m54s
CI/CD Pipeline / Integration Tests (push) Successful in 8m4s
CI/CD Pipeline / Unit Tests (push) Successful in 12m55s
CI/CD Pipeline / Validate - Security (push) Successful in 16m17s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
2026-10-12 06:38:46 +00:00
xiaoxia 7325d45019 Merge pull request 'fix(viral-video): P0-后端放宽口播字数限制+兜底脚本使用真实品牌名' (#2273) from fix/viral-video-mock-storyboard-fallback into develop
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 5s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 6s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m48s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m10s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 4m54s
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Successful in 6m28s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m20s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 3m38s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 5m1s
CI/CD Pipeline / Integration Tests (push) Failing after 6m22s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 3m23s
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Validate - Style (push) Has been cancelled
CI/CD Pipeline / Validate - Security (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
2026-10-12 14:28:08 +08:00
CI Bot c75b08e2fb fix(viral-video): 口播字数约束过严致3次LLM全失败+兜底文案脱离用户输入
CI/CD Pipeline / CI Gate (pull_request) Blocked by required conditions
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Integration Tests (pull_request) Has started running
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 22s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 57s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 54s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m17s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m10s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 4m16s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 5m14s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 5m30s
AI Code Review / AI Code Review (pull_request) Successful in 6m46s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 7m14s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m2s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 15m11s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
根因(运维日志实锤job c66e8c6b):
- dur=15s时max_chars=45(每秒3字)过严, LLM三次输出89/96/89字全部超长被丢弃
- 最终落到_fallback_script, 硬编码通用探店文案完全脱离养生馆输入
- 同时前端retry阶段未清scriptStreamText, 流式中间产物(餐桌幻觉)被继续显示

修复:
1. 后端max_chars从_dur*3放宽到_dur*4(中文口播正常4字/秒, 15s=60字给LLM合理空间)
2. _min_chars调整为_dur*2.5匹配
3. _fallback_script注入image_analysis真实信息(VLM name/brand), 生成包含真实商品名称的兜底文案
4. 前端MOCK兜底+XML标签剥离(ebf8419) + onDelta用full_text覆盖(已是正确逻辑)

249 viral单测全过
2026-10-12 13:41:09 +08:00
xiaoxia f6ff225abc ci: trigger staging deploy (PR #2272 MOCK_STORYBOARD fix)
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 4s
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 46s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m58s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m15s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m11s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 28s
CI/CD Pipeline / Build Staging API Image (push) Successful in 44s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 29s
AI Code Review / AI Code Review (pull_request) Successful in 6m47s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 4m45s
CI/CD Pipeline / Validate - Style (push) Successful in 5m44s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 5m12s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 6s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m37s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m59s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m33s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 4m42s
CI/CD Pipeline / Validate - Security (push) Successful in 12m31s
CI/CD Pipeline / Unit Tests (push) Successful in 13m51s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
2026-10-12 13:40:16 +08:00
xiaoxia 3fa1fbf05c Merge pull request 'fix(viral-video): 删除MOCK_STORYBOARD餐桌兜底+流式剥离XML标签' (#2272) from fix/viral-video-mock-storyboard-fallback into develop
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Check push changed paths (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (push) Has been cancelled
CI/CD Pipeline / Validate - Style (push) Has been cancelled
CI/CD Pipeline / Validate - Security (push) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / PR Build API Image (push) Has been cancelled
CI/CD Pipeline / PR Build Web Image (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Has been cancelled
CI/CD Pipeline / Check push changed paths (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled
2026-10-12 13:37:36 +08:00
CI Bot ebf841901f fix(viral-video): P0-分镜卡片错误显示硬编码MOCK(实木餐桌)+流式XML标签裸显
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 7s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 7s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m50s
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m49s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1m16s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m3s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 45s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 43s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m30s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 5m13s
AI Code Review / AI Code Review (pull_request) Successful in 6m57s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 4m20s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 6m10s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Successful in 13m12s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 4s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
问题1:流式输出显示<scrpit><clip><voiceover_script>等XML标签
根因:script_delta事件推送LLM原始XML输出,前端<pre>直接裸渲染,无标签过滤
修复:流式渲染时用正则剥离XML标签,只显示可读文本(copy_generated后仍用解析后的结构化卡片)

问题2:养生馆图片生成后卡片显示'实木餐桌/北美黑胡桃木餐桌',与图片内容完全无关
根因:renderCopyResult里isNewStructure判定过严——要求shots.length≥2+scene_and_lighting非空
+total_duration非空三个条件同时满足才用真实数据,否则fallback到硬编码MOCK_STORYBOARD
(MOCK_STORYBOARD写死的是'实木餐桌场景化种草')。后端_script_from_xml虽然有默认值,但
LLM输出不完整/解析异常时只要任何一个条件不满足就会回退到MOCK,用户看到与上传图片无关的餐桌文案
修复:
- 移除MOCK_STORYBOARD作为生产兜底(仅作开发示例,不能在真实用户场景出现)
- isNewStructure判定放宽:只要shots≥1或有voiceover_script就渲染真实数据
- 缺失字段用默认值补齐(scene_and_lighting默认'基于产品场景的真实画面',duration从shots时间轴推算)
- 新增durationForShots() helper从shots.time_range推算总时长

问题3:代码核查_step_script_generation入参链路——VLM summary_markdown通过_build_images_summary透传,
marketing_purpose/industry/duration/ratio/tone/target_customer/persona/viral_structure/language/
user_copy_text/style_guide全部正确传入user prompt,参数链路无遗漏,不需要修复
2026-10-12 13:35:34 +08:00
3 changed files with 121 additions and 31 deletions
+1 -1
View File
@@ -1 +1 @@
trigger staging deploy for bec75a07 (viral-video error isolation) at 2026-10-11 19:39:29
trigger staging deploy for 3fa1fbf0 (MOCK_STORYBOARD fix) at 2026-10-12 13:40:16
@@ -344,6 +344,16 @@ interface Storyboard {
}
/** 兼容旧 copy_result(final_copy/title/scenes)→ 新 Storyboard 结构 */
function durationForShots(shots: ShotScript[] | undefined): number {
if (!shots || shots.length === 0) return 15
let maxEnd = 0
for (const s of shots) {
const m = (s.time_range || "").match(/(\d+)-(\d+)秒?/)
if (m) maxEnd = Math.max(maxEnd, parseInt(m[2], 10))
}
return maxEnd > 0 ? maxEnd : 15
}
function copyResultToStoryboard(cr: CopyResult | null | undefined): Storyboard | null {
if (!cr) return null
// 新结构:含 shots/overview 字段直接用
@@ -717,7 +727,10 @@ const ViralVideoPage: React.FC = () => {
/wan 3\.0|seedance|视频生成|视频下载|视频渲染|tts|配音|render/i.test(err || "")
const looksLikeImageErr =
/vlm|图片分析|vision|商品识别|ocr|image analysis|图片识别/i.test(err || "")
if (isVideoStage(stage) || (!isImageAnalysisStage(stage) && !isCopyStage(stage) && looksLikeVideoErr)) {
if (
isVideoStage(stage) ||
(!isImageAnalysisStage(stage) && !isCopyStage(stage) && looksLikeVideoErr)
) {
videoError = err || videoError || "视频生成失败"
copyError = undefined
analysisError = undefined
@@ -1174,7 +1187,12 @@ const ViralVideoPage: React.FC = () => {
message.warning("请先完成图片分析")
return
}
setTask({ uiStep: "step2_generating", copyError: undefined, videoError: undefined, analysisError: undefined })
setTask({
uiStep: "step2_generating",
copyError: undefined,
videoError: undefined,
analysisError: undefined,
})
try {
const job = await generateViralCopy(task.jobId, {
industry: task.industry || undefined,
@@ -1218,7 +1236,12 @@ const ViralVideoPage: React.FC = () => {
* - 若 job 已在 copy_generated/image_analyzed 且文案已确认:重新调 confirm-copy
* - 其他情况:回退到旧的 /generate 全量提交(兼容旧任务/降级) */
const handleGenerateVideo = async () => {
setTask({ uiStep: "step3_generating", videoError: undefined, copyError: undefined, analysisError: undefined })
setTask({
uiStep: "step3_generating",
videoError: undefined,
copyError: undefined,
analysisError: undefined,
})
try {
let job
if (task.jobId && task.storyboard && task.storyboard.voiceover_script.trim()) {
@@ -1344,9 +1367,12 @@ const ViralVideoPage: React.FC = () => {
// 兜底:基于错误消息关键词判定(防止 stage 字段为空时错误归到文案)
const looksLikeVideoErr =
/wan 3\.0|seedance|视频生成|视频下载|视频渲染|tts|配音|render/i.test(cleaned)
const looksLikeImageErr = /vlm|图片分析|vision|商品识别|ocr|image analysis|图片识别/i.test(cleaned)
const looksLikeImageErr = /vlm|图片分析|vision|商品识别|ocr|image analysis|图片识别/i.test(
cleaned,
)
if (isVideoStage(st) || looksLikeVideoErr) return { stage: "video" as const, msg: cleaned }
if (isImageAnalysisStage(st) || looksLikeImageErr) return { stage: "image" as const, msg: cleaned }
if (isImageAnalysisStage(st) || looksLikeImageErr)
return { stage: "image" as const, msg: cleaned }
return { stage: "copy" as const, msg: cleaned }
}
return null
@@ -1527,7 +1553,10 @@ const ViralVideoPage: React.FC = () => {
</div>
<div className="vv-sb-doc vv-streaming-doc">
<pre className="vv-streaming-pre">
{task.scriptStreamText}
{task.scriptStreamText
.replace(/<\/?[a-zA-Z_][\w:-]*(?:\s[^>]*)?>/g, "")
.replace(/\s{3,}/g, "\n\n")
.trim()}
<span className="vv-streaming-caret" aria-hidden="true" />
</pre>
</div>
@@ -1537,16 +1566,46 @@ const ViralVideoPage: React.FC = () => {
</div>
)
}
// 后端新结构尚未就绪时,用 MOCK_STORYBOARD 做预览展示;新结构到了之后优先用真实数据
// P0修复:真实分镜数据渲染。移除MOCK_STORYBOARD硬编码兜底——旧逻辑isNewStructure判定过严
// (shots≥2 + scene_and_lighting非空 + duration非空)时才用真实数据,否则回退到写死的"实木餐桌"
// 导致任何字段缺失时用户看到与上传图片完全无关的MOCK卡片。改为:只要有shots或voiceover就用真实数据,
// 缺失字段用默认值补齐,永远不回退到MOCK(MOCK仅在开发预览时使用,生产绝不能出现)。
const sb: Storyboard | null = (() => {
if (!task.storyboard) return null
const isNewStructure =
task.storyboard.shots.length >= 2 &&
!!task.storyboard.scene_and_lighting &&
task.storyboard.overview.total_duration.length > 0
if (isNewStructure) return task.storyboard
// 后端还在旧结构:兜底用 mock 展示分镜卡片效果
return MOCK_STORYBOARD
const s = task.storyboard
// 有任何真实内容(shots≥1 或 有口播文案)就渲染真实数据
const hasRealContent =
(Array.isArray(s.shots) && s.shots.length >= 1) ||
(s.voiceover_script && s.voiceover_script.trim().length > 0)
if (!hasRealContent) return null
// 补齐可能缺失的字段,避免渲染崩溃
return {
...s,
overview: {
theme: s.overview?.theme || "AI 分镜脚本",
total_duration: s.overview?.total_duration || `${durationForShots(s.shots)}s`,
aspect_ratio: s.overview?.aspect_ratio || "9:16",
},
scene_and_lighting: s.scene_and_lighting || "基于产品场景的真实画面",
shots:
s.shots && s.shots.length > 0
? s.shots
: [
{
time_range: "0-15s",
shot_type_angle_movement: "",
scene_and_dialogue: s.voiceover_script || "",
action_details: "",
audio_bgm: "轻快BGM",
transition: "",
reference_image_index: 0,
},
],
hard_constraints: Array.isArray(s.hard_constraints) ? s.hard_constraints : [],
negative_prompts: Array.isArray(s.negative_prompts) ? s.negative_prompts : [],
voiceover_script: s.voiceover_script || "",
copy_display_markdown: s.copy_display_markdown || "",
}
})()
if (
!sb &&
+47 -16
View File
@@ -729,21 +729,52 @@ def _replace_henjin_everywhere(obj: Any) -> Any:
def _fallback_script(job: ViralVideoJob) -> dict:
"""脚本生成失败时的极简兜底脚本。"""
"""脚本生成失败时的极简兜底脚本。基于image_analysis注入真实商品/门店信息,避免生成脱离用户输入的通用文案。"""
dur = max(5, min(30, int(getattr(job, "duration", 15) or 15)))
ratio = getattr(job, "video_ratio", None) or "9:16"
image_analysis = normalize_image_analysis(getattr(job, "image_analysis", None))
default_theme = _determine_theme(image_analysis, getattr(job, "marketing_purpose", "") or "")
base = _empty_copy_result(dur, ratio, theme=default_theme)
_voiceover_map = {
"store": "带你探店!今天来到这家店,环境真的很不错,服务也很到位,推荐大家来体验一下。",
"person": "哈喽,今天给大家分享我的日常,简单舒适又好看,你们觉得怎么样?",
"scene": "带大家感受一下这个空间,氛围感拉满,真的很适合打卡体验。",
"product": "你好,给大家分享一款我最近在用的好物,真的很不错,推荐你们也试试。",
}
images = image_analysis.get("images", [])
# 从 VLM 结果中提取真实商品/门店名称,避免兜底文案完全脱离用户输入
images = image_analysis.get("images", []) if isinstance(image_analysis, dict) else []
_dominant = (images[0].get("type") if images else "product") or "product"
voiceover = job.user_copy_text or _voiceover_map.get(_dominant, _voiceover_map["product"])
_names = []
_brands = []
for img in images[:3]:
n = (img.get("name") or "").strip()
b = (img.get("brand") or "").strip()
if n and n != "未识别" and n not in _names:
_names.append(n)
if b and b not in _brands:
_brands.append(b)
_name_str = _names[0] if _names else ""
_brand_str = _brands[0] if _brands else ""
_mp = (getattr(job, "marketing_purpose", "") or "").strip()
# 基于真实识别结果构建口播,不再用"这家店""一款好物"等通用表述
if job.user_copy_text:
voiceover = job.user_copy_text
elif _dominant == "store" and _name_str:
voiceover = (
f"今天带大家来{_name_str}看看,{_brand_str + ',' if _brand_str else ''}环境和服务都很赞,推荐来体验!"
)
elif _dominant == "store":
voiceover = "今天带大家探店,这家店的环境和服务都很不错,推荐大家来体验一下。"
elif _dominant == "product" and _name_str:
voiceover = f"给大家分享{_brand_str + '家的' if _brand_str else ''}{_name_str},真心不错,推荐你们试试。"
elif _dominant == "product":
voiceover = "给大家分享一款我最近在用的好物,真的很不错,推荐你们也试试。"
elif _dominant == "person":
voiceover = "哈喽,今天给大家分享我的日常,简单舒适又好看,你们觉得怎么样?"
elif _dominant == "scene" and _name_str:
voiceover = f"带大家感受一下{_name_str},氛围感拉满,真的很适合打卡体验。"
else:
voiceover = "带大家感受一下这个空间,氛围感拉满,真的很适合打卡体验。"
# 口播超长时截断
_max_v = dur * 4
if len(voiceover) > _max_v:
voiceover = voiceover[:_max_v].rstrip(",、。, ") + "。"
base["shots"] = [
{
"time_range": f"0-{dur}秒",
@@ -978,9 +1009,9 @@ def _step_script_generation(
return None
# Bug2 fix: 口播字数 + 镜头数量 + 时间轴后校验
_dur = max(5, min(30, int(getattr(job, "duration", 15) or 15)))
_max_chars = _dur * 3 # 每秒最多3字
_max_chars = _dur * 4 # 中文口播正常4字/秒,3字太紧凑LLM多次超限触发兜底
_voiceover_chars = len(voiceover.strip())
_min_chars = max(10, int(_dur * 2.2))
_min_chars = max(10, int(_dur * 2.5))
if _voiceover_chars > _max_chars:
logger.warning(
"[爆款视频] 口播超长 label=%s voiceover_chars=%d max=%d dur=%ds,将尝试压缩",
@@ -1134,9 +1165,9 @@ def _step_script_generation(
if is_fallback:
return None
_dur = max(5, min(30, int(getattr(job, "duration", 15) or 15)))
_max_chars = _dur * 3
_max_chars = _dur * 4 # 中文口播正常4字/秒
_voiceover_chars = len(voiceover.strip())
_min_chars = max(10, int(_dur * 2.2))
_min_chars = max(10, int(_dur * 2.5))
if _voiceover_chars > _max_chars:
logger.warning(
"[爆款视频] 口播超长(流式) label=%s voiceover_chars=%d max=%d", label, _voiceover_chars, _max_chars
@@ -1168,8 +1199,8 @@ def _step_script_generation(
deadline = time.time() + 180
# Bug2 fix: 构建字数约束提示,注入到 user prompt
_dur = max(5, min(30, int(getattr(job, "duration", 15) or 15)))
_max_chars = _dur * 3
_min_chars = max(10, _dur * 2)
_max_chars = _dur * 4 # 中文口播正常4字/秒
_min_chars = max(10, int(_dur * 2.5))
_char_hint = f"口播总字数严格控制在 {_min_chars}~{_max_chars} 字({_dur}秒视频),超长会导致配音失败"
user = user + "\n\n" + _char_hint
@@ -1724,7 +1755,7 @@ def _finalize_fallback_script(job: ViralVideoJob) -> dict:
if not _validate_shot_timeline(shots, dur):
fb["shots"] = _redistribute_timeline(shots, dur)
voice = fb.get("voiceover_script", "") or ""
max_chars = dur * 3
max_chars = dur * 4
if len(voice) > max_chars:
voice = _truncate_voiceover(voice, max_chars)
fb["voiceover_script"] = voice