# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: WebMCP (experimental)

from __future__ import annotations
import enum
import typing
from dataclasses import dataclass
from .util import event_class, T_JSON_DICT
from . import dom
from . import page
from . import runtime


@dataclass
class Annotation:
    """Tool annotations"""
    #: A hint indicating that the tool does not modify any state.
    read_only: typing.Optional[bool] = None
    #: If the declarative tool was declared with the autosubmit attribute.
    autosubmit: typing.Optional[bool] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        if self.read_only is not None:
            json["readOnly"] = self.read_only
        if self.autosubmit is not None:
            json["autosubmit"] = self.autosubmit
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> Annotation:
        return cls(
            read_only=bool(json["readOnly"])
            if json.get("readOnly", None) is not None
            else None,
            autosubmit=bool(json["autosubmit"])
            if json.get("autosubmit", None) is not None
            else None,
        )


class InvocationStatus(enum.Enum):
    """Represents the status of a tool invocation."""
    SUCCESS = "Success"
    CANCELED = "Canceled"
    ERROR = "Error"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> InvocationStatus:
        return cls(json)


@dataclass
class Tool:
    """Definition of a tool that can be invoked."""
    #: Tool name.
    name: str
    #: Tool description.
    description: str
    #: Frame identifier associated with the tool registration.
    frame_id: page.FrameId
    #: Schema for the tool's input parameters.
    input_schema: typing.Optional[dict] = None
    #: Optional annotations for the tool.
    annotations: typing.Optional[Annotation] = None
    #: Optional node ID for declarative tools.
    backend_node_id: typing.Optional[dom.BackendNodeId] = None
    #: The stack trace at the time of the registration.
    stack_trace: typing.Optional[runtime.StackTrace] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["name"] = self.name
        json["description"] = self.description
        json["frameId"] = self.frame_id.to_json()
        if self.input_schema is not None:
            json["inputSchema"] = self.input_schema
        if self.annotations is not None:
            json["annotations"] = self.annotations.to_json()
        if self.backend_node_id is not None:
            json["backendNodeId"] = self.backend_node_id.to_json()
        if self.stack_trace is not None:
            json["stackTrace"] = self.stack_trace.to_json()
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> Tool:
        return cls(
            name=str(json["name"]),
            description=str(json["description"]),
            frame_id=page.FrameId.from_json(json["frameId"]),
            input_schema=dict(json["inputSchema"])
            if json.get("inputSchema", None) is not None
            else None,
            annotations=Annotation.from_json(json["annotations"])
            if json.get("annotations", None) is not None
            else None,
            backend_node_id=dom.BackendNodeId.from_json(json["backendNodeId"])
            if json.get("backendNodeId", None) is not None
            else None,
            stack_trace=runtime.StackTrace.from_json(json["stackTrace"])
            if json.get("stackTrace", None) is not None
            else None,
        )


def enable() -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Enables the WebMCP domain, allowing events to be sent.
    Enabling the domain will trigger a toolsAdded event for
    all currently registered tools.
    """
    cmd_dict: T_JSON_DICT = {
        "method": "WebMCP.enable",
    }
    json = yield cmd_dict  # noqa


def disable() -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """Disables the WebMCP domain."""
    cmd_dict: T_JSON_DICT = {
        "method": "WebMCP.disable",
    }
    json = yield cmd_dict  # noqa


@event_class("WebMCP.toolsAdded")
@dataclass
class ToolsAdded:
    """Event fired when new tools are added."""
    #: Array of tools that were added.
    tools: typing.List[Tool]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolsAdded:
        return cls(tools=[Tool.from_json(i) for i in json["tools"]])


@event_class("WebMCP.toolsRemoved")
@dataclass
class ToolsRemoved:
    """Event fired when tools are removed."""
    #: Array of tools that were removed.
    tools: typing.List[Tool]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolsRemoved:
        return cls(tools=[Tool.from_json(i) for i in json["tools"]])


@event_class("WebMCP.toolInvoked")
@dataclass
class ToolInvoked:
    """Event fired when a tool invocation starts."""
    #: Name of the tool to invoke.
    tool_name: str
    #: Frame id
    frame_id: page.FrameId
    #: Invocation identifier.
    invocation_id: str
    #: The input parameters used for the invocation.
    input_: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolInvoked:
        return cls(
            tool_name=str(json["toolName"]),
            frame_id=page.FrameId.from_json(json["frameId"]),
            invocation_id=str(json["invocationId"]),
            input_=str(json["input"]),
        )


@event_class("WebMCP.toolResponded")
@dataclass
class ToolResponded:
    """Event fired when a tool invocation completes or fails."""
    #: Invocation identifier.
    invocation_id: str
    #: Status of the invocation.
    status: InvocationStatus
    #: Output or error delivered as delivered to the agent.
    #: Missing if ``status`` is anything other than Success.
    output: typing.Optional[typing.Any]
    #: Error text for protocol users.
    error_text: typing.Optional[str]
    #: The exception object, if the javascript tool threw an error>
    exception: typing.Optional[runtime.RemoteObject]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolResponded:
        return cls(
            invocation_id=str(json["invocationId"]),
            status=InvocationStatus.from_json(json["status"]),
            output=json["output"]
            if json.get("output", None) is not None
            else None,
            error_text=str(json["errorText"])
            if json.get("errorText", None) is not None
            else None,
            exception=runtime.RemoteObject.from_json(json["exception"])
            if json.get("exception", None) is not None
            else None,
        )
