Merge branch '108' of https://github.com/HBAI-Ltd/Toonflow-app into 108
# Conflicts: # src/router.ts # src/types/database.d.ts
This commit is contained in:
commit
aeaed27933
@ -11,10 +11,15 @@ description: 短剧漫剧制作决策层。负责分析用户需求、制定执
|
||||
|
||||
| 工具 | 说明 |
|
||||
|------|------|
|
||||
| `get_project_info` | 获取当前项目信息(名称、风格、类型、描述、集数进度等) |
|
||||
| `get_state` | 获取当前执行状态,用于了解已完成的工作 |
|
||||
| `read_skill_file` | 读取技能参考资料文件 |
|
||||
| `execution` | 执行层工具,传入任务计划文本,由执行层完成具体工作 |
|
||||
| `activate_skill` | 激活技能,加载完整指令和资源列表到上下文 |
|
||||
| `read_skill_file` | 读取已激活技能目录下的参考资料文件 |
|
||||
| `deepRetrieve` | 深度检索记忆,通过关键词回忆历史对话详情 |
|
||||
| `run_sub_agent` | 启动子Agent执行任务(可用:`executionAI`、`supervisionAI`) |
|
||||
| `get_flowData` | 获取工作区数据(key: `script` 剧本 / `assets` 资产列表) |
|
||||
| `get_flowData_schema` | 获取工作区数据的类型结构 |
|
||||
| `set_flowData` | 保存数据到工作区(lodash 路径) |
|
||||
| `generate_assets_images` | 生成衍生资产图片(传入资产 id 列表) |
|
||||
| `generate_storyboard_images` | 生成分镜图(传入剧本文本) |
|
||||
|
||||
## 核心工作流程(必须严格遵循)
|
||||
|
||||
@ -30,22 +35,22 @@ description: 短剧漫剧制作决策层。负责分析用户需求、制定执
|
||||
|
||||
### 阶段一:收集信息(仅新任务触发)
|
||||
|
||||
1. 调用 `get_project_info` 获取项目基本信息
|
||||
2. 调用 `get_state` 了解当前已完成的工作进度
|
||||
1. 调用 `get_flowData` 获取当前工作区的剧本和资产数据,了解项目现状
|
||||
2. 调用 `deepRetrieve` 检索相关历史记忆,了解已完成的工作进度
|
||||
3. 使用 `read_skill_file` 加载 `references/plan.md` 获取计划制定规范
|
||||
|
||||
### 阶段二:制定计划并确认
|
||||
|
||||
1. 结合项目信息、当前状态和用户需求,按照 `plan.md` 的规范生成**结构化执行计划**
|
||||
1. 结合工作区数据、历史记忆和用户需求,按照 `plan.md` 的规范生成**结构化执行计划**
|
||||
2. **将计划回复给用户**,请求确认
|
||||
3. 如果用户要求调整,修改计划后重新回复,直到用户确认
|
||||
4. 输出计划后**停止并等待用户回复**,不要自行继续
|
||||
|
||||
### 阶段三:按计划执行(仅用户确认后触发)
|
||||
|
||||
用户确认后,按步骤顺序逐步调用 `execution` 工具:
|
||||
用户确认后,按步骤顺序逐步调用 `run_sub_agent` 工具:
|
||||
|
||||
1. 每次调用 `execution` 时,将当前步骤的任务描述作为 `taskDescription` 参数传入
|
||||
1. 每次调用 `run_sub_agent` 时,选择 `executionAI` 作为子Agent,将当前步骤的任务描述作为 `prompt` 参数传入
|
||||
2. 检查返回结果是否符合预期,不符合则调整指令重试
|
||||
3. 将上一步的输出作为上下文传入下一步(如有依赖)
|
||||
4. 全部步骤完成后,向用户汇报整体结果
|
||||
@ -55,7 +60,8 @@ description: 短剧漫剧制作决策层。负责分析用户需求、制定执
|
||||
- 根据项目类型(短剧/漫剧)和风格调整策略
|
||||
- 复杂任务拆分为可独立执行的小步骤
|
||||
- 关注步骤间的依赖关系,确保顺序合理
|
||||
- 利用 `get_state` 避免重复已完成的工作
|
||||
- 利用 `deepRetrieve` 检索历史记忆,避免重复已完成的工作
|
||||
- **提取衍生资产后**:计划中必须包含"询问用户是否生成资产图片"步骤。若用户确认,执行层将调用 `generate_assets_images` 工具批量生成衍生资产图片
|
||||
|
||||
## 参考资料
|
||||
|
||||
|
||||
@ -2,14 +2,14 @@
|
||||
|
||||
## 计划制定规范
|
||||
|
||||
根据 `get_project_info` 返回的项目信息和用户需求,按以下规范生成执行计划。
|
||||
根据 `get_flowData` 返回的工作区数据和用户需求,按以下规范生成执行计划。
|
||||
|
||||
## 计划结构
|
||||
|
||||
### 1. 任务总览
|
||||
|
||||
一段话概述:
|
||||
- 项目名称和类型(来自项目信息)
|
||||
- 当前工作区状态(剧本、资产情况)
|
||||
- 用户本次的核心需求
|
||||
- 预期最终产出
|
||||
|
||||
@ -21,11 +21,11 @@
|
||||
|------|------|
|
||||
| 步骤编号 | 从 1 开始 |
|
||||
| 步骤名称 | 简明标题 |
|
||||
| 具体内容 | 要做什么(需足够详细,可直接作为 `execution` 工具的 `plan` 参数) |
|
||||
| 具体内容 | 要做什么(需足够详细,可直接作为 `run_sub_agent` 工具的 `prompt` 参数) |
|
||||
| 预期输出 | 完成后应产出什么 |
|
||||
| 依赖步骤 | 前置步骤编号(无依赖填"无") |
|
||||
|
||||
**关键要求**:每个步骤的"具体内容"必须是一段完整的任务描述文本,能够独立传给 `execution` 工具执行,不能是模糊的一句话。
|
||||
**关键要求**:每个步骤的"具体内容"必须是一段完整的任务描述文本,能够独立传给 `run_sub_agent` 工具执行,不能是模糊的一句话。
|
||||
|
||||
### 3. 执行顺序
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
```
|
||||
## 📋 执行计划
|
||||
|
||||
**项目**:[项目名称] · [项目类型]
|
||||
**目标**:[一句话描述本次目标]
|
||||
**预计步骤**:[N] 步
|
||||
|
||||
@ -58,8 +57,8 @@
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 步骤粒度适中:每步对应一次 `execution` 调用
|
||||
- 结合项目当前进度(`get_state`),跳过已完成的工作
|
||||
- 步骤粒度适中:每步对应一次 `run_sub_agent` 调用
|
||||
- 利用 `deepRetrieve` 检索历史记忆,跳过已完成的工作
|
||||
- 考虑用户已有的素材和资源,避免重复
|
||||
- 每个步骤的内容描述要包含足够上下文,使执行层无需额外信息即可工作
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
---
|
||||
name: execution
|
||||
description: 用户需要拆分剧本的时候可以看此skill的参考资料,了解拆分原则和示例
|
||||
description: >
|
||||
用户需要拆分剧本或提取衍生资产时可以看此skill的参考资料,了解拆分原则、衍生资产提取原则和示例
|
||||
---
|
||||
|
||||
# execution Agent
|
||||
@ -12,19 +13,25 @@ description: 用户需要拆分剧本的时候可以看此skill的参考资料
|
||||
当用户需要以下帮助时激活此技能:
|
||||
|
||||
- 拆分剧本
|
||||
- 提取衍生资产(从剧本和已有角色资产中提取关联道具、场景物件等衍生资产)
|
||||
|
||||
## 工作指引
|
||||
|
||||
### 拆分剧本流程
|
||||
### 提取衍生资产流程
|
||||
|
||||
- 当执行拆分剧本任务的时候,你需要先调用 `get_flowData` 获取原始剧本
|
||||
- 根据[剧本拆分]文档中的拆分原则和示例,将剧本拆分成视频模型能够处理的片段
|
||||
- 将拆分后的剧本片段必须使用`set_flowData_script`工具保存,然后仅需告知用户拆分完成
|
||||
1. 调用 `get_flowData` 分别获取 `script`(剧本)和 `assets`(现有资产列表)
|
||||
2. 根据[衍生资产提取](references/derive-assets-extraction.md)文档中的提取原则,分析剧本内容,为每个角色资产识别出关联的衍生资产(道具、服饰、法器、座驾、场景物件等)
|
||||
3. 对每个有衍生状态的资产调用 `set_flowData({ key: "assets[N].derive", value: derive数组 })` 逐个保存
|
||||
4. 告知用户提取完成,列出为每个角色提取的衍生资产概要
|
||||
5. **询问用户是否需要生成衍生资产图片**:
|
||||
- 如果用户确认需要,收集所有需要生成图片的资产 id,调用 `generate_assets_images({ ids: [资产id列表] })` 生成图片
|
||||
- 如果用户拒绝,跳过此步骤,流程结束
|
||||
- 生成图片为异步操作,可以先回复用户"正在生成图片,稍后会自动更新",等图片生成完成后再通知用户查看
|
||||
|
||||
## 参考资料
|
||||
|
||||
本技能附带以下参考资料,根据任务需要使用 `read_skill_file` 工具按需加载:
|
||||
|
||||
- [剧本拆分](references/script-splitting.md) — 将剧本拆分成视频模型能够处理的片段,包含拆分原则和示例
|
||||
- [衍生资产提取](references/derive-assets-extraction.md) — 从剧本和角色资产中提取衍生资产的原则和示例
|
||||
|
||||
**注意**:根据用户当前任务选择性加载对应参考资料,不要一次性全部加载。
|
||||
|
||||
@ -0,0 +1,174 @@
|
||||
# 衍生资产提取(从剧本 + 资产 → derive[])
|
||||
|
||||
本指南只做一件事:
|
||||
根据剧本内容和已有资产,为每个资产提取在剧情中出现的**不同状态/变体**(derive)。
|
||||
|
||||
> **核心概念**:derive 是父资产的**其他视觉状态**,用于为后续图片生成提供参考。
|
||||
> 只衍生**图片模型无法仅凭提示词自行处理的视觉差异**,如服装、形态、伤势、物件状态等。
|
||||
> 表情、情绪、简单动作等模型可自行控制的内容**不需要衍生**。
|
||||
> - 角色资产 → 不同服装、伤势外观、形态变化等状态变体
|
||||
> - 道具资产 → 不同物理状态变体(破损、发光、打开等)
|
||||
> - 场景资产 → 不同时间/氛围状态变体(白天、夜晚、废墟等)
|
||||
|
||||
## 1. 输入与输出
|
||||
|
||||
### 输入
|
||||
|
||||
- 剧本文本(字符串),通过 `get_flowData("script")` 获取
|
||||
- 已有资产列表(数组),通过 `get_flowData("assets")` 获取
|
||||
|
||||
每个资产结构:
|
||||
|
||||
```ts
|
||||
{
|
||||
assetsId: string; // 资产唯一ID
|
||||
name: string; // 资产名称
|
||||
desc: string; // 资产描述
|
||||
src: string; // 资产图片URL
|
||||
derive?: Array<{ // 已有衍生状态(可能为空)
|
||||
assetsId: string;
|
||||
name: string;
|
||||
desc: string;
|
||||
src: string;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
|
||||
### 输出
|
||||
|
||||
对每个需要衍生状态的资产,调用 `set_flowData` 写入 derive。通过 `key` 指定 lodash 路径,只传最小更新数据。
|
||||
|
||||
```ts
|
||||
// 为索引 0 的资产设置 derive
|
||||
set_flowData({
|
||||
key: "assets[0].derive",
|
||||
value: [
|
||||
{ name: "状态名", desc: "状态描述" }
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
derive 元素格式:
|
||||
|
||||
```ts
|
||||
{
|
||||
name: string; // 状态名称(1~20字)
|
||||
desc: string; // 状态描述(1~100字)
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 衍生状态类型
|
||||
|
||||
derive 代表同一资产在不同剧情场景下的**视觉状态变体**:
|
||||
|
||||
### 角色资产的衍生状态
|
||||
|
||||
| 类型 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| 服装变体 | 角色穿着不同服饰的状态 | 战甲状态、便装状态、礼服状态 |
|
||||
| 伤势/身体状态 | 角色身体发生显著外观变化 | 重伤缠绷带、灵力暴走纹路蔓延、白发苍老 |
|
||||
| 形态变化 | 角色外形产生根本变化 | 魔化形态、兽化、幼年状态 |
|
||||
| 特殊装扮 | 伪装或临时装束 | 蒙面伪装、乞丐装扮 |
|
||||
|
||||
> **不需要衍生的状态**:表情、情绪、简单动作姿态等图片模型可通过提示词直接控制的内容,无需单独建立衍生资产。
|
||||
|
||||
### 道具/物件资产的衍生状态
|
||||
|
||||
| 类型 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| 损坏状态 | 物件受损的外观 | 令牌破损、剑身断裂 |
|
||||
| 激活/发光状态 | 物件被触发后的外观 | 令牌发光、法印激活 |
|
||||
| 变形状态 | 物件形态发生变化 | 玉佩碎裂、卷轴展开 |
|
||||
|
||||
### 场景资产的衍生状态
|
||||
|
||||
| 类型 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| 时间变体 | 同一场景不同时段 | 夜晚的宗门、黄昏的战场 |
|
||||
| 破坏状态 | 场景受到破坏后 | 废墟状态、火烧后 |
|
||||
| 氛围变体 | 场景氛围发生变化 | 战后的宗门大殿、雨中的山门 |
|
||||
|
||||
## 3. 提取原则
|
||||
|
||||
### 3.1 核心理解
|
||||
|
||||
- derive **不是**与父资产相关的独立物件(如角色的武器、坐骑)
|
||||
- derive **是**父资产自身在不同剧情节点的**视觉状态变体**,用于为图片生成提供参考图
|
||||
- 每个 derive 应该能被理解为"**父资产名 + 状态名**"(如"凌玄·重伤缠绷带"、"青云令·破损")
|
||||
- **不要衍生**图片模型可通过提示词直接控制的内容(表情、情绪、简单动作姿态等)
|
||||
|
||||
### 3.2 来源优先级
|
||||
|
||||
1. **剧本中明确描写** — 最高优先级,剧本中直接描写了资产的不同状态
|
||||
2. **角色描述暗示** — 中优先级,desc中暗示存在状态变化但剧本未直接描写
|
||||
3. **合理推测** — 低优先级,根据剧情发展合理推测的状态变化
|
||||
|
||||
### 3.3 提取规则
|
||||
|
||||
- 只提取**与默认状态有明显视觉差异、且图片模型无法仅凭提示词自行控制**的衍生状态
|
||||
- 已存在于资产 `derive` 数组中的状态**不要重复提取**
|
||||
- 每个资产的衍生状态数量建议 **1~5个**,宁缺勿滥
|
||||
- `desc` 字段格式:`[与默认态的差异] · [视觉特征] · [出现场景/触发条件]`
|
||||
- 衍生状态命名应能直接表达"这是什么状态",而非"这是什么东西"
|
||||
|
||||
### 3.4 命名规范
|
||||
|
||||
- 名称简洁,2~6个字
|
||||
- 体现**视觉外观变化**而非情绪动作,如"重伤缠绷带"而非"悲伤流泪"
|
||||
- 如果剧本中有明确的状态描写,直接提炼为状态名
|
||||
|
||||
## 4. 示例
|
||||
|
||||
### 输入剧本片段
|
||||
|
||||
```
|
||||
苏晚卿冷笑:「还有你当宝贝的青云令」
|
||||
「若不是我趁你养伤时,偷偷在令牌上动了手脚」
|
||||
△ 凌玄气血逆流,再次一口鲜血喷出
|
||||
△ 青云令表面灵纹暗淡,隐约可见细微裂痕
|
||||
```
|
||||
|
||||
### 输入资产
|
||||
|
||||
```json
|
||||
[
|
||||
{ "assetsId": "char-1", "name": "凌玄", "desc": "男主 · 青云宗宗主 · 重伤废修", "derive": [] },
|
||||
{ "assetsId": "char-2", "name": "苏晚卿", "desc": "女配 · 凌玄未婚妻 · 背叛者", "derive": [] },
|
||||
{ "assetsId": "item-1", "name": "青云令", "desc": "宗主信物 · 青玉材质 · 灵纹浮刻", "derive": [] }
|
||||
]
|
||||
```
|
||||
|
||||
### 输出
|
||||
|
||||
分别对每个需要衍生的资产调用 `set_flowData`,通过 key 精确定位:
|
||||
|
||||
```ts
|
||||
// 凌玄(索引 0)
|
||||
set_flowData({
|
||||
key: "assets[0].derive",
|
||||
value: [
|
||||
{ name: "重伤缠绷带", desc: "气血逆流后 · 胸口缠满绷带面色苍白 · 养伤期间外观" },
|
||||
{ name: "废修白发", desc: "灵力尽失 · 黑发变白面容憔悴 · 修为被废后常态" }
|
||||
]
|
||||
})
|
||||
|
||||
// 苏晚卿(索引 1)— 无需衍生,跳过
|
||||
|
||||
// 青云令(索引 2)
|
||||
set_flowData({
|
||||
key: "assets[2].derive",
|
||||
value: [
|
||||
{ name: "灵纹暗淡", desc: "被篡改后 · 灵纹失去光泽隐现裂痕 · 感应功能被破坏" },
|
||||
{ name: "令牌发光", desc: "被激活时 · 灵纹亮起青色光芒 · 正常使用状态" }
|
||||
]
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
## 5. 工具调用顺序
|
||||
|
||||
1. `get_flowData("script")` — 获取剧本内容
|
||||
2. `get_flowData("assets")` — 获取已有资产列表
|
||||
3. 分析剧本,为每个资产识别在剧情中出现的不同视觉状态
|
||||
4. 对每个有衍生状态的资产调用 `set_flowData({ key: "assets[N].derive", value: derive数组 })` 保存
|
||||
5. 向用户汇报提取结果概要
|
||||
@ -1,39 +0,0 @@
|
||||
# 剧本拆分(仅原始文本切割,输出 string[])
|
||||
|
||||
本指南只做一件事:
|
||||
把一份长剧本原文切成多个文本片段,输出 `string[]`。
|
||||
|
||||
不做结构化字段提取,不输出 JSON 对象,不附加角色卡、锚点、分镜元数据。
|
||||
|
||||
## 1. 输入与输出
|
||||
|
||||
### 输入
|
||||
|
||||
- 一段完整长剧本文本(字符串)
|
||||
|
||||
### 输出
|
||||
|
||||
- `string[]`
|
||||
- 数组每个元素是“原始剧本的一段子串”
|
||||
- 拼接后应可还原原文语义顺序(允许空白规范化差异)
|
||||
- 开头必须是**喵,**
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
[
|
||||
"喵,第一段原文...",
|
||||
"喵,第二段原文...",
|
||||
"喵,第三段原文..."
|
||||
]
|
||||
```
|
||||
|
||||
可能输出:
|
||||
|
||||
```ts
|
||||
[
|
||||
"喵,场景1:雨夜街道。林夏快步穿过巷口。",
|
||||
"喵,场景2:天台。她停下,回头看向门口。",
|
||||
"喵,场景3:脚步声逼近。她握紧手机。"
|
||||
]
|
||||
```
|
||||
@ -60,6 +60,7 @@
|
||||
"js-md5": "^0.8.3",
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"knex": "^3.1.0",
|
||||
"lodash": "^4.17.23",
|
||||
"morgan": "^1.10.1",
|
||||
"qwen-ai-provider-v5": "^2.1.0",
|
||||
"serialize-error": "^13.0.1",
|
||||
@ -78,6 +79,7 @@
|
||||
"@types/express-ws": "^3.0.6",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/license-checker": "^25.0.6",
|
||||
"@types/lodash": "^4.17.24",
|
||||
"@types/morgan": "^1.9.10",
|
||||
"cross-env": "^10.1.0",
|
||||
"electron": "^40.0.0",
|
||||
|
||||
@ -42,7 +42,7 @@ export async function decisionAI(ctx: AgentContext) {
|
||||
|
||||
const systemPrompt = buildSystemPrompt(skill.prompt, mem);
|
||||
|
||||
const prefixSystem = `不论用户说什么要做什么都请直接调用run_sub_agent运行**executionAI**执行剧本切分任务`;
|
||||
const prefixSystem = `请回复用户收到以后直接调用run_sub_agent运行**executionAI**执行用户的任务`;
|
||||
|
||||
const { textStream } = await u.Ai.Text("productionAgent").stream({
|
||||
system: prefixSystem + systemPrompt,
|
||||
|
||||
@ -1,49 +1,88 @@
|
||||
import { tool, Tool } from "ai";
|
||||
import { z } from "zod";
|
||||
import u from "@/utils";
|
||||
import { z, toJSONSchema } from "zod";
|
||||
import _ from "lodash";
|
||||
import { Socket } from "socket.io";
|
||||
|
||||
interface FlowData {
|
||||
rawScript: string;
|
||||
script: {
|
||||
blocks: string[];
|
||||
};
|
||||
}
|
||||
const deriveSchema = z.object({ name: z.string().min(1).max(20), desc: z.string().min(1).max(100) });
|
||||
const assetSchema = z.object({ assetsId: z.string(), name: z.string(), desc: z.string(), src: z.string(), derive: z.array(deriveSchema).optional() });
|
||||
const storyboardTableSchema = z.array(
|
||||
z.object({
|
||||
id: z.number(),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
camera: z.string(),
|
||||
duration: z.number(),
|
||||
frameMode: z.enum(["firstFrame", "endFrame", "linesSoundEffects"]),
|
||||
lines: z.string().nullable(),
|
||||
sound: z.string().nullable(),
|
||||
associateAssetsIds: z.array(z.number()),
|
||||
}),
|
||||
);
|
||||
const flowDataSchema = z.object({ script: z.string(), assets: z.array(assetSchema), storyboardTable: storyboardTableSchema });
|
||||
|
||||
type FlowData = z.infer<typeof flowDataSchema>;
|
||||
|
||||
const keySchema = z.object({ key: z.enum(["script", "assets", "storyboardTable"]).describe("script=剧本,assets=资产列表,storyboardTable=分镜表") });
|
||||
const valueSchema = z
|
||||
.union([z.string(), z.array(assetSchema), assetSchema, z.array(deriveSchema), z.array(storyboardTableSchema)])
|
||||
.describe("路径对应的值");
|
||||
|
||||
export default (socket: Socket, toolsNames?: string[]) => {
|
||||
let flowData: FlowData = {
|
||||
rawScript: "",
|
||||
script: {
|
||||
blocks: [],
|
||||
},
|
||||
};
|
||||
|
||||
const tools: Record<string, Tool> = {
|
||||
get_flowData: tool({
|
||||
description: "获取当前工作区的状态/数据",
|
||||
inputSchema: z.object({
|
||||
key: z.enum(["script"]).describe("state的key,rawScript代表原始剧本文字,script代表分块后的剧本"),
|
||||
}),
|
||||
description: "获取工作区数据",
|
||||
inputSchema: keySchema,
|
||||
execute: async ({ key }) => {
|
||||
flowData = await new Promise((resolve) => socket.emit("getFlowData", { key }, (res: any) => resolve(res)));
|
||||
console.log("[tool] get_flowData:", key);
|
||||
console.log("[tools] get_flowData", key);
|
||||
const flowData: FlowData = await new Promise((resolve) => socket.emit("getFlowData", { key }, (res: any) => resolve(res)));
|
||||
return flowData[key];
|
||||
},
|
||||
}),
|
||||
set_flowData_script: tool({
|
||||
description: "保存数据到工作区",
|
||||
get_flowData_schema: tool({
|
||||
description: "获取工作区数据的类型结构,在使用set_flowData前应先调用",
|
||||
inputSchema: keySchema,
|
||||
execute: async ({ key }) => {
|
||||
console.log("[tools] get_flowData_schema", key);
|
||||
return toJSONSchema(flowDataSchema.shape[key]);
|
||||
},
|
||||
}),
|
||||
set_flowData: tool({
|
||||
description: "保存数据到工作区,key为lodash路径,先调用get_flowData_schema了解可用路径和类型",
|
||||
inputSchema: z.object({
|
||||
value: z.array(z.string()).describe("剧本分块后的文本数组"),
|
||||
key: z.string().describe("lodash路径,如 script、assets[0].derive"),
|
||||
value: valueSchema,
|
||||
}),
|
||||
execute: async ({ value }) => {
|
||||
flowData.script.blocks = value;
|
||||
socket.emit("setFlowData", { key: "script", value: { blocks: value } });
|
||||
|
||||
execute: async ({ key, value }) => {
|
||||
console.log("[tools] set_flowData", key, value);
|
||||
const flowData: FlowData = await new Promise((resolve) => socket.emit("getFlowData", { key }, (res: any) => resolve(res)));
|
||||
const backup = _.cloneDeep(_.get(flowData, key));
|
||||
_.set(flowData, key, value);
|
||||
const r = flowDataSchema.safeParse(flowData);
|
||||
if (!r.success) {
|
||||
_.set(flowData, key, backup);
|
||||
return { error: r.error.issues.map((i) => `[${i.path.join(".")}] ${i.message}`).join("; ") };
|
||||
}
|
||||
socket.emit("setFlowData", { key, value });
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
generate_assets_images: tool({
|
||||
description: "生成衍生资产的图片",
|
||||
inputSchema: z.object({ ids: z.array(z.string()).describe("需要生成的资产id列表") }),
|
||||
execute: async ({ ids }) => {
|
||||
console.log("[tools] generated_assets", ids);
|
||||
return new Promise((resolve) => socket.emit("generatedAssets", { ids }, (res: any) => resolve(res)));
|
||||
},
|
||||
}),
|
||||
generate_storyboard_images: tool({
|
||||
description: "生成分镜图",
|
||||
inputSchema: z.object({ script: z.string().describe("剧本文本") }),
|
||||
execute: async ({ script }) => {
|
||||
console.log("[tools] generate_storyboard_images", script);
|
||||
return new Promise((resolve) => socket.emit("generateStoryboardImages", { script }, (res: any) => resolve(res)));
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
if (!toolsNames) return tools;
|
||||
else return Object.fromEntries(Object.entries(tools).filter(([name]) => toolsNames.includes(name)));
|
||||
return toolsNames ? Object.fromEntries(Object.entries(tools).filter(([n]) => toolsNames.includes(n))) : tools;
|
||||
};
|
||||
|
||||
@ -89,13 +89,13 @@ class Logger {
|
||||
(console as any)[level] = (...args: unknown[]) => {
|
||||
this.writing = true;
|
||||
try {
|
||||
// this.write(level, args);
|
||||
this.write(level, args);
|
||||
} catch (err) {
|
||||
this.originalConsole.error?.("[Logger Error]", err);
|
||||
}
|
||||
this.writing = false;
|
||||
|
||||
this.originalConsole[level]!(...args);
|
||||
this.writing = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
116
src/router.ts
116
src/router.ts
@ -1,4 +1,4 @@
|
||||
// @routes-hash a3ee46a441a84f41e515f5b26b9ccaa9
|
||||
// @routes-hash 3d0673061005074e704638efccc539d1
|
||||
import { Express } from "express";
|
||||
|
||||
import route1 from "./routes/agents/clearMemory";
|
||||
@ -39,34 +39,35 @@ import route35 from "./routes/production/editStoryboard/getStoryboardFlow";
|
||||
import route36 from "./routes/production/editStoryboard/saveStoryboardFlow";
|
||||
import route37 from "./routes/production/editStoryboard/updateStoryboardFlow";
|
||||
import route38 from "./routes/production/getProductionData";
|
||||
import route39 from "./routes/production/workbench/generateVideo";
|
||||
import route40 from "./routes/production/workbench/getVideoModelDetail";
|
||||
import route41 from "./routes/project/addProject";
|
||||
import route42 from "./routes/project/delProject";
|
||||
import route43 from "./routes/project/editProject";
|
||||
import route44 from "./routes/project/getProject";
|
||||
import route45 from "./routes/script/addScript";
|
||||
import route46 from "./routes/script/delScript";
|
||||
import route47 from "./routes/script/getScrptApi";
|
||||
import route48 from "./routes/script/updateScript";
|
||||
import route49 from "./routes/setting/agentDeploy/deployAgentModel";
|
||||
import route50 from "./routes/setting/agentDeploy/getAgentDeploy";
|
||||
import route51 from "./routes/setting/agentDeploy/updateKey";
|
||||
import route52 from "./routes/setting/dbConfig/clearData";
|
||||
import route53 from "./routes/setting/getTextModel";
|
||||
import route54 from "./routes/setting/loginConfig/getUser";
|
||||
import route55 from "./routes/setting/loginConfig/updateUserPwd";
|
||||
import route56 from "./routes/setting/memoryConfig/getMemory";
|
||||
import route57 from "./routes/setting/memoryConfig/sureMemory";
|
||||
import route58 from "./routes/setting/vendorConfig/addVendor";
|
||||
import route59 from "./routes/setting/vendorConfig/deleteVendor";
|
||||
import route60 from "./routes/setting/vendorConfig/getVendorList";
|
||||
import route61 from "./routes/setting/vendorConfig/modelTest";
|
||||
import route62 from "./routes/setting/vendorConfig/updateVendor";
|
||||
import route63 from "./routes/task/getMyTaskApi";
|
||||
import route64 from "./routes/task/getTaskCategories";
|
||||
import route65 from "./routes/task/taskDetails";
|
||||
import route66 from "./routes/test/test";
|
||||
import route39 from "./routes/production/getStoryboardData";
|
||||
import route40 from "./routes/production/workbench/generateVideo";
|
||||
import route41 from "./routes/production/workbench/getVideoModelDetail";
|
||||
import route42 from "./routes/project/addProject";
|
||||
import route43 from "./routes/project/delProject";
|
||||
import route44 from "./routes/project/editProject";
|
||||
import route45 from "./routes/project/getProject";
|
||||
import route46 from "./routes/script/addScript";
|
||||
import route47 from "./routes/script/delScript";
|
||||
import route48 from "./routes/script/getScrptApi";
|
||||
import route49 from "./routes/script/updateScript";
|
||||
import route50 from "./routes/setting/agentDeploy/deployAgentModel";
|
||||
import route51 from "./routes/setting/agentDeploy/getAgentDeploy";
|
||||
import route52 from "./routes/setting/agentDeploy/updateKey";
|
||||
import route53 from "./routes/setting/dbConfig/clearData";
|
||||
import route54 from "./routes/setting/getTextModel";
|
||||
import route55 from "./routes/setting/loginConfig/getUser";
|
||||
import route56 from "./routes/setting/loginConfig/updateUserPwd";
|
||||
import route57 from "./routes/setting/memoryConfig/getMemory";
|
||||
import route58 from "./routes/setting/memoryConfig/sureMemory";
|
||||
import route59 from "./routes/setting/vendorConfig/addVendor";
|
||||
import route60 from "./routes/setting/vendorConfig/deleteVendor";
|
||||
import route61 from "./routes/setting/vendorConfig/getVendorList";
|
||||
import route62 from "./routes/setting/vendorConfig/modelTest";
|
||||
import route63 from "./routes/setting/vendorConfig/updateVendor";
|
||||
import route64 from "./routes/task/getMyTaskApi";
|
||||
import route65 from "./routes/task/getTaskCategories";
|
||||
import route66 from "./routes/task/taskDetails";
|
||||
import route67 from "./routes/test/test";
|
||||
|
||||
export default async (app: Express) => {
|
||||
app.use("/api/agents/clearMemory", route1);
|
||||
@ -107,32 +108,33 @@ export default async (app: Express) => {
|
||||
app.use("/api/production/editStoryboard/saveStoryboardFlow", route36);
|
||||
app.use("/api/production/editStoryboard/updateStoryboardFlow", route37);
|
||||
app.use("/api/production/getProductionData", route38);
|
||||
app.use("/api/production/workbench/generateVideo", route39);
|
||||
app.use("/api/production/workbench/getVideoModelDetail", route40);
|
||||
app.use("/api/project/addProject", route41);
|
||||
app.use("/api/project/delProject", route42);
|
||||
app.use("/api/project/editProject", route43);
|
||||
app.use("/api/project/getProject", route44);
|
||||
app.use("/api/script/addScript", route45);
|
||||
app.use("/api/script/delScript", route46);
|
||||
app.use("/api/script/getScrptApi", route47);
|
||||
app.use("/api/script/updateScript", route48);
|
||||
app.use("/api/setting/agentDeploy/deployAgentModel", route49);
|
||||
app.use("/api/setting/agentDeploy/getAgentDeploy", route50);
|
||||
app.use("/api/setting/agentDeploy/updateKey", route51);
|
||||
app.use("/api/setting/dbConfig/clearData", route52);
|
||||
app.use("/api/setting/getTextModel", route53);
|
||||
app.use("/api/setting/loginConfig/getUser", route54);
|
||||
app.use("/api/setting/loginConfig/updateUserPwd", route55);
|
||||
app.use("/api/setting/memoryConfig/getMemory", route56);
|
||||
app.use("/api/setting/memoryConfig/sureMemory", route57);
|
||||
app.use("/api/setting/vendorConfig/addVendor", route58);
|
||||
app.use("/api/setting/vendorConfig/deleteVendor", route59);
|
||||
app.use("/api/setting/vendorConfig/getVendorList", route60);
|
||||
app.use("/api/setting/vendorConfig/modelTest", route61);
|
||||
app.use("/api/setting/vendorConfig/updateVendor", route62);
|
||||
app.use("/api/task/getMyTaskApi", route63);
|
||||
app.use("/api/task/getTaskCategories", route64);
|
||||
app.use("/api/task/taskDetails", route65);
|
||||
app.use("/api/test/test", route66);
|
||||
app.use("/api/production/getStoryboardData", route39);
|
||||
app.use("/api/production/workbench/generateVideo", route40);
|
||||
app.use("/api/production/workbench/getVideoModelDetail", route41);
|
||||
app.use("/api/project/addProject", route42);
|
||||
app.use("/api/project/delProject", route43);
|
||||
app.use("/api/project/editProject", route44);
|
||||
app.use("/api/project/getProject", route45);
|
||||
app.use("/api/script/addScript", route46);
|
||||
app.use("/api/script/delScript", route47);
|
||||
app.use("/api/script/getScrptApi", route48);
|
||||
app.use("/api/script/updateScript", route49);
|
||||
app.use("/api/setting/agentDeploy/deployAgentModel", route50);
|
||||
app.use("/api/setting/agentDeploy/getAgentDeploy", route51);
|
||||
app.use("/api/setting/agentDeploy/updateKey", route52);
|
||||
app.use("/api/setting/dbConfig/clearData", route53);
|
||||
app.use("/api/setting/getTextModel", route54);
|
||||
app.use("/api/setting/loginConfig/getUser", route55);
|
||||
app.use("/api/setting/loginConfig/updateUserPwd", route56);
|
||||
app.use("/api/setting/memoryConfig/getMemory", route57);
|
||||
app.use("/api/setting/memoryConfig/sureMemory", route58);
|
||||
app.use("/api/setting/vendorConfig/addVendor", route59);
|
||||
app.use("/api/setting/vendorConfig/deleteVendor", route60);
|
||||
app.use("/api/setting/vendorConfig/getVendorList", route61);
|
||||
app.use("/api/setting/vendorConfig/modelTest", route62);
|
||||
app.use("/api/setting/vendorConfig/updateVendor", route63);
|
||||
app.use("/api/task/getMyTaskApi", route64);
|
||||
app.use("/api/task/getTaskCategories", route65);
|
||||
app.use("/api/task/taskDetails", route66);
|
||||
app.use("/api/test/test", route67);
|
||||
}
|
||||
|
||||
@ -3,23 +3,88 @@ import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { success } from "@/lib/responseFormat";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
import axios from "axios";
|
||||
const router = express.Router();
|
||||
async function getImageBase64ForId(imageId: string | number) {
|
||||
const imagePath = await u
|
||||
.db("o_image")
|
||||
.select("filePath")
|
||||
.where({ id: Number(imageId) })
|
||||
.first();
|
||||
|
||||
if (!imagePath || !imagePath.filePath) return ""; // 未找到图片路径
|
||||
const url = await u.oss.getFileUrl(imagePath.filePath);
|
||||
return await urlToBase64(url);
|
||||
}
|
||||
|
||||
async function urlToBase64(imageUrl: string): Promise<string> {
|
||||
const response = await axios.get(imageUrl, { responseType: "arraybuffer" });
|
||||
const contentType = response.headers["content-type"] || "image/png";
|
||||
const base64 = Buffer.from(response.data, "binary").toString("base64");
|
||||
return `data:${contentType};base64,${base64}`;
|
||||
}
|
||||
// 将图片ID和指令转换为base64数组和替换后的指令
|
||||
async function convertDirectiveAndImages(images: Record<string, string>, directive: string) {
|
||||
// step1: 列出所有别名
|
||||
const aliasList = Object.keys(images);
|
||||
// step2: 在指令中提取所有 @别名出现
|
||||
const aliasRegex = /@[\u4e00-\u9fa5\w]+/g;
|
||||
const referencedAliases = directive.match(aliasRegex) || [];
|
||||
// step3: 检查别名
|
||||
for (const alias of referencedAliases) {
|
||||
if (!(alias in images)) {
|
||||
throw new Error(`您引用了不存在的图片:${alias}`);
|
||||
}
|
||||
}
|
||||
// step4: 构建别名与顺序编号映射
|
||||
const aliasToIndex: Record<string, number> = {};
|
||||
aliasList.forEach((alias, i) => {
|
||||
aliasToIndex[alias] = i + 1;
|
||||
});
|
||||
// step5: 替换指令中的别名为"图N"
|
||||
let prompt = directive;
|
||||
for (const [alias, idx] of Object.entries(aliasToIndex)) {
|
||||
// 转义alias可能含特殊字符
|
||||
const reg = new RegExp(alias.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"), "g");
|
||||
prompt = prompt.replace(reg, `图${idx}`);
|
||||
}
|
||||
// step6: 依次获取图片 base64 内容(区分id或者本身就是base64)
|
||||
const base64Images: string[] = [];
|
||||
|
||||
for (const imageVal of Object.values(images)) {
|
||||
// 判断是否为base64串
|
||||
const isBase64 = typeof imageVal === "string" && /^data:image\//.test(imageVal);
|
||||
if (isBase64) {
|
||||
base64Images.push(imageVal);
|
||||
} else if (typeof imageVal === "number") {
|
||||
const base64 = await getImageBase64ForId(imageVal);
|
||||
base64Images.push(base64);
|
||||
} else if (imageVal.includes("http")) {
|
||||
const base64 = await urlToBase64(imageVal);
|
||||
base64Images.push(base64);
|
||||
}
|
||||
}
|
||||
return {
|
||||
prompt,
|
||||
images: base64Images,
|
||||
};
|
||||
}
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
model: z.string(),
|
||||
references: z.array(z.string()).optional(),
|
||||
references: z.object().optional(),
|
||||
quality: z.string(),
|
||||
ratio: z.string(),
|
||||
prompt: z.string(),
|
||||
projectId: z.number(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { model, references = [], quality, ratio, prompt, projectId } = req.body;
|
||||
const { model, references = {}, quality, ratio, prompt, projectId } = req.body;
|
||||
const { prompt: userPrompt, images: base64Images } = await convertDirectiveAndImages(references, prompt);
|
||||
const imageClass = await u.Ai.Image(model).run({
|
||||
prompt: prompt,
|
||||
imageBase64: references,
|
||||
prompt: userPrompt,
|
||||
imageBase64: base64Images,
|
||||
size: quality,
|
||||
aspectRatio: ratio,
|
||||
taskClass: "分镜生成",
|
||||
|
||||
@ -10,16 +10,18 @@ export default router.post(
|
||||
validateFields({
|
||||
edges: z.any(),
|
||||
nodes: z.any(),
|
||||
imageId: z.number(),
|
||||
imageUrl: z.number(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { edges, nodes, imageId } = req.body;
|
||||
const { edges, nodes, imageUrl } = req.body;
|
||||
if (!imageUrl.includes("http")) {
|
||||
return res.status(400).send({ message: "图片地址不合法" });
|
||||
}
|
||||
// if
|
||||
const [id] = await u.db("o_storyboad").insert({
|
||||
imageId,
|
||||
filePath: new URL(imageUrl).pathname,
|
||||
});
|
||||
await u.db("o_storyboardFlow").insert({
|
||||
id: 1,
|
||||
stroryboardId: id,
|
||||
flowData: JSON.stringify({ edges, nodes }),
|
||||
});
|
||||
|
||||
@ -11,12 +11,18 @@ export default router.post(
|
||||
edges: z.any(),
|
||||
nodes: z.any(),
|
||||
id: z.number(),
|
||||
imageId: z.number(),
|
||||
imageUrl: z.number(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { edges, nodes, id, imageId } = req.body;
|
||||
const { edges, nodes, id, imageUrl } = req.body;
|
||||
if (!imageUrl.includes("http")) {
|
||||
return res.status(400).send({ message: "图片地址不合法" });
|
||||
}
|
||||
// if
|
||||
await u.db("o_storyboard").where("id", id).update({ imageId });
|
||||
await u
|
||||
.db("o_storyboard")
|
||||
.where("id", id)
|
||||
.update({ filePath: new URL(imageUrl).pathname });
|
||||
await u
|
||||
.db("o_storyboardFlow")
|
||||
.where("stroryboardId", id)
|
||||
|
||||
27
src/routes/production/getStoryboardData.ts
Normal file
27
src/routes/production/getStoryboardData.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import express from "express";
|
||||
import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { success } from "@/lib/responseFormat";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
const router = express.Router();
|
||||
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
projectId: z.number(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { projectId } = req.body;
|
||||
const storyboardData = await u.db("o_storyboard");
|
||||
console.log("%c Line:16 🍖 storyboardData", "background:#ed9ec7", storyboardData);
|
||||
const data = await Promise.all(
|
||||
storyboardData.map(async (i) => {
|
||||
return {
|
||||
...i,
|
||||
image: i.filePath ? await u.oss.getFileUrl(i.filePath!) : "",
|
||||
};
|
||||
}),
|
||||
);
|
||||
res.status(200).send(success(data));
|
||||
},
|
||||
);
|
||||
121
src/types/database.d.ts
vendored
121
src/types/database.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
// @db-hash f8ab3a7aee659c729c770f3555728f1b
|
||||
// @db-hash bd46e7c381481a74efedc662a4f9049f
|
||||
//该文件由脚本自动生成,请勿手动修改
|
||||
|
||||
export interface memories {
|
||||
@ -35,12 +35,18 @@ export interface o_assets {
|
||||
'projectId'?: number | null;
|
||||
'prompt'?: string | null;
|
||||
'remark'?: string | null;
|
||||
'scriptId'?: number | null;
|
||||
'sonId'?: number | null;
|
||||
'startTime'?: number | null;
|
||||
'state'?: string | null;
|
||||
'type'?: string | null;
|
||||
}
|
||||
export interface o_chatHistory {
|
||||
'data'?: string | null;
|
||||
'id'?: number;
|
||||
'novel'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
'type'?: string | null;
|
||||
}
|
||||
export interface o_event {
|
||||
'createTime'?: number | null;
|
||||
'detail'?: string | null;
|
||||
@ -61,10 +67,33 @@ export interface o_image {
|
||||
'assetsId'?: number | null;
|
||||
'filePath'?: string | null;
|
||||
'id'?: number;
|
||||
'model'?: string | null;
|
||||
'resolution'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
'scriptId'?: number | null;
|
||||
'state'?: string | null;
|
||||
'type'?: string | null;
|
||||
'videoId'?: number | null;
|
||||
}
|
||||
export interface o_model {
|
||||
'apiKey'?: string | null;
|
||||
'baseUrl'?: string | null;
|
||||
'createTime'?: number | null;
|
||||
'id'?: number;
|
||||
'index'?: number | null;
|
||||
'manufacturer'?: string | null;
|
||||
'model'?: string | null;
|
||||
'modelType'?: string | null;
|
||||
'type'?: string | null;
|
||||
}
|
||||
export interface o_myTasks {
|
||||
'describe'?: string | null;
|
||||
'id'?: number;
|
||||
'model'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
'reason'?: string | null;
|
||||
'relatedObjects'?: string | null;
|
||||
'startTime'?: number | null;
|
||||
'state'?: string | null;
|
||||
'taskClass'?: string | null;
|
||||
}
|
||||
export interface o_novel {
|
||||
'chapter'?: string | null;
|
||||
@ -97,6 +126,15 @@ export interface o_project {
|
||||
'userId'?: number | null;
|
||||
'videoRatio'?: string | null;
|
||||
}
|
||||
export interface o_prompts {
|
||||
'code'?: string | null;
|
||||
'customValue'?: string | null;
|
||||
'defaultValue'?: string | null;
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'parentCode'?: string | null;
|
||||
'type'?: string | null;
|
||||
}
|
||||
export interface o_script {
|
||||
'content'?: string | null;
|
||||
'createTime'?: number | null;
|
||||
@ -104,26 +142,40 @@ export interface o_script {
|
||||
'name'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
}
|
||||
export interface o_scriptAssets {
|
||||
'assetsId'?: number | null;
|
||||
'id'?: number;
|
||||
'scriptId'?: number | null;
|
||||
}
|
||||
export interface o_scriptOutline {
|
||||
'id'?: number;
|
||||
'outlineId'?: number | null;
|
||||
'scriptId'?: number | null;
|
||||
}
|
||||
export interface o_setting {
|
||||
'key'?: string | null;
|
||||
'value'?: string | null;
|
||||
}
|
||||
export interface o_storyboard {
|
||||
'createTime'?: number | null;
|
||||
'detail'?: string | null;
|
||||
'filePath'?: string | null;
|
||||
'frameType'?: string | null;
|
||||
export interface o_skills {
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'startTime'?: number | null;
|
||||
}
|
||||
export interface o_storyboard {
|
||||
'createTime'?: number | null;
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'prompt'?: string | null;
|
||||
'scriptId'?: number | null;
|
||||
'seconds'?: string | null;
|
||||
}
|
||||
export interface o_storyboardFlow {
|
||||
'flowData': string;
|
||||
'id'?: number;
|
||||
'stroryboardId': number;
|
||||
}
|
||||
export interface o_storyboardScript {
|
||||
'id'?: number;
|
||||
'scriptId'?: number | null;
|
||||
'storyboardId'?: number | null;
|
||||
}
|
||||
export interface o_tasks {
|
||||
'describe'?: string | null;
|
||||
'id'?: number;
|
||||
@ -152,27 +204,36 @@ export interface o_vendorConfig {
|
||||
'version'?: string | null;
|
||||
}
|
||||
export interface o_video {
|
||||
'configId'?: number | null;
|
||||
'errorReason'?: string | null;
|
||||
'filePath'?: string | null;
|
||||
'firstFrame'?: string | null;
|
||||
'id'?: number;
|
||||
'scriptId'?: number | null;
|
||||
'state'?: string | null;
|
||||
'storyboardId'?: number | null;
|
||||
'time'?: number | null;
|
||||
}
|
||||
export interface o_videoConfig {
|
||||
'audio'?: number | null;
|
||||
'createTime'?: number | null;
|
||||
'data'?: string | null;
|
||||
'duration'?: number | null;
|
||||
'id'?: number;
|
||||
'mode'?: string | null;
|
||||
'model'?: string | null;
|
||||
'prompt'?: string | null;
|
||||
'resolution'?: string | null;
|
||||
'storyboardId'?: number | null;
|
||||
'scriptId'?: number | null;
|
||||
'state'?: number | null;
|
||||
'storyboardImgs'?: string | null;
|
||||
'time'?: number | null;
|
||||
}
|
||||
export interface o_videoConfig {
|
||||
'aiConfigId'?: number | null;
|
||||
'audioEnabled'?: number | null;
|
||||
'createTime'?: number | null;
|
||||
'duration'?: number | null;
|
||||
'endFrame'?: string | null;
|
||||
'id'?: number;
|
||||
'images'?: string | null;
|
||||
'manufacturer'?: string | null;
|
||||
'mode'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
'prompt'?: string | null;
|
||||
'resolution'?: string | null;
|
||||
'scriptId'?: number | null;
|
||||
'selectedResultId'?: number | null;
|
||||
'startFrame'?: string | null;
|
||||
'updateTime'?: number | null;
|
||||
'videoId'?: number | null;
|
||||
}
|
||||
|
||||
export interface DB {
|
||||
@ -180,18 +241,26 @@ export interface DB {
|
||||
"o_agentDeploy": o_agentDeploy;
|
||||
"o_artStyle": o_artStyle;
|
||||
"o_assets": o_assets;
|
||||
"o_chatHistory": o_chatHistory;
|
||||
"o_event": o_event;
|
||||
"o_eventChapter": o_eventChapter;
|
||||
"o_flowData": o_flowData;
|
||||
"o_image": o_image;
|
||||
"o_model": o_model;
|
||||
"o_myTasks": o_myTasks;
|
||||
"o_novel": o_novel;
|
||||
"o_outline": o_outline;
|
||||
"o_outlineNovel": o_outlineNovel;
|
||||
"o_project": o_project;
|
||||
"o_prompts": o_prompts;
|
||||
"o_script": o_script;
|
||||
"o_scriptAssets": o_scriptAssets;
|
||||
"o_scriptOutline": o_scriptOutline;
|
||||
"o_setting": o_setting;
|
||||
"o_skills": o_skills;
|
||||
"o_storyboard": o_storyboard;
|
||||
"o_storyboardFlow": o_storyboardFlow;
|
||||
"o_storyboardScript": o_storyboardScript;
|
||||
"o_tasks": o_tasks;
|
||||
"o_user": o_user;
|
||||
"o_vendorConfig": o_vendorConfig;
|
||||
|
||||
@ -868,6 +868,11 @@
|
||||
resolved "https://registry.npmmirror.com/@types/license-checker/-/license-checker-25.0.6.tgz#c346285ee7e42bac58a4922059453f50a5d4175d"
|
||||
integrity sha512-ju/75+YPkNE5vX1iPer+qtI1eI/LqJVYZgOsmSHI1iiEM1bQL5Gh1lEvyjR9T7ZXVE1FwJa2doWJEEmPNwbZkw==
|
||||
|
||||
"@types/lodash@^4.17.24":
|
||||
version "4.17.24"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.24.tgz#4ae334fc62c0e915ca8ed8e35dcc6d4eeb29215f"
|
||||
integrity sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==
|
||||
|
||||
"@types/morgan@^1.9.10":
|
||||
version "1.9.10"
|
||||
resolved "https://registry.npmmirror.com/@types/morgan/-/morgan-1.9.10.tgz#725c15d95a5e6150237524cd713bc2d68f9edf1a"
|
||||
@ -3051,7 +3056,7 @@ lodash.once@^4.0.0:
|
||||
resolved "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
||||
|
||||
lodash@^4.17.15, lodash@^4.17.21:
|
||||
lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.23:
|
||||
version "4.17.23"
|
||||
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a"
|
||||
integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user