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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.5.1"
".": "1.7.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 112
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b493cadf2e3b9658163a6bcf8f51e088dda169f12d68469c4441d17e889f5556.yml
openapi_spec_hash: b27ec3822d88d10efa268f1681fddff3
config_hash: 6c26299fd9ef01fb4713612a9a2ad17c
configured_endpoints: 117
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-15b7fd06098d8cb3639efb3b401a03d7d97a8ab4960b08077aa871f0cacb33d3.yml
openapi_spec_hash: 93ab2fe88f9e57d8f262ad6d1179190e
config_hash: eb28692edd68a6ae95cf92af931c9976
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 1.7.0 (2026-02-05)

Full Changelog: [v1.5.1...v1.7.0](https://github.com/runloopai/api-client-python/compare/v1.5.1...v1.7.0)

### Features

* add api to query devbox usage ([#7296](https://github.com/runloopai/api-client-python/issues/7296)) ([ab903f5](https://github.com/runloopai/api-client-python/commit/ab903f557ecc8be15c8d150068a82dfaaac23f4e))
* adding MCP Config routes ([#7331](https://github.com/runloopai/api-client-python/issues/7331)) ([79d05c0](https://github.com/runloopai/api-client-python/commit/79d05c00f9bb85a458cc300c5b065b6249a16a88))
* **devbox:** add mcp configuration to devbox create ([#7341](https://github.com/runloopai/api-client-python/issues/7341)) ([0b81e31](https://github.com/runloopai/api-client-python/commit/0b81e3151e3df41f667923cac4e714ba6d7ca3bc))
* **devbox:** adding gateway config ([#736](https://github.com/runloopai/api-client-python/issues/736)) ([9f4b49d](https://github.com/runloopai/api-client-python/commit/9f4b49daa13dd3aac5a8ee26a262fd7b5b705ff1))


### Bug Fixes

* **sdk:** fixed pagination for scorer, scenario and network policy list methods ([#731](https://github.com/runloopai/api-client-python/issues/731)) ([d55fceb](https://github.com/runloopai/api-client-python/commit/d55fceb7d42877cd0ac69a934ef300815f371342))


### Chores

* Mark legacy tunnel methods deprecated ([#737](https://github.com/runloopai/api-client-python/issues/737)) ([764b445](https://github.com/runloopai/api-client-python/commit/764b445018ec50db3105c0dd8ea58b02e4690e12))

## 1.5.1 (2026-01-30)

Full Changelog: [v1.5.0...v1.5.1](https://github.com/runloopai/api-client-python/compare/v1.5.0...v1.5.1)
Expand Down
25 changes: 23 additions & 2 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ from runloop_api_client.types import (
DevboxExecutionDetailView,
DevboxKillExecutionRequest,
DevboxListView,
DevboxResourceUsageView,
DevboxSendStdInRequest,
DevboxSendStdInResult,
DevboxSnapshotListView,
Expand Down Expand Up @@ -158,6 +159,7 @@ Methods:
- <code title="post /v1/devboxes/{id}/read_file_contents">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">read_file_contents</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_read_file_contents_params.py">params</a>) -> str</code>
- <code title="post /v1/devboxes/{id}/remove_tunnel">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">remove_tunnel</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_remove_tunnel_params.py">params</a>) -> object</code>
- <code title="post /v1/devboxes/{id}/resume">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">resume</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
- <code title="get /v1/devboxes/{id}/usage">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">retrieve_resource_usage</a>(id) -> <a href="./src/runloop_api_client/types/devbox_resource_usage_view.py">DevboxResourceUsageView</a></code>
- <code title="post /v1/devboxes/{id}/shutdown">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">shutdown</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
- <code title="post /v1/devboxes/{id}/snapshot_disk">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">snapshot_disk</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_snapshot_disk_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_snapshot_view.py">DevboxSnapshotView</a></code>
- <code title="post /v1/devboxes/{id}/snapshot_disk_async">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">snapshot_disk_async</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_snapshot_disk_async_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_snapshot_view.py">DevboxSnapshotView</a></code>
Expand Down Expand Up @@ -299,7 +301,6 @@ from runloop_api_client.types.scenarios import (
ScorerRetrieveResponse,
ScorerUpdateResponse,
ScorerListResponse,
ScorerValidateResponse,
)
```

Expand All @@ -309,7 +310,6 @@ Methods:
- <code title="get /v1/scenarios/scorers/{id}">client.scenarios.scorers.<a href="./src/runloop_api_client/resources/scenarios/scorers.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/scenarios/scorer_retrieve_response.py">ScorerRetrieveResponse</a></code>
- <code title="post /v1/scenarios/scorers/{id}">client.scenarios.scorers.<a href="./src/runloop_api_client/resources/scenarios/scorers.py">update</a>(id, \*\*<a href="src/runloop_api_client/types/scenarios/scorer_update_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenarios/scorer_update_response.py">ScorerUpdateResponse</a></code>
- <code title="get /v1/scenarios/scorers">client.scenarios.scorers.<a href="./src/runloop_api_client/resources/scenarios/scorers.py">list</a>(\*\*<a href="src/runloop_api_client/types/scenarios/scorer_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenarios/scorer_list_response.py">SyncScenarioScorersCursorIDPage[ScorerListResponse]</a></code>
- <code title="post /v1/scenarios/scorers/{id}/validate">client.scenarios.scorers.<a href="./src/runloop_api_client/resources/scenarios/scorers.py">validate</a>(id, \*\*<a href="src/runloop_api_client/types/scenarios/scorer_validate_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenarios/scorer_validate_response.py">ScorerValidateResponse</a></code>

# Objects

Expand Down Expand Up @@ -420,3 +420,24 @@ Methods:
- <code title="post /v1/gateway-configs/{id}">client.gateway_configs.<a href="./src/runloop_api_client/resources/gateway_configs.py">update</a>(id, \*\*<a href="src/runloop_api_client/types/gateway_config_update_params.py">params</a>) -> <a href="./src/runloop_api_client/types/gateway_config_view.py">GatewayConfigView</a></code>
- <code title="get /v1/gateway-configs">client.gateway_configs.<a href="./src/runloop_api_client/resources/gateway_configs.py">list</a>(\*\*<a href="src/runloop_api_client/types/gateway_config_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/gateway_config_view.py">SyncGatewayConfigsCursorIDPage[GatewayConfigView]</a></code>
- <code title="post /v1/gateway-configs/{id}/delete">client.gateway_configs.<a href="./src/runloop_api_client/resources/gateway_configs.py">delete</a>(id) -> <a href="./src/runloop_api_client/types/gateway_config_view.py">GatewayConfigView</a></code>

# McpConfigs

Types:

```python
from runloop_api_client.types import (
McpConfigCreateParameters,
McpConfigListView,
McpConfigUpdateParameters,
McpConfigView,
)
```

Methods:

- <code title="post /v1/mcp-configs">client.mcp_configs.<a href="./src/runloop_api_client/resources/mcp_configs.py">create</a>(\*\*<a href="src/runloop_api_client/types/mcp_config_create_params.py">params</a>) -> <a href="./src/runloop_api_client/types/mcp_config_view.py">McpConfigView</a></code>
- <code title="get /v1/mcp-configs/{id}">client.mcp_configs.<a href="./src/runloop_api_client/resources/mcp_configs.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/mcp_config_view.py">McpConfigView</a></code>
- <code title="post /v1/mcp-configs/{id}">client.mcp_configs.<a href="./src/runloop_api_client/resources/mcp_configs.py">update</a>(id, \*\*<a href="src/runloop_api_client/types/mcp_config_update_params.py">params</a>) -> <a href="./src/runloop_api_client/types/mcp_config_view.py">McpConfigView</a></code>
- <code title="get /v1/mcp-configs">client.mcp_configs.<a href="./src/runloop_api_client/resources/mcp_configs.py">list</a>(\*\*<a href="src/runloop_api_client/types/mcp_config_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/mcp_config_view.py">SyncMcpConfigsCursorIDPage[McpConfigView]</a></code>
- <code title="post /v1/mcp-configs/{id}/delete">client.mcp_configs.<a href="./src/runloop_api_client/resources/mcp_configs.py">delete</a>(id) -> <a href="./src/runloop_api_client/types/mcp_config_view.py">McpConfigView</a></code>
4 changes: 1 addition & 3 deletions docs/sdk/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,14 @@ These TypeDicts define parameters for storage object creation, listing, and down
Scorer Parameters
-----------------

These TypeDicts define parameters for scorer creation, listing, updating, and validation.
These TypeDicts define parameters for scorer creation, listing, and updating.

.. autotypeddict:: runloop_api_client.sdk._types.SDKScorerCreateParams

.. autotypeddict:: runloop_api_client.sdk._types.SDKScorerListParams

.. autotypeddict:: runloop_api_client.sdk._types.SDKScorerUpdateParams

.. autotypeddict:: runloop_api_client.sdk._types.SDKScorerValidateParams

Core Request Options
--------------------

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "runloop_api_client"
version = "1.5.1"
version = "1.7.0"
description = "The official Python library for the runloop API"
dynamic = ["readme"]
license = "MIT"
Expand Down
38 changes: 38 additions & 0 deletions src/runloop_api_client/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
scenarios,
benchmarks,
blueprints,
mcp_configs,
repositories,
benchmark_jobs,
benchmark_runs,
Expand All @@ -50,6 +51,7 @@
from .resources.secrets import SecretsResource, AsyncSecretsResource
from .resources.benchmarks import BenchmarksResource, AsyncBenchmarksResource
from .resources.blueprints import BlueprintsResource, AsyncBlueprintsResource
from .resources.mcp_configs import McpConfigsResource, AsyncMcpConfigsResource
from .resources.repositories import RepositoriesResource, AsyncRepositoriesResource
from .resources.benchmark_jobs import BenchmarkJobsResource, AsyncBenchmarkJobsResource
from .resources.benchmark_runs import BenchmarkRunsResource, AsyncBenchmarkRunsResource
Expand Down Expand Up @@ -190,6 +192,12 @@ def gateway_configs(self) -> GatewayConfigsResource:

return GatewayConfigsResource(self)

@cached_property
def mcp_configs(self) -> McpConfigsResource:
from .resources.mcp_configs import McpConfigsResource

return McpConfigsResource(self)

@cached_property
def with_raw_response(self) -> RunloopWithRawResponse:
return RunloopWithRawResponse(self)
Expand Down Expand Up @@ -432,6 +440,12 @@ def gateway_configs(self) -> AsyncGatewayConfigsResource:

return AsyncGatewayConfigsResource(self)

@cached_property
def mcp_configs(self) -> AsyncMcpConfigsResource:
from .resources.mcp_configs import AsyncMcpConfigsResource

return AsyncMcpConfigsResource(self)

@cached_property
def with_raw_response(self) -> AsyncRunloopWithRawResponse:
return AsyncRunloopWithRawResponse(self)
Expand Down Expand Up @@ -623,6 +637,12 @@ def gateway_configs(self) -> gateway_configs.GatewayConfigsResourceWithRawRespon

return GatewayConfigsResourceWithRawResponse(self._client.gateway_configs)

@cached_property
def mcp_configs(self) -> mcp_configs.McpConfigsResourceWithRawResponse:
from .resources.mcp_configs import McpConfigsResourceWithRawResponse

return McpConfigsResourceWithRawResponse(self._client.mcp_configs)


class AsyncRunloopWithRawResponse:
_client: AsyncRunloop
Expand Down Expand Up @@ -702,6 +722,12 @@ def gateway_configs(self) -> gateway_configs.AsyncGatewayConfigsResourceWithRawR

return AsyncGatewayConfigsResourceWithRawResponse(self._client.gateway_configs)

@cached_property
def mcp_configs(self) -> mcp_configs.AsyncMcpConfigsResourceWithRawResponse:
from .resources.mcp_configs import AsyncMcpConfigsResourceWithRawResponse

return AsyncMcpConfigsResourceWithRawResponse(self._client.mcp_configs)


class RunloopWithStreamedResponse:
_client: Runloop
Expand Down Expand Up @@ -781,6 +807,12 @@ def gateway_configs(self) -> gateway_configs.GatewayConfigsResourceWithStreaming

return GatewayConfigsResourceWithStreamingResponse(self._client.gateway_configs)

@cached_property
def mcp_configs(self) -> mcp_configs.McpConfigsResourceWithStreamingResponse:
from .resources.mcp_configs import McpConfigsResourceWithStreamingResponse

return McpConfigsResourceWithStreamingResponse(self._client.mcp_configs)


class AsyncRunloopWithStreamedResponse:
_client: AsyncRunloop
Expand Down Expand Up @@ -860,6 +892,12 @@ def gateway_configs(self) -> gateway_configs.AsyncGatewayConfigsResourceWithStre

return AsyncGatewayConfigsResourceWithStreamingResponse(self._client.gateway_configs)

@cached_property
def mcp_configs(self) -> mcp_configs.AsyncMcpConfigsResourceWithStreamingResponse:
from .resources.mcp_configs import AsyncMcpConfigsResourceWithStreamingResponse

return AsyncMcpConfigsResourceWithStreamingResponse(self._client.mcp_configs)


Client = Runloop

Expand Down
2 changes: 1 addition & 1 deletion src/runloop_api_client/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "runloop_api_client"
__version__ = "1.5.1" # x-release-please-version
__version__ = "1.7.0" # x-release-please-version
75 changes: 75 additions & 0 deletions src/runloop_api_client/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"AsyncNetworkPoliciesCursorIDPage",
"SyncGatewayConfigsCursorIDPage",
"AsyncGatewayConfigsCursorIDPage",
"SyncMcpConfigsCursorIDPage",
"AsyncMcpConfigsCursorIDPage",
]

_T = TypeVar("_T")
Expand Down Expand Up @@ -102,6 +104,11 @@ class GatewayConfigsCursorIDPageItem(Protocol):
id: str


@runtime_checkable
class McpConfigsCursorIDPageItem(Protocol):
id: str


class SyncBlueprintsCursorIDPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
blueprints: List[_T]
has_more: Optional[bool] = None
Expand Down Expand Up @@ -984,3 +991,71 @@ def next_page_info(self) -> Optional[PageInfo]:
return None

return PageInfo(params={"starting_after": item.id})


class SyncMcpConfigsCursorIDPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
mcp_configs: List[_T]
has_more: Optional[bool] = None
total_count: Optional[int] = None

@override
def _get_page_items(self) -> List[_T]:
mcp_configs = self.mcp_configs
if not mcp_configs:
return []
return mcp_configs

@override
def has_next_page(self) -> bool:
has_more = self.has_more
if has_more is not None and has_more is False:
return False

return super().has_next_page()

@override
def next_page_info(self) -> Optional[PageInfo]:
mcp_configs = self.mcp_configs
if not mcp_configs:
return None

item = cast(Any, mcp_configs[-1])
if not isinstance(item, McpConfigsCursorIDPageItem) or item.id is None: # pyright: ignore[reportUnnecessaryComparison]
# TODO emit warning log
return None

return PageInfo(params={"starting_after": item.id})


class AsyncMcpConfigsCursorIDPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
mcp_configs: List[_T]
has_more: Optional[bool] = None
total_count: Optional[int] = None

@override
def _get_page_items(self) -> List[_T]:
mcp_configs = self.mcp_configs
if not mcp_configs:
return []
return mcp_configs

@override
def has_next_page(self) -> bool:
has_more = self.has_more
if has_more is not None and has_more is False:
return False

return super().has_next_page()

@override
def next_page_info(self) -> Optional[PageInfo]:
mcp_configs = self.mcp_configs
if not mcp_configs:
return None

item = cast(Any, mcp_configs[-1])
if not isinstance(item, McpConfigsCursorIDPageItem) or item.id is None: # pyright: ignore[reportUnnecessaryComparison]
# TODO emit warning log
return None

return PageInfo(params={"starting_after": item.id})
14 changes: 14 additions & 0 deletions src/runloop_api_client/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
BlueprintsResourceWithStreamingResponse,
AsyncBlueprintsResourceWithStreamingResponse,
)
from .mcp_configs import (
McpConfigsResource,
AsyncMcpConfigsResource,
McpConfigsResourceWithRawResponse,
AsyncMcpConfigsResourceWithRawResponse,
McpConfigsResourceWithStreamingResponse,
AsyncMcpConfigsResourceWithStreamingResponse,
)
from .repositories import (
RepositoriesResource,
AsyncRepositoriesResource,
Expand Down Expand Up @@ -170,4 +178,10 @@
"AsyncGatewayConfigsResourceWithRawResponse",
"GatewayConfigsResourceWithStreamingResponse",
"AsyncGatewayConfigsResourceWithStreamingResponse",
"McpConfigsResource",
"AsyncMcpConfigsResource",
"McpConfigsResourceWithRawResponse",
"AsyncMcpConfigsResourceWithRawResponse",
"McpConfigsResourceWithStreamingResponse",
"AsyncMcpConfigsResourceWithStreamingResponse",
]
Loading