# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Optional
from typing_extensions import Literal

from ..._models import BaseModel

__all__ = ["BetaRefusalStopDetails"]


class BetaRefusalStopDetails(BaseModel):
    """Structured information about a refusal."""

    category: Optional[Literal["cyber", "bio", "frontier_llm", "reasoning_extraction"]] = None
    """The policy category that triggered the refusal.

    `null` when the refusal doesn't map to a named category.
    """

    explanation: Optional[str] = None
    """Human-readable explanation of the refusal.

    This text is not guaranteed to be stable. `null` when no explanation is
    available for the category.
    """

    fallback_credit_token: Optional[str] = None
    """
    Opaque code that refunds the cache-miss cost when retrying this refused request
    on the fallback model. Pass it as `fallback_credit_token` on the retry request.
    Expires 5 minutes after the refusal.

    The retry is sent either with the same request body (`system`, `messages`,
    `tools`, and other render-shaping fields), or with the same body plus one
    appended `assistant` message whose content is the partial text (with any
    trailing whitespace stripped from the final text block) and paired server-tool
    blocks from this refusal — which also authorizes that appended turn as an
    assistant-prefill continuation on models that otherwise disallow prefill. A
    token minted mid-server-tool-loop whose partial content was continuable may only
    be redeemed the second way — if a same-body retry is rejected with a 400 saying
    the token must be redeemed by continuing the partial response, retry the second
    way instead. Either way: same workspace, same platform; a mismatch is a 400.
    Resending a token for an already-warm prefix is permitted but yields no
    additional credit.

    `null` when the refused model isn't eligible for a fallback credit.
    """

    fallback_has_prefill_claim: Optional[bool] = None
    """
    Whether the accompanying `fallback_credit_token` may be redeemed with the
    appended-assistant retry form. Only set when `fallback_credit_token` is present.

    `true`: retry by resending the same request body plus one appended `assistant`
    message whose content is this response's `content` with any trailing whitespace
    stripped from the final text block and unpaired `tool_use` blocks omitted (the
    same appended-turn shape described on `fallback_credit_token`), with the token
    attached. `false`: retry by resending the original request body unchanged, with
    the token attached — the appended-assistant form is not available for this
    refusal (no continuable partial content, or the request uses `output_format` or
    a `tool_choice` that forces tool use). One exception: when the request used
    `output_format` or a forced `tool_choice` and the refusal arrived after server
    tools (including MCP connector tools) had already executed, the token may not be
    redeemable by either retry form; if the exact-body retry is then rejected with a
    400 saying the token must be redeemed by continuing the partial response,
    discard the token and retry without it.

    Advisory: if an appended-assistant retry is rejected with a 400 despite `true`,
    fall back to resending the original request body with the token.
    """

    recommended_model: Optional[str] = None
    """The server's suggested retry target for this refusal.

    Populated when a fallback attempt could not be made (the fallback model's rate
    limit was exhausted, or it was overloaded); names the fallback model the caller
    can retry directly. Null otherwise.
    """

    type: Literal["refusal"]
