feat: checkpoint device agent runtime milestones
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
SEMANTIC_SCENE_SCHEMA: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["page", "intents", "widgets"],
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"intents": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
},
|
||||
"widgets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["element_id", "purpose"],
|
||||
"properties": {
|
||||
"element_id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"purpose": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SemanticWidget:
|
||||
element_id: str
|
||||
purpose: str
|
||||
|
||||
def to_dict(self) -> dict[str, str]:
|
||||
return {
|
||||
"element_id": self.element_id,
|
||||
"purpose": self.purpose,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict[str, Any]) -> "SemanticWidget":
|
||||
if not isinstance(data, dict):
|
||||
raise TypeError("semantic widget must be a mapping")
|
||||
element_id = data.get("element_id")
|
||||
purpose = data.get("purpose")
|
||||
if not isinstance(element_id, str) or not element_id.strip():
|
||||
raise ValueError("semantic widget element_id must be a non-empty string")
|
||||
if not isinstance(purpose, str) or not purpose.strip():
|
||||
raise ValueError("semantic widget purpose must be a non-empty string")
|
||||
return cls(element_id=element_id, purpose=purpose)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SemanticScene:
|
||||
page: str
|
||||
intents: list[str] = field(default_factory=list)
|
||||
widgets: list[SemanticWidget] = field(default_factory=list)
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"page": self.page,
|
||||
"intents": list(self.intents),
|
||||
"widgets": [widget.to_dict() for widget in self.widgets],
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict[str, Any]) -> "SemanticScene":
|
||||
if not isinstance(data, dict):
|
||||
raise TypeError("semantic scene must be a mapping")
|
||||
page = data.get("page")
|
||||
intents = data.get("intents")
|
||||
widgets = data.get("widgets")
|
||||
if not isinstance(page, str) or not page.strip():
|
||||
raise ValueError("semantic scene page must be a non-empty string")
|
||||
if not isinstance(intents, list) or not all(
|
||||
isinstance(intent, str) and intent.strip() for intent in intents
|
||||
):
|
||||
raise ValueError("semantic scene intents must be non-empty strings")
|
||||
if not isinstance(widgets, list):
|
||||
raise ValueError("semantic scene widgets must be a list")
|
||||
return cls(
|
||||
page=page,
|
||||
intents=list(intents),
|
||||
widgets=[SemanticWidget.from_dict(widget) for widget in widgets],
|
||||
)
|
||||
Reference in New Issue
Block a user