docs: Mintlify MDX docs + docs.json; bump Speakeasy to 1.787.0 (#382)

This commit is contained in:
Matt Apperson
2026-06-30 16:13:28 -04:00
committed by GitHub
parent 778e2e36fb
commit babeffc9aa
2100 changed files with 50407 additions and 16612 deletions
+13 -1
View File
@@ -3,7 +3,7 @@
from abc import ABC, abstractmethod
import httpx
from openrouter.sdkconfiguration import SDKConfiguration
from typing import Any, Callable, List, Optional, Tuple, Union
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
class HookContext:
@@ -12,6 +12,8 @@ class HookContext:
operation_id: str
oauth2_scopes: Optional[List[str]] = None
security_source: Optional[Union[Any, Callable[[], Any]]] = None
tags: Optional[List[str]] = None
extensions: Optional[Dict[str, Any]] = None
def __init__(
self,
@@ -20,12 +22,16 @@ class HookContext:
operation_id: str,
oauth2_scopes: Optional[List[str]],
security_source: Optional[Union[Any, Callable[[], Any]]],
tags: Optional[List[str]],
extensions: Optional[Dict[str, Any]],
):
self.config = config
self.base_url = base_url
self.operation_id = operation_id
self.oauth2_scopes = oauth2_scopes
self.security_source = security_source
self.tags = tags
self.extensions = extensions
class BeforeRequestContext(HookContext):
@@ -36,6 +42,8 @@ class BeforeRequestContext(HookContext):
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
hook_ctx.tags,
hook_ctx.extensions,
)
@@ -47,6 +55,8 @@ class AfterSuccessContext(HookContext):
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
hook_ctx.tags,
hook_ctx.extensions,
)
@@ -58,6 +68,8 @@ class AfterErrorContext(HookContext):
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
hook_ctx.tags,
hook_ctx.extensions,
)
+3 -3
View File
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "openrouter"
__version__: str = "0.10.8"
__version__: str = "0.11.0"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.788.4"
__user_agent__: str = "speakeasy-sdk/python 0.10.8 2.788.4 1.0.0 openrouter"
__gen_version__: str = "2.914.0"
__user_agent__: str = "speakeasy-sdk/python 0.11.0 2.914.0 1.0.0 openrouter"
try:
if __package__ is not None:
+6 -2
View File
@@ -107,9 +107,11 @@ class Analytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Analytics"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -249,9 +251,11 @@ class Analytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Analytics"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+36 -12
View File
@@ -99,9 +99,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -217,9 +219,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -344,9 +348,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -476,9 +482,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -629,9 +637,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -792,9 +802,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -928,9 +940,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1059,9 +1073,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1190,9 +1206,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1321,9 +1339,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1476,9 +1496,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1636,9 +1658,11 @@ class APIKeys(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["API Keys"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "404", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+68 -46
View File
@@ -7,8 +7,14 @@ from openrouter._hooks import (
AfterErrorContext,
AfterSuccessContext,
BeforeRequestContext,
HookContext,
)
from openrouter.utils import (
RetryConfig,
SerializedRequestBody,
get_body_content,
run_sync_in_thread,
)
from openrouter.utils import RetryConfig, SerializedRequestBody, get_body_content
from typing import Callable, List, Mapping, Optional, Tuple
from urllib.parse import parse_qs, urlparse
@@ -61,6 +67,7 @@ class BaseSDK:
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[str]] = None,
) -> httpx.Request:
client = self.sdk_configuration.async_client
return self._build_request_with_client(
@@ -82,6 +89,7 @@ class BaseSDK:
url_override,
http_headers,
allow_empty_value,
allowed_fields,
)
def _build_request(
@@ -105,6 +113,7 @@ class BaseSDK:
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[str]] = None,
) -> httpx.Request:
client = self.sdk_configuration.client
return self._build_request_with_client(
@@ -126,6 +135,7 @@ class BaseSDK:
url_override,
http_headers,
allow_empty_value,
allowed_fields,
)
def _build_request_with_client(
@@ -150,6 +160,7 @@ class BaseSDK:
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[str]] = None,
) -> httpx.Request:
query_params = {}
@@ -183,7 +194,9 @@ class BaseSDK:
security = security()
security = utils.get_security_from_env(security, components.Security)
if security is not None:
security_headers, security_query_params = utils.get_security(security)
security_headers, security_query_params = utils.get_security(
security, allowed_fields
)
headers = {**headers, **security_headers}
query_params = {**query_params, **security_query_params}
@@ -220,15 +233,15 @@ class BaseSDK:
data=serialized_request_body.data,
files=serialized_request_body.files,
headers=headers,
timeout=timeout,
timeout=timeout if timeout is not None else httpx.USE_CLIENT_DEFAULT,
)
def do_request(
self,
hook_ctx,
request,
error_status_codes,
stream=False,
hook_ctx: HookContext,
request: httpx.Request,
is_error_status_code: Callable[[int], bool],
stream: bool = False,
retry_config: Optional[Tuple[RetryConfig, List[str]]] = None,
) -> httpx.Response:
client = self.sdk_configuration.client
@@ -240,6 +253,8 @@ class BaseSDK:
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,
@@ -270,21 +285,6 @@ class BaseSDK:
"<streaming response>" if stream else http_res.text,
)
if utils.match_status_codes(error_status_codes, http_res.status_code):
result, err = hooks.after_error(
AfterErrorContext(hook_ctx), http_res, None
)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
return http_res
if retry_config is not None:
@@ -292,17 +292,29 @@ class BaseSDK:
else:
http_res = do()
if not utils.match_status_codes(error_status_codes, http_res.status_code):
if is_error_status_code(http_res.status_code):
result, err = hooks.after_error(AfterErrorContext(hook_ctx), http_res, None)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
else:
http_res = hooks.after_success(AfterSuccessContext(hook_ctx), http_res)
return http_res
async def do_request_async(
self,
hook_ctx,
request,
error_status_codes,
stream=False,
hook_ctx: HookContext,
request: httpx.Request,
is_error_status_code: Callable[[int], bool],
stream: bool = False,
retry_config: Optional[Tuple[RetryConfig, List[str]]] = None,
) -> httpx.Response:
client = self.sdk_configuration.async_client
@@ -313,7 +325,12 @@ class BaseSDK:
async def do():
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
req = await run_sync_in_thread(
hooks.before_request, BeforeRequestContext(hook_ctx), request
)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,
@@ -327,7 +344,10 @@ class BaseSDK:
http_res = await client.send(req, stream=stream)
except Exception as e:
_, e = hooks.after_error(AfterErrorContext(hook_ctx), None, e)
_, e = await run_sync_in_thread(
hooks.after_error, AfterErrorContext(hook_ctx), None, e
)
if e is not None:
logger.debug("Request Exception", exc_info=True)
raise e
@@ -344,21 +364,6 @@ class BaseSDK:
"<streaming response>" if stream else http_res.text,
)
if utils.match_status_codes(error_status_codes, http_res.status_code):
result, err = hooks.after_error(
AfterErrorContext(hook_ctx), http_res, None
)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
return http_res
if retry_config is not None:
@@ -368,7 +373,24 @@ class BaseSDK:
else:
http_res = await do()
if not utils.match_status_codes(error_status_codes, http_res.status_code):
http_res = hooks.after_success(AfterSuccessContext(hook_ctx), http_res)
if is_error_status_code(http_res.status_code):
result, err = await run_sync_in_thread(
hooks.after_error, AfterErrorContext(hook_ctx), http_res, None
)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
else:
http_res = await run_sync_in_thread(
hooks.after_success, AfterSuccessContext(hook_ctx), http_res
)
return http_res
+6 -2
View File
@@ -113,9 +113,11 @@ class Benchmarks(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Benchmarks"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -258,9 +260,11 @@ class Benchmarks(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Benchmarks"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+23 -15
View File
@@ -6,7 +6,7 @@ from openrouter._hooks import HookContext
from openrouter.types import OptionalNullable, UNSET
from openrouter.utils import get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, List, Mapping, Optional, Union
from typing import Any, Iterable, List, Mapping, Optional, Union
class BetaAnalytics(BaseSDK):
@@ -98,9 +98,11 @@ class BetaAnalytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["beta.Analytics"],
extensions=None,
),
request=req,
error_status_codes=["401", "403", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -223,9 +225,11 @@ class BetaAnalytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["beta.Analytics"],
extensions=None,
),
request=req,
error_status_codes=["401", "403", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -265,13 +269,13 @@ class BetaAnalytics(BaseSDK):
def query_analytics(
self,
*,
metrics: List[str],
metrics: Iterable[str],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
dimensions: Optional[List[str]] = None,
dimensions: Optional[Iterable[str]] = None,
filters: Optional[
Union[List[operations.Filter], List[operations.FilterTypedDict]]
Union[Iterable[operations.Filter], Iterable[operations.FilterTypedDict]]
] = None,
granularity: Optional[str] = None,
group_limit: Optional[int] = None,
@@ -326,14 +330,14 @@ class BetaAnalytics(BaseSDK):
x_open_router_title=x_open_router_title,
x_open_router_categories=x_open_router_categories,
request_body=operations.QueryAnalyticsRequestBody(
dimensions=dimensions,
dimensions=utils.unmarshal(dimensions, Optional[List[str]]),
filters=utils.get_pydantic_model(
filters, Optional[List[operations.Filter]]
),
granularity=granularity,
group_limit=group_limit,
limit=limit,
metrics=metrics,
metrics=utils.unmarshal(metrics, List[str]),
order_by=utils.get_pydantic_model(
order_by, Optional[operations.OrderBy]
),
@@ -393,9 +397,11 @@ class BetaAnalytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["beta.Analytics"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "408", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -443,13 +449,13 @@ class BetaAnalytics(BaseSDK):
async def query_analytics_async(
self,
*,
metrics: List[str],
metrics: Iterable[str],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
dimensions: Optional[List[str]] = None,
dimensions: Optional[Iterable[str]] = None,
filters: Optional[
Union[List[operations.Filter], List[operations.FilterTypedDict]]
Union[Iterable[operations.Filter], Iterable[operations.FilterTypedDict]]
] = None,
granularity: Optional[str] = None,
group_limit: Optional[int] = None,
@@ -504,14 +510,14 @@ class BetaAnalytics(BaseSDK):
x_open_router_title=x_open_router_title,
x_open_router_categories=x_open_router_categories,
request_body=operations.QueryAnalyticsRequestBody(
dimensions=dimensions,
dimensions=utils.unmarshal(dimensions, Optional[List[str]]),
filters=utils.get_pydantic_model(
filters, Optional[List[operations.Filter]]
),
granularity=granularity,
group_limit=group_limit,
limit=limit,
metrics=metrics,
metrics=utils.unmarshal(metrics, List[str]),
order_by=utils.get_pydantic_model(
order_by, Optional[operations.OrderBy]
),
@@ -571,9 +577,11 @@ class BetaAnalytics(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["beta.Analytics"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "408", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+75 -33
View File
@@ -7,7 +7,7 @@ from openrouter._hooks import HookContext
from openrouter.types import OptionalNullable, UNSET
from openrouter.utils import get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union
from typing import Any, Awaitable, Dict, Iterable, List, Mapping, Optional, Union
class Byok(BaseSDK):
@@ -111,24 +111,26 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
def next_func() -> Optional[operations.ListBYOKKeysResponse]:
body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
offset = request.offset if not request.offset is None else 0
offset = request.offset if isinstance(request.offset, int) else 0
if not http_res.text:
return None
results = JSONPath("$.data").parse(body)
if len(results) == 0 or len(results[0]) == 0:
return None
limit = request.limit if not request.limit is None else 0
if len(results[0]) < limit:
limit_ = request.limit if isinstance(request.limit, int) else 0
if len(results[0]) < limit_:
return None
next_offset = offset + len(results[0])
@@ -141,6 +143,9 @@ class Byok(BaseSDK):
workspace_id=workspace_id,
provider=provider,
retries=retries,
server_url=server_url,
timeout_ms=timeout_ms,
http_headers=http_headers,
)
response_data: Any = None
@@ -272,9 +277,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -284,15 +291,15 @@ class Byok(BaseSDK):
async def empty_result():
return None
offset = request.offset if not request.offset is None else 0
offset = request.offset if isinstance(request.offset, int) else 0
if not http_res.text:
return empty_result()
results = JSONPath("$.data").parse(body)
if len(results) == 0 or len(results[0]) == 0:
return empty_result()
limit = request.limit if not request.limit is None else 0
if len(results[0]) < limit:
limit_ = request.limit if isinstance(request.limit, int) else 0
if len(results[0]) < limit_:
return empty_result()
next_offset = offset + len(results[0])
@@ -305,6 +312,9 @@ class Byok(BaseSDK):
workspace_id=workspace_id,
provider=provider,
retries=retries,
server_url=server_url,
timeout_ms=timeout_ms,
http_headers=http_headers,
)
response_data: Any = None
@@ -346,8 +356,8 @@ class Byok(BaseSDK):
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
allowed_models: OptionalNullable[List[str]] = UNSET,
allowed_user_ids: OptionalNullable[List[str]] = UNSET,
allowed_models: OptionalNullable[Iterable[str]] = UNSET,
allowed_user_ids: OptionalNullable[Iterable[str]] = UNSET,
disabled: Optional[bool] = None,
is_fallback: Optional[bool] = None,
name: OptionalNullable[str] = UNSET,
@@ -396,8 +406,12 @@ class Byok(BaseSDK):
x_open_router_title=x_open_router_title,
x_open_router_categories=x_open_router_categories,
create_byok_key_request=components.CreateBYOKKeyRequest(
allowed_models=allowed_models,
allowed_user_ids=allowed_user_ids,
allowed_models=utils.unmarshal(
allowed_models, OptionalNullable[List[str]]
),
allowed_user_ids=utils.unmarshal(
allowed_user_ids, OptionalNullable[List[str]]
),
disabled=disabled,
is_fallback=is_fallback,
key=key,
@@ -457,9 +471,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -507,8 +523,8 @@ class Byok(BaseSDK):
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
allowed_models: OptionalNullable[List[str]] = UNSET,
allowed_user_ids: OptionalNullable[List[str]] = UNSET,
allowed_models: OptionalNullable[Iterable[str]] = UNSET,
allowed_user_ids: OptionalNullable[Iterable[str]] = UNSET,
disabled: Optional[bool] = None,
is_fallback: Optional[bool] = None,
name: OptionalNullable[str] = UNSET,
@@ -557,8 +573,12 @@ class Byok(BaseSDK):
x_open_router_title=x_open_router_title,
x_open_router_categories=x_open_router_categories,
create_byok_key_request=components.CreateBYOKKeyRequest(
allowed_models=allowed_models,
allowed_user_ids=allowed_user_ids,
allowed_models=utils.unmarshal(
allowed_models, OptionalNullable[List[str]]
),
allowed_user_ids=utils.unmarshal(
allowed_user_ids, OptionalNullable[List[str]]
),
disabled=disabled,
is_fallback=is_fallback,
key=key,
@@ -618,9 +638,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "403", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -749,9 +771,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -875,9 +899,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1001,9 +1027,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1127,9 +1155,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1171,8 +1201,8 @@ class Byok(BaseSDK):
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
allowed_models: OptionalNullable[List[str]] = UNSET,
allowed_user_ids: OptionalNullable[List[str]] = UNSET,
allowed_models: OptionalNullable[Iterable[str]] = UNSET,
allowed_user_ids: OptionalNullable[Iterable[str]] = UNSET,
disabled: Optional[bool] = None,
is_fallback: Optional[bool] = None,
key: Optional[str] = None,
@@ -1221,8 +1251,12 @@ class Byok(BaseSDK):
x_open_router_categories=x_open_router_categories,
id=id,
update_byok_key_request=components.UpdateBYOKKeyRequest(
allowed_models=allowed_models,
allowed_user_ids=allowed_user_ids,
allowed_models=utils.unmarshal(
allowed_models, OptionalNullable[List[str]]
),
allowed_user_ids=utils.unmarshal(
allowed_user_ids, OptionalNullable[List[str]]
),
disabled=disabled,
is_fallback=is_fallback,
key=key,
@@ -1280,9 +1314,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -1329,8 +1365,8 @@ class Byok(BaseSDK):
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
allowed_models: OptionalNullable[List[str]] = UNSET,
allowed_user_ids: OptionalNullable[List[str]] = UNSET,
allowed_models: OptionalNullable[Iterable[str]] = UNSET,
allowed_user_ids: OptionalNullable[Iterable[str]] = UNSET,
disabled: Optional[bool] = None,
is_fallback: Optional[bool] = None,
key: Optional[str] = None,
@@ -1379,8 +1415,12 @@ class Byok(BaseSDK):
x_open_router_categories=x_open_router_categories,
id=id,
update_byok_key_request=components.UpdateBYOKKeyRequest(
allowed_models=allowed_models,
allowed_user_ids=allowed_user_ids,
allowed_models=utils.unmarshal(
allowed_models, OptionalNullable[List[str]]
),
allowed_user_ids=utils.unmarshal(
allowed_user_ids, OptionalNullable[List[str]]
),
disabled=disabled,
is_fallback=is_fallback,
key=key,
@@ -1438,9 +1478,11 @@ class Byok(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["BYOK"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "404", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+467 -151
View File
@@ -1,18 +1,22 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .basesdk import BaseSDK
from enum import Enum
from openrouter import components, errors, operations, utils
from openrouter._hooks import HookContext
from openrouter.types import OptionalNullable, UNSET
from openrouter.utils import eventstreaming, get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Dict, List, Literal, Mapping, Optional, Union, overload
class SendAcceptEnum(str, Enum):
APPLICATION_JSON = "application/json"
TEXT_EVENT_STREAM = "text/event-stream"
from typing import (
Any,
Dict,
Iterable,
List,
Literal,
Mapping,
Optional,
Union,
overload,
)
class Chat(BaseSDK):
@@ -21,7 +25,8 @@ class Chat(BaseSDK):
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -39,24 +44,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -86,8 +91,8 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Union[Literal[False], None] = None,
@@ -100,8 +105,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -170,7 +175,6 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
@@ -179,7 +183,8 @@ class Chat(BaseSDK):
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -197,24 +202,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -244,8 +249,8 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Literal[True],
@@ -258,8 +263,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -328,15 +333,16 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
@overload
def send(
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -354,24 +360,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -401,11 +407,11 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Optional[bool] = False,
stream: bool,
stream_options: OptionalNullable[
Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
] = UNSET,
@@ -415,8 +421,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -431,7 +437,168 @@ class Chat(BaseSDK):
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> operations.SendChatCompletionRequestResponse:
) -> Union[
components.ChatResult, eventstreaming.EventStream[components.ChatStreamChunk]
]:
r"""Create a chat completion
Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
:param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
:param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
:param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
:param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
:param debug: Debug options for inspecting request transformations (streaming only)
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
:param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
:param model: Model to use for completion
:param models: Models to use for completion
:param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
:param plugins: Plugins you want to enable for this request, including their settings.
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param reasoning: Configuration options for reasoning models
:param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
:param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param service_tier: The service tier to use for processing this request.
:param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
:param stop: Stop sequences (up to 4)
:param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
:param stream: Enable streaming response
:param stream_options: Streaming configuration options
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
:param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
:param top_logprobs: Number of top log probabilities to return (0-20)
:param top_p: Nucleus sampling parameter (0-1)
:param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
:param user: Unique user identifier
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
def send(
self,
*,
messages: Union[
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
x_open_router_metadata: Optional[components.MetadataLevel] = None,
cache_control: Optional[
Union[
components.AnthropicCacheControlDirective,
components.AnthropicCacheControlDirectiveTypedDict,
]
] = None,
debug: Optional[
Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
provider: OptionalNullable[
Union[
components.ProviderPreferences, components.ProviderPreferencesTypedDict
]
] = UNSET,
reasoning: Optional[
Union[
components.ChatRequestReasoning,
components.ChatRequestReasoningTypedDict,
]
] = None,
reasoning_effort: OptionalNullable[
components.ChatRequestReasoningEffort
] = UNSET,
repetition_penalty: OptionalNullable[float] = UNSET,
response_format: Optional[
Union[components.ResponseFormat, components.ResponseFormatTypedDict]
] = None,
seed: OptionalNullable[int] = UNSET,
service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
session_id: Optional[str] = None,
stop: OptionalNullable[
Union[components.Stop, components.StopTypedDict]
] = UNSET,
stop_server_tools_when: Optional[
Union[
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Optional[bool] = False,
stream_options: OptionalNullable[
Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
] = UNSET,
temperature: OptionalNullable[float] = UNSET,
tool_choice: Optional[
Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
] = None,
tools: Optional[
Union[
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
top_k: OptionalNullable[int] = UNSET,
top_logprobs: OptionalNullable[int] = UNSET,
top_p: OptionalNullable[float] = UNSET,
trace: Optional[
Union[components.TraceConfig, components.TraceConfigTypedDict]
] = None,
user: Optional[str] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> Union[
components.ChatResult, eventstreaming.EventStream[components.ChatStreamChunk]
]:
r"""Create a chat completion
Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.
@@ -485,7 +652,6 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
@@ -511,19 +677,25 @@ class Chat(BaseSDK):
debug, Optional[components.ChatDebugOptions]
),
frequency_penalty=frequency_penalty,
image_config=image_config,
logit_bias=logit_bias,
image_config=utils.unmarshal(
image_config, Optional[Dict[str, components.ImageConfig]]
),
logit_bias=utils.unmarshal(
logit_bias, OptionalNullable[Dict[str, float]]
),
logprobs=logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
messages=utils.get_pydantic_model(
messages, List[components.ChatMessages]
),
metadata=metadata,
metadata=utils.unmarshal(metadata, Optional[Dict[str, str]]),
min_p=min_p,
modalities=modalities,
modalities=utils.unmarshal(
modalities, Optional[List[components.Modality]]
),
model=model,
models=models,
models=utils.unmarshal(models, Optional[List[str]]),
parallel_tool_calls=parallel_tool_calls,
plugins=utils.get_pydantic_model(
plugins, Optional[List[components.ChatRequestPlugin]]
@@ -543,7 +715,7 @@ class Chat(BaseSDK):
seed=seed,
service_tier=service_tier,
session_id=session_id,
stop=stop,
stop=utils.unmarshal(stop, OptionalNullable[components.Stop]),
stop_server_tools_when=utils.get_pydantic_model(
stop_server_tools_when,
Optional[List[components.StopServerToolsWhenCondition]],
@@ -578,7 +750,9 @@ class Chat(BaseSDK):
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="text/event-stream" if stream else "application/json",
accept_header_value="text/event-stream"
if stream is True
else "application/json",
http_headers=http_headers,
_globals=operations.SendChatCompletionRequestGlobals(
http_referer=self.sdk_configuration.globals.http_referer,
@@ -614,27 +788,12 @@ class Chat(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Chat"],
extensions=None,
),
request=req,
error_status_codes=[
"400",
"401",
"402",
"403",
"404",
"408",
"413",
"422",
"429",
"4XX",
"500",
"502",
"503",
"524",
"529",
"5XX",
],
stream=True,
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
stream=stream is True,
retry_config=retry_config,
)
@@ -647,8 +806,8 @@ class Chat(BaseSDK):
if utils.match_response(http_res, "200", "text/event-stream"):
return eventstreaming.EventStream(
http_res,
lambda raw: utils.unmarshal_json(
raw, components.ChatStreamingResponse
lambda raw: unmarshal_json_response(
components.ChatStreamingResponse, http_res, raw
).data,
sentinel="[DONE]",
client_ref=self,
@@ -778,7 +937,8 @@ class Chat(BaseSDK):
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -796,24 +956,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -843,8 +1003,8 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Union[Literal[False], None] = None,
@@ -857,8 +1017,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -927,7 +1087,6 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
@@ -936,7 +1095,8 @@ class Chat(BaseSDK):
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -954,24 +1114,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -1001,8 +1161,8 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Literal[True],
@@ -1015,8 +1175,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -1085,15 +1245,16 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
@overload
async def send_async(
self,
*,
messages: Union[
List[components.ChatMessages], List[components.ChatMessagesTypedDict]
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
@@ -1111,24 +1272,24 @@ class Chat(BaseSDK):
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Dict[str, components.ImageConfig],
Dict[str, components.ImageConfigTypedDict],
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Dict[str, str]] = None,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[List[components.Modality]] = None,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[List[str]] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
List[components.ChatRequestPlugin],
List[components.ChatRequestPluginTypedDict],
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
@@ -1158,11 +1319,11 @@ class Chat(BaseSDK):
] = UNSET,
stop_server_tools_when: Optional[
Union[
List[components.StopServerToolsWhenCondition],
List[components.StopServerToolsWhenConditionTypedDict],
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Optional[bool] = False,
stream: bool,
stream_options: OptionalNullable[
Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
] = UNSET,
@@ -1172,8 +1333,8 @@ class Chat(BaseSDK):
] = None,
tools: Optional[
Union[
List[components.ChatFunctionTool],
List[components.ChatFunctionToolTypedDict],
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
@@ -1188,7 +1349,170 @@ class Chat(BaseSDK):
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> operations.SendChatCompletionRequestResponse:
) -> Union[
components.ChatResult,
eventstreaming.EventStreamAsync[components.ChatStreamChunk],
]:
r"""Create a chat completion
Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
:param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
:param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
:param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
:param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
:param debug: Debug options for inspecting request transformations (streaming only)
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
:param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
:param model: Model to use for completion
:param models: Models to use for completion
:param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
:param plugins: Plugins you want to enable for this request, including their settings.
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param reasoning: Configuration options for reasoning models
:param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
:param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param service_tier: The service tier to use for processing this request.
:param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
:param stop: Stop sequences (up to 4)
:param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
:param stream: Enable streaming response
:param stream_options: Streaming configuration options
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
:param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
:param top_logprobs: Number of top log probabilities to return (0-20)
:param top_p: Nucleus sampling parameter (0-1)
:param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
:param user: Unique user identifier
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
async def send_async(
self,
*,
messages: Union[
Iterable[components.ChatMessages],
Iterable[components.ChatMessagesTypedDict],
],
http_referer: Optional[str] = None,
x_open_router_title: Optional[str] = None,
x_open_router_categories: Optional[str] = None,
x_open_router_metadata: Optional[components.MetadataLevel] = None,
cache_control: Optional[
Union[
components.AnthropicCacheControlDirective,
components.AnthropicCacheControlDirectiveTypedDict,
]
] = None,
debug: Optional[
Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
image_config: Optional[
Union[
Mapping[str, components.ImageConfig],
Mapping[str, components.ImageConfigTypedDict],
]
] = None,
logit_bias: OptionalNullable[Mapping[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
max_completion_tokens: OptionalNullable[int] = UNSET,
max_tokens: OptionalNullable[int] = UNSET,
metadata: Optional[Mapping[str, str]] = None,
min_p: OptionalNullable[float] = UNSET,
modalities: Optional[Iterable[components.Modality]] = None,
model: Optional[str] = None,
models: Optional[Iterable[str]] = None,
parallel_tool_calls: OptionalNullable[bool] = UNSET,
plugins: Optional[
Union[
Iterable[components.ChatRequestPlugin],
Iterable[components.ChatRequestPluginTypedDict],
]
] = None,
presence_penalty: OptionalNullable[float] = UNSET,
provider: OptionalNullable[
Union[
components.ProviderPreferences, components.ProviderPreferencesTypedDict
]
] = UNSET,
reasoning: Optional[
Union[
components.ChatRequestReasoning,
components.ChatRequestReasoningTypedDict,
]
] = None,
reasoning_effort: OptionalNullable[
components.ChatRequestReasoningEffort
] = UNSET,
repetition_penalty: OptionalNullable[float] = UNSET,
response_format: Optional[
Union[components.ResponseFormat, components.ResponseFormatTypedDict]
] = None,
seed: OptionalNullable[int] = UNSET,
service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
session_id: Optional[str] = None,
stop: OptionalNullable[
Union[components.Stop, components.StopTypedDict]
] = UNSET,
stop_server_tools_when: Optional[
Union[
Iterable[components.StopServerToolsWhenCondition],
Iterable[components.StopServerToolsWhenConditionTypedDict],
]
] = None,
stream: Optional[bool] = False,
stream_options: OptionalNullable[
Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
] = UNSET,
temperature: OptionalNullable[float] = UNSET,
tool_choice: Optional[
Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
] = None,
tools: Optional[
Union[
Iterable[components.ChatFunctionTool],
Iterable[components.ChatFunctionToolTypedDict],
]
] = None,
top_a: OptionalNullable[float] = UNSET,
top_k: OptionalNullable[int] = UNSET,
top_logprobs: OptionalNullable[int] = UNSET,
top_p: OptionalNullable[float] = UNSET,
trace: Optional[
Union[components.TraceConfig, components.TraceConfigTypedDict]
] = None,
user: Optional[str] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> Union[
components.ChatResult,
eventstreaming.EventStreamAsync[components.ChatStreamChunk],
]:
r"""Create a chat completion
Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.
@@ -1242,7 +1566,6 @@ class Chat(BaseSDK):
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param accept_header_override: Override the default accept header for this method
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
@@ -1268,19 +1591,25 @@ class Chat(BaseSDK):
debug, Optional[components.ChatDebugOptions]
),
frequency_penalty=frequency_penalty,
image_config=image_config,
logit_bias=logit_bias,
image_config=utils.unmarshal(
image_config, Optional[Dict[str, components.ImageConfig]]
),
logit_bias=utils.unmarshal(
logit_bias, OptionalNullable[Dict[str, float]]
),
logprobs=logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
messages=utils.get_pydantic_model(
messages, List[components.ChatMessages]
),
metadata=metadata,
metadata=utils.unmarshal(metadata, Optional[Dict[str, str]]),
min_p=min_p,
modalities=modalities,
modalities=utils.unmarshal(
modalities, Optional[List[components.Modality]]
),
model=model,
models=models,
models=utils.unmarshal(models, Optional[List[str]]),
parallel_tool_calls=parallel_tool_calls,
plugins=utils.get_pydantic_model(
plugins, Optional[List[components.ChatRequestPlugin]]
@@ -1300,7 +1629,7 @@ class Chat(BaseSDK):
seed=seed,
service_tier=service_tier,
session_id=session_id,
stop=stop,
stop=utils.unmarshal(stop, OptionalNullable[components.Stop]),
stop_server_tools_when=utils.get_pydantic_model(
stop_server_tools_when,
Optional[List[components.StopServerToolsWhenCondition]],
@@ -1335,7 +1664,9 @@ class Chat(BaseSDK):
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="text/event-stream" if stream else "application/json",
accept_header_value="text/event-stream"
if stream is True
else "application/json",
http_headers=http_headers,
_globals=operations.SendChatCompletionRequestGlobals(
http_referer=self.sdk_configuration.globals.http_referer,
@@ -1371,27 +1702,12 @@ class Chat(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Chat"],
extensions=None,
),
request=req,
error_status_codes=[
"400",
"401",
"402",
"403",
"404",
"408",
"413",
"422",
"429",
"4XX",
"500",
"502",
"503",
"524",
"529",
"5XX",
],
stream=True,
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
stream=stream is True,
retry_config=retry_config,
)
@@ -1404,8 +1720,8 @@ class Chat(BaseSDK):
if utils.match_response(http_res, "200", "text/event-stream"):
return eventstreaming.EventStreamAsync(
http_res,
lambda raw: utils.unmarshal_json(
raw, components.ChatStreamingResponse
lambda raw: unmarshal_json_response(
components.ChatStreamingResponse, http_res, raw
).data,
sentinel="[DONE]",
client_ref=self,
+6 -2
View File
@@ -119,9 +119,11 @@ class Classifications(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Classifications"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
@@ -270,9 +272,11 @@ class Classifications(BaseSDK):
security_source=get_security_from_env(
self.sdk_configuration.security, components.Security
),
tags=["Classifications"],
extensions=None,
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
+84 -41
View File
@@ -1,9 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
import sys
from typing import Any, TYPE_CHECKING
from openrouter.utils.dynamic_imports import lazy_getattr, lazy_dir
if TYPE_CHECKING:
from .aabenchmarkentry import AABenchmarkEntry, AABenchmarkEntryTypedDict
@@ -204,6 +203,7 @@ if TYPE_CHECKING:
from .applypatchcalloperation import (
ApplyPatchCallOperation,
ApplyPatchCallOperationTypedDict,
UnknownApplyPatchCallOperation,
)
from .applypatchcalloperationdiffdeltaevent import (
ApplyPatchCallOperationDiffDeltaEvent,
@@ -289,6 +289,7 @@ if TYPE_CHECKING:
BaseInputsUnion1,
BaseInputsUnion1TypedDict,
BaseInputsUnionTypedDict,
UnknownBaseInputsContent1,
)
from .basereasoningconfig import BaseReasoningConfig, BaseReasoningConfigTypedDict
from .bashservertool import (
@@ -363,6 +364,7 @@ if TYPE_CHECKING:
from .capabilitydescriptor import (
CapabilityDescriptor,
CapabilityDescriptorTypedDict,
UnknownCapabilityDescriptor,
)
from .chatassistantimages import (
ChatAssistantImages,
@@ -406,7 +408,11 @@ if TYPE_CHECKING:
ChatContentImageType,
ChatContentImageTypedDict,
)
from .chatcontentitems import ChatContentItems, ChatContentItemsTypedDict
from .chatcontentitems import (
ChatContentItems,
ChatContentItemsTypedDict,
UnknownChatContentItems,
)
from .chatcontenttext import (
ChatContentText,
ChatContentTextType,
@@ -646,6 +652,7 @@ if TYPE_CHECKING:
ContentPartAddedEventPartTypedDict,
ContentPartAddedEventType,
ContentPartAddedEventTypedDict,
UnknownContentPartAddedEventPart,
)
from .contentpartaudio import (
AudioURL,
@@ -660,6 +667,7 @@ if TYPE_CHECKING:
ContentPartDoneEventPartTypedDict,
ContentPartDoneEventType,
ContentPartDoneEventTypedDict,
UnknownContentPartDoneEventPart,
)
from .contentpartimage import (
ContentPartImage,
@@ -747,6 +755,7 @@ if TYPE_CHECKING:
FormatTypeText,
FormatTypedDict,
Syntax,
UnknownFormat,
)
from .customtoolcallinputdeltaevent import (
CustomToolCallInputDeltaEvent,
@@ -898,7 +907,7 @@ if TYPE_CHECKING:
FormatJSONSchemaConfigType,
FormatJSONSchemaConfigTypedDict,
)
from .formats import Formats, FormatsTypedDict
from .formats import Formats, FormatsTypedDict, UnknownFormats
from .formattextconfig import (
FormatTextConfig,
FormatTextConfigType,
@@ -1186,6 +1195,7 @@ if TYPE_CHECKING:
ImageStreamingResponseData,
ImageStreamingResponseDataTypedDict,
ImageStreamingResponseTypedDict,
UnknownImageStreamingResponseData,
)
from .incompletedetails import IncompleteDetails, IncompleteDetailsTypedDict, Reason
from .inputaudio import (
@@ -1585,6 +1595,7 @@ if TYPE_CHECKING:
from .observabilitydestination import (
ObservabilityDestination,
ObservabilityDestinationTypedDict,
UnknownObservabilityDestination,
)
from .observabilityfilterrulesconfig import (
FieldT,
@@ -1705,6 +1716,7 @@ if TYPE_CHECKING:
OpenAIResponseCustomToolCallOutputOutput2TypedDict,
OpenAIResponseCustomToolCallOutputType,
OpenAIResponseCustomToolCallOutputTypedDict,
UnknownOpenAIResponseCustomToolCallOutputOutput1,
)
from .openairesponsefunctiontoolcall import (
OpenAIResponseFunctionToolCall,
@@ -1720,6 +1732,7 @@ if TYPE_CHECKING:
OpenAIResponseFunctionToolCallOutputStatus,
OpenAIResponseFunctionToolCallOutputType,
OpenAIResponseFunctionToolCallOutputTypedDict,
UnknownOpenAIResponseFunctionToolCallOutputOutput1,
)
from .openairesponseinputmessageitem import (
OpenAIResponseInputMessageItem,
@@ -1732,10 +1745,12 @@ if TYPE_CHECKING:
OpenAIResponseInputMessageItemRoleUser,
OpenAIResponseInputMessageItemType,
OpenAIResponseInputMessageItemTypedDict,
UnknownOpenAIResponseInputMessageItemContent,
)
from .openairesponsesannotation import (
OpenAIResponsesAnnotation,
OpenAIResponsesAnnotationTypedDict,
UnknownOpenAIResponsesAnnotation,
)
from .openairesponsesrefusalcontent import (
OpenAIResponsesRefusalContent,
@@ -1785,6 +1800,7 @@ if TYPE_CHECKING:
OpenResponsesResultToolUnionTypedDict,
OpenResponsesResultType,
OpenResponsesResultTypedDict,
UnknownOpenResponsesResultToolUnion,
)
from .openroutermetadata import OpenRouterMetadata, OpenRouterMetadataTypedDict
from .openrouterwebsearchservertool import (
@@ -1829,6 +1845,7 @@ if TYPE_CHECKING:
OutputLogsTypedDict,
TypeCodeInterpreterCall,
TypeLogs,
UnknownOutputCodeInterpreterCallItemOutputUnion,
)
from .outputcodeinterpreterservertoolitem import (
OutputCodeInterpreterServerToolItem,
@@ -1897,7 +1914,7 @@ if TYPE_CHECKING:
OutputItemImageGenerationCallType,
OutputItemImageGenerationCallTypedDict,
)
from .outputitems import OutputItems, OutputItemsTypedDict
from .outputitems import OutputItems, OutputItemsTypedDict, UnknownOutputItems
from .outputmcpservertoolitem import (
OutputMcpServerToolItem,
OutputMcpServerToolItemType,
@@ -1925,6 +1942,7 @@ if TYPE_CHECKING:
OutputMessageStatusUnionTypedDict,
OutputMessageType,
OutputMessageTypedDict,
UnknownOutputMessageContent,
)
from .outputmessageitem import (
OutputMessageItem,
@@ -1942,6 +1960,7 @@ if TYPE_CHECKING:
OutputMessageItemStatusUnionTypedDict,
OutputMessageItemType,
OutputMessageItemTypedDict,
UnknownOutputMessageItemContent,
)
from .outputmodality import OutputModality
from .outputmodalityenum import OutputModalityEnum
@@ -1981,6 +2000,7 @@ if TYPE_CHECKING:
OutputShellCallOutputItemTypedDict,
TypeExit,
TypeTimeout,
UnknownOutcome,
)
from .outputsubagentservertoolitem import (
OutputSubagentServerToolItem,
@@ -2018,6 +2038,7 @@ if TYPE_CHECKING:
TypeFindInPage,
TypeOpenPage,
TypeWebSearchCall,
UnknownAction,
)
from .outputwebsearchservertoolitem import (
OutputWebSearchServerToolItem,
@@ -2175,6 +2196,7 @@ if TYPE_CHECKING:
from .reasoningdetailunion import (
ReasoningDetailUnion,
ReasoningDetailUnionTypedDict,
UnknownReasoningDetailUnion,
)
from .reasoningdoneevent import (
ReasoningDoneEvent,
@@ -2366,7 +2388,7 @@ if TYPE_CHECKING:
Variables,
VariablesTypedDict,
)
from .streamevents import StreamEvents, StreamEventsTypedDict
from .streamevents import StreamEvents, StreamEventsTypedDict, UnknownStreamEvents
from .streameventsresponsecompleted import (
StreamEventsResponseCompleted,
StreamEventsResponseCompletedType,
@@ -2498,6 +2520,7 @@ if TYPE_CHECKING:
UnifiedBenchmarksResponseData,
UnifiedBenchmarksResponseDataTypedDict,
UnifiedBenchmarksResponseTypedDict,
UnknownUnifiedBenchmarksResponseData,
)
from .unprocessableentityresponseerrordata import (
UnprocessableEntityResponseErrorData,
@@ -4528,6 +4551,30 @@ __all__ = [
"UniqueInsight",
"UniqueInsightTypedDict",
"Unit",
"UnknownAction",
"UnknownApplyPatchCallOperation",
"UnknownBaseInputsContent1",
"UnknownCapabilityDescriptor",
"UnknownChatContentItems",
"UnknownContentPartAddedEventPart",
"UnknownContentPartDoneEventPart",
"UnknownFormat",
"UnknownFormats",
"UnknownImageStreamingResponseData",
"UnknownObservabilityDestination",
"UnknownOpenAIResponseCustomToolCallOutputOutput1",
"UnknownOpenAIResponseFunctionToolCallOutputOutput1",
"UnknownOpenAIResponseInputMessageItemContent",
"UnknownOpenAIResponsesAnnotation",
"UnknownOpenResponsesResultToolUnion",
"UnknownOutcome",
"UnknownOutputCodeInterpreterCallItemOutputUnion",
"UnknownOutputItems",
"UnknownOutputMessageContent",
"UnknownOutputMessageItemContent",
"UnknownReasoningDetailUnion",
"UnknownStreamEvents",
"UnknownUnifiedBenchmarksResponseData",
"UnprocessableEntityResponseErrorData",
"UnprocessableEntityResponseErrorDataTypedDict",
"UpdateBYOKKeyRequest",
@@ -4768,6 +4815,7 @@ _dynamic_imports: dict[str, str] = {
"ApplyPatchCallItemTypedDict": ".applypatchcallitem",
"ApplyPatchCallOperation": ".applypatchcalloperation",
"ApplyPatchCallOperationTypedDict": ".applypatchcalloperation",
"UnknownApplyPatchCallOperation": ".applypatchcalloperation",
"ApplyPatchCallOperationDiffDeltaEvent": ".applypatchcalloperationdiffdeltaevent",
"ApplyPatchCallOperationDiffDeltaEventType": ".applypatchcalloperationdiffdeltaevent",
"ApplyPatchCallOperationDiffDeltaEventTypedDict": ".applypatchcalloperationdiffdeltaevent",
@@ -4829,6 +4877,7 @@ _dynamic_imports: dict[str, str] = {
"BaseInputsUnion1": ".baseinputs_union",
"BaseInputsUnion1TypedDict": ".baseinputs_union",
"BaseInputsUnionTypedDict": ".baseinputs_union",
"UnknownBaseInputsContent1": ".baseinputs_union",
"BaseReasoningConfig": ".basereasoningconfig",
"BaseReasoningConfigTypedDict": ".basereasoningconfig",
"BashServerTool": ".bashservertool",
@@ -4871,6 +4920,7 @@ _dynamic_imports: dict[str, str] = {
"BYOKProviderSlug": ".byokproviderslug",
"CapabilityDescriptor": ".capabilitydescriptor",
"CapabilityDescriptorTypedDict": ".capabilitydescriptor",
"UnknownCapabilityDescriptor": ".capabilitydescriptor",
"ChatAssistantImages": ".chatassistantimages",
"ChatAssistantImagesImageURL": ".chatassistantimages",
"ChatAssistantImagesImageURLTypedDict": ".chatassistantimages",
@@ -4905,6 +4955,7 @@ _dynamic_imports: dict[str, str] = {
"ChatContentImageTypedDict": ".chatcontentimage",
"ChatContentItems": ".chatcontentitems",
"ChatContentItemsTypedDict": ".chatcontentitems",
"UnknownChatContentItems": ".chatcontentitems",
"ChatContentText": ".chatcontenttext",
"ChatContentTextType": ".chatcontenttext",
"ChatContentTextTypedDict": ".chatcontenttext",
@@ -5079,6 +5130,7 @@ _dynamic_imports: dict[str, str] = {
"ContentPartAddedEventPartTypedDict": ".contentpartaddedevent",
"ContentPartAddedEventType": ".contentpartaddedevent",
"ContentPartAddedEventTypedDict": ".contentpartaddedevent",
"UnknownContentPartAddedEventPart": ".contentpartaddedevent",
"AudioURL": ".contentpartaudio",
"AudioURLTypedDict": ".contentpartaudio",
"ContentPartAudio": ".contentpartaudio",
@@ -5089,6 +5141,7 @@ _dynamic_imports: dict[str, str] = {
"ContentPartDoneEventPartTypedDict": ".contentpartdoneevent",
"ContentPartDoneEventType": ".contentpartdoneevent",
"ContentPartDoneEventTypedDict": ".contentpartdoneevent",
"UnknownContentPartDoneEventPart": ".contentpartdoneevent",
"ContentPartImage": ".contentpartimage",
"ContentPartImageImageURL": ".contentpartimage",
"ContentPartImageImageURLTypedDict": ".contentpartimage",
@@ -5145,6 +5198,7 @@ _dynamic_imports: dict[str, str] = {
"FormatTypeText": ".customtool",
"FormatTypedDict": ".customtool",
"Syntax": ".customtool",
"UnknownFormat": ".customtool",
"CustomToolCallInputDeltaEvent": ".customtoolcallinputdeltaevent",
"CustomToolCallInputDeltaEventType": ".customtoolcallinputdeltaevent",
"CustomToolCallInputDeltaEventTypedDict": ".customtoolcallinputdeltaevent",
@@ -5268,6 +5322,7 @@ _dynamic_imports: dict[str, str] = {
"FormatJSONSchemaConfigTypedDict": ".formatjsonschemaconfig",
"Formats": ".formats",
"FormatsTypedDict": ".formats",
"UnknownFormats": ".formats",
"FormatTextConfig": ".formattextconfig",
"FormatTextConfigType": ".formattextconfig",
"FormatTextConfigTypedDict": ".formattextconfig",
@@ -5473,6 +5528,7 @@ _dynamic_imports: dict[str, str] = {
"ImageStreamingResponseData": ".imagestreamingresponse",
"ImageStreamingResponseDataTypedDict": ".imagestreamingresponse",
"ImageStreamingResponseTypedDict": ".imagestreamingresponse",
"UnknownImageStreamingResponseData": ".imagestreamingresponse",
"IncompleteDetails": ".incompletedetails",
"IncompleteDetailsTypedDict": ".incompletedetails",
"Reason": ".incompletedetails",
@@ -5820,6 +5876,7 @@ _dynamic_imports: dict[str, str] = {
"ObservabilityDatadogDestinationTypedDict": ".observabilitydatadogdestination",
"ObservabilityDestination": ".observabilitydestination",
"ObservabilityDestinationTypedDict": ".observabilitydestination",
"UnknownObservabilityDestination": ".observabilitydestination",
"FieldT": ".observabilityfilterrulesconfig",
"Group": ".observabilityfilterrulesconfig",
"GroupTypedDict": ".observabilityfilterrulesconfig",
@@ -5908,6 +5965,7 @@ _dynamic_imports: dict[str, str] = {
"OpenAIResponseCustomToolCallOutputOutput2TypedDict": ".openairesponsecustomtoolcalloutput",
"OpenAIResponseCustomToolCallOutputType": ".openairesponsecustomtoolcalloutput",
"OpenAIResponseCustomToolCallOutputTypedDict": ".openairesponsecustomtoolcalloutput",
"UnknownOpenAIResponseCustomToolCallOutputOutput1": ".openairesponsecustomtoolcalloutput",
"OpenAIResponseFunctionToolCall": ".openairesponsefunctiontoolcall",
"OpenAIResponseFunctionToolCallType": ".openairesponsefunctiontoolcall",
"OpenAIResponseFunctionToolCallTypedDict": ".openairesponsefunctiontoolcall",
@@ -5919,6 +5977,7 @@ _dynamic_imports: dict[str, str] = {
"OpenAIResponseFunctionToolCallOutputStatus": ".openairesponsefunctiontoolcalloutput",
"OpenAIResponseFunctionToolCallOutputType": ".openairesponsefunctiontoolcalloutput",
"OpenAIResponseFunctionToolCallOutputTypedDict": ".openairesponsefunctiontoolcalloutput",
"UnknownOpenAIResponseFunctionToolCallOutputOutput1": ".openairesponsefunctiontoolcalloutput",
"OpenAIResponseInputMessageItem": ".openairesponseinputmessageitem",
"OpenAIResponseInputMessageItemContent": ".openairesponseinputmessageitem",
"OpenAIResponseInputMessageItemContentTypedDict": ".openairesponseinputmessageitem",
@@ -5929,8 +5988,10 @@ _dynamic_imports: dict[str, str] = {
"OpenAIResponseInputMessageItemRoleUser": ".openairesponseinputmessageitem",
"OpenAIResponseInputMessageItemType": ".openairesponseinputmessageitem",
"OpenAIResponseInputMessageItemTypedDict": ".openairesponseinputmessageitem",
"UnknownOpenAIResponseInputMessageItemContent": ".openairesponseinputmessageitem",
"OpenAIResponsesAnnotation": ".openairesponsesannotation",
"OpenAIResponsesAnnotationTypedDict": ".openairesponsesannotation",
"UnknownOpenAIResponsesAnnotation": ".openairesponsesannotation",
"OpenAIResponsesRefusalContent": ".openairesponsesrefusalcontent",
"OpenAIResponsesRefusalContentType": ".openairesponsesrefusalcontent",
"OpenAIResponsesRefusalContentTypedDict": ".openairesponsesrefusalcontent",
@@ -5970,6 +6031,7 @@ _dynamic_imports: dict[str, str] = {
"OpenResponsesResultToolUnionTypedDict": ".openresponsesresult",
"OpenResponsesResultType": ".openresponsesresult",
"OpenResponsesResultTypedDict": ".openresponsesresult",
"UnknownOpenResponsesResultToolUnion": ".openresponsesresult",
"OpenRouterMetadata": ".openroutermetadata",
"OpenRouterMetadataTypedDict": ".openroutermetadata",
"OpenRouterWebSearchServerTool": ".openrouterwebsearchservertool",
@@ -6001,6 +6063,7 @@ _dynamic_imports: dict[str, str] = {
"OutputLogsTypedDict": ".outputcodeinterpretercallitem",
"TypeCodeInterpreterCall": ".outputcodeinterpretercallitem",
"TypeLogs": ".outputcodeinterpretercallitem",
"UnknownOutputCodeInterpreterCallItemOutputUnion": ".outputcodeinterpretercallitem",
"OutputCodeInterpreterServerToolItem": ".outputcodeinterpreterservertoolitem",
"OutputCodeInterpreterServerToolItemType": ".outputcodeinterpreterservertoolitem",
"OutputCodeInterpreterServerToolItemTypedDict": ".outputcodeinterpreterservertoolitem",
@@ -6048,6 +6111,7 @@ _dynamic_imports: dict[str, str] = {
"OutputItemImageGenerationCallTypedDict": ".outputitemimagegenerationcall",
"OutputItems": ".outputitems",
"OutputItemsTypedDict": ".outputitems",
"UnknownOutputItems": ".outputitems",
"OutputMcpServerToolItem": ".outputmcpservertoolitem",
"OutputMcpServerToolItemType": ".outputmcpservertoolitem",
"OutputMcpServerToolItemTypedDict": ".outputmcpservertoolitem",
@@ -6070,6 +6134,7 @@ _dynamic_imports: dict[str, str] = {
"OutputMessageStatusUnionTypedDict": ".outputmessage",
"OutputMessageType": ".outputmessage",
"OutputMessageTypedDict": ".outputmessage",
"UnknownOutputMessageContent": ".outputmessage",
"OutputMessageItem": ".outputmessageitem",
"OutputMessageItemContent": ".outputmessageitem",
"OutputMessageItemContentTypedDict": ".outputmessageitem",
@@ -6085,6 +6150,7 @@ _dynamic_imports: dict[str, str] = {
"OutputMessageItemStatusUnionTypedDict": ".outputmessageitem",
"OutputMessageItemType": ".outputmessageitem",
"OutputMessageItemTypedDict": ".outputmessageitem",
"UnknownOutputMessageItemContent": ".outputmessageitem",
"OutputModality": ".outputmodality",
"OutputModalityEnum": ".outputmodalityenum",
"OutputReasoningItem": ".outputreasoningitem",
@@ -6116,6 +6182,7 @@ _dynamic_imports: dict[str, str] = {
"OutputShellCallOutputItemTypedDict": ".outputshellcalloutputitem",
"TypeExit": ".outputshellcalloutputitem",
"TypeTimeout": ".outputshellcalloutputitem",
"UnknownOutcome": ".outputshellcalloutputitem",
"OutputSubagentServerToolItem": ".outputsubagentservertoolitem",
"OutputSubagentServerToolItemType": ".outputsubagentservertoolitem",
"OutputSubagentServerToolItemTypedDict": ".outputsubagentservertoolitem",
@@ -6143,6 +6210,7 @@ _dynamic_imports: dict[str, str] = {
"TypeFindInPage": ".outputwebsearchcallitem",
"TypeOpenPage": ".outputwebsearchcallitem",
"TypeWebSearchCall": ".outputwebsearchcallitem",
"UnknownAction": ".outputwebsearchcallitem",
"OutputWebSearchServerToolItem": ".outputwebsearchservertoolitem",
"OutputWebSearchServerToolItemAction": ".outputwebsearchservertoolitem",
"OutputWebSearchServerToolItemActionTypedDict": ".outputwebsearchservertoolitem",
@@ -6258,6 +6326,7 @@ _dynamic_imports: dict[str, str] = {
"ReasoningDetailTextTypedDict": ".reasoningdetailtext",
"ReasoningDetailUnion": ".reasoningdetailunion",
"ReasoningDetailUnionTypedDict": ".reasoningdetailunion",
"UnknownReasoningDetailUnion": ".reasoningdetailunion",
"ReasoningDoneEvent": ".reasoningdoneevent",
"ReasoningDoneEventType": ".reasoningdoneevent",
"ReasoningDoneEventTypedDict": ".reasoningdoneevent",
@@ -6389,6 +6458,7 @@ _dynamic_imports: dict[str, str] = {
"VariablesTypedDict": ".storedprompttemplate",
"StreamEvents": ".streamevents",
"StreamEventsTypedDict": ".streamevents",
"UnknownStreamEvents": ".streamevents",
"StreamEventsResponseCompleted": ".streameventsresponsecompleted",
"StreamEventsResponseCompletedType": ".streameventsresponsecompleted",
"StreamEventsResponseCompletedTypedDict": ".streameventsresponsecompleted",
@@ -6482,6 +6552,7 @@ _dynamic_imports: dict[str, str] = {
"UnifiedBenchmarksResponseData": ".unifiedbenchmarksresponse",
"UnifiedBenchmarksResponseDataTypedDict": ".unifiedbenchmarksresponse",
"UnifiedBenchmarksResponseTypedDict": ".unifiedbenchmarksresponse",
"UnknownUnifiedBenchmarksResponseData": ".unifiedbenchmarksresponse",
"UnprocessableEntityResponseErrorData": ".unprocessableentityresponseerrordata",
"UnprocessableEntityResponseErrorDataTypedDict": ".unprocessableentityresponseerrordata",
"UpdateBYOKKeyRequest": ".updatebyokkeyrequest",
@@ -6596,39 +6667,11 @@ _dynamic_imports: dict[str, str] = {
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = dynamic_import(module_name)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __getattr__(attr_name: str) -> Any:
return lazy_getattr(
attr_name, package=__package__, dynamic_imports=_dynamic_imports
)
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
return lazy_dir(dynamic_imports=_dynamic_imports)
+2 -18
View File
@@ -31,30 +31,14 @@ class AABenchmarkEntry(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["agentic_index", "coding_index", "intelligence_index"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -64,3 +64,9 @@ class ActivityItem(BaseModel):
usage: float
r"""Total cost in USD (OpenRouter credits spent)"""
try:
ActivityItem.model_rebuild()
except NameError:
pass
+21 -2
View File
@@ -1,9 +1,9 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, Nullable
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
import pydantic
from pydantic import ConfigDict
from pydantic import ConfigDict, model_serializer
from typing import Any, Dict, Optional
from typing_extensions import NotRequired, TypedDict
@@ -34,3 +34,22 @@ class AdvisorNestedTool(BaseModel):
@additional_properties.setter
def additional_properties(self, value):
self.__pydantic_extra__ = value # pyright: ignore[reportIncompatibleVariableOverride]
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
serialized.pop(k, serialized.pop(n, None))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
for k, v in serialized.items():
m[k] = v
return m
+20 -7
View File
@@ -1,11 +1,10 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
from pydantic import model_serializer
from typing import Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
AdvisorReasoningEffort = Union[
@@ -35,10 +34,24 @@ class AdvisorReasoningTypedDict(TypedDict):
class AdvisorReasoning(BaseModel):
r"""Reasoning configuration forwarded to the advisor call. Use this to control reasoning effort and token budget for models that support extended thinking."""
effort: Annotated[
Optional[AdvisorReasoningEffort], PlainValidator(validate_open_enum(False))
] = None
effort: Optional[AdvisorReasoningEffort] = None
r"""Reasoning effort level for the advisor call."""
max_tokens: Optional[int] = None
r"""Maximum number of reasoning tokens the advisor may use."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["effort", "max_tokens"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -5,7 +5,8 @@ from .advisorservertoolconfig import (
AdvisorServerToolConfig,
AdvisorServerToolConfigTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -28,3 +29,19 @@ class AdvisorServerToolOpenRouter(BaseModel):
parameters: Optional[AdvisorServerToolConfig] = None
r"""Configuration for one openrouter:advisor server tool entry."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -3,7 +3,8 @@
from __future__ import annotations
from .advisornestedtool import AdvisorNestedTool, AdvisorNestedToolTypedDict
from .advisorreasoning import AdvisorReasoning, AdvisorReasoningTypedDict
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import NotRequired, TypedDict
@@ -65,3 +66,32 @@ class AdvisorServerToolConfig(BaseModel):
tools: Optional[List[AdvisorNestedTool]] = None
r"""Tools the advisor sub-agent may use while forming its advice. The advisor runs as an agentic sub-agent over these tools, then returns its text. Only OpenRouter server tools are supported — function tools are rejected — and the list must not include the advisor tool itself."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
[
"forward_transcript",
"instructions",
"max_completion_tokens",
"max_tool_calls",
"model",
"name",
"reasoning",
"stream",
"temperature",
"tools",
]
)
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -47,36 +47,33 @@ class AnthropicAdvisorMessageUsageIteration(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
nullable_fields = ["cache_creation"]
null_default_fields = []
optional_fields = set(
[
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
)
nullable_fields = set(["cache_creation"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -3,10 +3,8 @@
from __future__ import annotations
from .anthropicimagemimetype import AnthropicImageMimeType
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from typing import Literal
from typing_extensions import Annotated, TypedDict
from typing_extensions import TypedDict
AnthropicBase64ImageSourceType = Literal["base64",]
@@ -21,8 +19,6 @@ class AnthropicBase64ImageSourceTypedDict(TypedDict):
class AnthropicBase64ImageSource(BaseModel):
data: str
media_type: Annotated[
AnthropicImageMimeType, PlainValidator(validate_open_enum(False))
]
media_type: AnthropicImageMimeType
type: AnthropicBase64ImageSourceType
@@ -2,11 +2,10 @@
from __future__ import annotations
from .anthropiccachecontrolttl import AnthropicCacheControlTTL
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
AnthropicCacheControlDirectiveType = Literal["ephemeral",]
@@ -24,6 +23,20 @@ class AnthropicCacheControlDirective(BaseModel):
type: AnthropicCacheControlDirectiveType
ttl: Annotated[
Optional[AnthropicCacheControlTTL], PlainValidator(validate_open_enum(False))
] = None
ttl: Optional[AnthropicCacheControlTTL] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["ttl"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -34,30 +34,14 @@ class AnthropicCitationCharLocationParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["document_title"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -34,30 +34,14 @@ class AnthropicCitationContentBlockLocationParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["document_title"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -34,30 +34,14 @@ class AnthropicCitationPageLocationParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["document_title"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -37,30 +37,14 @@ class AnthropicCitationSearchResultLocation(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["title"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -31,30 +31,14 @@ class AnthropicCitationWebSearchResultLocation(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["title"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -44,36 +44,33 @@ class AnthropicCompactionUsageIteration(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
nullable_fields = ["cache_creation"]
null_default_fields = []
optional_fields = set(
[
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
)
nullable_fields = set(["cache_creation"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -46,6 +46,22 @@ class AnthropicDocumentBlockParamCitationsTypedDict(TypedDict):
class AnthropicDocumentBlockParamCitations(BaseModel):
enabled: Optional[bool] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["enabled"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
AnthropicDocumentBlockParamContent1TypedDict = TypeAliasType(
"AnthropicDocumentBlockParamContent1TypedDict",
@@ -141,30 +157,25 @@ class AnthropicDocumentBlockParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["cache_control", "citations", "context", "title"]
nullable_fields = ["citations", "context", "title"]
null_default_fields = []
optional_fields = set(["cache_control", "citations", "context", "title"])
nullable_fields = set(["citations", "context", "title"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -13,9 +13,9 @@ from .anthropicurlimagesource import (
AnthropicURLImageSource,
AnthropicURLImageSourceTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from pydantic import Discriminator, Tag, model_serializer
from typing import Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
@@ -52,3 +52,19 @@ class AnthropicImageBlockParam(BaseModel):
cache_control: Optional[AnthropicCacheControlDirective] = None
r"""Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["cache_control"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict
@@ -15,3 +16,21 @@ class AnthropicIterationCacheCreation(BaseModel):
ephemeral_1h_input_tokens: Optional[int] = None
ephemeral_5m_input_tokens: Optional[int] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
["ephemeral_1h_input_tokens", "ephemeral_5m_input_tokens"]
)
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -47,37 +47,34 @@ class AnthropicMessageUsageIteration(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
"model",
]
nullable_fields = ["cache_creation"]
null_default_fields = []
optional_fields = set(
[
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
"model",
]
)
nullable_fields = set(["cache_creation"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -9,7 +9,8 @@ from .anthropictextblockparam import (
AnthropicTextBlockParam,
AnthropicTextBlockParamTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -21,6 +22,22 @@ class AnthropicSearchResultBlockParamCitationsTypedDict(TypedDict):
class AnthropicSearchResultBlockParamCitations(BaseModel):
enabled: Optional[bool] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["enabled"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
AnthropicSearchResultBlockParamType = Literal["search_result",]
@@ -48,3 +65,19 @@ class AnthropicSearchResultBlockParam(BaseModel):
r"""Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models."""
citations: Optional[AnthropicSearchResultBlockParamCitations] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["cache_control", "citations"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -89,30 +89,25 @@ class AnthropicTextBlockParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["cache_control", "citations"]
nullable_fields = ["citations"]
null_default_fields = []
optional_fields = set(["cache_control", "citations"])
nullable_fields = set(["citations"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -41,36 +41,33 @@ class AnthropicUnknownUsageIteration(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
nullable_fields = ["cache_creation"]
null_default_fields = []
optional_fields = set(
[
"cache_creation",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"input_tokens",
"output_tokens",
]
)
nullable_fields = set(["cache_creation"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -37,30 +37,25 @@ class AnthropicWebSearchResultBlockParam(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["page_age"]
nullable_fields = ["page_age"]
null_default_fields = []
optional_fields = set(["page_age"])
nullable_fields = set(["page_age"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -37,30 +37,25 @@ class AnthropicWebSearchToolUserLocation(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["city", "country", "region", "timezone"]
nullable_fields = ["city", "country", "region", "timezone"]
null_default_fields = []
optional_fields = set(["city", "country", "region", "timezone"])
nullable_fields = set(["city", "country", "region", "timezone"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+16 -23
View File
@@ -13,11 +13,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Literal
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
ApplyPatchCallItemType = Literal["apply_patch_call",]
@@ -43,7 +41,7 @@ class ApplyPatchCallItem(BaseModel):
operation: ApplyPatchCallOperation
r"""The patch operation requested by an `apply_patch_call`. `create_file` and `update_file` carry a V4A diff; `delete_file` omits it."""
status: Annotated[ApplyPatchCallStatus, PlainValidator(validate_open_enum(False))]
status: ApplyPatchCallStatus
r"""Lifecycle state of an `apply_patch_call` output item."""
type: ApplyPatchCallItemType
@@ -52,30 +50,25 @@ class ApplyPatchCallItem(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["id"]
nullable_fields = ["id"]
null_default_fields = []
optional_fields = set(["id"])
nullable_fields = set(["id"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -13,9 +13,12 @@ from .applypatchupdatefileoperation import (
ApplyPatchUpdateFileOperation,
ApplyPatchUpdateFileOperationTypedDict,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from functools import partial
from openrouter.types import BaseModel
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Union
from typing_extensions import Annotated, TypeAliasType
@@ -30,12 +33,38 @@ ApplyPatchCallOperationTypedDict = TypeAliasType(
r"""The patch operation requested by an `apply_patch_call`. `create_file` and `update_file` carry a V4A diff; `delete_file` omits it."""
class UnknownApplyPatchCallOperation(BaseModel):
r"""A ApplyPatchCallOperation variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_APPLY_PATCH_CALL_OPERATION_VARIANTS: dict[str, Any] = {
"create_file": ApplyPatchCreateFileOperation,
"delete_file": ApplyPatchDeleteFileOperation,
"update_file": ApplyPatchUpdateFileOperation,
}
ApplyPatchCallOperation = Annotated[
Union[
Annotated[ApplyPatchCreateFileOperation, Tag("create_file")],
Annotated[ApplyPatchDeleteFileOperation, Tag("delete_file")],
Annotated[ApplyPatchUpdateFileOperation, Tag("update_file")],
ApplyPatchCreateFileOperation,
ApplyPatchDeleteFileOperation,
ApplyPatchUpdateFileOperation,
UnknownApplyPatchCallOperation,
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_APPLY_PATCH_CALL_OPERATION_VARIANTS,
unknown_cls=UnknownApplyPatchCallOperation,
union_name="ApplyPatchCallOperation",
)
),
]
r"""The patch operation requested by an `apply_patch_call`. `create_file` and `update_file` carry a V4A diff; `delete_file` omits it."""
@@ -9,11 +9,9 @@ from openrouter.types import (
UNSET_SENTINEL,
UnrecognizedStr,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Literal, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
ApplyPatchCallOutputItemStatus = Union[
@@ -43,9 +41,7 @@ class ApplyPatchCallOutputItem(BaseModel):
call_id: str
status: Annotated[
ApplyPatchCallOutputItemStatus, PlainValidator(validate_open_enum(False))
]
status: ApplyPatchCallOutputItemStatus
type: ApplyPatchCallOutputItemType
@@ -55,30 +51,25 @@ class ApplyPatchCallOutputItem(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["id", "output"]
nullable_fields = ["id", "output"]
null_default_fields = []
optional_fields = set(["id", "output"])
nullable_fields = set(["id", "output"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -5,7 +5,8 @@ from .applypatchservertoolconfig import (
ApplyPatchServerToolConfig,
ApplyPatchServerToolConfigTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -28,3 +29,19 @@ class ApplyPatchServerToolOpenRouter(BaseModel):
parameters: Optional[ApplyPatchServerToolConfig] = None
r"""Configuration for the openrouter:apply_patch server tool"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -2,11 +2,10 @@
from __future__ import annotations
from .applypatchengineenum import ApplyPatchEngineEnum
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ApplyPatchServerToolConfigTypedDict(TypedDict):
@@ -19,7 +18,21 @@ class ApplyPatchServerToolConfigTypedDict(TypedDict):
class ApplyPatchServerToolConfig(BaseModel):
r"""Configuration for the openrouter:apply_patch server tool"""
engine: Annotated[
Optional[ApplyPatchEngineEnum], PlainValidator(validate_open_enum(False))
] = None
engine: Optional[ApplyPatchEngineEnum] = None
r"""Which apply_patch engine to use. \"auto\" (default) uses native passthrough when the endpoint advertises native apply_patch support, otherwise falls back to OpenRouter's HITL validator. \"native\" forces native passthrough — when the endpoint does not support native, the request falls back to HITL. \"openrouter\" always runs the HITL validator. Native passthrough streams the diff incrementally via `apply_patch_call_operation_diff.delta` events; HITL buffers the diff for atomic delivery as a single delta."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["engine"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+18 -1
View File
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -30,3 +31,19 @@ class AutoRouterPlugin(BaseModel):
enabled: Optional[bool] = None
r"""Set to false to disable the auto-router plugin for this request. Defaults to true."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["allowed_models", "cost_quality_tradeoff", "enabled"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -32,30 +32,25 @@ class BadGatewayResponseErrorData(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["metadata"]
nullable_fields = ["metadata"]
null_default_fields = []
optional_fields = set(["metadata"])
nullable_fields = set(["metadata"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -32,30 +32,25 @@ class BadRequestResponseErrorData(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["metadata"]
nullable_fields = ["metadata"]
null_default_fields = []
optional_fields = set(["metadata"])
nullable_fields = set(["metadata"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+46 -28
View File
@@ -35,6 +35,7 @@ from .outputitemimagegenerationcall import (
OutputItemImageGenerationCallTypedDict,
)
from .outputmessage import OutputMessage, OutputMessageTypedDict
from functools import partial
from openrouter.types import (
BaseModel,
Nullable,
@@ -42,8 +43,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag, model_serializer
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict, model_serializer
from pydantic.functional_validators import BeforeValidator
from typing import Any, List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
@@ -56,14 +58,35 @@ BaseInputsContent1TypedDict = TypeAliasType(
)
class UnknownBaseInputsContent1(BaseModel):
r"""A BaseInputsContent1 variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_BASE_INPUTS_CONTENT_1_VARIANTS: dict[str, Any] = {
"input_audio": InputAudio,
"input_file": InputFile,
"input_image": InputImage,
"input_text": InputText,
}
BaseInputsContent1 = Annotated[
Union[
Annotated[InputAudio, Tag("input_audio")],
Annotated[InputFile, Tag("input_file")],
Annotated[InputImage, Tag("input_image")],
Annotated[InputText, Tag("input_text")],
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
Union[InputAudio, InputFile, InputImage, InputText, UnknownBaseInputsContent1],
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_BASE_INPUTS_CONTENT_1_VARIANTS,
unknown_cls=UnknownBaseInputsContent1,
union_name="BaseInputsContent1",
)
),
]
@@ -150,31 +173,26 @@ class BaseInputsMessage(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["phase", "type"]
nullable_fields = ["phase"]
null_default_fields = []
optional_fields = set(["phase", "type"])
nullable_fields = set(["phase"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -10,10 +10,8 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class BaseReasoningConfigTypedDict(TypedDict):
@@ -22,41 +20,31 @@ class BaseReasoningConfigTypedDict(TypedDict):
class BaseReasoningConfig(BaseModel):
effort: Annotated[
OptionalNullable[ReasoningEffort], PlainValidator(validate_open_enum(False))
] = UNSET
effort: OptionalNullable[ReasoningEffort] = UNSET
summary: Annotated[
OptionalNullable[ReasoningSummaryVerbosity],
PlainValidator(validate_open_enum(False)),
] = UNSET
summary: OptionalNullable[ReasoningSummaryVerbosity] = UNSET
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["effort", "summary"]
nullable_fields = ["effort", "summary"]
null_default_fields = []
optional_fields = set(["effort", "summary"])
nullable_fields = set(["effort", "summary"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+18 -1
View File
@@ -2,7 +2,8 @@
from __future__ import annotations
from .bashservertoolconfig import BashServerToolConfig, BashServerToolConfigTypedDict
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -25,3 +26,19 @@ class BashServerTool(BaseModel):
parameters: Optional[BashServerToolConfig] = None
r"""Configuration for the openrouter:bash server tool"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -6,11 +6,10 @@ from .bashservertoolenvironment import (
BashServerToolEnvironment,
BashServerToolEnvironmentTypedDict,
)
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class BashServerToolConfigTypedDict(TypedDict):
@@ -27,9 +26,7 @@ class BashServerToolConfigTypedDict(TypedDict):
class BashServerToolConfig(BaseModel):
r"""Configuration for the openrouter:bash server tool"""
engine: Annotated[
Optional[BashServerToolEngine], PlainValidator(validate_open_enum(False))
] = None
engine: Optional[BashServerToolEngine] = None
r"""Which bash engine to use. \"openrouter\" runs commands server-side in the OpenRouter sandbox. \"auto\" (default) and \"native\" use native passthrough, returning the tool call to your application to run client-side; OpenRouter does not execute the commands."""
environment: Optional[BashServerToolEnvironment] = None
@@ -37,3 +34,19 @@ class BashServerToolConfig(BaseModel):
sleep_after_seconds: Optional[int] = None
r"""How long (in seconds) the container stays warm after its last command before sleeping, freeing its capacity slot. Idle-based: each command renews the timer. Defaults to 900 (15 minutes); capped at 2592000 (30 days)."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["engine", "environment", "sleep_after_seconds"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+18 -28
View File
@@ -9,11 +9,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class BYOKKeyTypedDict(TypedDict):
@@ -68,7 +66,7 @@ class BYOKKey(BaseModel):
label: str
r"""Short masked snippet of the key (e.g. the first/last few characters) used to identify it in the UI."""
provider: Annotated[BYOKProviderSlug, PlainValidator(validate_open_enum(False))]
provider: BYOKProviderSlug
r"""The upstream provider this credential authenticates against, as a lowercase slug (e.g. `openai`, `anthropic`, `amazon-bedrock`)."""
sort_order: int
@@ -82,35 +80,27 @@ class BYOKKey(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["name"]
nullable_fields = [
"allowed_api_key_hashes",
"allowed_models",
"allowed_user_ids",
"name",
]
null_default_fields = []
optional_fields = set(["name"])
nullable_fields = set(
["allowed_api_key_hashes", "allowed_models", "allowed_user_ids", "name"]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -4,9 +4,12 @@ from __future__ import annotations
from .booleancapability import BooleanCapability, BooleanCapabilityTypedDict
from .enumcapability import EnumCapability, EnumCapabilityTypedDict
from .rangecapability import RangeCapability, RangeCapabilityTypedDict
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from functools import partial
from openrouter.types import BaseModel
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Union
from typing_extensions import Annotated, TypeAliasType
@@ -19,12 +22,35 @@ CapabilityDescriptorTypedDict = TypeAliasType(
r"""A typed descriptor for one supported request parameter."""
class UnknownCapabilityDescriptor(BaseModel):
r"""A CapabilityDescriptor variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_CAPABILITY_DESCRIPTOR_VARIANTS: dict[str, Any] = {
"enum": EnumCapability,
"range": RangeCapability,
"boolean": BooleanCapability,
}
CapabilityDescriptor = Annotated[
Union[
Annotated[EnumCapability, Tag("enum")],
Annotated[RangeCapability, Tag("range")],
Annotated[BooleanCapability, Tag("boolean")],
EnumCapability, RangeCapability, BooleanCapability, UnknownCapabilityDescriptor
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_CAPABILITY_DESCRIPTOR_VARIANTS,
unknown_cls=UnknownCapabilityDescriptor,
union_name="CapabilityDescriptor",
)
),
]
r"""A typed descriptor for one supported request parameter."""
@@ -87,39 +87,36 @@ class ChatAssistantMessage(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"audio",
"content",
"images",
"name",
"reasoning",
"reasoning_details",
"refusal",
"tool_calls",
]
nullable_fields = ["content", "reasoning", "refusal"]
null_default_fields = []
optional_fields = set(
[
"audio",
"content",
"images",
"name",
"reasoning",
"reasoning_details",
"refusal",
"tool_calls",
]
)
nullable_fields = set(["content", "reasoning", "refusal"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+18 -1
View File
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict
@@ -33,3 +34,19 @@ class ChatAudioOutput(BaseModel):
transcript: Optional[str] = None
r"""Audio transcript"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["data", "expires_at", "id", "transcript"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+16 -25
View File
@@ -11,10 +11,8 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ChatChoiceTypedDict(TypedDict):
@@ -32,9 +30,7 @@ class ChatChoiceTypedDict(TypedDict):
class ChatChoice(BaseModel):
r"""Chat completion choice"""
finish_reason: Annotated[
Nullable[ChatFinishReasonEnum], PlainValidator(validate_open_enum(False))
]
finish_reason: Nullable[ChatFinishReasonEnum]
index: int
r"""Choice index"""
@@ -47,30 +43,25 @@ class ChatChoice(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["logprobs"]
nullable_fields = ["finish_reason", "logprobs"]
null_default_fields = []
optional_fields = set(["logprobs"])
nullable_fields = set(["finish_reason", "logprobs"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -38,3 +38,9 @@ class ChatContentAudio(BaseModel):
input_audio: ChatContentAudioInputAudio
type: ChatContentAudioType
try:
ChatContentAudioInputAudio.model_rebuild()
except NameError:
pass
@@ -2,11 +2,10 @@
from __future__ import annotations
from .anthropiccachecontrolttl import AnthropicCacheControlTTL
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
ChatContentCacheControlType = Literal["ephemeral",]
@@ -24,6 +23,20 @@ class ChatContentCacheControl(BaseModel):
type: ChatContentCacheControlType
ttl: Annotated[
Optional[AnthropicCacheControlTTL], PlainValidator(validate_open_enum(False))
] = None
ttl: Optional[AnthropicCacheControlTTL] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["ttl"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+18 -1
View File
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -25,6 +26,22 @@ class File(BaseModel):
filename: Optional[str] = None
r"""Original filename"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["file_data", "file_id", "filename"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
ChatContentFileType = Literal["file",]
+20 -7
View File
@@ -1,11 +1,10 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
from pydantic import model_serializer
from typing import Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
ChatContentImageDetail = Union[
@@ -31,11 +30,25 @@ class ChatContentImageImageURL(BaseModel):
url: str
r"""URL of the image (data: URLs supported)"""
detail: Annotated[
Optional[ChatContentImageDetail], PlainValidator(validate_open_enum(False))
] = None
detail: Optional[ChatContentImageDetail] = None
r"""Image detail level for vision models. `original` is an OpenRouter extension (not in the OpenAI Chat Completions spec) requesting true original-resolution media; it is downgraded to `high` for providers that lack an original-resolution tier."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["detail"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
ChatContentImageType = Literal["image_url",]
+42 -10
View File
@@ -10,9 +10,12 @@ from .legacy_chatcontentvideo import (
LegacyChatContentVideo,
LegacyChatContentVideoTypedDict,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from functools import partial
from openrouter.types import BaseModel
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Union
from typing_extensions import Annotated, TypeAliasType
@@ -30,15 +33,44 @@ ChatContentItemsTypedDict = TypeAliasType(
r"""Content part for chat completion messages"""
class UnknownChatContentItems(BaseModel):
r"""A ChatContentItems variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_CHAT_CONTENT_ITEMS_VARIANTS: dict[str, Any] = {
"file": ChatContentFile,
"image_url": ChatContentImage,
"input_audio": ChatContentAudio,
"input_video": LegacyChatContentVideo,
"text": ChatContentText,
"video_url": ChatContentVideo,
}
ChatContentItems = Annotated[
Union[
Annotated[ChatContentFile, Tag("file")],
Annotated[ChatContentImage, Tag("image_url")],
Annotated[ChatContentAudio, Tag("input_audio")],
Annotated[LegacyChatContentVideo, Tag("input_video")],
Annotated[ChatContentText, Tag("text")],
Annotated[ChatContentVideo, Tag("video_url")],
ChatContentFile,
ChatContentImage,
ChatContentAudio,
LegacyChatContentVideo,
ChatContentText,
ChatContentVideo,
UnknownChatContentItems,
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_CHAT_CONTENT_ITEMS_VARIANTS,
unknown_cls=UnknownChatContentItems,
union_name="ChatContentItems",
)
),
]
r"""Content part for chat completion messages"""
+18 -1
View File
@@ -5,7 +5,8 @@ from .chatcontentcachecontrol import (
ChatContentCacheControl,
ChatContentCacheControlTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -31,3 +32,19 @@ class ChatContentText(BaseModel):
cache_control: Optional[ChatContentCacheControl] = None
r"""Cache control for the content part"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["cache_control"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+18 -1
View File
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict
@@ -18,3 +19,19 @@ class ChatDebugOptions(BaseModel):
echo_upstream_body: Optional[bool] = None
r"""If true, includes the transformed upstream request body in a debug chunk at the start of the stream. Only works with streaming mode."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["echo_upstream_body"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -2,7 +2,8 @@
from __future__ import annotations
from .chatcontenttext import ChatContentText, ChatContentTextTypedDict
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Literal, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
@@ -42,3 +43,19 @@ class ChatDeveloperMessage(BaseModel):
name: Optional[str] = None
r"""Optional name for the developer message"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["name"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+45 -42
View File
@@ -39,10 +39,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag, model_serializer
from pydantic import model_serializer
from typing import Any, Dict, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
from typing_extensions import NotRequired, TypeAliasType, TypedDict
class ChatFunctionToolFunctionFunctionTypedDict(TypedDict):
@@ -75,31 +74,26 @@ class ChatFunctionToolFunctionFunction(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["description", "parameters", "strict"]
nullable_fields = ["strict"]
null_default_fields = []
optional_fields = set(["description", "parameters", "strict"])
nullable_fields = set(["strict"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -124,6 +118,22 @@ class ChatFunctionToolFunction(BaseModel):
cache_control: Optional[ChatContentCacheControl] = None
r"""Cache control for the content part"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["cache_control"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
ChatFunctionToolTypedDict = TypeAliasType(
"ChatFunctionToolTypedDict",
@@ -143,26 +153,19 @@ ChatFunctionToolTypedDict = TypeAliasType(
r"""Tool definition for function calling (regular function or OpenRouter built-in server tool)"""
ChatFunctionTool = Annotated[
ChatFunctionTool = TypeAliasType(
"ChatFunctionTool",
Union[
Annotated[ChatFunctionToolFunction, Tag("function")],
Annotated[AdvisorServerToolOpenRouter, Tag("openrouter:advisor")],
Annotated[BashServerTool, Tag("openrouter:bash")],
Annotated[DatetimeServerTool, Tag("openrouter:datetime")],
Annotated[
ImageGenerationServerToolOpenRouter, Tag("openrouter:image_generation")
],
Annotated[
ChatSearchModelsServerTool, Tag("openrouter:experimental__search_models")
],
Annotated[SubagentServerToolOpenRouter, Tag("openrouter:subagent")],
Annotated[WebFetchServerTool, Tag("openrouter:web_fetch")],
Annotated[OpenRouterWebSearchServerTool, Tag("openrouter:web_search")],
Annotated[ChatWebSearchShorthand, Tag("web_search")],
Annotated[ChatWebSearchShorthand, Tag("web_search_preview")],
Annotated[ChatWebSearchShorthand, Tag("web_search_preview_2025_03_11")],
Annotated[ChatWebSearchShorthand, Tag("web_search_2025_08_26")],
AdvisorServerToolOpenRouter,
BashServerTool,
DatetimeServerTool,
ImageGenerationServerToolOpenRouter,
ChatSearchModelsServerTool,
SubagentServerToolOpenRouter,
WebFetchServerTool,
OpenRouterWebSearchServerTool,
ChatFunctionToolFunction,
ChatWebSearchShorthand,
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
]
)
r"""Tool definition for function calling (regular function or OpenRouter built-in server tool)"""
@@ -46,30 +46,31 @@ class ChatJSONSchemaConfig(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["description", "schema", "strict"]
nullable_fields = ["strict"]
null_default_fields = []
optional_fields = set(["description", "schema", "strict"])
nullable_fields = set(["strict"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
try:
ChatJSONSchemaConfig.model_rebuild()
except NameError:
pass
+97 -117
View File
@@ -55,9 +55,8 @@ from openrouter.types import (
UNSET_SENTINEL,
UnrecognizedStr,
)
from openrouter.utils import get_discriminator, validate_open_enum
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag, model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Any, Dict, List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
@@ -130,43 +129,33 @@ class ChatRequestReasoningTypedDict(TypedDict):
class ChatRequestReasoning(BaseModel):
r"""Configuration options for reasoning models"""
effort: Annotated[
OptionalNullable[ChatRequestEffort], PlainValidator(validate_open_enum(False))
] = UNSET
effort: OptionalNullable[ChatRequestEffort] = UNSET
r"""Constrains effort on reasoning for reasoning models"""
summary: Annotated[
OptionalNullable[ChatReasoningSummaryVerbosityEnum],
PlainValidator(validate_open_enum(False)),
] = UNSET
summary: OptionalNullable[ChatReasoningSummaryVerbosityEnum] = UNSET
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["effort", "summary"]
nullable_fields = ["effort", "summary"]
null_default_fields = []
optional_fields = set(["effort", "summary"])
nullable_fields = set(["effort", "summary"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -350,9 +339,7 @@ class ChatRequest(BaseModel):
min_p: OptionalNullable[float] = UNSET
r"""Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter."""
modalities: Optional[
List[Annotated[Modality, PlainValidator(validate_open_enum(False))]]
] = None
modalities: Optional[List[Modality]] = None
r"""Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\"."""
model: Optional[str] = None
@@ -376,10 +363,7 @@ class ChatRequest(BaseModel):
reasoning: Optional[ChatRequestReasoning] = None
r"""Configuration options for reasoning models"""
reasoning_effort: Annotated[
OptionalNullable[ChatRequestReasoningEffort],
PlainValidator(validate_open_enum(False)),
] = UNSET
reasoning_effort: OptionalNullable[ChatRequestReasoningEffort] = UNSET
r"""Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ."""
repetition_penalty: OptionalNullable[float] = UNSET
@@ -391,10 +375,7 @@ class ChatRequest(BaseModel):
seed: OptionalNullable[int] = UNSET
r"""Random seed for deterministic outputs"""
service_tier: Annotated[
OptionalNullable[ChatRequestServiceTier],
PlainValidator(validate_open_enum(False)),
] = UNSET
service_tier: OptionalNullable[ChatRequestServiceTier] = UNSET
r"""The service tier to use for processing this request."""
session_id: Optional[str] = None
@@ -441,89 +422,88 @@ class ChatRequest(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"cache_control",
"debug",
"frequency_penalty",
"image_config",
"logit_bias",
"logprobs",
"max_completion_tokens",
"max_tokens",
"metadata",
"min_p",
"modalities",
"model",
"models",
"parallel_tool_calls",
"plugins",
"presence_penalty",
"provider",
"reasoning",
"reasoning_effort",
"repetition_penalty",
"response_format",
"seed",
"service_tier",
"session_id",
"stop",
"stop_server_tools_when",
"stream",
"stream_options",
"temperature",
"tool_choice",
"tools",
"top_a",
"top_k",
"top_logprobs",
"top_p",
"trace",
"user",
]
nullable_fields = [
"frequency_penalty",
"logit_bias",
"logprobs",
"max_completion_tokens",
"max_tokens",
"min_p",
"parallel_tool_calls",
"presence_penalty",
"provider",
"reasoning_effort",
"repetition_penalty",
"seed",
"service_tier",
"stop",
"stream_options",
"temperature",
"top_a",
"top_k",
"top_logprobs",
"top_p",
]
null_default_fields = []
optional_fields = set(
[
"cache_control",
"debug",
"frequency_penalty",
"image_config",
"logit_bias",
"logprobs",
"max_completion_tokens",
"max_tokens",
"metadata",
"min_p",
"modalities",
"model",
"models",
"parallel_tool_calls",
"plugins",
"presence_penalty",
"provider",
"reasoning",
"reasoning_effort",
"repetition_penalty",
"response_format",
"seed",
"service_tier",
"session_id",
"stop",
"stop_server_tools_when",
"stream",
"stream_options",
"temperature",
"tool_choice",
"tools",
"top_a",
"top_k",
"top_logprobs",
"top_p",
"trace",
"user",
]
)
nullable_fields = set(
[
"frequency_penalty",
"logit_bias",
"logprobs",
"max_completion_tokens",
"max_tokens",
"min_p",
"parallel_tool_calls",
"presence_penalty",
"provider",
"reasoning_effort",
"repetition_penalty",
"seed",
"service_tier",
"stop",
"stream_options",
"temperature",
"top_a",
"top_k",
"top_logprobs",
"top_p",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+14 -19
View File
@@ -70,30 +70,25 @@ class ChatResult(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["openrouter_metadata", "service_tier", "usage"]
nullable_fields = ["service_tier", "system_fingerprint"]
null_default_fields = []
optional_fields = set(["openrouter_metadata", "service_tier", "usage"])
nullable_fields = set(["service_tier", "system_fingerprint"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -5,7 +5,8 @@ from .searchmodelsservertoolconfig import (
SearchModelsServerToolConfig,
SearchModelsServerToolConfigTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -28,3 +29,19 @@ class ChatSearchModelsServerTool(BaseModel):
parameters: Optional[SearchModelsServerToolConfig] = None
r"""Configuration for the openrouter:experimental__search_models server tool"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+16 -25
View File
@@ -11,10 +11,8 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ChatStreamChoiceTypedDict(TypedDict):
@@ -35,9 +33,7 @@ class ChatStreamChoice(BaseModel):
delta: ChatStreamDelta
r"""Delta changes in streaming response"""
finish_reason: Annotated[
Nullable[ChatFinishReasonEnum], PlainValidator(validate_open_enum(False))
]
finish_reason: Nullable[ChatFinishReasonEnum]
index: int
r"""Choice index"""
@@ -47,30 +43,25 @@ class ChatStreamChoice(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["logprobs"]
nullable_fields = ["finish_reason", "logprobs"]
null_default_fields = []
optional_fields = set(["logprobs"])
nullable_fields = set(["finish_reason", "logprobs"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+56 -29
View File
@@ -12,11 +12,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ChatStreamChunkMetadataTypedDict(TypedDict):
@@ -31,12 +29,28 @@ class ChatStreamChunkMetadataTypedDict(TypedDict):
class ChatStreamChunkMetadata(BaseModel):
r"""Structured error metadata"""
error_type: Annotated[APIErrorType, PlainValidator(validate_open_enum(False))]
error_type: APIErrorType
r"""Canonical OpenRouter error type, stable across all API formats"""
provider_code: Optional[str] = None
r"""Upstream provider-specific error code, when available"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["provider_code"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
class ChatStreamChunkErrorTypedDict(TypedDict):
r"""Error information"""
@@ -61,6 +75,22 @@ class ChatStreamChunkError(BaseModel):
metadata: Optional[ChatStreamChunkMetadata] = None
r"""Structured error metadata"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["metadata"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
ChatStreamChunkObject = Literal["chat.completion.chunk",]
@@ -121,36 +151,33 @@ class ChatStreamChunk(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"error",
"openrouter_metadata",
"service_tier",
"system_fingerprint",
"usage",
]
nullable_fields = ["service_tier"]
null_default_fields = []
optional_fields = set(
[
"error",
"openrouter_metadata",
"service_tier",
"system_fingerprint",
"usage",
]
)
nullable_fields = set(["service_tier"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+24 -27
View File
@@ -63,38 +63,35 @@ class ChatStreamDelta(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"audio",
"content",
"reasoning",
"reasoning_details",
"refusal",
"role",
"tool_calls",
]
nullable_fields = ["content", "reasoning", "refusal"]
null_default_fields = []
optional_fields = set(
[
"audio",
"content",
"reasoning",
"reasoning_details",
"refusal",
"role",
"tool_calls",
]
)
nullable_fields = set(["content", "reasoning", "refusal"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+18 -1
View File
@@ -1,8 +1,9 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
@@ -24,3 +25,19 @@ class ChatStreamOptions(BaseModel):
),
] = None
r"""Deprecated: This field has no effect. Full usage details are always included."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["include_usage"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -24,6 +25,22 @@ class ChatStreamToolCallFunction(BaseModel):
name: Optional[str] = None
r"""Function name"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["arguments", "name"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
ChatStreamToolCallType = Literal["function",]
r"""Tool call type"""
@@ -56,3 +73,19 @@ class ChatStreamToolCall(BaseModel):
type: Optional[ChatStreamToolCallType] = None
r"""Tool call type"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["function", "id", "type"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+18 -1
View File
@@ -2,7 +2,8 @@
from __future__ import annotations
from .chatcontenttext import ChatContentText, ChatContentTextTypedDict
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Literal, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
@@ -42,3 +43,19 @@ class ChatSystemMessage(BaseModel):
name: Optional[str] = None
r"""Optional name for the system message"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["name"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+14 -36
View File
@@ -23,30 +23,14 @@ class ChatTokenLogprobTopLogprob(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["bytes"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
@@ -82,30 +66,24 @@ class ChatTokenLogprob(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["bytes"]
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)
val = serialized.get(k, serialized.get(n))
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)
):
if val != UNSET_SENTINEL:
m[k] = val
return m
try:
ChatTokenLogprobTopLogprob.model_rebuild()
except NameError:
pass
try:
ChatTokenLogprob.model_rebuild()
except NameError:
pass
+14 -19
View File
@@ -34,30 +34,25 @@ class ChatTokenLogprobs(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["refusal"]
nullable_fields = ["content", "refusal"]
null_default_fields = []
optional_fields = set(["refusal"])
nullable_fields = set(["content", "refusal"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+95 -88
View File
@@ -44,41 +44,40 @@ class ChatUsageCompletionTokensDetails(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"accepted_prediction_tokens",
"audio_tokens",
"reasoning_tokens",
"rejected_prediction_tokens",
]
nullable_fields = [
"accepted_prediction_tokens",
"audio_tokens",
"reasoning_tokens",
"rejected_prediction_tokens",
]
null_default_fields = []
optional_fields = set(
[
"accepted_prediction_tokens",
"audio_tokens",
"reasoning_tokens",
"rejected_prediction_tokens",
]
)
nullable_fields = set(
[
"accepted_prediction_tokens",
"audio_tokens",
"reasoning_tokens",
"rejected_prediction_tokens",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -111,6 +110,24 @@ class ChatUsagePromptTokensDetails(BaseModel):
video_tokens: Optional[int] = None
r"""Video input tokens"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
["audio_tokens", "cache_write_tokens", "cached_tokens", "video_tokens"]
)
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
class ServerToolUseDetailsTypedDict(TypedDict):
r"""Usage for server-side tool execution (e.g., web search)"""
@@ -137,39 +154,30 @@ class ServerToolUseDetails(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"tool_calls_executed",
"tool_calls_requested",
"web_search_requests",
]
nullable_fields = [
"tool_calls_executed",
"tool_calls_requested",
"web_search_requests",
]
null_default_fields = []
optional_fields = set(
["tool_calls_executed", "tool_calls_requested", "web_search_requests"]
)
nullable_fields = set(
["tool_calls_executed", "tool_calls_requested", "web_search_requests"]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -233,43 +241,42 @@ class ChatUsage(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"completion_tokens_details",
"cost",
"cost_details",
"is_byok",
"prompt_tokens_details",
"server_tool_use_details",
]
nullable_fields = [
"completion_tokens_details",
"cost",
"cost_details",
"prompt_tokens_details",
"server_tool_use_details",
]
null_default_fields = []
optional_fields = set(
[
"completion_tokens_details",
"cost",
"cost_details",
"is_byok",
"prompt_tokens_details",
"server_tool_use_details",
]
)
nullable_fields = set(
[
"completion_tokens_details",
"cost",
"cost_details",
"prompt_tokens_details",
"server_tool_use_details",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+18 -1
View File
@@ -2,7 +2,8 @@
from __future__ import annotations
from .chatcontentitems import ChatContentItems, ChatContentItemsTypedDict
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List, Literal, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
@@ -42,3 +43,19 @@ class ChatUserMessage(BaseModel):
name: Optional[str] = None
r"""Optional name for the user"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["name"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -8,11 +8,10 @@ from .websearchuserlocationservertool import (
WebSearchUserLocationServerTool,
WebSearchUserLocationServerToolTypedDict,
)
from openrouter.types import BaseModel, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
from pydantic import model_serializer
from typing import List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
ChatWebSearchShorthandType = Union[
@@ -52,16 +51,12 @@ class ChatWebSearchShorthandTypedDict(TypedDict):
class ChatWebSearchShorthand(BaseModel):
r"""Web search tool using OpenAI Responses API syntax. Automatically converted to openrouter:web_search."""
type: Annotated[
ChatWebSearchShorthandType, PlainValidator(validate_open_enum(False))
]
type: ChatWebSearchShorthandType
allowed_domains: Optional[List[str]] = None
r"""Limit search results to these domains. Supported by Exa, Firecrawl, Parallel, Perplexity, and most native providers (Anthropic, OpenAI, xAI). Cannot be used with excluded_domains."""
engine: Annotated[
Optional[WebSearchEngineEnum], PlainValidator(validate_open_enum(False))
] = None
engine: Optional[WebSearchEngineEnum] = None
r"""Which search engine to use. \"auto\" (default) uses native if the provider supports it, otherwise Exa. \"native\" forces the provider's built-in search. \"exa\" forces the Exa search API. \"firecrawl\" uses Firecrawl (requires BYOK). \"parallel\" uses the Parallel search API. \"perplexity\" uses the Perplexity Search API (raw ranked results)."""
excluded_domains: Optional[List[str]] = None
@@ -78,10 +73,36 @@ class ChatWebSearchShorthand(BaseModel):
parameters: Optional[WebSearchConfig] = None
search_context_size: Annotated[
Optional[SearchQualityLevel], PlainValidator(validate_open_enum(False))
] = None
search_context_size: Optional[SearchQualityLevel] = None
r"""How much context to retrieve per result. Applies to Exa, Parallel, and Perplexity engines; ignored with native provider search and Firecrawl. For Exa, pins a fixed per-result character cap (low=5,000, medium=15,000, high=30,000); when omitted, Exa picks an adaptive size per query and document (typically ~2,0004,000 characters per result). For Parallel, controls the total characters across all results; when omitted, Parallel uses its own default size. For Perplexity, maps directly to the Search API's native search_context_size parameter. Overridden by `max_characters` when both are set."""
user_location: Optional[WebSearchUserLocationServerTool] = None
r"""Approximate user location for location-biased results."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
[
"allowed_domains",
"engine",
"excluded_domains",
"max_characters",
"max_results",
"max_total_results",
"parameters",
"search_context_size",
"user_location",
]
)
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -9,11 +9,9 @@ from openrouter.types import (
UNSET_SENTINEL,
UnrecognizedStr,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
from typing_extensions import NotRequired, TypeAliasType, TypedDict
MemoryLimit = Union[
@@ -41,37 +39,30 @@ class ContainerAuto(BaseModel):
file_ids: Optional[List[str]] = None
memory_limit: Annotated[
OptionalNullable[MemoryLimit], PlainValidator(validate_open_enum(False))
] = UNSET
memory_limit: OptionalNullable[MemoryLimit] = UNSET
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["file_ids", "memory_limit"]
nullable_fields = ["memory_limit"]
null_default_fields = []
optional_fields = set(["file_ids", "memory_limit"])
nullable_fields = set(["memory_limit"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+14 -19
View File
@@ -35,30 +35,25 @@ class CompactionItem(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["id"]
nullable_fields = ["id"]
null_default_fields = []
optional_fields = set(["id"])
nullable_fields = set(["id"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+2 -4
View File
@@ -2,10 +2,8 @@
from __future__ import annotations
from openrouter.types import BaseModel, Nullable, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from typing import Any, Dict, List, Literal, Union
from typing_extensions import Annotated, TypedDict
from typing_extensions import TypedDict
CompoundFilterType = Union[
@@ -29,4 +27,4 @@ class CompoundFilter(BaseModel):
filters: List[Dict[str, Nullable[Any]]]
type: Annotated[CompoundFilterType, PlainValidator(validate_open_enum(False))]
type: CompoundFilterType
@@ -2,10 +2,8 @@
from __future__ import annotations
from openrouter.types import BaseModel, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from typing import Literal, Union
from typing_extensions import Annotated, TypedDict
from typing_extensions import TypedDict
Environment = Union[
@@ -39,6 +37,6 @@ class ComputerUseServerTool(BaseModel):
display_width: int
environment: Annotated[Environment, PlainValidator(validate_open_enum(False))]
environment: Environment
type: ComputerUseServerToolType
@@ -32,30 +32,25 @@ class ConflictResponseErrorData(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["metadata"]
nullable_fields = ["metadata"]
null_default_fields = []
optional_fields = set(["metadata"])
nullable_fields = set(["metadata"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -4,11 +4,10 @@ from __future__ import annotations
from .contentfilterbuiltinaction import ContentFilterBuiltinAction
from .contentfilterbuiltinslug import ContentFilterBuiltinSlug
from .promptinjectionscanscope import PromptInjectionScanScope
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ContentFilterBuiltinEntryTypedDict(TypedDict):
@@ -27,18 +26,30 @@ class ContentFilterBuiltinEntryTypedDict(TypedDict):
class ContentFilterBuiltinEntry(BaseModel):
r"""A builtin content filter entry. Builtin filters include PII detectors and the regex-based prompt injection detector."""
action: Annotated[
ContentFilterBuiltinAction, PlainValidator(validate_open_enum(False))
]
action: ContentFilterBuiltinAction
r"""Action taken when the builtin filter triggers"""
slug: Annotated[ContentFilterBuiltinSlug, PlainValidator(validate_open_enum(False))]
slug: ContentFilterBuiltinSlug
r"""The builtin filter identifier"""
label: Optional[str] = None
r"""Read-only, system-assigned redaction placeholder derived from the slug (e.g. \"[EMAIL]\", \"[PHONE]\"). Not settable by the caller."""
scan_scope: Annotated[
Optional[PromptInjectionScanScope], PlainValidator(validate_open_enum(False))
] = None
scan_scope: Optional[PromptInjectionScanScope] = None
r"""Which message roles to scan for prompt injection. Only applies to the regex-prompt-injection builtin. Defaults to all_messages."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["label", "scan_scope"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -4,10 +4,9 @@ from __future__ import annotations
from .contentfilterbuiltinaction import ContentFilterBuiltinAction
from .contentfilterbuiltinslug import ContentFilterBuiltinSlug
from .promptinjectionscanscope import PromptInjectionScanScope
from openrouter.types import BaseModel
from openrouter.utils import validate_open_enum
from openrouter.types import BaseModel, UNSET_SENTINEL
import pydantic
from pydantic.functional_validators import PlainValidator
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
@@ -28,12 +27,10 @@ class ContentFilterBuiltinEntryInputTypedDict(TypedDict):
class ContentFilterBuiltinEntryInput(BaseModel):
r"""A builtin content filter entry for create/update requests. Labels are system-assigned and cannot be set by the caller."""
action: Annotated[
ContentFilterBuiltinAction, PlainValidator(validate_open_enum(False))
]
action: ContentFilterBuiltinAction
r"""Action taken when the builtin filter triggers"""
slug: Annotated[ContentFilterBuiltinSlug, PlainValidator(validate_open_enum(False))]
slug: ContentFilterBuiltinSlug
r"""The builtin filter identifier"""
label: Annotated[
@@ -44,7 +41,21 @@ class ContentFilterBuiltinEntryInput(BaseModel):
] = None
r"""Deprecated: labels are system-assigned and cannot be set by the caller. Accepted for backward compatibility but silently ignored."""
scan_scope: Annotated[
Optional[PromptInjectionScanScope], PlainValidator(validate_open_enum(False))
] = None
scan_scope: Optional[PromptInjectionScanScope] = None
r"""Which message roles to scan for prompt injection. Only applies to the regex-prompt-injection builtin. Defaults to all_messages."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["label", "scan_scope"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+16 -23
View File
@@ -9,10 +9,8 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class ContentFilterEntryTypedDict(TypedDict):
@@ -29,7 +27,7 @@ class ContentFilterEntryTypedDict(TypedDict):
class ContentFilterEntry(BaseModel):
r"""A custom regex content filter that scans request messages for matching patterns."""
action: Annotated[ContentFilterAction, PlainValidator(validate_open_enum(False))]
action: ContentFilterAction
r"""Action taken when the pattern matches"""
pattern: str
@@ -40,30 +38,25 @@ class ContentFilterEntry(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["label"]
nullable_fields = ["label"]
null_default_fields = []
optional_fields = set(["label"])
nullable_fields = set(["label"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -7,10 +7,12 @@ from .openairesponsesrefusalcontent import (
)
from .reasoningtextcontent import ReasoningTextContent, ReasoningTextContentTypedDict
from .responseoutputtext import ResponseOutputText, ResponseOutputTextTypedDict
from functools import partial
from openrouter.types import BaseModel
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Literal, Union
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Union
from typing_extensions import Annotated, TypeAliasType, TypedDict
@@ -24,13 +26,39 @@ ContentPartAddedEventPartTypedDict = TypeAliasType(
)
class UnknownContentPartAddedEventPart(BaseModel):
r"""A ContentPartAddedEventPart variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_CONTENT_PART_ADDED_EVENT_PART_VARIANTS: dict[str, Any] = {
"output_text": ResponseOutputText,
"reasoning_text": ReasoningTextContent,
"refusal": OpenAIResponsesRefusalContent,
}
ContentPartAddedEventPart = Annotated[
Union[
Annotated[ResponseOutputText, Tag("output_text")],
Annotated[ReasoningTextContent, Tag("reasoning_text")],
Annotated[OpenAIResponsesRefusalContent, Tag("refusal")],
ResponseOutputText,
ReasoningTextContent,
OpenAIResponsesRefusalContent,
UnknownContentPartAddedEventPart,
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_CONTENT_PART_ADDED_EVENT_PART_VARIANTS,
unknown_cls=UnknownContentPartAddedEventPart,
union_name="ContentPartAddedEventPart",
)
),
]
@@ -7,10 +7,12 @@ from .openairesponsesrefusalcontent import (
)
from .reasoningtextcontent import ReasoningTextContent, ReasoningTextContentTypedDict
from .responseoutputtext import ResponseOutputText, ResponseOutputTextTypedDict
from functools import partial
from openrouter.types import BaseModel
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Literal, Union
from openrouter.utils.unions import parse_open_union
from pydantic import ConfigDict
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Union
from typing_extensions import Annotated, TypeAliasType, TypedDict
@@ -24,13 +26,39 @@ ContentPartDoneEventPartTypedDict = TypeAliasType(
)
class UnknownContentPartDoneEventPart(BaseModel):
r"""A ContentPartDoneEventPart variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_CONTENT_PART_DONE_EVENT_PART_VARIANTS: dict[str, Any] = {
"output_text": ResponseOutputText,
"reasoning_text": ReasoningTextContent,
"refusal": OpenAIResponsesRefusalContent,
}
ContentPartDoneEventPart = Annotated[
Union[
Annotated[ResponseOutputText, Tag("output_text")],
Annotated[ReasoningTextContent, Tag("reasoning_text")],
Annotated[OpenAIResponsesRefusalContent, Tag("refusal")],
ResponseOutputText,
ReasoningTextContent,
OpenAIResponsesRefusalContent,
UnknownContentPartDoneEventPart,
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_CONTENT_PART_DONE_EVENT_PART_VARIANTS,
unknown_cls=UnknownContentPartDoneEventPart,
union_name="ContentPartDoneEventPart",
)
),
]
@@ -2,7 +2,8 @@
from __future__ import annotations
from .contextcompressionengine import ContextCompressionEngine
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -26,3 +27,19 @@ class ContextCompressionPlugin(BaseModel):
engine: Optional[ContextCompressionEngine] = None
r"""The compression engine to use. Defaults to \"middle-out\"."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["enabled", "engine"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+14 -19
View File
@@ -31,30 +31,25 @@ class CostDetails(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["upstream_inference_cost"]
nullable_fields = ["upstream_inference_cost"]
null_default_fields = []
optional_fields = set(["upstream_inference_cost"])
nullable_fields = set(["upstream_inference_cost"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -9,11 +9,9 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
class CreateBYOKKeyRequestTypedDict(TypedDict):
@@ -39,7 +37,7 @@ class CreateBYOKKeyRequest(BaseModel):
key: str
r"""The raw provider API key or credential. This value is encrypted at rest and never returned in API responses."""
provider: Annotated[BYOKProviderSlug, PlainValidator(validate_open_enum(False))]
provider: BYOKProviderSlug
r"""The upstream provider this credential authenticates against, as a lowercase slug (e.g. `openai`, `anthropic`, `amazon-bedrock`)."""
allowed_models: OptionalNullable[List[str]] = UNSET
@@ -62,37 +60,34 @@ class CreateBYOKKeyRequest(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"allowed_models",
"allowed_user_ids",
"disabled",
"is_fallback",
"name",
"workspace_id",
]
nullable_fields = ["allowed_models", "allowed_user_ids", "name"]
null_default_fields = []
optional_fields = set(
[
"allowed_models",
"allowed_user_ids",
"disabled",
"is_fallback",
"name",
"workspace_id",
]
)
nullable_fields = set(["allowed_models", "allowed_user_ids", "name"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -14,10 +14,8 @@ from openrouter.types import (
UNSET,
UNSET_SENTINEL,
)
from openrouter.utils import validate_open_enum
import pydantic
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
@@ -109,9 +107,7 @@ class CreateGuardrailRequest(BaseModel):
limit_usd: OptionalNullable[float] = UNSET
r"""Spending limit in USD"""
reset_interval: Annotated[
OptionalNullable[GuardrailInterval], PlainValidator(validate_open_enum(False))
] = UNSET
reset_interval: OptionalNullable[GuardrailInterval] = UNSET
r"""Interval at which the limit resets (daily, weekly, monthly)"""
workspace_id: Optional[str] = None
@@ -119,61 +115,60 @@ class CreateGuardrailRequest(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"allowed_models",
"allowed_providers",
"content_filter_builtins",
"content_filters",
"description",
"enforce_zdr",
"enforce_zdr_anthropic",
"enforce_zdr_google",
"enforce_zdr_openai",
"enforce_zdr_other",
"ignored_models",
"ignored_providers",
"limit_usd",
"reset_interval",
"workspace_id",
]
nullable_fields = [
"allowed_models",
"allowed_providers",
"content_filter_builtins",
"content_filters",
"description",
"enforce_zdr",
"enforce_zdr_anthropic",
"enforce_zdr_google",
"enforce_zdr_openai",
"enforce_zdr_other",
"ignored_models",
"ignored_providers",
"limit_usd",
"reset_interval",
]
null_default_fields = []
optional_fields = set(
[
"allowed_models",
"allowed_providers",
"content_filter_builtins",
"content_filters",
"description",
"enforce_zdr",
"enforce_zdr_anthropic",
"enforce_zdr_google",
"enforce_zdr_openai",
"enforce_zdr_other",
"ignored_models",
"ignored_providers",
"limit_usd",
"reset_interval",
"workspace_id",
]
)
nullable_fields = set(
[
"allowed_models",
"allowed_providers",
"content_filter_builtins",
"content_filters",
"description",
"enforce_zdr",
"enforce_zdr_anthropic",
"enforce_zdr_google",
"enforce_zdr_openai",
"enforce_zdr_other",
"ignored_models",
"ignored_providers",
"limit_usd",
"reset_interval",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -13,11 +13,9 @@ from openrouter.types import (
UNSET_SENTINEL,
UnrecognizedStr,
)
from openrouter.utils import validate_open_enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Any, Dict, List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
CreateObservabilityDestinationRequestType = Union[
@@ -73,10 +71,7 @@ class CreateObservabilityDestinationRequest(BaseModel):
name: str
r"""Human-readable name for the destination."""
type: Annotated[
CreateObservabilityDestinationRequestType,
PlainValidator(validate_open_enum(False)),
]
type: CreateObservabilityDestinationRequestType
r"""The destination type. Only stable destination types are accepted."""
api_key_hashes: OptionalNullable[List[str]] = UNSET
@@ -99,37 +94,34 @@ class CreateObservabilityDestinationRequest(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"api_key_hashes",
"enabled",
"filter_rules",
"privacy_mode",
"sampling_rate",
"workspace_id",
]
nullable_fields = ["api_key_hashes", "filter_rules"]
null_default_fields = []
optional_fields = set(
[
"api_key_hashes",
"enabled",
"filter_rules",
"privacy_mode",
"sampling_rate",
"workspace_id",
]
)
nullable_fields = set(["api_key_hashes", "filter_rules"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -74,46 +74,45 @@ class CreateWorkspaceRequest(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"default_image_model",
"default_provider_sort",
"default_text_model",
"description",
"io_logging_api_key_ids",
"io_logging_sampling_rate",
"is_data_discount_logging_enabled",
"is_observability_broadcast_enabled",
"is_observability_io_logging_enabled",
]
nullable_fields = [
"default_image_model",
"default_provider_sort",
"default_text_model",
"description",
"io_logging_api_key_ids",
]
null_default_fields = []
optional_fields = set(
[
"default_image_model",
"default_provider_sort",
"default_text_model",
"description",
"io_logging_api_key_ids",
"io_logging_sampling_rate",
"is_data_discount_logging_enabled",
"is_observability_broadcast_enabled",
"is_observability_io_logging_enabled",
]
)
nullable_fields = set(
[
"default_image_model",
"default_provider_sort",
"default_text_model",
"description",
"io_logging_api_key_ids",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
+55 -8
View File
@@ -1,12 +1,13 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, UnrecognizedStr
from openrouter.utils import get_discriminator, validate_open_enum
from functools import partial
from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
from openrouter.utils.unions import parse_open_union
import pydantic
from pydantic import Discriminator, Tag
from pydantic.functional_validators import PlainValidator
from typing import Literal, Optional, Union
from pydantic import ConfigDict, model_serializer
from pydantic.functional_validators import BeforeValidator
from typing import Any, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
@@ -31,7 +32,7 @@ class FormatGrammarTypedDict(TypedDict):
class FormatGrammar(BaseModel):
definition: str
syntax: Annotated[Syntax, PlainValidator(validate_open_enum(False))]
syntax: Syntax
type: FormatTypeGrammar
@@ -52,9 +53,33 @@ FormatTypedDict = TypeAliasType(
)
class UnknownFormat(BaseModel):
r"""A Format variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
is_unknown: Literal[True] = True
model_config = ConfigDict(frozen=True)
_FORMAT__VARIANTS: dict[str, Any] = {
"text": FormatText,
"grammar": FormatGrammar,
}
Format = Annotated[
Union[Annotated[FormatText, Tag("text")], Annotated[FormatGrammar, Tag("grammar")]],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
Union[FormatText, FormatGrammar, UnknownFormat],
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
variants=_FORMAT__VARIANTS,
unknown_cls=UnknownFormat,
union_name="Format",
)
),
]
@@ -80,3 +105,25 @@ class CustomTool(BaseModel):
description: Optional[str] = None
format_: Annotated[Optional[Format], pydantic.Field(alias="format")] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["description", "format"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
try:
CustomTool.model_rebuild()
except NameError:
pass
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -36,3 +37,19 @@ class CustomToolCallItem(BaseModel):
namespace: Optional[str] = None
r"""Namespace qualifier for tools registered as part of a namespace tool group (e.g. an MCP server)"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["id", "namespace"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -11,9 +11,8 @@ from openrouter.types import (
UNSET_SENTINEL,
UnrecognizedStr,
)
from openrouter.utils import get_discriminator, validate_open_enum
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag, model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
@@ -43,9 +42,7 @@ class CustomToolCallOutputItemOutputInputImageTypedDict(TypedDict):
class CustomToolCallOutputItemOutputInputImage(BaseModel):
r"""Image input content item"""
detail: Annotated[
CustomToolCallOutputItemDetail, PlainValidator(validate_open_enum(False))
]
detail: CustomToolCallOutputItemDetail
type: CustomToolCallOutputItemTypeInputImage
@@ -53,31 +50,26 @@ class CustomToolCallOutputItemOutputInputImage(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["image_url"]
nullable_fields = ["image_url"]
null_default_fields = []
optional_fields = set(["image_url"])
nullable_fields = set(["image_url"])
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -136,3 +128,19 @@ class CustomToolCallOutputItem(BaseModel):
type: CustomToolCallOutputItemTypeCustomToolCallOutput
id: Optional[str] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["id"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -5,7 +5,8 @@ from .datetimeservertoolconfig import (
DatetimeServerToolConfig,
DatetimeServerToolConfigTypedDict,
)
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Literal, Optional
from typing_extensions import NotRequired, TypedDict
@@ -28,3 +29,19 @@ class DatetimeServerTool(BaseModel):
parameters: Optional[DatetimeServerToolConfig] = None
r"""Configuration for the openrouter:datetime server tool"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["parameters"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
@@ -1,7 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict
@@ -18,3 +19,19 @@ class DatetimeServerToolConfig(BaseModel):
timezone: Optional[str] = None
r"""IANA timezone name (e.g. \"America/New_York\"). Defaults to UTC."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["timezone"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
+20 -5
View File
@@ -1,11 +1,10 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, Nullable, UnrecognizedStr
from openrouter.utils import validate_open_enum
from pydantic.functional_validators import PlainValidator
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
from pydantic import model_serializer
from typing import Any, Dict, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypedDict
from typing_extensions import NotRequired, TypedDict
Event = Union[
@@ -28,7 +27,7 @@ class TimingsTypedDict(TypedDict):
class Timings(BaseModel):
epoch_ms: int
event: Annotated[Event, PlainValidator(validate_open_enum(False))]
event: Event
start_ms: int
@@ -43,6 +42,22 @@ class Debug(BaseModel):
timings: Optional[Timings] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["echo_upstream_body", "timings"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
DebugEventType = Literal["response.debug",]
+32 -33
View File
@@ -40,44 +40,43 @@ class DefaultParameters(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"frequency_penalty",
"presence_penalty",
"repetition_penalty",
"temperature",
"top_k",
"top_p",
]
nullable_fields = [
"frequency_penalty",
"presence_penalty",
"repetition_penalty",
"temperature",
"top_k",
"top_p",
]
null_default_fields = []
optional_fields = set(
[
"frequency_penalty",
"presence_penalty",
"repetition_penalty",
"temperature",
"top_k",
"top_p",
]
)
nullable_fields = set(
[
"frequency_penalty",
"presence_penalty",
"repetition_penalty",
"temperature",
"top_k",
"top_p",
]
)
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)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
)
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
if val != UNSET_SENTINEL:
if (
val is not None
or k not in optional_fields
or is_nullable_and_explicitly_set
):
m[k] = val
return m
@@ -20,3 +20,9 @@ class DeleteBYOKKeyResponse(BaseModel):
pydantic.Field(alias="deleted"),
] = True
r"""Confirmation that the BYOK credential was deleted."""
try:
DeleteBYOKKeyResponse.model_rebuild()
except NameError:
pass

Some files were not shown because too many files have changed in this diff Show More