Coverage for apps / ai / services / timer.py: 25%

24 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 00:40 +0000

1"""Timer naming service using AI.""" 

2 

3import logging 

4 

5from ..models import AIPrompt 

6from .openrouter import OpenRouterService 

7from .validator import AIResponseValidator 

8 

9logger = logging.getLogger(__name__) 

10 

11 

12def generate_timer_name(step_text: str, duration_minutes: int) -> dict: 

13 """Generate a descriptive name for a cooking timer. 

14 

15 Args: 

16 step_text: The cooking instruction text. 

17 duration_minutes: The timer duration in minutes. 

18 

19 Returns: 

20 Dict with the generated label. 

21 

22 Raises: 

23 AIUnavailableError: If AI service is not available. 

24 AIResponseError: If AI returns invalid response. 

25 ValidationError: If response doesn't match expected schema. 

26 """ 

27 # Get the timer_naming prompt 

28 prompt = AIPrompt.get_prompt('timer_naming') 

29 

30 # Format duration nicely 

31 if duration_minutes >= 60: 

32 hours = duration_minutes // 60 

33 mins = duration_minutes % 60 

34 if mins > 0: 

35 duration_str = f'{hours} hour{"s" if hours > 1 else ""} {mins} minute{"s" if mins > 1 else ""}' 

36 else: 

37 duration_str = f'{hours} hour{"s" if hours > 1 else ""}' 

38 else: 

39 duration_str = f'{duration_minutes} minute{"s" if duration_minutes > 1 else ""}' 

40 

41 # Format the user prompt 

42 user_prompt = prompt.format_user_prompt( 

43 instruction=step_text, 

44 duration=duration_str, 

45 ) 

46 

47 # Call AI service 

48 service = OpenRouterService() 

49 response = service.complete( 

50 system_prompt=prompt.system_prompt, 

51 user_prompt=user_prompt, 

52 model=prompt.model, 

53 json_response=True, 

54 ) 

55 

56 # Validate response 

57 validator = AIResponseValidator() 

58 result = validator.validate('timer_naming', response) 

59 

60 # Truncate label if too long (max 30 chars as per spec) 

61 label = result['label'] 

62 if len(label) > 30: 

63 label = label[:27] + '...' 

64 

65 logger.info(f'Generated timer name: "{label}" for {duration_minutes}min timer') 

66 

67 return { 

68 'label': label, 

69 } 

← Back to Dashboard