Spaces:
Runtime error
Runtime error
Upload app.py
Browse files
app.py
CHANGED
|
@@ -188,6 +188,27 @@ def process_user_input(user_input: str, chat_history: list, game_session: dict):
|
|
| 188 |
# 1. NLU 解析
|
| 189 |
intent = nlu.parse_intent(user_input)
|
| 190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
# 2. 添加用户消息 + 空的 assistant 消息(用于流式填充)
|
| 192 |
chat_history.append({"role": "user", "content": user_input})
|
| 193 |
chat_history.append({"role": "assistant", "content": "⏳ 正在生成..."})
|
|
@@ -570,15 +591,43 @@ def _format_status_panel(gs: GameState) -> str:
|
|
| 570 |
else:
|
| 571 |
inventory_text = "空"
|
| 572 |
|
| 573 |
-
# 活跃任务
|
| 574 |
active_quests = [q for q in w.quests.values() if q.status == "active"]
|
| 575 |
if active_quests:
|
| 576 |
-
|
| 577 |
for q in active_quests:
|
| 578 |
done = sum(1 for v in q.objectives.values() if v)
|
| 579 |
total = len(q.objectives)
|
| 580 |
-
|
| 581 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 582 |
else:
|
| 583 |
quest_text = "无活跃任务"
|
| 584 |
|
|
@@ -640,7 +689,7 @@ def _format_status_panel(gs: GameState) -> str:
|
|
| 640 |
</span>
|
| 641 |
</div>
|
| 642 |
|
| 643 |
-
<div>
|
| 644 |
<h4 style="margin:4px 0 2px 0;">📜 任务</h4>
|
| 645 |
<span style="font-size:0.85em;">
|
| 646 |
{quest_text}
|
|
|
|
| 188 |
# 1. NLU 解析
|
| 189 |
intent = nlu.parse_intent(user_input)
|
| 190 |
|
| 191 |
+
# 1.5 预校验:立即驳回违反一致性的操作(不调用 LLM,不消耗回合)
|
| 192 |
+
is_valid, rejection_msg = gs.pre_validate_action(intent)
|
| 193 |
+
if not is_valid:
|
| 194 |
+
chat_history.append({"role": "user", "content": user_input})
|
| 195 |
+
options = game_session.get("current_options", [])
|
| 196 |
+
options = _ensure_min_options(options, 3)
|
| 197 |
+
options_text = _format_options(options)
|
| 198 |
+
rejection_content = (
|
| 199 |
+
f"⚠️ **行动被驳回**:{rejection_msg}\n\n"
|
| 200 |
+
f"请重新选择行动,或输入其他指令。\n\n{options_text}"
|
| 201 |
+
)
|
| 202 |
+
chat_history.append({"role": "assistant", "content": rejection_content})
|
| 203 |
+
btn_updates = _get_button_updates(options)
|
| 204 |
+
yield (
|
| 205 |
+
chat_history,
|
| 206 |
+
_format_status_panel(gs),
|
| 207 |
+
btn_updates[0], btn_updates[1], btn_updates[2],
|
| 208 |
+
game_session,
|
| 209 |
+
)
|
| 210 |
+
return
|
| 211 |
+
|
| 212 |
# 2. 添加用户消息 + 空的 assistant 消息(用于流式填充)
|
| 213 |
chat_history.append({"role": "user", "content": user_input})
|
| 214 |
chat_history.append({"role": "assistant", "content": "⏳ 正在生成..."})
|
|
|
|
| 591 |
else:
|
| 592 |
inventory_text = "空"
|
| 593 |
|
| 594 |
+
# 活跃任务(完整展示:描述、子目标、奖励、来源)
|
| 595 |
active_quests = [q for q in w.quests.values() if q.status == "active"]
|
| 596 |
if active_quests:
|
| 597 |
+
quest_blocks = []
|
| 598 |
for q in active_quests:
|
| 599 |
done = sum(1 for v in q.objectives.values() if v)
|
| 600 |
total = len(q.objectives)
|
| 601 |
+
tag = "主线" if q.quest_type == "main" else "支线" if q.quest_type == "side" else "🟡 " + q.quest_type
|
| 602 |
+
# 子目标列表
|
| 603 |
+
obj_lines = "".join(
|
| 604 |
+
f"<br> {'✅' if v else '⬜'} {k}"
|
| 605 |
+
for k, v in q.objectives.items()
|
| 606 |
+
)
|
| 607 |
+
# 奖励摘要
|
| 608 |
+
reward_parts = []
|
| 609 |
+
if q.rewards.gold:
|
| 610 |
+
reward_parts.append(f"{q.rewards.gold}💰")
|
| 611 |
+
if q.rewards.experience:
|
| 612 |
+
reward_parts.append(f"{q.rewards.experience}经验")
|
| 613 |
+
if q.rewards.items:
|
| 614 |
+
reward_parts.append("、".join(q.rewards.items))
|
| 615 |
+
if q.rewards.unlock_skill:
|
| 616 |
+
reward_parts.append(f"技能:{q.rewards.unlock_skill}")
|
| 617 |
+
if q.rewards.title:
|
| 618 |
+
reward_parts.append(f"称号:{q.rewards.title}")
|
| 619 |
+
reward_str = " | ".join(reward_parts) if reward_parts else "无"
|
| 620 |
+
|
| 621 |
+
block = (
|
| 622 |
+
f"<details open><summary><b>{tag} {q.title}</b>({done}/{total})</summary>"
|
| 623 |
+
f"<span style='font-size:0.82em;color:#888;'>来源: {q.giver_npc or '未知'}</span><br>"
|
| 624 |
+
f"<span style='font-size:0.82em;'>{q.description}</span>"
|
| 625 |
+
f"{obj_lines}"
|
| 626 |
+
f"<br><span style='font-size:0.82em;color:#4a6;'>奖励: {reward_str}</span>"
|
| 627 |
+
f"</details>"
|
| 628 |
+
)
|
| 629 |
+
quest_blocks.append(block)
|
| 630 |
+
quest_text = "".join(quest_blocks)
|
| 631 |
else:
|
| 632 |
quest_text = "无活跃任务"
|
| 633 |
|
|
|
|
| 689 |
</span>
|
| 690 |
</div>
|
| 691 |
|
| 692 |
+
<div style="grid-column: 1 / -1;">
|
| 693 |
<h4 style="margin:4px 0 2px 0;">📜 任务</h4>
|
| 694 |
<span style="font-size:0.85em;">
|
| 695 |
{quest_text}
|