Spaces:
Sleeping
Sleeping
Commit ·
d148ab1
1
Parent(s): 005293e
fix(prompt): flip refusal default to answer-by-default (mirror of main 7bad334)
Browse files- 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 |
-
# ----
|
| 639 |
-
# The
|
| 640 |
-
#
|
| 641 |
-
#
|
| 642 |
-
#
|
| 643 |
-
#
|
| 644 |
-
#
|
| 645 |
-
#
|
| 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 |
-
"\
|
| 653 |
-
f" -
|
| 654 |
-
|
| 655 |
-
"
|
| 656 |
-
"
|
| 657 |
-
"
|
| 658 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 659 |
f" I can only answer questions about {_refusal_target}. "
|
| 660 |
-
"Please
|
| 661 |
-
" -
|
| 662 |
-
"
|
| 663 |
-
"
|
| 664 |
-
"
|
| 665 |
-
"
|
| 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 GUARD — refuse 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
|