fix: merge context + topic into single field — one clear purpose

- Removed separate 'topic' field from BipolarTriggerRequest model
- Removed topic parameter from force_trigger_argument, force_trigger_argument_from_message_id, and run_argument
- trigger_context now doubles as the argument theme: if provided by user, it becomes the topic;
  if blank, a random topic is selected from the rotation pool
- Web UI: replaced two confusing fields (Context + Topic) with one clear field labeled
  'What should they argue about? (optional)' with a plain-English description
- JS: removed topic field reference, context.trim() ensures empty strings aren't sent
This commit is contained in:
2026-04-30 12:30:49 +03:00
parent 846557fa96
commit e6c818f647
5 changed files with 23 additions and 43 deletions

View File

@@ -129,7 +129,7 @@ def trigger_argument(data: BipolarTriggerRequest):
if message_id:
async def trigger_from_message():
success, error = await force_trigger_argument_from_message_id(
channel_id, message_id, globals.client, data.context, topic=data.topic
channel_id, message_id, globals.client, data.context
)
if not success:
logger.error(f"Failed to trigger argument from message: {error}")
@@ -148,8 +148,8 @@ def trigger_argument(data: BipolarTriggerRequest):
if not channel:
return JSONResponse(status_code=404, content={"status": "error", "message": f"Channel {channel_id} not found"})
# Trigger the argument with optional custom topic
globals.client.loop.create_task(force_trigger_argument(channel, globals.client, data.context, topic=data.topic))
# Trigger the argument — context doubles as the argument theme
globals.client.loop.create_task(force_trigger_argument(channel, globals.client, data.context))
return {
"status": "ok",

View File

@@ -45,8 +45,7 @@ class LogFilterUpdateRequest(BaseModel):
class BipolarTriggerRequest(BaseModel):
channel_id: str # String to handle large Discord IDs from JS
message_id: str = None # Optional: starting message ID (string)
context: str = ""
topic: str = "" # Optional: custom argument topic (overrides random topic selection)
context: str = "" # Optional: argument theme/context — tells them what to argue about
class ManualCropRequest(BaseModel):

View File

@@ -234,15 +234,10 @@
</div>
<div style="margin-bottom: 1rem;">
<label for="bipolar-context">Argument Context (optional):</label>
<input type="text" id="bipolar-context" placeholder="e.g., They're fighting about who's the real Miku..." style="width: 100%; margin-top: 0.3rem;">
</div>
<div style="margin-bottom: 1rem;">
<label for="bipolar-topic">Argument Topic (optional — overrides random topic):</label>
<input type="text" id="bipolar-topic" placeholder="e.g., Who deserves the spotlight? A philosophical debate about worth..." style="width: 100%; margin-top: 0.3rem;">
<label for="bipolar-context">What should they argue about? (optional):</label>
<input type="text" id="bipolar-context" placeholder="e.g., Who's the real Miku? Whether kindness is weakness. A petty grudge..." style="width: 100%; margin-top: 0.3rem;">
<div style="font-size: 0.75rem; color: #777; margin-top: 0.2rem;">
Leave blank for random topic selection. Enter a custom theme to frame the argument uniquely.
Leave blank for a random topic. Write anything to set the argument's theme.
</div>
</div>

View File

@@ -248,8 +248,7 @@ async function triggerPersonaDialogue() {
async function triggerBipolarArgument() {
const channelIdInput = document.getElementById('bipolar-channel-id').value.trim();
const messageIdInput = document.getElementById('bipolar-message-id').value.trim();
const context = document.getElementById('bipolar-context').value;
const topic = document.getElementById('bipolar-topic').value.trim();
const context = document.getElementById('bipolar-context').value.trim();
const statusDiv = document.getElementById('bipolar-status');
if (!channelIdInput) {
@@ -279,10 +278,6 @@ async function triggerBipolarArgument() {
requestBody.message_id = messageIdInput;
}
if (topic) {
requestBody.topic = topic;
}
const result = await apiCall('/bipolar-mode/trigger-argument', 'POST', requestBody);
if (result.status === 'error') {
@@ -295,7 +290,6 @@ async function triggerBipolarArgument() {
showNotification(`⚔️ Argument triggered!`);
document.getElementById('bipolar-context').value = '';
document.getElementById('bipolar-topic').value = '';
document.getElementById('bipolar-message-id').value = '';
loadActiveArguments();

View File

@@ -1175,18 +1175,17 @@ 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, argument_topic: str = None):
async def run_argument(channel: discord.TextChannel, client, trigger_context: str = "", starting_message: discord.Message = None):
"""Run a full argument event between both Mikus
Args:
channel: The Discord channel to run the argument in
client: Discord client
trigger_context: Optional context about what triggered the argument
trigger_context: Optional context about what triggered the argument.
If provided, doubles as the argument theme/topic.
If empty, a random topic is selected from the rotation pool.
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
@@ -1228,19 +1227,13 @@ 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.
# 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}")
# Determine the argument theme: if the caller provided trigger_context,
# use it as the argument topic. Otherwise, pick a random one.
if trigger_context and trigger_context.strip():
argument_topic = trigger_context.strip()
logger.info(f"Using context as argument topic: '{argument_topic[:80]}...'")
else:
# Custom topic from caller (e.g. Web UI field)
logger.info(f"Using custom argument topic for channel {channel_id}: '{argument_topic[:80]}...'")
argument_topic = pick_argument_topic(channel_id)
# If no starting message, generate the initial interrupting message
if last_message is None:
@@ -1538,15 +1531,14 @@ 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, topic: str = None):
async def force_trigger_argument(channel: discord.TextChannel, client, context: str = "", starting_message: discord.Message = None):
"""Force trigger an argument (for manual triggers)
Args:
channel: The Discord channel
client: Discord client
context: Optional context string
context: Optional context string — doubles as the argument theme
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")
@@ -1556,11 +1548,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, argument_topic=topic), task_name="bipolar_argument_forced")
create_tracked_task(run_argument(channel, client, context, starting_message), task_name="bipolar_argument_forced")
return True
async def force_trigger_argument_from_message_id(channel_id: int, message_id: int, client, context: str = "", topic: str = None):
async def force_trigger_argument_from_message_id(channel_id: int, message_id: int, client, context: str = ""):
"""Force trigger an argument starting from a specific message ID
Args:
@@ -1594,5 +1586,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, argument_topic=topic), task_name="bipolar_argument_from_msg")
create_tracked_task(run_argument(channel, client, context, message), task_name="bipolar_argument_from_msg")
return True, None