全能创作与模特库收口:品牌品名输入、确认角色循环、换款落点与鱼眼模板
补充品牌品名改为预填输入框且空骨架不跳步;痛点确认角色后「继续完善方案」可继续推进;点击换款要求每次落点不同;鱼眼换装改用小云雀连环换装 prompt 模板;模特详情标签自动换行。
This commit is contained in:
@@ -58,6 +58,8 @@ from .creation_agent import (
|
||||
submit_confirmed_image,
|
||||
submit_confirmed_video,
|
||||
submit_generated_person_reference,
|
||||
is_incomplete_product_brand_answer,
|
||||
PRODUCT_BRAND_EMPTY_TEMPLATE,
|
||||
)
|
||||
from .tasks import run_creation_agent_turn_task
|
||||
from .mentions import TYPE_LABELS, VALID_TYPES, refs_from_elicit_answers, search_mentions
|
||||
@@ -2237,6 +2239,20 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
fields = [item for item in (payload.get("fields") or []) if isinstance(item, dict)]
|
||||
if fields:
|
||||
field = fields[0]
|
||||
if payload.get("topic") == "product_info":
|
||||
clean_probe = text.strip()
|
||||
design_from_image = any(
|
||||
kw in clean_probe for kw in ("按图片", "设计品牌", "不用再问")
|
||||
)
|
||||
if (not design_from_image) and is_incomplete_product_brand_answer(clean_probe):
|
||||
conversation.agent_status = CreationConversation.AgentStatus.AWAITING_USER
|
||||
conversation.save(update_fields=["agent_status", "updated_at"])
|
||||
return JsonResponse({
|
||||
"conversation_id": str(conversation.id),
|
||||
"agent_status": conversation.agent_status,
|
||||
"detail": "请填写品牌和品名后再发送,例如「品牌浅蓝小熊,品名婴儿柔湿巾」。",
|
||||
"messages": [CreationMessageSerializer(pending).data],
|
||||
}, status=200)
|
||||
answers = {
|
||||
str(field.get("key") or "answer"):
|
||||
_chat_answer_for_field(field, text, conversation.team)
|
||||
@@ -2270,8 +2286,20 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
elif payload.get("topic") == "product_info":
|
||||
clean_ans = text.strip()
|
||||
memory = dict(conversation.memory or {})
|
||||
memory["product_info_resolved"] = True
|
||||
if clean_ans and not any(kw in clean_ans for kw in ("按图片", "设计品牌", "不用再问")):
|
||||
design_from_image = any(kw in clean_ans for kw in ("按图片", "设计品牌", "不用再问"))
|
||||
if design_from_image:
|
||||
memory["product_info_resolved"] = True
|
||||
continuation_instruction = (
|
||||
"用户要求直接根据图片内容设计品牌与品名推进创作。"
|
||||
"直接基于图片外观特征推进方案,不要重复追问品牌。"
|
||||
)
|
||||
elif is_incomplete_product_brand_answer(clean_ans):
|
||||
memory.pop("product_info_resolved", None)
|
||||
continuation_instruction = (
|
||||
"用户尚未填写完整品牌与品名。请继续请他补充,不要进入下一步。"
|
||||
)
|
||||
else:
|
||||
memory["product_info_resolved"] = True
|
||||
memory["product_brand_and_name"] = clean_ans
|
||||
bm = re.search(r"品牌[::是为]?\s*([^\n,,。!!]+)", clean_ans)
|
||||
nm = re.search(r"(?:品名|商品名|产品名)[::是为]?\s*([^\n,,。!!]+)", clean_ans)
|
||||
@@ -2284,9 +2312,10 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
r["name"] = clean_ans
|
||||
break
|
||||
conversation.pinned_refs = conversation.pinned_refs
|
||||
continuation_instruction = f"用户已提供商品品牌与品名:【{clean_ans}】。直接围绕该商品推进方案,不要重复追问。"
|
||||
else:
|
||||
continuation_instruction = "用户要求直接根据图片内容设计品牌与品名推进创作。直接基于图片外观特征推进方案,不要重复追问品牌。"
|
||||
continuation_instruction = (
|
||||
f"用户已提供商品品牌与品名:【{clean_ans}】。"
|
||||
"直接围绕该商品推进方案,不要重复追问。"
|
||||
)
|
||||
conversation.memory = memory
|
||||
conversation.save(update_fields=["memory", "pinned_refs", "updated_at"])
|
||||
# 保留用户原文气泡,便于回看刚填的品牌/品名;不要清空 text,
|
||||
@@ -2331,8 +2360,11 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
conversation.save(update_fields=["memory", "updated_at"])
|
||||
force_creative_turn = True
|
||||
continuation_instruction = (
|
||||
"用户已确认使用当前生成的角色出镜。直接基于该角色继续推进创作方案"
|
||||
"(若尚未选商品则确定商品,已选好商品则开始写创作策略和方案),不要再次追问角色来源。"
|
||||
"用户已确认使用当前生成的角色出镜。"
|
||||
"本轮必须实质推进创作:若还缺商品则 ask_user 选商品;"
|
||||
"痛点解决演示若还缺痛点方向则 ask_user(pain_point_direction);"
|
||||
"信息够了就立刻 write_strategy。"
|
||||
"禁止只回一句「可以回复继续完善方案」之类的空引导,也不要再次追问角色来源。"
|
||||
)
|
||||
elif is_platform_person and (regenerate_button or (person_confirm_pending and clean_text and not upload_person)):
|
||||
prev_prompt = str(memory_now.get("person_prompt") or "").strip()
|
||||
@@ -2662,24 +2694,45 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
elif payload.get("topic") == "product_info":
|
||||
ans = str(answers.get("product_brand_and_name") or "").strip()
|
||||
memory = dict(conversation.memory or {})
|
||||
memory["product_info_resolved"] = True
|
||||
clean_ans = ans.replace("品牌是:,商品名是:", "").strip()
|
||||
if clean_ans and not any(kw in clean_ans for kw in ("按图片", "设计品牌", "不用再问")):
|
||||
memory["product_brand_and_name"] = clean_ans
|
||||
bm = re.search(r"品牌[::是为]?\s*([^\n,,。!!]+)", clean_ans)
|
||||
nm = re.search(r"(?:品名|商品名|产品名)[::是为]?\s*([^\n,,。!!]+)", clean_ans)
|
||||
design_from_image = any(kw in ans for kw in ("按图片", "设计品牌", "不用再问"))
|
||||
clean_ans = ans.replace(PRODUCT_BRAND_EMPTY_TEMPLATE, "").strip()
|
||||
if (not design_from_image) and is_incomplete_product_brand_answer(ans):
|
||||
payload["submitted"] = False
|
||||
payload["answers"] = {}
|
||||
pending.payload = payload
|
||||
pending.save(update_fields=["payload", "updated_at"])
|
||||
conversation.agent_status = CreationConversation.AgentStatus.AWAITING_USER
|
||||
conversation.save(update_fields=["agent_status", "updated_at"])
|
||||
return JsonResponse({
|
||||
"conversation_id": str(conversation.id),
|
||||
"agent_status": conversation.agent_status,
|
||||
"detail": "请填写品牌和品名后再发送,例如「品牌浅蓝小熊,品名婴儿柔湿巾」。",
|
||||
"messages": [CreationMessageSerializer(pending).data],
|
||||
}, status=200)
|
||||
if design_from_image:
|
||||
memory["product_info_resolved"] = True
|
||||
continuation_instruction = (
|
||||
"用户要求直接根据图片内容设计品牌与品名推进创作。"
|
||||
"直接基于图片外观特征推进方案,不要重复追问品牌。"
|
||||
)
|
||||
else:
|
||||
memory["product_info_resolved"] = True
|
||||
memory["product_brand_and_name"] = clean_ans or ans
|
||||
bm = re.search(r"品牌[::是为]?\s*([^\n,,。!!]+)", clean_ans or ans)
|
||||
nm = re.search(r"(?:品名|商品名|产品名)[::是为]?\s*([^\n,,。!!]+)", clean_ans or ans)
|
||||
if bm:
|
||||
memory["product_brand"] = bm.group(1).strip()
|
||||
if nm:
|
||||
memory["product_name"] = nm.group(1).strip()
|
||||
for r in (conversation.pinned_refs or []):
|
||||
if isinstance(r, dict) and r.get("type") in ("asset", "product"):
|
||||
r["name"] = clean_ans
|
||||
r["name"] = clean_ans or ans
|
||||
break
|
||||
conversation.pinned_refs = conversation.pinned_refs
|
||||
continuation_instruction = f"用户已提供商品品牌与品名:【{clean_ans}】。直接围绕该商品推进方案,不要重复追问。"
|
||||
else:
|
||||
continuation_instruction = "用户要求直接根据图片内容设计品牌与品名推进创作。直接基于图片外观特征推进方案,不要重复追问品牌。"
|
||||
continuation_instruction = (
|
||||
f"用户已提供商品品牌与品名:【{clean_ans or ans}】。"
|
||||
"直接围绕该商品推进方案,不要重复追问。"
|
||||
)
|
||||
conversation.memory = memory
|
||||
conversation.save(update_fields=["memory", "pinned_refs", "updated_at"])
|
||||
text = ""
|
||||
|
||||
Reference in New Issue
Block a user