Spaces:
Sleeping
Sleeping
File size: 2,728 Bytes
6b4e5a8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | """Data models for the Spreadsheet Environment.
SpreadsheetAction has explicit Pydantic fields for MCP-style tool calls
(tool_name, arguments_json) compatible with the OpenEnv web interface.
"""
from __future__ import annotations
import json as _json
from typing import Any, Union
from pydantic import ConfigDict, Field, TypeAdapter, model_validator
from openenv.core.env_server.mcp_types import (
CallToolAction,
CallToolObservation,
ListToolsAction,
ListToolsObservation,
)
from openenv.core.env_server.types import Action, Observation, State
_mcp_action_adapter = TypeAdapter(Union[ListToolsAction, CallToolAction])
_AVAILABLE_TOOLS = (
"list_tools, get_session_info, list_scenarios, load_scenario, "
"list_sheets, read_range, write_cell, write_range, inspect_formula, "
"list_named_targets, validate_partial, submit_workbook, "
"get_edit_history, reset_scenario"
)
class SpreadsheetAction(Action):
"""Action with explicit fields for the web UI and MCP compatibility."""
model_config = ConfigDict(
extra="forbid",
validate_assignment=True,
arbitrary_types_allowed=True,
)
tool_name: str = Field(
default="list_tools",
description=f"MCP tool to invoke. Available: {_AVAILABLE_TOOLS}",
)
arguments_json: str = Field(
default="{}",
description=(
'Tool arguments as a JSON string. Examples: '
'"{}" for no args, '
'\'{"scenario_id":"formula_repair_01"}\' for load_scenario, '
'\'{"sheet":"Summary","range":"A1:D10"}\' for read_range, '
'\'{"sheet":"Summary","cell":"C15","value":"=SUM(A1:A10)"}\' for write_cell'
),
)
@model_validator(mode="after")
def _validate_json(self) -> "SpreadsheetAction":
if self.arguments_json.strip():
_json.loads(self.arguments_json)
return self
@classmethod
def model_validate(cls, data: Any, **kwargs: Any) -> Action:
if isinstance(data, dict) and data.get("type") in ("call_tool", "list_tools"):
return _mcp_action_adapter.validate_python(data)
return super().model_validate(data, **kwargs)
def to_mcp_action(self) -> Action:
if self.tool_name == "list_tools":
return ListToolsAction()
args = _json.loads(self.arguments_json) if self.arguments_json else {}
return CallToolAction(tool_name=self.tool_name, arguments=args)
SpreadsheetObservation = CallToolObservation
SpreadsheetState = State
__all__ = [
"SpreadsheetAction",
"SpreadsheetObservation",
"SpreadsheetState",
"CallToolAction",
"CallToolObservation",
"ListToolsAction",
"ListToolsObservation",
]
|