Coverage for core / src / sensorkit / std / safety.py: 93%
29 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-02 00:03 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-02 00:03 +0000
1# SPDX-License-Identifier: Apache-2.0
2from __future__ import annotations
4from typing import Literal, override
6from pydantic import BaseModel
8import sensorkit.api as sk
9from sensorkit.auto.constraint import Constraint, ConstraintEvaluator
10from sensorkit.common.keyword import validate_keyword_json
11from sensorkit.core.client import SensorKit
14@sk.declare_keyword
15class BasicSafety(BaseModel):
16 """Simple safety monitor keyword indicating whether conditions are currently safe to operate."""
17 is_safe: bool
20SafetyProvider = sk.declare_trait(
21 "SafetyProvider",
22 required_keywords=("BasicSafety",),
23)
25StandardSafety = sk.declare_archetype(
26 "safety",
27 required_traits=(SafetyProvider,),
28)
29"""Standard archetype for safety / go-no-go providers."""
32class SafetyConstraint(Constraint):
33 """Constraint that monitors a BasicSafety provider and activates when conditions are unsafe."""
35 kind: Literal["safety"] = "safety"
36 provider: str
38 @override
39 async def check_task(self, evaluator: ConstraintEvaluator, kit: SensorKit):
40 provider = kit.entity(self.provider)
41 consumer = await provider._stream.consume("BasicSafety")
43 async for msg in consumer:
44 try:
45 safety = validate_keyword_json("BasicSafety", msg.data)
46 except Exception:
47 continue
49 if not safety.is_safe:
50 evaluator.constrain("unsafe")
51 else:
52 evaluator.clear("safe")
54 evaluator.ready()