✅ TICKET-006: Wake-word Detection Service - Implemented wake-word detection using openWakeWord - HTTP/WebSocket server on port 8002 - Real-time detection with configurable threshold - Event emission for ASR integration - Location: home-voice-agent/wake-word/ ✅ TICKET-010: ASR Service - Implemented ASR using faster-whisper - HTTP endpoint for file transcription - WebSocket endpoint for streaming transcription - Support for multiple audio formats - Auto language detection - GPU acceleration support - Location: home-voice-agent/asr/ ✅ TICKET-014: TTS Service - Implemented TTS using Piper - HTTP endpoint for text-to-speech synthesis - Low-latency processing (< 500ms) - Multiple voice support - WAV audio output - Location: home-voice-agent/tts/ ✅ TICKET-047: Updated Hardware Purchases - Marked Pi5 kit, SSD, microphone, and speakers as purchased - Updated progress log with purchase status 📚 Documentation: - Added VOICE_SERVICES_README.md with complete testing guide - Each service includes README.md with usage instructions - All services ready for Pi5 deployment 🧪 Testing: - Created test files for each service - All imports validated - FastAPI apps created successfully - Code passes syntax validation 🚀 Ready for: - Pi5 deployment - End-to-end voice flow testing - Integration with MCP server Files Added: - wake-word/detector.py - wake-word/server.py - wake-word/requirements.txt - wake-word/README.md - wake-word/test_detector.py - asr/service.py - asr/server.py - asr/requirements.txt - asr/README.md - asr/test_service.py - tts/service.py - tts/server.py - tts/requirements.txt - tts/README.md - tts/test_service.py - VOICE_SERVICES_README.md Files Modified: - tickets/done/TICKET-047_hardware-purchases.md Files Moved: - tickets/backlog/TICKET-006_prototype-wake-word-node.md → tickets/done/ - tickets/backlog/TICKET-010_streaming-asr-service.md → tickets/done/ - tickets/backlog/TICKET-014_tts-service.md → tickets/done/
130 lines
4.1 KiB
Python
130 lines
4.1 KiB
Python
"""
|
|
Confirmation flow manager.
|
|
|
|
Orchestrates the confirmation process for high-risk actions.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Dict, Any, Optional, Tuple
|
|
from safety.confirmations.risk import get_classifier, RiskLevel
|
|
from safety.confirmations.confirmation_token import get_token_system
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ConfirmationFlow:
|
|
"""Manages confirmation flows for tool calls."""
|
|
|
|
def __init__(self):
|
|
"""Initialize confirmation flow."""
|
|
self.classifier = get_classifier()
|
|
self.token_system = get_token_system()
|
|
|
|
def check_confirmation_required(self, tool_name: str, **kwargs) -> Tuple[bool, Optional[str]]:
|
|
"""
|
|
Check if confirmation is required and get message.
|
|
|
|
Args:
|
|
tool_name: Name of the tool
|
|
**kwargs: Tool parameters
|
|
|
|
Returns:
|
|
(requires_confirmation, confirmation_message)
|
|
"""
|
|
requires = self.classifier.requires_confirmation(tool_name, **kwargs)
|
|
if requires:
|
|
message = self.classifier.get_confirmation_message(tool_name, **kwargs)
|
|
return True, message
|
|
return False, None
|
|
|
|
def generate_confirmation_token(self,
|
|
tool_name: str,
|
|
parameters: Dict[str, Any],
|
|
session_id: Optional[str] = None,
|
|
user_id: Optional[str] = None) -> str:
|
|
"""
|
|
Generate a confirmation token for an action.
|
|
|
|
Args:
|
|
tool_name: Name of the tool
|
|
parameters: Tool parameters
|
|
session_id: Session ID
|
|
user_id: User ID
|
|
|
|
Returns:
|
|
Confirmation token
|
|
"""
|
|
return self.token_system.generate_token(
|
|
tool_name=tool_name,
|
|
parameters=parameters,
|
|
session_id=session_id,
|
|
user_id=user_id
|
|
)
|
|
|
|
def validate_confirmation(self,
|
|
token: str,
|
|
tool_name: str,
|
|
parameters: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
|
"""
|
|
Validate a confirmation token.
|
|
|
|
Args:
|
|
token: Confirmation token
|
|
tool_name: Expected tool name
|
|
parameters: Expected parameters
|
|
|
|
Returns:
|
|
(is_valid, error_message)
|
|
"""
|
|
return self.token_system.verify_action(token, tool_name, parameters)
|
|
|
|
def process_confirmation_request(self,
|
|
tool_name: str,
|
|
parameters: Dict[str, Any],
|
|
session_id: Optional[str] = None,
|
|
user_id: Optional[str] = None) -> Dict[str, Any]:
|
|
"""
|
|
Process a confirmation request.
|
|
|
|
Args:
|
|
tool_name: Name of the tool
|
|
parameters: Tool parameters
|
|
session_id: Session ID
|
|
user_id: User ID
|
|
|
|
Returns:
|
|
Response dict with confirmation_required, message, and token
|
|
"""
|
|
requires, message = self.check_confirmation_required(tool_name, **parameters)
|
|
|
|
if requires:
|
|
token = self.generate_confirmation_token(
|
|
tool_name=tool_name,
|
|
parameters=parameters,
|
|
session_id=session_id,
|
|
user_id=user_id
|
|
)
|
|
|
|
return {
|
|
"confirmation_required": True,
|
|
"message": message,
|
|
"token": token,
|
|
"risk_level": self.classifier.classify_risk(tool_name, **parameters).value
|
|
}
|
|
else:
|
|
return {
|
|
"confirmation_required": False,
|
|
"message": None,
|
|
"token": None,
|
|
"risk_level": "low"
|
|
}
|
|
|
|
|
|
# Global flow instance
|
|
_flow = ConfirmationFlow()
|
|
|
|
|
|
def get_flow() -> ConfirmationFlow:
|
|
"""Get the global confirmation flow instance."""
|
|
return _flow
|