feat: add optional custom argument topic override via Web UI

- Added optional 'topic' field to BipolarTriggerRequest model
- Added topic parameter to force_trigger_argument and force_trigger_argument_from_message_id
- Updated run_argument to accept optional custom topic (None=random, ''=no topic, str=custom)
- Added topic input field to Web UI trigger-argument section
- Updated JS to send topic in API request body
- Custom topics bypass the random rotation system, allowing manual theme control
This commit is contained in:
2026-04-30 12:07:28 +03:00
parent 98fca53066
commit 846557fa96
5 changed files with 40 additions and 10 deletions

View File

@@ -1175,7 +1175,7 @@ def should_end_argument(channel_id: int) -> tuple:
return False, None
async def run_argument(channel: discord.TextChannel, client, trigger_context: str = "", starting_message: discord.Message = None):
async def run_argument(channel: discord.TextChannel, client, trigger_context: str = "", starting_message: discord.Message = None, argument_topic: str = None):
"""Run a full argument event between both Mikus
Args:
@@ -1184,6 +1184,9 @@ async def run_argument(channel: discord.TextChannel, client, trigger_context: st
trigger_context: Optional context about what triggered the argument
starting_message: Optional message to use as the first message in the argument
(the opposite persona will respond to it)
argument_topic: Optional custom topic string. If provided, overrides the
random topic selection. Pass empty string to force no topic.
Pass None (default) to use random topic selection.
"""
from utils.llm import query_llama
from utils.conversation_history import conversation_history
@@ -1225,8 +1228,19 @@ async def run_argument(channel: discord.TextChannel, client, trigger_context: st
conversation_log = []
try:
# Pick a dynamic argument topic to give this argument a unique framing
argument_topic = pick_argument_topic(channel_id)
# Pick a dynamic argument topic to give this argument a unique framing.
# If caller provided a custom topic, use it instead of random selection.
# If caller passed empty string, use no topic (no theme guidance).
if argument_topic is None:
# Default: random weighted selection from rotation system
argument_topic = pick_argument_topic(channel_id)
elif argument_topic == "":
# Explicitly no topic — skip theme guidance entirely
argument_topic = ""
logger.info(f"No argument topic requested for channel {channel_id}")
else:
# Custom topic from caller (e.g. Web UI field)
logger.info(f"Using custom argument topic for channel {channel_id}: '{argument_topic[:80]}...'")
# If no starting message, generate the initial interrupting message
if last_message is None:
@@ -1524,7 +1538,7 @@ async def maybe_trigger_argument(channel: discord.TextChannel, client, context:
return False
async def force_trigger_argument(channel: discord.TextChannel, client, context: str = "", starting_message: discord.Message = None):
async def force_trigger_argument(channel: discord.TextChannel, client, context: str = "", starting_message: discord.Message = None, topic: str = None):
"""Force trigger an argument (for manual triggers)
Args:
@@ -1532,6 +1546,7 @@ async def force_trigger_argument(channel: discord.TextChannel, client, context:
client: Discord client
context: Optional context string
starting_message: Optional message to use as the first message in the argument
topic: Optional custom argument topic. None = random, "" = no topic, str = custom.
"""
if not globals.BIPOLAR_MODE:
logger.warning("Cannot trigger argument - bipolar mode is not enabled")
@@ -1541,11 +1556,11 @@ async def force_trigger_argument(channel: discord.TextChannel, client, context:
logger.warning("Argument already in progress in this channel")
return False
create_tracked_task(run_argument(channel, client, context, starting_message), task_name="bipolar_argument_forced")
create_tracked_task(run_argument(channel, client, context, starting_message, argument_topic=topic), task_name="bipolar_argument_forced")
return True
async def force_trigger_argument_from_message_id(channel_id: int, message_id: int, client, context: str = ""):
async def force_trigger_argument_from_message_id(channel_id: int, message_id: int, client, context: str = "", topic: str = None):
"""Force trigger an argument starting from a specific message ID
Args:
@@ -1579,5 +1594,5 @@ async def force_trigger_argument_from_message_id(channel_id: int, message_id: in
return False, f"Failed to fetch message: {str(e)}"
# Trigger the argument with this message as starting point
create_tracked_task(run_argument(channel, client, context, message), task_name="bipolar_argument_from_msg")
create_tracked_task(run_argument(channel, client, context, message, argument_topic=topic), task_name="bipolar_argument_from_msg")
return True, None