添加全能创作功能
This commit is contained in:
@@ -279,3 +279,108 @@ class PromptTemplate(TimeStampedModel):
|
||||
def __str__(self) -> str:
|
||||
return f"prompt:{self.key}"
|
||||
|
||||
|
||||
class CreationConversation(TeamOwnedModel):
|
||||
"""全能创作的会话。一条会话 = 一次完整创作(可多轮改稿、多次出图/出片)。
|
||||
|
||||
和 ImageConversation 的区别:那张表只是「生图线程」,没有消息实体,历史靠 AITask 拼;
|
||||
这里是真对话,消息落 CreationMessage。两者并存,互不影响(图片工作台仍走旧表)。
|
||||
|
||||
mode 发起时定死,会话内不可切(设计稿顶栏的模型/分辨率/比例跟着 mode 固定)。
|
||||
pinned_refs 是「实体锁定」:本会话引用过的商品/角色/场景,每轮无条件带进上下文 ——
|
||||
这是多次生成之间锁脸、锁商品的唯一手段,别省。
|
||||
"""
|
||||
|
||||
class Mode(models.TextChoices):
|
||||
VIDEO = "video", "视频创作"
|
||||
IMAGE = "image", "图片创作"
|
||||
|
||||
class Status(models.TextChoices):
|
||||
RUNNING = "running", "进行中"
|
||||
COMPLETED = "completed", "已完成"
|
||||
FAILED = "failed", "失败"
|
||||
|
||||
title = models.CharField(max_length=120, default="未命名创作")
|
||||
mode = models.CharField(max_length=16, choices=Mode.choices, default=Mode.VIDEO)
|
||||
preset = models.CharField(max_length=64, blank=True, default="") # "" = 自由创作
|
||||
# 会话级参数:{model, resolution, ratio, duration} —— 设计稿顶栏 meta 就渲染它
|
||||
params = models.JSONField(default=dict, blank=True)
|
||||
# 实体锁定:[Ref],见契约 §1。每轮无条件带上
|
||||
pinned_refs = models.JSONField(default=list, blank=True)
|
||||
# 记忆:{summary, artifacts:[{msg_id,asset_id,prompt,kind}], turn_count}
|
||||
memory = models.JSONField(default=dict, blank=True)
|
||||
status = models.CharField(max_length=16, choices=Status.choices, default=Status.RUNNING)
|
||||
last_active_at = models.DateTimeField(auto_now_add=True)
|
||||
is_deleted = models.BooleanField(default=False)
|
||||
purged_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
# 创作历史页:按团队 + 最近活跃倒序
|
||||
models.Index(fields=["team", "-last_active_at"]),
|
||||
models.Index(fields=["team", "status", "-last_active_at"]),
|
||||
models.Index(fields=["team", "is_deleted", "purged_at"]),
|
||||
]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"creation:{self.mode}:{self.title}"
|
||||
|
||||
|
||||
class CreationMessage(TimeStampedModel):
|
||||
"""全能创作对话流里的一条消息。kind 决定前端渲染成哪种卡片(见契约 §2)。
|
||||
|
||||
text 只给 TEXT 用;其余 kind 的内容全在 payload 里 —— 前端按 kind 走不同组件,
|
||||
别把结构化内容塞进 text 再让前端解析。
|
||||
|
||||
生成类消息(GENERATING / RESULT)挂 task:提交时先落一条 GENERATING,
|
||||
轮询到终态后**原地改成 RESULT**(不新增消息),这样对话流不会被中间态刷屏。
|
||||
"""
|
||||
|
||||
class Role(models.TextChoices):
|
||||
USER = "user", "用户"
|
||||
ASSISTANT = "assistant", "AI"
|
||||
SYSTEM = "system", "系统"
|
||||
|
||||
class Kind(models.TextChoices):
|
||||
TEXT = "text", "文字气泡"
|
||||
ELICIT = "elicit", "追问卡" # AI 反问用户,带 单选/多选/填空/选素材 控件
|
||||
STRATEGY = "strategy", "创作策略理解卡"
|
||||
PLAN = "plan", "视频最终方案卡"
|
||||
PROMPT_FILE = "prompt_file", "生成 Prompt 文件卡"
|
||||
CONFIRM = "confirm", "确认闸门(带预计积分)"
|
||||
GENERATING = "generating", "生成中"
|
||||
RESULT = "result", "生成结果"
|
||||
ERROR = "error", "错误"
|
||||
|
||||
conversation = models.ForeignKey(
|
||||
CreationConversation, on_delete=models.CASCADE, related_name="messages"
|
||||
)
|
||||
role = models.CharField(max_length=16, choices=Role.choices)
|
||||
kind = models.CharField(max_length=24, choices=Kind.choices, default=Kind.TEXT)
|
||||
text = models.TextField(blank=True, default="")
|
||||
payload = models.JSONField(default=dict, blank=True)
|
||||
# 本条消息引用的实体:[Ref]。用 id 取事实与参考图,不许只存 "@商品名" 字符串
|
||||
refs = models.JSONField(default=list, blank=True)
|
||||
task = models.ForeignKey(
|
||||
AITask,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="creation_messages",
|
||||
)
|
||||
# 会话内自增渲染序;并发插入靠 select_for_update 取 max+1
|
||||
seq = models.PositiveIntegerField(default=0)
|
||||
|
||||
class Meta:
|
||||
ordering = ["seq", "created_at"]
|
||||
indexes = [
|
||||
models.Index(fields=["conversation", "seq"]),
|
||||
]
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["conversation", "seq"], name="uniq_creation_message_seq"
|
||||
),
|
||||
]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"msg:{self.kind}:{self.seq}"
|
||||
|
||||
Reference in New Issue
Block a user