OpenRouter
NAME
LLM::Chat::Backend::Response::OpenRouter - OpenRouter-flavoured Response with cost + routing metadata
SYNOPSIS
use LLM::Chat::Backend::Response::OpenRouter;
use UUID::V4;
# Built by L<LLM::Chat::Backend::OpenRouter>'s C<chat-completion> path
# ā you rarely construct one directly. The shape below shows what's
# available once the backend has lifted the response body.
my $resp = LLM::Chat::Backend::Response::OpenRouter.new(id => uuid-v4());
# Inherited from base Response (OAI-spec):
# $resp.prompt-tokens / completion-tokens / total-tokens / model-used
#
# Added by Augment (OpenRouter-specific):
# $resp.cost ā USD spent (Num) when usage.cost is in the body
# $resp.generation-id ā OR's "gen-XXXX" id for /generation lookups
# $resp.provider-name ā provider OR routed to (e.g. "Anthropic")
# $resp.is-byok ā True when call used user's BYOK keys
DESCRIPTION
Subclass of LLM::Chat::Backend::Response that adds OpenRouter-only
usage and routing fields via the
LLM::Chat::Backend::Response::OpenRouter::Augment role. Use it (or
its streaming sibling
LLM::Chat::Backend::Response::OpenRouter::Stream) when you need to
read costs, look up generation metadata via OpenRouter's
/generation endpoint, or branch on which underlying provider
served a request.
The split lets a generic OpenAI-compatible client (any
OpenAICommon-derived backend) keep its Response surface clean ā
fields that don't exist on the wire for OpenAI proper don't leak
into the base type.
Why a role + two classes?
Response and Response::Stream are sibling classes (Stream
extends Response). Adding the OR-specific attrs + setter via a role
that both classes consume avoids diamond inheritance and keeps the
extra fields in one place.
The role declares only attrs and a fresh setter ā no callsame /
nextsame dispatch from inside the role, so it sidesteps the
known-broken role-redispatch case.