Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions ai_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
Handling Commands & Actions:
1. When a user asks you to perform an action or command:
- If there is a matching tool in your tools list, ALWAYS invoke that tool.
- Perhatikan Informasi Server Terkini: Jika pengguna meminta tindakan untuk dirinya sendiri (seperti: "jadikan aku operator channel", "move aku ke channel X"), gunakan nama penanya dan channel tempat penanya berada.
- Jika pengguna meminta memindahkan pengguna atau join ke channel (seperti: "move kak fian ke channel ekskul"), cari dan gunakan nama channel yang paling cocok dari daftar channel server terkini.
- If the user asks you to perform an action or command that is NOT available in your tools list (contoh: memutar musik, memesan makanan, restart server atau komputer, atau perintah apapun yang tidak ada di daftar fungsi), JANGAN mengarang atau berpura-pura melaksanakannya. Katakan secara ramah dan santai khas Gen Z bahwa fungsinya belum ada (contoh: "Wah kayaknya belum ada deh function buat itu di bot ini", atau "Fitur itu belum tersedia nih").
2. If a sensitive function returns PERMISSION_DENIED because the requester is not an admin, firmly and casually refuse in your Gen Z vibe (for example: "Woi kamu bukan admin bro, gak boleh aneh-aneh ya").
3. If an action succeeds, confirm it casually in plain text without Markdown or emojis."""
Expand Down Expand Up @@ -373,18 +375,18 @@ def clean_answer(text: str) -> str:
"properties": {
"nickname": {
"type": "string",
"description": "The nickname of the user.",
"description": "The nickname of the user (or 'aku' to set requester).",
},
"channel": {
"type": "string",
"description": "Optional channel name or path (defaults to user's current channel).",
},
"is_operator": {
"type": "boolean",
"description": "True to grant operator status, False to revoke operator status.",
"description": "True to grant operator status (default True), False to revoke operator status.",
},
},
"required": ["nickname", "is_operator"],
"required": ["nickname"],
},
},
{
Expand Down Expand Up @@ -594,7 +596,20 @@ def _extract_tool_calls(self, result: Dict[str, Any]) -> Optional[List[Dict[str,

def answer(self, question: str, history: List[Tuple[str, str]], context: Any = None) -> str:
"""Ask the model and return its cleaned answer; handles function calls."""
messages: List[Dict[str, Any]] = [{"role": "system", "content": SYSTEM_PROMPT}]
system_content = SYSTEM_PROMPT
if isinstance(context, dict):
extra = []
req_nick = context.get("nickname") or "Pengguna"
chan_name = context.get("channel_name") or f"channel {context.get('channel')}"
extra.append(f"Penanya: {req_nick} (berada di channel: {chan_name}).")
if context.get("online_users"):
extra.append(f"Pengguna online: {', '.join(context['online_users'][:30])}.")
if context.get("channels"):
extra.append(f"Daftar channel server: {', '.join(context['channels'][:30])}.")
if extra:
system_content += "\n\nInformasi Server Terkini:\n" + "\n".join(extra)

messages: List[Dict[str, Any]] = [{"role": "system", "content": system_content}]
for earlier_question, earlier_answer in history:
messages.append({"role": "user", "content": earlier_question})
messages.append({"role": "assistant", "content": earlier_answer})
Expand Down
7 changes: 7 additions & 0 deletions docs/ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ The AI automatically invokes tools executed safely on the bot's main thread:

**Unrecognized or unsupported commands**: If a user asks the AI to perform a task or action that does not have a corresponding function in the bot (for example: playing songs, ordering food, restarting servers), the AI does not hallucinate or guess; it politely informs the user in its Gen Z persona that the function is not yet available (for example: *"Wah kayaknya belum ada deh function buat itu di bot ini"*).

**Live Server Context & Fuzzy Lookups**:
- **Server snapshot injection**: When answering `@ai`, the bot injects real-time context into the AI's prompt: requester nickname, requester's current channel, online users and their channels, and the server channel list.
- **Self-referential requests**: Requests mentioning "aku", "saya", or omitted nicknames (e.g. `@ai jadiin aku operator channel dong` or `@ai move aku ke channel ekskul dong`) automatically resolve to the requester and their current channel.
- **Fuzzy user lookups**: The bot strips common Indonesian honorifics (`kak`, `bang`, `mas`, `pak`, `bu`, `@`, `bro`) and matches by exact name, stem, tokens (e.g. `kak fian` matches `Kak Fian (Ketua)` or `Fian`), or username.
- **Fuzzy channel lookups**: Strips conversational prepositions and channel terms (e.g. `ke channel ekskul` or `ruang ekskul` cleanly matches `Ekskul Robotik` or `/Root/Ekskul Robotik`). Channel terms like `sini` or `channel ini` resolve to the requester's current channel.

Setup: the same Cloudflare keys as above, then `/abt aichat on` (off by
default). Other settings: `AI_CHAT_PREFIX` (default `@ai`), `AI_CHAT_MODEL`
(empty: same as `AI_MODEL`), `AI_CHAT_MAX_TOKENS` (default 300),
Expand All @@ -158,3 +164,4 @@ default). Other settings: `AI_CHAT_PREFIX` (default `@ai`), `AI_CHAT_MODEL`
answer; empty to leave it out).
Users can read `/help ai`.


Loading
Loading