添加艾特角色功能
This commit is contained in:
@@ -38,6 +38,7 @@ from .creation import (
|
||||
from .creation_agent import (
|
||||
_ASSET_CARD_LABELS,
|
||||
_RESTART_CONTINUATION,
|
||||
apply_cast_relation_choice,
|
||||
apply_pain_point_direction,
|
||||
apply_confirm_params,
|
||||
apply_restart_intent,
|
||||
@@ -288,6 +289,14 @@ def _store_click_swap_sequence(conversation: CreationConversation, value: str) -
|
||||
)
|
||||
|
||||
|
||||
def _mark_product_source_resolved(conversation: CreationConversation) -> None:
|
||||
"""用户选择跳过、自动推荐或直接描述商品后,不重复弹同一个商品闸门。"""
|
||||
memory = dict(conversation.memory or {})
|
||||
memory["product_source_resolved"] = True
|
||||
conversation.memory = memory
|
||||
conversation.save(update_fields=["memory", "updated_at"])
|
||||
|
||||
|
||||
_STEP_CONTINUE_INSTRUCTIONS = {
|
||||
"strategy": (
|
||||
"用户已确认创作策略。现在只调用 write_plan 写方案卡(含完整 video_prompt 存档);"
|
||||
@@ -1928,6 +1937,7 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
pending_fields = [item for item in (payload.get("pending_fields") or []) if isinstance(item, dict)]
|
||||
primary_field = pending_fields[0] if pending_fields else {}
|
||||
asset_types = [t for t in (primary_field.get("asset_types") or []) if t in TYPE_LABELS] or ["product"]
|
||||
is_product_gate = "product" in asset_types
|
||||
|
||||
# 1. 用户明确在打字说「发列表/发给我/发卡片/打开列表」
|
||||
if _WANTS_CARD_RE.search(text):
|
||||
@@ -1981,6 +1991,8 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
payload["answered_via"] = "chat"
|
||||
pending.payload = payload
|
||||
pending.save(update_fields=["payload", "updated_at"])
|
||||
if is_product_gate:
|
||||
_mark_product_source_resolved(conversation)
|
||||
|
||||
force_creative_turn = True
|
||||
if hits:
|
||||
@@ -1999,6 +2011,8 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
payload["answered_via"] = "chat"
|
||||
pending.payload = payload
|
||||
pending.save(update_fields=["payload", "updated_at"])
|
||||
if is_product_gate:
|
||||
_mark_product_source_resolved(conversation)
|
||||
|
||||
force_creative_turn = True
|
||||
continuation_instruction = (
|
||||
@@ -2037,6 +2051,8 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
payload["answered_via"] = "chat"
|
||||
pending.payload = payload
|
||||
pending.save(update_fields=["payload", "updated_at"])
|
||||
if is_product_gate:
|
||||
_mark_product_source_resolved(conversation)
|
||||
force_creative_turn = True
|
||||
|
||||
else:
|
||||
@@ -2212,6 +2228,17 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
sequence = str(answers.get("sku_sequence") or "").strip()
|
||||
if not sequence:
|
||||
return JsonResponse({"detail": "请填写要展示的款式和切换顺序"}, status=400)
|
||||
if payload.get("topic") == "cast_relation":
|
||||
choice = str(answers.get("cast_relation") or "").strip()
|
||||
valid_choices = {
|
||||
str(option.get("value") or "")
|
||||
for field in (payload.get("fields") or [])
|
||||
if isinstance(field, dict) and field.get("key") == "cast_relation"
|
||||
for option in (field.get("options") or [])
|
||||
if isinstance(option, dict)
|
||||
}
|
||||
if not choice or choice not in valid_choices:
|
||||
return JsonResponse({"detail": "请选择共同出镜或一位主讲角色"}, status=400)
|
||||
payload["answers"] = answers
|
||||
payload["submitted"] = True
|
||||
card.payload = payload
|
||||
@@ -2278,6 +2305,20 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
record_user_message = False
|
||||
force_creative_turn = True
|
||||
continuation_instruction = _store_click_swap_sequence(conversation, sequence)
|
||||
elif payload.get("topic") == "cast_relation":
|
||||
relation = apply_cast_relation_choice(
|
||||
conversation,
|
||||
str(answers.get("cast_relation") or ""),
|
||||
)
|
||||
if not relation:
|
||||
return JsonResponse({"detail": "这个角色选项已经失效,请重新选择"}, status=400)
|
||||
text = ""
|
||||
record_user_message = False
|
||||
force_creative_turn = True
|
||||
continuation_instruction = (
|
||||
f"商家已确认出镜安排:【{relation}】。保留全部已锁定角色,直接继续原任务;"
|
||||
"后续策略、脚本、分镜和视频分段都严格保持该人物关系,不要再次追问。"
|
||||
)
|
||||
elif payload.get("interaction") == "person_source_gate":
|
||||
source = str(answers.get("person_source") or "").strip()
|
||||
if source == "platform_generate":
|
||||
@@ -2322,10 +2363,12 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
)
|
||||
elif payload.get("phase") == "gate":
|
||||
choice = str(answers.get("_asset_gate") or "").strip()
|
||||
pending = payload.get("pending_fields") or []
|
||||
primary_field = pending[0] if pending else {}
|
||||
gate_types = [item for item in (primary_field.get("asset_types") or []) if item in TYPE_LABELS] or ["product"]
|
||||
is_product_gate = "product" in gate_types
|
||||
if choice == "send":
|
||||
pending = payload.get("pending_fields") or []
|
||||
primary_field = pending[0] if pending else {}
|
||||
types = [t for t in (primary_field.get("asset_types") or []) if t in TYPE_LABELS] or ["product"]
|
||||
types = gate_types
|
||||
pick_field = dict(primary_field)
|
||||
pick_field["label"] = _ASSET_CARD_LABELS.get(
|
||||
types[0], _ASSET_CARD_LABELS.get("asset", "请选择素材")
|
||||
@@ -2352,10 +2395,7 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
"messages": [CreationMessageSerializer(pick).data],
|
||||
}, status=200)
|
||||
elif choice == "auto":
|
||||
pending = payload.get("pending_fields") or []
|
||||
primary_field = pending[0] if pending else {}
|
||||
types = [item for item in (primary_field.get("asset_types") or []) if item in TYPE_LABELS] or ["product"]
|
||||
hits = search_mentions(conversation.team, q="", types=types, limit=1)
|
||||
hits = search_mentions(conversation.team, q="", types=gate_types, limit=1)
|
||||
if hits:
|
||||
refs = list(refs)
|
||||
refs.append(hits[0])
|
||||
@@ -2369,12 +2409,16 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
text = ""
|
||||
record_user_message = False
|
||||
force_creative_turn = True
|
||||
if is_product_gate:
|
||||
_mark_product_source_resolved(conversation)
|
||||
else:
|
||||
# 卡片本身已经记录了用户的选择。不要再伪造一条黑色用户气泡;
|
||||
# 继续原任务,并明确告诉模型不要再次追问同一项素材。
|
||||
text = ""
|
||||
record_user_message = False
|
||||
force_creative_turn = True
|
||||
if is_product_gate:
|
||||
_mark_product_source_resolved(conversation)
|
||||
continuation_instruction = (
|
||||
"用户刚选择暂不添加这项素材。接受这个选择,按会话里已有的需求和合理默认继续原任务。"
|
||||
"先用一句自然的话承接,随后直接推进创作;不要再次追问同一素材,不要只说收到或有需要再说。"
|
||||
|
||||
Reference in New Issue
Block a user