"""Auto-generated by bindgen. Do not edit."""
# ruff: noqa: E501, F401, I001
# fmt: off

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Optional, Union

from wasmtime.component import Variant as _WitVariant
from wasmtime.component import VariantCase as _WitVariantCase

from .messages import ContentBlock, Message, Metrics, ToolResultBlock, ToolUseBlock, Usage
from .models import ModelError
from .tools import ToolError


@dataclass(kw_only=True)
class Interrupt:
    """Human-in-the-loop interrupt raised by a tool or hook."""
    id: str
    name: str
    reason: str | None


class StopReason(str):
    """Why the model stopped generating."""
    __slots__ = ()

    END_TURN: StopReason
    TOOL_USE: StopReason
    MAX_TOKENS: StopReason
    ERROR: StopReason
    CONTENT_FILTERED: StopReason
    GUARDRAIL_INTERVENED: StopReason
    STOP_SEQUENCE: StopReason
    MODEL_CONTEXT_WINDOW_EXCEEDED: StopReason
    CANCELLED: StopReason

StopReason.END_TURN = StopReason('end-turn')  # type: ignore[attr-defined]
StopReason.TOOL_USE = StopReason('tool-use')  # type: ignore[attr-defined]
StopReason.MAX_TOKENS = StopReason('max-tokens')  # type: ignore[attr-defined]
StopReason.ERROR = StopReason('error')  # type: ignore[attr-defined]
StopReason.CONTENT_FILTERED = StopReason('content-filtered')  # type: ignore[attr-defined]
StopReason.GUARDRAIL_INTERVENED = StopReason('guardrail-intervened')  # type: ignore[attr-defined]
StopReason.STOP_SEQUENCE = StopReason('stop-sequence')  # type: ignore[attr-defined]
StopReason.MODEL_CONTEXT_WINDOW_EXCEEDED = StopReason('model-context-window-exceeded')  # type: ignore[attr-defined]
StopReason.CANCELLED = StopReason('cancelled')  # type: ignore[attr-defined]


@dataclass(kw_only=True)
class MetadataEvent:
    """Usage and metrics accumulated so far."""
    usage: Usage | None
    metrics: Metrics | None


@dataclass(kw_only=True)
class TraceMetadataEntry:
    """Single key-value pair attached to a trace. Values are string-typed
to keep traces compact; structured payloads belong on `message`."""
    key: str
    value: str


@dataclass(kw_only=True)
class AgentTrace:
    """In-memory trace node. Returned flat; reconstruct the tree via `parent-id`."""
    id: str
    name: str
    parent_id: str | None
    start_time_ms: int
    end_time_ms: int | None
    duration_ms: int
    metadata: list[TraceMetadataEntry]
    message: Message | None


@dataclass(kw_only=True)
class ToolMetrics:
    """Per-tool execution metrics keyed by tool name in `agent-metrics`."""
    tool_name: str
    call_count: int
    success_count: int
    error_count: int
    total_time_ms: int


@dataclass(kw_only=True)
class InvocationMetrics:
    """Per-invocation metrics. Cycles are flattened into `agent-metrics.cycles`
and linked back via `invocation-id`."""
    invocation_id: str
    usage: Usage


@dataclass(kw_only=True)
class AgentLoopMetrics:
    """Per-cycle usage tracking."""
    cycle_id: str
    invocation_id: str
    duration_ms: int
    usage: Usage


@dataclass(kw_only=True)
class AgentMetrics:
    """Snapshot of agent metrics. Returned by `agent.get-metrics`."""
    cycle_count: int
    accumulated_usage: Usage
    accumulated_metrics: Metrics
    invocations: list[InvocationMetrics]
    cycles: list[AgentLoopMetrics]
    tool_metrics: list[ToolMetrics]
    latest_context_size: int | None
    projected_context_size: int | None


@dataclass(kw_only=True)
class ToolUseData:
    """Mutable tool-use descriptor. `before-tool-call` hooks may rewrite fields."""
    name: str
    tool_use_id: str
    input: str


@dataclass(kw_only=True)
class HookRedaction:
    """Redaction information when guardrails block content."""
    user_message: str


@dataclass(kw_only=True)
class ModelStopData:
    """Model response surfaced on `after-model-call`."""
    message: Message
    stop_reason: StopReason
    redaction: HookRedaction | None


