feat(k1): complete canonical control lifecycle
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from collections.abc import Callable, Mapping
|
||||
from dataclasses import dataclass
|
||||
from datetime import UTC, datetime
|
||||
@@ -16,12 +17,14 @@ from missioncore_plugin_sdk.v0alpha2 import (
|
||||
RuntimeHealthSnapshot,
|
||||
RuntimePluginDescriptor,
|
||||
)
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic import BaseModel, ConfigDict, Field, ValidationError
|
||||
|
||||
from k1link.sessions.plugin_contract import ObservationRuntimeContribution
|
||||
|
||||
STATE_READ_ACTION_ID = "state.read"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DevicePluginActionRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
@@ -162,13 +165,28 @@ class InProcessDevicePluginRuntime:
|
||||
f"{invocation.action_id}"
|
||||
)
|
||||
output = await self._adapter.invoke(invocation)
|
||||
return RuntimeActionResult(
|
||||
invocation_id=invocation.invocation_id,
|
||||
plugin_id=invocation.plugin_id,
|
||||
action_id=invocation.action_id,
|
||||
completed_at=datetime.now(UTC),
|
||||
output=dict(output),
|
||||
)
|
||||
try:
|
||||
return RuntimeActionResult(
|
||||
invocation_id=invocation.invocation_id,
|
||||
plugin_id=invocation.plugin_id,
|
||||
action_id=invocation.action_id,
|
||||
completed_at=datetime.now(UTC),
|
||||
output=dict(output),
|
||||
)
|
||||
except ValidationError as exc:
|
||||
# Never allow a malformed plugin result to masquerade as invalid
|
||||
# operator input (HTTP 422). Do not log the output or validation
|
||||
# input: device snapshots may contain retained evidence.
|
||||
logger.error(
|
||||
"device plugin returned a non-JSON action result: "
|
||||
"plugin_id=%s action_id=%s validation_errors=%d",
|
||||
invocation.plugin_id,
|
||||
invocation.action_id,
|
||||
exc.error_count(),
|
||||
)
|
||||
raise PluginExecutionError(
|
||||
"Device plugin returned an invalid non-JSON action result"
|
||||
) from exc
|
||||
|
||||
def close(self) -> None:
|
||||
with self._lock:
|
||||
|
||||
Reference in New Issue
Block a user