feat(03-03): implement /project models and /project delete handlers
- /project models [list] - show/set AI models for current project - /project delete <id> - delete project by ID with confirmation - Clear user selection if deleted project was selected M2 milestone complete: full project CRUD via Telegram. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e2e10d9b2e
commit
bb3eab7bb4
1 changed files with 81 additions and 7 deletions
|
|
@ -8,9 +8,11 @@ from telegram.ext import ContextTypes
|
||||||
from moai.core.models import Project
|
from moai.core.models import Project
|
||||||
from moai.core.services.project import (
|
from moai.core.services.project import (
|
||||||
create_project,
|
create_project,
|
||||||
|
delete_project,
|
||||||
get_project,
|
get_project,
|
||||||
get_project_by_name,
|
get_project_by_name,
|
||||||
list_projects,
|
list_projects,
|
||||||
|
update_project_models,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,10 +37,10 @@ async def project_command(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
|
||||||
|
|
||||||
Subcommands:
|
Subcommands:
|
||||||
new "Name" - Create new project
|
new "Name" - Create new project
|
||||||
select <id|name> - Switch to project (future)
|
select <id|name> - Switch to project
|
||||||
delete <id> - Delete project (future)
|
delete <id> - Delete project by ID
|
||||||
models <list> - Set models (future)
|
models <list> - Set models for current project
|
||||||
info - Show current project (future)
|
info - Show current project
|
||||||
"""
|
"""
|
||||||
args = context.args or []
|
args = context.args or []
|
||||||
|
|
||||||
|
|
@ -46,8 +48,10 @@ async def project_command(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
'/project new "Name" - Create project\n'
|
'/project new "Name" - Create project\n'
|
||||||
"/project select <id> - Switch project\n"
|
"/project select <id|name> - Switch project\n"
|
||||||
"/project info - Show current project"
|
"/project info - Show current project\n"
|
||||||
|
"/project models [model1,model2,...] - Set/show models\n"
|
||||||
|
"/project delete <id> - Delete project"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -59,9 +63,13 @@ async def project_command(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
|
||||||
await _handle_project_select(update, context, args[1:])
|
await _handle_project_select(update, context, args[1:])
|
||||||
elif subcommand == "info":
|
elif subcommand == "info":
|
||||||
await _handle_project_info(update, context)
|
await _handle_project_info(update, context)
|
||||||
|
elif subcommand == "models":
|
||||||
|
await _handle_project_models(update, context, args[1:])
|
||||||
|
elif subcommand == "delete":
|
||||||
|
await _handle_project_delete(update, context, args[1:])
|
||||||
else:
|
else:
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
f"Unknown subcommand: {subcommand}\nAvailable: new, select, delete, models, info"
|
f"Unknown subcommand: {subcommand}\nAvailable: new, select, info, models, delete"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,6 +156,72 @@ async def _handle_project_info(update: Update, context: ContextTypes.DEFAULT_TYP
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _handle_project_models(
|
||||||
|
update: Update, context: ContextTypes.DEFAULT_TYPE, args: list[str]
|
||||||
|
) -> None:
|
||||||
|
"""Handle /project models [model1,model2,...] command."""
|
||||||
|
project = await get_selected_project(context)
|
||||||
|
|
||||||
|
if project is None:
|
||||||
|
await update.message.reply_text("No project selected. Use /project select <name> first.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# No args: show current models
|
||||||
|
if not args:
|
||||||
|
models_str = ", ".join(project.models) if project.models else "none"
|
||||||
|
await update.message.reply_text(f"Current models: {models_str}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Parse comma-separated model names
|
||||||
|
models_input = " ".join(args)
|
||||||
|
models = [m.strip() for m in models_input.split(",") if m.strip()]
|
||||||
|
|
||||||
|
if not models:
|
||||||
|
await update.message.reply_text("Usage: /project models claude,gpt,gemini")
|
||||||
|
return
|
||||||
|
|
||||||
|
updated_project = await update_project_models(project.id, models)
|
||||||
|
|
||||||
|
if updated_project is None:
|
||||||
|
await update.message.reply_text("Project not found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
models_str = ", ".join(updated_project.models)
|
||||||
|
await update.message.reply_text(f"Models updated: {models_str}")
|
||||||
|
|
||||||
|
|
||||||
|
async def _handle_project_delete(
|
||||||
|
update: Update, context: ContextTypes.DEFAULT_TYPE, args: list[str]
|
||||||
|
) -> None:
|
||||||
|
"""Handle /project delete <id> command."""
|
||||||
|
if not args:
|
||||||
|
await update.message.reply_text("Usage: /project delete <project-id>")
|
||||||
|
return
|
||||||
|
|
||||||
|
project_id = args[0]
|
||||||
|
|
||||||
|
# Get project first to show name in confirmation
|
||||||
|
project = await get_project(project_id)
|
||||||
|
|
||||||
|
if project is None:
|
||||||
|
await update.message.reply_text("Project not found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
project_name = project.name
|
||||||
|
|
||||||
|
deleted = await delete_project(project_id)
|
||||||
|
|
||||||
|
if not deleted:
|
||||||
|
await update.message.reply_text("Project not found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Clear selection if deleted project was selected
|
||||||
|
if context.user_data.get("selected_project_id") == project_id:
|
||||||
|
context.user_data.pop("selected_project_id", None)
|
||||||
|
|
||||||
|
await update.message.reply_text(f"Deleted project: {project_name}")
|
||||||
|
|
||||||
|
|
||||||
async def get_selected_project(context: ContextTypes.DEFAULT_TYPE) -> Project | None:
|
async def get_selected_project(context: ContextTypes.DEFAULT_TYPE) -> Project | None:
|
||||||
"""Get the currently selected project from user_data.
|
"""Get the currently selected project from user_data.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue