Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/components/costdetails.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

## Fields

| Field | Type | Required | Description |
| -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- |
| `upstream_inference_cost` | *OptionalNullable[float]* | :heavy_minus_sign: | N/A |
| `upstream_inference_input_cost` | *float* | :heavy_check_mark: | N/A |
| `upstream_inference_output_cost` | *float* | :heavy_check_mark: | N/A |
| Field | Type | Required | Description |
| ---------------------------------------- | ------------------------- | ------------------ | ----------- |
| `upstream_inference_completions_cost` | *float* | :heavy_check_mark: | N/A |
| `upstream_inference_prompt_cost` | *float* | :heavy_check_mark: | N/A |
| `upstream_inference_cost` | *OptionalNullable[float]* | :heavy_minus_sign: | N/A |
7 changes: 3 additions & 4 deletions src/openrouter/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1263,9 +1263,8 @@
UpdateGuardrailResponseTypedDict,
)
from .urlcitation import URLCitation, URLCitationType, URLCitationTypedDict
from .costdetails import CostDetails, CostDetailsTypedDict
from .usage import (
CostDetails,
CostDetailsTypedDict,
InputTokensDetails,
InputTokensDetailsTypedDict,
OutputTokensDetails,
Expand Down Expand Up @@ -3319,8 +3318,8 @@
"URLCitation": ".urlcitation",
"URLCitationType": ".urlcitation",
"URLCitationTypedDict": ".urlcitation",
"CostDetails": ".usage",
"CostDetailsTypedDict": ".usage",
"CostDetails": ".costdetails",
"CostDetailsTypedDict": ".costdetails",
"InputTokensDetails": ".usage",
"InputTokensDetailsTypedDict": ".usage",
"OutputTokensDetails": ".usage",
Expand Down
25 changes: 23 additions & 2 deletions src/openrouter/components/chatusage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from typing import Optional
from typing_extensions import NotRequired, TypedDict

from .costdetails import CostDetails, CostDetailsTypedDict


class CompletionTokensDetailsTypedDict(TypedDict):
r"""Detailed completion token usage"""
Expand Down Expand Up @@ -124,6 +126,11 @@ class ChatUsageTypedDict(TypedDict):
r"""Detailed completion token usage"""
prompt_tokens_details: NotRequired[Nullable[PromptTokensDetailsTypedDict]]
r"""Detailed prompt token usage"""
cost: NotRequired[Nullable[float]]
r"""Cost of the completion"""
cost_details: NotRequired[CostDetailsTypedDict]
is_byok: NotRequired[bool]
r"""Whether a request was made using a Bring Your Own Key configuration"""


class ChatUsage(BaseModel):
Expand All @@ -144,10 +151,24 @@ class ChatUsage(BaseModel):
prompt_tokens_details: OptionalNullable[PromptTokensDetails] = UNSET
r"""Detailed prompt token usage"""

cost: OptionalNullable[float] = UNSET
r"""Cost of the completion"""

cost_details: Optional[CostDetails] = None

is_byok: Optional[bool] = None
r"""Whether a request was made using a Bring Your Own Key configuration"""

@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["completion_tokens_details", "prompt_tokens_details"]
nullable_fields = ["completion_tokens_details", "prompt_tokens_details"]
optional_fields = [
"completion_tokens_details",
"prompt_tokens_details",
"cost",
"cost_details",
"is_byok",
]
nullable_fields = ["completion_tokens_details", "prompt_tokens_details", "cost"]
null_default_fields = []

serialized = handler(self)
Expand Down
60 changes: 60 additions & 0 deletions src/openrouter/components/costdetails.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing_extensions import NotRequired, TypedDict


class CostDetailsTypedDict(TypedDict):
r"""Breakdown of upstream inference costs"""

upstream_inference_completions_cost: float
upstream_inference_prompt_cost: float
upstream_inference_cost: NotRequired[Nullable[float]]


class CostDetails(BaseModel):
r"""Breakdown of upstream inference costs"""

upstream_inference_completions_cost: float

upstream_inference_prompt_cost: float

upstream_inference_cost: OptionalNullable[float] = UNSET

@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["upstream_inference_cost"]
nullable_fields = ["upstream_inference_cost"]
null_default_fields = []

serialized = handler(self)

m = {}

for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)

optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member

if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val

return m