## Python SDK Changes:

* `open_router.embeddings.list_models()`:  `response.data.[].reasoning` **Added**
* `open_router.models.get()`:  `response.data.reasoning` **Added**
* `open_router.models.list()`:  `response.data.[].reasoning` **Added**
* `open_router.models.list_for_user()`:  `response.data.[].reasoning` **Added**
This commit is contained in:
speakeasybot
2026-06-18 01:00:24 +00:00
parent b0eda78d3f
commit 15ce4685f3
12 changed files with 228 additions and 32 deletions
+36 -19
View File
@@ -1,19 +1,19 @@
lockVersion: 2.0.0
id: c48cf606-fb42-4a45-9c23-8f0555307828
management:
docChecksum: 8dd32184dc771115ba5e79b3c70e7f6f
docChecksum: cc6966b5800766370c195f5c42b10761
docVersion: 1.0.0
speakeasyVersion: 1.680.0
generationVersion: 2.788.4
releaseVersion: 0.10.0
configChecksum: 00a97c5bcdbddf7e591c0a1d7a45e98e
releaseVersion: 0.10.1
configChecksum: b1687c127d87a1ac114b35dd9b492f3c
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
generation_id: b6cb6701-b1ae-453f-beb8-2064f09433f4
pristine_commit_hash: ed0a00c99b7b3b76ed1de023bc8174696435c2cd
pristine_tree_hash: a5b3d8dc9253bb236d709d9f365f5766595d820b
generation_id: 8123354f-2376-451c-8dbd-6e7ed6d6980c
pristine_commit_hash: 48c154f879472adb6f282e81083593c020808530
pristine_tree_hash: 3e5484ebb7e5c6660a037fb427b4aa9edd240571
features:
python:
acceptHeaders: 3.0.0
@@ -1448,6 +1448,10 @@ trackedFiles:
id: 8d84fb41685d
last_write_checksum: sha1:fcfbe6740c505b263b90f7de5281d4f506922b05
pristine_git_object: 870296bd3335da46ecdf4ec1722a3d47037a09c9
docs/components/defaulteffort.md:
id: 08dabde07c1d
last_write_checksum: sha1:96f06eb8b68e44984b691338b99e746fef1253ac
pristine_git_object: f3f07f26e47692dd4e6a728e45f32cfe5795082e
docs/components/defaultparameters.md:
id: a84477afcaec
last_write_checksum: sha1:a20e8b576e341dbcdb91884b8fc83cf4316ab106
@@ -2522,8 +2526,8 @@ trackedFiles:
pristine_git_object: d5bbdc95f658be46eebf13f0ba8b9ae3716f72e2
docs/components/model.md:
id: 673ad57400cd
last_write_checksum: sha1:517cbce221606bacb2cab7b97e53d316d09a5f17
pristine_git_object: 8ce3d9d7c9ddc7c270da3a39df079148aa7ff207
last_write_checksum: sha1:ea20bf9ca8f49a181142f516f1b36758cf5ceac6
pristine_git_object: edb000fc276b3eec0dbe0bb1e82c4f5d7a72e8c9
docs/components/modelarchitecture.md:
id: 79816051e6e8
last_write_checksum: sha1:158b04c79b7a32a2d95e3d3fda8fa6da0ab91cd9
@@ -2548,10 +2552,14 @@ trackedFiles:
id: 74607e6a173d
last_write_checksum: sha1:445ec227b130763e2509d1a181dd5e3e6d71420a
pristine_git_object: 317190772f743d2aba63c4dad770827b46688f6a
docs/components/modelreasoning.md:
id: 47976b46e5b9
last_write_checksum: sha1:07deec55fe155257ef07086b6dc2fbc7e012e031
pristine_git_object: 306c0aeb39047768e6c79975996240584a97525b
docs/components/modelresponse.md:
id: 9d48c3f335b1
last_write_checksum: sha1:5d8890c41a9f448341037e9915dd6e93df9140cb
pristine_git_object: 2a7433dc87413943d14220ffdfda8b25e59bc9c0
last_write_checksum: sha1:442bb6c4d21debbceb5a48a9563b07704983123f
pristine_git_object: 2ad6e9dc16fa06d03318e98bc540c7aca0d497ed
docs/components/modelscountresponse.md:
id: abdad0c1a02a
last_write_checksum: sha1:50ae205604eddcbdced268b8cd3e1ac06f0dd7c0
@@ -6042,8 +6050,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
last_write_checksum: sha1:ccf5925a473a1eb527cec02639f862b79b601251
pristine_git_object: 396bd51f9c1428f03560f3e7988edc99edc698e8
last_write_checksum: sha1:8223abd8e7463dfa2b2c1097670bb28b2ec73e68
pristine_git_object: b98c0280ffbb42638747b1064375fa36f467223c
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -6070,8 +6078,8 @@ trackedFiles:
pristine_git_object: 07ace03229fd3267623c8f48665d2c3a67c3565d
src/openrouter/_version.py:
id: d8d15ad6c586
last_write_checksum: sha1:017dc1ec43588b31eee23532d74d4421993dd874
pristine_git_object: be619e3be1aa8d27deef5752ecc9ff09ccd4cd9f
last_write_checksum: sha1:856bdf17b7de36f6e1abd0b56f55bbc6093e4c68
pristine_git_object: ade61995259031f3789ff71f0cfd1d6ae4b39395
src/openrouter/analytics.py:
id: cb406b5aaabb
last_write_checksum: sha1:6d47d1ab3da9cb4ac9f0a2bfe442f1a82a614f35
@@ -6102,8 +6110,8 @@ trackedFiles:
pristine_git_object: a1894915bd32aee65f019885634eb7908970a046
src/openrouter/components/__init__.py:
id: 81754e97b3f4
last_write_checksum: sha1:56e0c315ac8fe611bf70b465a91341acbbe34534
pristine_git_object: 2c07302c12f51cdf053e306906ac30862e925246
last_write_checksum: sha1:a136f824b02becfa0584a28474bb5f308a6861dc
pristine_git_object: 9df66e9e82ebd373652cc654f23b104ef315f3c5
src/openrouter/components/aabenchmarkentry.py:
id: e2e0f0b48c82
last_write_checksum: sha1:1b6b66672fb80dccdc39843a98bdef6d7d804364
@@ -7178,8 +7186,8 @@ trackedFiles:
pristine_git_object: 1257b38d2001f34078cd1b052c20264e81a95e57
src/openrouter/components/model.py:
id: cef3adaa772b
last_write_checksum: sha1:53eb4a044a7bf546225416bb08597df46a3b60a2
pristine_git_object: 637b3fbe54ddcc454750d8de702045ee690c3333
last_write_checksum: sha1:53f544fe39ae08cde33f99c5d0bb4b6cc1555301
pristine_git_object: c0345109fb1717ea27010605984c27e1137426fd
src/openrouter/components/modelarchitecture.py:
id: b37ac27e512b
last_write_checksum: sha1:e1dd41aa140b2ca2c3bbf15abf74e034d42b0166
@@ -7196,6 +7204,10 @@ trackedFiles:
id: b8759a1a4787
last_write_checksum: sha1:69b2c991666848f4790e5136c67553733cc68a54
pristine_git_object: c197cb2c527296adff2c3cfd9e49bcbc48087ce7
src/openrouter/components/modelreasoning.py:
id: 58bb3f2d75e0
last_write_checksum: sha1:3da126ae596520b6d4f0edcc7fb8e4f786f686c7
pristine_git_object: b71947b65e2054b23ff2094a270763720e740d96
src/openrouter/components/modelresponse.py:
id: 023136e6dedf
last_write_checksum: sha1:af84587984cbe6341f59f176b08df43096ac48c6
@@ -10043,4 +10055,9 @@ examples:
"500":
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
examplesVersion: 1.0.2
releaseNotes: "## Python SDK Changes:\n* `open_router.beta.responses.send()`: \n * `request` **Changed** **Breaking** :warning:\n * `response` **Changed** **Breaking** :warning:\n* `open_router.presets.create_presets_responses()`: `request` **Changed** **Breaking** :warning:\n* `open_router.presets.create_presets_chat_completions()`: `request` **Changed** **Breaking** :warning:\n* `open_router.chat.send()`: `request` **Changed** **Breaking** :warning:\n* `open_router.workspaces.set_budget()`: **Added**\n* `open_router.o_auth.create_auth_code()`: \n * `request.workspace_id` **Added**\n * `error.status[403]` **Added**\n* `open_router.files.download()`: **Added**\n* `open_router.models.get()`: **Added**\n* `open_router.workspaces.list_budgets()`: **Added**\n* `open_router.workspaces.delete_budget()`: **Added**\n* `open_router.datasets.get_benchmarks_artificial_analysis()`: **Added**\n* `open_router.beta.analytics.query_analytics()`: `response.data.warnings` **Added**\n* `open_router.files.delete()`: **Added**\n* `open_router.files.retrieve()`: **Added**\n* `open_router.files.upload()`: **Added**\n* `open_router.embeddings.list_models()`: `response.data.[].benchmarks` **Added**\n* `open_router.models.list()`: \n * `request` **Changed**\n * `response.data.[].benchmarks` **Added**\n* `open_router.models.list_for_user()`: `response.data.[].benchmarks` **Added**\n* `open_router.files.list()`: **Added**\n* `open_router.presets.create_presets_messages()`: `request` **Changed**\n* `open_router.datasets.get_benchmarks_design_arena()`: **Added**\n"
releaseNotes: |
## Python SDK Changes:
* `open_router.embeddings.list_models()`: `response.data.[].reasoning` **Added**
* `open_router.models.get()`: `response.data.reasoning` **Added**
* `open_router.models.list()`: `response.data.[].reasoning` **Added**
* `open_router.models.list_for_user()`: `response.data.[].reasoning` **Added**
+1 -1
View File
@@ -32,7 +32,7 @@ generation:
skipResponseBodyAssertions: false
preApplyUnionDiscriminators: true
python:
version: 0.10.0
version: 0.10.1
additionalDependencies:
dev: {}
main: {}
+49 -1
View File
@@ -12151,6 +12151,15 @@ components:
image: '0'
prompt: '0.00003'
request: '0'
reasoning:
default_effort: medium
default_enabled: true
mandatory: false
supported_efforts:
- high
- medium
- low
- minimal
supported_parameters:
- temperature
- top_p
@@ -12213,6 +12222,8 @@ components:
$ref: '#/components/schemas/PerRequestLimits'
pricing:
$ref: '#/components/schemas/PublicPricing'
reasoning:
$ref: '#/components/schemas/ModelReasoning'
supported_parameters:
description: List of supported parameters for this model
items:
@@ -12377,6 +12388,43 @@ components:
description: Model to use for completion
example: openai/gpt-4
type: string
ModelReasoning:
description: Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models.
example:
default_effort: medium
default_enabled: true
mandatory: false
supported_efforts:
- high
- medium
- low
- minimal
properties:
default_effort:
allOf:
- $ref: '#/components/schemas/ReasoningEffort'
- description: >-
Default reasoning effort when the client enables reasoning without specifying effort. Maps to `reasoning.effort` in chat requests. When `"none"`, prefer omitting effort unless the user explicitly disables reasoning.
default_enabled:
description: Default reasoning enabled state when the client does not set `reasoning.enabled`.
type: boolean
mandatory:
description: When true, reasoning cannot be disabled and effort "none" is rejected.
type: boolean
supported_efforts:
description: >-
Allowed reasoning effort values for this model, in descending effort order (highest first). Null means no allowlist — all gateway effort values are accepted.
items:
$ref: '#/components/schemas/ReasoningEffort'
nullable: true
type: array
supports_max_tokens:
description: >-
Present and `true` when the model accepts `reasoning.max_tokens` in requests (Anthropic-style) instead of or in addition to `reasoning.effort`. Omitted otherwise.
type: boolean
required:
- mandatory
type: object
ModelResponse:
description: Single model response
example:
@@ -28725,7 +28773,7 @@ paths:
id: openai/gpt-4
knowledge_cutoff: null
links:
details: /api/v1/models/openai/gpt-5.4/endpoints
details: /api/v1/models/openai/gpt-4/endpoints
name: GPT-4
per_request_limits: null
pricing:
+6 -6
View File
@@ -2,20 +2,20 @@ speakeasyVersion: 1.680.0
sources:
OpenRouter API:
sourceNamespace: open-router-chat-completions-api
sourceRevisionDigest: sha256:716ece4a1211eac2ee0e7e5836c7b484cff9bb002bd4e676d9ecad8317ee7941
sourceBlobDigest: sha256:12d3dc8e7150ab2c4c5e3d613b01cb5e4dcce52b329eea89ca1fdc656d6fe045
sourceRevisionDigest: sha256:b28471bf9c3ac9b7d9b816a09bfb5b5c58d98db2d82dbc971d64f5aa980f4e10
sourceBlobDigest: sha256:8d445ea792f56fb2ebeb3f418757e6404802be1c21ab50520c66d10871bb960a
tags:
- latest
- speakeasy-sdk-regen-1781312282
- speakeasy-sdk-regen-1781726096
- 1.0.0
targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
sourceRevisionDigest: sha256:716ece4a1211eac2ee0e7e5836c7b484cff9bb002bd4e676d9ecad8317ee7941
sourceBlobDigest: sha256:12d3dc8e7150ab2c4c5e3d613b01cb5e4dcce52b329eea89ca1fdc656d6fe045
sourceRevisionDigest: sha256:b28471bf9c3ac9b7d9b816a09bfb5b5c58d98db2d82dbc971d64f5aa980f4e10
sourceBlobDigest: sha256:8d445ea792f56fb2ebeb3f418757e6404802be1c21ab50520c66d10871bb960a
codeSamplesNamespace: open-router-python-code-samples
codeSamplesRevisionDigest: sha256:e7d6f4de48a7c63cf15f3a8378f952277cd4c59373c28c61909497853fa769e2
codeSamplesRevisionDigest: sha256:0bb2447eb2e776cdc9347c290ddcde4be0b9f9ded69c93e5b29231e2c54c3e5f
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.680.0
+11 -1
View File
@@ -28,4 +28,14 @@ Based on:
### Generated
- [python v0.10.0] .
### Releases
- [PyPI v0.10.0] https://pypi.org/project/openrouter/0.10.0 - .
- [PyPI v0.10.0] https://pypi.org/project/openrouter/0.10.0 - .
## 2026-06-18 00:58:22
### Changes
Based on:
- OpenAPI Doc
- Speakeasy CLI 1.680.0 (2.788.4) https://github.com/speakeasy-api/speakeasy
### Generated
- [python v0.10.1] .
### Releases
- [PyPI v0.10.1] https://pypi.org/project/openrouter/0.10.1 - .
+1
View File
@@ -22,6 +22,7 @@ Information about an AI model available on OpenRouter
| `name` | *str* | :heavy_check_mark: | Display name of the model | GPT-4 |
| `per_request_limits` | [Nullable[components.PerRequestLimits]](../components/perrequestlimits.md) | :heavy_check_mark: | Per-request token limits | {<br/>"completion_tokens": 1000,<br/>"prompt_tokens": 1000<br/>} |
| `pricing` | [components.PublicPricing](../components/publicpricing.md) | :heavy_check_mark: | Pricing information for the model | {<br/>"completion": "0.00006",<br/>"image": "0",<br/>"prompt": "0.00003",<br/>"request": "0"<br/>} |
| `reasoning` | [Optional[components.ModelReasoning]](../components/modelreasoning.md) | :heavy_minus_sign: | Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models. | {<br/>"default_effort": "medium",<br/>"default_enabled": true,<br/>"mandatory": false,<br/>"supported_efforts": [<br/>"high",<br/>"medium",<br/>"low",<br/>"minimal"<br/>]<br/>} |
| `supported_parameters` | List[[components.Parameter](../components/parameter.md)] | :heavy_check_mark: | List of supported parameters for this model | |
| `supported_voices` | List[*str*] | :heavy_check_mark: | List of supported voice identifiers for TTS models. Null for non-TTS models. | <nil> |
| `top_provider` | [components.TopProviderInfo](../components/topproviderinfo.md) | :heavy_check_mark: | Information about the top provider for this model | {<br/>"context_length": 8192,<br/>"is_moderated": true,<br/>"max_completion_tokens": 4096<br/>} |
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
version = "0.10.0"
version = "0.10.1"
description = "Official Python Client SDK for OpenRouter."
authors = [{ name = "OpenRouter" },]
readme = "README-PYPI.md"
+2 -2
View File
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "openrouter"
__version__: str = "0.10.0"
__version__: str = "0.10.1"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.788.4"
__user_agent__: str = "speakeasy-sdk/python 0.10.0 2.788.4 1.0.0 openrouter"
__user_agent__: str = "speakeasy-sdk/python 0.10.1 2.788.4 1.0.0 openrouter"
try:
if __package__ is not None:
+7
View File
@@ -1436,6 +1436,7 @@ if TYPE_CHECKING:
from .modelbenchmarks import ModelBenchmarks, ModelBenchmarksTypedDict
from .modelgroup import ModelGroup
from .modellinks import ModelLinks, ModelLinksTypedDict
from .modelreasoning import DefaultEffort, ModelReasoning, ModelReasoningTypedDict
from .modelresponse import ModelResponse, ModelResponseTypedDict
from .modelscountresponse import (
ModelsCountResponse,
@@ -3076,6 +3077,7 @@ __all__ = [
"DatetimeServerToolConfigTypedDict",
"DatetimeServerToolType",
"DatetimeServerToolTypedDict",
"DefaultEffort",
"DefaultParameters",
"DefaultParametersTypedDict",
"DeleteBYOKKeyResponse",
@@ -3518,6 +3520,8 @@ __all__ = [
"ModelGroup",
"ModelLinks",
"ModelLinksTypedDict",
"ModelReasoning",
"ModelReasoningTypedDict",
"ModelResponse",
"ModelResponseTypedDict",
"ModelTypedDict",
@@ -5459,6 +5463,9 @@ _dynamic_imports: dict[str, str] = {
"ModelGroup": ".modelgroup",
"ModelLinks": ".modellinks",
"ModelLinksTypedDict": ".modellinks",
"DefaultEffort": ".modelreasoning",
"ModelReasoning": ".modelreasoning",
"ModelReasoningTypedDict": ".modelreasoning",
"ModelResponse": ".modelresponse",
"ModelResponseTypedDict": ".modelresponse",
"ModelsCountResponse": ".modelscountresponse",
+7
View File
@@ -5,6 +5,7 @@ from .defaultparameters import DefaultParameters, DefaultParametersTypedDict
from .modelarchitecture import ModelArchitecture, ModelArchitectureTypedDict
from .modelbenchmarks import ModelBenchmarks, ModelBenchmarksTypedDict
from .modellinks import ModelLinks, ModelLinksTypedDict
from .modelreasoning import ModelReasoning, ModelReasoningTypedDict
from .parameter import Parameter
from .perrequestlimits import PerRequestLimits, PerRequestLimitsTypedDict
from .publicpricing import PublicPricing, PublicPricingTypedDict
@@ -62,6 +63,8 @@ class ModelTypedDict(TypedDict):
r"""Hugging Face model identifier, if applicable"""
knowledge_cutoff: NotRequired[Nullable[str]]
r"""The date up to which the model was trained on data. ISO 8601 date string (YYYY-MM-DD) or null if unknown."""
reasoning: NotRequired[ModelReasoningTypedDict]
r"""Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models."""
class Model(BaseModel):
@@ -123,6 +126,9 @@ class Model(BaseModel):
knowledge_cutoff: OptionalNullable[str] = UNSET
r"""The date up to which the model was trained on data. ISO 8601 date string (YYYY-MM-DD) or null if unknown."""
reasoning: Optional[ModelReasoning] = None
r"""Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
@@ -131,6 +137,7 @@ class Model(BaseModel):
"expiration_date",
"hugging_face_id",
"knowledge_cutoff",
"reasoning",
]
nullable_fields = [
"context_length",
+106
View File
@@ -0,0 +1,106 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .reasoningeffort import ReasoningEffort
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
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, TypedDict
DefaultEffort = Union[
Literal[
"xhigh",
"high",
"medium",
"low",
"minimal",
"none",
],
UnrecognizedStr,
]
r"""Default reasoning effort when the client enables reasoning without specifying effort. Maps to `reasoning.effort` in chat requests. When `\"none\"`, prefer omitting effort unless the user explicitly disables reasoning."""
class ModelReasoningTypedDict(TypedDict):
r"""Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models."""
mandatory: bool
r"""When true, reasoning cannot be disabled and effort \"none\" is rejected."""
default_effort: NotRequired[Nullable[DefaultEffort]]
default_enabled: NotRequired[bool]
r"""Default reasoning enabled state when the client does not set `reasoning.enabled`."""
supported_efforts: NotRequired[Nullable[List[Nullable[ReasoningEffort]]]]
r"""Allowed reasoning effort values for this model, in descending effort order (highest first). Null means no allowlist — all gateway effort values are accepted."""
supports_max_tokens: NotRequired[bool]
r"""Present and `true` when the model accepts `reasoning.max_tokens` in requests (Anthropic-style) instead of or in addition to `reasoning.effort`. Omitted otherwise."""
class ModelReasoning(BaseModel):
r"""Reasoning effort configuration. Omitted for non-reasoning models and dynamic router models."""
mandatory: bool
r"""When true, reasoning cannot be disabled and effort \"none\" is rejected."""
default_effort: Annotated[
OptionalNullable[DefaultEffort], PlainValidator(validate_open_enum(False))
] = UNSET
default_enabled: Optional[bool] = None
r"""Default reasoning enabled state when the client does not set `reasoning.enabled`."""
supported_efforts: OptionalNullable[
List[
Annotated[
Nullable[ReasoningEffort], PlainValidator(validate_open_enum(False))
]
]
] = UNSET
r"""Allowed reasoning effort values for this model, in descending effort order (highest first). Null means no allowlist — all gateway effort values are accepted."""
supports_max_tokens: Optional[bool] = None
r"""Present and `true` when the model accepts `reasoning.max_tokens` in requests (Anthropic-style) instead of or in addition to `reasoning.effort`. Omitted otherwise."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"default_effort",
"default_enabled",
"supported_efforts",
"supports_max_tokens",
]
nullable_fields = ["default_effort", "supported_efforts"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
Generated
+1 -1
View File
@@ -220,7 +220,7 @@ wheels = [
[[package]]
name = "openrouter"
version = "0.10.0"
version = "0.10.1"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },