---
phase: 04-single-model-qa
plan: 02
type: execute
---
Implement /ask command for single model Q&A and integrate AI client into bot lifecycle.
Purpose: Complete M3 milestone - users can ask questions to individual AI models through Telegram.
Output: Working /ask command that sends questions to AI models and returns responses.
~/.claude/get-shit-done/workflows/execute-phase.md
~/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/04-single-model-qa/04-01-SUMMARY.md (will exist after 04-01)
# Key files:
@src/moai/bot/main.py
@src/moai/bot/config.py
@src/moai/bot/handlers/__init__.py
@src/moai/bot/handlers/projects.py
@src/moai/core/ai_client.py (will exist after 04-01)
**Tech available:**
- python-telegram-bot, sqlalchemy, httpx, aiosqlite, openai (added in 04-01)
- AI client abstraction (04-01)
**Established patterns:**
- Handler registration in handlers/__init__.py
- get_selected_project() helper in projects.py
- Module-level init pattern (database.py, ai_client.py)
- Async command handlers
**Constraining decisions:**
- Thin handlers delegating to core (CLAUDE.md)
- Service layer for business logic
Task 1: Integrate AI client into bot lifecycle
src/moai/bot/main.py
Modify main.py to initialize AI client during bot startup:
1. Import init_ai_client from moai.core.ai_client
2. In post_init callback (or create one if needed), after database init:
- Call init_ai_client(config)
- Log "AI client initialized with {config.AI_ROUTER}"
Follow existing pattern - database is initialized in post_init, AI client goes right after.
Keep error handling minimal - if AI_API_KEY is missing, let it fail at first use rather than at startup (user may just want to test bot commands first).
python -c "import moai.bot.main; print('main imports ok')"
main.py imports and initializes AI client alongside database in post_init
Task 2: Create /ask handler for single model queries
src/moai/bot/handlers/discussion.py, src/moai/bot/handlers/__init__.py
Create discussion.py with /ask handler:
1. Create src/moai/bot/handlers/discussion.py:
```python
"""Discussion handlers for MoAI bot."""
from telegram import Update
from telegram.ext import ContextTypes
from moai.bot.handlers.projects import get_selected_project
from moai.core.ai_client import get_ai_client, MODEL_MAP
async def ask_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Handle /ask command.
Examples:
/ask claude What is Python?
/ask gpt Explain async/await
"""
args = context.args or []
if len(args) < 2:
available = ", ".join(MODEL_MAP.keys())
await update.message.reply_text(
f"Usage: /ask \n"
f"Available models: {available}\n\n"
f"Example: /ask claude What is Python?"
)
return
model_name = args[0].lower()
question = " ".join(args[1:])
# Validate model
if model_name not in MODEL_MAP:
available = ", ".join(MODEL_MAP.keys())
await update.message.reply_text(
f"Unknown model: {model_name}\n"
f"Available: {available}"
)
return
# Get project context if available (optional for /ask)
project = await get_selected_project(context)
project_context = f"Project: {project.name}\n" if project else ""
# Send "typing" indicator while waiting for AI
await update.message.chat.send_action("typing")
try:
client = get_ai_client()
response = await client.complete(
model=model_name,
messages=[{"role": "user", "content": question}],
system_prompt=f"{project_context}You are a helpful AI assistant."
)
# Format response with model name
await update.message.reply_text(
f"*{model_name.title()}:*\n\n{response}",
parse_mode="Markdown"
)
except Exception as e:
await update.message.reply_text(f"Error: {e}")
```
2. Update handlers/__init__.py:
- Import ask_command from discussion
- Add CommandHandler("ask", ask_command) to register_handlers
python -c "from moai.bot.handlers.discussion import ask_command; print('handler ok')"
/ask handler registered, validates model name, sends typing indicator, calls AI client
Task 3: Update help text and status
src/moai/bot/handlers/commands.py, src/moai/bot/handlers/status.py
1. Update HELP_TEXT in commands.py to include:
```
*Questions*
/ask - Ask a single model
```
Add after the Project Management section.
2. Update status.py to show AI client status:
- Import get_ai_client (wrapped in try/except)
- In status_command, add a line showing AI router configured
- Example: "AI Router: requesty ✓" or "AI Router: not configured"
python -c "from moai.bot.handlers.commands import HELP_TEXT; print('/ask' in HELP_TEXT)"
Help shows /ask command, status shows AI router status
Before declaring plan complete:
- [ ] `ruff check src` passes
- [ ] Bot starts without errors (with valid AI_API_KEY in env)
- [ ] /help shows /ask command
- [ ] /status shows AI router status
- [ ] /ask without args shows usage
- [ ] /ask with invalid model shows available models
- AI client initialized in bot lifecycle
- /ask command works with model validation
- Help text updated with /ask
- Status shows AI configuration
- M3 milestone: Single model Q&A working