Initial TrueGrowth source import

This commit is contained in:
2026-07-07 09:36:36 +08:00
commit 3b6781d695
2283 changed files with 691996 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
## Context
爆款视频生成工具当前是一个三步工作流:
- 第 1 步:分析视频,生成结构化 `analysis`
- 第 2 步:基于 `analysis` + `productInfo` 改编镜头脚本
- 第 3 步:根据镜头脚本生成首尾帧和视频
其中第 3 步已经广泛复用了现有任务队列,但第 1、2 步仍然是组件内直连异步调用。这样做的问题是:
- 没有统一任务态,用户看不到排队/处理中状态
- 页面刷新后分析/改编过程无法恢复
- 失败后没有任务级重试语义
- 历史记录只有“结果”,缺少“可恢复输入”
## Goals / Non-Goals
- Goals:
- 让视频分析与脚本改编进入统一任务队列
- 让分析结果和改编结果能在任务完成后稳定回写到 `AnalysisRecord`
- 让历史记录可恢复 YouTube URL 与本地视频输入
- Non-Goals:
- 不将本地视频上传到远端持久化
- 不引入新的云存储或后端 API
- 不重构现有视频生成素材链路
## Decisions
### Decision: 复用 `TaskType.CHAT`,通过任务元数据区分视频分析器内部动作
分析和脚本改编本质上都属于文本模型调用,不新增新的 `TaskType`,继续复用 `TaskType.CHAT`
但普通聊天任务与视频分析器内部任务的行为不同,因此在任务参数中增加元数据,例如:
```ts
videoAnalyzerAction?: 'analyze' | 'rewrite'
videoAnalyzerRecordId?: string
videoAnalyzerSource?: 'upload' | 'youtube'
```
这样可以复用现有执行链,同时在 `AnalyzePage` / `ScriptPage` 监听任务完成事件,按动作类型回写对应记录。
### Decision: 视频分析继续使用专用 `video-analyze` 工具,而不是强行改造成普通 `generate_text`
视频分析依赖 `google.generateContent` 的视频输入能力,既支持 `inline_data`,也支持 `file_uri`
普通 `generate_text` 目前只覆盖文本 + 图片输入,无法直接承载视频。
因此本变更中:
- `video-analyze` 增加 `queue` 模式
- 入队任务仍使用 `TaskType.CHAT`
- 执行时由任务执行器识别 `videoAnalyzerAction === 'analyze'` 并走专用视频分析链
### Decision: 历史输入源分成“轻来源”和“本地缓存来源”
为避免把大体积 base64 直接塞进记录:
- YouTube持久化原始 URL
- 本地上传:把视频 `Blob` 缓存到本地缓存层,并在记录中仅保存缓存 key、文件名、MIME、大小
建议新增:
```ts
type AnalysisSourceSnapshot =
| { type: 'youtube'; youtubeUrl: string }
| {
type: 'upload';
cacheUrl: string;
fileName: string;
mimeType: string;
size: number;
};
```
分析页重新载入历史记录时:
- YouTube 直接回填输入框
- 本地上传通过缓存 URL 拉回 `Blob`,重建 `File`,恢复预览和重新分析能力
### Decision: 结果回写由页面监听任务事件完成,任务结果本身只存最小必要数据
为避免把完整 `analysis` 或完整镜头 JSON 既写入任务结果、又写入历史记录导致冗余过大:
- 任务结果可以保留结构化文本或最小 JSON
- 页面在收到完成事件后解析并回写 `AnalysisRecord`
- 本地视频的首尾帧缓存提取仍在分析结果落库后异步进行
## Risks / Trade-offs
- 本地视频缓存会占用浏览器本地存储空间
- Mitigation: 只缓存原始视频引用所需数据,不额外复制多份;保留后续清理入口
- `TaskType.CHAT` 复用后,任务列表里会出现“分析视频”“改编脚本”这类文本任务
- Mitigation: 通过任务标题/提示词前缀/元数据区分,确保用户能识别
- 页面刷新后如果缓存被浏览器清理,本地视频恢复可能失败
- Mitigation: 降级为提示用户原视频不可恢复,但保留分析结果
## Migration Plan
1. 扩展 `AnalysisRecord` 的输入源快照结构
2. 为旧记录补兼容YouTube 回退到 `sourceLabel`,上传记录视为“仅显示文件名,不可恢复视频”
3.`video-analyze` 增加 queue 模式
4. 为脚本改编增加基于任务队列的执行入口
5. 在分析页/脚本页监听任务完成事件并回写记录
## Open Questions
- 任务列表是否需要为视频分析器内部任务显示更明确的标题文案
- 本地视频缓存是否需要在历史删除时同步清理源文件缓存

View File

@@ -0,0 +1,48 @@
# Change: 将爆款视频生成的分析与改编接入任务队列,并补齐历史输入源回填
## Why
当前爆款视频生成工具的第 1 步分析和第 2 步脚本改编都在组件内直接发起异步调用,不进入统一任务队列。
这导致用户无法在任务面板里追踪进度、失败后重试,也无法在页面切换或刷新后恢复这些长耗时任务。
同时,历史记录目前只保存 `sourceLabel`。YouTube 场景还能靠文本回填 URL本地上传视频则只剩文件名无法在重新分析时恢复原视频输入。
## What Changes
- 将爆款视频生成工具的“视频分析”接入统一任务队列
- 将爆款视频生成工具的“脚本改编”接入统一任务队列
- 为这两类任务补充结构化任务元数据,区分普通文本任务与视频分析器内部任务
- 为分析历史补充输入源持久化:
- YouTube 记录真实 `youtubeUrl`
- 本地上传记录缓存后的视频来源信息,支持后续恢复
- 用户从历史记录重新进入分析页时,自动回填 YouTube URL 或本地视频预览,并可直接重新提交
- 保持现有素材生成、首尾帧提取和记录存储结构可兼容迁移
## Impact
- Affected specs:
- `video-analyzer`
- Affected code:
- `packages/drawnix/src/components/video-analyzer/*`
- `packages/drawnix/src/mcp/tools/video-analyze.ts`
- `packages/drawnix/src/mcp/tools/text-generation.ts`
- `packages/drawnix/src/services/task-queue-service.ts`
- `packages/drawnix/src/types/shared/core.types.ts`
- `packages/drawnix/src/utils/video-frame-cache.ts`
- `packages/drawnix/src/services/unified-cache-service.ts`
## Scope
### Included In This Change
- 视频分析任务的入队、进度展示、结果回写
- 脚本改编任务的入队、进度展示、结果回写
- 历史记录对 YouTube URL 和本地视频来源的恢复
- 必要的数据结构迁移与兼容处理
### Not Included In This Change
- 通用任务队列 UI 的大规模改版
- 将爆款视频生成的“素材生成”页面改造成新的队列协议
- 云端上传原视频或服务端持久化视频源
- 跨设备同步本地上传视频源

View File

@@ -0,0 +1,63 @@
## ADDED Requirements
### Requirement: 视频分析必须进入统一任务队列
爆款视频生成工具在用户提交视频分析时,系统 SHALL 创建一个可追踪的队列任务,而不是仅在组件内直接等待异步结果。
#### Scenario: YouTube 视频分析入队
- **WHEN** 用户在爆款视频生成工具第 1 步输入 YouTube URL 并开始分析
- **THEN** 系统创建一个视频分析任务并出现在任务队列中
- **AND** 任务完成后将结构化分析结果写回对应的分析记录
#### Scenario: 本地上传视频分析入队
- **WHEN** 用户在爆款视频生成工具第 1 步上传本地视频并开始分析
- **THEN** 系统创建一个视频分析任务并出现在任务队列中
- **AND** 任务完成后将结构化分析结果写回对应的分析记录
### Requirement: 脚本改编必须进入统一任务队列
爆款视频生成工具在用户执行 AI 脚本改编时,系统 SHALL 创建一个可追踪的队列任务,并在完成后回写镜头脚本。
#### Scenario: 脚本改编任务完成后回写
- **WHEN** 用户在第 2 步提交 AI 改编脚本
- **THEN** 系统创建一个脚本改编任务并出现在任务队列中
- **AND** 任务完成后将改编后的镜头数据写回当前分析记录
### Requirement: 历史分析记录必须保存可恢复输入源
爆款视频生成工具保存分析历史时,系统 SHALL 同时保存足以恢复再次分析的输入源快照。
#### Scenario: 保存 YouTube 输入源
- **WHEN** 用户使用 YouTube URL 完成一次分析
- **THEN** 历史记录保存原始 `youtubeUrl`
#### Scenario: 保存本地上传输入源
- **WHEN** 用户使用本地视频完成一次分析
- **THEN** 系统将本地视频缓存到本地存储
- **AND** 历史记录保存恢复该视频所需的缓存引用与文件元数据
### Requirement: 从历史记录重新进入分析页时必须回填输入源
用户从爆款视频生成工具的历史记录重新进入分析页时,系统 SHALL 尝试恢复原始输入源,而不是只展示历史结果。
#### Scenario: 回填 YouTube URL
- **WHEN** 用户打开一条来自 YouTube 的历史分析记录
- **THEN** 分析页自动回填对应的 YouTube URL
#### Scenario: 恢复本地上传视频
- **WHEN** 用户打开一条来自本地上传的历史分析记录且本地缓存仍可用
- **THEN** 分析页自动恢复视频预览
- **AND** 用户可以直接重新提交分析
#### Scenario: 本地视频缓存不可恢复时安全降级
- **WHEN** 用户打开一条来自本地上传的历史分析记录但原视频缓存已丢失
- **THEN** 系统保留原有分析结果展示
- **AND** 明确提示该历史记录无法恢复原视频输入

View File

@@ -0,0 +1,32 @@
# Tasks: 爆款视频生成分析/改编任务队列化与历史回填
## 1. 记录与输入源
- [x] 1.1 扩展 `AnalysisRecord`,保存可恢复的输入源快照
- [x] 1.2 为本地上传视频增加缓存与恢复工具,避免在记录中直接保存大块 base64
- [x] 1.3 为旧历史记录补兼容读取逻辑
## 2. 视频分析任务
- [x] 2.1 为 `video-analyze` 工具增加 `queue` 模式
- [x] 2.2 让任务执行链支持视频分析专用执行分支
- [x] 2.3 在分析页监听任务完成/失败并回写记录与错误状态
## 3. 脚本改编任务
- [x] 3.1 为脚本改编增加基于任务队列的执行入口
- [x] 3.2 在脚本页监听任务完成/失败并回写 `editedShots`
- [x] 3.3 保持现有手动编辑与自动保存行为不变
## 4. 历史恢复
- [x] 4.1 从历史记录进入分析页时回填 YouTube URL
- [x] 4.2 从历史记录进入分析页时恢复本地视频预览与重新分析能力
- [x] 4.3 对无法恢复的旧上传记录提供安全降级
## 5. 验证
- [x] 5.1 验证分析任务可在任务队列中追踪并完成回写
- [x] 5.2 验证脚本改编任务可在任务队列中追踪并完成回写
- [x] 5.3 验证 YouTube 历史记录可重新打开并回填 URL
- [x] 5.4 验证本地上传历史记录在缓存存在时可恢复视频