Includes atomic migrations, per-rule reminder semantics, first-run helper script and the note on the undecided UI chat idea. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
49 lines
1.9 KiB
Python
49 lines
1.9 KiB
Python
from typing import Callable, Sequence
|
|
|
|
from ..models import KIND_PROBLEM, Event, is_host_service
|
|
from .limits import AI_HINTS_TOTAL_MAX
|
|
from .rules import Route, matching_rules
|
|
|
|
SECONDS_PER_MINUTE = 60
|
|
|
|
|
|
def _problem_probe(host: str, service: str, state: int, output: str) -> Event:
|
|
return Event(0, host, service, KIND_PROBLEM, state, output)
|
|
|
|
|
|
def resolve_delay(rules: Sequence[Route], host: str, service: str, state: int, output: str,
|
|
default_minutes: int) -> int:
|
|
found = matching_rules(rules, _problem_probe(host, service, state, output))
|
|
delays = [r.delay_minutes for r in found if r.delay_minutes is not None]
|
|
return min(delays) if delays else default_minutes
|
|
|
|
|
|
def delay_provider(rules: Sequence[Route], default_minutes: int,
|
|
host_minutes: int = 0) -> Callable[[str, str, int, str], int]:
|
|
def seconds(host: str, service: str, state: int, output: str) -> int:
|
|
if is_host_service(service):
|
|
return host_minutes * SECONDS_PER_MINUTE
|
|
return resolve_delay(rules, host, service, state, output, default_minutes) * SECONDS_PER_MINUTE
|
|
return seconds
|
|
|
|
|
|
def ai_allowed(rules: Sequence[Route], event: Event) -> bool:
|
|
return all(rule.ai_enabled for rule in matching_rules(rules, event))
|
|
|
|
|
|
def resolve_loud(rules: Sequence[Route], event: Event) -> bool:
|
|
found = matching_rules(rules, event)
|
|
return not found or any(rule.loud for rule in found)
|
|
|
|
|
|
def ai_hints(rules: Sequence[Route], event: Event) -> str:
|
|
hints = [rule.ai_hint.strip() for rule in matching_rules(rules, event) if rule.ai_hint.strip()]
|
|
return "\n".join(hints)[:AI_HINTS_TOTAL_MAX]
|
|
|
|
|
|
def resolve_reminder_hours(rules: Sequence[Route], event: Event, default_hours: int) -> int:
|
|
values = [r.reminder_hours for r in matching_rules(rules, event) if r.reminder_hours is not None]
|
|
if any(value <= 0 for value in values):
|
|
return 0
|
|
return min(values) if values else default_hours
|