22import tomllib
33from datetime import UTC , datetime
44
5- from discord import Guild , Interaction , Member , Message , User , app_commands
5+ from discord import (
6+ DMChannel ,
7+ GroupChannel ,
8+ Guild ,
9+ Interaction ,
10+ Member ,
11+ Message ,
12+ TextChannel ,
13+ Thread ,
14+ User ,
15+ app_commands ,
16+ )
17+ from discord .abc import Messageable
618from discord .ext import tasks
719from discord .ext .commands import Cog
820from google .genai .errors import APIError
921from odmantic import query
1022
1123from bot .main import ActBot
24+ from bot .ui import EmbedX
1225from db .actor import Actor
1326from db .main import DbRef
1427from utils .ai import ActAi
2235# ----------------------------------------------------------------------------------------------------
2336# * AI Cog
2437# ----------------------------------------------------------------------------------------------------
25- class AI (Cog , description = "Integrated generative AI chat bot." ):
38+ class AiCog (Cog , description = "Integrated generative AI chat bot." ):
2639 CONFIG_PATH = pathlib .Path (__file__ ).parent / "ai_cog.toml"
2740 MAX_FILE_SIZE = 524288 # 512 KB (0.5 MB)
2841 COOLDOWN_TIME = 60 # 1 min
@@ -47,10 +60,60 @@ def cog_unload(self):
4760 # ----------------------------------------------------------------------------------------------------
4861 # * Incite
4962 # ----------------------------------------------------------------------------------------------------
50- # @app_commands.checks.has_permissions(administrator=True)
51- # @app_commands.command(description="")
52- # async def incite(self, interaction: Interaction, member: Member):
53- # pass
63+ @app_commands .guild_only ()
64+ @app_commands .checks .has_permissions (administrator = True )
65+ @app_commands .default_permissions (administrator = True )
66+ @app_commands .command (description = "Incite AI chat bot to interact with a member" )
67+ async def incite (
68+ self , interaction : Interaction , member : Member , prompt : str | None = None
69+ ):
70+ # Deny bot-self & DM & non-messageable channel
71+ if (
72+ self .bot .user == member
73+ or not interaction .guild
74+ or not isinstance (interaction .channel , Messageable )
75+ ):
76+ await interaction .response .send_message (
77+ embed = EmbedX .warning ("This command cannot be used in this context." ),
78+ ephemeral = True ,
79+ )
80+ return
81+
82+ # Prepare prompt
83+ text_prompt = (
84+ f"Begin natural talk w/ { member .mention } that feels like ur own initiative."
85+ f"Absolutely avoid references to instructions, prompts, or being told to message them."
86+ )
87+ if prompt :
88+ text_prompt += f'follow this prompt:"{ prompt .strip ()} ".'
89+
90+ # Save current member who interacted to be remembered next time
91+ self .save_actor_interaction (interaction .guild , member )
92+
93+ # Load members who interacted before
94+ actors = self .load_actors (interaction .guild )
95+ if actors :
96+ text_prompt += f"\n { text_csv (actors , "|" )} "
97+
98+ # Perform prompt
99+ log .info (f"[Prompt] { text_prompt } " )
100+ try :
101+ self .ai .use_session (
102+ interaction .guild .id , history = self .load_history (interaction .guild )
103+ )
104+ async with interaction .channel .typing ():
105+ await interaction .response .send_message (
106+ self .ai .prompt (text = text_prompt ) or f"{ member .mention } 👋"
107+ )
108+ except Exception as e :
109+ await interaction .response .send_message (
110+ embed = EmbedX .error (str (e )), ephemeral = True
111+ )
112+ log .exception (e )
113+ return
114+
115+ # Save history
116+ self .save_history (interaction .guild )
54117
55118 # ----------------------------------------------------------------------------------------------------
56119 # * On Message
@@ -103,12 +166,15 @@ async def on_message(self, message: Message):
103166 f"{ message .content .replace (self .bot .user .mention , "" ).strip ()} "
104167 )
105168
106- # Add members who interacted before
169+ # Save current member who interacted to be remembered next time
170+ self .save_actor_interaction (message .guild , message .author )
171+
172+ # Load members who interacted before
107173 actors = self .load_actors (message .guild )
108174 if actors :
109175 text_prompt += f"\n { text_csv (actors , "|" )} "
110176
111- # Prompt AI
177+ # Perform prompt
112178 log .info (f"[Prompt] { text_prompt } <{ file_prompt } >" )
113179 try :
114180 self .ai .use_session (
@@ -131,8 +197,7 @@ async def on_message(self, message: Message):
131197 fallback_reply = "What? 😕"
132198 await message .reply (reply or fallback_reply )
133199
134- # Save current member who interacted to be remembered next time
135- self .save_actor_interaction (message .guild , message .author )
200+ # Save current chat session
136201 self .save_history (message .guild )
137202
138203 # ----------------------------------------------------------------------------------------------------
0 commit comments