feat(05-03): implement /next and /stop commands for round progression
Add /next to advance discussion with full context passed to models: - Validates active discussion state - Auto-completes when round limit reached - Shows Round N/M progress indicator Add /stop to end discussion early: - Marks discussion as COMPLETED - Clears session state - Suggests /consensus for summarization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
104eceb246
commit
3ae08e9317
2 changed files with 107 additions and 1 deletions
|
|
@ -7,7 +7,13 @@ project management, discussion commands, and export functionality.
|
|||
from telegram.ext import Application, CommandHandler
|
||||
|
||||
from moai.bot.handlers.commands import help_command, start_command
|
||||
from moai.bot.handlers.discussion import ask_command, discuss_command, open_command
|
||||
from moai.bot.handlers.discussion import (
|
||||
ask_command,
|
||||
discuss_command,
|
||||
next_command,
|
||||
open_command,
|
||||
stop_command,
|
||||
)
|
||||
from moai.bot.handlers.projects import project_command, projects_command
|
||||
from moai.bot.handlers.status import status_command
|
||||
|
||||
|
|
@ -33,3 +39,5 @@ def register_handlers(app: Application) -> None:
|
|||
app.add_handler(CommandHandler("ask", ask_command))
|
||||
app.add_handler(CommandHandler("open", open_command))
|
||||
app.add_handler(CommandHandler("discuss", discuss_command))
|
||||
app.add_handler(CommandHandler("next", next_command))
|
||||
app.add_handler(CommandHandler("stop", stop_command))
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from moai.core.ai_client import MODEL_MAP, get_ai_client
|
|||
from moai.core.models import DiscussionType, RoundType
|
||||
from moai.core.orchestrator import query_models_parallel, run_discussion_round
|
||||
from moai.core.services.discussion import (
|
||||
complete_discussion,
|
||||
create_discussion,
|
||||
create_message,
|
||||
create_round,
|
||||
|
|
@ -245,3 +246,100 @@ async def discuss_command(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
|
|||
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f"Error: {e}")
|
||||
|
||||
|
||||
async def next_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Handle /next command - advance to the next discussion round.
|
||||
|
||||
Requires an active discussion started with /discuss. Runs the next
|
||||
sequential round with full context from prior rounds.
|
||||
"""
|
||||
# Check for active discussion state
|
||||
state = context.user_data.get("discussion_state")
|
||||
if state is None:
|
||||
await update.message.reply_text("No active discussion. Start one with /open then /discuss.")
|
||||
return
|
||||
|
||||
current_round = state["current_round"]
|
||||
round_limit = state["round_limit"]
|
||||
|
||||
# Check if already at limit
|
||||
if current_round > round_limit:
|
||||
await update.message.reply_text(
|
||||
f"Round limit ({round_limit}) reached. Start a new discussion with /open."
|
||||
)
|
||||
del context.user_data["discussion_state"]
|
||||
return
|
||||
|
||||
# Show typing indicator
|
||||
await update.message.chat.send_action("typing")
|
||||
|
||||
try:
|
||||
# Load discussion with full context
|
||||
discussion = await get_discussion(state["discussion_id"])
|
||||
if discussion is None:
|
||||
await update.message.reply_text("Discussion not found.")
|
||||
del context.user_data["discussion_state"]
|
||||
return
|
||||
|
||||
# Run the next round
|
||||
responses = await run_discussion_round(
|
||||
discussion=discussion,
|
||||
models=state["models"],
|
||||
project_name=state["project_name"],
|
||||
round_number=current_round,
|
||||
)
|
||||
|
||||
# Build response text
|
||||
response_lines = [f"*Round {current_round}/{round_limit}:*\n"]
|
||||
for model, response in responses.items():
|
||||
response_lines.append(f"*{model.title()}:*\n{response}\n")
|
||||
|
||||
if current_round >= round_limit:
|
||||
# Final round - complete discussion
|
||||
await complete_discussion(state["discussion_id"])
|
||||
response_lines.append(f"\n_Discussion complete ({round_limit} rounds)._")
|
||||
del context.user_data["discussion_state"]
|
||||
else:
|
||||
response_lines.append(
|
||||
f"\n_Round {current_round}/{round_limit} complete. Use /next or /stop._"
|
||||
)
|
||||
# Update state for next round
|
||||
context.user_data["discussion_state"]["current_round"] = current_round + 1
|
||||
|
||||
await update.message.reply_text(
|
||||
"\n".join(response_lines),
|
||||
parse_mode="Markdown",
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f"Error: {e}")
|
||||
|
||||
|
||||
async def stop_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Handle /stop command - stop the current discussion early.
|
||||
|
||||
Completes the discussion at the current round and clears the session state.
|
||||
"""
|
||||
# Check for active discussion state
|
||||
state = context.user_data.get("discussion_state")
|
||||
if state is None:
|
||||
await update.message.reply_text("No active discussion to stop.")
|
||||
return
|
||||
|
||||
current_round = state["current_round"]
|
||||
|
||||
try:
|
||||
# Complete the discussion in database
|
||||
await complete_discussion(state["discussion_id"])
|
||||
|
||||
# Clear session state
|
||||
del context.user_data["discussion_state"]
|
||||
|
||||
await update.message.reply_text(
|
||||
f"_Discussion stopped at round {current_round - 1}. Use /consensus to summarize._",
|
||||
parse_mode="Markdown",
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f"Error: {e}")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue