"""Response items used in agent execution."""

from __future__ import annotations

from typing import Literal, TypeAlias
from pydantic import BaseModel, ConfigDict

from openai.types.responses import (
    ResponseOutputMessage,
    ResponseReasoningItem,
    ResponseFunctionToolCall,
    ResponseFunctionWebSearch,
    ResponseInputText,
)


class ResponseFunctionToolCallOutput(BaseModel):
    """The output of a function tool call."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    call_id: str
    """The unique ID of the function tool call generated by the model."""

    output: str | ResponseInputText
    """The output from the function call generated by your code."""

    name: str
    """The name of the function tool call."""

    type: Literal["function_call_output"]
    """The type of the function tool call output. Always `function_call_output`."""

    id: str | None = None
    """The unique ID of the function tool call output."""

    status: Literal["in_progress", "completed", "incomplete"] | None = None
    """The status of the item."""


class MessageOutputItem(BaseModel):
    """Represents a message from the LLM."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    role: Literal["assistant"] = "assistant"

    content: str = ""
    """The text content of the message. Always `assistant`."""

    raw_item: ResponseOutputMessage | None = None
    """The raw response output message."""

    type: Literal["message_output_item"] = "message_output_item"
    """The type of the message output item. Always `message_output_item`."""


class ToolCallItem(BaseModel):
    """Represents a tool call e.g. a function call or computer action call."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    role: Literal["assistant"] = "assistant"

    content: str = ""
    """The content of the tool call. Usually empty."""

    raw_item: ResponseFunctionToolCall | ResponseFunctionWebSearch | None = None
    """The raw tool call item."""

    type: Literal["tool_call_item"] = "tool_call_item"
    """The type of the tool call item. Always `tool_call_item`."""


class ToolCallOutputItem(BaseModel):
    """Represents the output of a tool call."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    role: Literal["tool"] = "tool"

    content: str = ""
    """The output from the function call generated by your code."""

    raw_item: ResponseFunctionToolCallOutput | None = None
    """The raw tool call output item."""

    type: Literal["tool_call_output_item"] = "tool_call_output_item"
    """The type of the tool call output item. Always `tool_call_output_item`."""


class ReasoningItem(BaseModel):
    """Represents a reasoning item."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    role: Literal["assistant"] = "assistant"

    content: str | None = None
    """The reasoning content."""

    raw_item: ResponseReasoningItem | None = None
    """The raw reasoning item."""

    type: Literal["reasoning_item"] = "reasoning_item"
    """The type of the reasoning item. Always `reasoning_item`."""


RunItem: TypeAlias = (
    MessageOutputItem | ToolCallItem | ToolCallOutputItem | ReasoningItem
)
