修改全能创作

This commit is contained in:
Azmat@qq.com
2026-09-15 17:45:28 +08:00
parent 243a3aa54b
commit d4f282bfa9
8 changed files with 1142 additions and 212 deletions
+112 -7
View File
@@ -39,7 +39,9 @@ from .creation_agent import (
apply_confirm_params,
apply_restart_intent,
apply_session_params,
emit_prompt_gate,
emit_final_confirm_gate,
set_plot_twist_story_depth,
is_greeting,
is_restart_intent,
restore_gated_step_after_cancel,
@@ -167,6 +169,56 @@ def _pending_chat_question(conversation: CreationConversation) -> CreationMessag
return None
def _plot_twist_depth_continuation(depth: dict) -> str:
"""让故事深度卡的回答直接进入对应的创作分支。"""
if depth.get("value") == "smart":
return (
"用户选择智能推荐。先根据商品卖点、已有素材和剧情空间推荐 15、30 或 60 秒其中一个,"
"说明一句推荐理由,再调用 ask_user 让用户最终选择实际时长;未确认实际时长前不要给剧情方向、策略或方案。"
)
return (
f"用户已选择:{depth['label']}。立刻按这个故事深度给出 3 个明显不同的剧情方向,"
"每个方向必须写人物关系、开场冲突、商品如何进入剧情、商品承担的作用、最终反转、情绪和偏故事/偏转化;"
"然后调用 ask_user 让用户点击选择或输入自己的想法。不得按默认 15 秒偷换结构。"
)
def _plot_twist_direction_continuation(
conversation: CreationConversation,
payload: dict,
choice: str,
) -> str:
"""保存方向卡的真实内容,再让模型进入策略步骤。"""
direction = next(
(
item for item in (payload.get("directions") or [])
if isinstance(item, dict)
and (str(item.get("id") or "") == choice or str(item.get("title") or "") == choice)
),
None,
)
if isinstance(direction, dict):
title = str(direction.get("title") or choice).strip()
detail = ";".join(
str(direction.get(key) or "").strip()
for key in ("conflict", "product_role", "reversal", "tone")
if str(direction.get(key) or "").strip()
)
else:
title = choice.strip() or "用户自定义方向"
detail = title
memory = dict(conversation.memory or {})
memory["plot_twist_story_direction"] = title
memory["plot_twist_story_direction_detail"] = detail
conversation.memory = memory
conversation.save(update_fields=["memory", "updated_at"])
return (
f"用户已选择剧情方向【{title}】。方向细节:{detail}。"
"现在只调用 write_strategy 写创作策略卡,必须沿用该冲突、商品作用与反转;"
"不要再展示方向卡、不要复述选择、不要直接写方案或出片。"
)
_STEP_CONTINUE_INSTRUCTIONS = {
"strategy": (
"用户已确认创作策略。现在只调用 write_plan 写方案卡(含完整 video_prompt 存档);"
@@ -248,20 +300,17 @@ def _handle_step_confirm_answer(
return None, True, _STEP_CONTINUE_INSTRUCTIONS["strategy"]
if step == "plan":
confirm = emit_final_confirm_gate(conversation)
if confirm is None:
# 兼容旧会话或缓存丢失:让 agent 补齐后台出片指令,再直接给出积分确认。
prompt_messages = emit_prompt_gate(conversation)
if not prompt_messages:
# 兼容旧会话或缓存丢失:让 agent 补齐出片指令,再交给用户确认。
return None, True, _STEP_CONTINUE_INSTRUCTIONS["plan"]
conversation.agent_status = CreationConversation.AgentStatus.AWAITING_USER
conversation.save(update_fields=["agent_status", "updated_at"])
credits = int((confirm.payload or {}).get("estimated_credits") or 0)
body = {
"conversation_id": str(conversation.id),
"agent_status": conversation.agent_status,
"messages": [CreationMessageSerializer(confirm).data],
"messages": [CreationMessageSerializer(message).data for message in prompt_messages],
}
if credits:
body["estimated_credits"] = credits
return JsonResponse(body, status=200), False, ""
if step == "prompt":
@@ -1733,6 +1782,41 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
if short is not None:
return short
# 用户原文仍落库,方便回看;continuation 已带反馈
elif payload.get("interaction") == "plot_twist_story_depth":
# 故事深度卡既可点选,也允许用户直接输入「30 秒」之类的自然回答。
depth = set_plot_twist_story_depth(conversation, text)
if depth is not None:
payload["answers"] = {"story_depth": depth["value"]}
payload["submitted"] = True
payload["answered_via"] = "chat"
pending.payload = payload
pending.save(update_fields=["payload", "updated_at"])
text = ""
record_user_message = False
force_creative_turn = True
continuation_instruction = _plot_twist_depth_continuation(depth)
elif payload.get("interaction") == "plot_twist_directions":
options = [item for item in (payload.get("directions") or []) if isinstance(item, dict)]
chosen = next(
(
item for item in options
if str(item.get("title") or "") in text or str(item.get("id") or "") == text
),
None,
)
choice = str((chosen or {}).get("id") or text).strip()
if choice:
payload["answers"] = {"story_direction": choice}
payload["submitted"] = True
payload["answered_via"] = "chat"
pending.payload = payload
pending.save(update_fields=["payload", "updated_at"])
text = ""
record_user_message = False
force_creative_turn = True
continuation_instruction = _plot_twist_direction_continuation(
conversation, payload, choice
)
elif payload.get("phase") == "gate":
pending_fields = [item for item in (payload.get("pending_fields") or []) if isinstance(item, dict)]
primary_field = pending_fields[0] if pending_fields else {}
@@ -1973,6 +2057,27 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
# 素材选择闸门:用户愿意时再展开列表;跳过则直接沿原任务继续。
if payload.get("interaction") == "step_confirm":
pass # 已在上面处理
elif payload.get("interaction") == "plot_twist_story_depth":
depth = set_plot_twist_story_depth(
conversation,
str(answers.get("story_depth") or ""),
)
if depth is None:
return JsonResponse({"detail": "请选择一个有效的故事深度"}, status=400)
text = ""
record_user_message = False
force_creative_turn = True
continuation_instruction = _plot_twist_depth_continuation(depth)
elif payload.get("interaction") == "plot_twist_directions":
choice = str(answers.get("story_direction") or "").strip()
if not choice:
return JsonResponse({"detail": "请选择一个剧情方向"}, status=400)
text = ""
record_user_message = False
force_creative_turn = True
continuation_instruction = _plot_twist_direction_continuation(
conversation, payload, choice
)
elif payload.get("phase") == "gate":
choice = str(answers.get("_asset_gate") or "").strip()
if choice == "send":