103 lines
3.5 KiB
Python
103 lines
3.5 KiB
Python
import re
|
|
|
|
|
|
def _name_mentioned(name: str, text: str) -> bool:
|
|
"""Cek apakah nama AI disebut dalam pesan (case-insensitive, word-boundary)."""
|
|
text_lower = text.lower()
|
|
name_lower = name.lower()
|
|
pattern = r'\b' + re.escape(name_lower) + r'\b'
|
|
return bool(re.search(pattern, text_lower))
|
|
|
|
|
|
def need_response(message: str, sender_nickname: str, recent_history: str, my_name: str) -> str:
|
|
"""
|
|
Decide whether the AI should respond to a message.
|
|
|
|
Args:
|
|
message: The latest message to evaluate.
|
|
sender_nickname: Nickname of the sender.
|
|
recent_history: Recent conversation history for context.
|
|
my_name: The AI's name.
|
|
|
|
Returns:
|
|
"true" → should respond
|
|
"false" → should stay silent
|
|
|
|
Rules:
|
|
1. STRONG — Direct call/mention of AI's name → always True
|
|
2. BRIEF — Talks about AI in third person → True
|
|
3. CONTEXTUAL — Related to AI's previous conversation → True
|
|
4. NO REPLY — Unrelated, confusing, between other people → False
|
|
"""
|
|
msg = message.strip()
|
|
|
|
# --- Rule 4: Empty message ---
|
|
if not msg:
|
|
return "false"
|
|
|
|
# --- Rule 1: Direct mention/name call ---
|
|
if _name_mentioned(my_name, msg):
|
|
return "true"
|
|
|
|
# --- Rule 2: Talks about AI (third person) ---
|
|
name_parts = my_name.lower().split()
|
|
text_lower = msg.lower()
|
|
if any(part in text_lower for part in name_parts if len(part) > 1):
|
|
return "true"
|
|
|
|
# --- Rule 3: Contextual — check recent history ---
|
|
if recent_history:
|
|
return "true"
|
|
|
|
# --- Rule 4: Default — no strong signal, stay silent ---
|
|
return "false"
|
|
|
|
|
|
def should_respond(message: str, sender_nickname: str, recent_history: str, my_name: str) -> bool:
|
|
"""
|
|
Python-side helper: return boolean directly.
|
|
Used by XMPP client to gate whether to send the LLM's response.
|
|
"""
|
|
result = need_response(message, sender_nickname, recent_history, my_name)
|
|
return result.strip().lower() == "true"
|
|
|
|
|
|
schema_need_response = {
|
|
"type": "function",
|
|
"function": {
|
|
"name": "need_response",
|
|
"description": (
|
|
"Decide whether you should respond to the current message. "
|
|
"Use this tool when you are unsure whether to reply or stay silent. "
|
|
"Returns 'true' if you should respond, 'false' if you should stay silent. "
|
|
"Rules: "
|
|
"- Return 'true' if your name is mentioned or someone talks about you. "
|
|
"- Return 'true' if the message is related to your previous conversation. "
|
|
"- Return 'false' if the message is between other people, unclear, "
|
|
"unrelated to you, or you have nothing to add."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"description": "The latest message to evaluate.",
|
|
},
|
|
"sender_nickname": {
|
|
"type": "string",
|
|
"description": "The nickname of the person who sent the message.",
|
|
},
|
|
"recent_history": {
|
|
"type": "string",
|
|
"description": "Recent conversation history for context (last few messages).",
|
|
},
|
|
"my_name": {
|
|
"type": "string",
|
|
"description": "Your (the AI's) name.",
|
|
},
|
|
},
|
|
"required": ["message", "sender_nickname", "recent_history", "my_name"],
|
|
},
|
|
},
|
|
}
|