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,67 @@ 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+ # Defer response to prevent timeout
91+ await interaction .response .defer (ephemeral = True )
92+
93+ # Save current member who interacted to be remembered next time
94+ self .save_actor_interaction (interaction .guild , member )
95+
96+ # Load members who interacted before
97+ actors = self .load_actors (interaction .guild )
98+ if actors :
99+ text_prompt += f"\n { text_csv (actors , "|" )} "
100+
101+ # Perform prompt
102+ log .info (f"[Prompt] { text_prompt } " )
103+ try :
104+ self .ai .use_session (
105+ interaction .guild .id , history = self .load_history (interaction .guild )
106+ )
107+ reply = self .ai .prompt (text = text_prompt ) or f"{ member .mention } 👋"
108+ await interaction .followup .send (
109+ embed = EmbedX .success (
110+ title = "Incentive" ,
111+ description = f"{ self .bot .user } has been incited to talk with { member .mention } .\n \n **Prompt:**```{ text_prompt } ```" ,
112+ ),
113+ ephemeral = True ,
114+ )
115+ async with interaction .channel .typing ():
116+ await interaction .channel .send (reply )
117+ except Exception as e :
118+ await interaction .followup .send (embed = EmbedX .error (str (e )), ephemeral = True )
119+ log .exception (e )
120+ return
121+
122+ # Save history
123+ self .save_history (interaction .guild )
54124
55125 # ----------------------------------------------------------------------------------------------------
56126 # * On Message
@@ -103,12 +173,15 @@ async def on_message(self, message: Message):
103173 f"{ message .content .replace (self .bot .user .mention , "" ).strip ()} "
104174 )
105175
106- # Add members who interacted before
176+ # Save current member who interacted to be remembered next time
177+ self .save_actor_interaction (message .guild , message .author )
178+
179+ # Load members who interacted before
107180 actors = self .load_actors (message .guild )
108181 if actors :
109182 text_prompt += f"\n { text_csv (actors , "|" )} "
110183
111- # Prompt AI
184+ # Perform prompt
112185 log .info (f"[Prompt] { text_prompt } <{ file_prompt } >" )
113186 try :
114187 self .ai .use_session (
@@ -131,8 +204,7 @@ async def on_message(self, message: Message):
131204 fallback_reply = "What? 😕"
132205 await message .reply (reply or fallback_reply )
133206
134- # Save current member who interacted to be remembered next time
135- self .save_actor_interaction (message .guild , message .author )
207+ # Save current chat session
136208 self .save_history (message .guild )
137209
138210 # ----------------------------------------------------------------------------------------------------
0 commit comments