Opentu 项目概念文档
本文档定义了 Opentu 项目的核心概念和术语,确保团队成员在开发过程中保持一致的理解。
一、项目定位
Opentu(开图) 是一个以画布为核心工作区底座的开源 AI应用平台。
Opentu 的平台结构分为四层:
- 工作区层:画布、视口、元素、项目组织
- 应用层:图片、视频、灵感板、思维导图、流程图、知识库、工具箱、Agent/Skill
- 运行层:模型路由、任务队列、工作流执行、缓存与同步
- 开放层:插件化、开源、可部署、可扩展
画布仍然是产品骨架,但在品牌与概念体系里,它承担的是 工作区底座,而不是旧意义上的全部产品定义。
- 官网: https://opentu.ai
- 版本: 0.6.x
- 许可证: MIT
- 定位短句: 在同一工作区中连接模型、工具、知识与工作流
- 技术栈: React + TypeScript + Plait + Vite + Nx (Monorepo)
二、核心概念术语表
2.1 工作区层概念
| 术语 |
英文 |
定义 |
关键文件 |
| 画板 (Board) |
Board |
工作区中的单个画布页面,包含元素集合、视口状态和主题配置 |
workspace.types.ts |
| 元素 (Element) |
PlaitElement |
画板上的基本单位,如图片、图形、文字、视频等 |
@plait/core |
| 视口 (Viewport) |
Viewport |
画布的可视区域状态,包含缩放比例和偏移位置 |
@plait/core |
| 文件夹 (Folder) |
Folder |
组织画板的容器,支持嵌套结构 |
workspace.types.ts |
| 工作区 (Workspace) |
Workspace |
管理所有文件夹、画板与平台 UI 状态的顶层容器 |
workspace.types.ts |
| 画布工作区 |
Canvas Workspace |
面向用户的统一操作界面,承载 AI 应用与内容组织 |
drawnix.tsx |
层级关系:
2.2 AI 生成概念
| 术语 |
英文 |
定义 |
关键文件 |
| 任务 (Task) |
Task |
AI 生成的基本执行单位,有状态生命周期 |
task.types.ts |
| 任务类型 (TaskType) |
TaskType |
任务分类:IMAGE / VIDEO / CHARACTER / CHAT / INSPIRATION_BOARD |
task.types.ts |
| 任务状态 (TaskStatus) |
TaskStatus |
任务生命周期状态 |
task.types.ts |
| 任务队列 (TaskQueue) |
TaskQueue |
管理所有任务的队列系统,运行在 Service Worker 中 |
sw/task-queue/ |
| 远程 ID (RemoteId) |
remoteId |
服务端返回的任务标识,用于轮询和恢复 |
task.types.ts |
| 执行阶段 (ExecutionPhase) |
TaskExecutionPhase |
任务执行的细分阶段:SUBMITTING / POLLING / DOWNLOADING |
task.types.ts |
任务状态流转:
任务类型说明:
IMAGE: 图片生成任务
VIDEO: 视频生成任务
CHARACTER: 角色提取任务 (Sora-2 专属)
CHAT: 聊天/AI 分析任务
INSPIRATION_BOARD: 灵感板生成任务 (图片生成 + 分割 + 布局)
2.3 工作流概念
| 术语 |
英文 |
定义 |
关键文件 |
| 工作流 (Workflow) |
Workflow |
包含多个步骤的任务执行计划 |
workflow-types.ts |
| 工作流步骤 (WorkflowStep) |
WorkflowStep |
工作流中的单个 MCP 工具调用 |
workflow-types.ts |
| WorkZone |
WorkZone |
画布上显示工作流进度的特殊元素 |
workzone.types.ts |
| MCP 工具 |
MCPTool |
Model Context Protocol 工具,执行具体的 AI 操作 |
mcp/types.ts |
| 工作流上下文 |
WorkflowContext |
工作流的执行环境信息 |
workflow-types.ts |
工作流执行流程:
步骤状态:
pending: 待执行
running: 执行中
completed: 已完成
failed: 执行失败
skipped: 跳过执行
2.4 素材库概念
| 术语 |
英文 |
定义 |
关键文件 |
| 素材 (Asset) |
Asset |
媒体库中的图片或视频资源 |
asset.types.ts |
| 素材类型 (AssetType) |
AssetType |
素材分类:IMAGE / VIDEO |
asset.types.ts |
| 素材来源 (AssetSource) |
AssetSource |
素材来源:LOCAL / AI_GENERATED |
asset.types.ts |
| 统一缓存 (UnifiedCache) |
UnifiedCache |
协调 Cache Storage 和 IndexedDB 的缓存服务 |
unified-cache-service.ts |
| 存储素材 (StoredAsset) |
StoredAsset |
IndexedDB 中存储的素材元数据 |
asset.types.ts |
素材来源说明:
LOCAL: 用户从本地上传的素材
AI_GENERATED: 通过 AI 生成的素材
数据来源优先级:
- 本地上传素材 ← IndexedDB 元数据 + Cache Storage 实际数据
- AI 生成素材 ← 任务队列已完成任务
- Cache Storage 媒体 ← 虚拟路径缓存
2.5 聊天与对话概念
| 术语 |
英文 |
定义 |
关键文件 |
| 对话会话 (Session) |
ChatSession |
一个独立的对话上下文 |
chat.types.ts |
| 消息 (Message) |
ChatMessage |
对话中的单条消息 |
chat.types.ts |
| 消息角色 (Role) |
MessageRole |
消息发送者:USER / ASSISTANT |
chat.types.ts |
| 消息状态 (MessageStatus) |
MessageStatus |
消息发送状态 |
chat.types.ts |
| AI 输入上下文 |
AIInputContext |
用户输入的完整解析结果 |
chat.types.ts |
| 附件 (Attachment) |
Attachment |
消息中附带的文件 |
chat.types.ts |
消息状态:
sending: 发送中
streaming: 流式接收中
success: 发送成功
failed: 发送失败
AIInputContext 结构:
2.6 模型概念
| 术语 |
英文 |
定义 |
关键文件 |
| 模型类型 (ModelType) |
ModelType |
模型分类:image / video / text |
model-config.ts |
| 模型配置 (ModelConfig) |
ModelConfig |
模型的完整配置信息 |
model-config.ts |
| 短代码 (ShortCode) |
shortCode |
模型快捷标识,如 nbpv、veo3 |
model-config.ts |
| 参数配置 (ParamConfig) |
ParamConfig |
模型参数的配置信息 |
model-config.ts |
模型分类:
image: 图片生成模型 (Gemini Imagen, GPT Image)
video: 视频生成模型 (Veo3, Sora-2)
text: 文本/Agent 模型 (DeepSeek, Claude, Gemini)
常用短代码:
| 短代码 |
模型 |
类型 |
nbpv |
nano-banana-pro-vip |
图片 |
nb |
nano-banana |
图片 |
veo3 |
Veo 3 |
视频 |
sora-2 |
Sora 2 |
视频 |
2.7 角色概念 (Sora 专属)
| 术语 |
英文 |
定义 |
关键文件 |
| 角色 (Character) |
SoraCharacter |
从 Sora-2 视频中提取的可复用人物 |
character.types.ts |
| 角色状态 (CharacterStatus) |
CharacterStatus |
角色创建生命周期状态 |
character.types.ts |
| 时间戳范围 |
characterTimestamps |
角色提取的视频时间范围 (格式: "start,end") |
character.types.ts |
角色使用方式:
- 通过
@username 在提示词中引用角色
- 角色提取需要 1-3 秒的视频片段
2.8 工具箱概念
| 术语 |
英文 |
定义 |
关键文件 |
| 工具定义 (ToolDefinition) |
ToolDefinition |
工具箱中工具的配置信息 |
toolbox.types.ts |
| 工具元素 (PlaitTool) |
PlaitTool |
画布上的工具实例(iframe 容器) |
toolbox.types.ts |
| 工具窗口 (ToolWindow) |
ToolWindowState |
浮窗形式打开的工具状态 |
toolbox.types.ts |
| 工具分类 (ToolCategory) |
ToolCategory |
工具分类枚举 |
toolbox.types.ts |
工具分类:
AI_TOOLS: AI 工具(提示词、生成等)
CONTENT_TOOLS: 内容工具(文案、素材等)
UTILITIES: 实用工具(批处理、转换等)
CUSTOM: 自定义工具
2.9 平台分层概念
| 术语 |
英文 |
定义 |
| 应用层 |
Application Layer |
面向用户的能力模块,如图片、视频、知识库、工具箱、Agent |
| 运行层 |
Runtime Layer |
支撑应用运行的任务队列、模型路由、缓存、工作流 |
| 开放层 |
Extensibility Layer |
插件、部署、开源与扩展机制 |
三、架构分层概念
3.1 应用层 (apps/web)
| 模块 |
文件 |
职责 |
| 主入口 |
main.tsx |
应用启动、Service Worker 注册 |
| App 组件 |
app.tsx |
工作区管理、数据加载 |
| Service Worker |
sw/index.ts |
后台任务执行、缓存管理 |
| 任务队列 |
sw/task-queue/ |
任务调度、执行器 |
3.2 核心库 (packages/drawnix)
| 模块 |
目录 |
职责 |
| 主组件 |
drawnix.tsx |
编辑器主入口组件 |
| 插件 |
plugins/ |
功能扩展插件 (withXxx 模式) |
| 服务 |
services/ |
业务逻辑服务 |
| 钩子 |
hooks/ |
React 状态管理 |
| MCP 工具 |
mcp/ |
AI 工具系统 |
| 组件 |
components/ |
UI 组件库 |
| 类型 |
types/ |
TypeScript 类型定义 |
| 常量 |
constants/ |
配置常量 |
| 工具 |
utils/ |
工具函数 |
3.3 适配层
| 包 |
职责 |
packages/react-board |
Plait Board 的 React 适配 |
packages/react-text |
Slate 文本编辑的 React 适配 |
packages/utils |
共享工具函数 |
四、数据流概念
4.1 AI 生成数据流
4.2 素材库数据流
4.3 虚拟路径规范
| 路径前缀 |
用途 |
示例 |
/__aitu_cache__/image/ |
AI 生成图片、合并图片、分割图片 |
/__aitu_cache__/image/task-123.png |
/__aitu_cache__/video/ |
AI 生成视频 |
/__aitu_cache__/video/task-456.mp4 |
/asset-library/ |
本地上传素材 |
/asset-library/asset-789.jpg |
重要规则:
- 虚拟路径由 Service Worker 拦截并从 Cache Storage 返回
- 存储时使用相对路径作为缓存 key,确保一致性
- 查询时支持完整 URL 和相对路径的匹配
五、状态管理概念
5.1 React Context
| Context |
职责 |
提供者位置 |
DrawnixContext |
编辑器全局状态(指针模式、弹窗状态等) |
drawnix.tsx |
WorkflowContext |
工作流执行状态 |
drawnix.tsx |
AssetContext |
素材库状态和操作 |
drawnix.tsx |
ChatDrawerContext |
聊天抽屉状态 |
drawnix.tsx |
RecentColorsProvider |
最近使用颜色 |
drawnix.tsx |
I18nProvider |
国际化 |
drawnix.tsx |
ToolbarConfigProvider |
工具栏配置 |
drawnix.tsx |
5.2 持久化存储
| 存储方式 |
用途 |
API |
| LocalForage (IndexedDB) |
画板数据、会话消息、素材元数据、任务数据 |
localforage |
| Cache Storage |
媒体文件实际内容 |
caches.open() |
| localStorage |
设置配置、UI 状态 |
localStorage |
存储 Key 规范:
- 画板:
boards-{id}
- 文件夹:
folders-{id}
- 会话:
chat-sessions-{id}
- 消息:
chat-messages-{sessionId}
- 素材元数据:
assets-{id}
六、UI 层级概念 (Z-Index)
| 层级 |
范围 |
用途 |
示例 |
| Layer 0 |
0-999 |
基础画布元素 |
画布内容 |
| Layer 1 |
1000-1999 |
画布装饰元素 |
选中框 |
| Layer 2 |
2000-2999 |
工具栏 |
UnifiedToolbar |
| Layer 3 |
3000-3999 |
Popover / Tooltip |
弹出菜单 |
| Layer 4 |
4000-4999 |
抽屉 / 面板 |
TaskQueue, ChatDrawer |
| Layer 5 |
5000-5999 |
弹窗 / Dialog |
AI 生成弹窗 |
| Layer 6 |
6000-6999 |
通知 |
任务警告 |
| Layer 7 |
7000-7999 |
认证弹窗 |
登录框 |
| Layer 8 |
8000-8999 |
图片查看器 |
ImageViewer |
| Layer 9 |
9000+ |
系统级覆盖层 |
加载遮罩 |
使用规范:
- TypeScript: 从
constants/z-index.ts 导入 Z_INDEX
- SCSS: 从
styles/z-index.scss 导入 $z-* 变量
七、命名规范
7.1 文件命名
| 类型 |
规范 |
示例 |
| 组件 |
PascalCase.tsx |
ImageCropPopup.tsx |
| Hooks |
camelCase.ts (use 前缀) |
useImageCrop.ts |
| 服务 |
kebab-case-service.ts |
workspace-service.ts |
| 工具函数 |
kebab-case.ts |
image-utils.ts |
| 类型定义 |
kebab-case.types.ts |
task.types.ts |
| 常量 |
UPPER_SNAKE_CASE.ts |
TASK_CONSTANTS.ts |
| 样式 |
kebab-case.scss |
ai-input-bar.scss |
7.2 变量命名
| 类型 |
规范 |
示例 |
| 组件 |
PascalCase |
AIInputBar |
| 函数 |
camelCase |
handleSubmit |
| 常量 |
UPPER_SNAKE_CASE |
MAX_RETRY_COUNT |
| 类型/接口 |
PascalCase |
TaskStatus |
| 枚举值 |
UPPER_SNAKE_CASE |
TaskType.IMAGE |
| CSS 类名 |
kebab-case (BEM) |
.ai-input-bar__container |
7.3 事件命名
| 类型 |
规范 |
示例 |
| CustomEvent |
kebab-case |
ai-generation-complete |
| 追踪事件 |
snake_case |
toolbar_click_save |
| 回调 Props |
on + PascalCase |
onSubmit, onChange |
八、关键概念辨析
8.1 Task vs Workflow
| 维度 |
Task |
Workflow |
| 定义 |
单个 AI 生成任务 |
多步骤执行计划 |
| 粒度 |
原子操作 |
组合操作 |
| 状态 |
独立状态和结果 |
整体状态 + 步骤状态 |
| 创建方 |
TaskQueue |
WorkflowExecutor |
| 关系 |
一个 Workflow 可创建多个 Task |
- |
8.2 Board vs Workspace
| 维度 |
Board |
Workspace |
| 定义 |
单个画板 |
平台中的统一工作区容器 |
| 内容 |
元素、视口、主题 |
文件夹、画板、UI 状态 |
| 持久化 |
独立存储 |
状态存储 |
| 切换 |
可以切换当前画板 |
唯一实例 |
8.3 Asset vs Task Result
| 维度 |
Asset |
Task Result |
| 定义 |
素材库中的资源 |
任务的输出结果 |
| 元数据 |
完整(名称、来源、类型等) |
基本(URL、格式、尺寸) |
| 来源 |
本地上传 / AI 生成 |
仅 AI 生成 |
| 转换 |
Task Result 可转换为 Asset |
- |
8.4 MCP Tool vs Built-in Tool
| 维度 |
MCP Tool |
Built-in Tool |
| 定义 |
AI 相关工具 |
工具箱中的外部工具 |
| 实现 |
函数执行 |
iframe 嵌入 |
| 示例 |
generate_image, ai_analyze |
香蕉提示词、素材网站 |
| 调用 |
通过工作流步骤 |
用户手动打开 |
8.5 Service Worker 通信
| 消息方向 |
类型前缀 |
示例 |
| 主线程 → SW |
TASK_*, WORKFLOW_* |
TASK_SUBMIT, WORKFLOW_CANCEL |
| SW → 主线程 |
TASK_*, WORKFLOW_* |
TASK_COMPLETED, WORKFLOW_STEP_STATUS |
九、插件系统概念
9.1 插件模式
Opentu 使用 withXxx 模式扩展 Plait Board 功能:
9.2 核心插件列表
| 插件 |
功能 |
withDraw |
基础绘图能力 |
withMind |
思维导图支持 |
withFreehand |
自由绘画 |
withPen |
钢笔工具 |
withVideo |
视频元素支持 |
withTool |
工具元素(iframe) |
withWorkZone |
WorkZone 元素 |
withHotkey |
快捷键处理 |
withTextLink |
文本链接 |
withTextPaste |
文本粘贴 |
withImage |
图片粘贴 |
withTracking |
数据追踪 |
十、MCP 工具系统
10.1 工具注册
MCP 工具在 mcp/registry.ts 中注册:
10.2 工具接口
10.3 执行模式
| 模式 |
说明 |
使用场景 |
async |
同步等待 API 返回 |
快速操作 |
queue |
加入任务队列 |
长时间生成任务 |
十一、Service Worker 架构
11.1 核心职责
- 任务队列管理: 处理 AI 生成任务
- 缓存管理: 预缓存静态资源、缓存媒体文件
- 工作流执行: 执行多步骤工作流
- 消息通信: 与主线程双向通信
11.2 关键模块
| 模块 |
文件 |
职责 |
| 主入口 |
sw/index.ts |
SW 生命周期、fetch 拦截 |
| 任务队列 |
sw/task-queue/queue.ts |
任务调度 |
| 任务存储 |
sw/task-queue/storage.ts |
IndexedDB 持久化 |
| 处理器 |
sw/task-queue/handlers/ |
具体任务执行 |
| 工作流执行器 |
sw/task-queue/workflow-executor.ts |
工作流执行 |
11.3 消息协议
十二、附录
12.1 相关文档
12.2 类型定义文件索引
| 概念领域 |
文件路径 |
| 任务系统 |
packages/drawnix/src/types/task.types.ts |
| 工作区 |
packages/drawnix/src/types/workspace.types.ts |
| 素材库 |
packages/drawnix/src/types/asset.types.ts |
| 聊天 |
packages/drawnix/src/types/chat.types.ts |
| WorkZone |
packages/drawnix/src/types/workzone.types.ts |
| 角色 |
packages/drawnix/src/types/character.types.ts |
| 工具箱 |
packages/drawnix/src/types/toolbox.types.ts |
| MCP |
packages/drawnix/src/mcp/types.ts |
| 工作流 |
apps/web/src/sw/task-queue/workflow-types.ts |
| 模型配置 |
packages/drawnix/src/constants/model-config.ts |