@dataclass(kw_only=True)
class BeforeInvocationData:
    """Payload for `before-invocation`."""
    invocation_state: str


@dataclass(kw_only=True)
class AfterInvocationData:
    """Payload for `after-invocation`."""
    invocation_state: str


@dataclass(kw_only=True)
class MessageAddedData:
    """Payload for `message-added`."""
    message: Message


@dataclass(kw_only=True)
class BeforeModelCallData:
    """Payload for `before-model-call`."""
    projected_input_tokens: int | None


@dataclass(kw_only=True)
class AfterModelCallData:
    """Payload for `after-model-call`."""
    attempt_count: int
    stop_data: ModelStopData | None
    error: ModelError | None


@dataclass(kw_only=True)
class BeforeToolCallData:
    """Payload for `before-tool-call`."""
    tool_use: ToolUseData


@dataclass(kw_only=True)
class AfterToolCallData:
    """Payload for `after-tool-call`."""
    tool_use: ToolUseData
    tool_result: ToolResultBlock
    error: ToolError | None


@dataclass(kw_only=True)
class ToolsBatchData:
    """Payload for `before-tools` / `after-tools`."""
    message: Message


@dataclass(kw_only=True)
class ContentBlockData:
    """Payload for `content-block`."""
    content_block: ContentBlock


@dataclass(kw_only=True)
class ModelMessageData:
    """Payload for `model-message`."""
    message: Message
    stop_reason: StopReason


@dataclass(kw_only=True)
class ToolResultData:
    """Payload for `tool-result-hook`."""
    tool_result: ToolResultBlock


@dataclass(kw_only=True)
class ToolStreamUpdateData:
    """Payload for `tool-stream-update`."""
    data: str


@dataclass(kw_only=True)
class ModelStreamUpdateData:
    """Payload for `model-stream-update`."""
    event: str


@dataclass(kw_only=True)
class InputRedaction:
    """Input redaction emitted when a guardrail blocks input. Original is in history."""
    replace_content: str


@dataclass(kw_only=True)
class OutputRedaction:
    """Output redaction emitted when a guardrail blocks output."""
    redacted_content: str | None
    replace_content: str


@dataclass(kw_only=True)
class RedactionEvent:
    """Redaction event. Input and output fields are independent; at least one is set."""
    input_redaction: InputRedaction | None
    output_redaction: OutputRedaction | None


@dataclass(kw_only=True)
class StopEvent:
    """Terminal event for a stream."""
    reason: StopReason
    usage: Usage | None
    metrics: Metrics | None
    structured_output: str | None


@dataclass(kw_only=True)
class AgentResultData:
    """Payload for `agent-result`."""
    stop: StopEvent


class StreamError:
    """Why the agent loop surfaced an error mid-stream."""

    class Model(_WitVariantCase):
        """A model call failed."""
        tag = 'model'

    class Tool(_WitVariantCase):
        """A tool call failed."""
        tag = 'tool'

    class ContextWindowExceeded(_WitVariantCase):
        """Input exceeded the model's context window and no conversation
manager could recover."""
        tag = 'context-window-exceeded'

    class MaxTokensReached(_WitVariantCase):
        """Exceeded the model's max-tokens budget mid-response."""
        tag = 'max-tokens-reached'

    class StructuredOutputUnavailable(_WitVariantCase):
        """Structured output was requested but the model never called the
tool, even after being forced."""
        tag = 'structured-output-unavailable'

    class Internal(_WitVariantCase):
        """Catch-all for internal failures."""
        tag = 'internal'

    _CASES: dict[str, type] = {
        'model': Model,
        'tool': Tool,
        'context-window-exceeded': ContextWindowExceeded,
        'max-tokens-reached': MaxTokensReached,
        'structured-output-unavailable': StructuredOutputUnavailable,
        'internal': Internal,
    }

    @staticmethod
    def lift(raw: _WitVariant) -> StreamError:
        cls = StreamError._CASES.get(raw.tag)
        if cls is None:
            raise ValueError(f'unknown StreamError arm: {raw.tag!r}')
        return cls(raw.payload)

