Files
voidea/app/services/command_service.py
T

113 lines
2.7 KiB
Python

"""Voice command service — CRUD for user-specific dynamic commands."""
from uuid import uuid4
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.voice_command import VoiceCommand
async def list_commands(
db: AsyncSession,
user_id: str,
active_only: bool = True,
) -> list[dict]:
stmt = select(VoiceCommand).where(VoiceCommand.user_id == user_id)
if active_only:
stmt = stmt.where(VoiceCommand.is_active == True)
stmt = stmt.order_by(VoiceCommand.count.desc())
result = await db.execute(stmt)
return [
{
"id": str(c.id),
"phrase": c.phrase,
"action": c.action,
"agent_name": c.agent_name,
"count": c.count,
"is_active": c.is_active,
}
for c in result.scalars().all()
]
async def create_command(
db: AsyncSession,
user_id: str,
phrase: str,
action: str,
agent_name: str | None = None,
) -> dict:
cmd = VoiceCommand(
id=uuid4(),
user_id=user_id,
phrase=phrase,
action=action,
agent_name=agent_name,
count=0,
is_active=True,
)
db.add(cmd)
await db.commit()
await db.refresh(cmd)
return {
"id": str(cmd.id),
"phrase": cmd.phrase,
"action": cmd.action,
"agent_name": cmd.agent_name,
"count": cmd.count,
"is_active": cmd.is_active,
}
async def increment_command(
db: AsyncSession,
command_id: str,
) -> bool:
result = await db.execute(
update(VoiceCommand)
.where(VoiceCommand.id == command_id)
.values(count=VoiceCommand.count + 1)
)
await db.commit()
return result.rowcount > 0
async def delete_command(db: AsyncSession, command_id: str, user_id: str) -> bool:
result = await db.execute(
select(VoiceCommand).where(
VoiceCommand.id == command_id,
VoiceCommand.user_id == user_id,
)
)
cmd = result.scalar_one_or_none()
if not cmd:
return False
await db.delete(cmd)
await db.commit()
return True
async def get_suggested_command(
db: AsyncSession,
user_id: str,
min_count: int = 3,
) -> dict | None:
"""Find a frequently used command that could be suggested."""
result = await db.execute(
select(VoiceCommand)
.where(VoiceCommand.user_id == user_id)
.where(VoiceCommand.count >= min_count)
.where(VoiceCommand.is_active == True)
.order_by(VoiceCommand.count.desc())
.limit(1)
)
cmd = result.scalar_one_or_none()
if not cmd:
return None
return {
"phrase": cmd.phrase,
"action": cmd.action,
"agent_name": cmd.agent_name,
}