SachinKulk commited on
Commit
d148ab1
·
1 Parent(s): 005293e

fix(prompt): flip refusal default to answer-by-default (mirror of main 7bad334)

Browse files
Files changed (1) hide show
  1. app/graph/nodes.py +28 -26
app/graph/nodes.py CHANGED
@@ -635,36 +635,38 @@ def _build_system_prompt(state: ChatState) -> str:
635
  if scope.get("kind") == "single" and state.get("property_name"):
636
  base += f"Active property name: {state['property_name']}.\n"
637
 
638
- # ---- HARD REFUSAL: stay in domain + stay in scope ---------------------
639
- # The agent must refuse two classes of question outright:
640
- # (a) Anything not about property management for the active property
641
- # (general knowledge, math, coding, weather, jokes, etc.)
642
- # (b) Questions about a DIFFERENT property than the active one.
643
- # The clarify node already catches dropdown/message disagreements, but
644
- # if a user asks "what about <other property>?" in a follow-up turn the
645
- # graph won't re-clarify this prompt rule covers that case.
646
  _refusal_target = state.get("property_name") or scope.get("code") or "the active property"
647
- _active_codes = (
648
- [scope.get("code")] if scope.get("kind") == "single" and scope.get("code")
649
- else (scope.get("codes") or [])
650
- )
651
  base += (
652
- "\nHARD REFUSAL RULES non-negotiable:\n"
653
- f" - You ONLY answer questions about {_refusal_target}"
654
- f" (property code(s): {_active_codes}).\n"
655
- " - If the user asks about ANY other property, or about a topic "
656
- "unrelated to this property's rent roll / units / leases / residents "
657
- "/ charges / amenities / floor plans / marketing site, you MUST "
658
- "reply with EXACTLY this one sentence and call no tools:\n"
 
 
 
 
 
 
659
  f" I can only answer questions about {_refusal_target}. "
660
- "Please rephrase your question or switch the active property in the dropdown.\n"
661
- " - Do not be 'helpful' by partially answering off-scope questions, "
662
- "do not provide world knowledge, do not write code, do not do math "
663
- "puzzles. Refuse and stop.\n"
664
- " - Greetings ('hi', 'thanks') are fine respond briefly and "
665
- "invite a property question.\n"
666
  )
667
- # -----------------------------------------------------------------------
668
 
669
  # DISABLED: cross-property compare mode (kept commented out so the code is
670
  # easy to restore by uncommenting). The frontend no longer lets users
 
635
  if scope.get("kind") == "single" and state.get("property_name"):
636
  base += f"Active property name: {state['property_name']}.\n"
637
 
638
+ # ---- OFF-DOMAIN REFUSAL --------------------------------------------------
639
+ # The guardrails layer already routes cross-property questions to a
640
+ # terminal refusal node BEFORE we get here, so this prompt only needs to
641
+ # handle questions that are entirely outside the property-management
642
+ # domain (general knowledge, weather, math, code, jokes, etc.).
643
+ #
644
+ # Default behaviour: ATTEMPT the question by calling the appropriate tool.
645
+ # Only refuse when the question has nothing to do with this property.
646
  _refusal_target = state.get("property_name") or scope.get("code") or "the active property"
 
 
 
 
647
  base += (
648
+ "\nDOMAIN GUARDrefuse ONLY clearly off-domain questions:\n"
649
+ f" - DEFAULT: assume the user is asking about {_refusal_target} and "
650
+ "answer using the tools. 'tell me about this property', 'what's the "
651
+ "occupancy', 'show me photos', 'who's moving out', 'unit mix', "
652
+ "'amenities', 'fees', 'rent roll', 'compare units', etc. are ALL "
653
+ "in-scope call the matching tool.\n"
654
+ " - REFUSE only if the question is clearly NOT about this property's "
655
+ "rent roll / units / leases / residents / charges / amenities / "
656
+ "floor plans / marketing site. Examples that must be refused: "
657
+ "'what's the weather in Paris?', 'write me a poem', 'what's 2+2', "
658
+ "'who won the world cup?', 'help me debug this Python code'.\n"
659
+ " - When you refuse, reply with EXACTLY this one sentence and call "
660
+ "no tools:\n"
661
  f" I can only answer questions about {_refusal_target}. "
662
+ "Please ask a property-related question.\n"
663
+ " - Greetings ('hi', 'thanks') respond briefly and invite a "
664
+ "property question. Do NOT use the refusal sentence for greetings.\n"
665
+ " - When in doubt, ATTEMPT the question with a tool. It is better "
666
+ "to call a tool that returns 'no data' than to wrongly refuse a "
667
+ "legitimate property question.\n"
668
  )
669
+ # --------------------------------------------------------------------------
670
 
671
  # DISABLED: cross-property compare mode (kept commented out so the code is
672
  # easy to restore by uncommenting). The frontend no longer lets users