SidhaGarg/Cloud-DevOps-RLEnv
0
1# Copyright (c) Meta Platforms, Inc. and affiliates.2# All rights reserved.3#4# This source code is licensed under the BSD-style license found in the5# LICENSE file in the root directory of this source tree.6 7"""8Data models for the Cloud Devops Env Environment.9 10The cloud_devops_env environment simulates cloud/devops incident response tasks.11"""12 13import json14from typing import Any, Dict, Literal, Optional15 16from openenv.core.env_server.types import Action, Observation, State17from pydantic import Field, field_validator18 19 20class CloudAction(Action):21 """Action space (what the agent can do)."""22 23 command: Literal[24 "list_resources",25 "describe_resource",26 "view_logs",27 "query_metadata",28 "update_security_group",29 "restart_service",30 "submit_solution",31 ] = Field(..., description="The cloud API command to execute.")32 resource_id: Optional[str] = Field(33 default=None,34 description=(35 "The ID of the target resource (e.g., 'i-12345'). "36 "Required for most commands except list_resources and query_metadata."37 ),38 )39 parameters: Optional[Dict[str, Any]] = Field(40 default=None,41 description=(42 "Key-value pairs for updates "43 "(e.g., {'port': '80', 'action': 'allow'} for update_security_group, "44 "or {'ip_address': '10.0.4.5'} for query_metadata)."45 ),46 )47 message: Optional[str] = Field(48 default=None,49 description="Legacy field from template env; safe to remove after server/client migration.",50 )51 52 @field_validator("parameters", mode="before")53 @classmethod54 def _coerce_parameters(cls, value: Any) -> Any:55 """Allow /web text input to pass JSON for dict parameters."""56 if value is None or value == "":57 return None58 if isinstance(value, dict):59 return value60 if isinstance(value, str):61 try:62 parsed = json.loads(value)63 except json.JSONDecodeError as exc:64 raise ValueError(65 "parameters must be a JSON object string, e.g. {\"port\":80,\"action\":\"allow\"}"66 ) from exc67 if not isinstance(parsed, dict):68 raise ValueError("parameters JSON must decode to an object/dictionary")69 return parsed70 raise ValueError("parameters must be a dictionary or JSON object string")71 72 73class CloudObservation(Observation):74 """Observation space (what the agent sees)."""75 76 output: str = Field(77 ...,78 description="The terminal/API response from the last command executed.",79 )80 error: Optional[str] = Field(81 default=None,82 description="Error message if the last command failed or was invalid.",83 )84 system_health_status: str = Field(85 ...,86 description="Current status of the system (e.g., 'CRITICAL', 'DEGRADED', 'HEALTHY').",87 )88 echoed_message: Optional[str] = Field(89 default=None,90 description="Legacy field from template env; safe to remove after server/client migration.",91 )92 message_length: int = Field(93 default=0,94 description="Legacy field from template env; safe to remove after server/client migration.",95 )96 97 98class CloudState(State):99 """State space (the hidden environment state)."""100 101 task_difficulty: str = Field(..., description="Current task: easy, medium, or hard.")102 resources: Dict[str, Dict[str, Any]] = Field(103 ...,104 description="The hidden JSON state of all mock cloud resources.",105 )106 step_count: int = Field(..., description="Number of actions taken so far.")107 is_resolved: bool = Field(108 ...,109 description="Whether the root cause has been successfully fixed.",110 )111 112 113# Backward-compatible aliases for scaffolded files that still use template names.114CloudDevopsAction = CloudAction115CloudDevopsObservation = CloudObservation116 