class StreamEvent:
    """Events yielded during agent streaming.
Hot-path arms: `text-delta`, `tool-use`, `tool-result`. Other content
blocks flow through `content`. Lifecycle arms (`before-invocation`
through `agent-result`) mirror a hook system and can be filtered by tag."""

    class TextDelta(_WitVariantCase):
        """Incremental text from the model."""
        tag = 'text-delta'

    class ToolUse(_WitVariantCase):
        """Model requested a tool call."""
        tag = 'tool-use'

    class ToolResult(_WitVariantCase):
        """Tool call completed."""
        tag = 'tool-result'

    class Content(_WitVariantCase):
        """Non-hot-path content block (image, reasoning, citations, etc)."""
        tag = 'content'

    class Metadata(_WitVariantCase):
        """Cumulative usage and metrics snapshot."""
        tag = 'metadata'

    class Stop(_WitVariantCase):
        """Terminal event for the stream."""
        tag = 'stop'

    class Redaction(_WitVariantCase):
        """Guardrail redaction fired."""
        tag = 'redaction'

    class Error(_WitVariantCase):
        """Recoverable error surfaced mid-stream."""
        tag = 'error'

    class Interrupt(_WitVariantCase):
        """Human-in-the-loop pause; resume via `response-stream.respond`."""
        tag = 'interrupt'

    class Initialized(_WitVariantCase):
        """Agent finished construction."""
        tag = 'initialized'

    class BeforeInvocation(_WitVariantCase):
        """About to process a user invocation."""
        tag = 'before-invocation'

    class AfterInvocation(_WitVariantCase):
        """Finished processing a user invocation."""
        tag = 'after-invocation'

    class MessageAdded(_WitVariantCase):
        """A message was appended to the conversation."""
        tag = 'message-added'

    class BeforeModelCall(_WitVariantCase):
        """About to call the model."""
        tag = 'before-model-call'

    class AfterModelCall(_WitVariantCase):
        """Model call returned."""
        tag = 'after-model-call'

    class BeforeTools(_WitVariantCase):
        """About to run a batch of tool calls from one assistant turn."""
        tag = 'before-tools'

    class AfterTools(_WitVariantCase):
        """Tool batch finished."""
        tag = 'after-tools'

    class BeforeToolCall(_WitVariantCase):
        """About to call a single tool."""
        tag = 'before-tool-call'

    class AfterToolCall(_WitVariantCase):
        """Tool call returned."""
        tag = 'after-tool-call'

    class ContentBlock(_WitVariantCase):
        """A content block was assembled during streaming."""
        tag = 'content-block'

    class ModelMessage(_WitVariantCase):
        """Model finished producing a full message."""
        tag = 'model-message'

    class ToolResultHook(_WitVariantCase):
        """Tool finished execution (completion event, not streaming update)."""
        tag = 'tool-result-hook'

    class ToolUpdate(_WitVariantCase):
        """Streaming update from a tool."""
        tag = 'tool-update'

    class ModelUpdate(_WitVariantCase):
        """Streaming update from the model."""
        tag = 'model-update'

    class AgentResult(_WitVariantCase):
        """Final event for an invocation, carrying the terminal result."""
        tag = 'agent-result'

    _CASES: dict[str, type] = {
        'text-delta': TextDelta,
        'tool-use': ToolUse,
        'tool-result': ToolResult,
        'content': Content,
        'metadata': Metadata,
        'stop': Stop,
        'redaction': Redaction,
        'error': Error,
        'interrupt': Interrupt,
        'initialized': Initialized,
        'before-invocation': BeforeInvocation,
        'after-invocation': AfterInvocation,
        'message-added': MessageAdded,
        'before-model-call': BeforeModelCall,
        'after-model-call': AfterModelCall,
        'before-tools': BeforeTools,
        'after-tools': AfterTools,
        'before-tool-call': BeforeToolCall,
        'after-tool-call': AfterToolCall,
        'content-block': ContentBlock,
        'model-message': ModelMessage,
        'tool-result-hook': ToolResultHook,
        'tool-update': ToolUpdate,
        'model-update': ModelUpdate,
        'agent-result': AgentResult,
    }

    @staticmethod
    def lift(raw: _WitVariant) -> StreamEvent:
        cls = StreamEvent._CASES.get(raw.tag)
        if cls is None:
            raise ValueError(f'unknown StreamEvent arm: {raw.tag!r}')
        return cls(raw.payload)
